#190 Allow set Jenkins API authorization strategy
This commit is contained in:
		
							parent
							
								
									6de21202e8
								
							
						
					
					
						commit
						8e1d66de0f
					
				|  | @ -61,6 +61,24 @@ type JenkinsSpec struct { | ||||||
| 	// ServiceAccount defines Jenkins master service account attributes
 | 	// ServiceAccount defines Jenkins master service account attributes
 | ||||||
| 	// +optional
 | 	// +optional
 | ||||||
| 	ServiceAccount ServiceAccount `json:"serviceAccount,omitempty"` | 	ServiceAccount ServiceAccount `json:"serviceAccount,omitempty"` | ||||||
|  | 
 | ||||||
|  | 	// JenkinsAPISettings defines configuration used by the operator to gain admin access to the Jenkins API
 | ||||||
|  | 	JenkinsAPISettings JenkinsAPISettings `json:"jenkinsAPISettings"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // AuthorizationStrategy defines authorization strategy of the operator for the Jenkins API
 | ||||||
|  | type AuthorizationStrategy string | ||||||
|  | 
 | ||||||
|  | const ( | ||||||
|  | 	// CreateUserAuthorizationStrategy operator sets HudsonPrivateSecurityRealm and FullControlOnceLoggedInAuthorizationStrategy than creates user using init.d groovy script
 | ||||||
|  | 	CreateUserAuthorizationStrategy AuthorizationStrategy = "createUser" | ||||||
|  | 	// ServiceAccountAuthorizationStrategy operator gets token associated with Jenkins service account and uses it as bearer token
 | ||||||
|  | 	ServiceAccountAuthorizationStrategy AuthorizationStrategy = "serviceAccount" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // JenkinsAPISettings defines configuration used by the operator to gain admin access to the Jenkins API
 | ||||||
|  | type JenkinsAPISettings struct { | ||||||
|  | 	AuthorizationStrategy AuthorizationStrategy `json:"authorizationStrategy"` | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // ServiceAccount defines Kubernetes service account attributes
 | // ServiceAccount defines Kubernetes service account attributes
 | ||||||
|  |  | ||||||
|  | @ -68,6 +68,23 @@ type JenkinsAPIConnectionSettings struct { | ||||||
| 	UseNodePort bool | 	UseNodePort bool | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | type setBearerToken struct { | ||||||
|  | 	rt    http.RoundTripper | ||||||
|  | 	token string | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (t *setBearerToken) transport() http.RoundTripper { | ||||||
|  | 	if t.rt != nil { | ||||||
|  | 		return t.rt | ||||||
|  | 	} | ||||||
|  | 	return http.DefaultTransport | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (t *setBearerToken) RoundTrip(r *http.Request) (*http.Response, error) { | ||||||
|  | 	r.Header.Set("Authorization", fmt.Sprintf("Bearer %s", t.token)) | ||||||
|  | 	return t.transport().RoundTrip(r) | ||||||
|  | } | ||||||
|  | 
 | ||||||
| // CreateOrUpdateJob creates or updates a job from config
 | // CreateOrUpdateJob creates or updates a job from config
 | ||||||
| func (jenkins *jenkins) CreateOrUpdateJob(config, jobName string) (job *gojenkins.Job, created bool, err error) { | func (jenkins *jenkins) CreateOrUpdateJob(config, jobName string) (job *gojenkins.Job, created bool, err error) { | ||||||
| 	// create or update
 | 	// create or update
 | ||||||
|  | @ -114,19 +131,37 @@ func (j JenkinsAPIConnectionSettings) Validate() error { | ||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // New creates Jenkins API client
 | // NewUserAndPasswordAuthorization creates Jenkins API client with user and password authorization
 | ||||||
| func New(url, user, passwordOrToken string) (Jenkins, error) { | func NewUserAndPasswordAuthorization(url, userName, passwordOrToken string) (Jenkins, error) { | ||||||
|  | 	return newClient(url, userName, passwordOrToken) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // NewBearerTokenAuthorization creates Jenkins API client with bearer token authorization
 | ||||||
|  | func NewBearerTokenAuthorization(url, token string) (Jenkins, error) { | ||||||
|  | 	return newClient(url, "", token) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func newClient(url, userName, passwordOrToken string) (Jenkins, error) { | ||||||
| 	if strings.HasSuffix(url, "/") { | 	if strings.HasSuffix(url, "/") { | ||||||
| 		url = url[:len(url)-1] | 		url = url[:len(url)-1] | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	jenkinsClient := &jenkins{} | 	jenkinsClient := &jenkins{} | ||||||
| 	jenkinsClient.Server = url | 	jenkinsClient.Server = url | ||||||
|  | 
 | ||||||
|  | 	var basicAuth *gojenkins.BasicAuth | ||||||
|  | 	httpClient := http.DefaultClient | ||||||
|  | 	if len(userName) > 0 && len(passwordOrToken) > 0 { | ||||||
|  | 		basicAuth = &gojenkins.BasicAuth{Username: userName, Password: passwordOrToken} | ||||||
|  | 	} else { | ||||||
|  | 		httpClient.Transport = &setBearerToken{token: passwordOrToken, rt: httpClient.Transport} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	jenkinsClient.Requester = &gojenkins.Requester{ | 	jenkinsClient.Requester = &gojenkins.Requester{ | ||||||
| 		Base:      url, | 		Base:      url, | ||||||
| 		SslVerify: true, | 		SslVerify: true, | ||||||
| 		Client:    http.DefaultClient, | 		Client:    httpClient, | ||||||
| 		BasicAuth: &gojenkins.BasicAuth{Username: user, Password: passwordOrToken}, | 		BasicAuth: basicAuth, | ||||||
| 	} | 	} | ||||||
| 	if _, err := jenkinsClient.Init(); err != nil { | 	if _, err := jenkinsClient.Init(); err != nil { | ||||||
| 		return nil, errors.Wrap(err, "couldn't init Jenkins API client") | 		return nil, errors.Wrap(err, "couldn't init Jenkins API client") | ||||||
|  |  | ||||||
|  | @ -1,25 +1,19 @@ | ||||||
| package backuprestore | package backuprestore | ||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
| 	"bytes" |  | ||||||
| 	"context" | 	"context" | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"time" | 	"time" | ||||||
| 
 | 
 | ||||||
| 	"github.com/jenkinsci/kubernetes-operator/pkg/apis/jenkins/v1alpha2" | 	"github.com/jenkinsci/kubernetes-operator/pkg/apis/jenkins/v1alpha2" | ||||||
| 	jenkinsclient "github.com/jenkinsci/kubernetes-operator/pkg/controller/jenkins/client" | 	jenkinsclient "github.com/jenkinsci/kubernetes-operator/pkg/controller/jenkins/client" | ||||||
|  | 	"github.com/jenkinsci/kubernetes-operator/pkg/controller/jenkins/configuration" | ||||||
| 	"github.com/jenkinsci/kubernetes-operator/pkg/controller/jenkins/configuration/base/resources" | 	"github.com/jenkinsci/kubernetes-operator/pkg/controller/jenkins/configuration/base/resources" | ||||||
| 	"github.com/jenkinsci/kubernetes-operator/pkg/log" | 	"github.com/jenkinsci/kubernetes-operator/pkg/log" | ||||||
| 
 | 
 | ||||||
| 	"github.com/go-logr/logr" | 	"github.com/go-logr/logr" | ||||||
| 	"github.com/pkg/errors" |  | ||||||
| 	corev1 "k8s.io/api/core/v1" |  | ||||||
| 	apierrors "k8s.io/apimachinery/pkg/api/errors" | 	apierrors "k8s.io/apimachinery/pkg/api/errors" | ||||||
| 	"k8s.io/apimachinery/pkg/types" | 	"k8s.io/apimachinery/pkg/types" | ||||||
| 	"k8s.io/client-go/kubernetes" |  | ||||||
| 	"k8s.io/client-go/kubernetes/scheme" |  | ||||||
| 	"k8s.io/client-go/rest" |  | ||||||
| 	"k8s.io/client-go/tools/remotecommand" |  | ||||||
| 	k8s "sigs.k8s.io/controller-runtime/pkg/client" | 	k8s "sigs.k8s.io/controller-runtime/pkg/client" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
|  | @ -61,29 +55,27 @@ var triggers = backupTriggers{triggers: make(map[string]backupTrigger)} | ||||||
| 
 | 
 | ||||||
| // BackupAndRestore represents Jenkins backup and restore client
 | // BackupAndRestore represents Jenkins backup and restore client
 | ||||||
| type BackupAndRestore struct { | type BackupAndRestore struct { | ||||||
| 	config    rest.Config | 	configuration.Configuration | ||||||
| 	k8sClient k8s.Client |  | ||||||
| 	clientSet kubernetes.Clientset |  | ||||||
| 
 |  | ||||||
| 	logger logr.Logger | 	logger logr.Logger | ||||||
| 	jenkins *v1alpha2.Jenkins |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // New returns Jenkins backup and restore client
 | // New returns Jenkins backup and restore client
 | ||||||
| func New(k8sClient k8s.Client, clientSet kubernetes.Clientset, | func New(configuration configuration.Configuration, logger logr.Logger) *BackupAndRestore { | ||||||
| 	logger logr.Logger, jenkins *v1alpha2.Jenkins, config rest.Config) *BackupAndRestore { | 	return &BackupAndRestore{ | ||||||
| 	return &BackupAndRestore{k8sClient: k8sClient, clientSet: clientSet, logger: logger, jenkins: jenkins, config: config} | 		Configuration: configuration, | ||||||
|  | 		logger:        logger, | ||||||
|  | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Validate validates backup and restore configuration
 | // Validate validates backup and restore configuration
 | ||||||
| func (bar *BackupAndRestore) Validate() []string { | func (bar *BackupAndRestore) Validate() []string { | ||||||
| 	var messages []string | 	var messages []string | ||||||
| 	allContainers := map[string]v1alpha2.Container{} | 	allContainers := map[string]v1alpha2.Container{} | ||||||
| 	for _, container := range bar.jenkins.Spec.Master.Containers { | 	for _, container := range bar.Configuration.Jenkins.Spec.Master.Containers { | ||||||
| 		allContainers[container.Name] = container | 		allContainers[container.Name] = container | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	restore := bar.jenkins.Spec.Restore | 	restore := bar.Configuration.Jenkins.Spec.Restore | ||||||
| 	if len(restore.ContainerName) > 0 { | 	if len(restore.ContainerName) > 0 { | ||||||
| 		_, found := allContainers[restore.ContainerName] | 		_, found := allContainers[restore.ContainerName] | ||||||
| 		if !found { | 		if !found { | ||||||
|  | @ -94,7 +86,7 @@ func (bar *BackupAndRestore) Validate() []string { | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	backup := bar.jenkins.Spec.Backup | 	backup := bar.Configuration.Jenkins.Spec.Backup | ||||||
| 	if len(backup.ContainerName) > 0 { | 	if len(backup.ContainerName) > 0 { | ||||||
| 		_, found := allContainers[backup.ContainerName] | 		_, found := allContainers[backup.ContainerName] | ||||||
| 		if !found { | 		if !found { | ||||||
|  | @ -120,7 +112,7 @@ func (bar *BackupAndRestore) Validate() []string { | ||||||
| 
 | 
 | ||||||
| // Restore performs Jenkins restore backup operation
 | // Restore performs Jenkins restore backup operation
 | ||||||
| func (bar *BackupAndRestore) Restore(jenkinsClient jenkinsclient.Jenkins) error { | func (bar *BackupAndRestore) Restore(jenkinsClient jenkinsclient.Jenkins) error { | ||||||
| 	jenkins := bar.jenkins | 	jenkins := bar.Configuration.Jenkins | ||||||
| 	if len(jenkins.Spec.Restore.ContainerName) == 0 || jenkins.Spec.Restore.Action.Exec == nil { | 	if len(jenkins.Spec.Restore.ContainerName) == 0 || jenkins.Spec.Restore.Action.Exec == nil { | ||||||
| 		bar.logger.V(log.VDebug).Info("Skipping restore backup, backup restore not configured") | 		bar.logger.V(log.VDebug).Info("Skipping restore backup, backup restore not configured") | ||||||
| 		return nil | 		return nil | ||||||
|  | @ -133,7 +125,7 @@ func (bar *BackupAndRestore) Restore(jenkinsClient jenkinsclient.Jenkins) error | ||||||
| 		bar.logger.V(log.VDebug).Info("Skipping restore backup") | 		bar.logger.V(log.VDebug).Info("Skipping restore backup") | ||||||
| 		if jenkins.Status.PendingBackup == 0 { | 		if jenkins.Status.PendingBackup == 0 { | ||||||
| 			jenkins.Status.PendingBackup = 1 | 			jenkins.Status.PendingBackup = 1 | ||||||
| 			return bar.k8sClient.Update(context.TODO(), jenkins) | 			return bar.Client.Update(context.TODO(), jenkins) | ||||||
| 		} | 		} | ||||||
| 		return nil | 		return nil | ||||||
| 	} | 	} | ||||||
|  | @ -148,7 +140,7 @@ func (bar *BackupAndRestore) Restore(jenkinsClient jenkinsclient.Jenkins) error | ||||||
| 	podName := resources.GetJenkinsMasterPodName(*jenkins) | 	podName := resources.GetJenkinsMasterPodName(*jenkins) | ||||||
| 	command := jenkins.Spec.Restore.Action.Exec.Command | 	command := jenkins.Spec.Restore.Action.Exec.Command | ||||||
| 	command = append(command, fmt.Sprintf("%d", backupNumber)) | 	command = append(command, fmt.Sprintf("%d", backupNumber)) | ||||||
| 	_, _, err := bar.exec(podName, jenkins.Spec.Restore.ContainerName, command) | 	_, _, err := bar.Exec(podName, jenkins.Spec.Restore.ContainerName, command) | ||||||
| 
 | 
 | ||||||
| 	if err == nil { | 	if err == nil { | ||||||
| 		_, err := jenkinsClient.ExecuteScript("Jenkins.instance.reload()") | 		_, err := jenkinsClient.ExecuteScript("Jenkins.instance.reload()") | ||||||
|  | @ -159,7 +151,7 @@ func (bar *BackupAndRestore) Restore(jenkinsClient jenkinsclient.Jenkins) error | ||||||
| 		jenkins.Spec.Restore.RecoveryOnce = 0 | 		jenkins.Spec.Restore.RecoveryOnce = 0 | ||||||
| 		jenkins.Status.RestoredBackup = backupNumber | 		jenkins.Status.RestoredBackup = backupNumber | ||||||
| 		jenkins.Status.PendingBackup = backupNumber + 1 | 		jenkins.Status.PendingBackup = backupNumber + 1 | ||||||
| 		return bar.k8sClient.Update(context.TODO(), jenkins) | 		return bar.Client.Update(context.TODO(), jenkins) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	return err | 	return err | ||||||
|  | @ -167,7 +159,7 @@ func (bar *BackupAndRestore) Restore(jenkinsClient jenkinsclient.Jenkins) error | ||||||
| 
 | 
 | ||||||
| // Backup performs Jenkins backup operation
 | // Backup performs Jenkins backup operation
 | ||||||
| func (bar *BackupAndRestore) Backup() error { | func (bar *BackupAndRestore) Backup() error { | ||||||
| 	jenkins := bar.jenkins | 	jenkins := bar.Configuration.Jenkins | ||||||
| 	if len(jenkins.Spec.Backup.ContainerName) == 0 || jenkins.Spec.Backup.Action.Exec == nil { | 	if len(jenkins.Spec.Backup.ContainerName) == 0 || jenkins.Spec.Backup.Action.Exec == nil { | ||||||
| 		bar.logger.V(log.VDebug).Info("Skipping restore backup, backup restore not configured") | 		bar.logger.V(log.VDebug).Info("Skipping restore backup, backup restore not configured") | ||||||
| 		return nil | 		return nil | ||||||
|  | @ -181,7 +173,7 @@ func (bar *BackupAndRestore) Backup() error { | ||||||
| 	podName := resources.GetJenkinsMasterPodName(*jenkins) | 	podName := resources.GetJenkinsMasterPodName(*jenkins) | ||||||
| 	command := jenkins.Spec.Backup.Action.Exec.Command | 	command := jenkins.Spec.Backup.Action.Exec.Command | ||||||
| 	command = append(command, fmt.Sprintf("%d", backupNumber)) | 	command = append(command, fmt.Sprintf("%d", backupNumber)) | ||||||
| 	_, _, err := bar.exec(podName, jenkins.Spec.Backup.ContainerName, command) | 	_, _, err := bar.Exec(podName, jenkins.Spec.Backup.ContainerName, command) | ||||||
| 
 | 
 | ||||||
| 	if err == nil { | 	if err == nil { | ||||||
| 		if jenkins.Status.RestoredBackup == 0 { | 		if jenkins.Status.RestoredBackup == 0 { | ||||||
|  | @ -189,7 +181,7 @@ func (bar *BackupAndRestore) Backup() error { | ||||||
| 		} | 		} | ||||||
| 		jenkins.Status.LastBackup = backupNumber | 		jenkins.Status.LastBackup = backupNumber | ||||||
| 		jenkins.Status.PendingBackup = backupNumber | 		jenkins.Status.PendingBackup = backupNumber | ||||||
| 		return bar.k8sClient.Update(context.TODO(), jenkins) | 		return bar.Client.Update(context.TODO(), jenkins) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	return err | 	return err | ||||||
|  | @ -217,9 +209,9 @@ func triggerBackup(ticker *time.Ticker, k8sClient k8s.Client, logger logr.Logger | ||||||
| 
 | 
 | ||||||
| // EnsureBackupTrigger creates or update trigger which update CR to make backup
 | // EnsureBackupTrigger creates or update trigger which update CR to make backup
 | ||||||
| func (bar *BackupAndRestore) EnsureBackupTrigger() error { | func (bar *BackupAndRestore) EnsureBackupTrigger() error { | ||||||
| 	trigger, found := triggers.get(bar.jenkins.Namespace, bar.jenkins.Name) | 	trigger, found := triggers.get(bar.Configuration.Jenkins.Namespace, bar.Configuration.Jenkins.Name) | ||||||
| 
 | 
 | ||||||
| 	isBackupConfigured := len(bar.jenkins.Spec.Backup.ContainerName) > 0 && bar.jenkins.Spec.Backup.Interval > 0 | 	isBackupConfigured := len(bar.Configuration.Jenkins.Spec.Backup.ContainerName) > 0 && bar.Configuration.Jenkins.Spec.Backup.Interval > 0 | ||||||
| 	if found && !isBackupConfigured { | 	if found && !isBackupConfigured { | ||||||
| 		bar.StopBackupTrigger() | 		bar.StopBackupTrigger() | ||||||
| 		return nil | 		return nil | ||||||
|  | @ -231,7 +223,7 @@ func (bar *BackupAndRestore) EnsureBackupTrigger() error { | ||||||
| 		return nil | 		return nil | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if found && isBackupConfigured && bar.jenkins.Spec.Backup.Interval != trigger.interval { | 	if found && isBackupConfigured && bar.Configuration.Jenkins.Spec.Backup.Interval != trigger.interval { | ||||||
| 		bar.StopBackupTrigger() | 		bar.StopBackupTrigger() | ||||||
| 		bar.startBackupTrigger() | 		bar.startBackupTrigger() | ||||||
| 	} | 	} | ||||||
|  | @ -241,55 +233,21 @@ func (bar *BackupAndRestore) EnsureBackupTrigger() error { | ||||||
| 
 | 
 | ||||||
| // StopBackupTrigger stops trigger which update CR to make backup
 | // StopBackupTrigger stops trigger which update CR to make backup
 | ||||||
| func (bar *BackupAndRestore) StopBackupTrigger() { | func (bar *BackupAndRestore) StopBackupTrigger() { | ||||||
| 	triggers.stop(bar.logger, bar.jenkins.Namespace, bar.jenkins.Name) | 	triggers.stop(bar.logger, bar.Configuration.Jenkins.Namespace, bar.Configuration.Jenkins.Name) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| //IsBackupTriggerEnabled returns true if the backup trigger is enabled
 | //IsBackupTriggerEnabled returns true if the backup trigger is enabled
 | ||||||
| func (bar *BackupAndRestore) IsBackupTriggerEnabled() bool { | func (bar *BackupAndRestore) IsBackupTriggerEnabled() bool { | ||||||
| 	_, enabled := triggers.get(bar.jenkins.Namespace, bar.jenkins.Name) | 	_, enabled := triggers.get(bar.Configuration.Jenkins.Namespace, bar.Configuration.Jenkins.Name) | ||||||
| 	return enabled | 	return enabled | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (bar *BackupAndRestore) startBackupTrigger() { | func (bar *BackupAndRestore) startBackupTrigger() { | ||||||
| 	bar.logger.Info("Starting backup trigger") | 	bar.logger.Info("Starting backup trigger") | ||||||
| 	ticker := time.NewTicker(time.Duration(bar.jenkins.Spec.Backup.Interval) * time.Second) | 	ticker := time.NewTicker(time.Duration(bar.Configuration.Jenkins.Spec.Backup.Interval) * time.Second) | ||||||
| 	triggers.add(bar.jenkins.Namespace, bar.jenkins.Name, backupTrigger{ | 	triggers.add(bar.Configuration.Jenkins.Namespace, bar.Configuration.Jenkins.Name, backupTrigger{ | ||||||
| 		interval: bar.jenkins.Spec.Backup.Interval, | 		interval: bar.Configuration.Jenkins.Spec.Backup.Interval, | ||||||
| 		ticker:   ticker, | 		ticker:   ticker, | ||||||
| 	}) | 	}) | ||||||
| 	go triggerBackup(ticker, bar.k8sClient, bar.logger, bar.jenkins.Namespace, bar.jenkins.Name) | 	go triggerBackup(ticker, bar.Client, bar.logger, bar.Configuration.Jenkins.Namespace, bar.Configuration.Jenkins.Name) | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (bar *BackupAndRestore) exec(podName, containerName string, command []string) (stdout, stderr bytes.Buffer, err error) { |  | ||||||
| 	req := bar.clientSet.CoreV1().RESTClient().Post(). |  | ||||||
| 		Resource("pods"). |  | ||||||
| 		Name(podName). |  | ||||||
| 		Namespace(bar.jenkins.Namespace). |  | ||||||
| 		SubResource("exec") |  | ||||||
| 	req.VersionedParams(&corev1.PodExecOptions{ |  | ||||||
| 		Command:   command, |  | ||||||
| 		Container: containerName, |  | ||||||
| 		Stdin:     false, |  | ||||||
| 		Stdout:    true, |  | ||||||
| 		Stderr:    true, |  | ||||||
| 		TTY:       false, |  | ||||||
| 	}, scheme.ParameterCodec) |  | ||||||
| 
 |  | ||||||
| 	exec, err := remotecommand.NewSPDYExecutor(&bar.config, "POST", req.URL()) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return stdout, stderr, errors.Wrap(err, "pod exec error while creating Executor") |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	err = exec.Stream(remotecommand.StreamOptions{ |  | ||||||
| 		Stdin:  nil, |  | ||||||
| 		Stdout: &stdout, |  | ||||||
| 		Stderr: &stderr, |  | ||||||
| 		Tty:    false, |  | ||||||
| 	}) |  | ||||||
| 	bar.logger.V(log.VDebug).Info(fmt.Sprintf("pod exec: stdout '%s' stderr '%s'", stdout.String(), stderr.String())) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return stdout, stderr, errors.Wrapf(err, "pod exec error operation on stream: stdout '%s' stderr '%s'", stdout.String(), stderr.String()) |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	return |  | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -29,7 +29,6 @@ import ( | ||||||
| 	apierrors "k8s.io/apimachinery/pkg/api/errors" | 	apierrors "k8s.io/apimachinery/pkg/api/errors" | ||||||
| 	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" | ||||||
| 	"k8s.io/client-go/rest" |  | ||||||
| 	"sigs.k8s.io/controller-runtime/pkg/client" | 	"sigs.k8s.io/controller-runtime/pkg/client" | ||||||
| 	"sigs.k8s.io/controller-runtime/pkg/reconcile" | 	"sigs.k8s.io/controller-runtime/pkg/reconcile" | ||||||
| ) | ) | ||||||
|  | @ -43,16 +42,14 @@ type ReconcileJenkinsBaseConfiguration struct { | ||||||
| 	configuration.Configuration | 	configuration.Configuration | ||||||
| 	logger                       logr.Logger | 	logger                       logr.Logger | ||||||
| 	jenkinsAPIConnectionSettings jenkinsclient.JenkinsAPIConnectionSettings | 	jenkinsAPIConnectionSettings jenkinsclient.JenkinsAPIConnectionSettings | ||||||
| 	config                       *rest.Config |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // New create structure which takes care of base configuration
 | // New create structure which takes care of base configuration
 | ||||||
| func New(config configuration.Configuration, logger logr.Logger, jenkinsAPIConnectionSettings jenkinsclient.JenkinsAPIConnectionSettings, restConfig *rest.Config) *ReconcileJenkinsBaseConfiguration { | func New(config configuration.Configuration, logger logr.Logger, jenkinsAPIConnectionSettings jenkinsclient.JenkinsAPIConnectionSettings) *ReconcileJenkinsBaseConfiguration { | ||||||
| 	return &ReconcileJenkinsBaseConfiguration{ | 	return &ReconcileJenkinsBaseConfiguration{ | ||||||
| 		Configuration:                config, | 		Configuration:                config, | ||||||
| 		logger:                       logger, | 		logger:                       logger, | ||||||
| 		jenkinsAPIConnectionSettings: jenkinsAPIConnectionSettings, | 		jenkinsAPIConnectionSettings: jenkinsAPIConnectionSettings, | ||||||
| 		config:                       restConfig, |  | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -528,7 +525,7 @@ func (r *ReconcileJenkinsBaseConfiguration) ensureJenkinsMasterPod(meta metav1.O | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if r.IsJenkinsTerminating(*currentJenkinsMasterPod) && r.Configuration.Jenkins.Status.UserConfigurationCompletedTime != nil { | 	if r.IsJenkinsTerminating(*currentJenkinsMasterPod) && r.Configuration.Jenkins.Status.UserConfigurationCompletedTime != nil { | ||||||
| 		backupAndRestore := backuprestore.New(r.Client, r.ClientSet, r.logger, r.Configuration.Jenkins, *r.config) | 		backupAndRestore := backuprestore.New(r.Configuration, r.logger) | ||||||
| 		if backupAndRestore.IsBackupTriggerEnabled() { | 		if backupAndRestore.IsBackupTriggerEnabled() { | ||||||
| 			backupAndRestore.StopBackupTrigger() | 			backupAndRestore.StopBackupTrigger() | ||||||
| 		} | 		} | ||||||
|  | @ -904,6 +901,17 @@ func (r *ReconcileJenkinsBaseConfiguration) waitForJenkins() (reconcile.Result, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (r *ReconcileJenkinsBaseConfiguration) ensureJenkinsClient() (jenkinsclient.Jenkins, error) { | func (r *ReconcileJenkinsBaseConfiguration) ensureJenkinsClient() (jenkinsclient.Jenkins, error) { | ||||||
|  | 	switch r.Configuration.Jenkins.Spec.JenkinsAPISettings.AuthorizationStrategy { | ||||||
|  | 	case v1alpha2.ServiceAccountAuthorizationStrategy: | ||||||
|  | 		return r.ensureJenkinsClientFromServiceAccount() | ||||||
|  | 	case v1alpha2.CreateUserAuthorizationStrategy: | ||||||
|  | 		return r.ensureJenkinsClientFromSecret() | ||||||
|  | 	default: | ||||||
|  | 		return nil, stackerr.Errorf("unrecognized '%s' spec.jenkinsAPISettings.authorizationStrategy", r.Configuration.Jenkins.Spec.JenkinsAPISettings.AuthorizationStrategy) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (r *ReconcileJenkinsBaseConfiguration) getJenkinsAPIUrl() (string, error) { | ||||||
| 	var service corev1.Service | 	var service corev1.Service | ||||||
| 
 | 
 | ||||||
| 	err := r.Client.Get(context.TODO(), types.NamespacedName{ | 	err := r.Client.Get(context.TODO(), types.NamespacedName{ | ||||||
|  | @ -912,7 +920,7 @@ func (r *ReconcileJenkinsBaseConfiguration) ensureJenkinsClient() (jenkinsclient | ||||||
| 	}, &service) | 	}, &service) | ||||||
| 
 | 
 | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, err | 		return "", err | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	jenkinsURL := r.jenkinsAPIConnectionSettings.BuildJenkinsAPIUrl(service.Name, service.Namespace, service.Spec.Ports[0].Port, service.Spec.Ports[0].NodePort) | 	jenkinsURL := r.jenkinsAPIConnectionSettings.BuildJenkinsAPIUrl(service.Name, service.Namespace, service.Spec.Ports[0].Port, service.Spec.Ports[0].NodePort) | ||||||
|  | @ -921,6 +929,30 @@ func (r *ReconcileJenkinsBaseConfiguration) ensureJenkinsClient() (jenkinsclient | ||||||
| 		jenkinsURL = jenkinsURL + prefix | 		jenkinsURL = jenkinsURL + prefix | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	return jenkinsURL, nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (r *ReconcileJenkinsBaseConfiguration) ensureJenkinsClientFromServiceAccount() (jenkinsclient.Jenkins, error) { | ||||||
|  | 	jenkinsAPIUrl, err := r.getJenkinsAPIUrl() | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	podName := resources.GetJenkinsMasterPodName(*r.Configuration.Jenkins) | ||||||
|  | 	token, _, err := r.Configuration.Exec(podName, resources.JenkinsMasterContainerName, []string{"cat", "/var/run/secrets/kubernetes.io/serviceaccount/token"}) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return jenkinsclient.NewBearerTokenAuthorization(jenkinsAPIUrl, token.String()) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (r *ReconcileJenkinsBaseConfiguration) ensureJenkinsClientFromSecret() (jenkinsclient.Jenkins, error) { | ||||||
|  | 	jenkinsURL, err := r.getJenkinsAPIUrl() | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	r.logger.V(log.VDebug).Info(fmt.Sprintf("Jenkins API URL '%s'", jenkinsURL)) | 	r.logger.V(log.VDebug).Info(fmt.Sprintf("Jenkins API URL '%s'", jenkinsURL)) | ||||||
| 
 | 
 | ||||||
| 	credentialsSecret := &corev1.Secret{} | 	credentialsSecret := &corev1.Secret{} | ||||||
|  | @ -948,7 +980,7 @@ func (r *ReconcileJenkinsBaseConfiguration) ensureJenkinsClient() (jenkinsclient | ||||||
| 		currentJenkinsMasterPod.ObjectMeta.CreationTimestamp.Time.UTC().After(tokenCreationTime.UTC()) { | 		currentJenkinsMasterPod.ObjectMeta.CreationTimestamp.Time.UTC().After(tokenCreationTime.UTC()) { | ||||||
| 		r.logger.Info("Generating Jenkins API token for operator") | 		r.logger.Info("Generating Jenkins API token for operator") | ||||||
| 		userName := string(credentialsSecret.Data[resources.OperatorCredentialsSecretUserNameKey]) | 		userName := string(credentialsSecret.Data[resources.OperatorCredentialsSecretUserNameKey]) | ||||||
| 		jenkinsClient, err := jenkinsclient.New( | 		jenkinsClient, err := jenkinsclient.NewUserAndPasswordAuthorization( | ||||||
| 			jenkinsURL, | 			jenkinsURL, | ||||||
| 			userName, | 			userName, | ||||||
| 			string(credentialsSecret.Data[resources.OperatorCredentialsSecretPasswordKey])) | 			string(credentialsSecret.Data[resources.OperatorCredentialsSecretPasswordKey])) | ||||||
|  | @ -970,7 +1002,7 @@ func (r *ReconcileJenkinsBaseConfiguration) ensureJenkinsClient() (jenkinsclient | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	return jenkinsclient.New( | 	return jenkinsclient.NewUserAndPasswordAuthorization( | ||||||
| 		jenkinsURL, | 		jenkinsURL, | ||||||
| 		string(credentialsSecret.Data[resources.OperatorCredentialsSecretUserNameKey]), | 		string(credentialsSecret.Data[resources.OperatorCredentialsSecretUserNameKey]), | ||||||
| 		string(credentialsSecret.Data[resources.OperatorCredentialsSecretTokenKey])) | 		string(credentialsSecret.Data[resources.OperatorCredentialsSecretTokenKey])) | ||||||
|  |  | ||||||
|  | @ -240,7 +240,7 @@ func TestCompareVolumes(t *testing.T) { | ||||||
| 				Volumes:            resources.GetJenkinsMasterPodBaseVolumes(jenkins), | 				Volumes:            resources.GetJenkinsMasterPodBaseVolumes(jenkins), | ||||||
| 			}, | 			}, | ||||||
| 		} | 		} | ||||||
| 		reconciler := New(configuration.Configuration{Jenkins: jenkins}, nil, client.JenkinsAPIConnectionSettings{}, nil) | 		reconciler := New(configuration.Configuration{Jenkins: jenkins}, nil, client.JenkinsAPIConnectionSettings{}) | ||||||
| 
 | 
 | ||||||
| 		got := reconciler.compareVolumes(pod) | 		got := reconciler.compareVolumes(pod) | ||||||
| 
 | 
 | ||||||
|  | @ -264,7 +264,7 @@ func TestCompareVolumes(t *testing.T) { | ||||||
| 				Volumes:            resources.GetJenkinsMasterPodBaseVolumes(jenkins), | 				Volumes:            resources.GetJenkinsMasterPodBaseVolumes(jenkins), | ||||||
| 			}, | 			}, | ||||||
| 		} | 		} | ||||||
| 		reconciler := New(configuration.Configuration{Jenkins: jenkins}, nil, client.JenkinsAPIConnectionSettings{}, nil) | 		reconciler := New(configuration.Configuration{Jenkins: jenkins}, nil, client.JenkinsAPIConnectionSettings{}) | ||||||
| 
 | 
 | ||||||
| 		got := reconciler.compareVolumes(pod) | 		got := reconciler.compareVolumes(pod) | ||||||
| 
 | 
 | ||||||
|  | @ -288,7 +288,7 @@ func TestCompareVolumes(t *testing.T) { | ||||||
| 				Volumes:            append(resources.GetJenkinsMasterPodBaseVolumes(jenkins), corev1.Volume{Name: "added"}), | 				Volumes:            append(resources.GetJenkinsMasterPodBaseVolumes(jenkins), corev1.Volume{Name: "added"}), | ||||||
| 			}, | 			}, | ||||||
| 		} | 		} | ||||||
| 		reconciler := New(configuration.Configuration{Jenkins: jenkins}, nil, client.JenkinsAPIConnectionSettings{}, nil) | 		reconciler := New(configuration.Configuration{Jenkins: jenkins}, nil, client.JenkinsAPIConnectionSettings{}) | ||||||
| 
 | 
 | ||||||
| 		got := reconciler.compareVolumes(pod) | 		got := reconciler.compareVolumes(pod) | ||||||
| 
 | 
 | ||||||
|  | @ -766,7 +766,7 @@ func TestEnsureExtraRBAC(t *testing.T) { | ||||||
| 				Roles: []rbacv1.RoleRef{}, | 				Roles: []rbacv1.RoleRef{}, | ||||||
| 			}, | 			}, | ||||||
| 		} | 		} | ||||||
| 		reconciler := New(configuration.Configuration{Client: fakeClient, Jenkins: jenkins, Scheme: scheme.Scheme}, nil, client.JenkinsAPIConnectionSettings{}, nil) | 		reconciler := New(configuration.Configuration{Client: fakeClient, Jenkins: jenkins, Scheme: scheme.Scheme}, nil, client.JenkinsAPIConnectionSettings{}) | ||||||
| 		metaObject := resources.NewResourceObjectMeta(jenkins) | 		metaObject := resources.NewResourceObjectMeta(jenkins) | ||||||
| 
 | 
 | ||||||
| 		// when
 | 		// when
 | ||||||
|  | @ -802,7 +802,7 @@ func TestEnsureExtraRBAC(t *testing.T) { | ||||||
| 				}, | 				}, | ||||||
| 			}, | 			}, | ||||||
| 		} | 		} | ||||||
| 		reconciler := New(configuration.Configuration{Client: fakeClient, Jenkins: jenkins, Scheme: scheme.Scheme}, nil, client.JenkinsAPIConnectionSettings{}, nil) | 		reconciler := New(configuration.Configuration{Client: fakeClient, Jenkins: jenkins, Scheme: scheme.Scheme}, nil, client.JenkinsAPIConnectionSettings{}) | ||||||
| 		metaObject := resources.NewResourceObjectMeta(jenkins) | 		metaObject := resources.NewResourceObjectMeta(jenkins) | ||||||
| 
 | 
 | ||||||
| 		// when
 | 		// when
 | ||||||
|  | @ -844,7 +844,7 @@ func TestEnsureExtraRBAC(t *testing.T) { | ||||||
| 				}, | 				}, | ||||||
| 			}, | 			}, | ||||||
| 		} | 		} | ||||||
| 		reconciler := New(configuration.Configuration{Client: fakeClient, Jenkins: jenkins, Scheme: scheme.Scheme}, nil, client.JenkinsAPIConnectionSettings{}, nil) | 		reconciler := New(configuration.Configuration{Client: fakeClient, Jenkins: jenkins, Scheme: scheme.Scheme}, nil, client.JenkinsAPIConnectionSettings{}) | ||||||
| 		metaObject := resources.NewResourceObjectMeta(jenkins) | 		metaObject := resources.NewResourceObjectMeta(jenkins) | ||||||
| 
 | 
 | ||||||
| 		// when
 | 		// when
 | ||||||
|  | @ -887,7 +887,7 @@ func TestEnsureExtraRBAC(t *testing.T) { | ||||||
| 				}, | 				}, | ||||||
| 			}, | 			}, | ||||||
| 		} | 		} | ||||||
| 		reconciler := New(configuration.Configuration{Client: fakeClient, Jenkins: jenkins, Scheme: scheme.Scheme}, log.Log, client.JenkinsAPIConnectionSettings{}, nil) | 		reconciler := New(configuration.Configuration{Client: fakeClient, Jenkins: jenkins, Scheme: scheme.Scheme}, log.Log, client.JenkinsAPIConnectionSettings{}) | ||||||
| 		metaObject := resources.NewResourceObjectMeta(jenkins) | 		metaObject := resources.NewResourceObjectMeta(jenkins) | ||||||
| 
 | 
 | ||||||
| 		// when
 | 		// when
 | ||||||
|  |  | ||||||
|  | @ -17,6 +17,7 @@ const createOperatorUserFileName = "createOperatorUser.groovy" | ||||||
| var createOperatorUserGroovyFmtTemplate = template.Must(template.New(createOperatorUserFileName).Parse(` | var createOperatorUserGroovyFmtTemplate = template.Must(template.New(createOperatorUserFileName).Parse(` | ||||||
| import hudson.security.* | import hudson.security.* | ||||||
| 
 | 
 | ||||||
|  | {{- if .Enable }} | ||||||
| def jenkins = jenkins.model.Jenkins.getInstance() | def jenkins = jenkins.model.Jenkins.getInstance() | ||||||
| def operatorUserCreatedFile = new File('{{ .OperatorUserCreatedFilePath }}') | def operatorUserCreatedFile = new File('{{ .OperatorUserCreatedFilePath }}') | ||||||
| 
 | 
 | ||||||
|  | @ -34,15 +35,18 @@ if (!operatorUserCreatedFile.exists()) { | ||||||
| 
 | 
 | ||||||
| 	operatorUserCreatedFile.createNewFile() | 	operatorUserCreatedFile.createNewFile() | ||||||
| } | } | ||||||
|  | {{- end }} | ||||||
| `)) | `)) | ||||||
| 
 | 
 | ||||||
| func buildCreateJenkinsOperatorUserGroovyScript(jenkins *v1alpha2.Jenkins) (*string, error) { | func buildCreateJenkinsOperatorUserGroovyScript(jenkins *v1alpha2.Jenkins) (*string, error) { | ||||||
| 	data := struct { | 	data := struct { | ||||||
|  | 		Enable                      bool | ||||||
| 		OperatorCredentialsPath     string | 		OperatorCredentialsPath     string | ||||||
| 		OperatorUserNameFile        string | 		OperatorUserNameFile        string | ||||||
| 		OperatorPasswordFile        string | 		OperatorPasswordFile        string | ||||||
| 		OperatorUserCreatedFilePath string | 		OperatorUserCreatedFilePath string | ||||||
| 	}{ | 	}{ | ||||||
|  | 		Enable:                      jenkins.Spec.JenkinsAPISettings.AuthorizationStrategy == v1alpha2.CreateUserAuthorizationStrategy, | ||||||
| 		OperatorCredentialsPath:     jenkinsOperatorCredentialsVolumePath, | 		OperatorCredentialsPath:     jenkinsOperatorCredentialsVolumePath, | ||||||
| 		OperatorUserNameFile:        OperatorCredentialsSecretUserNameKey, | 		OperatorUserNameFile:        OperatorCredentialsSecretUserNameKey, | ||||||
| 		OperatorPasswordFile:        OperatorCredentialsSecretPasswordKey, | 		OperatorPasswordFile:        OperatorCredentialsSecretPasswordKey, | ||||||
|  |  | ||||||
|  | @ -62,6 +62,10 @@ func (r *ReconcileJenkinsBaseConfiguration) Validate(jenkins *v1alpha2.Jenkins) | ||||||
| 		messages = append(messages, msg...) | 		messages = append(messages, msg...) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	if jenkins.Spec.JenkinsAPISettings.AuthorizationStrategy != v1alpha2.CreateUserAuthorizationStrategy && jenkins.Spec.JenkinsAPISettings.AuthorizationStrategy != v1alpha2.ServiceAccountAuthorizationStrategy { | ||||||
|  | 		messages = append(messages, fmt.Sprintf("unrecognized '%s' spec.jenkinsAPISettings.authorizationStrategy", jenkins.Spec.JenkinsAPISettings.AuthorizationStrategy)) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	return messages, nil | 	return messages, nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -23,7 +23,7 @@ import ( | ||||||
| 
 | 
 | ||||||
| func TestValidatePlugins(t *testing.T) { | func TestValidatePlugins(t *testing.T) { | ||||||
| 	log.SetupLogger(true) | 	log.SetupLogger(true) | ||||||
| 	baseReconcileLoop := New(configuration.Configuration{}, log.Log, client.JenkinsAPIConnectionSettings{}, nil) | 	baseReconcileLoop := New(configuration.Configuration{}, log.Log, client.JenkinsAPIConnectionSettings{}) | ||||||
| 	t.Run("empty", func(t *testing.T) { | 	t.Run("empty", func(t *testing.T) { | ||||||
| 		var requiredBasePlugins []plugins.Plugin | 		var requiredBasePlugins []plugins.Plugin | ||||||
| 		var basePlugins []v1alpha2.Plugin | 		var basePlugins []v1alpha2.Plugin | ||||||
|  | @ -166,7 +166,7 @@ func TestReconcileJenkinsBaseConfiguration_validateImagePullSecrets(t *testing.T | ||||||
| 		baseReconcileLoop := New(configuration.Configuration{ | 		baseReconcileLoop := New(configuration.Configuration{ | ||||||
| 			Client:  fakeClient, | 			Client:  fakeClient, | ||||||
| 			Jenkins: &jenkins, | 			Jenkins: &jenkins, | ||||||
| 		}, logf.ZapLogger(false), client.JenkinsAPIConnectionSettings{}, nil) | 		}, logf.ZapLogger(false), client.JenkinsAPIConnectionSettings{}) | ||||||
| 
 | 
 | ||||||
| 		got, err := baseReconcileLoop.validateImagePullSecrets() | 		got, err := baseReconcileLoop.validateImagePullSecrets() | ||||||
| 		fmt.Println(got) | 		fmt.Println(got) | ||||||
|  | @ -190,7 +190,7 @@ func TestReconcileJenkinsBaseConfiguration_validateImagePullSecrets(t *testing.T | ||||||
| 		baseReconcileLoop := New(configuration.Configuration{ | 		baseReconcileLoop := New(configuration.Configuration{ | ||||||
| 			Client:  fakeClient, | 			Client:  fakeClient, | ||||||
| 			Jenkins: &jenkins, | 			Jenkins: &jenkins, | ||||||
| 		}, nil, client.JenkinsAPIConnectionSettings{}, nil) | 		}, nil, client.JenkinsAPIConnectionSettings{}) | ||||||
| 
 | 
 | ||||||
| 		got, _ := baseReconcileLoop.validateImagePullSecrets() | 		got, _ := baseReconcileLoop.validateImagePullSecrets() | ||||||
| 
 | 
 | ||||||
|  | @ -226,7 +226,7 @@ func TestReconcileJenkinsBaseConfiguration_validateImagePullSecrets(t *testing.T | ||||||
| 		baseReconcileLoop := New(configuration.Configuration{ | 		baseReconcileLoop := New(configuration.Configuration{ | ||||||
| 			Client:  fakeClient, | 			Client:  fakeClient, | ||||||
| 			Jenkins: &jenkins, | 			Jenkins: &jenkins, | ||||||
| 		}, nil, client.JenkinsAPIConnectionSettings{}, nil) | 		}, nil, client.JenkinsAPIConnectionSettings{}) | ||||||
| 
 | 
 | ||||||
| 		got, _ := baseReconcileLoop.validateImagePullSecrets() | 		got, _ := baseReconcileLoop.validateImagePullSecrets() | ||||||
| 
 | 
 | ||||||
|  | @ -262,7 +262,7 @@ func TestReconcileJenkinsBaseConfiguration_validateImagePullSecrets(t *testing.T | ||||||
| 		baseReconcileLoop := New(configuration.Configuration{ | 		baseReconcileLoop := New(configuration.Configuration{ | ||||||
| 			Client:  fakeClient, | 			Client:  fakeClient, | ||||||
| 			Jenkins: &jenkins, | 			Jenkins: &jenkins, | ||||||
| 		}, logf.ZapLogger(false), client.JenkinsAPIConnectionSettings{}, nil) | 		}, logf.ZapLogger(false), client.JenkinsAPIConnectionSettings{}) | ||||||
| 
 | 
 | ||||||
| 		got, _ := baseReconcileLoop.validateImagePullSecrets() | 		got, _ := baseReconcileLoop.validateImagePullSecrets() | ||||||
| 
 | 
 | ||||||
|  | @ -298,7 +298,7 @@ func TestReconcileJenkinsBaseConfiguration_validateImagePullSecrets(t *testing.T | ||||||
| 		baseReconcileLoop := New(configuration.Configuration{ | 		baseReconcileLoop := New(configuration.Configuration{ | ||||||
| 			Client:  fakeClient, | 			Client:  fakeClient, | ||||||
| 			Jenkins: &jenkins, | 			Jenkins: &jenkins, | ||||||
| 		}, logf.ZapLogger(false), client.JenkinsAPIConnectionSettings{}, nil) | 		}, logf.ZapLogger(false), client.JenkinsAPIConnectionSettings{}) | ||||||
| 
 | 
 | ||||||
| 		got, _ := baseReconcileLoop.validateImagePullSecrets() | 		got, _ := baseReconcileLoop.validateImagePullSecrets() | ||||||
| 
 | 
 | ||||||
|  | @ -334,7 +334,7 @@ func TestReconcileJenkinsBaseConfiguration_validateImagePullSecrets(t *testing.T | ||||||
| 		baseReconcileLoop := New(configuration.Configuration{ | 		baseReconcileLoop := New(configuration.Configuration{ | ||||||
| 			Client:  fakeClient, | 			Client:  fakeClient, | ||||||
| 			Jenkins: &jenkins, | 			Jenkins: &jenkins, | ||||||
| 		}, logf.ZapLogger(false), client.JenkinsAPIConnectionSettings{}, nil) | 		}, logf.ZapLogger(false), client.JenkinsAPIConnectionSettings{}) | ||||||
| 
 | 
 | ||||||
| 		got, _ := baseReconcileLoop.validateImagePullSecrets() | 		got, _ := baseReconcileLoop.validateImagePullSecrets() | ||||||
| 
 | 
 | ||||||
|  | @ -367,7 +367,7 @@ func TestValidateJenkinsMasterPodEnvs(t *testing.T) { | ||||||
| 		} | 		} | ||||||
| 		baseReconcileLoop := New(configuration.Configuration{ | 		baseReconcileLoop := New(configuration.Configuration{ | ||||||
| 			Jenkins: &jenkins, | 			Jenkins: &jenkins, | ||||||
| 		}, logf.ZapLogger(false), client.JenkinsAPIConnectionSettings{}, nil) | 		}, logf.ZapLogger(false), client.JenkinsAPIConnectionSettings{}) | ||||||
| 		got := baseReconcileLoop.validateJenkinsMasterPodEnvs() | 		got := baseReconcileLoop.validateJenkinsMasterPodEnvs() | ||||||
| 		assert.Nil(t, got) | 		assert.Nil(t, got) | ||||||
| 	}) | 	}) | ||||||
|  | @ -390,7 +390,7 @@ func TestValidateJenkinsMasterPodEnvs(t *testing.T) { | ||||||
| 		} | 		} | ||||||
| 		baseReconcileLoop := New(configuration.Configuration{ | 		baseReconcileLoop := New(configuration.Configuration{ | ||||||
| 			Jenkins: &jenkins, | 			Jenkins: &jenkins, | ||||||
| 		}, logf.ZapLogger(false), client.JenkinsAPIConnectionSettings{}, nil) | 		}, logf.ZapLogger(false), client.JenkinsAPIConnectionSettings{}) | ||||||
| 		got := baseReconcileLoop.validateJenkinsMasterPodEnvs() | 		got := baseReconcileLoop.validateJenkinsMasterPodEnvs() | ||||||
| 
 | 
 | ||||||
| 		assert.Equal(t, got, []string{"Jenkins Master container env 'JAVA_OPTS' doesn't have required flag '-Djava.awt.headless=true'"}) | 		assert.Equal(t, got, []string{"Jenkins Master container env 'JAVA_OPTS' doesn't have required flag '-Djava.awt.headless=true'"}) | ||||||
|  | @ -414,7 +414,7 @@ func TestValidateJenkinsMasterPodEnvs(t *testing.T) { | ||||||
| 		} | 		} | ||||||
| 		baseReconcileLoop := New(configuration.Configuration{ | 		baseReconcileLoop := New(configuration.Configuration{ | ||||||
| 			Jenkins: &jenkins, | 			Jenkins: &jenkins, | ||||||
| 		}, logf.ZapLogger(false), client.JenkinsAPIConnectionSettings{}, nil) | 		}, logf.ZapLogger(false), client.JenkinsAPIConnectionSettings{}) | ||||||
| 		got := baseReconcileLoop.validateJenkinsMasterPodEnvs() | 		got := baseReconcileLoop.validateJenkinsMasterPodEnvs() | ||||||
| 
 | 
 | ||||||
| 		assert.Equal(t, got, []string{"Jenkins Master container env 'JAVA_OPTS' doesn't have required flag '-Djenkins.install.runSetupWizard=false'"}) | 		assert.Equal(t, got, []string{"Jenkins Master container env 'JAVA_OPTS' doesn't have required flag '-Djenkins.install.runSetupWizard=false'"}) | ||||||
|  | @ -436,7 +436,7 @@ func TestValidateReservedVolumes(t *testing.T) { | ||||||
| 		} | 		} | ||||||
| 		baseReconcileLoop := New(configuration.Configuration{ | 		baseReconcileLoop := New(configuration.Configuration{ | ||||||
| 			Jenkins: &jenkins, | 			Jenkins: &jenkins, | ||||||
| 		}, logf.ZapLogger(false), client.JenkinsAPIConnectionSettings{}, nil) | 		}, logf.ZapLogger(false), client.JenkinsAPIConnectionSettings{}) | ||||||
| 		got := baseReconcileLoop.validateReservedVolumes() | 		got := baseReconcileLoop.validateReservedVolumes() | ||||||
| 		assert.Nil(t, got) | 		assert.Nil(t, got) | ||||||
| 	}) | 	}) | ||||||
|  | @ -454,7 +454,7 @@ func TestValidateReservedVolumes(t *testing.T) { | ||||||
| 		} | 		} | ||||||
| 		baseReconcileLoop := New(configuration.Configuration{ | 		baseReconcileLoop := New(configuration.Configuration{ | ||||||
| 			Jenkins: &jenkins, | 			Jenkins: &jenkins, | ||||||
| 		}, logf.ZapLogger(false), client.JenkinsAPIConnectionSettings{}, nil) | 		}, logf.ZapLogger(false), client.JenkinsAPIConnectionSettings{}) | ||||||
| 		got := baseReconcileLoop.validateReservedVolumes() | 		got := baseReconcileLoop.validateReservedVolumes() | ||||||
| 
 | 
 | ||||||
| 		assert.Equal(t, got, []string{"Jenkins Master pod volume 'jenkins-home' is reserved please choose different one"}) | 		assert.Equal(t, got, []string{"Jenkins Master pod volume 'jenkins-home' is reserved please choose different one"}) | ||||||
|  | @ -470,7 +470,7 @@ func TestValidateContainerVolumeMounts(t *testing.T) { | ||||||
| 		} | 		} | ||||||
| 		baseReconcileLoop := New(configuration.Configuration{ | 		baseReconcileLoop := New(configuration.Configuration{ | ||||||
| 			Jenkins: &jenkins, | 			Jenkins: &jenkins, | ||||||
| 		}, logf.ZapLogger(false), client.JenkinsAPIConnectionSettings{}, nil) | 		}, logf.ZapLogger(false), client.JenkinsAPIConnectionSettings{}) | ||||||
| 		got := baseReconcileLoop.validateContainerVolumeMounts(v1alpha2.Container{}) | 		got := baseReconcileLoop.validateContainerVolumeMounts(v1alpha2.Container{}) | ||||||
| 		assert.Nil(t, got) | 		assert.Nil(t, got) | ||||||
| 	}) | 	}) | ||||||
|  | @ -498,7 +498,7 @@ func TestValidateContainerVolumeMounts(t *testing.T) { | ||||||
| 		} | 		} | ||||||
| 		baseReconcileLoop := New(configuration.Configuration{ | 		baseReconcileLoop := New(configuration.Configuration{ | ||||||
| 			Jenkins: &jenkins, | 			Jenkins: &jenkins, | ||||||
| 		}, logf.ZapLogger(false), client.JenkinsAPIConnectionSettings{}, nil) | 		}, logf.ZapLogger(false), client.JenkinsAPIConnectionSettings{}) | ||||||
| 		got := baseReconcileLoop.validateContainerVolumeMounts(jenkins.Spec.Master.Containers[0]) | 		got := baseReconcileLoop.validateContainerVolumeMounts(jenkins.Spec.Master.Containers[0]) | ||||||
| 		assert.Nil(t, got) | 		assert.Nil(t, got) | ||||||
| 	}) | 	}) | ||||||
|  | @ -526,7 +526,7 @@ func TestValidateContainerVolumeMounts(t *testing.T) { | ||||||
| 		} | 		} | ||||||
| 		baseReconcileLoop := New(configuration.Configuration{ | 		baseReconcileLoop := New(configuration.Configuration{ | ||||||
| 			Jenkins: &jenkins, | 			Jenkins: &jenkins, | ||||||
| 		}, logf.ZapLogger(false), client.JenkinsAPIConnectionSettings{}, nil) | 		}, logf.ZapLogger(false), client.JenkinsAPIConnectionSettings{}) | ||||||
| 		got := baseReconcileLoop.validateContainerVolumeMounts(jenkins.Spec.Master.Containers[0]) | 		got := baseReconcileLoop.validateContainerVolumeMounts(jenkins.Spec.Master.Containers[0]) | ||||||
| 		assert.Equal(t, got, []string{"mountPath not set for 'example' volume mount in container ''"}) | 		assert.Equal(t, got, []string{"mountPath not set for 'example' volume mount in container ''"}) | ||||||
| 	}) | 	}) | ||||||
|  | @ -549,7 +549,7 @@ func TestValidateContainerVolumeMounts(t *testing.T) { | ||||||
| 		} | 		} | ||||||
| 		baseReconcileLoop := New(configuration.Configuration{ | 		baseReconcileLoop := New(configuration.Configuration{ | ||||||
| 			Jenkins: &jenkins, | 			Jenkins: &jenkins, | ||||||
| 		}, logf.ZapLogger(false), client.JenkinsAPIConnectionSettings{}, nil) | 		}, logf.ZapLogger(false), client.JenkinsAPIConnectionSettings{}) | ||||||
| 		got := baseReconcileLoop.validateContainerVolumeMounts(jenkins.Spec.Master.Containers[0]) | 		got := baseReconcileLoop.validateContainerVolumeMounts(jenkins.Spec.Master.Containers[0]) | ||||||
| 
 | 
 | ||||||
| 		assert.Equal(t, got, []string{"Not found volume for 'missing-volume' volume mount in container ''"}) | 		assert.Equal(t, got, []string{"Not found volume for 'missing-volume' volume mount in container ''"}) | ||||||
|  | @ -571,7 +571,7 @@ func TestValidateConfigMapVolume(t *testing.T) { | ||||||
| 		fakeClient := fake.NewFakeClient() | 		fakeClient := fake.NewFakeClient() | ||||||
| 		baseReconcileLoop := New(configuration.Configuration{ | 		baseReconcileLoop := New(configuration.Configuration{ | ||||||
| 			Client: fakeClient, | 			Client: fakeClient, | ||||||
| 		}, logf.ZapLogger(false), client.JenkinsAPIConnectionSettings{}, nil) | 		}, logf.ZapLogger(false), client.JenkinsAPIConnectionSettings{}) | ||||||
| 
 | 
 | ||||||
| 		got, err := baseReconcileLoop.validateConfigMapVolume(volume) | 		got, err := baseReconcileLoop.validateConfigMapVolume(volume) | ||||||
| 
 | 
 | ||||||
|  | @ -599,7 +599,7 @@ func TestValidateConfigMapVolume(t *testing.T) { | ||||||
| 		baseReconcileLoop := New(configuration.Configuration{ | 		baseReconcileLoop := New(configuration.Configuration{ | ||||||
| 			Client:  fakeClient, | 			Client:  fakeClient, | ||||||
| 			Jenkins: jenkins, | 			Jenkins: jenkins, | ||||||
| 		}, logf.ZapLogger(false), client.JenkinsAPIConnectionSettings{}, nil) | 		}, logf.ZapLogger(false), client.JenkinsAPIConnectionSettings{}) | ||||||
| 
 | 
 | ||||||
| 		got, err := baseReconcileLoop.validateConfigMapVolume(volume) | 		got, err := baseReconcileLoop.validateConfigMapVolume(volume) | ||||||
| 
 | 
 | ||||||
|  | @ -625,7 +625,7 @@ func TestValidateConfigMapVolume(t *testing.T) { | ||||||
| 		baseReconcileLoop := New(configuration.Configuration{ | 		baseReconcileLoop := New(configuration.Configuration{ | ||||||
| 			Client:  fakeClient, | 			Client:  fakeClient, | ||||||
| 			Jenkins: jenkins, | 			Jenkins: jenkins, | ||||||
| 		}, logf.ZapLogger(false), client.JenkinsAPIConnectionSettings{}, nil) | 		}, logf.ZapLogger(false), client.JenkinsAPIConnectionSettings{}) | ||||||
| 
 | 
 | ||||||
| 		got, err := baseReconcileLoop.validateConfigMapVolume(volume) | 		got, err := baseReconcileLoop.validateConfigMapVolume(volume) | ||||||
| 
 | 
 | ||||||
|  | @ -650,7 +650,7 @@ func TestValidateSecretVolume(t *testing.T) { | ||||||
| 		fakeClient := fake.NewFakeClient() | 		fakeClient := fake.NewFakeClient() | ||||||
| 		baseReconcileLoop := New(configuration.Configuration{ | 		baseReconcileLoop := New(configuration.Configuration{ | ||||||
| 			Client: fakeClient, | 			Client: fakeClient, | ||||||
| 		}, logf.ZapLogger(false), client.JenkinsAPIConnectionSettings{}, nil) | 		}, logf.ZapLogger(false), client.JenkinsAPIConnectionSettings{}) | ||||||
| 
 | 
 | ||||||
| 		got, err := baseReconcileLoop.validateSecretVolume(volume) | 		got, err := baseReconcileLoop.validateSecretVolume(volume) | ||||||
| 
 | 
 | ||||||
|  | @ -676,7 +676,7 @@ func TestValidateSecretVolume(t *testing.T) { | ||||||
| 		baseReconcileLoop := New(configuration.Configuration{ | 		baseReconcileLoop := New(configuration.Configuration{ | ||||||
| 			Client:  fakeClient, | 			Client:  fakeClient, | ||||||
| 			Jenkins: jenkins, | 			Jenkins: jenkins, | ||||||
| 		}, logf.ZapLogger(false), client.JenkinsAPIConnectionSettings{}, nil) | 		}, logf.ZapLogger(false), client.JenkinsAPIConnectionSettings{}) | ||||||
| 
 | 
 | ||||||
| 		got, err := baseReconcileLoop.validateSecretVolume(volume) | 		got, err := baseReconcileLoop.validateSecretVolume(volume) | ||||||
| 
 | 
 | ||||||
|  | @ -700,7 +700,7 @@ func TestValidateSecretVolume(t *testing.T) { | ||||||
| 		baseReconcileLoop := New(configuration.Configuration{ | 		baseReconcileLoop := New(configuration.Configuration{ | ||||||
| 			Client:  fakeClient, | 			Client:  fakeClient, | ||||||
| 			Jenkins: jenkins, | 			Jenkins: jenkins, | ||||||
| 		}, logf.ZapLogger(false), client.JenkinsAPIConnectionSettings{}, nil) | 		}, logf.ZapLogger(false), client.JenkinsAPIConnectionSettings{}) | ||||||
| 		got, err := baseReconcileLoop.validateSecretVolume(volume) | 		got, err := baseReconcileLoop.validateSecretVolume(volume) | ||||||
| 
 | 
 | ||||||
| 		assert.NoError(t, err) | 		assert.NoError(t, err) | ||||||
|  | @ -724,7 +724,7 @@ func TestValidateCustomization(t *testing.T) { | ||||||
| 		baseReconcileLoop := New(configuration.Configuration{ | 		baseReconcileLoop := New(configuration.Configuration{ | ||||||
| 			Jenkins: jenkins, | 			Jenkins: jenkins, | ||||||
| 			Client:  fakeClient, | 			Client:  fakeClient, | ||||||
| 		}, logf.ZapLogger(false), client.JenkinsAPIConnectionSettings{}, nil) | 		}, logf.ZapLogger(false), client.JenkinsAPIConnectionSettings{}) | ||||||
| 
 | 
 | ||||||
| 		got, err := baseReconcileLoop.validateCustomization(customization, "spec.groovyScripts") | 		got, err := baseReconcileLoop.validateCustomization(customization, "spec.groovyScripts") | ||||||
| 
 | 
 | ||||||
|  | @ -746,7 +746,7 @@ func TestValidateCustomization(t *testing.T) { | ||||||
| 		baseReconcileLoop := New(configuration.Configuration{ | 		baseReconcileLoop := New(configuration.Configuration{ | ||||||
| 			Jenkins: jenkins, | 			Jenkins: jenkins, | ||||||
| 			Client:  fakeClient, | 			Client:  fakeClient, | ||||||
| 		}, logf.ZapLogger(false), client.JenkinsAPIConnectionSettings{}, nil) | 		}, logf.ZapLogger(false), client.JenkinsAPIConnectionSettings{}) | ||||||
| 		err := fakeClient.Create(context.TODO(), secret) | 		err := fakeClient.Create(context.TODO(), secret) | ||||||
| 		require.NoError(t, err) | 		require.NoError(t, err) | ||||||
| 
 | 
 | ||||||
|  | @ -777,7 +777,7 @@ func TestValidateCustomization(t *testing.T) { | ||||||
| 		baseReconcileLoop := New(configuration.Configuration{ | 		baseReconcileLoop := New(configuration.Configuration{ | ||||||
| 			Jenkins: jenkins, | 			Jenkins: jenkins, | ||||||
| 			Client:  fakeClient, | 			Client:  fakeClient, | ||||||
| 		}, logf.ZapLogger(false), client.JenkinsAPIConnectionSettings{}, nil) | 		}, logf.ZapLogger(false), client.JenkinsAPIConnectionSettings{}) | ||||||
| 		err := fakeClient.Create(context.TODO(), secret) | 		err := fakeClient.Create(context.TODO(), secret) | ||||||
| 		require.NoError(t, err) | 		require.NoError(t, err) | ||||||
| 		err = fakeClient.Create(context.TODO(), configMap) | 		err = fakeClient.Create(context.TODO(), configMap) | ||||||
|  | @ -804,7 +804,7 @@ func TestValidateCustomization(t *testing.T) { | ||||||
| 		baseReconcileLoop := New(configuration.Configuration{ | 		baseReconcileLoop := New(configuration.Configuration{ | ||||||
| 			Jenkins: jenkins, | 			Jenkins: jenkins, | ||||||
| 			Client:  fakeClient, | 			Client:  fakeClient, | ||||||
| 		}, logf.ZapLogger(false), client.JenkinsAPIConnectionSettings{}, nil) | 		}, logf.ZapLogger(false), client.JenkinsAPIConnectionSettings{}) | ||||||
| 		err := fakeClient.Create(context.TODO(), configMap) | 		err := fakeClient.Create(context.TODO(), configMap) | ||||||
| 		require.NoError(t, err) | 		require.NoError(t, err) | ||||||
| 
 | 
 | ||||||
|  | @ -829,7 +829,7 @@ func TestValidateCustomization(t *testing.T) { | ||||||
| 		baseReconcileLoop := New(configuration.Configuration{ | 		baseReconcileLoop := New(configuration.Configuration{ | ||||||
| 			Jenkins: jenkins, | 			Jenkins: jenkins, | ||||||
| 			Client:  fakeClient, | 			Client:  fakeClient, | ||||||
| 		}, logf.ZapLogger(false), client.JenkinsAPIConnectionSettings{}, nil) | 		}, logf.ZapLogger(false), client.JenkinsAPIConnectionSettings{}) | ||||||
| 		err := fakeClient.Create(context.TODO(), secret) | 		err := fakeClient.Create(context.TODO(), secret) | ||||||
| 		require.NoError(t, err) | 		require.NoError(t, err) | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -1,6 +1,7 @@ | ||||||
| package configuration | package configuration | ||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
|  | 	"bytes" | ||||||
| 	"context" | 	"context" | ||||||
| 
 | 
 | ||||||
| 	"github.com/jenkinsci/kubernetes-operator/pkg/apis/jenkins/v1alpha2" | 	"github.com/jenkinsci/kubernetes-operator/pkg/apis/jenkins/v1alpha2" | ||||||
|  | @ -15,6 +16,9 @@ import ( | ||||||
| 	"k8s.io/apimachinery/pkg/runtime" | 	"k8s.io/apimachinery/pkg/runtime" | ||||||
| 	"k8s.io/apimachinery/pkg/types" | 	"k8s.io/apimachinery/pkg/types" | ||||||
| 	"k8s.io/client-go/kubernetes" | 	"k8s.io/client-go/kubernetes" | ||||||
|  | 	"k8s.io/client-go/kubernetes/scheme" | ||||||
|  | 	"k8s.io/client-go/rest" | ||||||
|  | 	"k8s.io/client-go/tools/remotecommand" | ||||||
| 	"sigs.k8s.io/controller-runtime/pkg/client" | 	"sigs.k8s.io/controller-runtime/pkg/client" | ||||||
| 	"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" | 	"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" | ||||||
| ) | ) | ||||||
|  | @ -26,6 +30,7 @@ type Configuration struct { | ||||||
| 	Notifications *chan event.Event | 	Notifications *chan event.Event | ||||||
| 	Jenkins       *v1alpha2.Jenkins | 	Jenkins       *v1alpha2.Jenkins | ||||||
| 	Scheme        *runtime.Scheme | 	Scheme        *runtime.Scheme | ||||||
|  | 	Config        *rest.Config | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // RestartJenkinsMasterPod terminate Jenkins master pod and notifies about it
 | // RestartJenkinsMasterPod terminate Jenkins master pod and notifies about it
 | ||||||
|  | @ -111,3 +116,37 @@ func (c *Configuration) CreateOrUpdateResource(obj metav1.Object) error { | ||||||
| 
 | 
 | ||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | // Exec executes command in the given pod and it's container
 | ||||||
|  | func (c *Configuration) Exec(podName, containerName string, command []string) (stdout, stderr bytes.Buffer, err error) { | ||||||
|  | 	req := c.ClientSet.CoreV1().RESTClient().Post(). | ||||||
|  | 		Resource("pods"). | ||||||
|  | 		Name(podName). | ||||||
|  | 		Namespace(c.Jenkins.Namespace). | ||||||
|  | 		SubResource("exec") | ||||||
|  | 	req.VersionedParams(&corev1.PodExecOptions{ | ||||||
|  | 		Command:   command, | ||||||
|  | 		Container: containerName, | ||||||
|  | 		Stdin:     false, | ||||||
|  | 		Stdout:    true, | ||||||
|  | 		Stderr:    true, | ||||||
|  | 		TTY:       false, | ||||||
|  | 	}, scheme.ParameterCodec) | ||||||
|  | 
 | ||||||
|  | 	exec, err := remotecommand.NewSPDYExecutor(c.Config, "POST", req.URL()) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return stdout, stderr, stackerr.Wrap(err, "pod exec error while creating Executor") | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	err = exec.Stream(remotecommand.StreamOptions{ | ||||||
|  | 		Stdin:  nil, | ||||||
|  | 		Stdout: &stdout, | ||||||
|  | 		Stderr: &stderr, | ||||||
|  | 		Tty:    false, | ||||||
|  | 	}) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return stdout, stderr, stackerr.Wrapf(err, "pod exec error operation on stream: stdout '%s' stderr '%s'", stdout.String(), stderr.String()) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return | ||||||
|  | } | ||||||
|  |  | ||||||
|  | @ -12,7 +12,6 @@ import ( | ||||||
| 	"github.com/jenkinsci/kubernetes-operator/pkg/controller/jenkins/groovy" | 	"github.com/jenkinsci/kubernetes-operator/pkg/controller/jenkins/groovy" | ||||||
| 
 | 
 | ||||||
| 	"github.com/go-logr/logr" | 	"github.com/go-logr/logr" | ||||||
| 	"k8s.io/client-go/rest" |  | ||||||
| 	"sigs.k8s.io/controller-runtime/pkg/reconcile" | 	"sigs.k8s.io/controller-runtime/pkg/reconcile" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
|  | @ -21,22 +20,20 @@ type ReconcileUserConfiguration struct { | ||||||
| 	configuration.Configuration | 	configuration.Configuration | ||||||
| 	jenkinsClient jenkinsclient.Jenkins | 	jenkinsClient jenkinsclient.Jenkins | ||||||
| 	logger        logr.Logger | 	logger        logr.Logger | ||||||
| 	config        rest.Config |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // New create structure which takes care of user configuration
 | // New create structure which takes care of user configuration
 | ||||||
| func New(configuration configuration.Configuration, jenkinsClient jenkinsclient.Jenkins, logger logr.Logger, config rest.Config) *ReconcileUserConfiguration { | func New(configuration configuration.Configuration, jenkinsClient jenkinsclient.Jenkins, logger logr.Logger) *ReconcileUserConfiguration { | ||||||
| 	return &ReconcileUserConfiguration{ | 	return &ReconcileUserConfiguration{ | ||||||
| 		Configuration: configuration, | 		Configuration: configuration, | ||||||
| 		jenkinsClient: jenkinsClient, | 		jenkinsClient: jenkinsClient, | ||||||
| 		logger:        logger, | 		logger:        logger, | ||||||
| 		config:        config, |  | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Reconcile it's a main reconciliation loop for user supplied configuration
 | // Reconcile it's a main reconciliation loop for user supplied configuration
 | ||||||
| func (r *ReconcileUserConfiguration) Reconcile() (reconcile.Result, error) { | func (r *ReconcileUserConfiguration) Reconcile() (reconcile.Result, error) { | ||||||
| 	backupAndRestore := backuprestore.New(r.Client, r.ClientSet, r.logger, r.Configuration.Jenkins, r.config) | 	backupAndRestore := backuprestore.New(r.Configuration, r.logger) | ||||||
| 
 | 
 | ||||||
| 	result, err := r.ensureSeedJobs() | 	result, err := r.ensureSeedJobs() | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
|  |  | ||||||
|  | @ -8,7 +8,7 @@ import ( | ||||||
| 
 | 
 | ||||||
| // Validate validates Jenkins CR Spec section
 | // Validate validates Jenkins CR Spec section
 | ||||||
| func (r *ReconcileUserConfiguration) Validate(jenkins *v1alpha2.Jenkins) ([]string, error) { | func (r *ReconcileUserConfiguration) Validate(jenkins *v1alpha2.Jenkins) ([]string, error) { | ||||||
| 	backupAndRestore := backuprestore.New(r.Client, r.ClientSet, r.logger, r.Configuration.Jenkins, r.config) | 	backupAndRestore := backuprestore.New(r.Configuration, r.logger) | ||||||
| 	if msg := backupAndRestore.Validate(); msg != nil { | 	if msg := backupAndRestore.Validate(); msg != nil { | ||||||
| 		return msg, nil | 		return msg, nil | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | @ -232,10 +232,11 @@ func (r *ReconcileJenkins) reconcile(request reconcile.Request, logger logr.Logg | ||||||
| 		Notifications: r.notificationEvents, | 		Notifications: r.notificationEvents, | ||||||
| 		Jenkins:       jenkins, | 		Jenkins:       jenkins, | ||||||
| 		Scheme:        r.scheme, | 		Scheme:        r.scheme, | ||||||
|  | 		Config:        &r.config, | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	// Reconcile base configuration
 | 	// Reconcile base configuration
 | ||||||
| 	baseConfiguration := base.New(config, logger, r.jenkinsAPIConnectionSettings, &r.config) | 	baseConfiguration := base.New(config, logger, r.jenkinsAPIConnectionSettings) | ||||||
| 
 | 
 | ||||||
| 	var baseMessages []string | 	var baseMessages []string | ||||||
| 	baseMessages, err = baseConfiguration.Validate(jenkins) | 	baseMessages, err = baseConfiguration.Validate(jenkins) | ||||||
|  | @ -289,7 +290,7 @@ func (r *ReconcileJenkins) reconcile(request reconcile.Request, logger logr.Logg | ||||||
| 		logger.Info(message) | 		logger.Info(message) | ||||||
| 	} | 	} | ||||||
| 	// Reconcile user configuration
 | 	// Reconcile user configuration
 | ||||||
| 	userConfiguration := user.New(config, jenkinsClient, logger, r.config) | 	userConfiguration := user.New(config, jenkinsClient, logger) | ||||||
| 
 | 
 | ||||||
| 	var messages []string | 	var messages []string | ||||||
| 	messages, err = userConfiguration.Validate(jenkins) | 	messages, err = userConfiguration.Validate(jenkins) | ||||||
|  | @ -496,6 +497,18 @@ func (r *ReconcileJenkins) setDefaults(jenkins *v1alpha2.Jenkins, logger logr.Lo | ||||||
| 		jenkins.Spec.Master.SecurityContext = &securityContext | 		jenkins.Spec.Master.SecurityContext = &securityContext | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	if reflect.DeepEqual(jenkins.Spec.JenkinsAPISettings, v1alpha2.JenkinsAPISettings{}) { | ||||||
|  | 		logger.Info("Setting default Jenkins API settings") | ||||||
|  | 		changed = true | ||||||
|  | 		jenkins.Spec.JenkinsAPISettings = v1alpha2.JenkinsAPISettings{AuthorizationStrategy: v1alpha2.CreateUserAuthorizationStrategy} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if jenkins.Spec.JenkinsAPISettings.AuthorizationStrategy == "" { | ||||||
|  | 		logger.Info("Setting default Jenkins API settings authorization strategy") | ||||||
|  | 		changed = true | ||||||
|  | 		jenkins.Spec.JenkinsAPISettings.AuthorizationStrategy = v1alpha2.CreateUserAuthorizationStrategy | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	if changed { | 	if changed { | ||||||
| 		return changed, errors.WithStack(r.client.Update(context.TODO(), jenkins)) | 		return changed, errors.WithStack(r.client.Update(context.TODO(), jenkins)) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | @ -70,7 +70,7 @@ func createJenkinsAPIClient(jenkins *v1alpha2.Jenkins, hostname string, port int | ||||||
| 		UseNodePort: useNodePort, | 		UseNodePort: useNodePort, | ||||||
| 	}.BuildJenkinsAPIUrl(service.Name, service.Namespace, service.Spec.Ports[0].Port, service.Spec.Ports[0].NodePort) | 	}.BuildJenkinsAPIUrl(service.Name, service.Namespace, service.Spec.Ports[0].Port, service.Spec.Ports[0].NodePort) | ||||||
| 
 | 
 | ||||||
| 	return jenkinsclient.New( | 	return jenkinsclient.NewUserAndPasswordAuthorization( | ||||||
| 		jenkinsAPIURL, | 		jenkinsAPIURL, | ||||||
| 		string(adminSecret.Data[resources.OperatorCredentialsSecretUserNameKey]), | 		string(adminSecret.Data[resources.OperatorCredentialsSecretUserNameKey]), | ||||||
| 		string(adminSecret.Data[resources.OperatorCredentialsSecretTokenKey]), | 		string(adminSecret.Data[resources.OperatorCredentialsSecretTokenKey]), | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue