160 lines
4.6 KiB
Go
160 lines
4.6 KiB
Go
/*
|
|
Copyright 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
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"strconv"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/pkg/errors"
|
|
"github.com/sirupsen/logrus"
|
|
|
|
"github.com/vmware-tanzu/velero/internal/credentials"
|
|
velerov1api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
|
|
repoconfig "github.com/vmware-tanzu/velero/pkg/repository/config"
|
|
"github.com/vmware-tanzu/velero/pkg/util/filesystem"
|
|
)
|
|
|
|
const (
|
|
|
|
// DefaultMaintenanceFrequency is the default time interval
|
|
// at which restic prune is run.
|
|
DefaultMaintenanceFrequency = 7 * 24 * time.Hour
|
|
|
|
// insecureSkipTLSVerifyKey is the flag in BackupStorageLocation's config
|
|
// to indicate whether to skip TLS verify to setup insecure HTTPS connection.
|
|
insecureSkipTLSVerifyKey = "insecureSkipTLSVerify"
|
|
|
|
// resticInsecureTLSFlag is the flag for Restic command line to indicate
|
|
// skip TLS verify on https connection.
|
|
resticInsecureTLSFlag = "--insecure-tls"
|
|
)
|
|
|
|
// TempCACertFile creates a temp file containing a CA bundle
|
|
// and returns its path. The caller should generally call os.Remove()
|
|
// to remove the file when done with it.
|
|
func TempCACertFile(caCert []byte, bsl string, fs filesystem.Interface) (string, error) {
|
|
file, err := fs.TempFile("", fmt.Sprintf("cacert-%s", bsl))
|
|
if err != nil {
|
|
return "", errors.WithStack(err)
|
|
}
|
|
|
|
if _, err := file.Write(caCert); err != nil {
|
|
// nothing we can do about an error closing the file here, and we're
|
|
// already returning an error about the write failing.
|
|
file.Close()
|
|
return "", errors.WithStack(err)
|
|
}
|
|
|
|
name := file.Name()
|
|
|
|
if err := file.Close(); err != nil {
|
|
return "", errors.WithStack(err)
|
|
}
|
|
|
|
return name, nil
|
|
}
|
|
|
|
// environ is a slice of strings representing the environment, in the form "key=value".
|
|
type environ []string
|
|
|
|
// Unset a single environment variable.
|
|
func (e *environ) Unset(key string) {
|
|
for i := range *e {
|
|
if strings.HasPrefix((*e)[i], key+"=") {
|
|
(*e)[i] = (*e)[len(*e)-1]
|
|
*e = (*e)[:len(*e)-1]
|
|
break
|
|
}
|
|
}
|
|
}
|
|
|
|
// CmdEnv returns a list of environment variables (in the format var=val) that
|
|
// should be used when running a restic command for a particular backend provider.
|
|
// This list is the current environment, plus any provider-specific variables restic needs.
|
|
func CmdEnv(backupLocation *velerov1api.BackupStorageLocation, credentialFileStore credentials.FileStore) ([]string, error) {
|
|
var env environ
|
|
env = os.Environ()
|
|
customEnv := map[string]string{}
|
|
var err error
|
|
|
|
config := backupLocation.Spec.Config
|
|
if config == nil {
|
|
config = map[string]string{}
|
|
}
|
|
|
|
if backupLocation.Spec.Credential != nil {
|
|
credsFile, err := credentialFileStore.Path(backupLocation.Spec.Credential)
|
|
if err != nil {
|
|
return []string{}, errors.WithStack(err)
|
|
}
|
|
config[repoconfig.CredentialsFileKey] = credsFile
|
|
}
|
|
|
|
backendType := repoconfig.GetBackendType(backupLocation.Spec.Provider, backupLocation.Spec.Config)
|
|
|
|
switch backendType {
|
|
case repoconfig.AWSBackend:
|
|
customEnv, err = repoconfig.GetS3ResticEnvVars(config)
|
|
if err != nil {
|
|
return []string{}, err
|
|
}
|
|
case repoconfig.AzureBackend:
|
|
customEnv, err = repoconfig.GetAzureResticEnvVars(config)
|
|
if err != nil {
|
|
return []string{}, err
|
|
}
|
|
case repoconfig.GCPBackend:
|
|
customEnv, err = repoconfig.GetGCPResticEnvVars(config)
|
|
if err != nil {
|
|
return []string{}, err
|
|
}
|
|
}
|
|
|
|
for k, v := range customEnv {
|
|
env.Unset(k)
|
|
if v == "" {
|
|
continue
|
|
}
|
|
env = append(env, fmt.Sprintf("%s=%s", k, v))
|
|
}
|
|
|
|
return env, nil
|
|
}
|
|
|
|
// GetInsecureSkipTLSVerifyFromBSL get insecureSkipTLSVerify flag from BSL configuration,
|
|
// Then return --insecure-tls flag with boolean value as result.
|
|
func GetInsecureSkipTLSVerifyFromBSL(backupLocation *velerov1api.BackupStorageLocation, logger logrus.FieldLogger) string {
|
|
result := ""
|
|
|
|
if backupLocation == nil {
|
|
logger.Info("bsl is nil. return empty.")
|
|
return result
|
|
}
|
|
|
|
if insecure, _ := strconv.ParseBool(backupLocation.Spec.Config[insecureSkipTLSVerifyKey]); insecure {
|
|
logger.Debugf("set --insecure-tls=true for Restic command according to BSL %s config", backupLocation.Name)
|
|
result = resticInsecureTLSFlag + "=true"
|
|
return result
|
|
}
|
|
|
|
return result
|
|
}
|