Merge lp:~rvb/gwacl/add-network-config into lp:gwacl
- add-network-config
- Merge into trunk
Status: | Merged |
---|---|
Approved by: | Raphaël Badin |
Approved revision: | 153 |
Merged at revision: | 154 |
Proposed branch: | lp:~rvb/gwacl/add-network-config |
Merge into: | lp:gwacl |
Diff against target: |
475 lines (+140/-101) 5 files modified
example/management/run.go (+19/-4) helpers_apiobjects_test.go (+4/-11) management_base_test.go (+3/-3) xmlobjects.go (+57/-42) xmlobjects_test.go (+57/-41) |
To merge this branch: | bzr merge lp:~rvb/gwacl/add-network-config |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Jeroen T. Vermeulen (community) | Approve | ||
Review via email: mp+172518@code.launchpad.net |
Commit message
Add support for configuring the network when creating a VM.
Description of the change
This branch's main goal is to allow the user to configure the network using a ConfigurationSet object. It can be used when creating the VM and (hopefully) later on when reconfiguring the VM to open/close ports.
The main trick is that the object we used to call LinuxProvisioni
I changed the DisableSSHPassw
I had to tweak the XML used in tests in xmlobjects_test.go because the examples (I /think/, not my doing) where taken straight out of the documentation and are not actually valid (for instance the value for the ports where not integers).
Drive-by fixes:
- display the host/username/
- add the GeoReplicated stuff as a parameter
Jeroen T. Vermeulen (jtv) wrote : | # |
Raphaël Badin (rvb) wrote : | # |
> Is it really worth adding GeoReplicationE
> NewCreateStorag
> from "I want optional and named parameters for my function" to "I'll use a
> Parameter Object" to "I need a constructor for my Parameter Object" to "I want
> another parameter added to the constructor" to "my constructor needs a
> Parameter Object."
>
> So unless we need to set the GeoReplicationE
> something fundamentally dangerous that requires an explicit choice, I'd just
> make NewCreateStorag
> to either "false" or "true," whichever makes more sense. Or if you do make it
> a parameter, then IMO at least the constructor should take a boolean so that
> the caller can ignore the weirdness in the field's type!
You've right, I forgot to say *why* I thought it was important: the geo replication has a very high cost (dixit Scott) and thus I thought that it would be better to force the user to explicitly set it.
Jeroen T. Vermeulen (jtv) wrote : | # |
Also, why only retrieve deployment information in the optional "pause" bit? Isn't this something you might as well do anyway, as part of the test?
Arguably it's not useful if you're not pausing, but then again the same goes for creating the virtual machine in the first place. :) If shutdown fails, for example, you might still want to have a closer look at the instance, perhaps using the information you got from GetDeployment.
Finally, would it be worth adding a few words of how-and-
- 152. By Raphaël Badin
-
Review fixes.
- 153. By Raphaël Badin
-
Remove test data.
Raphaël Badin (rvb) wrote : | # |
> Also, why only retrieve deployment information in the optional "pause" bit?
> Isn't this something you might as well do anyway, as part of the test?
>
> Arguably it's not useful if you're not pausing, but then again the same goes
> for creating the virtual machine in the first place. :) If shutdown fails,
> for example, you might still want to have a closer look at the instance,
> perhaps using the information you got from GetDeployment.
Very true, fixed.
> Finally, would it be worth adding a few words of how-and-
> documentation to ConfigurationSet?
Done.
Thanks for the review!
Julian Edwards (julian-edwards) wrote : | # |
On 02/07/13 20:44, Raphaël Badin wrote:
> I changed the DisableSSHPassw
FWIW, this really is shouting that LinuxProvisioni
the same as a generic ConfigurationSet at all ... which is why I did it
that way to start with.
Preview Diff
1 | === modified file 'example/management/run.go' |
2 | --- example/management/run.go 2013-07-02 00:33:52 +0000 |
3 | +++ example/management/run.go 2013-07-02 13:56:26 +0000 |
4 | @@ -139,14 +139,16 @@ |
5 | // test with your instance, so we'll use a fixed one. It's not really a |
6 | // security hazard in such a short-lived private instance. |
7 | password := "Ubuntu123" |
8 | + username := "ubuntu" |
9 | vhdName := makeRandomIdentifier("gwacldisk", 16) |
10 | - configurationSet := gwacl.NewLinuxProvisioningConfiguration(hostname, "ubuntu", password, "TEST_USER_DATA", false) |
11 | + linuxConfigurationSet := gwacl.NewLinuxProvisioningConfiguration(hostname, username, password, "TEST_USER_DATA", "false") |
12 | + inputendpoint := gwacl.InputEndpoint{LocalPort: 22, Name: "sshport", Port: 22, Protocol: "TCP"} |
13 | + networkConfigurationSet := gwacl.NewNetworkConfiguration([]gwacl.InputEndpoint{inputendpoint}) |
14 | |
15 | storageAccount := makeRandomIdentifier("gwacl", 24) |
16 | storageLabel := makeRandomIdentifier("gwacl", 64) |
17 | fmt.Printf("Requesting storage account with name '%s' and label '%s'...\n", storageAccount, storageLabel) |
18 | - cssi := gwacl.NewCreateStorageServiceInputWithLocation(storageAccount, storageLabel, location) |
19 | - cssi.GeoReplicationEnabled = "false" |
20 | + cssi := gwacl.NewCreateStorageServiceInputWithLocation(storageAccount, storageLabel, location, "false") |
21 | err = api.AddStorageAccount(cssi) |
22 | checkError(err) |
23 | fmt.Println("Done requesting storage account\n") |
24 | @@ -162,7 +164,7 @@ |
25 | diskLabel := makeRandomIdentifier("gwacl", 64) |
26 | vhd := gwacl.NewOSVirtualHardDisk("", diskLabel, diskName, mediaLink, sourceImageName, "Linux") |
27 | roleName := makeRandomIdentifier("gwaclrole", 16) |
28 | - role := gwacl.NewRole("ExtraSmall", roleName, []gwacl.LinuxProvisioningConfiguration{*configurationSet}, []gwacl.OSVirtualHardDisk{*vhd}) |
29 | + role := gwacl.NewRole("ExtraSmall", roleName, []gwacl.ConfigurationSet{*linuxConfigurationSet, *networkConfigurationSet}, []gwacl.OSVirtualHardDisk{*vhd}) |
30 | machineName := makeRandomIdentifier("gwaclmachine", 20) |
31 | deployment := gwacl.NewDeploymentForCreateVMDeployment(machineName, "Staging", machineName, []gwacl.Role{*role}, "") |
32 | err = api.AddDeployment(deployment, hostServiceName) |
33 | @@ -201,6 +203,19 @@ |
34 | fmt.Printf("Got %d instance(s)\n", len(instances)) |
35 | fmt.Println("Done listing VM\n") |
36 | |
37 | + fmt.Println("Getting deployment info...") |
38 | + request := &gwacl.GetDeploymentRequest{ServiceName: hostServiceName, DeploymentName: machineName} |
39 | + deploy, err := api.GetDeployment(request) |
40 | + checkError(err) |
41 | + fqdn, err := deploy.GetFQDN() |
42 | + checkError(err) |
43 | + fmt.Println("Got deployment info\n") |
44 | + |
45 | + fmt.Println("host:", fqdn) |
46 | + fmt.Println("username:", username) |
47 | + fmt.Println("password:", password) |
48 | + fmt.Println("") |
49 | + |
50 | if pause { |
51 | var wait string |
52 | fmt.Println("Pausing so you can play with the newly-created VM") |
53 | |
54 | === modified file 'helpers_apiobjects_test.go' |
55 | --- helpers_apiobjects_test.go 2013-06-28 00:14:46 +0000 |
56 | +++ helpers_apiobjects_test.go 2013-07-02 13:56:26 +0000 |
57 | @@ -42,20 +42,13 @@ |
58 | Protocol: params.protocol} |
59 | } |
60 | |
61 | -func makeLinuxProvisioningConfiguration() *LinuxProvisioningConfiguration { |
62 | +func makeLinuxProvisioningConfiguration() *ConfigurationSet { |
63 | hostname := MakeRandomString(10) |
64 | username := MakeRandomString(10) |
65 | password := MakeRandomString(10) |
66 | userdata := MakeRandomString(10) |
67 | - disableSSH := MakeRandomBool() |
68 | - |
69 | - return &LinuxProvisioningConfiguration{ |
70 | - ConfigurationSetType: "LinuxProvisioningConfiguration", |
71 | - Hostname: hostname, |
72 | - Username: username, |
73 | - Password: password, |
74 | - UserData: userdata, |
75 | - DisableSSHPasswordAuthentication: disableSSH} |
76 | + disableSSH := BoolToString(MakeRandomBool()) |
77 | + return NewLinuxProvisioningConfiguration(hostname, username, password, userdata, disableSSH) |
78 | } |
79 | |
80 | func makeOSVirtualHardDisk() *OSVirtualHardDisk { |
81 | @@ -78,7 +71,7 @@ |
82 | RoleName := MakeRandomString(10) |
83 | RoleType := "PersistentVMRole" |
84 | config := makeLinuxProvisioningConfiguration() |
85 | - configset := []LinuxProvisioningConfiguration{*config} |
86 | + configset := []ConfigurationSet{*config} |
87 | |
88 | return &Role{ |
89 | RoleSize: RoleSize, |
90 | |
91 | === modified file 'management_base_test.go' |
92 | --- management_base_test.go 2013-07-01 01:14:04 +0000 |
93 | +++ management_base_test.go 2013-07-02 13:56:26 +0000 |
94 | @@ -495,9 +495,9 @@ |
95 | api := makeAPI(c) |
96 | recordedRequests := setUpDispatcher("operationID") |
97 | serviceName := "serviceName" |
98 | - configurationSet := NewLinuxProvisioningConfiguration("testHostname12345", "test", "test123#@!", "user-data", false) |
99 | + configurationSet := NewLinuxProvisioningConfiguration("testHostname12345", "test", "test123#@!", "user-data", "false") |
100 | vhd := NewOSVirtualHardDisk("hostCaching", "diskLabel", "diskName", "http://mediaLink", "sourceImageName", "os") |
101 | - role := NewRole("ExtraSmall", "test-role-123", []LinuxProvisioningConfiguration{*configurationSet}, []OSVirtualHardDisk{*vhd}) |
102 | + role := NewRole("ExtraSmall", "test-role-123", []ConfigurationSet{*configurationSet}, []OSVirtualHardDisk{*vhd}) |
103 | deployment := NewDeploymentForCreateVMDeployment("test-machine-name", "Staging", "testLabel", []Role{*role}, "testNetwork") |
104 | err := api.AddDeployment(deployment, serviceName) |
105 | |
106 | @@ -629,7 +629,7 @@ |
107 | rigFixedResponseDispatcher(&fixedResponse) |
108 | recordedRequests := make([]*X509Request, 0) |
109 | rigRecordingDispatcher(&recordedRequests) |
110 | - cssi := NewCreateStorageServiceInputWithLocation("name", "label", "East US") |
111 | + cssi := NewCreateStorageServiceInputWithLocation("name", "label", "East US", "false") |
112 | |
113 | err := api.AddStorageAccount(cssi) |
114 | c.Assert(err, IsNil) |
115 | |
116 | === modified file 'xmlobjects.go' |
117 | --- xmlobjects.go 2013-07-02 06:08:22 +0000 |
118 | +++ xmlobjects.go 2013-07-02 13:56:26 +0000 |
119 | @@ -36,31 +36,48 @@ |
120 | } |
121 | |
122 | // |
123 | -// LinuxProvisioningConfiguration bits |
124 | +// ConfigurationSet bits |
125 | // |
126 | |
127 | -// TODO: this should contain InputEndpoints objects. |
128 | -type LinuxProvisioningConfiguration struct { |
129 | - ConfigurationSetType string `xml:"ConfigurationSetType"` // "LinuxProvisioningConfiguration" |
130 | - Hostname string `xml:"HostName"` |
131 | - Username string `xml:"UserName"` |
132 | - Password string `xml:"UserPassword"` |
133 | - UserData string `xml:"UserData"` |
134 | - DisableSSHPasswordAuthentication bool `xml:"DisableSshPasswordAuthentication"` |
135 | -} |
136 | - |
137 | -func (c *LinuxProvisioningConfiguration) Serialize() (string, error) { |
138 | +// A ConfigurationSet object can be different things depending on its 'type'. |
139 | +// The types we currently support are: |
140 | +// - LinuxProvisioningConfigurationSet: configuration of a Linux VM |
141 | +// - NetworkConfiguration: configuration of the network of a VM |
142 | +type ConfigurationSet struct { |
143 | + ConfigurationSetType string `xml:"ConfigurationSetType"` // "ConfigurationSet" |
144 | + |
145 | + // LinuxProvisioningConfiguration fields. |
146 | + Hostname string `xml:"HostName,omitempty"` |
147 | + Username string `xml:"UserName,omitempty"` |
148 | + Password string `xml:"UserPassword,omitempty"` |
149 | + UserData string `xml:"UserData,omitempty"` |
150 | + DisableSSHPasswordAuthentication string `xml:"DisableSshPasswordAuthentication,omitempty"` |
151 | + |
152 | + // NetworkConfiguration fields. |
153 | + // We use a pointer in the 'InputEndpoints' field to work around bug: |
154 | + // https://code.google.com/p/go/issues/detail?id=4168 |
155 | + // We need the whole 'InputEndpoints' element to be omitted when no InputEndpoint objects are |
156 | + // present (this happens when the ConfigurationSet object has a |
157 | + // LinuxProvisioningConfiguration type for instance). |
158 | + InputEndpoints *[]InputEndpoint `xml:"InputEndpoints>InputEndpoint,omitempty"` |
159 | +} |
160 | + |
161 | +func (c *ConfigurationSet) inputEndpoints() []InputEndpoint { |
162 | + return *c.InputEndpoints |
163 | +} |
164 | + |
165 | +func (c *ConfigurationSet) Serialize() (string, error) { |
166 | return toxml(c) |
167 | } |
168 | |
169 | -// NewLinuxProvisioningConfiguration creates and returns a |
170 | -// LinuxProvisioningConfiguration which is used when deploying a Linux VM |
171 | -// instance. Note that UserData is passed to Azure *as-is* which also stores |
172 | -// it as passed, so consider base64 encoding it. |
173 | +// NewLinuxProvisioningConfiguration creates and returns a ConfigurationSet of type |
174 | +// "LinuxProvisioningConfiguration" which is used when deploying a Linux VM instance. |
175 | +// Note that UserData is passed to Azure *as-is* which also stores it as passed, so consider |
176 | +// base64 encoding it. |
177 | func NewLinuxProvisioningConfiguration( |
178 | Hostname, Username, Password, UserData string, |
179 | - DisableSSHPasswordAuthentication bool) *LinuxProvisioningConfiguration { |
180 | - return &LinuxProvisioningConfiguration{ |
181 | + DisableSSHPasswordAuthentication string) *ConfigurationSet { |
182 | + return &ConfigurationSet{ |
183 | ConfigurationSetType: "LinuxProvisioningConfiguration", |
184 | Hostname: Hostname, |
185 | Username: Username, |
186 | @@ -70,12 +87,21 @@ |
187 | } |
188 | } |
189 | |
190 | +// NewNetworkConfiguration creates a ConfigurationSet of type "NetworkConfiguration". |
191 | +func NewNetworkConfiguration( |
192 | + inputEndpoints []InputEndpoint) *ConfigurationSet { |
193 | + return &ConfigurationSet{ |
194 | + ConfigurationSetType: "NetworkConfiguration", |
195 | + InputEndpoints: &inputEndpoints, |
196 | + } |
197 | +} |
198 | + |
199 | // |
200 | // InputEndpoint bits |
201 | // |
202 | |
203 | type InputEndpoint struct { |
204 | - LoadBalancedEndpointSetName string `xml:"LoadBalancedEndpointSetName"` |
205 | + LoadBalancedEndpointSetName string `xml:"LoadBalancedEndpointSetName,omitempty"` |
206 | LocalPort int `xml:"LocalPort"` |
207 | Name string `xml:"Name"` |
208 | Port int `xml:"Port"` |
209 | @@ -245,24 +271,12 @@ |
210 | } |
211 | } |
212 | |
213 | -// |
214 | -// NetworkConfiguration bits |
215 | -// |
216 | - |
217 | -type NetworkConfiguration struct { |
218 | - InputEndpoints []InputEndpoint `xml:"InputEndpoints>InputEndpoint"` |
219 | -} |
220 | - |
221 | -func (c *NetworkConfiguration) Serialize() (string, error) { |
222 | - return toxml(c) |
223 | -} |
224 | - |
225 | type Role struct { |
226 | - RoleName string `xml:"RoleName"` |
227 | - RoleType string `xml:"RoleType"` // Always "PersistentVMRole" |
228 | - ConfigurationSets []LinuxProvisioningConfiguration `xml:"ConfigurationSets>ConfigurationSet"` |
229 | - OSVirtualHardDisk []OSVirtualHardDisk `xml:"OSVirtualHardDisk"` |
230 | - RoleSize string `xml:"RoleSize"` |
231 | + RoleName string `xml:"RoleName"` |
232 | + RoleType string `xml:"RoleType"` // Always "PersistentVMRole" |
233 | + ConfigurationSets []ConfigurationSet `xml:"ConfigurationSets>ConfigurationSet"` |
234 | + OSVirtualHardDisk []OSVirtualHardDisk `xml:"OSVirtualHardDisk"` |
235 | + RoleSize string `xml:"RoleSize"` |
236 | } |
237 | |
238 | // |
239 | @@ -274,7 +288,7 @@ |
240 | } |
241 | |
242 | func NewRole(RoleSize string, RoleName string, |
243 | - ConfigurationSets []LinuxProvisioningConfiguration, vhds []OSVirtualHardDisk) *Role { |
244 | + ConfigurationSets []ConfigurationSet, vhds []OSVirtualHardDisk) *Role { |
245 | return &Role{ |
246 | RoleSize: RoleSize, |
247 | RoleName: RoleName, |
248 | @@ -560,12 +574,13 @@ |
249 | |
250 | // NewCreateStorageServiceInputWithLocation creates a location-based |
251 | // CreateStorageServiceInput, with all required fields filled out. |
252 | -func NewCreateStorageServiceInputWithLocation(name, label, location string) *CreateStorageServiceInput { |
253 | +func NewCreateStorageServiceInputWithLocation(name, label, location string, geoReplicationEnabled string) *CreateStorageServiceInput { |
254 | return &CreateStorageServiceInput{ |
255 | - XMLNS: XMLNS, |
256 | - ServiceName: name, |
257 | - Label: base64.StdEncoding.EncodeToString([]byte(label)), |
258 | - Location: location, |
259 | + XMLNS: XMLNS, |
260 | + ServiceName: name, |
261 | + Label: base64.StdEncoding.EncodeToString([]byte(label)), |
262 | + Location: location, |
263 | + GeoReplicationEnabled: geoReplicationEnabled, |
264 | } |
265 | } |
266 | |
267 | |
268 | === modified file 'xmlobjects_test.go' |
269 | --- xmlobjects_test.go 2013-07-02 06:08:22 +0000 |
270 | +++ xmlobjects_test.go 2013-07-02 13:56:26 +0000 |
271 | @@ -20,20 +20,20 @@ |
272 | // Tests for Marshallers |
273 | // |
274 | |
275 | -func (suite *xmlSuite) TestLinuxProvisioningConfiguration(c *C) { |
276 | +func (suite *xmlSuite) TestConfigurationSet(c *C) { |
277 | config := makeLinuxProvisioningConfiguration() |
278 | |
279 | xml, err := config.Serialize() |
280 | c.Assert(err, IsNil) |
281 | template := dedent.Dedent(` |
282 | - <LinuxProvisioningConfiguration> |
283 | + <ConfigurationSet> |
284 | <ConfigurationSetType>LinuxProvisioningConfiguration</ConfigurationSetType> |
285 | <HostName>%s</HostName> |
286 | <UserName>%s</UserName> |
287 | <UserPassword>%s</UserPassword> |
288 | <UserData>%s</UserData> |
289 | <DisableSshPasswordAuthentication>%v</DisableSshPasswordAuthentication> |
290 | - </LinuxProvisioningConfiguration>`) |
291 | + </ConfigurationSet>`) |
292 | expected := fmt.Sprintf(template, config.Hostname, config.Username, |
293 | config.Password, config.UserData, |
294 | config.DisableSSHPasswordAuthentication) |
295 | @@ -76,16 +76,16 @@ |
296 | c.Check(xml, Equals, expected) |
297 | } |
298 | |
299 | -func (suite *xmlSuite) TestNetworkConfiguration(c *C) { |
300 | +func (suite *xmlSuite) TestConfigurationSetNetworkConfiguration(c *C) { |
301 | endpoint1 := makeEndpoint(endpointParams{}) |
302 | endpoint2 := makeEndpoint(endpointParams{}) |
303 | endpoints := []InputEndpoint{*endpoint1, *endpoint2} |
304 | - config := &NetworkConfiguration{ |
305 | - InputEndpoints: endpoints} |
306 | + config := NewNetworkConfiguration(endpoints) |
307 | xml, err := config.Serialize() |
308 | c.Assert(err, IsNil) |
309 | template := dedent.Dedent(` |
310 | - <NetworkConfiguration> |
311 | + <ConfigurationSet> |
312 | + <ConfigurationSetType>NetworkConfiguration</ConfigurationSetType> |
313 | <InputEndpoints> |
314 | <InputEndpoint> |
315 | <LoadBalancedEndpointSetName>%s</LoadBalancedEndpointSetName> |
316 | @@ -102,7 +102,7 @@ |
317 | <Protocol>%s</Protocol> |
318 | </InputEndpoint> |
319 | </InputEndpoints> |
320 | - </NetworkConfiguration>`) |
321 | + </ConfigurationSet>`) |
322 | expected := fmt.Sprintf(template, endpoint1.LoadBalancedEndpointSetName, |
323 | endpoint1.LocalPort, endpoint1.Name, endpoint1.Port, |
324 | endpoint1.Protocol, endpoint2.LoadBalancedEndpointSetName, |
325 | @@ -351,14 +351,8 @@ |
326 | <OsVersion>operating-system-version</OsVersion> |
327 | <ConfigurationSets> |
328 | <ConfigurationSet> |
329 | - <ConfigurationSetType>NetworkConfiguration</ConfigurationSetType> |
330 | - <InputEndpoints> |
331 | - <InputEndpoint> |
332 | - <Port>port-number-of-input-endpoint-in-network</Port> |
333 | - <Protocol>protocol-of-input-endpoint-in-network</Protocol> |
334 | - <Vip>virtual-ip-address-of-input-endpoint-in-network</Vip> |
335 | - </InputEndpoint> |
336 | - </InputEndpoints> |
337 | + <ConfigurationSetType>LinuxProvisioningConfiguration</ConfigurationSetType> |
338 | + <DisableSshPasswordAuthentication>false</DisableSshPasswordAuthentication> |
339 | </ConfigurationSet> |
340 | </ConfigurationSets> |
341 | </Role> |
342 | @@ -369,21 +363,14 @@ |
343 | <ConfigurationSets> |
344 | <ConfigurationSet> |
345 | <ConfigurationSetType>NetworkConfiguration</ConfigurationSetType> |
346 | - <InputEndpoints> |
347 | - <InputEndpoint> |
348 | - <LoadBalancedEndpointSetName>name-of-load-balanced-endpoint-set</LoadBalancedEndpointSetName> |
349 | - <LocalPort>internal-facing-port-of-input-endpoint</LocalPort> |
350 | - <Name>name-of-input-endpoint</Name> |
351 | - <Port>external-facing-port-of-input-endpoint</Port> |
352 | - <LoadBalancerProbe> |
353 | - <Path>path-of-probe</Path> |
354 | - <Port>port-assigned-to-probe</Port> |
355 | - <Protocol>protocol-of-probe-port</Protocol> |
356 | - </LoadBalancerProbe> |
357 | - <Protocol>protocol-of-input-endpoint</Protocol> |
358 | - <Vip>virtual-ip-address-of-input-endpoint</Vip> |
359 | - </InputEndpoint> |
360 | - </InputEndpoints> |
361 | + <InputEndpoints> |
362 | + <InputEndpoint> |
363 | + <Port>2222</Port> |
364 | + <LocalPort>111</LocalPort> |
365 | + <Protocol>TCP</Protocol> |
366 | + <Name>test-name</Name> |
367 | + </InputEndpoint> |
368 | + </InputEndpoints> |
369 | <SubnetNames> |
370 | <SubnetName>name-of-subnet</SubnetName> |
371 | </SubnetNames> |
372 | @@ -498,20 +485,27 @@ |
373 | RoleList: []Role{ |
374 | { |
375 | RoleName: "name-of-role", |
376 | - ConfigurationSets: []LinuxProvisioningConfiguration{ |
377 | + ConfigurationSets: []ConfigurationSet{ |
378 | { |
379 | - ConfigurationSetType: "NetworkConfiguration", |
380 | - DisableSSHPasswordAuthentication: false, |
381 | + ConfigurationSetType: "LinuxProvisioningConfiguration", |
382 | + DisableSSHPasswordAuthentication: "false", |
383 | }, |
384 | }, |
385 | }, |
386 | { |
387 | RoleName: "name-of-role", |
388 | RoleType: "PersistentVMRole", |
389 | - ConfigurationSets: []LinuxProvisioningConfiguration{ |
390 | + ConfigurationSets: []ConfigurationSet{ |
391 | { |
392 | - ConfigurationSetType: "NetworkConfiguration", |
393 | - DisableSSHPasswordAuthentication: false, |
394 | + ConfigurationSetType: "NetworkConfiguration", |
395 | + InputEndpoints: &[]InputEndpoint{ |
396 | + { |
397 | + Name: "test-name", |
398 | + Port: 2222, |
399 | + LocalPort: 111, |
400 | + Protocol: "TCP", |
401 | + }, |
402 | + }, |
403 | }, |
404 | }, |
405 | OSVirtualHardDisk: []OSVirtualHardDisk{ |
406 | @@ -597,7 +591,7 @@ |
407 | deploymentSlot := "staging" |
408 | label := "deploymentLabel" |
409 | vhd := NewOSVirtualHardDisk("hostCaching", "diskLabel", "diskName", "mediaLink", "sourceImageName", "os") |
410 | - roles := []Role{*NewRole("size", "name", []LinuxProvisioningConfiguration{}, []OSVirtualHardDisk{*vhd})} |
411 | + roles := []Role{*NewRole("size", "name", []ConfigurationSet{}, []OSVirtualHardDisk{*vhd})} |
412 | virtualNetworkName := "network" |
413 | |
414 | deployment := NewDeploymentForCreateVMDeployment(name, deploymentSlot, label, roles, virtualNetworkName) |
415 | @@ -853,7 +847,7 @@ |
416 | rolesize := MakeRandomString(10) |
417 | rolename := MakeRandomString(10) |
418 | config := makeLinuxProvisioningConfiguration() |
419 | - configset := []LinuxProvisioningConfiguration{*config} |
420 | + configset := []ConfigurationSet{*config} |
421 | vhd := NewOSVirtualHardDisk("hostCaching", "diskLabel", "diskName", "mediaLink", "sourceImageName", "os") |
422 | |
423 | role := NewRole(rolesize, rolename, configset, []OSVirtualHardDisk{*vhd}) |
424 | @@ -867,8 +861,8 @@ |
425 | hostname := MakeRandomString(10) |
426 | username := MakeRandomString(10) |
427 | password := MakeRandomString(10) |
428 | + disablessh := BoolToString(MakeRandomBool()) |
429 | userdata := MakeRandomString(10) |
430 | - disablessh := MakeRandomBool() |
431 | |
432 | config := NewLinuxProvisioningConfiguration( |
433 | hostname, username, password, userdata, disablessh) |
434 | @@ -880,6 +874,27 @@ |
435 | c.Check(config.ConfigurationSetType, Equals, "LinuxProvisioningConfiguration") |
436 | } |
437 | |
438 | +func (suite *xmlSuite) TestNewNetworkConfiguration(c *C) { |
439 | + name := "name1" |
440 | + port := 242 |
441 | + localPort := 922 |
442 | + protocol := "TCP" |
443 | + bName := "bname1" |
444 | + inputendpoint := InputEndpoint{ |
445 | + LoadBalancedEndpointSetName: bName, LocalPort: localPort, Name: name, Port: port, Protocol: protocol} |
446 | + |
447 | + config := NewNetworkConfiguration([]InputEndpoint{inputendpoint}) |
448 | + inputEndpoints := *config.InputEndpoints |
449 | + c.Check(len(inputEndpoints), Equals, 1) |
450 | + inputEndpoint := inputEndpoints[0] |
451 | + c.Check(inputEndpoint.Name, Equals, name) |
452 | + c.Check(inputEndpoint.Port, Equals, port) |
453 | + c.Check(inputEndpoint.Protocol, Equals, protocol) |
454 | + c.Check(inputEndpoint.LoadBalancedEndpointSetName, Equals, bName) |
455 | + c.Check(inputEndpoint.LocalPort, Equals, localPort) |
456 | + c.Check(config.ConfigurationSetType, Equals, "NetworkConfiguration") |
457 | +} |
458 | + |
459 | func (suite *xmlSuite) TestNewOSVirtualHardDisk(c *C) { |
460 | var hostcaching HostCachingType = "ReadWrite" |
461 | disklabel := MakeRandomString(10) |
462 | @@ -1110,11 +1125,12 @@ |
463 | } |
464 | |
465 | func (suite *xmlSuite) TestNewCreateStorageServiceInputWithLocation(c *C) { |
466 | - cssi := NewCreateStorageServiceInputWithLocation("name", "label", "location") |
467 | + cssi := NewCreateStorageServiceInputWithLocation("name", "label", "location", "false") |
468 | c.Check(cssi.XMLNS, Equals, XMLNS) |
469 | c.Check(cssi.ServiceName, Equals, "name") |
470 | c.Check(cssi.Label, Equals, base64.StdEncoding.EncodeToString([]byte("label"))) |
471 | c.Check(cssi.Location, Equals, "location") |
472 | + c.Check(cssi.GeoReplicationEnabled, Equals, "false") |
473 | } |
474 | |
475 | func (suite *xmlSuite) TestBlockListSerialize(c *C) { |
Is it really worth adding GeoReplicationE nabled as a parameter to NewCreateStorag eServiceInputWi thLocation? Go puts you on this slippery slope from "I want optional and named parameters for my function" to "I'll use a Parameter Object" to "I need a constructor for my Parameter Object" to "I want another parameter added to the constructor" to "my constructor needs a Parameter Object."
So unless we need to set the GeoReplicationE nabled all the time, or there is something fundamentally dangerous that requires an explicit choice, I'd just make NewCreateStorag eServiceInputWi thLocation initialize GeoReplicationE nabled to either "false" or "true," whichever makes more sense. Or if you do make it a parameter, then IMO at least the constructor should take a boolean so that the caller can ignore the weirdness in the field's type!