-
Notifications
You must be signed in to change notification settings - Fork 4.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add support for outputting kube config credentials from AKS (#953)
* Add kubeconfig to aks resource output * Added kube config to output variables * Updated docs * Fixed naming in docs * Rebased onto origin master * Refactored out kubernetes helper * Made kubeconfig embedded structs private * Loaded test configs from testdata directory * Added additional unit tests * Checking the outputs are set * Added raw kube config as output * Changes required for sdkv15 * Parsing the Kube Config as a raw string, since it's decoded via string(bytes) * Ensuring the Kubernetes Config is set & tested
- Loading branch information
1 parent
ad13561
commit 587c815
Showing
33 changed files
with
10,411 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
package kubernetes | ||
|
||
import ( | ||
"fmt" | ||
|
||
yaml "gopkg.in/yaml.v2" | ||
) | ||
|
||
type clusterItem struct { | ||
Name string `yaml:"name"` | ||
Cluster cluster `yaml:"cluster"` | ||
} | ||
|
||
type cluster struct { | ||
ClusterAuthorityData string `yaml:"certificate-authority-data"` | ||
Server string `yaml:"server"` | ||
} | ||
|
||
type userItem struct { | ||
Name string `yaml:"name"` | ||
User user `yaml:"user"` | ||
} | ||
|
||
type user struct { | ||
ClientCertificteData string `yaml:"client-certificate-data"` | ||
Token string `yaml:"token"` | ||
ClientKeyData string `yaml:"client-key-data"` | ||
} | ||
|
||
type contextItem struct { | ||
Name string `yaml:"name"` | ||
Context context `yaml:"context"` | ||
} | ||
|
||
type context struct { | ||
Cluster string `yaml:"cluster"` | ||
User string `yaml:"user"` | ||
Namespace string `yaml:"namespace,omitempty"` | ||
} | ||
|
||
type KubeConfig struct { | ||
APIVersion string `yaml:"apiVersion"` | ||
Clusters []clusterItem `yaml:"clusters"` | ||
Users []userItem `yaml:"users"` | ||
Contexts []contextItem `yaml:"contexts,omitempty"` | ||
CurrentContext string `yaml:"current-context,omitempty"` | ||
Kind string `yaml:"kind,omitempty"` | ||
Preferences map[string]interface{} `yaml:"preferences,omitempty"` | ||
} | ||
|
||
func ParseKubeConfig(config string) (*KubeConfig, error) { | ||
if config == "" { | ||
return nil, fmt.Errorf("Cannot parse empty config") | ||
} | ||
|
||
var kubeConfig KubeConfig | ||
err := yaml.Unmarshal([]byte(config), &kubeConfig) | ||
if err != nil { | ||
return nil, fmt.Errorf("Failed to unmarshal YAML config with error %+v", err) | ||
} | ||
if len(kubeConfig.Clusters) <= 0 || len(kubeConfig.Users) <= 0 { | ||
return nil, fmt.Errorf("Config %+v contains no valid clusters or users", kubeConfig) | ||
} | ||
user := kubeConfig.Users[0].User | ||
if user.Token == "" && (user.ClientCertificteData == "" || user.ClientKeyData == "") { | ||
return nil, fmt.Errorf("Config requires either token or certificate auth for user %+v", user) | ||
} | ||
cluster := kubeConfig.Clusters[0].Cluster | ||
if cluster.Server == "" { | ||
return nil, fmt.Errorf("Config has invalid or non existent server for cluster %+v", cluster) | ||
} | ||
|
||
return &kubeConfig, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,189 @@ | ||
package kubernetes | ||
|
||
import ( | ||
"fmt" | ||
"io/ioutil" | ||
"path/filepath" | ||
"reflect" | ||
"testing" | ||
) | ||
|
||
func TestParseKubeConfig(t *testing.T) { | ||
testCases := []struct { | ||
sourceFile string | ||
expected KubeConfig | ||
checkFunc func(expected KubeConfig, config string) (bool, error) | ||
}{ | ||
{ | ||
"user_with_token.yml", | ||
KubeConfig{ | ||
APIVersion: "v1", | ||
Clusters: []clusterItem{ | ||
{ | ||
Name: "test-cluster", | ||
Cluster: cluster{ | ||
Server: "https://testcluster.net:8080", | ||
}, | ||
}, | ||
}, | ||
Users: []userItem{ | ||
{ | ||
Name: "test-user", | ||
User: user{ | ||
Token: "test-token", | ||
}, | ||
}, | ||
}, | ||
Kind: "Config", | ||
}, | ||
isValidConfig, | ||
}, | ||
{ | ||
"user_with_cert.yml", | ||
KubeConfig{ | ||
APIVersion: "v1", | ||
Clusters: []clusterItem{ | ||
{ | ||
Name: "test-cluster", | ||
Cluster: cluster{ | ||
ClusterAuthorityData: "test-cluster-authority-data", | ||
Server: "https://testcluster.org:443", | ||
}, | ||
}, | ||
}, | ||
Users: []userItem{ | ||
{ | ||
Name: "test-user", | ||
User: user{ | ||
ClientCertificteData: "test-client-certificate-data", | ||
ClientKeyData: "test-client-key-data", | ||
}, | ||
}, | ||
}, | ||
Contexts: []contextItem{ | ||
{ | ||
Name: "test-cluster", | ||
Context: context{ | ||
Cluster: "test-cluster", | ||
User: "test-user", | ||
Namespace: "test-namespace", | ||
}, | ||
}, | ||
}, | ||
CurrentContext: "test-cluster", | ||
Kind: "Config", | ||
Preferences: nil, | ||
}, | ||
isValidConfig, | ||
}, | ||
{ | ||
"user_with_cert_token.yml", | ||
KubeConfig{ | ||
APIVersion: "v1", | ||
Clusters: []clusterItem{ | ||
{ | ||
Name: "test-cluster", | ||
Cluster: cluster{ | ||
ClusterAuthorityData: "test-cluster-authority-data", | ||
Server: "https://testcluster.org:443", | ||
}, | ||
}, | ||
}, | ||
Users: []userItem{ | ||
{ | ||
Name: "test-user", | ||
User: user{ | ||
ClientCertificteData: "test-client-certificate-data", | ||
ClientKeyData: "test-client-key-data", | ||
Token: "test-token", | ||
}, | ||
}, | ||
}, | ||
Contexts: []contextItem{ | ||
{ | ||
Name: "test-cluster", | ||
Context: context{ | ||
Cluster: "test-cluster", | ||
User: "test-user", | ||
Namespace: "test-namespace", | ||
}, | ||
}, | ||
}, | ||
CurrentContext: "test-cluster", | ||
Kind: "Config", | ||
Preferences: map[string]interface{}{ | ||
"colors": true, | ||
}, | ||
}, | ||
isValidConfig, | ||
}, | ||
{ | ||
"user_with_no_auth.yml", | ||
KubeConfig{}, | ||
isInvalidConfig, | ||
}, | ||
{ | ||
"no_cluster.yml", | ||
KubeConfig{}, | ||
isInvalidConfig, | ||
}, | ||
{ | ||
"no_user.yml", | ||
KubeConfig{}, | ||
isInvalidConfig, | ||
}, | ||
{ | ||
"user_with_partial_auth.yml", | ||
KubeConfig{}, | ||
isInvalidConfig, | ||
}, | ||
{ | ||
"cluster_with_no_server.yml", | ||
KubeConfig{}, | ||
isInvalidConfig, | ||
}, | ||
} | ||
|
||
for i, test := range testCases { | ||
encodedConfig := LoadConfig(test.sourceFile) | ||
if len(encodedConfig) <= 0 { | ||
t.Fatalf("Test case [%d]: Failed to read config from file '%+v' \n", | ||
i, test.sourceFile) | ||
} | ||
if success, err := test.checkFunc(test.expected, encodedConfig); !success { | ||
t.Fatalf("Test case [%d]: Failed, config '%+v' with error: '%+v'", | ||
i, test.sourceFile, err) | ||
} | ||
} | ||
} | ||
|
||
func isValidConfig(expected KubeConfig, encodedConfig string) (bool, error) { | ||
result, err := ParseKubeConfig(encodedConfig) | ||
if err != nil { | ||
return false, err | ||
} | ||
|
||
if !reflect.DeepEqual(expected, *result) { | ||
return false, fmt.Errorf("expected '%+v but got '%+v' with encoded config '%+v'", | ||
expected, *result, encodedConfig) | ||
} | ||
return true, nil | ||
} | ||
|
||
func isInvalidConfig(expected KubeConfig, encodedConfig string) (bool, error) { | ||
_, err := ParseKubeConfig(encodedConfig) | ||
if err == nil { | ||
return false, fmt.Errorf("expected test to throw error but didn't") | ||
} | ||
return true, nil | ||
} | ||
|
||
func LoadConfig(fileName string) string { | ||
filePath := filepath.Join("testdata", fileName) | ||
bytes, err := ioutil.ReadFile(filePath) | ||
if err != nil { | ||
return "" | ||
} | ||
|
||
return string(bytes) | ||
} |
9 changes: 9 additions & 0 deletions
9
azurerm/helpers/kubernetes/testdata/cluster_with_no_server.yml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
apiVersion: v1 | ||
clusters: | ||
- cluster: | ||
name: test-cluster | ||
users: | ||
- name: test-user | ||
user: | ||
token: test-token | ||
kind: Config |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
apiVersion: v1 | ||
clusters: | ||
users: | ||
- name: test-user | ||
user: | ||
token: test-token | ||
kind: Config |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
apiVersion: v1 | ||
clusters: | ||
- cluster: | ||
certificate-authority-data: test-cluster-authority-data | ||
server: https://testcluster.org:443 | ||
name: test-cluster | ||
users: |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
apiVersion: v1 | ||
clusters: | ||
- cluster: | ||
certificate-authority-data: test-cluster-authority-data | ||
server: https://testcluster.org:443 | ||
name: test-cluster | ||
contexts: | ||
- context: | ||
cluster: test-cluster | ||
user: test-user | ||
namespace: test-namespace | ||
name: test-cluster | ||
current-context: test-cluster | ||
users: | ||
- name: test-user | ||
user: | ||
client-certificate-data: test-client-certificate-data | ||
client-key-data: test-client-key-data | ||
kind: Config |
22 changes: 22 additions & 0 deletions
22
azurerm/helpers/kubernetes/testdata/user_with_cert_token.yml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
apiVersion: v1 | ||
clusters: | ||
- cluster: | ||
certificate-authority-data: test-cluster-authority-data | ||
server: https://testcluster.org:443 | ||
name: test-cluster | ||
contexts: | ||
- context: | ||
cluster: test-cluster | ||
user: test-user | ||
namespace: test-namespace | ||
name: test-cluster | ||
current-context: test-cluster | ||
users: | ||
- name: test-user | ||
user: | ||
client-certificate-data: test-client-certificate-data | ||
client-key-data: test-client-key-data | ||
token: test-token | ||
kind: Config | ||
preferences: | ||
colors: true |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
apiVersion: v1 | ||
clusters: | ||
- cluster: | ||
certificate-authority-data: test-cluster-authority-data | ||
server: https://testcluster.org:443 | ||
name: test-cluster | ||
users: | ||
- name: test-user | ||
user: |
20 changes: 20 additions & 0 deletions
20
azurerm/helpers/kubernetes/testdata/user_with_partial_auth.yml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
apiVersion: v1 | ||
clusters: | ||
- cluster: | ||
certificate-authority-data: test-cluster-authority-data | ||
server: https://testcluster.org:443 | ||
name: test-cluster | ||
contexts: | ||
- context: | ||
cluster: test-cluster | ||
user: test-user | ||
namespace: test-namespace | ||
name: test-cluster | ||
current-context: test-cluster | ||
users: | ||
- name: test-user | ||
user: | ||
client-certificate-data: test-client-certificate-data | ||
kind: Config | ||
preferences: | ||
colors: true |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
apiVersion: v1 | ||
clusters: | ||
- cluster: | ||
server: https://testcluster.net:8080 | ||
name: test-cluster | ||
users: | ||
- name: test-user | ||
user: | ||
token: test-token | ||
kind: Config |
Oops, something went wrong.