Added TestPlugins, TestRestart and TestRestoreBackup (#504)
Co-authored-by: Tomasz Sęk
This commit is contained in:
parent
294be87c64
commit
021ebb4745
|
|
@ -211,14 +211,6 @@ func (r *JenkinsReconciler) reconcile(request reconcile.Request) (reconcile.Resu
|
||||||
return reconcile.Result{Requeue: true}, jenkins, nil
|
return reconcile.Result{Requeue: true}, jenkins, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
requeue, err = r.handleDeprecatedData(jenkins)
|
|
||||||
if err != nil {
|
|
||||||
return reconcile.Result{}, jenkins, err
|
|
||||||
}
|
|
||||||
if requeue {
|
|
||||||
return reconcile.Result{Requeue: true}, jenkins, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
config := r.newJenkinsReconcilier(jenkins)
|
config := r.newJenkinsReconcilier(jenkins)
|
||||||
// Reconcile base configuration
|
// Reconcile base configuration
|
||||||
baseConfiguration := base.New(config, r.JenkinsAPIConnectionSettings)
|
baseConfiguration := base.New(config, r.JenkinsAPIConnectionSettings)
|
||||||
|
|
@ -367,7 +359,7 @@ func (r *JenkinsReconciler) setDefaults(jenkins *v1alpha2.Jenkins) (requeue bool
|
||||||
if jenkinsContainer.ReadinessProbe == nil {
|
if jenkinsContainer.ReadinessProbe == nil {
|
||||||
logger.Info("Setting default Jenkins readinessProbe")
|
logger.Info("Setting default Jenkins readinessProbe")
|
||||||
changed = true
|
changed = true
|
||||||
jenkinsContainer.ReadinessProbe = resources.NewSimpleProbe(containerProbeURI, containerProbePortName, corev1.URISchemeHTTP, 30)
|
jenkinsContainer.ReadinessProbe = resources.NewProbe(containerProbeURI, containerProbePortName, corev1.URISchemeHTTP, 30, 1, 3)
|
||||||
}
|
}
|
||||||
if jenkinsContainer.LivenessProbe == nil {
|
if jenkinsContainer.LivenessProbe == nil {
|
||||||
logger.Info("Setting default Jenkins livenessProbe")
|
logger.Info("Setting default Jenkins livenessProbe")
|
||||||
|
|
@ -493,7 +485,3 @@ func basePlugins() (result []v1alpha2.Plugin) {
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *JenkinsReconciler) handleDeprecatedData(_ *v1alpha2.Jenkins) (requeue bool, err error) {
|
|
||||||
return false, nil
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ import (
|
||||||
"k8s.io/apimachinery/pkg/util/intstr"
|
"k8s.io/apimachinery/pkg/util/intstr"
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewSimpleProbe(uri string, port string, scheme corev1.URIScheme, initialDelaySeconds int32) *corev1.Probe {
|
func NewProbe(uri string, port string, scheme corev1.URIScheme, initialDelaySeconds, timeoutSeconds, failureThreshold int32) *corev1.Probe {
|
||||||
return &corev1.Probe{
|
return &corev1.Probe{
|
||||||
Handler: corev1.Handler{
|
Handler: corev1.Handler{
|
||||||
HTTPGet: &corev1.HTTPGetAction{
|
HTTPGet: &corev1.HTTPGetAction{
|
||||||
|
|
@ -15,14 +15,9 @@ func NewSimpleProbe(uri string, port string, scheme corev1.URIScheme, initialDel
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
InitialDelaySeconds: initialDelaySeconds,
|
InitialDelaySeconds: initialDelaySeconds,
|
||||||
|
TimeoutSeconds: timeoutSeconds,
|
||||||
|
FailureThreshold: failureThreshold,
|
||||||
SuccessThreshold: int32(1),
|
SuccessThreshold: int32(1),
|
||||||
PeriodSeconds: int32(1),
|
PeriodSeconds: int32(1),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewProbe(uri string, port string, scheme corev1.URIScheme, initialDelaySeconds, timeoutSeconds, failureThreshold int32) *corev1.Probe {
|
|
||||||
p := NewSimpleProbe(uri, port, scheme, initialDelaySeconds)
|
|
||||||
p.TimeoutSeconds = timeoutSeconds
|
|
||||||
p.FailureThreshold = failureThreshold
|
|
||||||
return p
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -23,49 +23,6 @@ import (
|
||||||
|
|
||||||
const e2e = "e2e"
|
const e2e = "e2e"
|
||||||
|
|
||||||
// FIXME
|
|
||||||
/*func TestPlugins(t *testing.T) {
|
|
||||||
t.Parallel()
|
|
||||||
namespace, ctx := setupTest(t)
|
|
||||||
// Deletes test namespace
|
|
||||||
defer showLogsAndCleanup(t, ctx)
|
|
||||||
|
|
||||||
jobID := "k8s-e2e"
|
|
||||||
|
|
||||||
priorityClassName := ""
|
|
||||||
seedJobs := &[]v1alpha2.SeedJob{
|
|
||||||
{
|
|
||||||
ID: "jenkins-operator",
|
|
||||||
CredentialID: "jenkins-operator",
|
|
||||||
JenkinsCredentialType: v1alpha2.NoJenkinsCredentialCredentialType,
|
|
||||||
Targets: "cicd/jobs/k8s.jenkins",
|
|
||||||
Description: "Jenkins Operator repository",
|
|
||||||
RepositoryBranch: "master",
|
|
||||||
RepositoryURL: "https://github.com/jenkinsci/kubernetes-operator.git",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
jenkins := createJenkinsCR(t, "k8s-e2e", namespace, seedJobs, v1alpha2.GroovyScripts{}, v1alpha2.ConfigurationAsCode{}, priorityClassName)
|
|
||||||
waitForJenkinsUserConfigurationToComplete(t, jenkins)
|
|
||||||
|
|
||||||
jenkinsClient, cleanUpFunc := verifyJenkinsAPIConnection(t, jenkins, namespace)
|
|
||||||
defer cleanUpFunc()
|
|
||||||
waitForJob(t, jenkinsClient, jobID)
|
|
||||||
job, err := jenkinsClient.GetJob(jobID)
|
|
||||||
|
|
||||||
require.NoError(t, err, job)
|
|
||||||
i, err := job.InvokeSimple(map[string]string{})
|
|
||||||
require.NoError(t, err, i)
|
|
||||||
// FIXME: waitForJobToFinish use
|
|
||||||
time.Sleep(100 * time.Second) // wait for the build to complete
|
|
||||||
|
|
||||||
job, err = jenkinsClient.GetJob(jobID)
|
|
||||||
require.NoError(t, err, job)
|
|
||||||
build, err := job.GetLastBuild()
|
|
||||||
require.NoError(t, err)
|
|
||||||
assert.True(t, build.IsGood())
|
|
||||||
}*/
|
|
||||||
|
|
||||||
func createUserConfigurationSecret(namespace string, stringData map[string]string) {
|
func createUserConfigurationSecret(namespace string, stringData map[string]string) {
|
||||||
By("creating user configuration secret")
|
By("creating user configuration secret")
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -139,3 +139,58 @@ var _ = Describe("Jenkins controller priority class", func() {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
var _ = Describe("Jenkins controller plugins test", func() {
|
||||||
|
|
||||||
|
const (
|
||||||
|
jenkinsCRName = e2e
|
||||||
|
priorityClassName = ""
|
||||||
|
jobID = "k8s-e2e"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
namespace *corev1.Namespace
|
||||||
|
jenkins *v1alpha2.Jenkins
|
||||||
|
mySeedJob = seedJobConfig{
|
||||||
|
SeedJob: v1alpha2.SeedJob{
|
||||||
|
ID: "jenkins-operator",
|
||||||
|
CredentialID: "jenkins-operator",
|
||||||
|
JenkinsCredentialType: v1alpha2.NoJenkinsCredentialCredentialType,
|
||||||
|
Targets: "cicd/jobs/k8s.jenkins",
|
||||||
|
Description: "Jenkins Operator repository",
|
||||||
|
RepositoryBranch: "master",
|
||||||
|
RepositoryURL: "https://github.com/jenkinsci/kubernetes-operator.git",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
groovyScripts = v1alpha2.GroovyScripts{
|
||||||
|
Customization: v1alpha2.Customization{
|
||||||
|
Configurations: []v1alpha2.ConfigMapRef{},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
casc = v1alpha2.ConfigurationAsCode{
|
||||||
|
Customization: v1alpha2.Customization{
|
||||||
|
Configurations: []v1alpha2.ConfigMapRef{},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
BeforeEach(func() {
|
||||||
|
namespace = createNamespace()
|
||||||
|
jenkins = createJenkinsCRSafe(jenkinsCRName, namespace.Name, &[]v1alpha2.SeedJob{mySeedJob.SeedJob}, groovyScripts, casc, priorityClassName)
|
||||||
|
})
|
||||||
|
|
||||||
|
AfterEach(func() {
|
||||||
|
destroyNamespace(namespace)
|
||||||
|
})
|
||||||
|
|
||||||
|
Context("when deploying CR with a SeedJob to cluster", func() {
|
||||||
|
It("runs kubernetes plugin job successfully", func() {
|
||||||
|
waitForJenkinsUserConfigurationToComplete(jenkins)
|
||||||
|
jenkinsClient, cleanUpFunc := verifyJenkinsAPIConnection(jenkins, namespace.Name)
|
||||||
|
defer cleanUpFunc()
|
||||||
|
waitForJobCreation(jenkinsClient, jobID)
|
||||||
|
verifyJobCanBeRun(jenkinsClient, jobID)
|
||||||
|
verifyJobHasBeenRunCorrectly(jenkinsClient, jobID)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,108 @@
|
||||||
|
package e2e
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/jenkinsci/kubernetes-operator/api/v1alpha2"
|
||||||
|
|
||||||
|
. "github.com/onsi/ginkgo"
|
||||||
|
. "github.com/onsi/gomega"
|
||||||
|
corev1 "k8s.io/api/core/v1"
|
||||||
|
// +kubebuilder:scaffold:imports
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ = Describe("Jenkins controller", func() {
|
||||||
|
|
||||||
|
const (
|
||||||
|
jenkinsCRName = e2e
|
||||||
|
priorityClassName = ""
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
namespace *corev1.Namespace
|
||||||
|
jenkins *v1alpha2.Jenkins
|
||||||
|
groovyScripts = v1alpha2.GroovyScripts{
|
||||||
|
Customization: v1alpha2.Customization{
|
||||||
|
Configurations: []v1alpha2.ConfigMapRef{},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
casc = v1alpha2.ConfigurationAsCode{
|
||||||
|
Customization: v1alpha2.Customization{
|
||||||
|
Configurations: []v1alpha2.ConfigMapRef{},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
BeforeEach(func() {
|
||||||
|
namespace = createNamespace()
|
||||||
|
|
||||||
|
configureAuthorizationToUnSecure(namespace.Name, userConfigurationConfigMapName)
|
||||||
|
jenkins = createJenkinsCR(jenkinsCRName, namespace.Name, nil, groovyScripts, casc, priorityClassName)
|
||||||
|
})
|
||||||
|
|
||||||
|
AfterEach(func() {
|
||||||
|
destroyNamespace(namespace)
|
||||||
|
})
|
||||||
|
|
||||||
|
Context("when restarting Jenkins master pod", func() {
|
||||||
|
It("new Jenkins Master pod should be created", func() {
|
||||||
|
waitForJenkinsBaseConfigurationToComplete(jenkins)
|
||||||
|
restartJenkinsMasterPod(jenkins)
|
||||||
|
waitForRecreateJenkinsMasterPod(jenkins)
|
||||||
|
checkBaseConfigurationCompleteTimeIsNotSet(jenkins)
|
||||||
|
waitForJenkinsBaseConfigurationToComplete(jenkins)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
var _ = Describe("Jenkins controller", func() {
|
||||||
|
|
||||||
|
const (
|
||||||
|
jenkinsCRName = e2e
|
||||||
|
priorityClassName = ""
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
namespace *corev1.Namespace
|
||||||
|
jenkins *v1alpha2.Jenkins
|
||||||
|
groovyScripts = v1alpha2.GroovyScripts{
|
||||||
|
Customization: v1alpha2.Customization{
|
||||||
|
Configurations: []v1alpha2.ConfigMapRef{
|
||||||
|
{
|
||||||
|
Name: userConfigurationConfigMapName,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
casc = v1alpha2.ConfigurationAsCode{
|
||||||
|
Customization: v1alpha2.Customization{
|
||||||
|
Configurations: []v1alpha2.ConfigMapRef{},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
BeforeEach(func() {
|
||||||
|
namespace = createNamespace()
|
||||||
|
|
||||||
|
configureAuthorizationToUnSecure(namespace.Name, userConfigurationConfigMapName)
|
||||||
|
jenkins = createJenkinsCRSafeRestart(jenkinsCRName, namespace.Name, nil, groovyScripts, casc, priorityClassName)
|
||||||
|
})
|
||||||
|
|
||||||
|
AfterEach(func() {
|
||||||
|
destroyNamespace(namespace)
|
||||||
|
})
|
||||||
|
|
||||||
|
Context("when running Jenkins safe restart", func() {
|
||||||
|
It("authorization strategy is not overwritten", func() {
|
||||||
|
waitForJenkinsBaseConfigurationToComplete(jenkins)
|
||||||
|
waitForJenkinsUserConfigurationToComplete(jenkins)
|
||||||
|
jenkinsClient, cleanUpFunc := verifyJenkinsAPIConnection(jenkins, namespace.Name)
|
||||||
|
defer cleanUpFunc()
|
||||||
|
checkIfAuthorizationStrategyUnsecuredIsSet(jenkinsClient)
|
||||||
|
|
||||||
|
err := jenkinsClient.SafeRestart()
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
waitForJenkinsSafeRestart(jenkinsClient)
|
||||||
|
|
||||||
|
checkIfAuthorizationStrategyUnsecuredIsSet(jenkinsClient)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
@ -0,0 +1,61 @@
|
||||||
|
package e2e
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/jenkinsci/kubernetes-operator/api/v1alpha2"
|
||||||
|
|
||||||
|
. "github.com/onsi/ginkgo"
|
||||||
|
corev1 "k8s.io/api/core/v1"
|
||||||
|
// +kubebuilder:scaffold:imports
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ = Describe("Jenkins controller backup and restore", func() {
|
||||||
|
|
||||||
|
const (
|
||||||
|
jenkinsCRName = e2e
|
||||||
|
jobID = "e2e-jenkins-operator"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
namespace *corev1.Namespace
|
||||||
|
jenkins *v1alpha2.Jenkins
|
||||||
|
)
|
||||||
|
|
||||||
|
BeforeEach(func() {
|
||||||
|
namespace = createNamespace()
|
||||||
|
|
||||||
|
createPVC(namespace.Name)
|
||||||
|
jenkins = createJenkinsWithBackupAndRestoreConfigured(jenkinsCRName, namespace.Name)
|
||||||
|
})
|
||||||
|
|
||||||
|
AfterEach(func() {
|
||||||
|
destroyNamespace(namespace)
|
||||||
|
})
|
||||||
|
|
||||||
|
Context("when deploying CR with backup enabled to cluster", func() {
|
||||||
|
It("performs backups before pod deletion and restores them even Jenkins status is restarted", func() {
|
||||||
|
waitForJenkinsUserConfigurationToComplete(jenkins)
|
||||||
|
jenkinsClient, cleanUpFunc := verifyJenkinsAPIConnection(jenkins, namespace.Name)
|
||||||
|
defer cleanUpFunc()
|
||||||
|
waitForJobCreation(jenkinsClient, jobID)
|
||||||
|
verifyJobCanBeRun(jenkinsClient, jobID)
|
||||||
|
|
||||||
|
jenkins = getJenkins(jenkins.Namespace, jenkins.Name)
|
||||||
|
restartJenkinsMasterPod(jenkins)
|
||||||
|
waitForRecreateJenkinsMasterPod(jenkins)
|
||||||
|
waitForJenkinsUserConfigurationToComplete(jenkins)
|
||||||
|
jenkinsClient2, cleanUpFunc2 := verifyJenkinsAPIConnection(jenkins, namespace.Name)
|
||||||
|
defer cleanUpFunc2()
|
||||||
|
waitForJobCreation(jenkinsClient2, jobID)
|
||||||
|
verifyJobBuildsAfterRestoreBackup(jenkinsClient2, jobID)
|
||||||
|
|
||||||
|
resetJenkinsStatus(jenkins)
|
||||||
|
jenkins = getJenkins(jenkins.Namespace, jenkins.Name)
|
||||||
|
checkBaseConfigurationCompleteTimeIsNotSet(jenkins)
|
||||||
|
waitForJenkinsUserConfigurationToComplete(jenkins)
|
||||||
|
jenkinsClient3, cleanUpFunc3 := verifyJenkinsAPIConnection(jenkins, namespace.Name)
|
||||||
|
defer cleanUpFunc3()
|
||||||
|
waitForJobCreation(jenkinsClient3, jobID)
|
||||||
|
verifyJobBuildsAfterRestoreBackup(jenkinsClient3, jobID)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
@ -152,6 +152,112 @@ func createJenkinsCR(name, namespace string, seedJob *[]v1alpha2.SeedJob, groovy
|
||||||
return jenkins
|
return jenkins
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func createJenkinsCRSafeRestart(name, namespace string, seedJob *[]v1alpha2.SeedJob, groovyScripts v1alpha2.GroovyScripts, casc v1alpha2.ConfigurationAsCode, priorityClassName string) *v1alpha2.Jenkins {
|
||||||
|
var seedJobs []v1alpha2.SeedJob
|
||||||
|
if seedJob != nil {
|
||||||
|
seedJobs = append(seedJobs, *seedJob...)
|
||||||
|
}
|
||||||
|
|
||||||
|
jenkins := &v1alpha2.Jenkins{
|
||||||
|
TypeMeta: v1alpha2.JenkinsTypeMeta(),
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: name,
|
||||||
|
Namespace: namespace,
|
||||||
|
},
|
||||||
|
Spec: v1alpha2.JenkinsSpec{
|
||||||
|
GroovyScripts: groovyScripts,
|
||||||
|
ConfigurationAsCode: casc,
|
||||||
|
Master: v1alpha2.JenkinsMaster{
|
||||||
|
Annotations: map[string]string{"test": "label"},
|
||||||
|
Containers: []v1alpha2.Container{
|
||||||
|
{
|
||||||
|
Name: resources.JenkinsMasterContainerName,
|
||||||
|
Env: []corev1.EnvVar{
|
||||||
|
{
|
||||||
|
Name: "TEST_ENV",
|
||||||
|
Value: "test_env_value",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
ReadinessProbe: &corev1.Probe{
|
||||||
|
Handler: corev1.Handler{
|
||||||
|
HTTPGet: &corev1.HTTPGetAction{
|
||||||
|
Path: "/login",
|
||||||
|
Port: intstr.FromString("http"),
|
||||||
|
Scheme: corev1.URISchemeHTTP,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
InitialDelaySeconds: int32(80),
|
||||||
|
TimeoutSeconds: int32(4),
|
||||||
|
FailureThreshold: int32(10),
|
||||||
|
SuccessThreshold: int32(1),
|
||||||
|
PeriodSeconds: int32(1),
|
||||||
|
},
|
||||||
|
LivenessProbe: &corev1.Probe{
|
||||||
|
Handler: corev1.Handler{
|
||||||
|
HTTPGet: &corev1.HTTPGetAction{
|
||||||
|
Path: "/login",
|
||||||
|
Port: intstr.FromString("http"),
|
||||||
|
Scheme: corev1.URISchemeHTTP,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
InitialDelaySeconds: int32(100),
|
||||||
|
TimeoutSeconds: int32(5),
|
||||||
|
FailureThreshold: int32(12),
|
||||||
|
SuccessThreshold: int32(1),
|
||||||
|
PeriodSeconds: int32(5),
|
||||||
|
},
|
||||||
|
VolumeMounts: []corev1.VolumeMount{
|
||||||
|
{
|
||||||
|
Name: "plugins-cache",
|
||||||
|
MountPath: "/usr/share/jenkins/ref/plugins",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "envoyproxy",
|
||||||
|
Image: "envoyproxy/envoy-alpine:v1.14.1",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Plugins: []v1alpha2.Plugin{
|
||||||
|
{Name: "audit-trail", Version: "3.7"},
|
||||||
|
{Name: "simple-theme-plugin", Version: "0.6"},
|
||||||
|
{Name: "github", Version: "1.32.0"},
|
||||||
|
{Name: "devoptics", Version: "1.1905", DownloadURL: "https://jenkins-updates.cloudbees.com/download/plugins/devoptics/1.1905/devoptics.hpi"},
|
||||||
|
},
|
||||||
|
PriorityClassName: priorityClassName,
|
||||||
|
NodeSelector: map[string]string{"kubernetes.io/os": "linux"},
|
||||||
|
Volumes: []corev1.Volume{
|
||||||
|
{
|
||||||
|
Name: "plugins-cache",
|
||||||
|
VolumeSource: corev1.VolumeSource{
|
||||||
|
EmptyDir: &corev1.EmptyDirVolumeSource{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
SeedJobs: seedJobs,
|
||||||
|
Service: v1alpha2.Service{
|
||||||
|
Type: corev1.ServiceTypeNodePort,
|
||||||
|
Port: constants.DefaultHTTPPortInt32,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
jenkins.Spec.Roles = []rbacv1.RoleRef{
|
||||||
|
{
|
||||||
|
APIGroup: "rbac.authorization.k8s.io",
|
||||||
|
Kind: "Role",
|
||||||
|
Name: resources.GetResourceName(jenkins),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
updateJenkinsCR(jenkins)
|
||||||
|
|
||||||
|
_, _ = fmt.Fprintf(GinkgoWriter, "Jenkins CR %+v\n", *jenkins)
|
||||||
|
|
||||||
|
Expect(k8sClient.Create(context.TODO(), jenkins)).Should(Succeed())
|
||||||
|
|
||||||
|
return jenkins
|
||||||
|
}
|
||||||
|
|
||||||
func createJenkinsAPIClientFromServiceAccount(jenkins *v1alpha2.Jenkins, jenkinsAPIURL string) (jenkinsclient.Jenkins, error) {
|
func createJenkinsAPIClientFromServiceAccount(jenkins *v1alpha2.Jenkins, jenkinsAPIURL string) (jenkinsclient.Jenkins, error) {
|
||||||
podName := resources.GetJenkinsMasterPodName(jenkins)
|
podName := resources.GetJenkinsMasterPodName(jenkins)
|
||||||
|
|
||||||
|
|
@ -224,12 +330,18 @@ func verifyJenkinsAPIConnection(jenkins *v1alpha2.Jenkins, namespace string) (je
|
||||||
return jenkinsClient, cleanUpFunc
|
return jenkinsClient, cleanUpFunc
|
||||||
}
|
}
|
||||||
|
|
||||||
/*func restartJenkinsMasterPod(jenkins *v1alpha2.Jenkins) {
|
func restartJenkinsMasterPod(jenkins *v1alpha2.Jenkins) {
|
||||||
_, _ = fmt.Fprintf(GinkgoWriter, "Restarting Jenkins master pod")
|
_, _ = fmt.Fprintf(GinkgoWriter, "Restarting Jenkins master pod\n")
|
||||||
jenkinsPod := getJenkinsMasterPod(jenkins)
|
jenkinsPod := getJenkinsMasterPod(jenkins)
|
||||||
Expect(k8sClient.Delete(context.TODO(), jenkinsPod)).Should(Succeed())
|
Expect(k8sClient.Delete(context.TODO(), jenkinsPod)).Should(Succeed())
|
||||||
_, _ = fmt.Fprintf(GinkgoWriter, "Jenkins master pod has been restarted")
|
|
||||||
}*/
|
Eventually(func() (bool, error) {
|
||||||
|
jenkinsPod = getJenkinsMasterPod(jenkins)
|
||||||
|
return jenkinsPod.DeletionTimestamp != nil, nil
|
||||||
|
}, 30*retryInterval, retryInterval).Should(BeTrue())
|
||||||
|
|
||||||
|
_, _ = fmt.Fprintf(GinkgoWriter, "Jenkins master pod has been restarted\n")
|
||||||
|
}
|
||||||
|
|
||||||
func getJenkinsService(jenkins *v1alpha2.Jenkins, serviceKind string) *corev1.Service {
|
func getJenkinsService(jenkins *v1alpha2.Jenkins, serviceKind string) *corev1.Service {
|
||||||
service := &corev1.Service{}
|
service := &corev1.Service{}
|
||||||
|
|
|
||||||
|
|
@ -1,70 +1,20 @@
|
||||||
package e2e
|
package e2e
|
||||||
|
|
||||||
// TODO
|
|
||||||
/*
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"testing"
|
"time"
|
||||||
|
|
||||||
"github.com/jenkinsci/kubernetes-operator/pkg/apis/jenkins/v1alpha2"
|
"github.com/jenkinsci/kubernetes-operator/api/v1alpha2"
|
||||||
jenkinsclient "github.com/jenkinsci/kubernetes-operator/pkg/client"
|
jenkinsclient "github.com/jenkinsci/kubernetes-operator/pkg/client"
|
||||||
|
|
||||||
framework "github.com/operator-framework/operator-sdk/pkg/test"
|
. "github.com/onsi/ginkgo"
|
||||||
"github.com/stretchr/testify/require"
|
. "github.com/onsi/gomega"
|
||||||
corev1 "k8s.io/api/core/v1"
|
corev1 "k8s.io/api/core/v1"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apimachinery/pkg/types"
|
"k8s.io/apimachinery/pkg/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestJenkinsMasterPodRestart(t *testing.T) {
|
func configureAuthorizationToUnSecure(namespace, configMapName string) {
|
||||||
t.Parallel()
|
|
||||||
namespace, ctx := setupTest(t)
|
|
||||||
|
|
||||||
defer showLogsAndCleanup(t, ctx)
|
|
||||||
|
|
||||||
jenkins := createJenkinsCR(t, "e2e", namespace, nil, v1alpha2.GroovyScripts{}, v1alpha2.ConfigurationAsCode{}, "")
|
|
||||||
waitForJenkinsBaseConfigurationToComplete(t, jenkins)
|
|
||||||
restartJenkinsMasterPod(t, jenkins)
|
|
||||||
waitForRecreateJenkinsMasterPod(t, jenkins)
|
|
||||||
checkBaseConfigurationCompleteTimeIsNotSet(t, jenkins)
|
|
||||||
waitForJenkinsBaseConfigurationToComplete(t, jenkins)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestSafeRestart(t *testing.T) {
|
|
||||||
if skipTestSafeRestart {
|
|
||||||
t.Skip()
|
|
||||||
}
|
|
||||||
t.Parallel()
|
|
||||||
namespace, ctx := setupTest(t)
|
|
||||||
// Deletes test namespace
|
|
||||||
defer ctx.Cleanup()
|
|
||||||
|
|
||||||
jenkinsCRName := "e2e"
|
|
||||||
configureAuthorizationToUnSecure(t, namespace, userConfigurationConfigMapName)
|
|
||||||
groovyScriptsConfig := v1alpha2.GroovyScripts{
|
|
||||||
Customization: v1alpha2.Customization{
|
|
||||||
Configurations: []v1alpha2.ConfigMapRef{
|
|
||||||
{
|
|
||||||
Name: userConfigurationConfigMapName,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
jenkins := createJenkinsCR(t, jenkinsCRName, namespace, nil, groovyScriptsConfig, v1alpha2.ConfigurationAsCode{}, "")
|
|
||||||
waitForJenkinsBaseConfigurationToComplete(t, jenkins)
|
|
||||||
waitForJenkinsUserConfigurationToComplete(t, jenkins)
|
|
||||||
jenkinsClient, cleanUpFunc := verifyJenkinsAPIConnection(t, jenkins, namespace)
|
|
||||||
defer cleanUpFunc()
|
|
||||||
checkIfAuthorizationStrategyUnsecuredIsSet(t, jenkinsClient)
|
|
||||||
|
|
||||||
err := jenkinsClient.SafeRestart()
|
|
||||||
require.NoError(t, err)
|
|
||||||
waitForJenkinsSafeRestart(t, jenkinsClient)
|
|
||||||
|
|
||||||
checkIfAuthorizationStrategyUnsecuredIsSet(t, jenkinsClient)
|
|
||||||
}
|
|
||||||
|
|
||||||
func configureAuthorizationToUnSecure(t *testing.T, namespace, configMapName string) {
|
|
||||||
limitRange := &corev1.ConfigMap{
|
limitRange := &corev1.ConfigMap{
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
Name: configMapName,
|
Name: configMapName,
|
||||||
|
|
@ -83,11 +33,12 @@ jenkins.save()
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
err := framework.Global.Client.Create(context.TODO(), limitRange, nil)
|
Expect(k8sClient.Create(context.TODO(), limitRange)).Should(Succeed())
|
||||||
require.NoError(t, err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func checkIfAuthorizationStrategyUnsecuredIsSet(t *testing.T, jenkinsClient jenkinsclient.Jenkins) {
|
func checkIfAuthorizationStrategyUnsecuredIsSet(jenkinsClient jenkinsclient.Jenkins) {
|
||||||
|
By("checking if Authorization Strategy Unsecured is set")
|
||||||
|
|
||||||
logs, err := jenkinsClient.ExecuteScript(`
|
logs, err := jenkinsClient.ExecuteScript(`
|
||||||
import hudson.security.*
|
import hudson.security.*
|
||||||
|
|
||||||
|
|
@ -97,18 +48,18 @@ func checkIfAuthorizationStrategyUnsecuredIsSet(t *testing.T, jenkinsClient jenk
|
||||||
throw new Exception('AuthorizationStrategy.Unsecured is not set')
|
throw new Exception('AuthorizationStrategy.Unsecured is not set')
|
||||||
}
|
}
|
||||||
`)
|
`)
|
||||||
require.NoError(t, err, logs)
|
Expect(err).NotTo(HaveOccurred(), logs)
|
||||||
}
|
}
|
||||||
|
|
||||||
func checkBaseConfigurationCompleteTimeIsNotSet(t *testing.T, jenkins *v1alpha2.Jenkins) {
|
func checkBaseConfigurationCompleteTimeIsNotSet(jenkins *v1alpha2.Jenkins) {
|
||||||
jenkinsStatus := &v1alpha2.Jenkins{}
|
By("checking that Base Configuration's complete time is not set")
|
||||||
namespaceName := types.NamespacedName{Namespace: jenkins.Namespace, Name: jenkins.Name}
|
|
||||||
err := framework.Global.Client.Get(context.TODO(), namespaceName, jenkinsStatus)
|
Eventually(func() (bool, error) {
|
||||||
|
actualJenkins := &v1alpha2.Jenkins{}
|
||||||
|
err := k8sClient.Get(context.TODO(), types.NamespacedName{Name: jenkins.Name, Namespace: jenkins.Namespace}, actualJenkins)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
return false, err
|
||||||
}
|
|
||||||
if jenkinsStatus.Status.BaseConfigurationCompletedTime != nil {
|
|
||||||
t.Fatalf("Status.BaseConfigurationCompletedTime is set after pod restart, status %+v", jenkinsStatus.Status)
|
|
||||||
}
|
}
|
||||||
|
return actualJenkins.Status.BaseConfigurationCompletedTime == nil, nil
|
||||||
|
}, time.Duration(110)*retryInterval, time.Second).Should(BeTrue())
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
|
||||||
|
|
@ -1,21 +1,17 @@
|
||||||
package e2e
|
package e2e
|
||||||
|
|
||||||
// TODO
|
|
||||||
/*
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"testing"
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/jenkinsci/kubernetes-operator/internal/try"
|
"github.com/jenkinsci/kubernetes-operator/api/v1alpha2"
|
||||||
"github.com/jenkinsci/kubernetes-operator/pkg/apis/jenkins/v1alpha2"
|
|
||||||
"github.com/jenkinsci/kubernetes-operator/pkg/client"
|
"github.com/jenkinsci/kubernetes-operator/pkg/client"
|
||||||
"github.com/jenkinsci/kubernetes-operator/pkg/configuration/base/resources"
|
"github.com/jenkinsci/kubernetes-operator/pkg/configuration/base/resources"
|
||||||
"github.com/jenkinsci/kubernetes-operator/pkg/constants"
|
"github.com/jenkinsci/kubernetes-operator/pkg/constants"
|
||||||
|
|
||||||
framework "github.com/operator-framework/operator-sdk/pkg/test"
|
. "github.com/onsi/ginkgo"
|
||||||
"github.com/stretchr/testify/assert"
|
. "github.com/onsi/gomega"
|
||||||
"github.com/stretchr/testify/require"
|
|
||||||
corev1 "k8s.io/api/core/v1"
|
corev1 "k8s.io/api/core/v1"
|
||||||
"k8s.io/apimachinery/pkg/api/resource"
|
"k8s.io/apimachinery/pkg/api/resource"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
|
|
@ -23,64 +19,33 @@ import (
|
||||||
|
|
||||||
const pvcName = "pvc-jenkins"
|
const pvcName = "pvc-jenkins"
|
||||||
|
|
||||||
func TestBackupAndRestore(t *testing.T) {
|
func waitForJobCreation(jenkinsClient client.Jenkins, jobID string) {
|
||||||
t.Parallel()
|
By("waiting for Jenkins job creation")
|
||||||
namespace, ctx := setupTest(t)
|
|
||||||
|
|
||||||
defer showLogsAndCleanup(t, ctx)
|
var err error
|
||||||
|
Eventually(func() (bool, error) {
|
||||||
jobID := "e2e-jenkins-operator"
|
|
||||||
createPVC(t, namespace)
|
|
||||||
jenkins := createJenkinsWithBackupAndRestoreConfigured(t, "e2e", namespace)
|
|
||||||
waitForJenkinsUserConfigurationToComplete(t, jenkins)
|
|
||||||
|
|
||||||
jenkinsClient, cleanUpFunc := verifyJenkinsAPIConnection(t, jenkins, namespace)
|
|
||||||
defer cleanUpFunc()
|
|
||||||
waitForJob(t, jenkinsClient, jobID)
|
|
||||||
job, err := jenkinsClient.GetJob(jobID)
|
|
||||||
require.NoError(t, err, job)
|
|
||||||
i, err := job.InvokeSimple(map[string]string{})
|
|
||||||
require.NoError(t, err, i)
|
|
||||||
// FIXME: waitForJobToFinish use
|
|
||||||
time.Sleep(60 * time.Second) // wait for the build to complete
|
|
||||||
|
|
||||||
jenkins = getJenkins(t, jenkins.Namespace, jenkins.Name)
|
|
||||||
lastDoneBackup := jenkins.Status.LastBackup
|
|
||||||
restartJenkinsMasterPod(t, jenkins)
|
|
||||||
waitForRecreateJenkinsMasterPod(t, jenkins)
|
|
||||||
waitForJenkinsUserConfigurationToComplete(t, jenkins)
|
|
||||||
jenkins = getJenkins(t, jenkins.Namespace, jenkins.Name)
|
|
||||||
assert.Equal(t, lastDoneBackup, jenkins.Status.RestoredBackup)
|
|
||||||
jenkinsClient2, cleanUpFunc2 := verifyJenkinsAPIConnection(t, jenkins, namespace)
|
|
||||||
defer cleanUpFunc2()
|
|
||||||
waitForJob(t, jenkinsClient2, jobID)
|
|
||||||
verifyJobBuildsAfterRestoreBackup(t, jenkinsClient2, jobID)
|
|
||||||
|
|
||||||
jenkins = getJenkins(t, jenkins.Namespace, jenkins.Name)
|
|
||||||
lastDoneBackup = jenkins.Status.LastBackup
|
|
||||||
resetJenkinsStatus(t, jenkins)
|
|
||||||
waitForJenkinsUserConfigurationToComplete(t, jenkins)
|
|
||||||
jenkins = getJenkins(t, jenkins.Namespace, jenkins.Name)
|
|
||||||
assert.Equal(t, lastDoneBackup, jenkins.Status.RestoredBackup)
|
|
||||||
}
|
|
||||||
|
|
||||||
func waitForJob(t *testing.T, jenkinsClient client.Jenkins, jobID string) {
|
|
||||||
err := try.Until(func() (end bool, err error) {
|
|
||||||
_, err = jenkinsClient.GetJob(jobID)
|
_, err = jenkinsClient.GetJob(jobID)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
return err == nil, err
|
return err == nil, err
|
||||||
}, time.Second*2, time.Minute*3)
|
}, time.Minute*3, time.Second*2).Should(BeTrue())
|
||||||
require.NoErrorf(t, err, "Jenkins job '%s' not created by seed job", jobID)
|
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
}
|
}
|
||||||
|
|
||||||
func verifyJobBuildsAfterRestoreBackup(t *testing.T, jenkinsClient client.Jenkins, jobID string) {
|
func verifyJobBuildsAfterRestoreBackup(jenkinsClient client.Jenkins, jobID string) {
|
||||||
|
By("checking if job builds after restoring backup")
|
||||||
|
|
||||||
job, err := jenkinsClient.GetJob(jobID)
|
job, err := jenkinsClient.GetJob(jobID)
|
||||||
require.NoError(t, err)
|
Expect(err).NotTo(HaveOccurred())
|
||||||
build, err := job.GetLastBuild()
|
build, err := job.GetLastBuild()
|
||||||
require.NoError(t, err)
|
Expect(err).NotTo(HaveOccurred())
|
||||||
assert.Equal(t, int64(1), build.GetBuildNumber())
|
|
||||||
|
Expect(build.GetBuildNumber()).To(Equal(int64(1)))
|
||||||
}
|
}
|
||||||
|
|
||||||
func createPVC(t *testing.T, namespace string) {
|
func createPVC(namespace string) {
|
||||||
pvc := &corev1.PersistentVolumeClaim{
|
pvc := &corev1.PersistentVolumeClaim{
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
Name: pvcName,
|
Name: pvcName,
|
||||||
|
|
@ -96,11 +61,10 @@ func createPVC(t *testing.T, namespace string) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
err := framework.Global.Client.Create(context.TODO(), pvc, nil)
|
Expect(k8sClient.Create(context.TODO(), pvc)).Should(Succeed())
|
||||||
require.NoError(t, err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func createJenkinsWithBackupAndRestoreConfigured(t *testing.T, name, namespace string) *v1alpha2.Jenkins {
|
func createJenkinsWithBackupAndRestoreConfigured(name, namespace string) *v1alpha2.Jenkins {
|
||||||
containerName := "backup"
|
containerName := "backup"
|
||||||
jenkins := &v1alpha2.Jenkins{
|
jenkins := &v1alpha2.Jenkins{
|
||||||
TypeMeta: v1alpha2.JenkinsTypeMeta(),
|
TypeMeta: v1alpha2.JenkinsTypeMeta(),
|
||||||
|
|
@ -130,6 +94,16 @@ func createJenkinsWithBackupAndRestoreConfigured(t *testing.T, name, namespace s
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
GroovyScripts: v1alpha2.GroovyScripts{
|
||||||
|
Customization: v1alpha2.Customization{
|
||||||
|
Configurations: []v1alpha2.ConfigMapRef{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
ConfigurationAsCode: v1alpha2.ConfigurationAsCode{
|
||||||
|
Customization: v1alpha2.Customization{
|
||||||
|
Configurations: []v1alpha2.ConfigMapRef{},
|
||||||
|
},
|
||||||
|
},
|
||||||
Master: v1alpha2.JenkinsMaster{
|
Master: v1alpha2.JenkinsMaster{
|
||||||
Containers: []v1alpha2.Container{
|
Containers: []v1alpha2.Container{
|
||||||
{
|
{
|
||||||
|
|
@ -201,19 +175,20 @@ func createJenkinsWithBackupAndRestoreConfigured(t *testing.T, name, namespace s
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
updateJenkinsCR(t, jenkins)
|
|
||||||
|
|
||||||
t.Logf("Jenkins CR %+v", *jenkins)
|
updateJenkinsCR(jenkins)
|
||||||
err := framework.Global.Client.Create(context.TODO(), jenkins, nil)
|
|
||||||
require.NoError(t, err)
|
_, _ = fmt.Fprintf(GinkgoWriter, "Jenkins CR %+v\n", *jenkins)
|
||||||
|
|
||||||
|
Expect(k8sClient.Create(context.TODO(), jenkins)).Should(Succeed())
|
||||||
|
|
||||||
return jenkins
|
return jenkins
|
||||||
}
|
}
|
||||||
|
|
||||||
func resetJenkinsStatus(t *testing.T, jenkins *v1alpha2.Jenkins) {
|
func resetJenkinsStatus(jenkins *v1alpha2.Jenkins) {
|
||||||
jenkins = getJenkins(t, jenkins.Namespace, jenkins.Name)
|
By("resetting Jenkins status")
|
||||||
|
|
||||||
|
jenkins = getJenkins(jenkins.Namespace, jenkins.Name)
|
||||||
jenkins.Status = v1alpha2.JenkinsStatus{}
|
jenkins.Status = v1alpha2.JenkinsStatus{}
|
||||||
err := framework.Global.Client.Update(context.TODO(), jenkins)
|
Expect(k8sClient.Status().Update(context.TODO(), jenkins)).Should(Succeed())
|
||||||
require.NoError(t, err)
|
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ import (
|
||||||
"github.com/jenkinsci/kubernetes-operator/pkg/configuration/user/seedjobs"
|
"github.com/jenkinsci/kubernetes-operator/pkg/configuration/user/seedjobs"
|
||||||
"github.com/jenkinsci/kubernetes-operator/pkg/constants"
|
"github.com/jenkinsci/kubernetes-operator/pkg/constants"
|
||||||
|
|
||||||
|
"github.com/bndr/gojenkins"
|
||||||
. "github.com/onsi/ginkgo"
|
. "github.com/onsi/ginkgo"
|
||||||
. "github.com/onsi/gomega"
|
. "github.com/onsi/gomega"
|
||||||
corev1 "k8s.io/api/core/v1"
|
corev1 "k8s.io/api/core/v1"
|
||||||
|
|
@ -27,12 +28,13 @@ type seedJobConfig struct {
|
||||||
PrivateKey string `json:"privateKey,omitempty"`
|
PrivateKey string `json:"privateKey,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
/*type seedJobsConfig struct {
|
/*
|
||||||
|
type seedJobsConfig struct {
|
||||||
SeedJobs []seedJobConfig `json:"seedJobs,omitempty"`
|
SeedJobs []seedJobConfig `json:"seedJobs,omitempty"`
|
||||||
}*/
|
}
|
||||||
|
|
||||||
// FIXME
|
// FIXME
|
||||||
/*func TestSeedJobs(t *testing.T) {
|
func TestSeedJobs(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
if seedJobConfigurationFile == nil || len(*seedJobConfigurationFile) == 0 {
|
if seedJobConfigurationFile == nil || len(*seedJobConfigurationFile) == 0 {
|
||||||
t.Skipf("Skipping test because flag '%+v' is not set", seedJobConfigurationFile)
|
t.Skipf("Skipping test because flag '%+v' is not set", seedJobConfigurationFile)
|
||||||
|
|
@ -63,22 +65,22 @@ type seedJobConfig struct {
|
||||||
verifyJenkinsSeedJobs(t, jenkinsClient, seedJobsConfig.SeedJobs)
|
verifyJenkinsSeedJobs(t, jenkinsClient, seedJobsConfig.SeedJobs)
|
||||||
}
|
}
|
||||||
|
|
||||||
func loadSeedJobsConfig(t *testing.T) seedJobsConfig {
|
func loadSeedJobsConfig() seedJobsConfig {
|
||||||
|
//seedJobConfigurationFile = flag.String(seedJobConfigurationParameterName, "", "path to seed job config")
|
||||||
jsonFile, err := os.Open(*seedJobConfigurationFile)
|
jsonFile, err := os.Open(*seedJobConfigurationFile)
|
||||||
assert.NoError(t, err)
|
Expect(err).NotTo(HaveOccurred())
|
||||||
defer func() { _ = jsonFile.Close() }()
|
defer func() { _ = jsonFile.Close() }()
|
||||||
|
|
||||||
byteValue, err := ioutil.ReadAll(jsonFile)
|
byteValue, err := ioutil.ReadAll(jsonFile)
|
||||||
assert.NoError(t, err)
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
|
||||||
var result seedJobsConfig
|
var result seedJobsConfig
|
||||||
err = json.Unmarshal(byteValue, &result)
|
err = json.Unmarshal(byteValue, &result)
|
||||||
assert.NoError(t, err)
|
Expect(err).NotTo(HaveOccurred())
|
||||||
assert.NotEmpty(t, result.SeedJobs)
|
Expect(result.SeedJobs).NotTo(BeEmpty())
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
func createKubernetesCredentialsProviderSecret(namespace string, config seedJobConfig) {
|
func createKubernetesCredentialsProviderSecret(namespace string, config seedJobConfig) {
|
||||||
if config.JenkinsCredentialType == v1alpha2.NoJenkinsCredentialCredentialType {
|
if config.JenkinsCredentialType == v1alpha2.NoJenkinsCredentialCredentialType {
|
||||||
return
|
return
|
||||||
|
|
@ -112,7 +114,7 @@ func verifyJenkinsSeedJobs(jenkinsClient jenkinsclient.Jenkins, seedJobs []seedJ
|
||||||
for _, seedJob := range seedJobs {
|
for _, seedJob := range seedJobs {
|
||||||
if seedJob.JenkinsCredentialType == v1alpha2.BasicSSHCredentialType || seedJob.JenkinsCredentialType == v1alpha2.UsernamePasswordCredentialType {
|
if seedJob.JenkinsCredentialType == v1alpha2.BasicSSHCredentialType || seedJob.JenkinsCredentialType == v1alpha2.UsernamePasswordCredentialType {
|
||||||
err = verifyIfJenkinsCredentialExists(jenkinsClient, seedJob.CredentialID)
|
err = verifyIfJenkinsCredentialExists(jenkinsClient, seedJob.CredentialID)
|
||||||
Expect(err).NotTo(HaveOccurred(), fmt.Sprintf("Jenkins credential '%s' not created for seed job ID '%s'", seedJob.CredentialID, seedJob.ID))
|
Expect(err).NotTo(HaveOccurred(), fmt.Sprintf("Jenkins credential '%s' not created for seed job ID '%s'\n", seedJob.CredentialID, seedJob.ID))
|
||||||
}
|
}
|
||||||
|
|
||||||
verifySeedJobProperties(jenkinsClient, seedJob)
|
verifySeedJobProperties(jenkinsClient, seedJob)
|
||||||
|
|
@ -122,7 +124,7 @@ func verifyJenkinsSeedJobs(jenkinsClient jenkinsclient.Jenkins, seedJobs []seedJ
|
||||||
_, err = jenkinsClient.GetJob(requireJobName)
|
_, err = jenkinsClient.GetJob(requireJobName)
|
||||||
return err == nil, err
|
return err == nil, err
|
||||||
}, time.Second*2, time.Minute*2)
|
}, time.Second*2, time.Minute*2)
|
||||||
Expect(err).NotTo(HaveOccurred(), fmt.Sprintf("Jenkins job '%s' not created by seed job ID '%s'", requireJobName, seedJob.ID))
|
Expect(err).NotTo(HaveOccurred(), fmt.Sprintf("Jenkins job '%s' not created by seed job ID '%s'\n", requireJobName, seedJob.ID))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -292,3 +294,36 @@ for (BuildStep step : jobRef.getBuildersList()) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`))
|
`))
|
||||||
|
|
||||||
|
func verifyJobCanBeRun(jenkinsClient jenkinsclient.Jenkins, jobID string) {
|
||||||
|
By("retrieving created Jenkins job")
|
||||||
|
job, err := jenkinsClient.GetJob(jobID)
|
||||||
|
Expect(err).To(BeNil())
|
||||||
|
|
||||||
|
By("running Jenkins job")
|
||||||
|
_, err = job.InvokeSimple(map[string]string{})
|
||||||
|
Expect(err).To(BeNil())
|
||||||
|
|
||||||
|
// FIXME: waitForJobToFinish use
|
||||||
|
By("waiting for the job to finish")
|
||||||
|
time.Sleep(100 * time.Second) // wait for the build to complete
|
||||||
|
}
|
||||||
|
func verifyJobHasBeenRunCorrectly(jenkinsClient jenkinsclient.Jenkins, jobID string) {
|
||||||
|
By("retrieving finished job")
|
||||||
|
|
||||||
|
var (
|
||||||
|
err error
|
||||||
|
job *gojenkins.Job
|
||||||
|
build *gojenkins.Build
|
||||||
|
)
|
||||||
|
|
||||||
|
Eventually(func() (bool, error) {
|
||||||
|
job, err = jenkinsClient.GetJob(jobID)
|
||||||
|
Expect(err).To(BeNil())
|
||||||
|
build, err = job.GetLastBuild()
|
||||||
|
Expect(err).To(BeNil())
|
||||||
|
|
||||||
|
By("evaluating correctness of the outcome")
|
||||||
|
return build.IsGood(), err
|
||||||
|
}, time.Duration(110)*retryInterval, retryInterval).Should(BeTrue())
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,13 +3,20 @@ package e2e
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"net/http"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/jenkinsci/kubernetes-operator/api/v1alpha2"
|
"github.com/jenkinsci/kubernetes-operator/api/v1alpha2"
|
||||||
|
jenkinsclient "github.com/jenkinsci/kubernetes-operator/pkg/client"
|
||||||
|
"github.com/jenkinsci/kubernetes-operator/pkg/configuration/base/resources"
|
||||||
|
|
||||||
. "github.com/onsi/ginkgo"
|
. "github.com/onsi/ginkgo"
|
||||||
. "github.com/onsi/gomega"
|
. "github.com/onsi/gomega"
|
||||||
|
corev1 "k8s.io/api/core/v1"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
|
"k8s.io/apimachinery/pkg/labels"
|
||||||
"k8s.io/apimachinery/pkg/types"
|
"k8s.io/apimachinery/pkg/types"
|
||||||
|
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|
@ -36,26 +43,28 @@ func waitForJenkinsBaseConfigurationToComplete(jenkins *v1alpha2.Jenkins) {
|
||||||
Expect(k8sClient.Get(context.TODO(), namespacedName, jenkins)).Should(Succeed())
|
Expect(k8sClient.Get(context.TODO(), namespacedName, jenkins)).Should(Succeed())
|
||||||
}
|
}
|
||||||
|
|
||||||
/*func waitForRecreateJenkinsMasterPod(t *testing.T, jenkins *v1alpha2.Jenkins) {
|
func waitForRecreateJenkinsMasterPod(jenkins *v1alpha2.Jenkins) {
|
||||||
err := wait.Poll(retryInterval, 30*retryInterval, func() (bool, error) {
|
By("waiting for Jenkins Master Pod recreation")
|
||||||
lo := metav1.ListOptions{
|
|
||||||
LabelSelector: labels.SelectorFromSet(resources.GetJenkinsMasterPodLabels(*jenkins)).String(),
|
Eventually(func() (bool, error) {
|
||||||
|
lo := &client.ListOptions{
|
||||||
|
LabelSelector: labels.SelectorFromSet(resources.GetJenkinsMasterPodLabels(*jenkins)),
|
||||||
|
Namespace: jenkins.Namespace,
|
||||||
}
|
}
|
||||||
podList, err := framework.Global.KubeClient.CoreV1().Pods(jenkins.ObjectMeta.Namespace).List(lo)
|
pods := &corev1.PodList{}
|
||||||
|
err := k8sClient.List(context.TODO(), pods, lo)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
if len(podList.Items) != 1 {
|
if len(pods.Items) != 1 {
|
||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return podList.Items[0].DeletionTimestamp == nil, nil
|
return pods.Items[0].DeletionTimestamp == nil, nil
|
||||||
})
|
}, 30*retryInterval, retryInterval).Should(BeTrue())
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
_, _ = fmt.Fprintf(GinkgoWriter, "Jenkins pod has been recreated\n")
|
||||||
}
|
}
|
||||||
_, _ = fmt.Fprintf(GinkgoWriter,"Jenkins pod has been recreated")
|
|
||||||
}*/
|
|
||||||
|
|
||||||
func waitForJenkinsUserConfigurationToComplete(jenkins *v1alpha2.Jenkins) {
|
func waitForJenkinsUserConfigurationToComplete(jenkins *v1alpha2.Jenkins) {
|
||||||
By("waiting for Jenkins user configuration phase to complete")
|
By("waiting for Jenkins user configuration phase to complete")
|
||||||
|
|
@ -66,22 +75,23 @@ func waitForJenkinsUserConfigurationToComplete(jenkins *v1alpha2.Jenkins) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return actualJenkins.Status.UserConfigurationCompletedTime, nil
|
return actualJenkins.Status.UserConfigurationCompletedTime, nil
|
||||||
}, time.Duration(110)*retryInterval, retryInterval).Should(Not(BeNil()))
|
}, time.Duration(110)*retryInterval, retryInterval).Should(Not(BeNil()))
|
||||||
_, _ = fmt.Fprintf(GinkgoWriter, "Jenkins instance is up and ready\n")
|
_, _ = fmt.Fprintf(GinkgoWriter, "Jenkins instance is up and ready\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
/*func waitForJenkinsSafeRestart(t *testing.T, jenkinsClient jenkinsclient.Jenkins) {
|
func waitForJenkinsSafeRestart(jenkinsClient jenkinsclient.Jenkins) {
|
||||||
err := try.Until(func() (end bool, err error) {
|
By("waiting for Jenkins safe restart")
|
||||||
|
|
||||||
|
Eventually(func() (bool, error) {
|
||||||
status, err := jenkinsClient.Poll()
|
status, err := jenkinsClient.Poll()
|
||||||
|
_, _ = fmt.Fprintf(GinkgoWriter, "Safe restart status: %+v, err: %s\n", status, err)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
if status != http.StatusOK {
|
if status != http.StatusOK {
|
||||||
return false, errors.Wrap(err, "couldn't poll data from Jenkins API")
|
return false, err
|
||||||
}
|
}
|
||||||
return true, nil
|
return true, nil
|
||||||
}, time.Second, time.Second*70)
|
}, time.Second*200, time.Second*5).Should(BeTrue())
|
||||||
require.NoError(t, err)
|
}
|
||||||
}*/
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue