sigs.k8s.io/cluster-api-provider-aws@v1.5.5/pkg/eks/identityprovider/plan_test.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 identityprovider
    18  
    19  import (
    20  	"context"
    21  	"testing"
    22  
    23  	"github.com/aws/aws-sdk-go/aws"
    24  	"github.com/aws/aws-sdk-go/service/eks"
    25  	"github.com/golang/mock/gomock"
    26  	. "github.com/onsi/gomega"
    27  	"k8s.io/klog/v2/klogr"
    28  
    29  	infrav1 "sigs.k8s.io/cluster-api-provider-aws/api/v1beta1"
    30  	"sigs.k8s.io/cluster-api-provider-aws/pkg/cloud/services/eks/mock_eksiface"
    31  )
    32  
    33  func TestEKSAddonPlan(t *testing.T) {
    34  	clusterName := "default.cluster"
    35  	identityProviderARN := "aws:mock:provider:arn"
    36  	idnetityProviderName := "IdentityProviderConfigName"
    37  	log := klogr.New()
    38  
    39  	testCases := []struct {
    40  		name                    string
    41  		currentIdentityProvider *OidcIdentityProviderConfig
    42  		desiredIdentityProvider *OidcIdentityProviderConfig
    43  		expect                  func(m *mock_eksiface.MockEKSAPIMockRecorder)
    44  		expectCreateError       bool
    45  		expectDoError           bool
    46  	}{
    47  		{
    48  			name: "no desired and no installed",
    49  			expect: func(m *mock_eksiface.MockEKSAPIMockRecorder) {
    50  				// Do nothing
    51  			},
    52  			expectCreateError: false,
    53  			expectDoError:     false,
    54  		},
    55  		{
    56  			name: "no installed and 1 desired",
    57  			expect: func(m *mock_eksiface.MockEKSAPIMockRecorder) {
    58  				m.AssociateIdentityProviderConfigWithContext(gomock.Eq(context.TODO()), gomock.Eq(&eks.AssociateIdentityProviderConfigInput{
    59  					ClusterName: aws.String(clusterName),
    60  					Oidc:        createDesiredIdentityProviderRequest(aws.String(idnetityProviderName)),
    61  					Tags:        aws.StringMap(createTags()),
    62  				}))
    63  			},
    64  			desiredIdentityProvider: createDesiredIdentityProvider(idnetityProviderName, createTags()),
    65  			expectCreateError:       false,
    66  			expectDoError:           false,
    67  		},
    68  		{
    69  			name:                    "1 installed and 1 desired - both same and installed active",
    70  			currentIdentityProvider: createCurrentIdentityProvider(idnetityProviderName, identityProviderARN, eks.ConfigStatusActive, createTags()),
    71  			desiredIdentityProvider: createDesiredIdentityProvider(idnetityProviderName, createTags()),
    72  			expect: func(m *mock_eksiface.MockEKSAPIMockRecorder) {
    73  
    74  			},
    75  			expectCreateError: false,
    76  			expectDoError:     false,
    77  		},
    78  		{
    79  			name:                    "1 installed and 1 desired - both same and installed is creating",
    80  			currentIdentityProvider: createCurrentIdentityProvider(idnetityProviderName, identityProviderARN, eks.ConfigStatusCreating, createTags()),
    81  			desiredIdentityProvider: createDesiredIdentityProvider(idnetityProviderName, createTags()),
    82  			expect: func(m *mock_eksiface.MockEKSAPIMockRecorder) {
    83  				m.DescribeIdentityProviderConfigWithContext(gomock.Eq(context.TODO()),
    84  					gomock.Eq(&eks.DescribeIdentityProviderConfigInput{
    85  						ClusterName: aws.String(clusterName),
    86  						IdentityProviderConfig: &eks.IdentityProviderConfig{
    87  							Name: aws.String("IdentityProviderConfigName"),
    88  							Type: oidcType,
    89  						},
    90  					})).
    91  					Return(&eks.DescribeIdentityProviderConfigOutput{
    92  						IdentityProviderConfig: &eks.IdentityProviderConfigResponse{
    93  							Oidc: &eks.OidcIdentityProviderConfig{
    94  								ClusterName:                aws.String(clusterName),
    95  								IdentityProviderConfigArn:  aws.String(identityProviderARN),
    96  								IdentityProviderConfigName: aws.String("IdentityProviderConfigName"),
    97  								Status:                     aws.String(eks.ConfigStatusActive),
    98  								Tags:                       aws.StringMap(createTags()),
    99  							},
   100  						},
   101  					}, nil)
   102  			},
   103  			expectCreateError: false,
   104  			expectDoError:     false,
   105  		},
   106  
   107  		{
   108  			name:                    "1 installed and 1 desired - both same and installed is active",
   109  			currentIdentityProvider: createCurrentIdentityProvider(idnetityProviderName, identityProviderARN, eks.ConfigStatusActive, createTags()),
   110  			desiredIdentityProvider: createDesiredIdentityProvider(idnetityProviderName, createTags()),
   111  			expect: func(m *mock_eksiface.MockEKSAPIMockRecorder) {
   112  
   113  			},
   114  			expectCreateError: false,
   115  			expectDoError:     false,
   116  		},
   117  		{
   118  			name:                    "1 installed and 1 desired - both same and installed is active, and tags added",
   119  			currentIdentityProvider: createCurrentIdentityProvider(idnetityProviderName, identityProviderARN, eks.ConfigStatusActive, createTags()),
   120  			desiredIdentityProvider: createDesiredIdentityProvider(idnetityProviderName, changeTags(createTags())),
   121  			expect: func(m *mock_eksiface.MockEKSAPIMockRecorder) {
   122  				m.TagResource(gomock.Eq(&eks.TagResourceInput{
   123  					ResourceArn: aws.String(identityProviderARN),
   124  					Tags:        aws.StringMap(changeTags(createTags())),
   125  				}))
   126  			},
   127  			expectCreateError: false,
   128  			expectDoError:     false,
   129  		},
   130  		{
   131  			name:                    "1 installed and 1 desired - both same and installed is active, and tags removed",
   132  			currentIdentityProvider: createCurrentIdentityProvider(idnetityProviderName, identityProviderARN, eks.ConfigStatusActive, createTags()),
   133  			desiredIdentityProvider: createDesiredIdentityProvider(idnetityProviderName, nil),
   134  			expect: func(m *mock_eksiface.MockEKSAPIMockRecorder) {
   135  				m.UntagResource(gomock.Eq(&eks.UntagResourceInput{
   136  					ResourceArn: aws.String(identityProviderARN),
   137  					TagKeys:     []*string{aws.String("key1")},
   138  				}))
   139  			},
   140  			expectCreateError: false,
   141  			expectDoError:     false,
   142  		},
   143  
   144  		{
   145  			name:                    "1 installed and 0 desired - installed provider is removed",
   146  			currentIdentityProvider: createCurrentIdentityProvider(idnetityProviderName, identityProviderARN, eks.ConfigStatusActive, createTags()),
   147  			expect: func(m *mock_eksiface.MockEKSAPIMockRecorder) {
   148  				m.DisassociateIdentityProviderConfigWithContext(gomock.Eq(context.TODO()),
   149  					gomock.Eq(&eks.DisassociateIdentityProviderConfigInput{
   150  						ClusterName: aws.String(clusterName),
   151  						IdentityProviderConfig: &eks.IdentityProviderConfig{
   152  							Name: aws.String("IdentityProviderConfigName"),
   153  							Type: oidcType,
   154  						},
   155  					}))
   156  			},
   157  			expectCreateError: false,
   158  			expectDoError:     false,
   159  		},
   160  
   161  		{
   162  			name:                    "1 installed and desired client id changed - installed provider is removed",
   163  			currentIdentityProvider: createCurrentIdentityProvider(idnetityProviderName, identityProviderARN, eks.ConfigStatusActive, createTags()),
   164  			desiredIdentityProvider: createDesiredIdentityProviderWithDifferentClientID(idnetityProviderName, createTags()),
   165  			expect: func(m *mock_eksiface.MockEKSAPIMockRecorder) {
   166  				m.DisassociateIdentityProviderConfigWithContext(gomock.Eq(context.TODO()),
   167  					gomock.Eq(&eks.DisassociateIdentityProviderConfigInput{
   168  						ClusterName: aws.String(clusterName),
   169  						IdentityProviderConfig: &eks.IdentityProviderConfig{
   170  							Name: aws.String("IdentityProviderConfigName"),
   171  							Type: oidcType,
   172  						},
   173  					}))
   174  			},
   175  			expectCreateError: false,
   176  			expectDoError:     false,
   177  		},
   178  	}
   179  
   180  	for _, tc := range testCases {
   181  		t.Run(tc.name, func(t *testing.T) {
   182  			g := NewWithT(t)
   183  
   184  			mockControl := gomock.NewController(t)
   185  			defer mockControl.Finish()
   186  
   187  			eksMock := mock_eksiface.NewMockEKSAPI(mockControl)
   188  			tc.expect(eksMock.EXPECT())
   189  
   190  			ctx := context.TODO()
   191  
   192  			planner := NewPlan(clusterName, tc.currentIdentityProvider, tc.desiredIdentityProvider, eksMock, log)
   193  			procedures, err := planner.Create(ctx)
   194  			if tc.expectCreateError {
   195  				g.Expect(err).To(HaveOccurred())
   196  				return
   197  			}
   198  			g.Expect(err).To(BeNil())
   199  			g.Expect(procedures).NotTo(BeNil())
   200  
   201  			for _, proc := range procedures {
   202  				procErr := proc.Do(ctx)
   203  				if tc.expectDoError {
   204  					g.Expect(procErr).To(HaveOccurred())
   205  					return
   206  				}
   207  				g.Expect(procErr).To(BeNil())
   208  			}
   209  		})
   210  	}
   211  }
   212  
   213  func createTags() infrav1.Tags {
   214  	tags := infrav1.Tags{}
   215  	tags["key1"] = "value1"
   216  	return tags
   217  }
   218  
   219  func createDesiredIdentityProvider(name string, tags infrav1.Tags) *OidcIdentityProviderConfig {
   220  	return &OidcIdentityProviderConfig{
   221  		ClientID:                   "clientId",
   222  		IdentityProviderConfigName: name,
   223  		IssuerURL:                  "http://IssuerURL.com",
   224  		Tags:                       tags,
   225  	}
   226  }
   227  
   228  func createCurrentIdentityProvider(name string, arn, status string, tags infrav1.Tags) *OidcIdentityProviderConfig {
   229  	config := createDesiredIdentityProvider(name, tags)
   230  	config.IdentityProviderConfigArn = aws.String(arn)
   231  	config.Status = aws.String(status)
   232  
   233  	return config
   234  }
   235  
   236  func changeTags(original infrav1.Tags) infrav1.Tags {
   237  	original["key2"] = "value2"
   238  	return original
   239  }
   240  
   241  func createDesiredIdentityProviderRequest(name *string) *eks.OidcIdentityProviderConfigRequest {
   242  	return &eks.OidcIdentityProviderConfigRequest{
   243  		ClientId:                   aws.String("clientId"),
   244  		IdentityProviderConfigName: name,
   245  		IssuerUrl:                  aws.String("http://IssuerURL.com"),
   246  	}
   247  }
   248  
   249  func createDesiredIdentityProviderWithDifferentClientID(name string, tags infrav1.Tags) *OidcIdentityProviderConfig {
   250  	p := createDesiredIdentityProvider(name, tags)
   251  	p.ClientID = "clientId2"
   252  	return p
   253  }