/
authentication.go
114 lines (101 loc) · 3.46 KB
/
authentication.go
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
106
107
108
109
110
111
112
113
114
/*
Copyright (c) Microsoft Corporation.
Licensed under the Apache 2.0 license.
*/
package auth
import (
"bytes"
"context"
"encoding/binary"
"encoding/json"
"fmt"
"io"
"os"
"unicode/utf16"
"github.com/dimchansky/utfbom"
"github.com/virtual-kubelet/virtual-kubelet/log"
)
// 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"`
UserIdentityClientId string `json:"userIdentityClientId,omitempty"`
}
// NewAuthentication returns an Authentication struct from user provided credentials.
func NewAuthentication(clientID, clientSecret, subscriptionID, tenantID, userAssignedIdentityID string) *Authentication {
return &Authentication{
ClientID: clientID,
ClientSecret: clientSecret,
SubscriptionID: subscriptionID,
TenantID: tenantID,
UserIdentityClientId: userAssignedIdentityID,
}
}
// newAuthenticationFromFile returns an Authentication struct from file path.
func (a *Authentication) newAuthenticationFromFile(filepath string) error {
b, err := os.ReadFile(filepath)
if err != nil {
return fmt.Errorf("reading Authentication file %q failed: %v", filepath, err)
}
// Authentication file might be encoded.
decoded, err := a.decode(b)
if err != nil {
return fmt.Errorf("decoding Authentication file %q failed: %v", filepath, err)
}
// Unmarshal the Authentication file.
if err := json.Unmarshal(decoded, &a); err != nil {
return err
}
return nil
}
// aksCredential represents the credential file for AKS
type aksCredential struct {
Cloud string `json:"cloud"`
TenantID string `json:"tenantId"`
SubscriptionID string `json:"subscriptionId"`
ClientID string `json:"aadClientId"`
ClientSecret string `json:"aadClientSecret"`
ResourceGroup string `json:"resourceGroup"`
Region string `json:"location"`
VNetName string `json:"vnetName"`
VNetResourceGroup string `json:"vnetResourceGroup"`
UserAssignedIdentityID string `json:"userAssignedIdentityID"`
}
// newAKSCredential returns an aksCredential struct from file path.
func newAKSCredential(ctx context.Context, filePath string) (*aksCredential, error) {
logger := log.G(ctx).WithField("method", "newAKSCredential").WithField("file", filePath)
logger.Debug("Reading AKS credential file")
b, err := os.ReadFile(filePath)
if err != nil {
return nil, fmt.Errorf("reading AKS credential file %q failed: %v", filePath, err)
}
// Unmarshal the Authentication file.
var cred aksCredential
if err := json.Unmarshal(b, &cred); err != nil {
return nil, err
}
logger.Debug("load AKS credential file successfully")
return &cred, nil
}
func (a *Authentication) 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 io.ReadAll(reader)
}