github.com/telepresenceio/telepresence/v2@v2.20.0-pro.6.0.20240517030216-236ea954e789/pkg/authenticator/authenticator_test.go (about)

     1  package authenticator
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"testing"
     7  
     8  	"github.com/golang/mock/gomock"
     9  	"github.com/stretchr/testify/assert"
    10  	"github.com/stretchr/testify/suite"
    11  	clientcmd_api "k8s.io/client-go/tools/clientcmd/api"
    12  
    13  	mock_authenticator "github.com/telepresenceio/telepresence/v2/pkg/authenticator/mocks"
    14  )
    15  
    16  const mockExecCredentials = `{
    17      "kind": "ExecCredential",
    18      "apiVersion": "client.authentication.k8s.io/v1beta1",
    19      "spec": {
    20          "interactive": false
    21      },
    22      "status": {
    23          "expirationTimestamp": "2023-03-01T19:43:26Z",
    24          "token": "xxxx"
    25      }
    26  }`
    27  
    28  type SuiteService struct {
    29  	suite.Suite
    30  
    31  	ctrl *gomock.Controller
    32  
    33  	kubeClientConfig        *mock_authenticator.MockClientConfig
    34  	execCredentialsResolver *mock_authenticator.MockExecCredentialsResolver
    35  
    36  	service *Service
    37  }
    38  
    39  func (s *SuiteService) SetupTest() {
    40  	s.ctrl = gomock.NewController(s.T())
    41  
    42  	s.kubeClientConfig = mock_authenticator.NewMockClientConfig(s.ctrl)
    43  	s.execCredentialsResolver = mock_authenticator.NewMockExecCredentialsResolver(s.ctrl)
    44  
    45  	s.service = &Service{
    46  		kubeClientConfig:        s.kubeClientConfig,
    47  		execCredentialsResolver: s.execCredentialsResolver,
    48  	}
    49  }
    50  
    51  func (s *SuiteService) AfterTest() {
    52  	s.ctrl.Finish()
    53  }
    54  
    55  func (s *SuiteService) TestGetExecCredentialsGetRawConfigFail() {
    56  	// given
    57  	ctx := context.Background()
    58  	s.kubeClientConfig.EXPECT().RawConfig().Return(clientcmd_api.Config{}, fmt.Errorf("some internal error"))
    59  
    60  	// then
    61  	rawCredentials, err := s.service.GetExecCredentials(ctx, "context")
    62  
    63  	// when
    64  	assert.ErrorContains(s.T(), err, "some internal error")
    65  	assert.Empty(s.T(), rawCredentials)
    66  }
    67  
    68  func (s *SuiteService) TestGetExecCredentialsContextNotFound() {
    69  	// given
    70  	ctx := context.Background()
    71  	kubeConfig := clientcmd_api.Config{
    72  		AuthInfos: map[string]*clientcmd_api.AuthInfo{
    73  			"my-user": {
    74  				Exec: &clientcmd_api.ExecConfig{},
    75  			},
    76  		},
    77  		Contexts: map[string]*clientcmd_api.Context{
    78  			"my-context": {},
    79  		},
    80  		CurrentContext: "my-context",
    81  	}
    82  	s.kubeClientConfig.EXPECT().RawConfig().Return(kubeConfig, nil)
    83  
    84  	// then
    85  	rawCredentials, err := s.service.GetExecCredentials(ctx, "unknown-context")
    86  
    87  	// when
    88  	assert.ErrorContains(s.T(), err, "failed to get exec config from context unknown-context, kube context unknown-context doesn't exist")
    89  	assert.Empty(s.T(), rawCredentials)
    90  }
    91  
    92  func (s *SuiteService) TestGetExecCredentialsAuthInfoNotFound() {
    93  	// given
    94  	ctx := context.Background()
    95  	kubeConfig := clientcmd_api.Config{
    96  		Clusters: map[string]*clientcmd_api.Cluster{
    97  			"my-cluster": {},
    98  		},
    99  		AuthInfos: map[string]*clientcmd_api.AuthInfo{
   100  			"my-user": {},
   101  		},
   102  		Contexts: map[string]*clientcmd_api.Context{
   103  			"my-context": {
   104  				Cluster:  "my-cluster",
   105  				AuthInfo: "my-unknown-user",
   106  			},
   107  		},
   108  		CurrentContext: "my-context",
   109  	}
   110  	s.kubeClientConfig.EXPECT().RawConfig().Return(kubeConfig, nil)
   111  
   112  	// then
   113  	rawCredentials, err := s.service.GetExecCredentials(ctx, "my-context")
   114  
   115  	// when
   116  	assert.ErrorContains(s.T(), err, "failed to get exec config from context my-context, auth info my-unknown-user doesn't exist")
   117  	assert.Nil(s.T(), rawCredentials)
   118  }
   119  
   120  func (s *SuiteService) TestGetExecCredentialsAuthInfoNotExecType() {
   121  	// given
   122  	ctx := context.Background()
   123  	kubeConfig := clientcmd_api.Config{
   124  		Clusters: map[string]*clientcmd_api.Cluster{
   125  			"my-cluster": {},
   126  		},
   127  		AuthInfos: map[string]*clientcmd_api.AuthInfo{
   128  			"my-user": {},
   129  		},
   130  		Contexts: map[string]*clientcmd_api.Context{
   131  			"my-context": {
   132  				Cluster:  "unknown-cluster",
   133  				AuthInfo: "my-user",
   134  			},
   135  		},
   136  		CurrentContext: "my-context",
   137  	}
   138  	s.kubeClientConfig.EXPECT().RawConfig().Return(kubeConfig, nil)
   139  
   140  	// then
   141  	rawCredentials, err := s.service.GetExecCredentials(ctx, "my-context")
   142  
   143  	// when
   144  	assert.ErrorContains(s.T(), err, "failed to get exec config from context my-context, auth info my-user isn't of type exec")
   145  	assert.Nil(s.T(), rawCredentials)
   146  }
   147  
   148  var mockKubeConfig = clientcmd_api.Config{
   149  	Clusters: map[string]*clientcmd_api.Cluster{
   150  		"my-cluster": {},
   151  	},
   152  	AuthInfos: map[string]*clientcmd_api.AuthInfo{
   153  		"my-user": {
   154  			Exec: &clientcmd_api.ExecConfig{
   155  				Command: "/opt/homebrew/Caskroom/google-cloud-sdk/latest/google-cloud-sdk/bin/gke-gcloud-auth-plugin",
   156  				Args:    []string{"jdoe@gmail.com"},
   157  				Env: []clientcmd_api.ExecEnvVar{
   158  					{
   159  						Name:  "SOME_VAR",
   160  						Value: "SOME_VALUE",
   161  					},
   162  				},
   163  			},
   164  		},
   165  	},
   166  	Contexts: map[string]*clientcmd_api.Context{
   167  		"my-context": {
   168  			Cluster:  "my-cluster",
   169  			AuthInfo: "my-user",
   170  		},
   171  	},
   172  	CurrentContext: "my-context",
   173  }
   174  
   175  func (s *SuiteService) TestGetExecCredentialsResolveFailure() {
   176  	// given
   177  	ctx := context.Background()
   178  	s.kubeClientConfig.EXPECT().RawConfig().Return(mockKubeConfig, nil)
   179  	s.execCredentialsResolver.EXPECT().Resolve(ctx, &clientcmd_api.ExecConfig{
   180  		Command: mockKubeConfig.AuthInfos["my-user"].Exec.Command,
   181  		Args:    mockKubeConfig.AuthInfos["my-user"].Exec.Args,
   182  		Env:     mockKubeConfig.AuthInfos["my-user"].Exec.Env,
   183  	}).Return(nil, fmt.Errorf("some internal error"))
   184  
   185  	// then
   186  	rawCredentials, err := s.service.GetExecCredentials(ctx, "my-context")
   187  
   188  	// when
   189  	assert.ErrorContains(s.T(), err, "some internal error")
   190  	assert.Nil(s.T(), rawCredentials)
   191  }
   192  
   193  func (s *SuiteService) TestGetExecCredentialsSuccess() {
   194  	// given
   195  	ctx := context.Background()
   196  	s.kubeClientConfig.EXPECT().RawConfig().Return(mockKubeConfig, nil)
   197  	s.execCredentialsResolver.EXPECT().Resolve(ctx, &clientcmd_api.ExecConfig{
   198  		Command: mockKubeConfig.AuthInfos["my-user"].Exec.Command,
   199  		Args:    mockKubeConfig.AuthInfos["my-user"].Exec.Args,
   200  		Env:     mockKubeConfig.AuthInfos["my-user"].Exec.Env,
   201  	}).Return([]byte(mockExecCredentials), nil)
   202  
   203  	// then
   204  	rawCredentials, err := s.service.GetExecCredentials(ctx, "my-context")
   205  
   206  	// when
   207  	assert.NoError(s.T(), err)
   208  	assert.Equal(s.T(), []byte(mockExecCredentials), rawCredentials)
   209  }
   210  
   211  func TestSuiteService(t *testing.T) {
   212  	suite.Run(t, new(SuiteService))
   213  }