Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(712)

Delta Between Two Patch Sets: environs/openstack/provider.go

Issue 6850087: environs/config: make CA cert optional
Left Patch Set: environs/config: make CA cert optional Created 12 years, 4 months ago
Right Patch Set: environs/config: make CA cert optional Created 12 years, 4 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
Right: Side by side diff | Download
« no previous file with change/comment | « environs/openstack/local_test.go ('k') | environs/openstack/testdata/2011-01-01/meta-data/local-hostname » ('j') | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
(no file at all)
1 // Stub provider for OpenStack, using goose will be implemented here
2
3 package openstack
4
5 import (
6 "fmt"
7 "io/ioutil"
8 "launchpad.net/juju-core/environs"
9 "launchpad.net/juju-core/environs/config"
10 "launchpad.net/juju-core/log"
11 "launchpad.net/juju-core/state"
12 "launchpad.net/juju-core/trivial"
13 "net/http"
14 "strings"
15 "sync"
16 "time"
17 )
18
19 type environProvider struct{}
20
21 var _ environs.EnvironProvider = (*environProvider)(nil)
22
23 var providerInstance environProvider
24
25 // A request may fail to due "eventual consistency" semantics, which
26 // should resolve fairly quickly. A request may also fail due to a slow
27 // state transition (for instance an instance taking a while to release
28 // a security group after termination). The former failure mode is
29 // dealt with by shortAttempt, the latter by longAttempt.
30 var shortAttempt = trivial.AttemptStrategy{
31 Total: 5 * time.Second,
32 Delay: 200 * time.Millisecond,
33 }
34
35 var longAttempt = trivial.AttemptStrategy{
36 Total: 3 * time.Minute,
37 Delay: 1 * time.Second,
38 }
39
40 func init() {
41 environs.RegisterProvider("openstack", environProvider{})
42 }
43
44 func (p environProvider) Open(cfg *config.Config) (environs.Environ, error) {
45 log.Printf("environs/openstack: opening environment %q", cfg.Name())
46 e := new(environ)
47 err := e.SetConfig(cfg)
48 if err != nil {
49 return nil, err
50 }
51 return e, nil
52 }
53
54 func (p environProvider) SecretAttrs(cfg *config.Config) (map[string]interface{} , error) {
55 m := make(map[string]interface{})
56 ecfg, err := providerInstance.newConfig(cfg)
57 if err != nil {
58 return nil, err
59 }
60 m["username"] = ecfg.username()
61 m["password"] = ecfg.password()
62 m["tenant-name"] = ecfg.tenantName()
63 return m, nil
64 }
65
66 func (p environProvider) PublicAddress() (string, error) {
67 return fetchMetadata("public-hostname")
68 }
69
70 func (p environProvider) PrivateAddress() (string, error) {
71 return fetchMetadata("local-hostname")
72 }
73
74 type environ struct {
75 name string
76
77 ecfgMutex sync.Mutex
78 ecfgUnlocked *environConfig
79 }
80
81 var _ environs.Environ = (*environ)(nil)
82
83 func (e *environ) ecfg() *environConfig {
84 e.ecfgMutex.Lock()
85 ecfg := e.ecfgUnlocked
86 e.ecfgMutex.Unlock()
87 return ecfg
88 }
89
90 func (e *environ) Name() string {
91 return e.name
92 }
93
94 func (e *environ) Bootstrap(uploadTools bool, stateServerPEM []byte) error {
95 panic("not implemented")
96 }
97
98 func (e *environ) StateInfo() (*state.Info, error) {
99 panic("not implemented")
100 }
101
102 func (e *environ) Config() *config.Config {
103 panic("not implemented")
104 }
105
106 func (e *environ) SetConfig(cfg *config.Config) error {
107 ecfg, err := providerInstance.newConfig(cfg)
108 if err != nil {
109 return err
110 }
111 e.ecfgMutex.Lock()
112 defer e.ecfgMutex.Unlock()
113 e.name = ecfg.Name()
114 e.ecfgUnlocked = ecfg
115
116 // TODO(dimitern): setup the goose client auth/compute, etc. here
117 return nil
118 }
119
120 func (e *environ) StartInstance(machineId int, info *state.Info, tools *state.To ols) (environs.Instance, error) {
121 panic("not implemented")
122 }
123
124 func (e *environ) StopInstances([]environs.Instance) error {
125 panic("not implemented")
126 }
127
128 func (e *environ) Instances(ids []string) ([]environs.Instance, error) {
129 panic("not implemented")
130 }
131
132 func (e *environ) AllInstances() ([]environs.Instance, error) {
133 panic("not implemented")
134 }
135
136 func (e *environ) Storage() environs.Storage {
137 panic("not implemented")
138 }
139
140 func (e *environ) PublicStorage() environs.StorageReader {
141 panic("not implemented")
142 }
143
144 func (e *environ) Destroy(insts []environs.Instance) error {
145 panic("not implemented")
146 }
147
148 func (e *environ) AssignmentPolicy() state.AssignmentPolicy {
149 panic("not implemented")
150 }
151
152 func (e *environ) OpenPorts(ports []state.Port) error {
153 panic("not implemented")
154 }
155
156 func (e *environ) ClosePorts(ports []state.Port) error {
157 panic("not implemented")
158 }
159
160 func (e *environ) Ports() ([]state.Port, error) {
161 panic("not implemented")
162 }
163
164 func (e *environ) Provider() environs.EnvironProvider {
165 return &providerInstance
166 }
167
168 // metadataHost holds the address of the instance metadata service.
169 // It is a variable so that tests can change it to refer to a local
170 // server when needed.
171 var metadataHost = "http://169.254.169.254"
172
173 // fetchMetadata fetches a single atom of data from the openstack instance metad ata service.
174 // http://docs.amazonwebservices.com/AWSEC2/latest/UserGuide/AESDG-chapter-insta ncedata.html
175 // (the same specs is implemented in OpenStack, hence the reference)
176 func fetchMetadata(name string) (value string, err error) {
177 uri := fmt.Sprintf("%s/2011-01-01/meta-data/%s", metadataHost, name)
178 for a := shortAttempt.Start(); a.Next(); {
179 var resp *http.Response
180 resp, err = http.Get(uri)
181 if err != nil {
182 continue
183 }
184 defer resp.Body.Close()
185 if resp.StatusCode != http.StatusOK {
186 err = fmt.Errorf("bad http response %v", resp.Status)
187 continue
188 }
189 var data []byte
190 data, err = ioutil.ReadAll(resp.Body)
191 if err != nil {
192 continue
193 }
194 return strings.TrimSpace(string(data)), nil
195 }
196 if err != nil {
197 return "", fmt.Errorf("cannot get %q: %v", uri, err)
198 }
199 return
200 }
LEFTRIGHT

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b