* Read ACS Credentials for Azure Authentication Supprt a new environment variable: ACS_CREDENTIAL_LOCATION Expect the value to be the ACS credential filepath, which is the /etc/kubernetes/azure.json file generated on the ACS nodes. If the ACS_CREDENTIAL_LOCATION is specified and loaded, create the Azure Authentication class from its values. If the AZURE_AUTHENTICATION_LOCATION is specified and loaded, its values will overwrite the value above. Refactor the ACI provider and ACI client to be able to override the SPN by environment variable
105 lines
3.2 KiB
Go
105 lines
3.2 KiB
Go
package azure
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/binary"
|
|
"encoding/json"
|
|
"fmt"
|
|
"io/ioutil"
|
|
"unicode/utf16"
|
|
|
|
"github.com/dimchansky/utfbom"
|
|
)
|
|
|
|
// Authentication represents the authentication file for Azure.
|
|
type Authentication struct {
|
|
ClientID string `json:"clientId,omitempty"`
|
|
ClientSecret string `json:"clientSecret,omitempty"`
|
|
SubscriptionID string `json:"subscriptionId,omitempty"`
|
|
TenantID string `json:"tenantId,omitempty"`
|
|
ActiveDirectoryEndpoint string `json:"activeDirectoryEndpointUrl,omitempty"`
|
|
ResourceManagerEndpoint string `json:"resourceManagerEndpointUrl,omitempty"`
|
|
GraphResourceID string `json:"activeDirectoryGraphResourceId,omitempty"`
|
|
SQLManagementEndpoint string `json:"sqlManagementEndpointUrl,omitempty"`
|
|
GalleryEndpoint string `json:"galleryEndpointUrl,omitempty"`
|
|
ManagementEndpoint string `json:"managementEndpointUrl,omitempty"`
|
|
}
|
|
|
|
// NewAuthentication returns an authentication struct from user provided
|
|
// credentials.
|
|
func NewAuthentication(azureCloud, clientID, clientSecret, subscriptionID, tenantID string) *Authentication {
|
|
environment := PublicCloud
|
|
|
|
switch azureCloud {
|
|
case PublicCloud.Name:
|
|
environment = PublicCloud
|
|
break;
|
|
case USGovernmentCloud.Name:
|
|
environment = USGovernmentCloud
|
|
break;
|
|
case ChinaCloud.Name:
|
|
environment = ChinaCloud
|
|
break;
|
|
case GermanCloud.Name:
|
|
environment = GermanCloud
|
|
break;
|
|
}
|
|
|
|
return &Authentication{
|
|
ClientID: clientID,
|
|
ClientSecret: clientSecret,
|
|
SubscriptionID: subscriptionID,
|
|
TenantID: tenantID,
|
|
ActiveDirectoryEndpoint: environment.ActiveDirectoryEndpoint,
|
|
ResourceManagerEndpoint: environment.ResourceManagerEndpoint,
|
|
GraphResourceID: environment.GraphEndpoint,
|
|
SQLManagementEndpoint: environment.SQLDatabaseDNSSuffix,
|
|
GalleryEndpoint: environment.GalleryEndpoint,
|
|
ManagementEndpoint: environment.ServiceManagementEndpoint,
|
|
}
|
|
}
|
|
|
|
// NewAuthenticationFromFile returns an authentication struct from file path
|
|
func NewAuthenticationFromFile(filepath string) (*Authentication, error) {
|
|
b, err := ioutil.ReadFile(filepath)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("Reading authentication file %q failed: %v", filepath, err)
|
|
}
|
|
|
|
// Authentication file might be encoded.
|
|
decoded, err := decode(b)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("Decoding authentication file %q failed: %v", filepath, err)
|
|
}
|
|
|
|
// Unmarshal the authentication file.
|
|
var auth Authentication
|
|
if err := json.Unmarshal(decoded, &auth); err != nil {
|
|
return nil, err
|
|
}
|
|
return &auth, nil
|
|
|
|
}
|
|
|
|
func decode(b []byte) ([]byte, error) {
|
|
reader, enc := utfbom.Skip(bytes.NewReader(b))
|
|
|
|
switch enc {
|
|
case utfbom.UTF16LittleEndian:
|
|
u16 := make([]uint16, (len(b)/2)-1)
|
|
err := binary.Read(reader, binary.LittleEndian, &u16)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return []byte(string(utf16.Decode(u16))), nil
|
|
case utfbom.UTF16BigEndian:
|
|
u16 := make([]uint16, (len(b)/2)-1)
|
|
err := binary.Read(reader, binary.BigEndian, &u16)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return []byte(string(utf16.Decode(u16))), nil
|
|
}
|
|
return ioutil.ReadAll(reader)
|
|
}
|