Support AWS_PROFILE for restic backups/restore operations (#2096)

* Support AWS_PROFILE for restic backups/restore operations

It enables Velero to switch credentials if multiple s3-compatible
backupLocations are present.

Signed-off-by: dinesh <dinesh1042@gmail.com>

* better comments and fixing typos

Signed-off-by: dinesh <dinesh1042@gmail.com>

* add changelog entry

Signed-off-by: dinesh <dinesh1042@gmail.com>
This commit is contained in:
Dinesh Yadav
2019-12-09 20:16:02 +05:30
committed by Nolan Brubaker
parent 6391b84dc6
commit 83ef4eb4d0
7 changed files with 88 additions and 5 deletions

36
pkg/restic/aws.go Normal file
View File

@@ -0,0 +1,36 @@
/*
Copyright 2019 the Velero contributors.
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 restic
const (
// AWS specific environment variable
awsProfileEnvVar = "AWS_PROFILE"
awsProfileKey = "profile"
)
// getS3ResticEnvVars gets the environment variables that restic
// relies on (AWS_PROFILE) based on info in the provided object
// storage location config map.
func getS3ResticEnvVars(config map[string]string) (map[string]string, error) {
result := make(map[string]string)
if profile, ok := config[awsProfileKey]; ok {
result[awsProfileEnvVar] = profile
}
return result, nil
}

View File

@@ -114,10 +114,10 @@ func mapLookup(data map[string]string) func(string) string {
}
}
// getResticEnvVars gets the environment variables that restic
// getAzureResticEnvVars gets the environment variables that restic
// relies on (AZURE_ACCOUNT_NAME and AZURE_ACCOUNT_KEY) based
// on info in the provided object storage location config map.
func getResticEnvVars(config map[string]string) (map[string]string, error) {
func getAzureResticEnvVars(config map[string]string) (map[string]string, error) {
storageAccountKey, _, err := getStorageAccountKey(config)
if err != nil {
return nil, err

View File

@@ -228,7 +228,7 @@ func AzureCmdEnv(backupLocationLister velerov1listers.BackupStorageLocationListe
return nil, errors.Wrap(err, "error getting backup storage location")
}
azureVars, err := getResticEnvVars(loc.Spec.Config)
azureVars, err := getAzureResticEnvVars(loc.Spec.Config)
if err != nil {
return nil, errors.Wrap(err, "error getting azure restic env vars")
}
@@ -240,3 +240,26 @@ func AzureCmdEnv(backupLocationLister velerov1listers.BackupStorageLocationListe
return env, nil
}
// S3CmdEnv returns a list of environment variables (in the format var=val) that
// should be used when running a restic command for an S3 backend. This list is
// the current environment, plus the AWS-specific variables restic needs, namely
// a credential profile.
func S3CmdEnv(backupLocationLister velerov1listers.BackupStorageLocationLister, namespace, backupLocation string) ([]string, error) {
loc, err := backupLocationLister.BackupStorageLocations(namespace).Get(backupLocation)
if err != nil {
return nil, errors.Wrap(err, "error getting backup storage location")
}
awsVars, err := getS3ResticEnvVars(loc.Spec.Config)
if err != nil {
return nil, errors.Wrap(err, "error getting aws restic env vars")
}
env := os.Environ()
for k, v := range awsVars {
env = append(env, fmt.Sprintf("%s=%s", k, v))
}
return env, nil
}

View File

@@ -254,6 +254,16 @@ func (rm *repositoryManager) exec(cmd *Command, backupLocation string) error {
return err
}
cmd.Env = env
} else if strings.HasPrefix(cmd.RepoIdentifier, "s3") {
if !cache.WaitForCacheSync(rm.ctx.Done(), rm.backupLocationInformerSynced) {
return errors.New("timed out waiting for cache to sync")
}
env, err := S3CmdEnv(rm.backupLocationLister, rm.namespace, backupLocation)
if err != nil {
return err
}
cmd.Env = env
}
stdout, stderr, err := veleroexec.RunCommand(cmd.Cmd())