Fix calculating hash for user/base configuration
This commit is contained in:
parent
f8190d61ce
commit
516418f97f
2
Makefile
2
Makefile
|
|
@ -328,7 +328,7 @@ deepcopy-gen: ## Generate deepcopy golang code
|
|||
start-minikube: ## Start minikube
|
||||
@echo "+ $@"
|
||||
@minikube status && exit 0 || \
|
||||
minikube start --kubernetes-version $(MINIKUBE_KUBERNETES_VERSION) --vm-driver=$(MINIKUBE_DRIVER) --memory 2048
|
||||
minikube start --kubernetes-version $(MINIKUBE_KUBERNETES_VERSION) --vm-driver=$(MINIKUBE_DRIVER) --memory 4096
|
||||
|
||||
.PHONY: bump-version
|
||||
BUMP := patch
|
||||
|
|
|
|||
|
|
@ -2,11 +2,8 @@ package base
|
|||
|
||||
import (
|
||||
"context"
|
||||
"crypto/sha256"
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"sort"
|
||||
"time"
|
||||
|
||||
virtuslabv1alpha1 "github.com/VirtusLab/jenkins-operator/pkg/apis/virtuslab/v1alpha1"
|
||||
|
|
@ -35,7 +32,7 @@ const (
|
|||
|
||||
// ReconcileJenkinsBaseConfiguration defines values required for Jenkins base configuration
|
||||
type ReconcileJenkinsBaseConfiguration struct {
|
||||
client client.Client
|
||||
k8sClient client.Client
|
||||
scheme *runtime.Scheme
|
||||
logger logr.Logger
|
||||
jenkins *virtuslabv1alpha1.Jenkins
|
||||
|
|
@ -46,7 +43,7 @@ type ReconcileJenkinsBaseConfiguration struct {
|
|||
func New(client client.Client, scheme *runtime.Scheme, logger logr.Logger,
|
||||
jenkins *virtuslabv1alpha1.Jenkins, local, minikube bool) *ReconcileJenkinsBaseConfiguration {
|
||||
return &ReconcileJenkinsBaseConfiguration{
|
||||
client: client,
|
||||
k8sClient: client,
|
||||
scheme: scheme,
|
||||
logger: logger,
|
||||
jenkins: jenkins,
|
||||
|
|
@ -128,7 +125,7 @@ func (r *ReconcileJenkinsBaseConfiguration) Reconcile() (*reconcile.Result, jenk
|
|||
if err != nil {
|
||||
return &reconcile.Result{}, nil, err
|
||||
}
|
||||
if err := r.client.Delete(context.TODO(), currentJenkinsMasterPod); err != nil {
|
||||
if err := r.k8sClient.Delete(context.TODO(), currentJenkinsMasterPod); err != nil {
|
||||
return &reconcile.Result{}, nil, err
|
||||
}
|
||||
}
|
||||
|
|
@ -180,7 +177,7 @@ func isPluginInstalled(plugins *gojenkins.Plugins, requiredPlugin plugin.Plugin)
|
|||
|
||||
func (r *ReconcileJenkinsBaseConfiguration) createOperatorCredentialsSecret(meta metav1.ObjectMeta) error {
|
||||
found := &corev1.Secret{}
|
||||
err := r.client.Get(context.TODO(), types.NamespacedName{Name: resources.GetOperatorCredentialsSecretName(r.jenkins), Namespace: r.jenkins.ObjectMeta.Namespace}, found)
|
||||
err := r.k8sClient.Get(context.TODO(), types.NamespacedName{Name: resources.GetOperatorCredentialsSecretName(r.jenkins), Namespace: r.jenkins.ObjectMeta.Namespace}, found)
|
||||
|
||||
if err != nil && apierrors.IsNotFound(err) {
|
||||
return r.createResource(resources.NewOperatorCredentialsSecret(meta, r.jenkins))
|
||||
|
|
@ -222,9 +219,9 @@ func (r *ReconcileJenkinsBaseConfiguration) createBaseConfigurationConfigMap(met
|
|||
|
||||
func (r *ReconcileJenkinsBaseConfiguration) createUserConfigurationConfigMap(meta metav1.ObjectMeta) error {
|
||||
currentConfigMap := &corev1.ConfigMap{}
|
||||
err := r.client.Get(context.TODO(), types.NamespacedName{Name: resources.GetUserConfigurationConfigMapName(r.jenkins), Namespace: r.jenkins.Namespace}, currentConfigMap)
|
||||
err := r.k8sClient.Get(context.TODO(), types.NamespacedName{Name: resources.GetUserConfigurationConfigMapName(r.jenkins), Namespace: r.jenkins.Namespace}, currentConfigMap)
|
||||
if err != nil && errors.IsNotFound(err) {
|
||||
return r.client.Create(context.TODO(), resources.NewUserConfigurationConfigMap(meta, r.jenkins))
|
||||
return r.k8sClient.Create(context.TODO(), resources.NewUserConfigurationConfigMap(meta, r.jenkins))
|
||||
} else if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
@ -267,7 +264,7 @@ func (r *ReconcileJenkinsBaseConfiguration) createService(meta metav1.ObjectMeta
|
|||
func (r *ReconcileJenkinsBaseConfiguration) getJenkinsMasterPod(meta metav1.ObjectMeta) (*corev1.Pod, error) {
|
||||
jenkinsMasterPod := resources.NewJenkinsMasterPod(meta, r.jenkins)
|
||||
currentJenkinsMasterPod := &corev1.Pod{}
|
||||
err := r.client.Get(context.TODO(), types.NamespacedName{Name: jenkinsMasterPod.Name, Namespace: jenkinsMasterPod.Namespace}, currentJenkinsMasterPod)
|
||||
err := r.k8sClient.Get(context.TODO(), types.NamespacedName{Name: jenkinsMasterPod.Name, Namespace: jenkinsMasterPod.Namespace}, currentJenkinsMasterPod)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -324,7 +321,7 @@ func (r *ReconcileJenkinsBaseConfiguration) createJenkinsMasterPod(meta metav1.O
|
|||
|
||||
if currentJenkinsMasterPod != nil && recreatePod && currentJenkinsMasterPod.ObjectMeta.DeletionTimestamp == nil {
|
||||
r.logger.Info(fmt.Sprintf("Terminating Jenkins Master Pod %s/%s", currentJenkinsMasterPod.Namespace, currentJenkinsMasterPod.Name))
|
||||
if err := r.client.Delete(context.TODO(), currentJenkinsMasterPod); err != nil {
|
||||
if err := r.k8sClient.Delete(context.TODO(), currentJenkinsMasterPod); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &reconcile.Result{Requeue: true}, nil
|
||||
|
|
@ -368,7 +365,7 @@ func (r *ReconcileJenkinsBaseConfiguration) getJenkinsClient(meta metav1.ObjectM
|
|||
r.logger.V(log.VDebug).Info(fmt.Sprintf("Jenkins API URL %s", jenkinsURL))
|
||||
|
||||
credentialsSecret := &corev1.Secret{}
|
||||
err = r.client.Get(context.TODO(), types.NamespacedName{Name: resources.GetOperatorCredentialsSecretName(r.jenkins), Namespace: r.jenkins.ObjectMeta.Namespace}, credentialsSecret)
|
||||
err = r.k8sClient.Get(context.TODO(), types.NamespacedName{Name: resources.GetOperatorCredentialsSecretName(r.jenkins), Namespace: r.jenkins.ObjectMeta.Namespace}, credentialsSecret)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -421,7 +418,7 @@ func (r *ReconcileJenkinsBaseConfiguration) getJenkinsClient(meta metav1.ObjectM
|
|||
}
|
||||
|
||||
func (r *ReconcileJenkinsBaseConfiguration) baseConfiguration(jenkinsClient jenkinsclient.Jenkins) (*reconcile.Result, error) {
|
||||
groovyClient := groovy.New(jenkinsClient, r.client, r.logger, fmt.Sprintf("%s-base-configuration", constants.OperatorName), resources.JenkinsBaseConfigurationVolumePath)
|
||||
groovyClient := groovy.New(jenkinsClient, r.k8sClient, r.logger, fmt.Sprintf("%s-base-configuration", constants.OperatorName), resources.JenkinsBaseConfigurationVolumePath)
|
||||
|
||||
err := groovyClient.ConfigureGroovyJob()
|
||||
if err != nil {
|
||||
|
|
@ -429,30 +426,16 @@ func (r *ReconcileJenkinsBaseConfiguration) baseConfiguration(jenkinsClient jenk
|
|||
}
|
||||
|
||||
configuration := &corev1.ConfigMap{}
|
||||
namespaceName := types.NamespacedName{Namespace: r.jenkins.Namespace, Name: resources.GetUserConfigurationConfigMapName(r.jenkins)}
|
||||
err = r.client.Get(context.TODO(), namespaceName, configuration)
|
||||
if err != nil {
|
||||
return &reconcile.Result{}, err
|
||||
}
|
||||
hash := sha256.New()
|
||||
|
||||
var keys []string
|
||||
for key := range configuration.Data {
|
||||
keys = append(keys, key)
|
||||
}
|
||||
sort.Strings(keys)
|
||||
for _, key := range keys {
|
||||
hash.Write([]byte(key))
|
||||
hash.Write([]byte(configuration.Data[key]))
|
||||
}
|
||||
|
||||
encodedHash := base64.URLEncoding.EncodeToString(hash.Sum(nil))
|
||||
|
||||
done, err := groovyClient.EnsureGroovyJob(encodedHash, r.jenkins)
|
||||
namespaceName := types.NamespacedName{Namespace: r.jenkins.Namespace, Name: resources.GetBaseConfigurationConfigMapName(r.jenkins)}
|
||||
err = r.k8sClient.Get(context.TODO(), namespaceName, configuration)
|
||||
if err != nil {
|
||||
return &reconcile.Result{}, err
|
||||
}
|
||||
|
||||
done, err := groovyClient.EnsureGroovyJob(configuration.Data, r.jenkins)
|
||||
if err != nil {
|
||||
return &reconcile.Result{}, err
|
||||
}
|
||||
if !done {
|
||||
return &reconcile.Result{Requeue: true, RequeueAfter: time.Second * 10}, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ func (r *ReconcileJenkinsBaseConfiguration) createResource(obj metav1.Object) er
|
|||
return err
|
||||
}
|
||||
|
||||
return r.client.Create(context.TODO(), runtimeObj)
|
||||
return r.k8sClient.Create(context.TODO(), runtimeObj)
|
||||
}
|
||||
|
||||
func (r *ReconcileJenkinsBaseConfiguration) updateResource(obj metav1.Object) error {
|
||||
|
|
@ -33,7 +33,7 @@ func (r *ReconcileJenkinsBaseConfiguration) updateResource(obj metav1.Object) er
|
|||
// set Jenkins instance as the owner and controller, don't check error(can be already set)
|
||||
_ = controllerutil.SetControllerReference(r.jenkins, obj, r.scheme)
|
||||
|
||||
return r.client.Update(context.TODO(), runtimeObj)
|
||||
return r.k8sClient.Update(context.TODO(), runtimeObj)
|
||||
}
|
||||
|
||||
func (r *ReconcileJenkinsBaseConfiguration) createOrUpdateResource(obj metav1.Object) error {
|
||||
|
|
@ -45,7 +45,7 @@ func (r *ReconcileJenkinsBaseConfiguration) createOrUpdateResource(obj metav1.Ob
|
|||
// set Jenkins instance as the owner and controller, don't check error(can be already set)
|
||||
_ = controllerutil.SetControllerReference(r.jenkins, obj, r.scheme)
|
||||
|
||||
err := r.client.Create(context.TODO(), runtimeObj)
|
||||
err := r.k8sClient.Create(context.TODO(), runtimeObj)
|
||||
if err != nil && errors.IsAlreadyExists(err) {
|
||||
return r.updateResource(obj)
|
||||
} else if err != nil && !errors.IsAlreadyExists(err) {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package user
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
|
|
@ -8,12 +9,13 @@ import (
|
|||
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/user/seedjobs"
|
||||
"github.com/VirtusLab/jenkins-operator/pkg/controller/jenkins/configuration/user/theme"
|
||||
"github.com/VirtusLab/jenkins-operator/pkg/controller/jenkins/constants"
|
||||
"github.com/VirtusLab/jenkins-operator/pkg/controller/jenkins/groovy"
|
||||
"github.com/VirtusLab/jenkins-operator/pkg/controller/jenkins/jobs"
|
||||
|
||||
"github.com/go-logr/logr"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
k8s "sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"sigs.k8s.io/controller-runtime/pkg/reconcile"
|
||||
)
|
||||
|
|
@ -78,7 +80,14 @@ func (r *ReconcileUserConfiguration) userConfiguration(jenkinsClient jenkinsclie
|
|||
return &reconcile.Result{}, err
|
||||
}
|
||||
|
||||
done, err := groovyClient.EnsureGroovyJob(theme.SetThemeGroovyScript, r.jenkins)
|
||||
configuration := &corev1.ConfigMap{}
|
||||
namespaceName := types.NamespacedName{Namespace: r.jenkins.Namespace, Name: resources.GetUserConfigurationConfigMapName(r.jenkins)}
|
||||
err = r.k8sClient.Get(context.TODO(), namespaceName, configuration)
|
||||
if err != nil {
|
||||
return &reconcile.Result{}, err
|
||||
}
|
||||
|
||||
done, err := groovyClient.EnsureGroovyJob(configuration.Data, r.jenkins)
|
||||
if err != nil {
|
||||
return &reconcile.Result{}, err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,25 +0,0 @@
|
|||
package theme
|
||||
|
||||
// SetThemeGroovyScript it's a groovy script which set custom jenkins theme
|
||||
// TODO move to base configuration
|
||||
var SetThemeGroovyScript = `
|
||||
import jenkins.*
|
||||
import jenkins.model.*
|
||||
import hudson.*
|
||||
import hudson.model.*
|
||||
import org.jenkinsci.plugins.simpletheme.ThemeElement
|
||||
import org.jenkinsci.plugins.simpletheme.CssTextThemeElement
|
||||
import org.jenkinsci.plugins.simpletheme.CssUrlThemeElement
|
||||
|
||||
Jenkins jenkins = Jenkins.getInstance()
|
||||
|
||||
def decorator = Jenkins.instance.getDescriptorByType(org.codefirst.SimpleThemeDecorator.class)
|
||||
|
||||
List<ThemeElement> configElements = new ArrayList<>();
|
||||
configElements.add(new CssTextThemeElement("DEFAULT"));
|
||||
configElements.add(new CssUrlThemeElement("https://cdn.rawgit.com/afonsof/jenkins-material-theme/gh-pages/dist/material-light-green.css"));
|
||||
decorator.setElements(configElements);
|
||||
decorator.save();
|
||||
|
||||
jenkins.save()
|
||||
`
|
||||
|
|
@ -1,7 +1,10 @@
|
|||
package groovy
|
||||
|
||||
import (
|
||||
"crypto/sha256"
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"sort"
|
||||
|
||||
virtuslabv1alpha1 "github.com/VirtusLab/jenkins-operator/pkg/apis/virtuslab/v1alpha1"
|
||||
jenkinsclient "github.com/VirtusLab/jenkins-operator/pkg/controller/jenkins/client"
|
||||
|
|
@ -41,17 +44,31 @@ func (g *Groovy) ConfigureGroovyJob() error {
|
|||
}
|
||||
|
||||
// EnsureGroovyJob executes groovy script and verifies jenkins job status according to reconciliation loop lifecycle
|
||||
// see https://wiki.jenkins.io/display/JENKINS/Jenkins+Script+Console
|
||||
func (g *Groovy) EnsureGroovyJob(hash string, jenkins *virtuslabv1alpha1.Jenkins) (bool, error) {
|
||||
func (g *Groovy) EnsureGroovyJob(secretOrConfigMapData map[string]string, jenkins *virtuslabv1alpha1.Jenkins) (bool, error) {
|
||||
jobsClient := jobs.New(g.jenkinsClient, g.k8sClient, g.logger)
|
||||
|
||||
done, err := jobsClient.EnsureBuildJob(g.jobName, hash, map[string]string{}, jenkins, true)
|
||||
done, err := jobsClient.EnsureBuildJob(g.jobName, g.calculateHash(secretOrConfigMapData), map[string]string{}, jenkins, true)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return done, nil
|
||||
}
|
||||
|
||||
func (g *Groovy) calculateHash(secretOrConfigMapData map[string]string) string {
|
||||
hash := sha256.New()
|
||||
|
||||
var keys []string
|
||||
for key := range secretOrConfigMapData {
|
||||
keys = append(keys, key)
|
||||
}
|
||||
sort.Strings(keys)
|
||||
for _, key := range keys {
|
||||
hash.Write([]byte(key))
|
||||
hash.Write([]byte(secretOrConfigMapData[key]))
|
||||
}
|
||||
return base64.URLEncoding.EncodeToString(hash.Sum(nil))
|
||||
}
|
||||
|
||||
const configurationJobXMLFmt = `<?xml version='1.1' encoding='UTF-8'?>
|
||||
<flow-definition plugin="workflow-job@2.25">
|
||||
<actions/>
|
||||
|
|
|
|||
Loading…
Reference in New Issue