Merge lp:~axwalk/gwacl/add-delete-role into lp:gwacl

Proposed by Andrew Wilkins
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
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.

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.

To post a comment you must log in.
lp:~axwalk/gwacl/add-delete-role updated
234. By Andrew Wilkins

Fix copy and paste error

Unmerged revisions

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'example/management/run.go'
--- example/management/run.go 2013-10-31 08:10:35 +0000
+++ example/management/run.go 2014-03-10 04:06:20 +0000
@@ -214,9 +214,8 @@
214 diskLabel := makeRandomIdentifier("gwacl", 64)214 diskLabel := makeRandomIdentifier("gwacl", 64)
215 vhd := gwacl.NewOSVirtualHardDisk("", diskLabel, diskName, mediaLink, sourceImageName, "Linux")215 vhd := gwacl.NewOSVirtualHardDisk("", diskLabel, diskName, mediaLink, sourceImageName, "Linux")
216 roleName := gwacl.MakeRandomRoleName("gwaclrole")216 roleName := gwacl.MakeRandomRoleName("gwaclrole")
217 role := gwacl.NewRole("ExtraSmall", roleName,217 role := gwacl.NewRole("ExtraSmall", roleName, vhd,
218 []gwacl.ConfigurationSet{*linuxConfigurationSet, *networkConfigurationSet},218 []gwacl.ConfigurationSet{*linuxConfigurationSet, *networkConfigurationSet})
219 []gwacl.OSVirtualHardDisk{*vhd})
220 machineName := makeRandomIdentifier("gwaclmachine", 20)219 machineName := makeRandomIdentifier("gwaclmachine", 20)
221 deployment := gwacl.NewDeploymentForCreateVMDeployment(220 deployment := gwacl.NewDeploymentForCreateVMDeployment(
222 machineName, "Production", machineName, []gwacl.Role{*role}, virtualNetworkName)221 machineName, "Production", machineName, []gwacl.Role{*role}, virtualNetworkName)
223222
=== modified file 'management.go'
--- management.go 2013-08-28 00:13:04 +0000
+++ management.go 2014-03-10 04:06:20 +0000
@@ -140,9 +140,7 @@
140 // 1. Get the list of the VM disks.140 // 1. Get the list of the VM disks.
141 diskNameMap := make(map[string]bool)141 diskNameMap := make(map[string]bool)
142 for _, role := range deployment.RoleList {142 for _, role := range deployment.RoleList {
143 for _, osVHD := range role.OSVirtualHardDisk {143 diskNameMap[role.OSVirtualHardDisk.DiskName] = true
144 diskNameMap[osVHD.DiskName] = true
145 }
146 }144 }
147 // 2. Delete deployment. This will delete all the role instances inside145 // 2. Delete deployment. This will delete all the role instances inside
148 // this deployment as a side effect.146 // this deployment as a side effect.
149147
=== modified file 'management_base.go'
--- management_base.go 2013-10-31 04:16:38 +0000
+++ management_base.go 2014-03-10 04:06:20 +0000
@@ -474,6 +474,57 @@
474 return api.blockUntilCompleted(response)474 return api.blockUntilCompleted(response)
475}475}
476476
477type DeleteRoleRequest struct {
478 ServiceName string
479 DeploymentName string
480 RoleName string
481 DeleteMedia bool
482}
483
484// DeleteRole deletes a named Role from within the specified Cloud Service
485// and Deployment.
486// See http://msdn.microsoft.com/en-us/library/windowsazure/jj157187.aspx
487func (api *ManagementAPI) DeleteRole(request *DeleteRoleRequest) error {
488 checkPathComponents(request.ServiceName, request.DeploymentName, request.RoleName)
489 url := ("services/hostedservices/" + request.ServiceName +
490 "/deployments/" + request.DeploymentName + "/roles/" + request.RoleName)
491 if request.DeleteMedia {
492 url = addURLQueryParams(url, "comp", "media")
493 }
494 response, err := api.session.delete(url, "2013-08-01")
495 if err != nil {
496 if IsNotFoundError(err) {
497 return nil
498 }
499 return err
500 }
501 return api.blockUntilCompleted(response)
502}
503
504type AddRoleRequest struct {
505 ServiceName string
506 DeploymentName string
507 PersistentVMRole *PersistentVMRole
508}
509
510// AddRole creates a new Role within the specified Cloud Service
511// and Deployment.
512// See http://msdn.microsoft.com/en-us/library/windowsazure/jj157187.aspx
513func (api *ManagementAPI) AddRole(request *AddRoleRequest) error {
514 checkPathComponents(request.ServiceName, request.DeploymentName)
515 url := ("services/hostedservices/" + request.ServiceName +
516 "/deployments/" + request.DeploymentName + "/roles")
517 role, err := request.PersistentVMRole.Serialize()
518 if err != nil {
519 return err
520 }
521 response, err := api.session.post(url, "2013-10-01", []byte(role), "application/xml")
522 if err != nil {
523 return err
524 }
525 return api.blockUntilCompleted(response)
526}
527
477type CreateAffinityGroupRequest struct {528type CreateAffinityGroupRequest struct {
478 CreateAffinityGroup *CreateAffinityGroup529 CreateAffinityGroup *CreateAffinityGroup
479}530}
480531
=== modified file 'management_base_test.go'
--- management_base_test.go 2013-10-31 04:16:38 +0000
+++ management_base_test.go 2014-03-10 04:06:20 +0000
@@ -681,7 +681,7 @@
681 serviceName := "serviceName"681 serviceName := "serviceName"
682 configurationSet := NewLinuxProvisioningConfigurationSet("testHostname12345", "test", "test123#@!", "user-data", "false")682 configurationSet := NewLinuxProvisioningConfigurationSet("testHostname12345", "test", "test123#@!", "user-data", "false")
683 vhd := NewOSVirtualHardDisk("hostCaching", "diskLabel", "diskName", "http://mediaLink", "sourceImageName", "os")683 vhd := NewOSVirtualHardDisk("hostCaching", "diskLabel", "diskName", "http://mediaLink", "sourceImageName", "os")
684 role := NewRole("ExtraSmall", "test-role-123", []ConfigurationSet{*configurationSet}, []OSVirtualHardDisk{*vhd})684 role := NewRole("ExtraSmall", "test-role-123", vhd, []ConfigurationSet{*configurationSet})
685 deployment := NewDeploymentForCreateVMDeployment("test-machine-name", "Staging", "testLabel", []Role{*role}, "testNetwork")685 deployment := NewDeploymentForCreateVMDeployment("test-machine-name", "Staging", "testLabel", []Role{*role}, "testNetwork")
686 err := api.AddDeployment(deployment, serviceName)686 err := api.AddDeployment(deployment, serviceName)
687687
@@ -1109,6 +1109,76 @@
1109 c.Check(recordedRequests[1].URL, Matches, ".*/operations/foobar")1109 c.Check(recordedRequests[1].URL, Matches, ".*/operations/foobar")
1110}1110}
11111111
1112func assertDeleteRoleRequest(c *C, api *ManagementAPI, httpRequest *X509Request, serviceName, deploymentName, roleName string, deleteMedia bool) {
1113 expectedURL := (defaultManagement + api.session.subscriptionId +
1114 "/services/hostedservices/" +
1115 serviceName + "/deployments/" + deploymentName + "/roles/" + roleName)
1116 if deleteMedia {
1117 expectedURL += "?comp=media"
1118 }
1119 checkRequest(
1120 c, httpRequest, expectedURL, "2013-08-01", nil, "DELETE")
1121}
1122
1123func (suite *managementBaseAPISuite) TestDeleteRole(c *C) {
1124 suite.testDeleteRole(c, false)
1125}
1126
1127func (suite *managementBaseAPISuite) TestDeleteRoleDeleteMedia(c *C) {
1128 suite.testDeleteRole(c, true)
1129}
1130
1131func (suite *managementBaseAPISuite) testDeleteRole(c *C, deleteMedia bool) {
1132 api := makeAPI(c)
1133 request := &DeleteRoleRequest{
1134 ServiceName: "serviceName",
1135 DeploymentName: "deploymentName",
1136 RoleName: "roleName",
1137 DeleteMedia: deleteMedia,
1138 }
1139 rigFixedResponseDispatcher(&x509Response{StatusCode: http.StatusOK})
1140 recordedRequests := make([]*X509Request, 0)
1141 rigRecordingDispatcher(&recordedRequests)
1142
1143 err := api.DeleteRole(request)
1144 c.Assert(err, IsNil)
1145 assertDeleteRoleRequest(
1146 c, api, recordedRequests[0], request.ServiceName,
1147 request.DeploymentName, request.RoleName, deleteMedia)
1148}
1149
1150func assertAddRoleRequest(c *C, api *ManagementAPI, httpRequest *X509Request, serviceName, deploymentName, expectedXML string) {
1151 expectedURL := (defaultManagement + api.session.subscriptionId +
1152 "/services/hostedservices/" +
1153 serviceName + "/deployments/" + deploymentName + "/roles")
1154 checkRequest(
1155 c, httpRequest, expectedURL, "2013-10-01", []byte(expectedXML), "POST")
1156 c.Assert(httpRequest.ContentType, Equals, "application/xml")
1157}
1158
1159func (suite *managementBaseAPISuite) TestAddRole(c *C) {
1160 api := makeAPI(c)
1161 request := &UpdateRoleRequest{
1162 ServiceName: "serviceName",
1163 DeploymentName: "deploymentName",
1164 PersistentVMRole: &PersistentVMRole{
1165 RoleName: "newRoleNamePerhaps",
1166 },
1167 }
1168 rigFixedResponseDispatcher(&x509Response{StatusCode: http.StatusOK})
1169 recordedRequests := make([]*X509Request, 0)
1170 rigRecordingDispatcher(&recordedRequests)
1171
1172 err := api.UpdateRole(request)
1173 c.Assert(err, IsNil)
1174
1175 expectedXML, err := request.PersistentVMRole.Serialize()
1176 c.Assert(err, IsNil)
1177 assertUpdateRoleRequest(
1178 c, api, recordedRequests[0], request.ServiceName,
1179 request.DeploymentName, request.RoleName, expectedXML)
1180}
1181
1112func (suite *managementBaseAPISuite) TestCreateAffinityGroup(c *C) {1182func (suite *managementBaseAPISuite) TestCreateAffinityGroup(c *C) {
1113 api := makeAPI(c)1183 api := makeAPI(c)
1114 cag := NewCreateAffinityGroup(1184 cag := NewCreateAffinityGroup(
11151185
=== modified file 'management_test.go'
--- management_test.go 2013-08-28 00:13:04 +0000
+++ management_test.go 2014-03-10 04:06:20 +0000
@@ -265,10 +265,8 @@
265 return &Deployment{265 return &Deployment{
266 RoleInstanceList: makeNamedRoleInstances("one", "two"),266 RoleInstanceList: makeNamedRoleInstances("one", "two"),
267 RoleList: []Role{267 RoleList: []Role{
268 {OSVirtualHardDisk: []OSVirtualHardDisk{268 {OSVirtualHardDisk: &OSVirtualHardDisk{DiskName: "disk1"}},
269 {DiskName: "disk1"}, {DiskName: "disk2"}}},269 {OSVirtualHardDisk: &OSVirtualHardDisk{DiskName: "disk2"}},
270 {OSVirtualHardDisk: []OSVirtualHardDisk{
271 {DiskName: "disk1"}, {DiskName: "disk3"}}},
272 },270 },
273 }271 }
274}272}
@@ -292,14 +290,13 @@
292 }290 }
293 err := api.DestroyDeployment(request)291 err := api.DestroyDeployment(request)
294 c.Assert(err, IsNil)292 c.Assert(err, IsNil)
295 c.Check(record, HasLen, 5)293 c.Check(record, HasLen, 4)
296 assertGetDeploymentRequest(c, api, &GetDeploymentRequest{294 assertGetDeploymentRequest(c, api, &GetDeploymentRequest{
297 request.ServiceName, request.DeploymentName}, record[0])295 request.ServiceName, request.DeploymentName}, record[0])
298 assertDeleteDeploymentRequest(c, api, request.ServiceName,296 assertDeleteDeploymentRequest(c, api, request.ServiceName,
299 request.DeploymentName, record[1])297 request.DeploymentName, record[1])
300 assertDeleteDiskRequest(c, api, "disk1", record[2], true)298 assertDeleteDiskRequest(c, api, "disk1", record[2], true)
301 assertDeleteDiskRequest(c, api, "disk2", record[3], true)299 assertDeleteDiskRequest(c, api, "disk2", record[3], true)
302 assertDeleteDiskRequest(c, api, "disk3", record[4], true)
303}300}
304301
305func (suite *suiteDestroyDeployment) TestOkayWhenDeploymentNotFound(c *C) {302func (suite *suiteDestroyDeployment) TestOkayWhenDeploymentNotFound(c *C) {
@@ -338,14 +335,13 @@
338 }335 }
339 err := api.DestroyDeployment(request)336 err := api.DestroyDeployment(request)
340 c.Assert(err, IsNil)337 c.Assert(err, IsNil)
341 c.Check(record, HasLen, 5)338 c.Check(record, HasLen, 4)
342 assertGetDeploymentRequest(c, api, &GetDeploymentRequest{339 assertGetDeploymentRequest(c, api, &GetDeploymentRequest{
343 request.ServiceName, request.DeploymentName}, record[0])340 request.ServiceName, request.DeploymentName}, record[0])
344 assertDeleteDeploymentRequest(c, api, request.ServiceName,341 assertDeleteDeploymentRequest(c, api, request.ServiceName,
345 request.DeploymentName, record[1])342 request.DeploymentName, record[1])
346 assertDeleteDiskRequest(c, api, "disk1", record[2], true)343 assertDeleteDiskRequest(c, api, "disk1", record[2], true)
347 assertDeleteDiskRequest(c, api, "disk2", record[3], true)344 assertDeleteDiskRequest(c, api, "disk2", record[3], true)
348 assertDeleteDiskRequest(c, api, "disk3", record[4], true)
349}345}
350346
351func (suite *suiteDestroyDeployment) TestFailsGettingDeployment(c *C) {347func (suite *suiteDestroyDeployment) TestFailsGettingDeployment(c *C) {
@@ -393,7 +389,7 @@
393 exampleDeployment := suite.makeExampleDeployment()389 exampleDeployment := suite.makeExampleDeployment()
394 responses = append(responses, makeOKXMLResponse(c, exampleDeployment)...)390 responses = append(responses, makeOKXMLResponse(c, exampleDeployment)...)
395 // For deleting disks.391 // For deleting disks.
396 responses = append(responses, exampleOkayResponse, exampleOkayResponse, exampleOkayResponse)392 responses = append(responses, exampleOkayResponse, exampleOkayResponse)
397 // For other requests.393 // For other requests.
398 responses = append(responses, exampleFailResponse)394 responses = append(responses, exampleFailResponse)
399 record := []*X509Request{}395 record := []*X509Request{}
@@ -407,7 +403,7 @@
407 err := api.DestroyDeployment(request)403 err := api.DestroyDeployment(request)
408 c.Assert(err, NotNil)404 c.Assert(err, NotNil)
409 c.Check(err, ErrorMatches, "DELETE request failed [(]500: Internal Server Error[)]")405 c.Check(err, ErrorMatches, "DELETE request failed [(]500: Internal Server Error[)]")
410 c.Check(record, HasLen, 5)406 c.Check(record, HasLen, 4)
411}407}
412408
413type suiteDestroyHostedService struct{}409type suiteDestroyHostedService struct{}
414410
=== modified file 'x509dispatcher.go'
--- x509dispatcher.go 2014-02-05 04:46:09 +0000
+++ x509dispatcher.go 2014-03-10 04:06:20 +0000
@@ -6,7 +6,7 @@
6import (6import (
7 "bytes"7 "bytes"
8 "fmt"8 "fmt"
9 "io/ioutil"9 "io"
10 "launchpad.net/gwacl/fork/http"10 "launchpad.net/gwacl/fork/http"
11 . "launchpad.net/gwacl/logging"11 . "launchpad.net/gwacl/logging"
12 "net/url"12 "net/url"
@@ -70,6 +70,17 @@
70 Header http.Header70 Header http.Header
71}71}
7272
73// rewindCloser returns an io.ReadCloser that seeks back
74// to the beginning of the reader upong Close being called.
75type rewindCloser struct {
76 io.ReadSeeker
77}
78
79func (c rewindCloser) Close() error {
80 _, err := c.Seek(0, 0)
81 return err
82}
83
73func performX509Request(session *x509Session, request *X509Request) (*x509Response, error) {84func performX509Request(session *x509Session, request *X509Request) (*x509Response, error) {
74 response := &x509Response{}85 response := &x509Response{}
7586
@@ -78,11 +89,12 @@
78 Debugf("Request body:\n%s", request.Payload)89 Debugf("Request body:\n%s", request.Payload)
79 }90 }
8091
81 bodyReader := ioutil.NopCloser(bytes.NewReader(request.Payload))92 bodyReader := rewindCloser{bytes.NewReader(request.Payload)}
82 httpRequest, err := http.NewRequest(request.Method, request.URL, bodyReader)93 httpRequest, err := http.NewRequest(request.Method, request.URL, bodyReader)
83 if err != nil {94 if err != nil {
84 return nil, err95 return nil, err
85 }96 }
97 httpRequest.ContentLength = int64(len(request.Payload))
86 httpRequest.Header.Set("Content-Type", request.ContentType)98 httpRequest.Header.Set("Content-Type", request.ContentType)
87 httpRequest.Header.Set("x-ms-version", request.APIVersion)99 httpRequest.Header.Set("x-ms-version", request.APIVersion)
88 retrier := session.retryPolicy.getForkedHttpRetrier(session.client)100 retrier := session.retryPolicy.getForkedHttpRetrier(session.client)
89101
=== modified file 'x509dispatcher_test.go'
--- x509dispatcher_test.go 2014-02-05 04:46:09 +0000
+++ x509dispatcher_test.go 2014-03-10 04:06:20 +0000
@@ -219,6 +219,31 @@
219 }219 }
220}220}
221221
222func (*x509DispatcherSuite) TestRedirectRewindsBody(c *C) {
223 httpRequests := make(chan *Request, 2)
224 serverConflict := makeRecordingHTTPServer(httpRequests, http.StatusConflict, nil, nil)
225 defer serverConflict.Close()
226 redirPath := "/else/where"
227 responseHeaders := make(http.Header)
228 responseHeaders.Set("Location", serverConflict.URL+redirPath)
229 serverRedir := makeRecordingHTTPServer(httpRequests, http.StatusTemporaryRedirect, nil, responseHeaders)
230 defer serverRedir.Close()
231 session, err := newX509Session("subscriptionid", "", "West US", NoRetryPolicy)
232 c.Assert(err, IsNil)
233 path := "/foo/bar"
234 version := "test-version"
235 content := []byte("ponies")
236 contentType := "text/plain"
237
238 request := newX509RequestPOST(serverRedir.URL+path, version, content, contentType)
239 response, err := performX509Request(session, request)
240 c.Assert(err, IsNil)
241 c.Assert(response.StatusCode, Equals, http.StatusConflict)
242 c.Assert(httpRequests, HasLen, 2)
243 c.Assert((<-httpRequests).BodyContent, DeepEquals, content)
244 c.Assert((<-httpRequests).BodyContent, DeepEquals, content)
245}
246
222func (*x509DispatcherSuite) TestRequestsLimitRedirects(c *C) {247func (*x509DispatcherSuite) TestRequestsLimitRedirects(c *C) {
223 httpRequests := make(chan *Request, 10)248 httpRequests := make(chan *Request, 10)
224 serverRedir := makeRecordingHTTPServer(httpRequests, http.StatusTemporaryRedirect, nil, nil)249 serverRedir := makeRecordingHTTPServer(httpRequests, http.StatusTemporaryRedirect, nil, nil)
225250
=== modified file 'xmlobjects.go'
--- xmlobjects.go 2013-10-31 07:59:14 +0000
+++ xmlobjects.go 2014-03-10 04:06:20 +0000
@@ -109,7 +109,7 @@
109//109//
110110
111type LoadBalancerProbe struct {111type LoadBalancerProbe struct {
112 Path string `xml:"Path"`112 Path string `xml:"Path,omitempty"`
113 Port int `xml:"Port"` // Not uint16; see https://bugs.launchpad.net/juju-core/+bug/1201880113 Port int `xml:"Port"` // Not uint16; see https://bugs.launchpad.net/juju-core/+bug/1201880
114 Protocol string `xml:"Protocol"`114 Protocol string `xml:"Protocol"`
115}115}
@@ -310,11 +310,16 @@
310}310}
311311
312type Role struct {312type Role struct {
313 RoleName string `xml:"RoleName"`313 XMLNS string `xml:"xmlns,attr,omitempty"`
314 RoleType string `xml:"RoleType"` // Always "PersistentVMRole"314 RoleName string `xml:"RoleName"`
315 ConfigurationSets []ConfigurationSet `xml:"ConfigurationSets>ConfigurationSet"`315 OsVersion string `xml:"OsVersion,omitempty"`
316 OSVirtualHardDisk []OSVirtualHardDisk `xml:"OSVirtualHardDisk"`316 RoleType string `xml:"RoleType"` // Always "PersistentVMRole"
317 RoleSize string `xml:"RoleSize"`317 ConfigurationSets []ConfigurationSet `xml:"ConfigurationSets>ConfigurationSet"`
318 AvailabilitySetName string `xml:"AvailabilitySetName,omitempty"`
319 DataVirtualHardDisks *[]DataVirtualHardDisk `xml:"DataVirtualHardDisks>DataVirtualHardDisk,omitempty"`
320 OSVirtualHardDisk *OSVirtualHardDisk `xml:"OSVirtualHardDisk,omitempty"`
321 RoleSize string `xml:"RoleSize"`
322 DefaultWinRmCertificateThumbprint string `xml:"DefaultWinRmCertificateThumbprint,omitempty"`
318}323}
319324
320//325//
@@ -325,14 +330,13 @@
325 return toxml(c)330 return toxml(c)
326}331}
327332
328func NewRole(RoleSize string, RoleName string,333func NewRole(RoleSize, RoleName string, vhd *OSVirtualHardDisk, ConfigurationSets []ConfigurationSet) *Role {
329 ConfigurationSets []ConfigurationSet, vhds []OSVirtualHardDisk) *Role {
330 return &Role{334 return &Role{
331 RoleSize: RoleSize,335 RoleSize: RoleSize,
332 RoleName: RoleName,336 RoleName: RoleName,
333 RoleType: "PersistentVMRole",337 RoleType: "PersistentVMRole",
334 ConfigurationSets: ConfigurationSets,338 ConfigurationSets: ConfigurationSets,
335 OSVirtualHardDisk: vhds,339 OSVirtualHardDisk: vhd,
336 }340 }
337}341}
338342
@@ -600,24 +604,18 @@
600//604//
601// PersistentVMRole, as used by GetRole, UpdateRole, etc.605// PersistentVMRole, as used by GetRole, UpdateRole, etc.
602//606//
603type PersistentVMRole struct {607type PersistentVMRole Role
604 XMLNS string `xml:"xmlns,attr"`
605 RoleName string `xml:"RoleName"`
606 OsVersion string `xml:"OsVersion"`
607 RoleType string `xml:"RoleType"` // Always PersistentVMRole
608 ConfigurationSets []ConfigurationSet `xml:"ConfigurationSets>ConfigurationSet"`
609 AvailabilitySetName string `xml:"AvailabilitySetName"`
610 DataVirtualHardDisks *[]DataVirtualHardDisk `xml:"DataVirtualHardDisks>DataVirtualHardDisk,omitempty"`
611 OSVirtualHardDisk OSVirtualHardDisk `xml:"OSVirtualHardDisk"`
612 RoleSize string `xml:"RoleSize"`
613 DefaultWinRmCertificateThumbprint string `xml:"DefaultWinRmCertificateThumbprint"`
614}
615608
616func (role *PersistentVMRole) Deserialize(data []byte) error {609func (role *PersistentVMRole) Deserialize(data []byte) error {
617 return xml.Unmarshal(data, role)610 return xml.Unmarshal(data, role)
618}611}
619612
620func (role *PersistentVMRole) Serialize() (string, error) {613func (role *PersistentVMRole) Serialize() (string, error) {
614 if role.XMLNS == "" {
615 clone := *role
616 clone.XMLNS = XMLNS
617 role = &clone
618 }
621 return toxml(role)619 return toxml(role)
622}620}
623621
624622
=== modified file 'xmlobjects_test.go'
--- xmlobjects_test.go 2013-10-31 07:59:14 +0000
+++ xmlobjects_test.go 2014-03-10 04:06:20 +0000
@@ -291,7 +291,7 @@
291 MediaLink: "path-to-vhd",291 MediaLink: "path-to-vhd",
292 },292 },
293 },293 },
294 OSVirtualHardDisk: OSVirtualHardDisk{294 OSVirtualHardDisk: &OSVirtualHardDisk{
295 HostCaching: "host-caching-mode-of-os-disk",295 HostCaching: "host-caching-mode-of-os-disk",
296 DiskName: "name-of-os-disk",296 DiskName: "name-of-os-disk",
297 MediaLink: "path-to-vhd",297 MediaLink: "path-to-vhd",
@@ -360,7 +360,7 @@
360 MediaLink: "path-to-vhd",360 MediaLink: "path-to-vhd",
361 },361 },
362 },362 },
363 OSVirtualHardDisk: OSVirtualHardDisk{363 OSVirtualHardDisk: &OSVirtualHardDisk{
364 HostCaching: "host-caching-mode-of-os-disk",364 HostCaching: "host-caching-mode-of-os-disk",
365 DiskName: "name-of-os-disk",365 DiskName: "name-of-os-disk",
366 MediaLink: "path-to-vhd",366 MediaLink: "path-to-vhd",
@@ -922,7 +922,8 @@
922 UpgradeDomainCount: "number-of-upgrade-domains-in-deployment",922 UpgradeDomainCount: "number-of-upgrade-domains-in-deployment",
923 RoleList: []Role{923 RoleList: []Role{
924 {924 {
925 RoleName: "name-of-role",925 RoleName: "name-of-role",
926 OsVersion: "operating-system-version",
926 ConfigurationSets: []ConfigurationSet{927 ConfigurationSets: []ConfigurationSet{
927 {928 {
928 ConfigurationSetType: "LinuxProvisioningConfiguration",929 ConfigurationSetType: "LinuxProvisioningConfiguration",
@@ -931,8 +932,9 @@
931 },932 },
932 },933 },
933 {934 {
934 RoleName: "name-of-role",935 RoleName: "name-of-role",
935 RoleType: "PersistentVMRole",936 OsVersion: "operating-system-version",
937 RoleType: "PersistentVMRole",
936 ConfigurationSets: []ConfigurationSet{938 ConfigurationSets: []ConfigurationSet{
937 {939 {
938 ConfigurationSetType: CONFIG_SET_NETWORK,940 ConfigurationSetType: CONFIG_SET_NETWORK,
@@ -947,15 +949,23 @@
947 SubnetNames: &[]string{"name-of-subnet"},949 SubnetNames: &[]string{"name-of-subnet"},
948 },950 },
949 },951 },
950 OSVirtualHardDisk: []OSVirtualHardDisk{952 AvailabilitySetName: "name-of-availability-set",
953 DataVirtualHardDisks: &[]DataVirtualHardDisk{
951 {954 {
952 HostCaching: "host-caching-mode-of-os-disk",955 HostCaching: "host-caching-mode-of-data-disk",
953 DiskName: "name-of-os-disk",956 DiskName: "name-of-data-disk",
954 MediaLink: "path-to-vhd",957 LUN: "logical-unit-number-of-data-disk",
955 SourceImageName: "image-used-to-create-os-disk",958 LogicalDiskSizeInGB: "size-of-data-disk",
956 OS: "operating-system-on-os-disk",959 MediaLink: "path-to-vhd",
957 },960 },
958 },961 },
962 OSVirtualHardDisk: &OSVirtualHardDisk{
963 HostCaching: "host-caching-mode-of-os-disk",
964 DiskName: "name-of-os-disk",
965 MediaLink: "path-to-vhd",
966 SourceImageName: "image-used-to-create-os-disk",
967 OS: "operating-system-on-os-disk",
968 },
959 RoleSize: "size-of-instance",969 RoleSize: "size-of-instance",
960 },970 },
961 },971 },
@@ -1030,7 +1040,7 @@
1030 deploymentSlot := "staging"1040 deploymentSlot := "staging"
1031 label := "deploymentLabel"1041 label := "deploymentLabel"
1032 vhd := NewOSVirtualHardDisk("hostCaching", "diskLabel", "diskName", "mediaLink", "sourceImageName", "os")1042 vhd := NewOSVirtualHardDisk("hostCaching", "diskLabel", "diskName", "mediaLink", "sourceImageName", "os")
1033 roles := []Role{*NewRole("size", "name", []ConfigurationSet{}, []OSVirtualHardDisk{*vhd})}1043 roles := []Role{*NewRole("size", "name", vhd, []ConfigurationSet{})}
1034 virtualNetworkName := "network"1044 virtualNetworkName := "network"
10351045
1036 deployment := NewDeploymentForCreateVMDeployment(name, deploymentSlot, label, roles, virtualNetworkName)1046 deployment := NewDeploymentForCreateVMDeployment(name, deploymentSlot, label, roles, virtualNetworkName)
@@ -1303,7 +1313,7 @@
1303 configset := []ConfigurationSet{*config}1313 configset := []ConfigurationSet{*config}
1304 vhd := NewOSVirtualHardDisk("hostCaching", "diskLabel", "diskName", "mediaLink", "sourceImageName", "os")1314 vhd := NewOSVirtualHardDisk("hostCaching", "diskLabel", "diskName", "mediaLink", "sourceImageName", "os")
13051315
1306 role := NewRole(rolesize, rolename, configset, []OSVirtualHardDisk{*vhd})1316 role := NewRole(rolesize, rolename, vhd, configset)
1307 c.Check(role.RoleSize, Equals, rolesize)1317 c.Check(role.RoleSize, Equals, rolesize)
1308 c.Check(role.RoleName, Equals, rolename)1318 c.Check(role.RoleName, Equals, rolename)
1309 c.Check(role.ConfigurationSets, DeepEquals, configset)1319 c.Check(role.ConfigurationSets, DeepEquals, configset)

Subscribers

People subscribed via source and target branches

to all changes: