Skip to content

Commit

Permalink
Merge pull request #597 from ikolomiyets/master
Browse files Browse the repository at this point in the history
Kubelet 1.27.x failing to get credentials when credentialprovider.kubelet.k8s.io/v1 api is used
  • Loading branch information
k8s-ci-robot authored Apr 17, 2023
2 parents b36ba4d + 21900c5 commit 261c123
Show file tree
Hide file tree
Showing 5 changed files with 34 additions and 35 deletions.
10 changes: 5 additions & 5 deletions cmd/ecr-credential-provider/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ import (

metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/klog/v2"
"k8s.io/kubelet/pkg/apis/credentialprovider/v1alpha1"
"k8s.io/kubelet/pkg/apis/credentialprovider/v1"
)

var ecrPattern = regexp.MustCompile(`^(\d{12})\.dkr\.ecr(\-fips)?\.([a-zA-Z0-9][a-zA-Z0-9-_]*)\.(amazonaws\.com(\.cn)?|sc2s\.sgov\.gov|c2s\.ic\.gov)$`)
Expand All @@ -59,7 +59,7 @@ func defaultECRProvider(region string, registryID string) (*ecr.ECR, error) {
return ecr.New(sess), nil
}

func (e *ecrPlugin) GetCredentials(ctx context.Context, image string, args []string) (*v1alpha1.CredentialProviderResponse, error) {
func (e *ecrPlugin) GetCredentials(ctx context.Context, image string, args []string) (*v1.CredentialProviderResponse, error) {
registryID, region, registry, err := parseRepoURL(image)
if err != nil {
return nil, err
Expand Down Expand Up @@ -104,10 +104,10 @@ func (e *ecrPlugin) GetCredentials(ctx context.Context, image string, args []str

cacheDuration := getCacheDuration(data.ExpiresAt)

return &v1alpha1.CredentialProviderResponse{
CacheKeyType: v1alpha1.RegistryPluginCacheKeyType,
return &v1.CredentialProviderResponse{
CacheKeyType: v1.RegistryPluginCacheKeyType,
CacheDuration: cacheDuration,
Auth: map[string]v1alpha1.AuthConfig{
Auth: map[string]v1.AuthConfig{
registry: {
Username: parts[0],
Password: parts[1],
Expand Down
12 changes: 6 additions & 6 deletions cmd/ecr-credential-provider/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ import (
"github.com/golang/mock/gomock"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/cloud-provider-aws/pkg/providers/v2/mocks"
"k8s.io/kubelet/pkg/apis/credentialprovider/v1alpha1"
"k8s.io/kubelet/pkg/apis/credentialprovider/v1"
)

func generateGetAuthorizationTokenOutput(user string, password string, proxy string, expiration *time.Time) *ecr.GetAuthorizationTokenOutput {
Expand All @@ -45,11 +45,11 @@ func generateGetAuthorizationTokenOutput(user string, password string, proxy str
return output
}

func generateResponse(registry string, username string, password string) *v1alpha1.CredentialProviderResponse {
return &v1alpha1.CredentialProviderResponse{
CacheKeyType: v1alpha1.RegistryPluginCacheKeyType,
func generateResponse(registry string, username string, password string) *v1.CredentialProviderResponse {
return &v1.CredentialProviderResponse{
CacheKeyType: v1.RegistryPluginCacheKeyType,
CacheDuration: &metav1.Duration{Duration: 0},
Auth: map[string]v1alpha1.AuthConfig{
Auth: map[string]v1.AuthConfig{
registry: {
Username: username,
Password: password,
Expand All @@ -70,7 +70,7 @@ func Test_GetCredentials(t *testing.T) {
args []string
getAuthorizationTokenOutput *ecr.GetAuthorizationTokenOutput
getAuthorizationTokenError error
response *v1alpha1.CredentialProviderResponse
response *v1.CredentialProviderResponse
expectedError error
}{
{
Expand Down
25 changes: 12 additions & 13 deletions cmd/ecr-credential-provider/plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,13 @@ import (
"errors"
"fmt"
"io"
"io/ioutil"
"os"

"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/serializer"
"k8s.io/apimachinery/pkg/runtime/serializer/json"
"k8s.io/kubelet/pkg/apis/credentialprovider/install"
"k8s.io/kubelet/pkg/apis/credentialprovider/v1alpha1"
"k8s.io/kubelet/pkg/apis/credentialprovider/v1"
)

var (
Expand All @@ -44,7 +43,7 @@ func init() {
// CredentialProvider is an interface implemented by the kubelet credential provider plugin to fetch
// the username/password based on the provided image name.
type CredentialProvider interface {
GetCredentials(ctx context.Context, image string, args []string) (response *v1alpha1.CredentialProviderResponse, err error)
GetCredentials(ctx context.Context, image string, args []string) (response *v1.CredentialProviderResponse, err error)
}

// ExecPlugin implements the exec-based plugin for fetching credentials that is invoked by the kubelet.
Expand All @@ -59,15 +58,15 @@ func NewCredentialProvider(plugin CredentialProvider) *ExecPlugin {
}

// Run executes the credential provider plugin. Required information for the plugin request (in
// the form of v1alpha1.CredentialProviderRequest) is provided via stdin from the kubelet.
// the form of v1.CredentialProviderRequest) is provided via stdin from the kubelet.
// The CredentialProviderResponse, containing the username/password required for pulling
// the provided image, will be sent back to the kubelet via stdout.
func (e *ExecPlugin) Run(ctx context.Context) error {
return e.runPlugin(ctx, os.Stdin, os.Stdout, os.Args[1:])
}

func (e *ExecPlugin) runPlugin(ctx context.Context, r io.Reader, w io.Writer, args []string) error {
data, err := ioutil.ReadAll(r)
data, err := io.ReadAll(r)
if err != nil {
return err
}
Expand All @@ -77,7 +76,7 @@ func (e *ExecPlugin) runPlugin(ctx context.Context, r io.Reader, w io.Writer, ar
return err
}

if gvk.GroupVersion() != v1alpha1.SchemeGroupVersion {
if gvk.GroupVersion() != v1.SchemeGroupVersion {
return fmt.Errorf("group version %s is not supported", gvk.GroupVersion())
}

Expand Down Expand Up @@ -113,8 +112,8 @@ func (e *ExecPlugin) runPlugin(ctx context.Context, r io.Reader, w io.Writer, ar
return nil
}

func decodeRequest(data []byte) (*v1alpha1.CredentialProviderRequest, error) {
obj, gvk, err := codecs.UniversalDecoder(v1alpha1.SchemeGroupVersion).Decode(data, nil, nil)
func decodeRequest(data []byte) (*v1.CredentialProviderRequest, error) {
obj, gvk, err := codecs.UniversalDecoder(v1.SchemeGroupVersion).Decode(data, nil, nil)
if err != nil {
return nil, err
}
Expand All @@ -123,26 +122,26 @@ func decodeRequest(data []byte) (*v1alpha1.CredentialProviderRequest, error) {
return nil, fmt.Errorf("kind was %q, expected CredentialProviderRequest", gvk.Kind)
}

if gvk.Group != v1alpha1.GroupName {
return nil, fmt.Errorf("group was %q, expected %s", gvk.Group, v1alpha1.GroupName)
if gvk.Group != v1.GroupName {
return nil, fmt.Errorf("group was %q, expected %s", gvk.Group, v1.GroupName)
}

request, ok := obj.(*v1alpha1.CredentialProviderRequest)
request, ok := obj.(*v1.CredentialProviderRequest)
if !ok {
return nil, fmt.Errorf("unable to convert %T to *CredentialProviderRequest", obj)
}

return request, nil
}

func encodeResponse(response *v1alpha1.CredentialProviderResponse) ([]byte, error) {
func encodeResponse(response *v1.CredentialProviderResponse) ([]byte, error) {
mediaType := "application/json"
info, ok := runtime.SerializerInfoForMediaType(codecs.SupportedMediaTypes(), mediaType)
if !ok {
return nil, fmt.Errorf("unsupported media type %q", mediaType)
}

encoder := codecs.EncoderForVersion(info.Serializer, v1alpha1.SchemeGroupVersion)
encoder := codecs.EncoderForVersion(info.Serializer, v1.SchemeGroupVersion)
data, err := runtime.Encode(encoder, response)
if err != nil {
return nil, fmt.Errorf("failed to encode response: %v", err)
Expand Down
20 changes: 10 additions & 10 deletions cmd/ecr-credential-provider/plugin_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,17 @@ import (
"time"

metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/kubelet/pkg/apis/credentialprovider/v1alpha1"
"k8s.io/kubelet/pkg/apis/credentialprovider/v1"
)

type fakePlugin struct {
}

func (f *fakePlugin) GetCredentials(ctx context.Context, image string, args []string) (*v1alpha1.CredentialProviderResponse, error) {
return &v1alpha1.CredentialProviderResponse{
CacheKeyType: v1alpha1.RegistryPluginCacheKeyType,
func (f *fakePlugin) GetCredentials(ctx context.Context, image string, args []string) (*v1.CredentialProviderResponse, error) {
return &v1.CredentialProviderResponse{
CacheKeyType: v1.RegistryPluginCacheKeyType,
CacheDuration: &metav1.Duration{Duration: 10 * time.Minute},
Auth: map[string]v1alpha1.AuthConfig{
Auth: map[string]v1.AuthConfig{
"*.registry.io": {
Username: "user",
Password: "password",
Expand All @@ -52,26 +52,26 @@ func Test_runPlugin(t *testing.T) {
}{
{
name: "successful test case",
in: bytes.NewBufferString(`{"kind":"CredentialProviderRequest","apiVersion":"credentialprovider.kubelet.k8s.io/v1alpha1","image":"test.registry.io/foobar"}`),
expectedOut: []byte(`{"kind":"CredentialProviderResponse","apiVersion":"credentialprovider.kubelet.k8s.io/v1alpha1","cacheKeyType":"Registry","cacheDuration":"10m0s","auth":{"*.registry.io":{"username":"user","password":"password"}}}
in: bytes.NewBufferString(`{"kind":"CredentialProviderRequest","apiVersion":"credentialprovider.kubelet.k8s.io/v1","image":"test.registry.io/foobar"}`),
expectedOut: []byte(`{"kind":"CredentialProviderResponse","apiVersion":"credentialprovider.kubelet.k8s.io/v1","cacheKeyType":"Registry","cacheDuration":"10m0s","auth":{"*.registry.io":{"username":"user","password":"password"}}}
`),
expectErr: false,
},
{
name: "invalid kind",
in: bytes.NewBufferString(`{"kind":"CredentialProviderFoo","apiVersion":"credentialprovider.kubelet.k8s.io/v1alpha1","image":"test.registry.io/foobar"}`),
in: bytes.NewBufferString(`{"kind":"CredentialProviderFoo","apiVersion":"credentialprovider.kubelet.k8s.io/v1","image":"test.registry.io/foobar"}`),
expectedOut: nil,
expectErr: true,
},
{
name: "invalid apiVersion",
in: bytes.NewBufferString(`{"kind":"CredentialProviderRequest","apiVersion":"foo.k8s.io/v1alpha1","image":"test.registry.io/foobar"}`),
in: bytes.NewBufferString(`{"kind":"CredentialProviderRequest","apiVersion":"foo.k8s.io/v1","image":"test.registry.io/foobar"}`),
expectedOut: nil,
expectErr: true,
},
{
name: "empty image",
in: bytes.NewBufferString(`{"kind":"CredentialProviderRequest","apiVersion":"credentialprovider.kubelet.k8s.io/v1alpha1","image":""}`),
in: bytes.NewBufferString(`{"kind":"CredentialProviderRequest","apiVersion":"credentialprovider.kubelet.k8s.io/v1","image":""}`),
expectedOut: nil,
expectErr: true,
},
Expand Down
2 changes: 1 addition & 1 deletion docs/credential_provider.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ Example config:
"*.dkr.ecr.*.amazonaws.com",
"*.dkr.ecr.*.amazonaws.com.cn",
],
"apiVersion": "credentialprovider.kubelet.k8s.io/v1alpha1",
"apiVersion": "credentialprovider.kubelet.k8s.io/v1",
"defaultCacheDuration": "0"
}
]
Expand Down

0 comments on commit 261c123

Please sign in to comment.