Add AWS S3 backup provider
This commit is contained in:
parent
9e6c44484c
commit
b78bff897e
|
|
@ -0,0 +1,240 @@
|
||||||
|
package aws
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
virtuslabv1alpha1 "github.com/VirtusLab/jenkins-operator/pkg/apis/virtuslab/v1alpha1"
|
||||||
|
"github.com/VirtusLab/jenkins-operator/pkg/controller/jenkins/configuration/base/resources"
|
||||||
|
"github.com/VirtusLab/jenkins-operator/pkg/controller/jenkins/constants"
|
||||||
|
"github.com/VirtusLab/jenkins-operator/pkg/controller/jenkins/plugins"
|
||||||
|
"github.com/VirtusLab/jenkins-operator/pkg/log"
|
||||||
|
|
||||||
|
"github.com/go-logr/logr"
|
||||||
|
corev1 "k8s.io/api/core/v1"
|
||||||
|
"k8s.io/apimachinery/pkg/types"
|
||||||
|
k8s "sigs.k8s.io/controller-runtime/pkg/client"
|
||||||
|
)
|
||||||
|
|
||||||
|
// AmazonS3Backup is a backup strategy where backup is stored in AWS S3 bucket
|
||||||
|
// credentials required to make calls to AWS API are provided by user in backup credentials Kubernetes secret
|
||||||
|
type AmazonS3Backup struct{}
|
||||||
|
|
||||||
|
// GetRestoreJobXML returns Jenkins restore backup job config XML
|
||||||
|
func (b *AmazonS3Backup) GetRestoreJobXML(jenkins virtuslabv1alpha1.Jenkins) (string, error) {
|
||||||
|
return `<?xml version='1.1' encoding='UTF-8'?>
|
||||||
|
<flow-definition plugin="workflow-job@2.31">
|
||||||
|
<actions/>
|
||||||
|
<description></description>
|
||||||
|
<keepDependencies>false</keepDependencies>
|
||||||
|
<properties>
|
||||||
|
<org.jenkinsci.plugins.workflow.job.properties.DisableConcurrentBuildsJobProperty/>
|
||||||
|
<org.jenkinsci.plugins.workflow.job.properties.DisableResumeJobProperty/>
|
||||||
|
</properties>
|
||||||
|
<definition class="org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition" plugin="workflow-cps@2.61.1">
|
||||||
|
<script>import com.amazonaws.auth.PropertiesFileCredentialsProvider
|
||||||
|
import com.amazonaws.services.s3.AmazonS3ClientBuilder
|
||||||
|
import com.amazonaws.services.s3.model.AmazonS3Exception
|
||||||
|
import com.amazonaws.services.s3.model.S3Object
|
||||||
|
|
||||||
|
node('master') {
|
||||||
|
def accessKeyFilePath = "` + resources.JenkinsBackupCredentialsVolumePath + `/` + constants.BackupAmazonS3SecretAccessKey + `"
|
||||||
|
def secretKeyFilePath = "` + resources.JenkinsBackupCredentialsVolumePath + `/` + constants.BackupAmazonS3SecretSecretKey + `"
|
||||||
|
def credentialsFileName = "backup-credentials"
|
||||||
|
def bucketName = "` + jenkins.Spec.BackupAmazonS3.BucketName + `"
|
||||||
|
def bucketKey = "` + jenkins.Spec.BackupAmazonS3.BucketPath + `"
|
||||||
|
def region = "` + jenkins.Spec.BackupAmazonS3.Region + `"
|
||||||
|
def latestBackupFile = "` + constants.BackupLatestFileName + `"
|
||||||
|
|
||||||
|
def jenkinsHome = env.JENKINS_HOME
|
||||||
|
def latestBackupKey = "${bucketKey}/${latestBackupFile}"
|
||||||
|
def tmpBackupPath = "/tmp/restore.tar.gz"
|
||||||
|
boolean backupExists = true
|
||||||
|
|
||||||
|
def accessKey = new java.io.File(accessKeyFilePath).text
|
||||||
|
def secretKey = new java.io.File(secretKeyFilePath).text
|
||||||
|
sh "touch ${env.WORKSPACE}/${credentialsFileName}"
|
||||||
|
new java.io.File("${env.WORKSPACE}/${credentialsFileName}").write("accessKey=${accessKey}\nsecretKey=${secretKey}\n")
|
||||||
|
|
||||||
|
stage('Check if backup exists') {
|
||||||
|
def s3 = AmazonS3ClientBuilder
|
||||||
|
.standard()
|
||||||
|
.withCredentials(new PropertiesFileCredentialsProvider("${env.WORKSPACE}/${credentialsFileName}"))
|
||||||
|
.withRegion(region)
|
||||||
|
.build()
|
||||||
|
try {
|
||||||
|
println s3.getObjectMetadata(bucketName, latestBackupKey)
|
||||||
|
} catch (AmazonS3Exception e) {
|
||||||
|
if (e.getStatusCode() == 404) {
|
||||||
|
println "There is no backup ${bucketName}/${latestBackupKey}"
|
||||||
|
backupExists = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (backupExists) {
|
||||||
|
stage('Download backup') {
|
||||||
|
def s3 = AmazonS3ClientBuilder
|
||||||
|
.standard()
|
||||||
|
.withCredentials(new PropertiesFileCredentialsProvider("${env.WORKSPACE}/${credentialsFileName}"))
|
||||||
|
.withRegion(region)
|
||||||
|
.build()
|
||||||
|
S3Object backup = s3.getObject(bucketName, latestBackupKey)
|
||||||
|
java.nio.file.Files.copy(
|
||||||
|
backup.getObjectContent(),
|
||||||
|
new java.io.File(tmpBackupPath).toPath(),
|
||||||
|
java.nio.file.StandardCopyOption.REPLACE_EXISTING);
|
||||||
|
}
|
||||||
|
|
||||||
|
stage('Unpack backup') {
|
||||||
|
sh "tar -C ${jenkinsHome} -zxf ${tmpBackupPath}"
|
||||||
|
}
|
||||||
|
|
||||||
|
stage('Reload Jenkins') {
|
||||||
|
jenkins.model.Jenkins.getInstance().reload()
|
||||||
|
}
|
||||||
|
|
||||||
|
sh "rm ${tmpBackupPath}"
|
||||||
|
sh "rm ${env.WORKSPACE}/${credentialsFileName}"
|
||||||
|
}
|
||||||
|
}</script>
|
||||||
|
<sandbox>false</sandbox>
|
||||||
|
</definition>
|
||||||
|
<triggers/>
|
||||||
|
<disabled>false</disabled>
|
||||||
|
</flow-definition>`, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetBackupJobXML returns Jenkins backup job config XML
|
||||||
|
func (b *AmazonS3Backup) GetBackupJobXML(jenkins virtuslabv1alpha1.Jenkins) (string, error) {
|
||||||
|
return `<?xml version='1.1' encoding='UTF-8'?>
|
||||||
|
<flow-definition plugin="workflow-job@2.31">
|
||||||
|
<actions/>
|
||||||
|
<description></description>
|
||||||
|
<keepDependencies>false</keepDependencies>
|
||||||
|
<properties>
|
||||||
|
<org.jenkinsci.plugins.workflow.job.properties.DisableConcurrentBuildsJobProperty/>
|
||||||
|
<org.jenkinsci.plugins.workflow.job.properties.DisableResumeJobProperty/>
|
||||||
|
<org.jenkinsci.plugins.workflow.job.properties.PipelineTriggersJobProperty>
|
||||||
|
<triggers>
|
||||||
|
<hudson.triggers.TimerTrigger>
|
||||||
|
<spec>H/60 * * * *</spec>
|
||||||
|
</hudson.triggers.TimerTrigger>
|
||||||
|
</triggers>
|
||||||
|
</org.jenkinsci.plugins.workflow.job.properties.PipelineTriggersJobProperty>
|
||||||
|
</properties>
|
||||||
|
<definition class="org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition" plugin="workflow-cps@2.61">
|
||||||
|
<script>import com.amazonaws.auth.PropertiesFileCredentialsProvider
|
||||||
|
import com.amazonaws.services.s3.AmazonS3ClientBuilder
|
||||||
|
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
|
node('master') {
|
||||||
|
def accessKeyFilePath = "` + resources.JenkinsBackupCredentialsVolumePath + `/` + constants.BackupAmazonS3SecretAccessKey + `"
|
||||||
|
def secretKeyFilePath = "` + resources.JenkinsBackupCredentialsVolumePath + `/` + constants.BackupAmazonS3SecretSecretKey + `"
|
||||||
|
def credentialsFileName = "backup-credentials"
|
||||||
|
def bucketName = "` + jenkins.Spec.BackupAmazonS3.BucketName + `"
|
||||||
|
def bucketKey = "` + jenkins.Spec.BackupAmazonS3.BucketPath + `"
|
||||||
|
def region = "` + jenkins.Spec.BackupAmazonS3.Region + `"
|
||||||
|
def latestBackupFile = "` + constants.BackupLatestFileName + `"
|
||||||
|
|
||||||
|
def jenkinsHome = env.JENKINS_HOME
|
||||||
|
def backupTime = sh(script: "date '+%Y-%m-%d-%H-%M'", returnStdout: true).trim()
|
||||||
|
def tmpBackupPath = "/tmp/backup.tar.gz"
|
||||||
|
|
||||||
|
def backupKey = "${bucketKey}/build-history-${backupTime}.tar.gz"
|
||||||
|
def latestBackupKey = "${bucketKey}/${latestBackupFile}"
|
||||||
|
|
||||||
|
def accessKey = new java.io.File(accessKeyFilePath).text
|
||||||
|
def secretKey = new java.io.File(secretKeyFilePath).text
|
||||||
|
sh "touch ${env.WORKSPACE}/${credentialsFileName}"
|
||||||
|
new java.io.File("${env.WORKSPACE}/${credentialsFileName}").write("accessKey=${accessKey}\nsecretKey=${secretKey}\n")
|
||||||
|
|
||||||
|
stage('Create backup archive') {
|
||||||
|
println "Creating backup archive to ${tmpBackupPath}"
|
||||||
|
sh "tar -C ${jenkinsHome} -z --exclude jobs/*/config.xml --exclude jobs/*/workspace* --exclude jobs/*/simulation.log -c config-history jobs -f ${tmpBackupPath}"
|
||||||
|
}
|
||||||
|
|
||||||
|
stage('Upload backup') {
|
||||||
|
def s3 = AmazonS3ClientBuilder
|
||||||
|
.standard()
|
||||||
|
.withCredentials(new PropertiesFileCredentialsProvider("${env.WORKSPACE}/${credentialsFileName}"))
|
||||||
|
.withRegion(region)
|
||||||
|
.build()
|
||||||
|
println "Uploading backup to ${bucketName}/${backupKey}"
|
||||||
|
s3.putObject(bucketName, backupKey, new File(tmpBackupPath))
|
||||||
|
println s3.getObjectMetadata(bucketName, backupKey)
|
||||||
|
}
|
||||||
|
|
||||||
|
stage('Copy backup') {
|
||||||
|
def s3 = AmazonS3ClientBuilder
|
||||||
|
.standard()
|
||||||
|
.withCredentials(new PropertiesFileCredentialsProvider("${env.WORKSPACE}/${credentialsFileName}"))
|
||||||
|
.withRegion(region)
|
||||||
|
.build()
|
||||||
|
println "Coping backup ${bucketName}${backupKey} to ${bucketName}/${latestBackupKey}"
|
||||||
|
s3.copyObject(bucketName, backupKey, bucketName, latestBackupKey)
|
||||||
|
println s3.getObjectMetadata(bucketName, latestBackupKey)
|
||||||
|
}
|
||||||
|
|
||||||
|
sh "rm ${tmpBackupPath}"
|
||||||
|
sh "rm ${env.WORKSPACE}/${credentialsFileName}"
|
||||||
|
}</script>
|
||||||
|
<sandbox>false</sandbox>
|
||||||
|
</definition>
|
||||||
|
<triggers/>
|
||||||
|
<disabled>false</disabled>
|
||||||
|
</flow-definition>`, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsConfigurationValidForBasePhase validates if user provided valid configuration of backup for base phase
|
||||||
|
func (b *AmazonS3Backup) IsConfigurationValidForBasePhase(jenkins virtuslabv1alpha1.Jenkins, logger logr.Logger) bool {
|
||||||
|
if len(jenkins.Spec.BackupAmazonS3.BucketName) == 0 {
|
||||||
|
logger.V(log.VWarn).Info("Bucket name not set in 'spec.backupAmazonS3.bucketName'")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(jenkins.Spec.BackupAmazonS3.BucketPath) == 0 {
|
||||||
|
logger.V(log.VWarn).Info("Bucket path not set in 'spec.backupAmazonS3.bucketPath'")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(jenkins.Spec.BackupAmazonS3.Region) == 0 {
|
||||||
|
logger.V(log.VWarn).Info("Region not set in 'spec.backupAmazonS3.region'")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsConfigurationValidForUserPhase validates if user provided valid configuration of backup for user phase
|
||||||
|
func (b *AmazonS3Backup) IsConfigurationValidForUserPhase(k8sClient k8s.Client, jenkins virtuslabv1alpha1.Jenkins, logger logr.Logger) (bool, error) {
|
||||||
|
backupSecretName := resources.GetBackupCredentialsSecretName(&jenkins)
|
||||||
|
backupSecret := &corev1.Secret{}
|
||||||
|
err := k8sClient.Get(context.TODO(), types.NamespacedName{Namespace: jenkins.Namespace, Name: backupSecretName}, backupSecret)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(backupSecret.Data[constants.BackupAmazonS3SecretSecretKey]) == 0 {
|
||||||
|
logger.V(log.VWarn).Info(fmt.Sprintf("Secret '%s' doesn't contains key: %s", backupSecretName, constants.BackupAmazonS3SecretSecretKey))
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(backupSecret.Data[constants.BackupAmazonS3SecretAccessKey]) == 0 {
|
||||||
|
logger.V(log.VWarn).Info(fmt.Sprintf("Secret '%s' doesn't contains key: %s", backupSecretName, constants.BackupAmazonS3SecretAccessKey))
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetRequiredPlugins returns all required Jenkins plugins by this backup strategy
|
||||||
|
func (b *AmazonS3Backup) GetRequiredPlugins() map[string][]plugins.Plugin {
|
||||||
|
return map[string][]plugins.Plugin{
|
||||||
|
"aws-java-sdk:1.11.457": {
|
||||||
|
plugins.Must(plugins.New(plugins.ApacheComponentsClientPlugin)),
|
||||||
|
plugins.Must(plugins.New(plugins.Jackson2ADIPlugin)),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,165 @@
|
||||||
|
package aws
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
virtuslabv1alpha1 "github.com/VirtusLab/jenkins-operator/pkg/apis/virtuslab/v1alpha1"
|
||||||
|
"github.com/VirtusLab/jenkins-operator/pkg/controller/jenkins/constants"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
corev1 "k8s.io/api/core/v1"
|
||||||
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
|
"sigs.k8s.io/controller-runtime/pkg/client/fake"
|
||||||
|
logf "sigs.k8s.io/controller-runtime/pkg/runtime/log"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestAmazonS3Backup_IsConfigurationValidForBasePhase(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
jenkins virtuslabv1alpha1.Jenkins
|
||||||
|
want bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "happy",
|
||||||
|
jenkins: virtuslabv1alpha1.Jenkins{
|
||||||
|
Spec: virtuslabv1alpha1.JenkinsSpec{
|
||||||
|
BackupAmazonS3: virtuslabv1alpha1.JenkinsBackupAmazonS3{
|
||||||
|
BucketName: "some-value",
|
||||||
|
BucketPath: "some-value",
|
||||||
|
Region: "some-value",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
want: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "fail, no bucket name",
|
||||||
|
jenkins: virtuslabv1alpha1.Jenkins{
|
||||||
|
Spec: virtuslabv1alpha1.JenkinsSpec{
|
||||||
|
BackupAmazonS3: virtuslabv1alpha1.JenkinsBackupAmazonS3{
|
||||||
|
BucketName: "",
|
||||||
|
BucketPath: "some-value",
|
||||||
|
Region: "some-value",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
want: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "fail, no bucket path",
|
||||||
|
jenkins: virtuslabv1alpha1.Jenkins{
|
||||||
|
Spec: virtuslabv1alpha1.JenkinsSpec{
|
||||||
|
BackupAmazonS3: virtuslabv1alpha1.JenkinsBackupAmazonS3{
|
||||||
|
BucketName: "some-value",
|
||||||
|
BucketPath: "",
|
||||||
|
Region: "some-value",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
want: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "fail, no region",
|
||||||
|
jenkins: virtuslabv1alpha1.Jenkins{
|
||||||
|
Spec: virtuslabv1alpha1.JenkinsSpec{
|
||||||
|
BackupAmazonS3: virtuslabv1alpha1.JenkinsBackupAmazonS3{
|
||||||
|
BucketName: "some-value",
|
||||||
|
BucketPath: "some-value",
|
||||||
|
Region: "",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
want: false,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
r := &AmazonS3Backup{}
|
||||||
|
got := r.IsConfigurationValidForBasePhase(tt.jenkins, logf.ZapLogger(false))
|
||||||
|
assert.Equal(t, tt.want, got)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAmazonS3Backup_IsConfigurationValidForUserPhase(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
jenkins *virtuslabv1alpha1.Jenkins
|
||||||
|
secret *corev1.Secret
|
||||||
|
want bool
|
||||||
|
wantErr bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "happy",
|
||||||
|
jenkins: &virtuslabv1alpha1.Jenkins{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{Namespace: "namespace-name", Name: "jenkins-cr-name"},
|
||||||
|
},
|
||||||
|
secret: &corev1.Secret{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{Namespace: "namespace-name", Name: "jenkins-operator-backup-credentials-jenkins-cr-name"},
|
||||||
|
Data: map[string][]byte{
|
||||||
|
constants.BackupAmazonS3SecretSecretKey: []byte("some-value"),
|
||||||
|
constants.BackupAmazonS3SecretAccessKey: []byte("some-value"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
want: true,
|
||||||
|
wantErr: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "fail, no secret",
|
||||||
|
jenkins: &virtuslabv1alpha1.Jenkins{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{Namespace: "namespace-name", Name: "jenkins-cr-name"},
|
||||||
|
},
|
||||||
|
want: false,
|
||||||
|
wantErr: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "fail, no secret key in secret",
|
||||||
|
jenkins: &virtuslabv1alpha1.Jenkins{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{Namespace: "namespace-name", Name: "jenkins-cr-name"},
|
||||||
|
},
|
||||||
|
secret: &corev1.Secret{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{Namespace: "namespace-name", Name: "jenkins-operator-backup-credentials-jenkins-cr-name"},
|
||||||
|
Data: map[string][]byte{
|
||||||
|
constants.BackupAmazonS3SecretSecretKey: []byte(""),
|
||||||
|
constants.BackupAmazonS3SecretAccessKey: []byte("some-value"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
want: false,
|
||||||
|
wantErr: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "fail, no access key in secret",
|
||||||
|
jenkins: &virtuslabv1alpha1.Jenkins{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{Namespace: "namespace-name", Name: "jenkins-cr-name"},
|
||||||
|
},
|
||||||
|
secret: &corev1.Secret{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{Namespace: "namespace-name", Name: "jenkins-operator-backup-credentials-jenkins-cr-name"},
|
||||||
|
Data: map[string][]byte{
|
||||||
|
constants.BackupAmazonS3SecretSecretKey: []byte("some-value"),
|
||||||
|
constants.BackupAmazonS3SecretAccessKey: []byte(""),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
want: false,
|
||||||
|
wantErr: false,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
k8sClient := fake.NewFakeClient()
|
||||||
|
logger := logf.ZapLogger(false)
|
||||||
|
b := &AmazonS3Backup{}
|
||||||
|
if tt.secret != nil {
|
||||||
|
e := k8sClient.Create(context.TODO(), tt.secret)
|
||||||
|
assert.NoError(t, e)
|
||||||
|
}
|
||||||
|
got, err := b.IsConfigurationValidForUserPhase(k8sClient, *tt.jenkins, logger)
|
||||||
|
if tt.wantErr {
|
||||||
|
assert.Error(t, err)
|
||||||
|
} else {
|
||||||
|
assert.NoError(t, err)
|
||||||
|
}
|
||||||
|
assert.Equal(t, tt.want, got)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -6,6 +6,7 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
virtuslabv1alpha1 "github.com/VirtusLab/jenkins-operator/pkg/apis/virtuslab/v1alpha1"
|
virtuslabv1alpha1 "github.com/VirtusLab/jenkins-operator/pkg/apis/virtuslab/v1alpha1"
|
||||||
|
"github.com/VirtusLab/jenkins-operator/pkg/controller/jenkins/backup/aws"
|
||||||
"github.com/VirtusLab/jenkins-operator/pkg/controller/jenkins/backup/nobackup"
|
"github.com/VirtusLab/jenkins-operator/pkg/controller/jenkins/backup/nobackup"
|
||||||
jenkinsclient "github.com/VirtusLab/jenkins-operator/pkg/controller/jenkins/client"
|
jenkinsclient "github.com/VirtusLab/jenkins-operator/pkg/controller/jenkins/client"
|
||||||
"github.com/VirtusLab/jenkins-operator/pkg/controller/jenkins/configuration/base/resources"
|
"github.com/VirtusLab/jenkins-operator/pkg/controller/jenkins/configuration/base/resources"
|
||||||
|
|
@ -32,7 +33,7 @@ type Provider interface {
|
||||||
GetRequiredPlugins() map[string][]plugins.Plugin
|
GetRequiredPlugins() map[string][]plugins.Plugin
|
||||||
}
|
}
|
||||||
|
|
||||||
// Backup defines backup manager which is responsible of backup jobs history
|
// Backup defines backup manager which is responsible of backup of jobs history
|
||||||
type Backup struct {
|
type Backup struct {
|
||||||
jenkins *virtuslabv1alpha1.Jenkins
|
jenkins *virtuslabv1alpha1.Jenkins
|
||||||
k8sClient k8s.Client
|
k8sClient k8s.Client
|
||||||
|
|
@ -130,6 +131,8 @@ func GetBackupProvider(backupType virtuslabv1alpha1.JenkinsBackup) (Provider, er
|
||||||
switch backupType {
|
switch backupType {
|
||||||
case virtuslabv1alpha1.JenkinsBackupTypeNoBackup:
|
case virtuslabv1alpha1.JenkinsBackupTypeNoBackup:
|
||||||
return &nobackup.NoBackup{}, nil
|
return &nobackup.NoBackup{}, nil
|
||||||
|
case virtuslabv1alpha1.JenkinsBackupTypeAmazonS3:
|
||||||
|
return &aws.AmazonS3Backup{}, nil
|
||||||
default:
|
default:
|
||||||
return nil, errors.Errorf("Invalid BackupManager type '%s'", backupType)
|
return nil, errors.Errorf("Invalid BackupManager type '%s'", backupType)
|
||||||
}
|
}
|
||||||
|
|
@ -155,6 +158,6 @@ func GetPluginsRequiredByAllBackupProviders() map[string][]plugins.Plugin {
|
||||||
|
|
||||||
func getAllProviders() []Provider {
|
func getAllProviders() []Provider {
|
||||||
return []Provider{
|
return []Provider{
|
||||||
&nobackup.NoBackup{},
|
&nobackup.NoBackup{}, &aws.AmazonS3Backup{},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,4 +15,6 @@ const (
|
||||||
BackupAmazonS3SecretSecretKey = "secret-key"
|
BackupAmazonS3SecretSecretKey = "secret-key"
|
||||||
// BackupJobName is the Jenkins job name used to backup jobs history
|
// BackupJobName is the Jenkins job name used to backup jobs history
|
||||||
BackupJobName = OperatorName + "-backup"
|
BackupJobName = OperatorName + "-backup"
|
||||||
|
// BackupLatestFileName is the latest backup file name
|
||||||
|
BackupLatestFileName = "build-history-latest.tar.gz"
|
||||||
)
|
)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue