internal/kubelet/image-credential-provider.go (82 lines of code) (raw):

package kubelet import ( "bytes" _ "embed" "fmt" "os" "path" "path/filepath" "text/template" "go.uber.org/zap" "golang.org/x/mod/semver" "github.com/aws/eks-hybrid/internal/api" "github.com/aws/eks-hybrid/internal/util" ) const ( // #nosec G101 //constant path, not credential imageCredentialProviderRoot = "/etc/eks/image-credential-provider" // #nosec G101 //constant path, not credential imageCredentialProviderConfig = "config.json" imageCredentialProviderPerm = 0o644 // #nosec G101 //constant path, not credential ecrCredentialProviderBinPathEnvironmentName = "ECR_CREDENTIAL_PROVIDER_BIN_PATH" ) var ( //go:embed image-credential-provider.template.json imageCredentialProviderTemplateData string //go:embed hybrid-roles-anywhere-image-credential-provider.template.json hybridRolesAnywhereImageCredentialProviderTemplateData string imageCredentialProviderConfigPath = path.Join(imageCredentialProviderRoot, imageCredentialProviderConfig) ) func (k *kubelet) writeImageCredentialProviderConfig() error { // fallback default for image credential provider binary if not overridden ecrCredentialProviderBinPath := path.Join(imageCredentialProviderRoot, "ecr-credential-provider") if binPath, set := os.LookupEnv(ecrCredentialProviderBinPathEnvironmentName); set { zap.L().Info("picked up image credential provider binary path from environment", zap.String("bin-path", binPath)) ecrCredentialProviderBinPath = binPath } if err := ensureCredentialProviderBinaryExists(ecrCredentialProviderBinPath); err != nil { return err } config, err := generateImageCredentialProviderConfig(k.nodeConfig, ecrCredentialProviderBinPath) if err != nil { return err } k.flags["image-credential-provider-bin-dir"] = path.Dir(ecrCredentialProviderBinPath) k.flags["image-credential-provider-config"] = imageCredentialProviderConfigPath return util.WriteFileWithDir(imageCredentialProviderConfigPath, config, imageCredentialProviderPerm) } type imageCredentialProviderTemplateVars struct { ConfigApiVersion string ProviderApiVersion string EcrProviderName string AwsConfigPath string } func generateImageCredentialProviderConfig(cfg *api.NodeConfig, ecrCredentialProviderBinPath string) ([]byte, error) { templateVars := imageCredentialProviderTemplateVars{ EcrProviderName: filepath.Base(ecrCredentialProviderBinPath), } kubeletVersion, err := GetKubeletVersion() if err != nil { return nil, err } if semver.Compare(kubeletVersion, "v1.27.0") < 0 { templateVars.ConfigApiVersion = "kubelet.config.k8s.io/v1alpha1" templateVars.ProviderApiVersion = "credentialprovider.kubelet.k8s.io/v1alpha1" } else { templateVars.ConfigApiVersion = "kubelet.config.k8s.io/v1" templateVars.ProviderApiVersion = "credentialprovider.kubelet.k8s.io/v1" } var buf bytes.Buffer var imageCredentialProviderTemplate *template.Template if cfg.IsIAMRolesAnywhere() { templateVars.AwsConfigPath = cfg.Spec.Hybrid.IAMRolesAnywhere.AwsConfigPath imageCredentialProviderTemplate = template.Must(template.New("image-credential-provider").Parse(hybridRolesAnywhereImageCredentialProviderTemplateData)) } else { // The regular non-iam roles anywhere credential provider would still work for SSM based installs imageCredentialProviderTemplate = template.Must(template.New("image-credential-provider").Parse(imageCredentialProviderTemplateData)) } if err := imageCredentialProviderTemplate.Execute(&buf, templateVars); err != nil { return nil, err } return buf.Bytes(), nil } func ensureCredentialProviderBinaryExists(binPath string) error { if _, err := os.Stat(binPath); err != nil { return fmt.Errorf("image credential provider binary was not found on path %s. error: %s", binPath, err) } return nil }