Merge lp:~axwalk/gwacl/add-delete-role into lp:gwacl
- add-delete-role
- Merge into trunk
Status: | Superseded |
---|---|
Proposed branch: | lp:~axwalk/gwacl/add-delete-role |
Merge into: | lp:gwacl |
Diff against target: |
505 lines (+212/-53) 9 files modified
example/management/run.go (+2/-3) management.go (+1/-3) management_base.go (+51/-0) management_base_test.go (+71/-1) management_test.go (+6/-10) x509dispatcher.go (+14/-2) x509dispatcher_test.go (+25/-0) xmlobjects.go (+19/-21) xmlobjects_test.go (+23/-13) |
To merge this branch: | bzr merge lp:~axwalk/gwacl/add-delete-role |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
GWACL Hackers | Pending | ||
Review via email: mp+210120@code.launchpad.net |
This proposal has been superseded by a proposal from 2014-03-10.
Commit message
Description of the change
Introduce AddRole, DeleteRole; add missing Role fields
Two more management service API methods are added: AddRole
and DeleteRole (operating on deployments). These are
required when working with Availability Sets, where a role
must be added to an existing Cloud Service.
PersistentVMRole has been changed to be an alias for Role,
which has been expanded to include missing fields.
PersistentVMRole continues to have its own serialisation
methods, so it gets the correct XML tag name and namespace.
Roles can only have a single OS disk, so I've changed the
signature of NewRole to reflect this. Roles may have
additional data disks.
- 234. By Andrew Wilkins
-
Fix copy and paste error
Unmerged revisions
Preview Diff
1 | === modified file 'example/management/run.go' | |||
2 | --- example/management/run.go 2013-10-31 08:10:35 +0000 | |||
3 | +++ example/management/run.go 2014-03-10 04:06:20 +0000 | |||
4 | @@ -214,9 +214,8 @@ | |||
5 | 214 | diskLabel := makeRandomIdentifier("gwacl", 64) | 214 | diskLabel := makeRandomIdentifier("gwacl", 64) |
6 | 215 | vhd := gwacl.NewOSVirtualHardDisk("", diskLabel, diskName, mediaLink, sourceImageName, "Linux") | 215 | vhd := gwacl.NewOSVirtualHardDisk("", diskLabel, diskName, mediaLink, sourceImageName, "Linux") |
7 | 216 | roleName := gwacl.MakeRandomRoleName("gwaclrole") | 216 | roleName := gwacl.MakeRandomRoleName("gwaclrole") |
11 | 217 | role := gwacl.NewRole("ExtraSmall", roleName, | 217 | role := gwacl.NewRole("ExtraSmall", roleName, vhd, |
12 | 218 | []gwacl.ConfigurationSet{*linuxConfigurationSet, *networkConfigurationSet}, | 218 | []gwacl.ConfigurationSet{*linuxConfigurationSet, *networkConfigurationSet}) |
10 | 219 | []gwacl.OSVirtualHardDisk{*vhd}) | ||
13 | 220 | machineName := makeRandomIdentifier("gwaclmachine", 20) | 219 | machineName := makeRandomIdentifier("gwaclmachine", 20) |
14 | 221 | deployment := gwacl.NewDeploymentForCreateVMDeployment( | 220 | deployment := gwacl.NewDeploymentForCreateVMDeployment( |
15 | 222 | machineName, "Production", machineName, []gwacl.Role{*role}, virtualNetworkName) | 221 | machineName, "Production", machineName, []gwacl.Role{*role}, virtualNetworkName) |
16 | 223 | 222 | ||
17 | === modified file 'management.go' | |||
18 | --- management.go 2013-08-28 00:13:04 +0000 | |||
19 | +++ management.go 2014-03-10 04:06:20 +0000 | |||
20 | @@ -140,9 +140,7 @@ | |||
21 | 140 | // 1. Get the list of the VM disks. | 140 | // 1. Get the list of the VM disks. |
22 | 141 | diskNameMap := make(map[string]bool) | 141 | diskNameMap := make(map[string]bool) |
23 | 142 | for _, role := range deployment.RoleList { | 142 | for _, role := range deployment.RoleList { |
27 | 143 | for _, osVHD := range role.OSVirtualHardDisk { | 143 | diskNameMap[role.OSVirtualHardDisk.DiskName] = true |
25 | 144 | diskNameMap[osVHD.DiskName] = true | ||
26 | 145 | } | ||
28 | 146 | } | 144 | } |
29 | 147 | // 2. Delete deployment. This will delete all the role instances inside | 145 | // 2. Delete deployment. This will delete all the role instances inside |
30 | 148 | // this deployment as a side effect. | 146 | // this deployment as a side effect. |
31 | 149 | 147 | ||
32 | === modified file 'management_base.go' | |||
33 | --- management_base.go 2013-10-31 04:16:38 +0000 | |||
34 | +++ management_base.go 2014-03-10 04:06:20 +0000 | |||
35 | @@ -474,6 +474,57 @@ | |||
36 | 474 | return api.blockUntilCompleted(response) | 474 | return api.blockUntilCompleted(response) |
37 | 475 | } | 475 | } |
38 | 476 | 476 | ||
39 | 477 | type DeleteRoleRequest struct { | ||
40 | 478 | ServiceName string | ||
41 | 479 | DeploymentName string | ||
42 | 480 | RoleName string | ||
43 | 481 | DeleteMedia bool | ||
44 | 482 | } | ||
45 | 483 | |||
46 | 484 | // DeleteRole deletes a named Role from within the specified Cloud Service | ||
47 | 485 | // and Deployment. | ||
48 | 486 | // See http://msdn.microsoft.com/en-us/library/windowsazure/jj157187.aspx | ||
49 | 487 | func (api *ManagementAPI) DeleteRole(request *DeleteRoleRequest) error { | ||
50 | 488 | checkPathComponents(request.ServiceName, request.DeploymentName, request.RoleName) | ||
51 | 489 | url := ("services/hostedservices/" + request.ServiceName + | ||
52 | 490 | "/deployments/" + request.DeploymentName + "/roles/" + request.RoleName) | ||
53 | 491 | if request.DeleteMedia { | ||
54 | 492 | url = addURLQueryParams(url, "comp", "media") | ||
55 | 493 | } | ||
56 | 494 | response, err := api.session.delete(url, "2013-08-01") | ||
57 | 495 | if err != nil { | ||
58 | 496 | if IsNotFoundError(err) { | ||
59 | 497 | return nil | ||
60 | 498 | } | ||
61 | 499 | return err | ||
62 | 500 | } | ||
63 | 501 | return api.blockUntilCompleted(response) | ||
64 | 502 | } | ||
65 | 503 | |||
66 | 504 | type AddRoleRequest struct { | ||
67 | 505 | ServiceName string | ||
68 | 506 | DeploymentName string | ||
69 | 507 | PersistentVMRole *PersistentVMRole | ||
70 | 508 | } | ||
71 | 509 | |||
72 | 510 | // AddRole creates a new Role within the specified Cloud Service | ||
73 | 511 | // and Deployment. | ||
74 | 512 | // See http://msdn.microsoft.com/en-us/library/windowsazure/jj157187.aspx | ||
75 | 513 | func (api *ManagementAPI) AddRole(request *AddRoleRequest) error { | ||
76 | 514 | checkPathComponents(request.ServiceName, request.DeploymentName) | ||
77 | 515 | url := ("services/hostedservices/" + request.ServiceName + | ||
78 | 516 | "/deployments/" + request.DeploymentName + "/roles") | ||
79 | 517 | role, err := request.PersistentVMRole.Serialize() | ||
80 | 518 | if err != nil { | ||
81 | 519 | return err | ||
82 | 520 | } | ||
83 | 521 | response, err := api.session.post(url, "2013-10-01", []byte(role), "application/xml") | ||
84 | 522 | if err != nil { | ||
85 | 523 | return err | ||
86 | 524 | } | ||
87 | 525 | return api.blockUntilCompleted(response) | ||
88 | 526 | } | ||
89 | 527 | |||
90 | 477 | type CreateAffinityGroupRequest struct { | 528 | type CreateAffinityGroupRequest struct { |
91 | 478 | CreateAffinityGroup *CreateAffinityGroup | 529 | CreateAffinityGroup *CreateAffinityGroup |
92 | 479 | } | 530 | } |
93 | 480 | 531 | ||
94 | === modified file 'management_base_test.go' | |||
95 | --- management_base_test.go 2013-10-31 04:16:38 +0000 | |||
96 | +++ management_base_test.go 2014-03-10 04:06:20 +0000 | |||
97 | @@ -681,7 +681,7 @@ | |||
98 | 681 | serviceName := "serviceName" | 681 | serviceName := "serviceName" |
99 | 682 | configurationSet := NewLinuxProvisioningConfigurationSet("testHostname12345", "test", "test123#@!", "user-data", "false") | 682 | configurationSet := NewLinuxProvisioningConfigurationSet("testHostname12345", "test", "test123#@!", "user-data", "false") |
100 | 683 | vhd := NewOSVirtualHardDisk("hostCaching", "diskLabel", "diskName", "http://mediaLink", "sourceImageName", "os") | 683 | vhd := NewOSVirtualHardDisk("hostCaching", "diskLabel", "diskName", "http://mediaLink", "sourceImageName", "os") |
102 | 684 | role := NewRole("ExtraSmall", "test-role-123", []ConfigurationSet{*configurationSet}, []OSVirtualHardDisk{*vhd}) | 684 | role := NewRole("ExtraSmall", "test-role-123", vhd, []ConfigurationSet{*configurationSet}) |
103 | 685 | deployment := NewDeploymentForCreateVMDeployment("test-machine-name", "Staging", "testLabel", []Role{*role}, "testNetwork") | 685 | deployment := NewDeploymentForCreateVMDeployment("test-machine-name", "Staging", "testLabel", []Role{*role}, "testNetwork") |
104 | 686 | err := api.AddDeployment(deployment, serviceName) | 686 | err := api.AddDeployment(deployment, serviceName) |
105 | 687 | 687 | ||
106 | @@ -1109,6 +1109,76 @@ | |||
107 | 1109 | c.Check(recordedRequests[1].URL, Matches, ".*/operations/foobar") | 1109 | c.Check(recordedRequests[1].URL, Matches, ".*/operations/foobar") |
108 | 1110 | } | 1110 | } |
109 | 1111 | 1111 | ||
110 | 1112 | func assertDeleteRoleRequest(c *C, api *ManagementAPI, httpRequest *X509Request, serviceName, deploymentName, roleName string, deleteMedia bool) { | ||
111 | 1113 | expectedURL := (defaultManagement + api.session.subscriptionId + | ||
112 | 1114 | "/services/hostedservices/" + | ||
113 | 1115 | serviceName + "/deployments/" + deploymentName + "/roles/" + roleName) | ||
114 | 1116 | if deleteMedia { | ||
115 | 1117 | expectedURL += "?comp=media" | ||
116 | 1118 | } | ||
117 | 1119 | checkRequest( | ||
118 | 1120 | c, httpRequest, expectedURL, "2013-08-01", nil, "DELETE") | ||
119 | 1121 | } | ||
120 | 1122 | |||
121 | 1123 | func (suite *managementBaseAPISuite) TestDeleteRole(c *C) { | ||
122 | 1124 | suite.testDeleteRole(c, false) | ||
123 | 1125 | } | ||
124 | 1126 | |||
125 | 1127 | func (suite *managementBaseAPISuite) TestDeleteRoleDeleteMedia(c *C) { | ||
126 | 1128 | suite.testDeleteRole(c, true) | ||
127 | 1129 | } | ||
128 | 1130 | |||
129 | 1131 | func (suite *managementBaseAPISuite) testDeleteRole(c *C, deleteMedia bool) { | ||
130 | 1132 | api := makeAPI(c) | ||
131 | 1133 | request := &DeleteRoleRequest{ | ||
132 | 1134 | ServiceName: "serviceName", | ||
133 | 1135 | DeploymentName: "deploymentName", | ||
134 | 1136 | RoleName: "roleName", | ||
135 | 1137 | DeleteMedia: deleteMedia, | ||
136 | 1138 | } | ||
137 | 1139 | rigFixedResponseDispatcher(&x509Response{StatusCode: http.StatusOK}) | ||
138 | 1140 | recordedRequests := make([]*X509Request, 0) | ||
139 | 1141 | rigRecordingDispatcher(&recordedRequests) | ||
140 | 1142 | |||
141 | 1143 | err := api.DeleteRole(request) | ||
142 | 1144 | c.Assert(err, IsNil) | ||
143 | 1145 | assertDeleteRoleRequest( | ||
144 | 1146 | c, api, recordedRequests[0], request.ServiceName, | ||
145 | 1147 | request.DeploymentName, request.RoleName, deleteMedia) | ||
146 | 1148 | } | ||
147 | 1149 | |||
148 | 1150 | func assertAddRoleRequest(c *C, api *ManagementAPI, httpRequest *X509Request, serviceName, deploymentName, expectedXML string) { | ||
149 | 1151 | expectedURL := (defaultManagement + api.session.subscriptionId + | ||
150 | 1152 | "/services/hostedservices/" + | ||
151 | 1153 | serviceName + "/deployments/" + deploymentName + "/roles") | ||
152 | 1154 | checkRequest( | ||
153 | 1155 | c, httpRequest, expectedURL, "2013-10-01", []byte(expectedXML), "POST") | ||
154 | 1156 | c.Assert(httpRequest.ContentType, Equals, "application/xml") | ||
155 | 1157 | } | ||
156 | 1158 | |||
157 | 1159 | func (suite *managementBaseAPISuite) TestAddRole(c *C) { | ||
158 | 1160 | api := makeAPI(c) | ||
159 | 1161 | request := &UpdateRoleRequest{ | ||
160 | 1162 | ServiceName: "serviceName", | ||
161 | 1163 | DeploymentName: "deploymentName", | ||
162 | 1164 | PersistentVMRole: &PersistentVMRole{ | ||
163 | 1165 | RoleName: "newRoleNamePerhaps", | ||
164 | 1166 | }, | ||
165 | 1167 | } | ||
166 | 1168 | rigFixedResponseDispatcher(&x509Response{StatusCode: http.StatusOK}) | ||
167 | 1169 | recordedRequests := make([]*X509Request, 0) | ||
168 | 1170 | rigRecordingDispatcher(&recordedRequests) | ||
169 | 1171 | |||
170 | 1172 | err := api.UpdateRole(request) | ||
171 | 1173 | c.Assert(err, IsNil) | ||
172 | 1174 | |||
173 | 1175 | expectedXML, err := request.PersistentVMRole.Serialize() | ||
174 | 1176 | c.Assert(err, IsNil) | ||
175 | 1177 | assertUpdateRoleRequest( | ||
176 | 1178 | c, api, recordedRequests[0], request.ServiceName, | ||
177 | 1179 | request.DeploymentName, request.RoleName, expectedXML) | ||
178 | 1180 | } | ||
179 | 1181 | |||
180 | 1112 | func (suite *managementBaseAPISuite) TestCreateAffinityGroup(c *C) { | 1182 | func (suite *managementBaseAPISuite) TestCreateAffinityGroup(c *C) { |
181 | 1113 | api := makeAPI(c) | 1183 | api := makeAPI(c) |
182 | 1114 | cag := NewCreateAffinityGroup( | 1184 | cag := NewCreateAffinityGroup( |
183 | 1115 | 1185 | ||
184 | === modified file 'management_test.go' | |||
185 | --- management_test.go 2013-08-28 00:13:04 +0000 | |||
186 | +++ management_test.go 2014-03-10 04:06:20 +0000 | |||
187 | @@ -265,10 +265,8 @@ | |||
188 | 265 | return &Deployment{ | 265 | return &Deployment{ |
189 | 266 | RoleInstanceList: makeNamedRoleInstances("one", "two"), | 266 | RoleInstanceList: makeNamedRoleInstances("one", "two"), |
190 | 267 | RoleList: []Role{ | 267 | RoleList: []Role{ |
195 | 268 | {OSVirtualHardDisk: []OSVirtualHardDisk{ | 268 | {OSVirtualHardDisk: &OSVirtualHardDisk{DiskName: "disk1"}}, |
196 | 269 | {DiskName: "disk1"}, {DiskName: "disk2"}}}, | 269 | {OSVirtualHardDisk: &OSVirtualHardDisk{DiskName: "disk2"}}, |
193 | 270 | {OSVirtualHardDisk: []OSVirtualHardDisk{ | ||
194 | 271 | {DiskName: "disk1"}, {DiskName: "disk3"}}}, | ||
197 | 272 | }, | 270 | }, |
198 | 273 | } | 271 | } |
199 | 274 | } | 272 | } |
200 | @@ -292,14 +290,13 @@ | |||
201 | 292 | } | 290 | } |
202 | 293 | err := api.DestroyDeployment(request) | 291 | err := api.DestroyDeployment(request) |
203 | 294 | c.Assert(err, IsNil) | 292 | c.Assert(err, IsNil) |
205 | 295 | c.Check(record, HasLen, 5) | 293 | c.Check(record, HasLen, 4) |
206 | 296 | assertGetDeploymentRequest(c, api, &GetDeploymentRequest{ | 294 | assertGetDeploymentRequest(c, api, &GetDeploymentRequest{ |
207 | 297 | request.ServiceName, request.DeploymentName}, record[0]) | 295 | request.ServiceName, request.DeploymentName}, record[0]) |
208 | 298 | assertDeleteDeploymentRequest(c, api, request.ServiceName, | 296 | assertDeleteDeploymentRequest(c, api, request.ServiceName, |
209 | 299 | request.DeploymentName, record[1]) | 297 | request.DeploymentName, record[1]) |
210 | 300 | assertDeleteDiskRequest(c, api, "disk1", record[2], true) | 298 | assertDeleteDiskRequest(c, api, "disk1", record[2], true) |
211 | 301 | assertDeleteDiskRequest(c, api, "disk2", record[3], true) | 299 | assertDeleteDiskRequest(c, api, "disk2", record[3], true) |
212 | 302 | assertDeleteDiskRequest(c, api, "disk3", record[4], true) | ||
213 | 303 | } | 300 | } |
214 | 304 | 301 | ||
215 | 305 | func (suite *suiteDestroyDeployment) TestOkayWhenDeploymentNotFound(c *C) { | 302 | func (suite *suiteDestroyDeployment) TestOkayWhenDeploymentNotFound(c *C) { |
216 | @@ -338,14 +335,13 @@ | |||
217 | 338 | } | 335 | } |
218 | 339 | err := api.DestroyDeployment(request) | 336 | err := api.DestroyDeployment(request) |
219 | 340 | c.Assert(err, IsNil) | 337 | c.Assert(err, IsNil) |
221 | 341 | c.Check(record, HasLen, 5) | 338 | c.Check(record, HasLen, 4) |
222 | 342 | assertGetDeploymentRequest(c, api, &GetDeploymentRequest{ | 339 | assertGetDeploymentRequest(c, api, &GetDeploymentRequest{ |
223 | 343 | request.ServiceName, request.DeploymentName}, record[0]) | 340 | request.ServiceName, request.DeploymentName}, record[0]) |
224 | 344 | assertDeleteDeploymentRequest(c, api, request.ServiceName, | 341 | assertDeleteDeploymentRequest(c, api, request.ServiceName, |
225 | 345 | request.DeploymentName, record[1]) | 342 | request.DeploymentName, record[1]) |
226 | 346 | assertDeleteDiskRequest(c, api, "disk1", record[2], true) | 343 | assertDeleteDiskRequest(c, api, "disk1", record[2], true) |
227 | 347 | assertDeleteDiskRequest(c, api, "disk2", record[3], true) | 344 | assertDeleteDiskRequest(c, api, "disk2", record[3], true) |
228 | 348 | assertDeleteDiskRequest(c, api, "disk3", record[4], true) | ||
229 | 349 | } | 345 | } |
230 | 350 | 346 | ||
231 | 351 | func (suite *suiteDestroyDeployment) TestFailsGettingDeployment(c *C) { | 347 | func (suite *suiteDestroyDeployment) TestFailsGettingDeployment(c *C) { |
232 | @@ -393,7 +389,7 @@ | |||
233 | 393 | exampleDeployment := suite.makeExampleDeployment() | 389 | exampleDeployment := suite.makeExampleDeployment() |
234 | 394 | responses = append(responses, makeOKXMLResponse(c, exampleDeployment)...) | 390 | responses = append(responses, makeOKXMLResponse(c, exampleDeployment)...) |
235 | 395 | // For deleting disks. | 391 | // For deleting disks. |
237 | 396 | responses = append(responses, exampleOkayResponse, exampleOkayResponse, exampleOkayResponse) | 392 | responses = append(responses, exampleOkayResponse, exampleOkayResponse) |
238 | 397 | // For other requests. | 393 | // For other requests. |
239 | 398 | responses = append(responses, exampleFailResponse) | 394 | responses = append(responses, exampleFailResponse) |
240 | 399 | record := []*X509Request{} | 395 | record := []*X509Request{} |
241 | @@ -407,7 +403,7 @@ | |||
242 | 407 | err := api.DestroyDeployment(request) | 403 | err := api.DestroyDeployment(request) |
243 | 408 | c.Assert(err, NotNil) | 404 | c.Assert(err, NotNil) |
244 | 409 | c.Check(err, ErrorMatches, "DELETE request failed [(]500: Internal Server Error[)]") | 405 | c.Check(err, ErrorMatches, "DELETE request failed [(]500: Internal Server Error[)]") |
246 | 410 | c.Check(record, HasLen, 5) | 406 | c.Check(record, HasLen, 4) |
247 | 411 | } | 407 | } |
248 | 412 | 408 | ||
249 | 413 | type suiteDestroyHostedService struct{} | 409 | type suiteDestroyHostedService struct{} |
250 | 414 | 410 | ||
251 | === modified file 'x509dispatcher.go' | |||
252 | --- x509dispatcher.go 2014-02-05 04:46:09 +0000 | |||
253 | +++ x509dispatcher.go 2014-03-10 04:06:20 +0000 | |||
254 | @@ -6,7 +6,7 @@ | |||
255 | 6 | import ( | 6 | import ( |
256 | 7 | "bytes" | 7 | "bytes" |
257 | 8 | "fmt" | 8 | "fmt" |
259 | 9 | "io/ioutil" | 9 | "io" |
260 | 10 | "launchpad.net/gwacl/fork/http" | 10 | "launchpad.net/gwacl/fork/http" |
261 | 11 | . "launchpad.net/gwacl/logging" | 11 | . "launchpad.net/gwacl/logging" |
262 | 12 | "net/url" | 12 | "net/url" |
263 | @@ -70,6 +70,17 @@ | |||
264 | 70 | Header http.Header | 70 | Header http.Header |
265 | 71 | } | 71 | } |
266 | 72 | 72 | ||
267 | 73 | // rewindCloser returns an io.ReadCloser that seeks back | ||
268 | 74 | // to the beginning of the reader upong Close being called. | ||
269 | 75 | type rewindCloser struct { | ||
270 | 76 | io.ReadSeeker | ||
271 | 77 | } | ||
272 | 78 | |||
273 | 79 | func (c rewindCloser) Close() error { | ||
274 | 80 | _, err := c.Seek(0, 0) | ||
275 | 81 | return err | ||
276 | 82 | } | ||
277 | 83 | |||
278 | 73 | func performX509Request(session *x509Session, request *X509Request) (*x509Response, error) { | 84 | func performX509Request(session *x509Session, request *X509Request) (*x509Response, error) { |
279 | 74 | response := &x509Response{} | 85 | response := &x509Response{} |
280 | 75 | 86 | ||
281 | @@ -78,11 +89,12 @@ | |||
282 | 78 | Debugf("Request body:\n%s", request.Payload) | 89 | Debugf("Request body:\n%s", request.Payload) |
283 | 79 | } | 90 | } |
284 | 80 | 91 | ||
286 | 81 | bodyReader := ioutil.NopCloser(bytes.NewReader(request.Payload)) | 92 | bodyReader := rewindCloser{bytes.NewReader(request.Payload)} |
287 | 82 | httpRequest, err := http.NewRequest(request.Method, request.URL, bodyReader) | 93 | httpRequest, err := http.NewRequest(request.Method, request.URL, bodyReader) |
288 | 83 | if err != nil { | 94 | if err != nil { |
289 | 84 | return nil, err | 95 | return nil, err |
290 | 85 | } | 96 | } |
291 | 97 | httpRequest.ContentLength = int64(len(request.Payload)) | ||
292 | 86 | httpRequest.Header.Set("Content-Type", request.ContentType) | 98 | httpRequest.Header.Set("Content-Type", request.ContentType) |
293 | 87 | httpRequest.Header.Set("x-ms-version", request.APIVersion) | 99 | httpRequest.Header.Set("x-ms-version", request.APIVersion) |
294 | 88 | retrier := session.retryPolicy.getForkedHttpRetrier(session.client) | 100 | retrier := session.retryPolicy.getForkedHttpRetrier(session.client) |
295 | 89 | 101 | ||
296 | === modified file 'x509dispatcher_test.go' | |||
297 | --- x509dispatcher_test.go 2014-02-05 04:46:09 +0000 | |||
298 | +++ x509dispatcher_test.go 2014-03-10 04:06:20 +0000 | |||
299 | @@ -219,6 +219,31 @@ | |||
300 | 219 | } | 219 | } |
301 | 220 | } | 220 | } |
302 | 221 | 221 | ||
303 | 222 | func (*x509DispatcherSuite) TestRedirectRewindsBody(c *C) { | ||
304 | 223 | httpRequests := make(chan *Request, 2) | ||
305 | 224 | serverConflict := makeRecordingHTTPServer(httpRequests, http.StatusConflict, nil, nil) | ||
306 | 225 | defer serverConflict.Close() | ||
307 | 226 | redirPath := "/else/where" | ||
308 | 227 | responseHeaders := make(http.Header) | ||
309 | 228 | responseHeaders.Set("Location", serverConflict.URL+redirPath) | ||
310 | 229 | serverRedir := makeRecordingHTTPServer(httpRequests, http.StatusTemporaryRedirect, nil, responseHeaders) | ||
311 | 230 | defer serverRedir.Close() | ||
312 | 231 | session, err := newX509Session("subscriptionid", "", "West US", NoRetryPolicy) | ||
313 | 232 | c.Assert(err, IsNil) | ||
314 | 233 | path := "/foo/bar" | ||
315 | 234 | version := "test-version" | ||
316 | 235 | content := []byte("ponies") | ||
317 | 236 | contentType := "text/plain" | ||
318 | 237 | |||
319 | 238 | request := newX509RequestPOST(serverRedir.URL+path, version, content, contentType) | ||
320 | 239 | response, err := performX509Request(session, request) | ||
321 | 240 | c.Assert(err, IsNil) | ||
322 | 241 | c.Assert(response.StatusCode, Equals, http.StatusConflict) | ||
323 | 242 | c.Assert(httpRequests, HasLen, 2) | ||
324 | 243 | c.Assert((<-httpRequests).BodyContent, DeepEquals, content) | ||
325 | 244 | c.Assert((<-httpRequests).BodyContent, DeepEquals, content) | ||
326 | 245 | } | ||
327 | 246 | |||
328 | 222 | func (*x509DispatcherSuite) TestRequestsLimitRedirects(c *C) { | 247 | func (*x509DispatcherSuite) TestRequestsLimitRedirects(c *C) { |
329 | 223 | httpRequests := make(chan *Request, 10) | 248 | httpRequests := make(chan *Request, 10) |
330 | 224 | serverRedir := makeRecordingHTTPServer(httpRequests, http.StatusTemporaryRedirect, nil, nil) | 249 | serverRedir := makeRecordingHTTPServer(httpRequests, http.StatusTemporaryRedirect, nil, nil) |
331 | 225 | 250 | ||
332 | === modified file 'xmlobjects.go' | |||
333 | --- xmlobjects.go 2013-10-31 07:59:14 +0000 | |||
334 | +++ xmlobjects.go 2014-03-10 04:06:20 +0000 | |||
335 | @@ -109,7 +109,7 @@ | |||
336 | 109 | // | 109 | // |
337 | 110 | 110 | ||
338 | 111 | type LoadBalancerProbe struct { | 111 | type LoadBalancerProbe struct { |
340 | 112 | Path string `xml:"Path"` | 112 | Path string `xml:"Path,omitempty"` |
341 | 113 | Port int `xml:"Port"` // Not uint16; see https://bugs.launchpad.net/juju-core/+bug/1201880 | 113 | Port int `xml:"Port"` // Not uint16; see https://bugs.launchpad.net/juju-core/+bug/1201880 |
342 | 114 | Protocol string `xml:"Protocol"` | 114 | Protocol string `xml:"Protocol"` |
343 | 115 | } | 115 | } |
344 | @@ -310,11 +310,16 @@ | |||
345 | 310 | } | 310 | } |
346 | 311 | 311 | ||
347 | 312 | type Role struct { | 312 | type Role struct { |
353 | 313 | RoleName string `xml:"RoleName"` | 313 | XMLNS string `xml:"xmlns,attr,omitempty"` |
354 | 314 | RoleType string `xml:"RoleType"` // Always "PersistentVMRole" | 314 | RoleName string `xml:"RoleName"` |
355 | 315 | ConfigurationSets []ConfigurationSet `xml:"ConfigurationSets>ConfigurationSet"` | 315 | OsVersion string `xml:"OsVersion,omitempty"` |
356 | 316 | OSVirtualHardDisk []OSVirtualHardDisk `xml:"OSVirtualHardDisk"` | 316 | RoleType string `xml:"RoleType"` // Always "PersistentVMRole" |
357 | 317 | RoleSize string `xml:"RoleSize"` | 317 | ConfigurationSets []ConfigurationSet `xml:"ConfigurationSets>ConfigurationSet"` |
358 | 318 | AvailabilitySetName string `xml:"AvailabilitySetName,omitempty"` | ||
359 | 319 | DataVirtualHardDisks *[]DataVirtualHardDisk `xml:"DataVirtualHardDisks>DataVirtualHardDisk,omitempty"` | ||
360 | 320 | OSVirtualHardDisk *OSVirtualHardDisk `xml:"OSVirtualHardDisk,omitempty"` | ||
361 | 321 | RoleSize string `xml:"RoleSize"` | ||
362 | 322 | DefaultWinRmCertificateThumbprint string `xml:"DefaultWinRmCertificateThumbprint,omitempty"` | ||
363 | 318 | } | 323 | } |
364 | 319 | 324 | ||
365 | 320 | // | 325 | // |
366 | @@ -325,14 +330,13 @@ | |||
367 | 325 | return toxml(c) | 330 | return toxml(c) |
368 | 326 | } | 331 | } |
369 | 327 | 332 | ||
372 | 328 | func NewRole(RoleSize string, RoleName string, | 333 | func NewRole(RoleSize, RoleName string, vhd *OSVirtualHardDisk, ConfigurationSets []ConfigurationSet) *Role { |
371 | 329 | ConfigurationSets []ConfigurationSet, vhds []OSVirtualHardDisk) *Role { | ||
373 | 330 | return &Role{ | 334 | return &Role{ |
374 | 331 | RoleSize: RoleSize, | 335 | RoleSize: RoleSize, |
375 | 332 | RoleName: RoleName, | 336 | RoleName: RoleName, |
376 | 333 | RoleType: "PersistentVMRole", | 337 | RoleType: "PersistentVMRole", |
377 | 334 | ConfigurationSets: ConfigurationSets, | 338 | ConfigurationSets: ConfigurationSets, |
379 | 335 | OSVirtualHardDisk: vhds, | 339 | OSVirtualHardDisk: vhd, |
380 | 336 | } | 340 | } |
381 | 337 | } | 341 | } |
382 | 338 | 342 | ||
383 | @@ -600,24 +604,18 @@ | |||
384 | 600 | // | 604 | // |
385 | 601 | // PersistentVMRole, as used by GetRole, UpdateRole, etc. | 605 | // PersistentVMRole, as used by GetRole, UpdateRole, etc. |
386 | 602 | // | 606 | // |
399 | 603 | type PersistentVMRole struct { | 607 | type PersistentVMRole Role |
388 | 604 | XMLNS string `xml:"xmlns,attr"` | ||
389 | 605 | RoleName string `xml:"RoleName"` | ||
390 | 606 | OsVersion string `xml:"OsVersion"` | ||
391 | 607 | RoleType string `xml:"RoleType"` // Always PersistentVMRole | ||
392 | 608 | ConfigurationSets []ConfigurationSet `xml:"ConfigurationSets>ConfigurationSet"` | ||
393 | 609 | AvailabilitySetName string `xml:"AvailabilitySetName"` | ||
394 | 610 | DataVirtualHardDisks *[]DataVirtualHardDisk `xml:"DataVirtualHardDisks>DataVirtualHardDisk,omitempty"` | ||
395 | 611 | OSVirtualHardDisk OSVirtualHardDisk `xml:"OSVirtualHardDisk"` | ||
396 | 612 | RoleSize string `xml:"RoleSize"` | ||
397 | 613 | DefaultWinRmCertificateThumbprint string `xml:"DefaultWinRmCertificateThumbprint"` | ||
398 | 614 | } | ||
400 | 615 | 608 | ||
401 | 616 | func (role *PersistentVMRole) Deserialize(data []byte) error { | 609 | func (role *PersistentVMRole) Deserialize(data []byte) error { |
402 | 617 | return xml.Unmarshal(data, role) | 610 | return xml.Unmarshal(data, role) |
403 | 618 | } | 611 | } |
404 | 619 | 612 | ||
405 | 620 | func (role *PersistentVMRole) Serialize() (string, error) { | 613 | func (role *PersistentVMRole) Serialize() (string, error) { |
406 | 614 | if role.XMLNS == "" { | ||
407 | 615 | clone := *role | ||
408 | 616 | clone.XMLNS = XMLNS | ||
409 | 617 | role = &clone | ||
410 | 618 | } | ||
411 | 621 | return toxml(role) | 619 | return toxml(role) |
412 | 622 | } | 620 | } |
413 | 623 | 621 | ||
414 | 624 | 622 | ||
415 | === modified file 'xmlobjects_test.go' | |||
416 | --- xmlobjects_test.go 2013-10-31 07:59:14 +0000 | |||
417 | +++ xmlobjects_test.go 2014-03-10 04:06:20 +0000 | |||
418 | @@ -291,7 +291,7 @@ | |||
419 | 291 | MediaLink: "path-to-vhd", | 291 | MediaLink: "path-to-vhd", |
420 | 292 | }, | 292 | }, |
421 | 293 | }, | 293 | }, |
423 | 294 | OSVirtualHardDisk: OSVirtualHardDisk{ | 294 | OSVirtualHardDisk: &OSVirtualHardDisk{ |
424 | 295 | HostCaching: "host-caching-mode-of-os-disk", | 295 | HostCaching: "host-caching-mode-of-os-disk", |
425 | 296 | DiskName: "name-of-os-disk", | 296 | DiskName: "name-of-os-disk", |
426 | 297 | MediaLink: "path-to-vhd", | 297 | MediaLink: "path-to-vhd", |
427 | @@ -360,7 +360,7 @@ | |||
428 | 360 | MediaLink: "path-to-vhd", | 360 | MediaLink: "path-to-vhd", |
429 | 361 | }, | 361 | }, |
430 | 362 | }, | 362 | }, |
432 | 363 | OSVirtualHardDisk: OSVirtualHardDisk{ | 363 | OSVirtualHardDisk: &OSVirtualHardDisk{ |
433 | 364 | HostCaching: "host-caching-mode-of-os-disk", | 364 | HostCaching: "host-caching-mode-of-os-disk", |
434 | 365 | DiskName: "name-of-os-disk", | 365 | DiskName: "name-of-os-disk", |
435 | 366 | MediaLink: "path-to-vhd", | 366 | MediaLink: "path-to-vhd", |
436 | @@ -922,7 +922,8 @@ | |||
437 | 922 | UpgradeDomainCount: "number-of-upgrade-domains-in-deployment", | 922 | UpgradeDomainCount: "number-of-upgrade-domains-in-deployment", |
438 | 923 | RoleList: []Role{ | 923 | RoleList: []Role{ |
439 | 924 | { | 924 | { |
441 | 925 | RoleName: "name-of-role", | 925 | RoleName: "name-of-role", |
442 | 926 | OsVersion: "operating-system-version", | ||
443 | 926 | ConfigurationSets: []ConfigurationSet{ | 927 | ConfigurationSets: []ConfigurationSet{ |
444 | 927 | { | 928 | { |
445 | 928 | ConfigurationSetType: "LinuxProvisioningConfiguration", | 929 | ConfigurationSetType: "LinuxProvisioningConfiguration", |
446 | @@ -931,8 +932,9 @@ | |||
447 | 931 | }, | 932 | }, |
448 | 932 | }, | 933 | }, |
449 | 933 | { | 934 | { |
452 | 934 | RoleName: "name-of-role", | 935 | RoleName: "name-of-role", |
453 | 935 | RoleType: "PersistentVMRole", | 936 | OsVersion: "operating-system-version", |
454 | 937 | RoleType: "PersistentVMRole", | ||
455 | 936 | ConfigurationSets: []ConfigurationSet{ | 938 | ConfigurationSets: []ConfigurationSet{ |
456 | 937 | { | 939 | { |
457 | 938 | ConfigurationSetType: CONFIG_SET_NETWORK, | 940 | ConfigurationSetType: CONFIG_SET_NETWORK, |
458 | @@ -947,15 +949,23 @@ | |||
459 | 947 | SubnetNames: &[]string{"name-of-subnet"}, | 949 | SubnetNames: &[]string{"name-of-subnet"}, |
460 | 948 | }, | 950 | }, |
461 | 949 | }, | 951 | }, |
463 | 950 | OSVirtualHardDisk: []OSVirtualHardDisk{ | 952 | AvailabilitySetName: "name-of-availability-set", |
464 | 953 | DataVirtualHardDisks: &[]DataVirtualHardDisk{ | ||
465 | 951 | { | 954 | { |
471 | 952 | HostCaching: "host-caching-mode-of-os-disk", | 955 | HostCaching: "host-caching-mode-of-data-disk", |
472 | 953 | DiskName: "name-of-os-disk", | 956 | DiskName: "name-of-data-disk", |
473 | 954 | MediaLink: "path-to-vhd", | 957 | LUN: "logical-unit-number-of-data-disk", |
474 | 955 | SourceImageName: "image-used-to-create-os-disk", | 958 | LogicalDiskSizeInGB: "size-of-data-disk", |
475 | 956 | OS: "operating-system-on-os-disk", | 959 | MediaLink: "path-to-vhd", |
476 | 957 | }, | 960 | }, |
477 | 958 | }, | 961 | }, |
478 | 962 | OSVirtualHardDisk: &OSVirtualHardDisk{ | ||
479 | 963 | HostCaching: "host-caching-mode-of-os-disk", | ||
480 | 964 | DiskName: "name-of-os-disk", | ||
481 | 965 | MediaLink: "path-to-vhd", | ||
482 | 966 | SourceImageName: "image-used-to-create-os-disk", | ||
483 | 967 | OS: "operating-system-on-os-disk", | ||
484 | 968 | }, | ||
485 | 959 | RoleSize: "size-of-instance", | 969 | RoleSize: "size-of-instance", |
486 | 960 | }, | 970 | }, |
487 | 961 | }, | 971 | }, |
488 | @@ -1030,7 +1040,7 @@ | |||
489 | 1030 | deploymentSlot := "staging" | 1040 | deploymentSlot := "staging" |
490 | 1031 | label := "deploymentLabel" | 1041 | label := "deploymentLabel" |
491 | 1032 | vhd := NewOSVirtualHardDisk("hostCaching", "diskLabel", "diskName", "mediaLink", "sourceImageName", "os") | 1042 | vhd := NewOSVirtualHardDisk("hostCaching", "diskLabel", "diskName", "mediaLink", "sourceImageName", "os") |
493 | 1033 | roles := []Role{*NewRole("size", "name", []ConfigurationSet{}, []OSVirtualHardDisk{*vhd})} | 1043 | roles := []Role{*NewRole("size", "name", vhd, []ConfigurationSet{})} |
494 | 1034 | virtualNetworkName := "network" | 1044 | virtualNetworkName := "network" |
495 | 1035 | 1045 | ||
496 | 1036 | deployment := NewDeploymentForCreateVMDeployment(name, deploymentSlot, label, roles, virtualNetworkName) | 1046 | deployment := NewDeploymentForCreateVMDeployment(name, deploymentSlot, label, roles, virtualNetworkName) |
497 | @@ -1303,7 +1313,7 @@ | |||
498 | 1303 | configset := []ConfigurationSet{*config} | 1313 | configset := []ConfigurationSet{*config} |
499 | 1304 | vhd := NewOSVirtualHardDisk("hostCaching", "diskLabel", "diskName", "mediaLink", "sourceImageName", "os") | 1314 | vhd := NewOSVirtualHardDisk("hostCaching", "diskLabel", "diskName", "mediaLink", "sourceImageName", "os") |
500 | 1305 | 1315 | ||
502 | 1306 | role := NewRole(rolesize, rolename, configset, []OSVirtualHardDisk{*vhd}) | 1316 | role := NewRole(rolesize, rolename, vhd, configset) |
503 | 1307 | c.Check(role.RoleSize, Equals, rolesize) | 1317 | c.Check(role.RoleSize, Equals, rolesize) |
504 | 1308 | c.Check(role.RoleName, Equals, rolename) | 1318 | c.Check(role.RoleName, Equals, rolename) |
505 | 1309 | c.Check(role.ConfigurationSets, DeepEquals, configset) | 1319 | c.Check(role.ConfigurationSets, DeepEquals, configset) |