Skip to content

Conversation

richabanker
Copy link
Owner

What type of PR is this?

What this PR does / why we need it:

Which issue(s) this PR fixes:

Fixes #

Special notes for your reviewer:

Does this PR introduce a user-facing change?


Additional documentation e.g., KEPs (Kubernetes Enhancement Proposals), usage docs, etc.:


@@ -125,6 +127,35 @@ func validateCredentialProviderConfig(config *kubeletconfig.CredentialProviderCo
if provider.DefaultCacheDuration != nil && provider.DefaultCacheDuration.Duration < 0 {
allErrs = append(allErrs, field.Invalid(fieldPath.Child("defaultCacheDuration"), provider.DefaultCacheDuration.Duration, "defaultCacheDuration must be greater than or equal to 0"))

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider adding a comment that indicates the reason why serviceAccountTokenAudience is required. This will help future developers understand the intent of the validation.

@@ -125,6 +127,35 @@ func validateCredentialProviderConfig(config *kubeletconfig.CredentialProviderCo
if provider.DefaultCacheDuration != nil && provider.DefaultCacheDuration.Duration < 0 {
allErrs = append(allErrs, field.Invalid(fieldPath.Child("defaultCacheDuration"), provider.DefaultCacheDuration.Duration, "defaultCacheDuration must be greater than or equal to 0"))
}

if provider.TokenAttributes != nil {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider adding a comment that indicates the reason why requireServiceAccount is required. This will help future developers understand the intent of the validation.

if provider.TokenAttributes != nil {
fldPath := fieldPath.Child("tokenAttributes")
if !saTokenForCredentialProviders {
allErrs = append(allErrs, field.Forbidden(fldPath, "tokenAttributes is not supported when KubeletServiceAccountTokenForCredentialProviders feature gate is disabled"))

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This error message should include the API Group as well as the version, because without that information it can be hard to understand which API version it is referring to.

allErrs = append(allErrs, field.Forbidden(fldPath, "tokenAttributes is not supported when KubeletServiceAccountTokenForCredentialProviders feature gate is disabled"))
}
if len(provider.TokenAttributes.ServiceAccountTokenAudience) == 0 {
allErrs = append(allErrs, field.Required(fldPath.Child("serviceAccountTokenAudience"), "serviceAccountTokenAudience is required"))

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider extracting this logic into its own function. This will help to keep the validateCredentialProviderConfig function small and easy to understand.

}
if len(provider.TokenAttributes.ServiceAccountTokenAudience) == 0 {
allErrs = append(allErrs, field.Required(fldPath.Child("serviceAccountTokenAudience"), "serviceAccountTokenAudience is required"))
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add comments that state the source of this validation logic.

allErrs = append(allErrs, field.Required(fldPath.Child("serviceAccountTokenAudience"), "serviceAccountTokenAudience is required"))
}
if provider.TokenAttributes.RequireServiceAccount == nil {
allErrs = append(allErrs, field.Required(fldPath.Child("requireServiceAccount"), "requireServiceAccount is required"))

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Validation functions from k8s.io/apimachinery return a slice of strings, so there's no need to iterate over them. You can just append them to allErrs directly.

allErrs = append(allErrs, field.Required(fldPath.Child("requireServiceAccount"), "requireServiceAccount is required"))
}
if provider.APIVersion != credentialproviderv1.SchemeGroupVersion.String() {
allErrs = append(allErrs, field.Forbidden(fldPath, fmt.Sprintf("tokenAttributes is only supported for %s API version", credentialproviderv1.SchemeGroupVersion.String())))

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider using sets.String.Insert(strings.ToLower(k)) for consistency with line 140.

@@ -42,6 +48,7 @@ import (
credentialproviderv1alpha1 "k8s.io/kubelet/pkg/apis/credentialprovider/v1alpha1"
credentialproviderv1beta1 "k8s.io/kubelet/pkg/apis/credentialprovider/v1beta1"
"k8s.io/kubernetes/pkg/credentialprovider"
"k8s.io/kubernetes/pkg/features"

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider directly passing the boolean value of the feature gate instead of passing the entire utility function to minimize dependencies. This can improve testability and encapsulation.

@@ -134,7 +147,6 @@ func newPluginProvider(pluginBinDir string, provider kubeletconfig.CredentialPro
}

clock := clock.RealClock{}

return &pluginProvider{
clock: clock,
matchImages: provider.MatchImages,

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The lastCachePurge field is updated inside a lock in getCachedCredentials but not in Provide. Consider adding a lock around the update in Provide to prevent race conditions.

@@ -178,6 +191,82 @@ type pluginProvider struct {

// lastCachePurge is the last time cache is cleaned for expired entries.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The featureGateEnabled variable is defined but not used. Remove the unused variable.

if !ok {
continue
}
requiredAnnotations[k] = val

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is helpful to include documentation for each parameter in the getServiceAccountToken function, explaining its purpose and expected value.

// that the plugin can use this information to get the pod's service account and generate bound service account tokens
// for plugins running in service account token mode.
type perPodPluginProvider struct {
provider *pluginProvider

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The err variable is shadowed within the if p.serviceAccountProvider != nil block. Rename the err variable in the outer scope or use a different name in the inner scope to avoid shadowing.

}

// Enabled always returns true since registration of the plugin via kubelet implies it should be enabled.
func (p *perPodPluginProvider) Enabled() bool {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be good to log what parameters are being passed to ExecPlugin, especially the image and if a service account token is being passed. This would be helpful for debugging.

// Enabled always returns true since registration of the plugin via kubelet implies it should be enabled.
func (p *perPodPluginProvider) Enabled() bool {
return true
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The err variable is shadowed within the res, err, _ := p.group.Do block. Rename the err variable in the outer scope or use a different name in the inner scope to avoid shadowing.

var requiredAnnotations map[string]string
var err error
var baseCacheKey string

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This block of code repeats itself. Consider creating a helper function to encapsulate this logic to reduce duplication.

klog.Errorf("Failed to get service account %s/%s: %v", podNamespace, serviceAccountName, err)
return credentialprovider.DockerConfig{}
}
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A singleflight key should be created if p.serviceAccountProvider != nil.

@@ -280,6 +437,12 @@ func (p *pluginProvider) Provide(image string) credentialprovider.DockerConfig {
expiresAt = p.clock.Now().Add(response.CacheDuration.Duration)
}

cacheKey, err = p.generateCacheKey(cacheKey, baseCacheKey)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be helpful to include documentation for each parameter in the ExecPlugin function, explaining its purpose and expected value. Also, add a brief description of what the ExecPlugin function does.

return nil, false, fmt.Errorf("error generating cache key: %w", err)
}

obj, found, err = p.cache.GetByKey(cacheKey)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be helpful to include documentation for each parameter in the generateBaseCacheKey function, explaining its purpose and expected value. Also, add a brief description of what the generateBaseCacheKey function does.

return nil, false, fmt.Errorf("error generating cache key: %w", err)
}

obj, found, err = p.cache.GetByKey(cacheKey)
if err != nil {
return nil, false, err
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider adding validation to ensure that serviceAccountNamespace, serviceAccountName, and serviceAccountUID are not empty before adding them to the cache key. This prevents unexpected behavior if these values are missing.

"k8s.io/kubernetes/pkg/credentialprovider"
"k8s.io/kubernetes/pkg/features"
)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider using a more descriptive name than p for the loop variable in registerCredentialProviderPlugin. Something like pluginEntry would improve readability.

@@ -125,6 +127,35 @@ func validateCredentialProviderConfig(config *kubeletconfig.CredentialProviderCo
if provider.DefaultCacheDuration != nil && provider.DefaultCacheDuration.Duration < 0 {
allErrs = append(allErrs, field.Invalid(fieldPath.Child("defaultCacheDuration"), provider.DefaultCacheDuration.Duration, "defaultCacheDuration must be greater than or equal to 0"))

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When KubeletServiceAccountTokenForCredentialProviders feature gate is disabled, the function should return immediately.

@@ -125,6 +127,35 @@ func validateCredentialProviderConfig(config *kubeletconfig.CredentialProviderCo
if provider.DefaultCacheDuration != nil && provider.DefaultCacheDuration.Duration < 0 {
allErrs = append(allErrs, field.Invalid(fieldPath.Child("defaultCacheDuration"), provider.DefaultCacheDuration.Duration, "defaultCacheDuration must be greater than or equal to 0"))
}

if provider.TokenAttributes != nil {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

serviceAccountTokenAudience should have validation limits, and check that it has the correct format.

if provider.TokenAttributes != nil {
fldPath := fieldPath.Child("tokenAttributes")
if !saTokenForCredentialProviders {
allErrs = append(allErrs, field.Forbidden(fldPath, "tokenAttributes is not supported when KubeletServiceAccountTokenForCredentialProviders feature gate is disabled"))

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might be clearer to use provider.TokenAttributes.RequireServiceAccount == nil to check if RequireServiceAccount has a default value.

allErrs = append(allErrs, field.Required(fldPath.Child("serviceAccountTokenAudience"), "serviceAccountTokenAudience is required"))
}
if provider.TokenAttributes.RequireServiceAccount == nil {
allErrs = append(allErrs, field.Required(fldPath.Child("requireServiceAccount"), "requireServiceAccount is required"))

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does tokenAttributes support other API versions? If it's going to support the new API, it would be better to have an if statement instead of direct comparison.

if provider.APIVersion != credentialproviderv1.SchemeGroupVersion.String() {
allErrs = append(allErrs, field.Forbidden(fldPath, fmt.Sprintf("tokenAttributes is only supported for %s API version", credentialproviderv1.SchemeGroupVersion.String())))
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The loop variable k should be a qualified name and not accept characters from other languages.

func RegisterCredentialProviderPlugins(pluginConfigFile, pluginBinDir string,
getServiceAccountToken func(namespace, name string, tr *authenticationv1.TokenRequest) (*authenticationv1.TokenRequest, error),
getServiceAccount func(namespace, name string) (*v1.ServiceAccount, error),
) error {
if _, err := os.Stat(pluginBinDir); err != nil {
if os.IsNotExist(err) {
return fmt.Errorf("plugin binary directory %s did not exist", pluginBinDir)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

saTokenForCredentialProvidersFeatureEnabled is calculated but not used directly within this function. It is only used within the validateCredentialProviderConfig function. Consider moving the calculation of this variable inside the validateCredentialProviderConfig function to reduce the scope of the variable. This would improve readability and reduce the chance of accidental misuse.

}

type serviceAccountProvider struct {
audience string

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

featureGateEnabled and serviceAccountTokenAudienceSet are calculated and then used to determine if the serviceAccountProvider is initialized. If the serviceAccountProvider is nil in several places, then there will be a lot of if provider.serviceAccountProvider != nil { ... } checks. Consider returning an error from this function if the feature gate is not enabled, which would simplify the subsequent logic and make it easier to reason about.

defer providersMutex.RUnlock()

keyring := &externalCredentialProviderKeyring{
providers: make([]credentialprovider.DockerConfigProvider, 0, len(providers)),

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be helpful to add a comment briefly explaining the purpose of checking if the feature gate is enabled. Specifically, indicate why the perPodPluginProvider is being initialized differently based on the feature gate.


keyring := &externalCredentialProviderKeyring{
providers: make([]credentialprovider.DockerConfigProvider, 0, len(providers)),
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider adding more context on the klog message by including the feature gate being checked KubeletServiceAccountTokenForCredentialProviders.

}

keyring.providers = append(keyring.providers, pp)
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be helpful to add a comment explaining why a temporary BasicDockerKeyring is instantiated. Clarify the purpose of transferring provided auths to this temporary keyring.

Lifetime: 5 * time.Minute,
})
}

// CachingDockerConfigProvider implements DockerConfigProvider by composing

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider removing the init() function and registering the default provider elsewhere. This makes the provider more configurable and testable.

Provider: &defaultDockerConfigProvider{},
Lifetime: 5 * time.Minute,
},
},

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of hardcoding the lifetime to 5 minutes, consider making it configurable via a flag or a configuration file. This would allow users to tune the caching behavior based on their specific needs and environment.

@@ -37,17 +37,20 @@ const (
// across the file.

// owner: @aojea
// Deprecated: v1.31

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider adding a comment explaining what "Deprecated" means in this context (e.g., "Deprecated: This feature gate will be removed in a future release.")

//
// Allow kubelet to request a certificate without any Node IP available, only
// with DNS names.
AllowDNSOnlyNodeCSR featuregate.Feature = "AllowDNSOnlyNodeCSR"

// owner: @HirazawaUi
// Deprecated: v1.32
//
// Allow spec.terminationGracePeriodSeconds to be overridden by MaxPodGracePeriodSeconds in soft evictions.
AllowOverwriteTerminationGracePeriodSeconds featuregate.Feature = "AllowOverwriteTerminationGracePeriodSeconds"

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above.

@richabanker richabanker force-pushed the hackathon-test-api-review-1 branch from 945dbd5 to 6683b3e Compare February 20, 2025 01:36
@@ -125,6 +127,35 @@ func validateCredentialProviderConfig(config *kubeletconfig.CredentialProviderCo
if provider.DefaultCacheDuration != nil && provider.DefaultCacheDuration.Duration < 0 {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider adding a feature gate check before accessing config.Providers[*].TokenAttributes. This mirrors the pattern used for fldPath and saTokenForCredentialProviders and ensures that the code accessing the TokenAttributes is only executed when the feature gate is enabled.

@@ -125,6 +127,35 @@ func validateCredentialProviderConfig(config *kubeletconfig.CredentialProviderCo
if provider.DefaultCacheDuration != nil && provider.DefaultCacheDuration.Duration < 0 {
allErrs = append(allErrs, field.Invalid(fieldPath.Child("defaultCacheDuration"), provider.DefaultCacheDuration.Duration, "defaultCacheDuration must be greater than or equal to 0"))
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change the error message to "The KubeletServiceAccountTokenForCredentialProviders feature gate must be enabled to use tokenAttributes". This provides a more user-friendly error message that clearly indicates how to resolve the issue.

@@ -125,6 +127,35 @@ func validateCredentialProviderConfig(config *kubeletconfig.CredentialProviderCo
if provider.DefaultCacheDuration != nil && provider.DefaultCacheDuration.Duration < 0 {
allErrs = append(allErrs, field.Invalid(fieldPath.Child("defaultCacheDuration"), provider.DefaultCacheDuration.Duration, "defaultCacheDuration must be greater than or equal to 0"))
}

if provider.TokenAttributes != nil {
fldPath := fieldPath.Child("tokenAttributes")

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change the error message to "serviceAccountTokenAudience must be specified when tokenAttributes is provided". This clarifies the requirement and indicates that the field cannot be left empty when the parent field is used.

fldPath := fieldPath.Child("tokenAttributes")
if !saTokenForCredentialProviders {
allErrs = append(allErrs, field.Forbidden(fldPath, "tokenAttributes is not supported when KubeletServiceAccountTokenForCredentialProviders feature gate is disabled"))
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change the error message to "requireServiceAccount must be specified when tokenAttributes is provided". This clarifies the requirement and indicates that the field cannot be left empty when the parent field is used.

}
if len(provider.TokenAttributes.ServiceAccountTokenAudience) == 0 {
allErrs = append(allErrs, field.Required(fldPath.Child("serviceAccountTokenAudience"), "serviceAccountTokenAudience is required"))
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change the error message to "tokenAttributes is only supported for the credentialprovider.kubelet.k8s.io/v1 API version". It's more conventional to display the full group/version string instead of relying on SchemeGroupVersion, making the error message self-contained.

allErrs = append(allErrs, field.Required(fldPath.Child("requireServiceAccount"), "requireServiceAccount is required"))
}
if provider.APIVersion != credentialproviderv1.SchemeGroupVersion.String() {
allErrs = append(allErrs, field.Forbidden(fldPath, fmt.Sprintf("tokenAttributes is only supported for %s API version", credentialproviderv1.SchemeGroupVersion.String())))

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment // Using the validation logic for keys from... should be reworded to more concisely convey the intent, such as // Validate service account annotation keys.

if provider.APIVersion != credentialproviderv1.SchemeGroupVersion.String() {
allErrs = append(allErrs, field.Forbidden(fldPath, fmt.Sprintf("tokenAttributes is only supported for %s API version", credentialproviderv1.SchemeGroupVersion.String())))
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add a check to see if credentialproviderv1.SchemeGroupVersion.String() is same as config.Providers[*].APIVersion. It doesn't make sense for saTokenForCredentialProviders to be enabled, but have an older APIVersion.

func RegisterCredentialProviderPlugins(pluginConfigFile, pluginBinDir string,
getServiceAccountToken func(namespace, name string, tr *authenticationv1.TokenRequest) (*authenticationv1.TokenRequest, error),
getServiceAccount func(namespace, name string) (*v1.ServiceAccount, error),
) error {
if _, err := os.Stat(pluginBinDir); err != nil {
if os.IsNotExist(err) {
return fmt.Errorf("plugin binary directory %s did not exist", pluginBinDir)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: It would be helpful to log the reason for validation failures to assist debugging.

@@ -134,7 +147,6 @@ func newPluginProvider(pluginBinDir string, provider kubeletconfig.CredentialPro
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: Consider using a more descriptive name than serviceAccountProvider, such as tokenProvider or authProvider, to better reflect its purpose.

@@ -178,6 +191,82 @@ type pluginProvider struct {

// lastCachePurge is the last time cache is cleaned for expired entries.
lastCachePurge time.Time

// serviceAccountProvider holds the logic for handling service account tokens when needed.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: The comment says "...that's defined in the...". It should read, "...that are defined in...".


requiredAnnotations := make(map[string]string, len(s.serviceAccountAnnotationKeys))
for _, k := range s.serviceAccountAnnotationKeys {
val, ok := sa.Annotations[k]

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: Add a comment explaining the singleflight key.

return sa.UID, requiredAnnotations, nil
}

// getServiceAccountToken returns a service account token for the service account.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: The comments for types Plugin interface and execPlugin should both clarify what CredentialProviderResponse actually represents.

if p.serviceAccountProvider != nil {
if singleFlightKey, err = p.generateCacheKey(singleFlightKey, baseCacheKey); err != nil {
klog.Errorf("Error generating singleflight key: %v", err)
return credentialprovider.DockerConfig{}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: Given the added complexity of service account token mode, consider adding more structured logging, for example, logging the service account details or success/failure events related to token retrieval.

@@ -331,7 +499,13 @@ func (p *pluginProvider) getCachedCredentials(image string) (credentialprovider.
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: Use backticks for 1., 2. to be consistent with the rest of the document.

cacheKey, err = p.generateCacheKey(registry, baseCacheKey)
if err != nil {
return nil, false, fmt.Errorf("error generating cache key: %w", err)
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: The comment does not accurately describe all of the base cache key's components. It should include a reference to the service account UID and the annotations.

return nil, false, fmt.Errorf("error generating cache key: %w", err)
}

obj, found, err = p.cache.GetByKey(cacheKey)
if err != nil {
return nil, false, err
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: It is not clear how cryptobyte ensures security of the keys.

providersMutex.Lock()
defer providersMutex.Unlock()

if seenProviderNames.Has(name) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider using a more descriptive name than p for the loop variable in registerCredentialProviderPlugin, such as providerEntry or currProvider, to improve readability.

keyring := &externalCredentialProviderKeyring{
providers: make([]credentialprovider.DockerConfigProvider, 0, len(providers)),
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be helpful to add a comment explaining why externalCredentialProviderKeyring is needed, what problem does this struct solves, and how does it interacts with DockerConfigProvider and credentialprovider.DockerKeyring interface.

var pp *perPodPluginProvider
if utilfeature.DefaultFeatureGate.Enabled(features.KubeletServiceAccountTokenForCredentialProviders) {
klog.V(4).InfoS("Generating per pod credential provider", "provider", p.name, "podName", podName, "podNamespace", podNamespace, "podUID", podUID, "serviceAccountName", serviceAccountName)
pp = &perPodPluginProvider{provider: p.impl, podName: podName, podNamespace: podNamespace, podUID: types.UID(podUID), serviceAccountName: serviceAccountName}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The KubeletServiceAccountTokenForCredentialProviders feature gate name is quite long. Is there a shorter, more conventional name that could be used? Perhaps related to "PerPodCredentials" or "ScopedCredentials"?

if utilfeature.DefaultFeatureGate.Enabled(features.KubeletServiceAccountTokenForCredentialProviders) {
klog.V(4).InfoS("Generating per pod credential provider", "provider", p.name, "podName", podName, "podNamespace", podNamespace, "podUID", podUID, "serviceAccountName", serviceAccountName)
pp = &perPodPluginProvider{provider: p.impl, podName: podName, podNamespace: podNamespace, podUID: types.UID(podUID), serviceAccountName: serviceAccountName}
} else {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider using klog.InfoS's arguments to set the podUID as types.UID since you are already converting the type and will allow to print a more accurate value for debugging.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant