Merge lp:~mark-sheahan-ms/gwacl/cert-args into lp:gwacl

Proposed by Mark Sheahan on 2014-09-25
Status: Merged
Merged at revision: 238
Proposed branch: lp:~mark-sheahan-ms/gwacl/cert-args
Merge into: lp:gwacl
Diff against target: 221 lines (+94/-10)
3 files modified
management_base.go (+44/-1)
management_base_test.go (+30/-6)
x509session.go (+20/-3)
To merge this branch: bzr merge lp:~mark-sheahan-ms/gwacl/cert-args
Reviewer Review Type Date Requested Status
Andrew Wilkins (community) 2014-09-25 Approve on 2014-09-25
Review via email: mp+235889@code.launchpad.net

Commit message

Add functions to instantiate a new management API, with the certificate+key provided as input byte arrays rather than a file path.

Description of the change

Add functions to instantiate a new management API, with the certificate+key provided as input byte arrays rather than a file path.

func NewManagementAPICertDataWithRetryPolicy(subscriptionId string, cert, key []byte, location string, policy RetryPolicy) (*ManagementAPI, error)

func NewManagementAPICertData(subscriptionId string, cert, key []byte, location string) (*ManagementAPI, error)

To post a comment you must log in.
Andrew Wilkins (axwalk) wrote :

Thank you. I've been meaning to do this for a while, but never got around to it. This looks good to land as is. Can you please take a moment to sign the CLA? http://www.ubuntu.com/legal/contributors

Andrew Wilkins (axwalk) :
review: Approve
Mark Sheahan (mark-sheahan-ms) wrote :

Thanks Andrew. I have signed the agreement as a contributor from ScriptRock
Inc.

What are the next steps for submission back into trunk? I haven't used
Bazaar or launchpad until yesterday.

Regards,
Mark

On Thu, Sep 25, 2014 at 12:05 AM, Andrew Wilkins <
<email address hidden>> wrote:

> Review: Approve
>
>
> --
> https://code.launchpad.net/~mark-sheahan-ms/gwacl/cert-args/+merge/235889
> You are the owner of lp:~mark-sheahan-ms/gwacl/cert-args.
>

Andrew Wilkins (axwalk) wrote :

Landing requires someone from the "GWACL Hackers" group (e.g. me) to push it through. I'll handle it from here. Thanks again.

Go Bot (go-bot) wrote :

The attempt to merge lp:~mark-sheahan-ms/gwacl/cert-args into lp:gwacl failed. Below is the output from the failed tests.

/bin/sh: 1: Syntax error: "&&" unexpected

Andrew Wilkins (axwalk) wrote :

I'll need to get in touch with the maintainer of the landing bot to see what's going on there.

Andrew Wilkins (axwalk) wrote :

I went ahead and merged manually. Thanks again.

Mark Sheahan (mark-sheahan-ms) wrote :

Thanks Andrew; hopefully we can contribute more as we use it more
extensively.

On Tue, Sep 30, 2014 at 6:09 PM, Andrew Wilkins <
<email address hidden>> wrote:

> I went ahead and merged manually. Thanks again.
> --
> https://code.launchpad.net/~mark-sheahan-ms/gwacl/cert-args/+merge/235889
> You are the owner of lp:~mark-sheahan-ms/gwacl/cert-args.
>

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'management_base.go'
2--- management_base.go 2014-06-24 09:32:41 +0000
3+++ management_base.go 2014-09-25 02:19:41 +0000
4@@ -9,6 +9,7 @@
5 "net/http"
6 "strings"
7 "time"
8+ "launchpad.net/gwacl/fork/tls"
9 )
10
11 // Note: each API call is required to include a version string in the request header.
12@@ -37,7 +38,8 @@
13 const DefaultPollerTimeout = 20 * time.Minute
14
15 // NewManagementAPIWithRetryPolicy creates an object used to interact with
16-// Windows Azure's API.
17+// Windows Azure's API. Certificate data is provided through a file path;
18+// the file must contain the private key, then the certificate, both in PEM format.
19 // http://msdn.microsoft.com/en-us/library/windowsazure/ff800682.aspx
20 func NewManagementAPIWithRetryPolicy(subscriptionId, certFile, location string, policy RetryPolicy) (*ManagementAPI, error) {
21 session, err := newX509Session(subscriptionId, certFile, location, policy)
22@@ -49,11 +51,52 @@
23 }
24
25 // NewManagementAPI creates an object used to interact with Windows Azure's API.
26+// Certificate data is provided through a file path; the file must contain the
27+// private key, then the certificate, both in PEM format.
28 // http://msdn.microsoft.com/en-us/library/windowsazure/ff800682.aspx
29 func NewManagementAPI(subscriptionId, certFile, location string) (*ManagementAPI, error) {
30 return NewManagementAPIWithRetryPolicy(subscriptionId, certFile, location, NoRetryPolicy)
31 }
32
33+// NewManagementAPICertDataWithRetryPolicy creates an object used to interact with
34+// Windows Azure's API. Certificate and private key data are provided through input
35+// byte arrays, each containing data in PEM format.
36+// http://msdn.microsoft.com/en-us/library/windowsazure/ff800682.aspx
37+func NewManagementAPICertDataWithRetryPolicy(subscriptionId string, cert, key []byte, location string, policy RetryPolicy) (*ManagementAPI, error) {
38+ session, err := newX509SessionCertData(subscriptionId, cert, key, location, policy)
39+ if err != nil {
40+ return nil, err
41+ }
42+ api := ManagementAPI{session, DefaultPollerInterval, DefaultPollerTimeout}
43+ return &api, nil
44+}
45+
46+// NewManagementAPICertData creates an object used to interact with Windows Azure's API.
47+// Certificate and private key data are provided through input byte arrays,
48+// each containing data in PEM format.
49+// http://msdn.microsoft.com/en-us/library/windowsazure/ff800682.aspx
50+func NewManagementAPICertData(subscriptionId string, cert, key []byte, location string) (*ManagementAPI, error) {
51+ return NewManagementAPICertDataWithRetryPolicy(subscriptionId, cert, key, location, NoRetryPolicy)
52+}
53+
54+// NewManagementAPICertsWithRetryPolicy creates an object used to interact with
55+// Windows Azure's API.
56+// http://msdn.microsoft.com/en-us/library/windowsazure/ff800682.aspx
57+func NewManagementAPICertsWithRetryPolicy(subscriptionId string, certs []tls.Certificate, location string, policy RetryPolicy) (*ManagementAPI, error) {
58+ session, err := newX509SessionCerts(subscriptionId, certs, location, policy)
59+ if err != nil {
60+ return nil, err
61+ }
62+ api := ManagementAPI{session, DefaultPollerInterval, DefaultPollerTimeout}
63+ return &api, nil
64+}
65+
66+// NewManagementAPICerts creates an object used to interact with Windows Azure's API.
67+// http://msdn.microsoft.com/en-us/library/windowsazure/ff800682.aspx
68+func NewManagementAPICerts(subscriptionId string, certs []tls.Certificate, location string) (*ManagementAPI, error) {
69+ return NewManagementAPICertsWithRetryPolicy(subscriptionId, certs, location, NoRetryPolicy)
70+}
71+
72 var operationIDHeaderName = http.CanonicalHeaderKey("x-ms-request-id")
73
74 // getOperationID extracts the Windows Azure operation ID from the headers
75
76=== modified file 'management_base_test.go'
77--- management_base_test.go 2014-03-12 03:56:53 +0000
78+++ management_base_test.go 2014-09-25 02:19:41 +0000
79@@ -4,6 +4,7 @@
80 package gwacl
81
82 import (
83+ "bytes"
84 "encoding/base64"
85 "encoding/xml"
86 "errors"
87@@ -207,7 +208,7 @@
88 c.Assert(err, IsNil)
89 }
90
91-var testCert = dedent.Dedent(`
92+var testKey = []byte(dedent.Dedent(`
93 -----BEGIN PRIVATE KEY-----
94 MIIBCgIBADANBgkqhkiG9w0BAQEFAASB9TCB8gIBAAIxAKQGQxP1i0VfCWn4KmMP
95 taUFn8sMBKjP/9vHnUYdZRvvmoJCA1C6arBUDp8s2DNX+QIDAQABAjBLRqhwN4dU
96@@ -216,6 +217,8 @@
97 GBW7VXLxbExpgnhb1V97vjQmTfthXQjYAwIYSTEjoFXm4+Bk5xuBh2IidgSeGZaC
98 FFY9AhkAsteo31cyQw2xJ80SWrmsIw+ps7Cvt5W9
99 -----END PRIVATE KEY-----
100+ `[1:]))
101+var testCert = []byte(dedent.Dedent(`
102 -----BEGIN CERTIFICATE-----
103 MIIBDzCByqADAgECAgkAgIBb3+lSwzEwDQYJKoZIhvcNAQEFBQAwFTETMBEGA1UE
104 AxQKQEhvc3ROYW1lQDAeFw0xMzA3MTkxNjA1NTRaFw0yMzA3MTcxNjA1NTRaMBUx
105@@ -224,20 +227,20 @@
106 AAGjDTALMAkGA1UdEwQCMAAwDQYJKoZIhvcNAQEFBQADMQABKfn08tKfzzqMMD2w
107 PI2fs3bw5bRH8tmGjrsJeEdp9crCBS8I3hKcxCkTTRTowdY=
108 -----END CERTIFICATE-----
109- `[1:])
110+ `[1:]))
111+var testCertKey = bytes.Join([][]byte{testKey, testCert}, []byte{})
112
113 func (suite *managementBaseAPISuite) TestNewManagementAPI(c *C) {
114 subscriptionId := "subscriptionId"
115 certDir := c.MkDir()
116 certFile := certDir + "/cert.pem"
117- err := ioutil.WriteFile(certFile, []byte(testCert), 0600)
118+ err := ioutil.WriteFile(certFile, testCertKey, 0600)
119 c.Assert(err, IsNil)
120
121 api, err := NewManagementAPI(subscriptionId, certFile, "West US")
122 c.Assert(err, IsNil)
123
124 c.Assert(api.session.subscriptionId, DeepEquals, subscriptionId)
125- c.Assert(api.session.certFile, DeepEquals, certFile)
126 c.Assert(api.session.retryPolicy, DeepEquals, NoRetryPolicy)
127 }
128
129@@ -245,7 +248,7 @@
130 subscriptionId := "subscriptionId"
131 certDir := c.MkDir()
132 certFile := certDir + "/cert.pem"
133- err := ioutil.WriteFile(certFile, []byte(testCert), 0600)
134+ err := ioutil.WriteFile(certFile, testCertKey, 0600)
135 c.Assert(err, IsNil)
136 retryPolicy := RetryPolicy{NbRetries: 5, HttpStatusCodes: []int{409}, Delay: time.Minute}
137
138@@ -253,7 +256,28 @@
139 c.Assert(err, IsNil)
140
141 c.Assert(api.session.subscriptionId, DeepEquals, subscriptionId)
142- c.Assert(api.session.certFile, DeepEquals, certFile)
143+ c.Assert(api.session.retryPolicy, DeepEquals, retryPolicy)
144+ c.Assert(api.GetRetryPolicy(), DeepEquals, retryPolicy)
145+}
146+
147+func (suite *managementBaseAPISuite) TestNewManagementAPICertData(c *C) {
148+ subscriptionId := "subscriptionId"
149+
150+ api, err := NewManagementAPICertData(subscriptionId, testCert, testKey, "West US")
151+ c.Assert(err, IsNil)
152+
153+ c.Assert(api.session.subscriptionId, DeepEquals, subscriptionId)
154+ c.Assert(api.session.retryPolicy, DeepEquals, NoRetryPolicy)
155+}
156+
157+func (suite *managementBaseAPISuite) TestNewManagementAPICertDataWithRetryPolicy(c *C) {
158+ subscriptionId := "subscriptionId"
159+ retryPolicy := RetryPolicy{NbRetries: 5, HttpStatusCodes: []int{409}, Delay: time.Minute}
160+
161+ api, err := NewManagementAPICertDataWithRetryPolicy(subscriptionId, testCert, testKey, "West US", retryPolicy)
162+ c.Assert(err, IsNil)
163+
164+ c.Assert(api.session.subscriptionId, DeepEquals, subscriptionId)
165 c.Assert(api.session.retryPolicy, DeepEquals, retryPolicy)
166 c.Assert(api.GetRetryPolicy(), DeepEquals, retryPolicy)
167 }
168
169=== modified file 'x509session.go'
170--- x509session.go 2014-02-04 08:58:10 +0000
171+++ x509session.go 2014-09-25 02:19:41 +0000
172@@ -14,7 +14,6 @@
173
174 type x509Session struct {
175 subscriptionId string
176- certFile string
177 client *http.Client
178 baseURL *url.URL
179 retryPolicy RetryPolicy
180@@ -32,13 +31,32 @@
181 func newX509Session(subscriptionId, certFile, location string, retryPolicy RetryPolicy) (*x509Session, error) {
182 certs := []tls.Certificate{}
183 if certFile != "" {
184- //
185 cert, err := tls.LoadX509KeyPair(certFile, certFile)
186 if err != nil {
187 return nil, err
188 }
189 certs = append(certs, cert)
190 }
191+ return newX509SessionCerts(subscriptionId, certs, location, retryPolicy)
192+}
193+
194+// newX509SessionCertData creates and returns a new x509Session based on credentials
195+// and X509 certificate byte arrays.
196+func newX509SessionCertData(subscriptionId string, cert, key []byte, location string, retryPolicy RetryPolicy) (*x509Session, error) {
197+ certs := []tls.Certificate{}
198+ if cert != nil && key != nil {
199+ cert, err := tls.X509KeyPair(cert, key)
200+ if err != nil {
201+ return nil, err
202+ }
203+ certs = append(certs, cert)
204+ }
205+ return newX509SessionCerts(subscriptionId, certs, location, retryPolicy)
206+}
207+
208+// newX509SessionCerts creates and returns a new x509Session based on credentials
209+// and X509 certificate files.
210+func newX509SessionCerts(subscriptionId string, certs []tls.Certificate, location string, retryPolicy RetryPolicy) (*x509Session, error) {
211 client := http.Client{
212 Transport: &http.Transport{
213 TLSClientConfig: &tls.Config{
214@@ -66,7 +84,6 @@
215
216 session := x509Session{
217 subscriptionId: subscriptionId,
218- certFile: certFile,
219 client: &client,
220 baseURL: baseURL,
221 retryPolicy: retryPolicy,

Subscribers

People subscribed via source and target branches

to all changes: