Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ bin/
tests/e2e/e2e.test
cover.out
.DS_Store
tests/e2e/templates/*.yaml
72 changes: 60 additions & 12 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,13 +1,50 @@
OADP_TEST_NAMESPACE ?= openshift-adp
REGION ?= us-east-1
PROVIDER ?= aws
CLUSTER_PROFILE ?= aws
CLUSTER_TYPE ?= aws

# CONFIGS FOR CLOUD
# bsl / blob storage cred dir
OADP_CRED_DIR ?= /var/run/oadp-credentials
# vsl / volume/cluster cred dir
CLUSTER_PROFILE_DIR ?= /Users/drajds/.aws

# bsl cred file
OADP_CRED_FILE ?= ${OADP_CRED_DIR}/new-aws-credentials
# vsl cred file
CI_CRED_FILE ?= ${CLUSTER_PROFILE_DIR}/.awscred

# aws configs - default
BSL_REGION ?= us-east-1
VSL_REGION ?= ${LEASED_RESOURCE}
BSL_AWS_PROFILE ?= default
# BSL_AWS_PROFILE ?= migration-engineering

# vsl secret
CREDS_SECRET_REF ?= cloud-credentials
OADP_AWS_CRED_FILE ?= /var/run/oadp-credentials/aws-credentials
OADP_S3_BUCKET ?= /var/run/oadp-credentials/velero-bucket-name
VELERO_INSTANCE_NAME ?= velero-sample
# bucket file
OADP_BUCKET_FILE ?= ${OADP_CRED_DIR}/new-velero-bucket-name
# azure cluster resource file - only in CI
AZURE_RESOURCE_FILE ?= /var/run/secrets/ci.openshift.io/multi-stage/metadata.json
AZURE_CI_JSON_CRED_FILE ?= ${CLUSTER_PROFILE_DIR}/osServicePrincipal.json
AZURE_OADP_JSON_CRED_FILE ?= ${OADP_CRED_DIR}/azure-credentials

# Misc
OPENSHIFT_CI ?= true
VELERO_INSTANCE_NAME ?= velero-test
E2E_TIMEOUT_MULTIPLIER ?= 1

ifeq ($(CLUSTER_TYPE), gcp)
CI_CRED_FILE = ${CLUSTER_PROFILE_DIR}/gce.json
OADP_CRED_FILE = ${OADP_CRED_DIR}/gcp-credentials
CREDS_SECRET_REF = cloud-credentials-gcp
OADP_BUCKET_FILE = ${OADP_CRED_DIR}/gcp-velero-bucket-name
else ifeq ($(CLUSTER_TYPE), azure4)
CLUSTER_TYPE = azure
CI_CRED_FILE = /tmp/ci-azure-credentials
OADP_CRED_FILE = /tmp/oadp-azure-credentials
CREDS_SECRET_REF = cloud-credentials-azure
OADP_BUCKET_FILE = ${OADP_CRED_DIR}/azure-velero-bucket-name
endif

# ENVTEST_K8S_VERSION refers to the version of kubebuilder assets to be downloaded by envtest binary.
ENVTEST_K8S_VERSION = 1.21

Expand Down Expand Up @@ -290,16 +327,27 @@ catalog-build: opm ## Build a catalog image.
catalog-push: ## Push a catalog image.
$(MAKE) docker-push IMG=$(CATALOG_IMG)

S3_BUCKET := $(shell cat $(OADP_S3_BUCKET) | awk '/velero-bucket-name/ {gsub(/"/, "", $$2);gsub(/}/,""); print $$2}')
OADP_BUCKET := $(shell cat $(OADP_BUCKET_FILE))
TEST_FILTER := $(shell echo '! aws && ! gcp && ! azure' | sed -r "s/[&]* [!] $(CLUSTER_TYPE)|[!] $(CLUSTER_TYPE) [&]*//")
SETTINGS_TMP=/tmp/test-settings
test-e2e:

test-e2e-setup:
mkdir -p $(SETTINGS_TMP)
PROVIDER="$(PROVIDER)" BUCKET="$(S3_BUCKET)" REGION="$(REGION)" SECRET="$(CREDS_SECRET_REF)" TMP_DIR=$(SETTINGS_TMP) /bin/bash tests/e2e/scripts/aws_settings.sh
ginkgo -mod=mod tests/e2e/ -- -cloud=$(OADP_AWS_CRED_FILE) \
TARGET_CI_CRED_FILE="$(CI_CRED_FILE)" AZURE_RESOURCE_FILE="$(AZURE_RESOURCE_FILE)" CI_JSON_CRED_FILE="$(AZURE_CI_JSON_CRED_FILE)" \
OADP_JSON_CRED_FILE="$(AZURE_OADP_JSON_CRED_FILE)" OADP_CRED_FILE="$(OADP_CRED_FILE)" OPENSHIFT_CI="$(OPENSHIFT_CI)" \
PROVIDER="$(CLUSTER_TYPE)" BUCKET="$(OADP_BUCKET)" BSL_REGION="$(BSL_REGION)" SECRET="$(CREDS_SECRET_REF)" TMP_DIR=$(SETTINGS_TMP) \
VSL_REGION="$(VSL_REGION)" BSL_AWS_PROFILE="$(BSL_AWS_PROFILE)" BSL_REGION="$(BSL_REGION)" /bin/bash "tests/e2e/scripts/$(CLUSTER_TYPE)_settings.sh"

test-e2e: test-e2e-setup
ginkgo run -mod=mod tests/e2e/ -- -credentials=$(OADP_CRED_FILE) \
-velero_namespace=$(OADP_TEST_NAMESPACE) \
-settings=$(SETTINGS_TMP)/awscreds \
-settings=$(SETTINGS_TMP)/oadpcreds \
-velero_instance_name=$(VELERO_INSTANCE_NAME) \
-timeout_multiplier=$(E2E_TIMEOUT_MULTIPLIER) \
-cluster_profile=$(CLUSTER_PROFILE)
--ginkgo.label-filter="$(TEST_FILTER)" \
-ci_cred_file=$(CI_CRED_FILE) \
-provider=$(CLUSTER_TYPE) \
-creds_secret_ref=$(CREDS_SECRET_REF)

test-e2e-cleanup:
rm -rf $(SETTINGS_TMP)
3 changes: 2 additions & 1 deletion build/ci-Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
# TODO! Find a real ubi8 image for golang 1.16
FROM quay.io/app-sre/boilerplate:image-v2.1.0 as builder

RUN go get -u github.com/onsi/ginkgo/ginkgo
RUN go get -u github.com/onsi/ginkgo/ginkgo && \
go get -u github.com/onsi/ginkgo/v2/ginkgo
RUN go get github.com/onsi/gomega/...

WORKDIR /go/src/github.com/openshift/oadp-operator
Expand Down
3 changes: 2 additions & 1 deletion build/custom-ci-Dockerfile
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
FROM openshift/origin-release:golang-1.16
RUN yum -y install epel-release --disablerepo=epel && yum clean all
RUN yum -y install make
RUN go get -u github.com/onsi/ginkgo/ginkgo
RUN go get -u github.com/onsi/ginkgo/ginkgo && \
go get -u github.com/onsi/ginkgo/v2/ginkgo
RUN go get github.com/onsi/gomega/...
RUN chmod g+rw /etc/passwd
ENV LC_ALL=en_US.utf-8 LANG=en_US.utf-8
2 changes: 1 addition & 1 deletion controllers/bsl.go
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,7 @@ func (r *DPAReconciler) validateProviderPluginAndSecret(bslSpec velerov1.BackupS
r.Log.Info(fmt.Sprintf("%s backupstoragelocation is configured but velero plugin for %s is not present", bslSpec.Provider, bslSpec.Provider))
//TODO: set warning condition on Velero CR
}
secretName, _ := r.getSecretNameAndKey(bslSpec.Credential, oadpv1alpha1.DefaultPlugin(bslSpec.Provider))
secretName, _ := r.getSecretNameAndKey(&bslSpec, oadpv1alpha1.DefaultPlugin(bslSpec.Provider))

_, err := r.getProviderSecret(secretName)

Expand Down
86 changes: 69 additions & 17 deletions controllers/registry.go
Original file line number Diff line number Diff line change
Expand Up @@ -283,16 +283,29 @@ func (r *DPAReconciler) buildRegistryDeployment(registryDeployment *appsv1.Deplo
},
}

// attach gcp secret volume if provider is gcp
if bsl.Spec.Provider == GCPProvider {
// check for secret name
secretName, _ := r.getSecretNameAndKey(bsl.Spec.Credential, oadpv1alpha1.DefaultPluginGCP)
// attach secret volume for cloud providers
if _, ok := bsl.Spec.Config["credentialsFile"]; ok {
if secretName, err := credentials.GetSecretNameFromCredentialsFileConfigString(bsl.Spec.Config["credentialsFile"]); err == nil {
registryDeployment.Spec.Template.Spec.Volumes = append(
registryDeployment.Spec.Template.Spec.Volumes,
corev1.Volume{
Name: secretName,
VolumeSource: corev1.VolumeSource{
Secret: &corev1.SecretVolumeSource{
SecretName: secretName,
},
},
},
)
}
} else if bsl.Spec.Provider == GCPProvider {
cloudProviderMap := credentials.PluginSpecificFields[oadpv1alpha1.DefaultPluginGCP]
registryDeployment.Spec.Template.Spec.Volumes = []corev1.Volume{
{
Name: secretName,
Name: cloudProviderMap.SecretName,
VolumeSource: corev1.VolumeSource{
Secret: &corev1.SecretVolumeSource{
SecretName: secretName,
SecretName: cloudProviderMap.SecretName,
},
},
},
Expand Down Expand Up @@ -372,10 +385,20 @@ func (r *DPAReconciler) buildRegistryContainer(bsl *velerov1.BackupStorageLocati
},
}

// append secret volumes if the BSL provider is GCP
if bsl.Spec.Provider == GCPProvider {
// check for secret name
secretName, _ := r.getSecretNameAndKey(bsl.Spec.Credential, oadpv1alpha1.DefaultPluginGCP)
// check for secret name
if _, ok := bsl.Spec.Config["credentialsFile"]; ok { // If credentialsFile config is used, then mount the bsl secret
if secretName, err := credentials.GetSecretNameFromCredentialsFileConfigString(bsl.Spec.Config["credentialsFile"]); err == nil {
if _, bslCredOk := credentials.PluginSpecificFields[oadpv1alpha1.DefaultPlugin(bsl.Spec.Provider)]; bslCredOk {
containers[0].VolumeMounts = []corev1.VolumeMount{
{
Name: secretName,
MountPath: credentials.PluginSpecificFields[oadpv1alpha1.DefaultPlugin(bsl.Spec.Provider)].BslMountPath,
},
}
}
}
} else if bsl.Spec.Provider == GCPProvider { // append secret volumes if the BSL provider is GCP
secretName, _ := r.getSecretNameAndKey(&bsl.Spec, oadpv1alpha1.DefaultPluginGCP)
containers[0].VolumeMounts = []corev1.VolumeMount{
{
Name: secretName,
Expand Down Expand Up @@ -512,8 +535,12 @@ func (r *DPAReconciler) getGCPRegistryEnvVars(bsl *velerov1.BackupStorageLocatio

if gcpEnvVars[i].Name == RegistryStorageGCSKeyfile {
// check for secret key
_, secretKey := r.getSecretNameAndKey(bsl.Spec.Credential, oadpv1alpha1.DefaultPluginGCP)
gcpEnvVars[i].Value = credentials.PluginSpecificFields[oadpv1alpha1.DefaultPluginGCP].MountPath + "/" + secretKey
_, secretKey := r.getSecretNameAndKey(&bsl.Spec, oadpv1alpha1.DefaultPluginGCP)
if _, ok := bsl.Spec.Config["credentialsFile"]; ok {
gcpEnvVars[i].Value = credentials.PluginSpecificFields[oadpv1alpha1.DefaultPluginGCP].BslMountPath + "/" + secretKey
} else {
gcpEnvVars[i].Value = credentials.PluginSpecificFields[oadpv1alpha1.DefaultPluginGCP].MountPath + "/" + secretKey
}
}
}
return gcpEnvVars, nil
Expand All @@ -532,8 +559,22 @@ func (r *DPAReconciler) getProviderSecret(secretName string) (corev1.Secret, err
return secret, err
}
r.Log.Info(fmt.Sprintf("got provider secret name: %s", secret.Name))
// replace carriage return with new line
secret.Data = replaceCarriageReturn(secret.Data, r.Log)
return secret, nil
}

func replaceCarriageReturn(data map[string][]byte, logger logr.Logger) map[string][]byte {
for k, v := range data {
// report if carriage return is found
if strings.Contains(string(v), "\r\n") {
logger.Info("carriage return replaced")
data[k] = []byte(strings.ReplaceAll(string(v), "\r\n", "\n"))
}
}
return data
}

func (r *DPAReconciler) getSecretNameAndKeyforBackupLocation(bslspec oadpv1alpha1.BackupLocation) (string, string) {

if bslspec.CloudStorage != nil {
Expand All @@ -542,18 +583,25 @@ func (r *DPAReconciler) getSecretNameAndKeyforBackupLocation(bslspec oadpv1alpha
}
}
if bslspec.Velero != nil {
return r.getSecretNameAndKey(bslspec.Velero.Credential, oadpv1alpha1.DefaultPlugin(bslspec.Velero.Provider))
return r.getSecretNameAndKey(bslspec.Velero, oadpv1alpha1.DefaultPlugin(bslspec.Velero.Provider))
}

return "", ""
}

func (r *DPAReconciler) getSecretNameAndKey(credential *corev1.SecretKeySelector, plugin oadpv1alpha1.DefaultPlugin) (string, string) {
func (r *DPAReconciler) getSecretNameAndKey(bslSpec *velerov1.BackupStorageLocationSpec, plugin oadpv1alpha1.DefaultPlugin) (string, string) {
// Assume default values unless user has overriden them
secretName := credentials.PluginSpecificFields[plugin].SecretName
secretKey := credentials.PluginSpecificFields[plugin].PluginSecretKey

if _, ok := bslSpec.Config["credentialsFile"]; ok {
if secretName, secretKey, err :=
credentials.GetSecretNameKeyFromCredentialsFileConfigString(bslSpec.Config["credentialsFile"]); err == nil {
r.Log.Info(fmt.Sprintf("credentialsFile secret: %s, key: %s", secretName, secretKey))
return secretName, secretKey
}
}
// check if user specified the Credential Name and Key
credential := bslSpec.Credential
if credential != nil {
if len(credential.Name) > 0 {
secretName = credential.Name
Expand Down Expand Up @@ -1143,12 +1191,16 @@ func (r *DPAReconciler) updateRegistrySecret(secret *corev1.Secret, bsl *velerov
err = r.populateAzureRegistrySecret(bsl, secret)
}

if err != nil {
return err
}

return nil
}

func (r *DPAReconciler) populateAWSRegistrySecret(bsl *velerov1.BackupStorageLocation, registrySecret *corev1.Secret) error {
// Check for secret name
secretName, secretKey := r.getSecretNameAndKey(bsl.Spec.Credential, oadpv1alpha1.DefaultPluginAWS)
secretName, secretKey := r.getSecretNameAndKey(&bsl.Spec, oadpv1alpha1.DefaultPluginAWS)

// fetch secret and error
secret, err := r.getProviderSecret(secretName)
Expand Down Expand Up @@ -1177,7 +1229,7 @@ func (r *DPAReconciler) populateAWSRegistrySecret(bsl *velerov1.BackupStorageLoc

func (r *DPAReconciler) populateAzureRegistrySecret(bsl *velerov1.BackupStorageLocation, registrySecret *corev1.Secret) error {
// Check for secret name
secretName, secretKey := r.getSecretNameAndKey(bsl.Spec.Credential, oadpv1alpha1.DefaultPluginMicrosoftAzure)
secretName, secretKey := r.getSecretNameAndKey(&bsl.Spec, oadpv1alpha1.DefaultPluginMicrosoftAzure)
r.Log.Info(fmt.Sprintf("Azure secret name: %s and secret key: %s", secretName, secretKey))

// fetch secret and error
Expand Down
Loading