From 2e459019efd50cdf8d8503ce076537fd2e378739 Mon Sep 17 00:00:00 2001 From: Pradipta Banerjee Date: Thu, 14 Sep 2023 10:33:37 -0400 Subject: [PATCH] cloud: Add registry auth json to userdata This patch makes the auth json used for container registry available via userdata. There are two parts of the change. Part-1 is for CAA, to add the auth json to the daemon config Part-2 is for the process-user-data command to process the auth json and update the kata agent-config toml to refer to the auth json file Fixes: #1119 Signed-off-by: Pradipta Banerjee --- cmd/process-user-data/provision.go | 18 ++++++++++++++++++ cmd/process-user-data/types.go | 4 +++- cmd/process-user-data/update.go | 19 +++++++++++++++++++ pkg/adaptor/cloud/cloud.go | 21 +++++++-------------- pkg/forwarder/forwarder.go | 2 ++ pkg/util/cloudinit/cloudconfig.go | 6 +++--- 6 files changed, 52 insertions(+), 18 deletions(-) diff --git a/cmd/process-user-data/provision.go b/cmd/process-user-data/provision.go index a99472f0e..edd6e9ef3 100644 --- a/cmd/process-user-data/provision.go +++ b/cmd/process-user-data/provision.go @@ -148,5 +148,23 @@ func provisionFiles(cmd *cobra.Command, args []string) error { return err } + // Copy the authJson to the authJsonFilePath + config := getConfigFromUserData(cfg.userData) + if config.AuthJson != "" { + // Create the file + file, err := os.Create(defaultAuthJsonFilePath) + if err != nil { + return fmt.Errorf("failed to create file: %s", err) + } + defer file.Close() + + // Write the authJson to the file + _, err = file.WriteString(config.AuthJson) + if err != nil { + return fmt.Errorf("failed to write authJson to file: %s", err) + } + + } + return nil } diff --git a/cmd/process-user-data/types.go b/cmd/process-user-data/types.go index 883ba20ce..bc9daeb0f 100644 --- a/cmd/process-user-data/types.go +++ b/cmd/process-user-data/types.go @@ -5,7 +5,9 @@ const ( providerAzure = "azure" providerAws = "aws" - defaultAgentConfigPath = "/etc/agent-config.toml" + defaultAgentConfigPath = "/etc/agent-config.toml" + defaultAuthJsonFilePath = "/etc/auth.json" + offlineKbcAuthFile = "/etc/aa-offline_fs_kbc-resources.json" ) type Config struct { diff --git a/cmd/process-user-data/update.go b/cmd/process-user-data/update.go index 44d0c8efb..417eb5be0 100644 --- a/cmd/process-user-data/update.go +++ b/cmd/process-user-data/update.go @@ -106,6 +106,25 @@ func updateAgentConfig(cmd *cobra.Command, args []string) error { agentConfig.AaKbcParams = config.AAKBCParams } + if config.AuthJson != "" { + + fmt.Printf("Updating image_registry_auth_file in agent config file with value\n") + + // Check if authJsonFilePath exists. If it doesn't exists create the file + + if _, err := os.Stat(defaultAuthJsonFilePath); err != nil && os.IsNotExist(err) { + // Write the authJson to the defaultAuthJsonFilePath + err = os.WriteFile(defaultAuthJsonFilePath, []byte(config.AuthJson), 0644) + if err != nil { + return fmt.Errorf("failed to write auth.json file: %s", err) + } + } + + // Update the file path in the agent config + agentConfig.ImageRegistryAuthFile = "file://" + defaultAuthJsonFilePath + + } + // Write the updated agent config file err = writeAgentConfig(*agentConfig, cfg.agentConfigPath) if err != nil { diff --git a/pkg/adaptor/cloud/cloud.go b/pkg/adaptor/cloud/cloud.go index 535dbd061..8917f07be 100644 --- a/pkg/adaptor/cloud/cloud.go +++ b/pkg/adaptor/cloud/cloud.go @@ -225,6 +225,13 @@ func (s *cloudService) CreateVM(ctx context.Context, req *pb.CreateVMRequest) (r daemonConfig.AAKBCParams = s.aaKBCParams } + // Check if auth json file is present + if authJSON, err := os.ReadFile(cloudinit.DefaultAuthfileSrcPath); err == nil { + daemonConfig.AuthJson = string(authJSON) + } else { + logger.Printf("Credentials file is not in a valid Json format, ignored") + } + daemonJSON, err := json.MarshalIndent(daemonConfig, "", " ") if err != nil { return nil, fmt.Errorf("generating JSON data: %w", err) @@ -246,20 +253,6 @@ func (s *cloudService) CreateVM(ctx context.Context, req *pb.CreateVMRequest) (r }, } - if authJSON, err := os.ReadFile(cloudinit.DefaultAuthfileSrcPath); err == nil { - if json.Valid(authJSON) && (len(authJSON) < cloudinit.DefaultAuthfileLimit) { - cloudConfig.WriteFiles = append(cloudConfig.WriteFiles, - cloudinit.WriteFile{ - Path: cloudinit.DefaultAuthfileDstPath, - Content: cloudinit.AuthJSONToResourcesJSON(string(authJSON)), - }) - } else if len(authJSON) >= cloudinit.DefaultAuthfileLimit { - logger.Printf("Credentials file size (%d) is too large to use as userdata, ignored", len(authJSON)) - } else { - logger.Printf("Credentials file is not in a valid Json format, ignored") - } - } - sandbox := &sandbox{ id: sid, podName: pod, diff --git a/pkg/forwarder/forwarder.go b/pkg/forwarder/forwarder.go index e1725917d..9d04d2ff0 100644 --- a/pkg/forwarder/forwarder.go +++ b/pkg/forwarder/forwarder.go @@ -44,6 +44,8 @@ type Config struct { TLSClientCA string `json:"tls-client-ca,omitempty"` AAKBCParams string `json:"aa-kbc-params,omitempty"` + + AuthJson string `json:"auth-json,omitempty"` } type Daemon interface { diff --git a/pkg/util/cloudinit/cloudconfig.go b/pkg/util/cloudinit/cloudconfig.go index a573212cc..b8d1a6cd8 100644 --- a/pkg/util/cloudinit/cloudconfig.go +++ b/pkg/util/cloudinit/cloudconfig.go @@ -13,9 +13,9 @@ import ( const ( DefaultAuthfileSrcPath = "/root/containers/auth.json" - // image-rs fixed dst path for support at the agent, we convert it explictly to the resources file format - // e.g. https://github.com/confidential-containers/guest-components/blob/main/attestation-agent/kbc/src/offline_fs_kbc/aa-offline_fs_kbc-resources.json - DefaultAuthfileDstPath = "/etc/aa-offline_fs_kbc-resources.json" + + // Location of the container registry auth json file + DefaultAuthfileDstPath = "/etc/attestation-agent/auth.json" DefaultAuthfileLimit = 12288 // TODO: use a whole userdata limit mechanism instead of limiting authfile DefaultAAKBCParamsPath = "/etc/attestation-agent/kbc-params.json" )