diff --git a/pkg/kubelet/apis/config/types.go b/pkg/kubelet/apis/config/types.go index c7e5057257e..96481ad9f13 100644 --- a/pkg/kubelet/apis/config/types.go +++ b/pkg/kubelet/apis/config/types.go @@ -495,7 +495,8 @@ type CredentialProvider struct { DefaultCacheDuration *metav1.Duration // Required input version of the exec CredentialProviderRequest. The returned CredentialProviderResponse - // MUST use the same encoding version as the input. + // MUST use the same encoding version as the input. Current supported values are: + // - credentialprovider.kubelet.k8s.io/v1alpha1 APIVersion string // Arguments to pass to the command when executing it. diff --git a/staging/src/k8s.io/kubelet/BUILD b/staging/src/k8s.io/kubelet/BUILD index e84c3d6bac7..76a7c6f2fb3 100644 --- a/staging/src/k8s.io/kubelet/BUILD +++ b/staging/src/k8s.io/kubelet/BUILD @@ -11,6 +11,7 @@ filegroup( ":package-srcs", "//staging/src/k8s.io/kubelet/config/v1alpha1:all-srcs", "//staging/src/k8s.io/kubelet/config/v1beta1:all-srcs", + "//staging/src/k8s.io/kubelet/pkg/apis/credentialprovider:all-srcs", "//staging/src/k8s.io/kubelet/pkg/apis/deviceplugin/v1alpha:all-srcs", "//staging/src/k8s.io/kubelet/pkg/apis/deviceplugin/v1beta1:all-srcs", "//staging/src/k8s.io/kubelet/pkg/apis/pluginregistration/v1:all-srcs", diff --git a/staging/src/k8s.io/kubelet/config/v1alpha1/types.go b/staging/src/k8s.io/kubelet/config/v1alpha1/types.go index d9b2f67efc1..e869bc18244 100644 --- a/staging/src/k8s.io/kubelet/config/v1alpha1/types.go +++ b/staging/src/k8s.io/kubelet/config/v1alpha1/types.go @@ -74,7 +74,8 @@ type CredentialProvider struct { DefaultCacheDuration *metav1.Duration `json:"defaultCacheDuration"` // Required input version of the exec CredentialProviderRequest. The returned CredentialProviderResponse - // MUST use the same encoding version as the input. + // MUST use the same encoding version as the input. Current supported values are: + // - credentialprovider.kubelet.k8s.io/v1alpha1 APIVersion string `json:"apiVersion"` // Arguments to pass to the command when executing it. diff --git a/staging/src/k8s.io/kubelet/pkg/apis/credentialprovider/BUILD b/staging/src/k8s.io/kubelet/pkg/apis/credentialprovider/BUILD new file mode 100644 index 00000000000..b59f2a3ab23 --- /dev/null +++ b/staging/src/k8s.io/kubelet/pkg/apis/credentialprovider/BUILD @@ -0,0 +1,37 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") + +go_library( + name = "go_default_library", + srcs = [ + "doc.go", + "register.go", + "types.go", + "zz_generated.deepcopy.go", + ], + importmap = "k8s.io/kubernetes/vendor/k8s.io/kubelet/pkg/apis/credentialprovider", + importpath = "k8s.io/kubelet/pkg/apis/credentialprovider", + visibility = ["//visibility:public"], + deps = [ + "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", + "//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library", + "//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library", + ], +) + +filegroup( + name = "package-srcs", + srcs = glob(["**"]), + tags = ["automanaged"], + visibility = ["//visibility:private"], +) + +filegroup( + name = "all-srcs", + srcs = [ + ":package-srcs", + "//staging/src/k8s.io/kubelet/pkg/apis/credentialprovider/install:all-srcs", + "//staging/src/k8s.io/kubelet/pkg/apis/credentialprovider/v1alpha1:all-srcs", + ], + tags = ["automanaged"], + visibility = ["//visibility:public"], +) diff --git a/staging/src/k8s.io/kubelet/pkg/apis/credentialprovider/OWNERS b/staging/src/k8s.io/kubelet/pkg/apis/credentialprovider/OWNERS new file mode 100644 index 00000000000..b74b7dda04a --- /dev/null +++ b/staging/src/k8s.io/kubelet/pkg/apis/credentialprovider/OWNERS @@ -0,0 +1,10 @@ +# See the OWNERS docs at https://go.k8s.io/owners + +# Disable inheritance as this is an api owners file +options: + no_parent_owners: true +approvers: +- api-approvers +reviewers: +- sig-node-api-reviewers +- sig-auth-api-reviewers diff --git a/staging/src/k8s.io/kubelet/pkg/apis/credentialprovider/doc.go b/staging/src/k8s.io/kubelet/pkg/apis/credentialprovider/doc.go new file mode 100644 index 00000000000..181583089c8 --- /dev/null +++ b/staging/src/k8s.io/kubelet/pkg/apis/credentialprovider/doc.go @@ -0,0 +1,20 @@ +/* +Copyright 2020 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// +k8s:deepcopy-gen=package +// +groupName=credentialprovider.kubelet.k8s.io + +package credentialprovider // import "k8s.io/kubelet/pkg/apis/credentialprovider" diff --git a/staging/src/k8s.io/kubelet/pkg/apis/credentialprovider/install/BUILD b/staging/src/k8s.io/kubelet/pkg/apis/credentialprovider/install/BUILD new file mode 100644 index 00000000000..a85ef4812b9 --- /dev/null +++ b/staging/src/k8s.io/kubelet/pkg/apis/credentialprovider/install/BUILD @@ -0,0 +1,29 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") + +go_library( + name = "go_default_library", + srcs = ["install.go"], + importmap = "k8s.io/kubernetes/vendor/k8s.io/kubelet/pkg/apis/credentialprovider/install", + importpath = "k8s.io/kubelet/pkg/apis/credentialprovider/install", + visibility = ["//visibility:public"], + deps = [ + "//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library", + "//staging/src/k8s.io/apimachinery/pkg/util/runtime:go_default_library", + "//staging/src/k8s.io/kubelet/pkg/apis/credentialprovider:go_default_library", + "//staging/src/k8s.io/kubelet/pkg/apis/credentialprovider/v1alpha1:go_default_library", + ], +) + +filegroup( + name = "package-srcs", + srcs = glob(["**"]), + tags = ["automanaged"], + visibility = ["//visibility:private"], +) + +filegroup( + name = "all-srcs", + srcs = [":package-srcs"], + tags = ["automanaged"], + visibility = ["//visibility:public"], +) diff --git a/staging/src/k8s.io/kubelet/pkg/apis/credentialprovider/install/install.go b/staging/src/k8s.io/kubelet/pkg/apis/credentialprovider/install/install.go new file mode 100644 index 00000000000..df5225a870b --- /dev/null +++ b/staging/src/k8s.io/kubelet/pkg/apis/credentialprovider/install/install.go @@ -0,0 +1,31 @@ +/* +Copyright 2020 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package install + +import ( + "k8s.io/apimachinery/pkg/runtime" + utilruntime "k8s.io/apimachinery/pkg/util/runtime" + "k8s.io/kubelet/pkg/apis/credentialprovider" + "k8s.io/kubelet/pkg/apis/credentialprovider/v1alpha1" +) + +// Install registers the credentialprovider.kubelet.k8s.io APIs into the given scheme. +func Install(scheme *runtime.Scheme) { + utilruntime.Must(credentialprovider.AddToScheme(scheme)) + utilruntime.Must(v1alpha1.AddToScheme(scheme)) + utilruntime.Must(scheme.SetVersionPriority(v1alpha1.SchemeGroupVersion)) +} diff --git a/staging/src/k8s.io/kubelet/pkg/apis/credentialprovider/register.go b/staging/src/k8s.io/kubelet/pkg/apis/credentialprovider/register.go new file mode 100644 index 00000000000..9319c21fe67 --- /dev/null +++ b/staging/src/k8s.io/kubelet/pkg/apis/credentialprovider/register.go @@ -0,0 +1,41 @@ +/* +Copyright 2020 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package credentialprovider + +import ( + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +// GroupName is the group name use in this package +const GroupName = "credentialprovider.kubelet.k8s.io" + +// SchemeGroupVersion is group version used to register these objects +var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: runtime.APIVersionInternal} + +var ( + SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes) + AddToScheme = SchemeBuilder.AddToScheme +) + +func addKnownTypes(scheme *runtime.Scheme) error { + scheme.AddKnownTypes(SchemeGroupVersion, + &CredentialProviderRequest{}, + &CredentialProviderResponse{}, + ) + return nil +} diff --git a/staging/src/k8s.io/kubelet/pkg/apis/credentialprovider/types.go b/staging/src/k8s.io/kubelet/pkg/apis/credentialprovider/types.go new file mode 100644 index 00000000000..f8e84ae6e70 --- /dev/null +++ b/staging/src/k8s.io/kubelet/pkg/apis/credentialprovider/types.go @@ -0,0 +1,117 @@ +/* +Copyright 2020 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package credentialprovider + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// CredentialProviderRequest includes the image that the kubelet requires authentication for. +// Kubelet will pass this request object to the plugin via stdin. In general, plugins should +// prefer responding with the same apiVersion they were sent. +type CredentialProviderRequest struct { + metav1.TypeMeta + + // image is the container image that is being pulled as part of the + // credential provider plugin request. Plugins may optionally parse the image + // to extract any information required to fetch credentials. + Image string +} + +type PluginCacheKeyType string + +const ( + // ImagePluginCacheKeyType means the kubelet will cache credentials on a per-image basis, + // using the image passed from the kubelet directly as the cache key. This includes + // the registry domain, port (if specified), and path but does not include tags or SHAs. + ImagePluginCacheKeyType PluginCacheKeyType = "Image" + // RegistryPluginCacheKeyType means the kubelet will cache credentials on a per-registry basis. + // The cache key will be based on the registry domain and port (if present) parsed from the requested image. + RegistryPluginCacheKeyType PluginCacheKeyType = "Registry" + // GlobalPluginCacheKeyType means the kubelet will cache credentials for all images that + // match for a given plugin. This cache key should only be returned by plugins that do not use + // the image input at all. + GlobalPluginCacheKeyType PluginCacheKeyType = "Global" +) + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// CredentialProviderResponse holds credentials that the kubelet should use for the specified +// image provided in the original request. Kubelet will read the response from the plugin via stdout. +// This response should be set to the same apiVersion as CredentialProviderRequest. +type CredentialProviderResponse struct { + metav1.TypeMeta + + // cacheKeyType indiciates the type of caching key to use based on the image provided + // in the request. There are three valid values for the cache key type: Image, Registry, and + // Global. If an invalid value is specified, the response will NOT be used by the kubelet. + CacheKeyType PluginCacheKeyType + + // cacheDuration indicates the duration the provided credentials should be cached for. + // The kubelet will use this field to set the in-memory cache duration for credentials + // in the AuthConfig. If null, the kubelet will use defaultCacheDuration provided in + // CredentialProviderConfig. If set to 0, the kubelet will not cache the provided AuthConfig. + // +optional + CacheDuration *metav1.Duration + + // auth is a map containing authentication information passed into the kubelet. + // Each key is a match image string (more on this below). The corresponding authConfig value + // should be valid for all images that match against this key. A plugin should set + // this field to null if no valid credentials can be returned for the requested image. + // + // Each key in the map is a pattern which can optionally contain a port and a path. + // Globs can be used in the domain, but not in the port or the path. Globs are supported + // as subdomains like '*.k8s.io' or 'k8s.*.io', and top-level-domains such as 'k8s.*'. + // Matching partial subdomains like 'app*.k8s.io' is also supported. Each glob can only match + // a single subdomain segment, so *.io does not match *.k8s.io. + // + // The kubelet will match images against the key when all of the below are true: + // - Both contain the same number of domain parts and each part matches. + // - The URL path of an imageMatch must be a prefix of the target image URL path. + // - If the imageMatch contains a port, then the port must match in the image as well. + // + // When multiple keys are returned, the kubelet will traverse all keys in reverse order so that: + // - longer keys come before shorter keys with the same prefix + // - non-wildcard keys come before wildcard keys with the same prefix. + // + // For any given match, the kubelet will attempt an image pull with the provided credentials, + // stopping after the first successfully authenticated pull. + // + // Example keys: + // - 123456789.dkr.ecr.us-east-1.amazonaws.com + // - *.azurecr.io + // - gcr.io + // - *.*.registry.io + // - registry.io:8080/path + // +optional + Auth map[string]AuthConfig +} + +// AuthConfig contains authentication information for a container registry. +// Only username/password based authentication is supported today, but more authentication +// mechanisms may be added in the future. +type AuthConfig struct { + // username is the username used for authenticating to the container registry + // An empty username is valid. + Username string + + // password is the password used for authenticating to the container registry + // An empty password is valid. + Password string +} diff --git a/staging/src/k8s.io/kubelet/pkg/apis/credentialprovider/v1alpha1/BUILD b/staging/src/k8s.io/kubelet/pkg/apis/credentialprovider/v1alpha1/BUILD new file mode 100644 index 00000000000..d51534dfd39 --- /dev/null +++ b/staging/src/k8s.io/kubelet/pkg/apis/credentialprovider/v1alpha1/BUILD @@ -0,0 +1,37 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") + +go_library( + name = "go_default_library", + srcs = [ + "doc.go", + "register.go", + "types.go", + "zz_generated.conversion.go", + "zz_generated.deepcopy.go", + "zz_generated.defaults.go", + ], + importmap = "k8s.io/kubernetes/vendor/k8s.io/kubelet/pkg/apis/credentialprovider/v1alpha1", + importpath = "k8s.io/kubelet/pkg/apis/credentialprovider/v1alpha1", + visibility = ["//visibility:public"], + deps = [ + "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", + "//staging/src/k8s.io/apimachinery/pkg/conversion:go_default_library", + "//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library", + "//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library", + "//staging/src/k8s.io/kubelet/pkg/apis/credentialprovider:go_default_library", + ], +) + +filegroup( + name = "package-srcs", + srcs = glob(["**"]), + tags = ["automanaged"], + visibility = ["//visibility:private"], +) + +filegroup( + name = "all-srcs", + srcs = [":package-srcs"], + tags = ["automanaged"], + visibility = ["//visibility:public"], +) diff --git a/staging/src/k8s.io/kubelet/pkg/apis/credentialprovider/v1alpha1/doc.go b/staging/src/k8s.io/kubelet/pkg/apis/credentialprovider/v1alpha1/doc.go new file mode 100644 index 00000000000..6c0f42a0d70 --- /dev/null +++ b/staging/src/k8s.io/kubelet/pkg/apis/credentialprovider/v1alpha1/doc.go @@ -0,0 +1,22 @@ +/* +Copyright 2020 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// +k8s:deepcopy-gen=package +// +k8s:conversion-gen=k8s.io/kubelet/pkg/apis/credentialprovider +// +k8s:defaulter-gen=TypeMeta +// +groupName=credentialprovider.kubelet.k8s.io + +package v1alpha1 // import "k8s.io/kubelet/pkg/apis/credentialprovider/v1alpha1" diff --git a/staging/src/k8s.io/kubelet/pkg/apis/credentialprovider/v1alpha1/register.go b/staging/src/k8s.io/kubelet/pkg/apis/credentialprovider/v1alpha1/register.go new file mode 100644 index 00000000000..ac0984edbb0 --- /dev/null +++ b/staging/src/k8s.io/kubelet/pkg/apis/credentialprovider/v1alpha1/register.go @@ -0,0 +1,46 @@ +/* +Copyright 2020 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1alpha1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +// GroupName is the group name use in this package +const GroupName = "credentialprovider.kubelet.k8s.io" + +// SchemeGroupVersion is group version used to register these objects +var ( + SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: "v1alpha1"} + localSchemeBuilder = &SchemeBuilder +) + +var ( + SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes) + AddToScheme = SchemeBuilder.AddToScheme +) + +func addKnownTypes(scheme *runtime.Scheme) error { + scheme.AddKnownTypes(SchemeGroupVersion, + &CredentialProviderRequest{}, + &CredentialProviderResponse{}, + ) + metav1.AddToGroupVersion(scheme, SchemeGroupVersion) + return nil +} diff --git a/staging/src/k8s.io/kubelet/pkg/apis/credentialprovider/v1alpha1/types.go b/staging/src/k8s.io/kubelet/pkg/apis/credentialprovider/v1alpha1/types.go new file mode 100644 index 00000000000..ddc309c53f3 --- /dev/null +++ b/staging/src/k8s.io/kubelet/pkg/apis/credentialprovider/v1alpha1/types.go @@ -0,0 +1,117 @@ +/* +Copyright 2020 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1alpha1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// CredentialProviderRequest includes the image that the kubelet requires authentication for. +// Kubelet will pass this request object to the plugin via stdin. In general, plugins should +// prefer responding with the same apiVersion they were sent. +type CredentialProviderRequest struct { + metav1.TypeMeta `json:",inline"` + + // image is the container image that is being pulled as part of the + // credential provider plugin request. Plugins may optionally parse the image + // to extract any information required to fetch credentials. + Image string `json:"image"` +} + +type PluginCacheKeyType string + +const ( + // ImagePluginCacheKeyType means the kubelet will cache credentials on a per-image basis, + // using the image passed from the kubelet directly as the cache key. This includes + // the registry domain, port (if specified), and path but does not include tags or SHAs. + ImagePluginCacheKeyType PluginCacheKeyType = "Image" + // RegistryPluginCacheKeyType means the kubelet will cache credentials on a per-registry basis. + // The cache key will be based on the registry domain and port (if present) parsed from the requested image. + RegistryPluginCacheKeyType PluginCacheKeyType = "Registry" + // GlobalPluginCacheKeyType means the kubelet will cache credentials for all images that + // match for a given plugin. This cache key should only be returned by plugins that do not use + // the image input at all. + GlobalPluginCacheKeyType PluginCacheKeyType = "Global" +) + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// CredentialProviderResponse holds credentials that the kubelet should use for the specified +// image provided in the original request. Kubelet will read the response from the plugin via stdout. +// This response should be set to the same apiVersion as CredentialProviderRequest. +type CredentialProviderResponse struct { + metav1.TypeMeta `json:",inline"` + + // cacheKeyType indiciates the type of caching key to use based on the image provided + // in the request. There are three valid values for the cache key type: Image, Registry, and + // Global. If an invalid value is specified, the response will NOT be used by the kubelet. + CacheKeyType PluginCacheKeyType `json:"cacheKeyType"` + + // cacheDuration indicates the duration the provided credentials should be cached for. + // The kubelet will use this field to set the in-memory cache duration for credentials + // in the AuthConfig. If null, the kubelet will use defaultCacheDuration provided in + // CredentialProviderConfig. If set to 0, the kubelet will not cache the provided AuthConfig. + // +optional + CacheDuration *metav1.Duration `json:"cacheDuration,omitempty"` + + // auth is a map containing authentication information passed into the kubelet. + // Each key is a match image string (more on this below). The corresponding authConfig value + // should be valid for all images that match against this key. A plugin should set + // this field to null if no valid credentials can be returned for the requested image. + // + // Each key in the map is a pattern which can optionally contain a port and a path. + // Globs can be used in the domain, but not in the port or the path. Globs are supported + // as subdomains like '*.k8s.io' or 'k8s.*.io', and top-level-domains such as 'k8s.*'. + // Matching partial subdomains like 'app*.k8s.io' is also supported. Each glob can only match + // a single subdomain segment, so *.io does not match *.k8s.io. + // + // The kubelet will match images against the key when all of the below are true: + // - Both contain the same number of domain parts and each part matches. + // - The URL path of an imageMatch must be a prefix of the target image URL path. + // - If the imageMatch contains a port, then the port must match in the image as well. + // + // When multiple keys are returned, the kubelet will traverse all keys in reverse order so that: + // - longer keys come before shorter keys with the same prefix + // - non-wildcard keys come before wildcard keys with the same prefix. + // + // For any given match, the kubelet will attempt an image pull with the provided credentials, + // stopping after the first successfully authenticated pull. + // + // Example keys: + // - 123456789.dkr.ecr.us-east-1.amazonaws.com + // - *.azurecr.io + // - gcr.io + // - *.*.registry.io + // - registry.io:8080/path + // +optional + Auth map[string]AuthConfig `json:"auth,omitempty"` +} + +// AuthConfig contains authentication information for a container registry. +// Only username/password based authentication is supported today, but more authentication +// mechanisms may be added in the future. +type AuthConfig struct { + // username is the username used for authenticating to the container registry + // An empty username is valid. + Username string `json:"username"` + + // password is the password used for authenticating to the container registry + // An empty password is valid. + Password string `json:"password"` +} diff --git a/staging/src/k8s.io/kubelet/pkg/apis/credentialprovider/v1alpha1/zz_generated.conversion.go b/staging/src/k8s.io/kubelet/pkg/apis/credentialprovider/v1alpha1/zz_generated.conversion.go new file mode 100644 index 00000000000..a51bdd5a955 --- /dev/null +++ b/staging/src/k8s.io/kubelet/pkg/apis/credentialprovider/v1alpha1/zz_generated.conversion.go @@ -0,0 +1,136 @@ +// +build !ignore_autogenerated + +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by conversion-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + unsafe "unsafe" + + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + conversion "k8s.io/apimachinery/pkg/conversion" + runtime "k8s.io/apimachinery/pkg/runtime" + credentialprovider "k8s.io/kubelet/pkg/apis/credentialprovider" +) + +func init() { + localSchemeBuilder.Register(RegisterConversions) +} + +// RegisterConversions adds conversion functions to the given scheme. +// Public to allow building arbitrary schemes. +func RegisterConversions(s *runtime.Scheme) error { + if err := s.AddGeneratedConversionFunc((*AuthConfig)(nil), (*credentialprovider.AuthConfig)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha1_AuthConfig_To_credentialprovider_AuthConfig(a.(*AuthConfig), b.(*credentialprovider.AuthConfig), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*credentialprovider.AuthConfig)(nil), (*AuthConfig)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_credentialprovider_AuthConfig_To_v1alpha1_AuthConfig(a.(*credentialprovider.AuthConfig), b.(*AuthConfig), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*CredentialProviderRequest)(nil), (*credentialprovider.CredentialProviderRequest)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha1_CredentialProviderRequest_To_credentialprovider_CredentialProviderRequest(a.(*CredentialProviderRequest), b.(*credentialprovider.CredentialProviderRequest), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*credentialprovider.CredentialProviderRequest)(nil), (*CredentialProviderRequest)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_credentialprovider_CredentialProviderRequest_To_v1alpha1_CredentialProviderRequest(a.(*credentialprovider.CredentialProviderRequest), b.(*CredentialProviderRequest), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*CredentialProviderResponse)(nil), (*credentialprovider.CredentialProviderResponse)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha1_CredentialProviderResponse_To_credentialprovider_CredentialProviderResponse(a.(*CredentialProviderResponse), b.(*credentialprovider.CredentialProviderResponse), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*credentialprovider.CredentialProviderResponse)(nil), (*CredentialProviderResponse)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_credentialprovider_CredentialProviderResponse_To_v1alpha1_CredentialProviderResponse(a.(*credentialprovider.CredentialProviderResponse), b.(*CredentialProviderResponse), scope) + }); err != nil { + return err + } + return nil +} + +func autoConvert_v1alpha1_AuthConfig_To_credentialprovider_AuthConfig(in *AuthConfig, out *credentialprovider.AuthConfig, s conversion.Scope) error { + out.Username = in.Username + out.Password = in.Password + return nil +} + +// Convert_v1alpha1_AuthConfig_To_credentialprovider_AuthConfig is an autogenerated conversion function. +func Convert_v1alpha1_AuthConfig_To_credentialprovider_AuthConfig(in *AuthConfig, out *credentialprovider.AuthConfig, s conversion.Scope) error { + return autoConvert_v1alpha1_AuthConfig_To_credentialprovider_AuthConfig(in, out, s) +} + +func autoConvert_credentialprovider_AuthConfig_To_v1alpha1_AuthConfig(in *credentialprovider.AuthConfig, out *AuthConfig, s conversion.Scope) error { + out.Username = in.Username + out.Password = in.Password + return nil +} + +// Convert_credentialprovider_AuthConfig_To_v1alpha1_AuthConfig is an autogenerated conversion function. +func Convert_credentialprovider_AuthConfig_To_v1alpha1_AuthConfig(in *credentialprovider.AuthConfig, out *AuthConfig, s conversion.Scope) error { + return autoConvert_credentialprovider_AuthConfig_To_v1alpha1_AuthConfig(in, out, s) +} + +func autoConvert_v1alpha1_CredentialProviderRequest_To_credentialprovider_CredentialProviderRequest(in *CredentialProviderRequest, out *credentialprovider.CredentialProviderRequest, s conversion.Scope) error { + out.Image = in.Image + return nil +} + +// Convert_v1alpha1_CredentialProviderRequest_To_credentialprovider_CredentialProviderRequest is an autogenerated conversion function. +func Convert_v1alpha1_CredentialProviderRequest_To_credentialprovider_CredentialProviderRequest(in *CredentialProviderRequest, out *credentialprovider.CredentialProviderRequest, s conversion.Scope) error { + return autoConvert_v1alpha1_CredentialProviderRequest_To_credentialprovider_CredentialProviderRequest(in, out, s) +} + +func autoConvert_credentialprovider_CredentialProviderRequest_To_v1alpha1_CredentialProviderRequest(in *credentialprovider.CredentialProviderRequest, out *CredentialProviderRequest, s conversion.Scope) error { + out.Image = in.Image + return nil +} + +// Convert_credentialprovider_CredentialProviderRequest_To_v1alpha1_CredentialProviderRequest is an autogenerated conversion function. +func Convert_credentialprovider_CredentialProviderRequest_To_v1alpha1_CredentialProviderRequest(in *credentialprovider.CredentialProviderRequest, out *CredentialProviderRequest, s conversion.Scope) error { + return autoConvert_credentialprovider_CredentialProviderRequest_To_v1alpha1_CredentialProviderRequest(in, out, s) +} + +func autoConvert_v1alpha1_CredentialProviderResponse_To_credentialprovider_CredentialProviderResponse(in *CredentialProviderResponse, out *credentialprovider.CredentialProviderResponse, s conversion.Scope) error { + out.CacheKeyType = credentialprovider.PluginCacheKeyType(in.CacheKeyType) + out.CacheDuration = (*v1.Duration)(unsafe.Pointer(in.CacheDuration)) + out.Auth = *(*map[string]credentialprovider.AuthConfig)(unsafe.Pointer(&in.Auth)) + return nil +} + +// Convert_v1alpha1_CredentialProviderResponse_To_credentialprovider_CredentialProviderResponse is an autogenerated conversion function. +func Convert_v1alpha1_CredentialProviderResponse_To_credentialprovider_CredentialProviderResponse(in *CredentialProviderResponse, out *credentialprovider.CredentialProviderResponse, s conversion.Scope) error { + return autoConvert_v1alpha1_CredentialProviderResponse_To_credentialprovider_CredentialProviderResponse(in, out, s) +} + +func autoConvert_credentialprovider_CredentialProviderResponse_To_v1alpha1_CredentialProviderResponse(in *credentialprovider.CredentialProviderResponse, out *CredentialProviderResponse, s conversion.Scope) error { + out.CacheKeyType = PluginCacheKeyType(in.CacheKeyType) + out.CacheDuration = (*v1.Duration)(unsafe.Pointer(in.CacheDuration)) + out.Auth = *(*map[string]AuthConfig)(unsafe.Pointer(&in.Auth)) + return nil +} + +// Convert_credentialprovider_CredentialProviderResponse_To_v1alpha1_CredentialProviderResponse is an autogenerated conversion function. +func Convert_credentialprovider_CredentialProviderResponse_To_v1alpha1_CredentialProviderResponse(in *credentialprovider.CredentialProviderResponse, out *CredentialProviderResponse, s conversion.Scope) error { + return autoConvert_credentialprovider_CredentialProviderResponse_To_v1alpha1_CredentialProviderResponse(in, out, s) +} diff --git a/staging/src/k8s.io/kubelet/pkg/apis/credentialprovider/v1alpha1/zz_generated.deepcopy.go b/staging/src/k8s.io/kubelet/pkg/apis/credentialprovider/v1alpha1/zz_generated.deepcopy.go new file mode 100644 index 00000000000..0a0e3acfefe --- /dev/null +++ b/staging/src/k8s.io/kubelet/pkg/apis/credentialprovider/v1alpha1/zz_generated.deepcopy.go @@ -0,0 +1,104 @@ +// +build !ignore_autogenerated + +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by deepcopy-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" +) + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AuthConfig) DeepCopyInto(out *AuthConfig) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AuthConfig. +func (in *AuthConfig) DeepCopy() *AuthConfig { + if in == nil { + return nil + } + out := new(AuthConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CredentialProviderRequest) DeepCopyInto(out *CredentialProviderRequest) { + *out = *in + out.TypeMeta = in.TypeMeta + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CredentialProviderRequest. +func (in *CredentialProviderRequest) DeepCopy() *CredentialProviderRequest { + if in == nil { + return nil + } + out := new(CredentialProviderRequest) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *CredentialProviderRequest) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CredentialProviderResponse) DeepCopyInto(out *CredentialProviderResponse) { + *out = *in + out.TypeMeta = in.TypeMeta + if in.CacheDuration != nil { + in, out := &in.CacheDuration, &out.CacheDuration + *out = new(v1.Duration) + **out = **in + } + if in.Auth != nil { + in, out := &in.Auth, &out.Auth + *out = make(map[string]AuthConfig, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CredentialProviderResponse. +func (in *CredentialProviderResponse) DeepCopy() *CredentialProviderResponse { + if in == nil { + return nil + } + out := new(CredentialProviderResponse) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *CredentialProviderResponse) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} diff --git a/staging/src/k8s.io/kubelet/pkg/apis/credentialprovider/v1alpha1/zz_generated.defaults.go b/staging/src/k8s.io/kubelet/pkg/apis/credentialprovider/v1alpha1/zz_generated.defaults.go new file mode 100644 index 00000000000..dd621a3acda --- /dev/null +++ b/staging/src/k8s.io/kubelet/pkg/apis/credentialprovider/v1alpha1/zz_generated.defaults.go @@ -0,0 +1,32 @@ +// +build !ignore_autogenerated + +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by defaulter-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + runtime "k8s.io/apimachinery/pkg/runtime" +) + +// RegisterDefaults adds defaulters functions to the given scheme. +// Public to allow building arbitrary schemes. +// All generated defaulters are covering - they call all nested defaulters. +func RegisterDefaults(scheme *runtime.Scheme) error { + return nil +} diff --git a/staging/src/k8s.io/kubelet/pkg/apis/credentialprovider/zz_generated.deepcopy.go b/staging/src/k8s.io/kubelet/pkg/apis/credentialprovider/zz_generated.deepcopy.go new file mode 100644 index 00000000000..4b7b7e65077 --- /dev/null +++ b/staging/src/k8s.io/kubelet/pkg/apis/credentialprovider/zz_generated.deepcopy.go @@ -0,0 +1,104 @@ +// +build !ignore_autogenerated + +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by deepcopy-gen. DO NOT EDIT. + +package credentialprovider + +import ( + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" +) + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AuthConfig) DeepCopyInto(out *AuthConfig) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AuthConfig. +func (in *AuthConfig) DeepCopy() *AuthConfig { + if in == nil { + return nil + } + out := new(AuthConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CredentialProviderRequest) DeepCopyInto(out *CredentialProviderRequest) { + *out = *in + out.TypeMeta = in.TypeMeta + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CredentialProviderRequest. +func (in *CredentialProviderRequest) DeepCopy() *CredentialProviderRequest { + if in == nil { + return nil + } + out := new(CredentialProviderRequest) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *CredentialProviderRequest) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CredentialProviderResponse) DeepCopyInto(out *CredentialProviderResponse) { + *out = *in + out.TypeMeta = in.TypeMeta + if in.CacheDuration != nil { + in, out := &in.CacheDuration, &out.CacheDuration + *out = new(v1.Duration) + **out = **in + } + if in.Auth != nil { + in, out := &in.Auth, &out.Auth + *out = make(map[string]AuthConfig, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CredentialProviderResponse. +func (in *CredentialProviderResponse) DeepCopy() *CredentialProviderResponse { + if in == nil { + return nil + } + out := new(CredentialProviderResponse) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *CredentialProviderResponse) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} diff --git a/vendor/modules.txt b/vendor/modules.txt index 4cd47a1552e..49f5be7f3d3 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -2428,6 +2428,9 @@ k8s.io/kubectl/pkg/validation # k8s.io/kubelet => ./staging/src/k8s.io/kubelet k8s.io/kubelet/config/v1alpha1 k8s.io/kubelet/config/v1beta1 +k8s.io/kubelet/pkg/apis/credentialprovider +k8s.io/kubelet/pkg/apis/credentialprovider/install +k8s.io/kubelet/pkg/apis/credentialprovider/v1alpha1 k8s.io/kubelet/pkg/apis/deviceplugin/v1beta1 k8s.io/kubelet/pkg/apis/pluginregistration/v1 k8s.io/kubelet/pkg/apis/podresources/v1