compute: parse raw kubeconfig data into resource credentials secret keys format
Signed-off-by: Jared Watts <jbw976@gmail.com>
This commit is contained in:
parent
3012c705e7
commit
e1cd0967d5
|
|
@ -0,0 +1,99 @@
|
|||
/*
|
||||
Copyright 2018 The Crossplane Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
corev1alpha1 "github.com/crossplaneio/crossplane/pkg/apis/core/v1alpha1"
|
||||
"github.com/ghodss/yaml"
|
||||
kubectlv1 "k8s.io/client-go/tools/clientcmd/api/v1"
|
||||
)
|
||||
|
||||
func ParseKubeconfig(rawKubeconfig []byte) (map[string][]byte, error) {
|
||||
// unmarshal the raw kubeconfig into a strongly typed kubeconfig struct
|
||||
kubeconfig := &kubectlv1.Config{}
|
||||
if err := yaml.Unmarshal(rawKubeconfig, kubeconfig); err != nil {
|
||||
return nil, fmt.Errorf("failed to unmarshal kubeconfig: %+v", err)
|
||||
}
|
||||
|
||||
if len(kubeconfig.Contexts) == 0 {
|
||||
// no contexts in the kubeconfig, we can't return anything meaningful
|
||||
return nil, fmt.Errorf("no contexts found in kubeconfig")
|
||||
}
|
||||
|
||||
// find the current context for this kubeconfig
|
||||
var currentContext *kubectlv1.NamedContext
|
||||
if kubeconfig.CurrentContext == "" {
|
||||
// no current context set, just use the first context
|
||||
currentContext = &kubeconfig.Contexts[0]
|
||||
} else {
|
||||
// current context is set, find the matching named context
|
||||
for i, ctx := range kubeconfig.Contexts {
|
||||
if kubeconfig.CurrentContext == ctx.Name {
|
||||
currentContext = &kubeconfig.Contexts[i]
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if currentContext == nil {
|
||||
// failed to find a current context
|
||||
return nil, fmt.Errorf("failed to find current context in kubeconfig")
|
||||
}
|
||||
|
||||
// find the cluster for the current context
|
||||
var cluster *kubectlv1.NamedCluster
|
||||
for i, c := range kubeconfig.Clusters {
|
||||
if currentContext.Context.Cluster == c.Name {
|
||||
cluster = &kubeconfig.Clusters[i]
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if cluster == nil {
|
||||
// failed to find the current context's cluster
|
||||
return nil, fmt.Errorf("failed to find cluster %s in kubeconfig", currentContext.Context.Cluster)
|
||||
}
|
||||
|
||||
// find the auth info for the current context
|
||||
var authInfo *kubectlv1.NamedAuthInfo
|
||||
for i, ai := range kubeconfig.AuthInfos {
|
||||
if currentContext.Context.AuthInfo == ai.Name {
|
||||
authInfo = &kubeconfig.AuthInfos[i]
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if authInfo == nil {
|
||||
// failed to find the current context's auth info
|
||||
return nil, fmt.Errorf("failed to find auth info %s in kubeconfig", currentContext.Context.AuthInfo)
|
||||
}
|
||||
|
||||
// we have a context, a cluster, and an auth info. let's fill out the cluster resource map
|
||||
kubeconfigData := map[string][]byte{
|
||||
corev1alpha1.ResourceCredentialsSecretEndpointKey: []byte(cluster.Cluster.Server),
|
||||
corev1alpha1.ResourceCredentialsSecretUserKey: []byte(authInfo.AuthInfo.Username),
|
||||
corev1alpha1.ResourceCredentialsSecretPasswordKey: []byte(authInfo.AuthInfo.Password),
|
||||
corev1alpha1.ResourceCredentialsSecretCAKey: cluster.Cluster.CertificateAuthorityData,
|
||||
corev1alpha1.ResourceCredentialsSecretClientCertKey: authInfo.AuthInfo.ClientCertificateData,
|
||||
corev1alpha1.ResourceCredentialsSecretClientKeyKey: authInfo.AuthInfo.ClientKeyData,
|
||||
corev1alpha1.ResourceCredentialsTokenKey: []byte(authInfo.AuthInfo.Token),
|
||||
}
|
||||
|
||||
return kubeconfigData, nil
|
||||
}
|
||||
|
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
Copyright 2018 The Crossplane Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
corev1alpha1 "github.com/crossplaneio/crossplane/pkg/apis/core/v1alpha1"
|
||||
"github.com/onsi/gomega"
|
||||
)
|
||||
|
||||
const (
|
||||
// This data format is the general kubectl config (kubeconfig) format, but it specifically
|
||||
// came from the Azure AKS ListClusterAdminCredentials API:
|
||||
// https://docs.microsoft.com/en-us/rest/api/aks/managedclusters/listclusteradmincredentials
|
||||
// The values in it have all been replaced with fake data
|
||||
mockRawClusterCredentialsData = `apiVersion: v1
|
||||
clusters:
|
||||
- cluster:
|
||||
certificate-authority-data: Y2VydGlmaWNhdGUtYXV0aG9yaXR5LWRhdGEtdmFsdWU=
|
||||
server: https://crossplane-aks-55e038af.hcp.westus2.azmk8s.io:443
|
||||
name: aks-c7f893e4-d903-402c-ba60-8be6bbeac6a3
|
||||
contexts:
|
||||
- context:
|
||||
cluster: aks-c7f893e4-d903-402c-ba60-8be6bbeac6a3
|
||||
user: clusterAdmin_rg-123_aks-c7f893e4-d903-402c-ba60-8be6bbeac6a3
|
||||
namespace: foo
|
||||
name: aks-c7f893e4-d903-402c-ba60-8be6bbeac6a3
|
||||
current-context: aks-c7f893e4-d903-402c-ba60-8be6bbeac6a3
|
||||
kind: Config
|
||||
preferences: {}
|
||||
users:
|
||||
- name: clusterAdmin_rg-123_aks-c7f893e4-d903-402c-ba60-8be6bbeac6a3
|
||||
user:
|
||||
client-certificate-data: Y2xpZW50LWNlcnRpZmljYXRlLWRhdGEtdmFsdWU=
|
||||
client-key-data: Y2xpZW50LWtleS1kYXRhLXZhbHVl
|
||||
token: 799e6a56219da5ff09e3b41b1dd08f3f
|
||||
`
|
||||
)
|
||||
|
||||
func TestParseKubeconfig(t *testing.T) {
|
||||
g := gomega.NewGomegaWithT(t)
|
||||
|
||||
// the unmarshal of the raw data will decode the base64 encoded values, so we expect them in plain-text
|
||||
expectedKubeconfigData := map[string][]byte{
|
||||
corev1alpha1.ResourceCredentialsSecretEndpointKey: []byte("https://crossplane-aks-55e038af.hcp.westus2.azmk8s.io:443"),
|
||||
corev1alpha1.ResourceCredentialsSecretUserKey: []byte(""),
|
||||
corev1alpha1.ResourceCredentialsSecretPasswordKey: []byte(""),
|
||||
corev1alpha1.ResourceCredentialsSecretCAKey: []byte("certificate-authority-data-value"),
|
||||
corev1alpha1.ResourceCredentialsSecretClientCertKey: []byte("client-certificate-data-value"),
|
||||
corev1alpha1.ResourceCredentialsSecretClientKeyKey: []byte("client-key-data-value"),
|
||||
corev1alpha1.ResourceCredentialsTokenKey: []byte("799e6a56219da5ff09e3b41b1dd08f3f"),
|
||||
}
|
||||
|
||||
kubeconfigData, err := ParseKubeconfig([]byte(mockRawClusterCredentialsData))
|
||||
g.Expect(err).NotTo(gomega.HaveOccurred())
|
||||
g.Expect(kubeconfigData).To(gomega.Equal(expectedKubeconfigData))
|
||||
}
|
||||
|
|
@ -31,10 +31,10 @@ const (
|
|||
ResourceCredentialsSecretClientCertKey = "clientCert"
|
||||
// ResourceCredentialsSecretClientKeyKey is the key inside a connection secret for the client key
|
||||
ResourceCredentialsSecretClientKeyKey = "clientKey"
|
||||
// ResourceCredentialsSecretClusterConfigFile is the key inside a connection secret for the full cluster configuration file
|
||||
ResourceCredentialsSecretClusterConfigFile = "clusterConfig"
|
||||
// ResourceCredentialsTokenKey is the key inside a connection secret for the bearer token value
|
||||
ResourceCredentialsTokenKey = "token"
|
||||
// ResourceCredentialsSecretKubeconfigFileKey is the key inside a connection secret for the full kubeconfig file
|
||||
ResourceCredentialsSecretKubeconfigFileKey = "kubeconfig"
|
||||
)
|
||||
|
||||
// Resource defines operations supported by managed resource
|
||||
|
|
|
|||
Loading…
Reference in New Issue