1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
|
package management
import (
"encoding/base64"
"encoding/pem"
"encoding/xml"
"fmt"
"io/ioutil"
"golang.org/x/crypto/pkcs12"
)
// ClientFromPublishSettingsData unmarshalls the contents of a publish settings file
// from https://manage.windowsazure.com/publishsettings.
// If subscriptionID is left empty, the first subscription in the file is used.
func ClientFromPublishSettingsData(settingsData []byte, subscriptionID string) (client Client, err error) {
return ClientFromPublishSettingsDataWithConfig(settingsData, subscriptionID, DefaultConfig())
}
// ClientFromPublishSettingsFile reads a publish settings file downloaded from https://manage.windowsazure.com/publishsettings.
// If subscriptionID is left empty, the first subscription in the file is used.
func ClientFromPublishSettingsFile(filePath, subscriptionID string) (client Client, err error) {
return ClientFromPublishSettingsFileWithConfig(filePath, subscriptionID, DefaultConfig())
}
// ClientFromPublishSettingsFileWithConfig reads a publish settings file downloaded from https://manage.windowsazure.com/publishsettings.
// If subscriptionID is left empty, the first subscription in the file is used.
func ClientFromPublishSettingsFileWithConfig(filePath, subscriptionID string, config ClientConfig) (client Client, err error) {
if filePath == "" {
return client, fmt.Errorf(errParamNotSpecified, "filePath")
}
publishSettingsContent, err := ioutil.ReadFile(filePath)
if err != nil {
return client, err
}
return ClientFromPublishSettingsDataWithConfig(publishSettingsContent, subscriptionID, config)
}
// ClientFromPublishSettingsDataWithConfig unmarshalls the contents of a publish settings file
// from https://manage.windowsazure.com/publishsettings.
// If subscriptionID is left empty, the first subscription in the string is used.
func ClientFromPublishSettingsDataWithConfig(data []byte, subscriptionID string, config ClientConfig) (client Client, err error) {
publishData := publishData{}
if err = xml.Unmarshal(data, &publishData); err != nil {
return client, err
}
for _, profile := range publishData.PublishProfiles {
for _, sub := range profile.Subscriptions {
if sub.ID == subscriptionID || subscriptionID == "" {
base64Cert := sub.ManagementCertificate
if base64Cert == "" {
base64Cert = profile.ManagementCertificate
}
pfxData, err := base64.StdEncoding.DecodeString(base64Cert)
if err != nil {
return client, err
}
pems, err := pkcs12.ToPEM(pfxData, "")
cert := []byte{}
for _, b := range pems {
cert = append(cert, pem.EncodeToMemory(b)...)
}
config.ManagementURL = sub.ServiceManagementURL
return makeClient(sub.ID, cert, config)
}
}
}
return client, fmt.Errorf("could not find subscription '%s' in settings provided", subscriptionID)
}
type publishSettings struct {
SubscriptionID string
SubscriptionCert []byte
SubscriptionKey []byte
}
type publishData struct {
XMLName xml.Name `xml:"PublishData"`
PublishProfiles []publishProfile `xml:"PublishProfile"`
}
type publishProfile struct {
XMLName xml.Name `xml:"PublishProfile"`
SchemaVersion string `xml:",attr"`
PublishMethod string `xml:",attr"`
URL string `xml:"Url,attr"`
ManagementCertificate string `xml:",attr"`
Subscriptions []subscription `xml:"Subscription"`
}
type subscription struct {
XMLName xml.Name `xml:"Subscription"`
ServiceManagementURL string `xml:"ServiceManagementUrl,attr"`
ID string `xml:"Id,attr"`
Name string `xml:",attr"`
ManagementCertificate string `xml:",attr"`
}
|