sigs.k8s.io/cluster-api-provider-aws@v1.5.5/pkg/cloud/services/eks/identity_provider.go (about)

     1  /*
     2  Copyright 2021 The Kubernetes Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8  	http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package eks
    18  
    19  import (
    20  	"context"
    21  	"fmt"
    22  
    23  	"github.com/aws/aws-sdk-go/aws"
    24  	"github.com/aws/aws-sdk-go/service/eks"
    25  	"github.com/pkg/errors"
    26  
    27  	ekscontrolplanev1 "sigs.k8s.io/cluster-api-provider-aws/controlplane/eks/api/v1beta1"
    28  	"sigs.k8s.io/cluster-api-provider-aws/pkg/cloud/converters"
    29  	"sigs.k8s.io/cluster-api-provider-aws/pkg/eks/identityprovider"
    30  )
    31  
    32  func (s *Service) reconcileIdentityProvider(ctx context.Context) error {
    33  	s.scope.Info("reconciling oidc identity provider")
    34  	if s.scope.ControlPlane.Spec.OIDCIdentityProviderConfig == nil {
    35  		return nil
    36  	}
    37  
    38  	clusterName := s.scope.KubernetesClusterName()
    39  	current, err := s.getAssociatedIdentityProvider(ctx, clusterName)
    40  	if err != nil {
    41  		return errors.Wrap(err, "unable to list associated identity providers")
    42  	}
    43  
    44  	desired := converters.ConvertSDKToIdentityProvider(s.scope.OIDCIdentityProviderConfig())
    45  
    46  	if desired == nil && current == nil {
    47  		s.scope.Info("no identity provider required or installed, no action needed")
    48  		return nil
    49  	}
    50  
    51  	s.scope.V(2).Info("creating oidc provider plan", "desired", desired, "current", current)
    52  
    53  	identityProviderPlan := identityprovider.NewPlan(clusterName, current, desired, s.EKSClient, s.scope.Logger)
    54  
    55  	procedures, err := identityProviderPlan.Create(ctx)
    56  	if err != nil {
    57  		s.scope.Error(err, "failed creating eks identity provider plan")
    58  		return fmt.Errorf("creating eks identity provider plan: %w", err)
    59  	}
    60  	s.scope.V(2).Info("computed EKS identity provider plan", "numprocs", len(procedures))
    61  
    62  	// Perform required operations
    63  	for _, procedure := range procedures {
    64  		s.scope.Info("Executing identity provider procedure", "name", procedure.Name())
    65  		if err := procedure.Do(ctx); err != nil {
    66  			s.scope.Error(err, "failed executing identity provider procedure", "name", procedure.Name())
    67  			return fmt.Errorf("%s: %w", procedure.Name(), err)
    68  		}
    69  	}
    70  
    71  	latest, err := s.getAssociatedIdentityProvider(ctx, clusterName)
    72  	if err != nil {
    73  		return errors.Wrap(err, "getting associated identity provider")
    74  	}
    75  
    76  	if latest != nil {
    77  		s.scope.ControlPlane.Status.IdentityProviderStatus = ekscontrolplanev1.IdentityProviderStatus{
    78  			ARN:    aws.StringValue(latest.IdentityProviderConfigArn),
    79  			Status: aws.StringValue(latest.Status),
    80  		}
    81  
    82  		err := s.scope.PatchObject()
    83  		if err != nil {
    84  			return errors.Wrap(err, "updating identity provider status")
    85  		}
    86  	}
    87  
    88  	return nil
    89  }
    90  
    91  func (s *Service) getAssociatedIdentityProvider(ctx context.Context, clusterName string) (*identityprovider.OidcIdentityProviderConfig, error) {
    92  	list, err := s.EKSClient.ListIdentityProviderConfigsWithContext(ctx, &eks.ListIdentityProviderConfigsInput{
    93  		ClusterName: aws.String(clusterName),
    94  	})
    95  	if err != nil {
    96  		return nil, errors.Wrap(err, "listing identity provider configs")
    97  	}
    98  
    99  	// these is only one identity provider
   100  
   101  	if len(list.IdentityProviderConfigs) == 0 {
   102  		return nil, nil
   103  	}
   104  
   105  	providerconfig, err := s.EKSClient.DescribeIdentityProviderConfigWithContext(ctx, &eks.DescribeIdentityProviderConfigInput{
   106  		ClusterName:            aws.String(clusterName),
   107  		IdentityProviderConfig: list.IdentityProviderConfigs[0],
   108  	})
   109  
   110  	if err != nil {
   111  		return nil, errors.Wrap(err, "describing identity provider config")
   112  	}
   113  
   114  	config := providerconfig.IdentityProviderConfig.Oidc
   115  
   116  	return &identityprovider.OidcIdentityProviderConfig{
   117  		ClientID:                   *config.ClientId,
   118  		GroupsClaim:                config.GroupsClaim,
   119  		GroupsPrefix:               config.GroupsPrefix,
   120  		IdentityProviderConfigArn:  config.IdentityProviderConfigArn,
   121  		IdentityProviderConfigName: *config.IdentityProviderConfigName,
   122  		IssuerURL:                  *config.IssuerUrl,
   123  		RequiredClaims:             config.RequiredClaims,
   124  		Status:                     config.Status,
   125  		Tags:                       converters.MapPtrToMap(config.Tags),
   126  		UsernameClaim:              config.UsernameClaim,
   127  		UsernamePrefix:             config.UsernamePrefix,
   128  	}, nil
   129  }