github.com/juju/juju@v0.0.0-20240430160146-1752b71fcf00/caas/kubernetes/provider/credentials.go (about)

     1  // Copyright 2018 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package provider
     5  
     6  import (
     7  	jujuclock "github.com/juju/clock"
     8  	"github.com/juju/errors"
     9  
    10  	k8s "github.com/juju/juju/caas/kubernetes"
    11  	"github.com/juju/juju/caas/kubernetes/clientconfig"
    12  	k8scloud "github.com/juju/juju/caas/kubernetes/cloud"
    13  	"github.com/juju/juju/caas/kubernetes/provider/constants"
    14  	"github.com/juju/juju/cloud"
    15  	"github.com/juju/juju/environs"
    16  )
    17  
    18  type environProviderCredentials struct {
    19  	cmdRunner               CommandRunner
    20  	builtinCredentialGetter func(CommandRunner) (cloud.Credential, error)
    21  }
    22  
    23  // CredentialSchemas is part of the environs.ProviderCredentials interface.
    24  func (environProviderCredentials) CredentialSchemas() map[cloud.AuthType]cloud.CredentialSchema {
    25  	schemas := make(map[cloud.AuthType]cloud.CredentialSchema)
    26  	for k, v := range k8scloud.SupportedCredentialSchemas {
    27  		schemas[k] = v
    28  	}
    29  	for k, v := range k8scloud.LegacyCredentialSchemas {
    30  		schemas[k] = v
    31  	}
    32  	return schemas
    33  }
    34  
    35  // DetectCredentials is part of the environs.ProviderCredentials interface.
    36  func (environProviderCredentials) DetectCredentials(cloudName string) (*cloud.CloudCredential, error) {
    37  	clientConfigFunc, err := clientconfig.NewClientConfigReader(constants.CAASProviderType)
    38  	if err != nil {
    39  		return nil, errors.Trace(err)
    40  	}
    41  	caasConfig, err := clientConfigFunc("", nil, "", "", nil)
    42  	if err != nil {
    43  		return nil, errors.Trace(err)
    44  	}
    45  
    46  	if len(caasConfig.Contexts) == 0 {
    47  		return nil, errors.NotFoundf("k8s cluster definitions")
    48  	}
    49  
    50  	defaultContext := caasConfig.Contexts[caasConfig.CurrentContext]
    51  	result := &cloud.CloudCredential{
    52  		AuthCredentials:   caasConfig.Credentials,
    53  		DefaultCredential: defaultContext.CredentialName,
    54  	}
    55  	return result, nil
    56  }
    57  
    58  // FinalizeCredential is part of the environs.ProviderCredentials interface.
    59  func (environProviderCredentials) FinalizeCredential(_ environs.FinalizeCredentialContext, args environs.FinalizeCredentialParams) (*cloud.Credential, error) {
    60  	cred, err := k8scloud.MigrateLegacyCredential(&args.Credential)
    61  	if errors.IsNotSupported(err) {
    62  		return &args.Credential, nil
    63  	} else if err != nil {
    64  		return &cred, errors.Annotatef(err, "migrating credential %s", args.Credential.Label)
    65  	}
    66  	return &cred, nil
    67  }
    68  
    69  // RegisterCredentials is part of the environs.ProviderCredentialsRegister interface.
    70  func (p environProviderCredentials) RegisterCredentials(cld cloud.Cloud) (map[string]*cloud.CloudCredential, error) {
    71  	cloudName := cld.Name
    72  	if cloudName != k8s.K8sCloudMicrok8s {
    73  		return registerCredentialsKubeConfig(cld)
    74  	}
    75  	cred, err := p.builtinCredentialGetter(p.cmdRunner)
    76  
    77  	if err != nil {
    78  		return nil, errors.Trace(err)
    79  	}
    80  
    81  	return map[string]*cloud.CloudCredential{
    82  		cloudName: {
    83  			DefaultCredential: cloudName,
    84  			AuthCredentials: map[string]cloud.Credential{
    85  				cloudName: cred,
    86  			},
    87  		},
    88  	}, nil
    89  }
    90  
    91  func registerCredentialsKubeConfig(
    92  	cld cloud.Cloud,
    93  ) (map[string]*cloud.CloudCredential, error) {
    94  	k8sConfig, err := clientconfig.GetLocalKubeConfig()
    95  	if err != nil {
    96  		return make(map[string]*cloud.CloudCredential), errors.Annotate(err, "reading local kubeconf")
    97  	}
    98  
    99  	context, exists := k8sConfig.Contexts[cld.Name]
   100  	if !exists {
   101  		return make(map[string]*cloud.CloudCredential), nil
   102  	}
   103  
   104  	resolver := clientconfig.GetJujuAdminServiceAccountResolver(jujuclock.WallClock)
   105  	conf, err := resolver(cld.Name, k8sConfig, cld.Name)
   106  	if err != nil {
   107  		return make(map[string]*cloud.CloudCredential), errors.Annotatef(
   108  			err,
   109  			"registering juju admin service account for cloud %q", cld.Name)
   110  	}
   111  
   112  	cred, err := k8scloud.CredentialFromKubeConfig(context.AuthInfo, conf)
   113  	return map[string]*cloud.CloudCredential{
   114  		cld.Name: {
   115  			DefaultCredential: cld.Name,
   116  			AuthCredentials: map[string]cloud.Credential{
   117  				cld.Name: cred,
   118  			},
   119  		},
   120  	}, err
   121  }