// Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"). You may not // use this file except in compliance with the License. A copy of the // License is located at // // http://aws.amazon.com/apache2.0/ // // or in the "license" file accompanying this file. This file 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 runtimeconfiginit import ( "github.com/aws/amazon-ssm-agent/agent/backoffconfig" "github.com/aws/amazon-ssm-agent/agent/log" "github.com/aws/amazon-ssm-agent/common/identity" identity2 "github.com/aws/amazon-ssm-agent/common/identity/identity" "github.com/aws/amazon-ssm-agent/common/runtimeconfig" "github.com/cenkalti/backoff/v4" ) var backoffRetry = backoff.Retry type IRuntimeConfigInit interface { Init() error } type runtimeConfigInit struct { log log.T backoffConfig *backoff.ExponentialBackOff agentIdentity identity.IAgentIdentity identityConfigClient runtimeconfig.IIdentityRuntimeConfigClient } func (r *runtimeConfigInit) saveIdentityConfigWithRetry(currentConfig runtimeconfig.IdentityRuntimeConfig) error { return backoffRetry(func() error { r.log.Debugf("Trying to save identity runtime config") err := r.identityConfigClient.SaveConfig(currentConfig) if err != nil { r.log.Warnf("Failed to save runtime config: %v", err) } return err }, r.backoffConfig) } func (r *runtimeConfigInit) getCurrentIdentityRuntimeConfig() (runtimeconfig.IdentityRuntimeConfig, error) { var currentConfig runtimeconfig.IdentityRuntimeConfig var err error currentConfig.IdentityType = r.agentIdentity.IdentityType() currentConfig.InstanceId, err = r.agentIdentity.InstanceID() if err != nil { return currentConfig, err } if credentialsRefresherIdentity, ok := identity2.GetRemoteProvider(r.agentIdentity); ok { currentConfig.ShareFile = credentialsRefresherIdentity.ShareFile() currentConfig.ShareProfile = credentialsRefresherIdentity.ShareProfile() } return currentConfig, nil } func (r *runtimeConfigInit) initIdentityRuntimeConfig() error { currentConfig, err := r.getCurrentIdentityRuntimeConfig() if err != nil { return err } var savedConfig runtimeconfig.IdentityRuntimeConfig if ok, err := r.identityConfigClient.ConfigExists(); err != nil { // failed to check if runtime config exists, initialize new one anyways r.log.Warnf("failed to check identity runtime config during init: %v", err) } else if ok { if savedConfig, err = r.identityConfigClient.GetConfig(); err != nil { r.log.Warnf("failed to read identity runtime config during init: %v", err) } } // else config does not exist // If saved config and current config are not equal, save the current runtime config if !savedConfig.Equal(currentConfig) { return r.saveIdentityConfigWithRetry(currentConfig) } return nil } func (r *runtimeConfigInit) Init() error { var err error r.backoffConfig, err = backoffconfig.GetDefaultExponentialBackoff() if err != nil { return err } return r.initIdentityRuntimeConfig() } func New(log log.T, identity identity.IAgentIdentity) IRuntimeConfigInit { return &runtimeConfigInit{ log, nil, // initialized in Init identity, runtimeconfig.NewIdentityRuntimeConfigClient(), } }