Small code improvements
This commit is contained in:
parent
64f6fa68eb
commit
89c46a1720
|
|
@ -32,4 +32,3 @@ spec:
|
||||||
fieldPath: metadata.name
|
fieldPath: metadata.name
|
||||||
- name: OPERATOR_NAME
|
- name: OPERATOR_NAME
|
||||||
value: "jenkins-operator"
|
value: "jenkins-operator"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -424,7 +424,7 @@ spec:
|
||||||
- name: JENKINS_HOME
|
- name: JENKINS_HOME
|
||||||
value: /jenkins-home
|
value: /jenkins-home
|
||||||
- name: BACKUP_COUNT
|
- name: BACKUP_COUNT
|
||||||
value: "2" # keep only the 2 most recent backups
|
value: "3" # keep only the 2 most recent backups
|
||||||
image: virtuslab/jenkins-operator-backup-pvc:v0.0.5 # look at backup/pvc directory
|
image: virtuslab/jenkins-operator-backup-pvc:v0.0.5 # look at backup/pvc directory
|
||||||
imagePullPolicy: IfNotPresent
|
imagePullPolicy: IfNotPresent
|
||||||
volumeMounts:
|
volumeMounts:
|
||||||
|
|
|
||||||
|
|
@ -569,7 +569,7 @@ spec:
|
||||||
- name: JENKINS_HOME
|
- name: JENKINS_HOME
|
||||||
value: /jenkins-home
|
value: /jenkins-home
|
||||||
- name: BACKUP_COUNT
|
- name: BACKUP_COUNT
|
||||||
value: "2" # keep only the 2 most recent backups
|
value: "3" # keep only the 2 most recent backups
|
||||||
image: virtuslab/jenkins-operator-backup-pvc:v0.0.5 # look at backup/pvc directory
|
image: virtuslab/jenkins-operator-backup-pvc:v0.0.5 # look at backup/pvc directory
|
||||||
imagePullPolicy: IfNotPresent
|
imagePullPolicy: IfNotPresent
|
||||||
volumeMounts:
|
volumeMounts:
|
||||||
|
|
|
||||||
|
|
@ -17,8 +17,8 @@ type JenkinsSpec struct {
|
||||||
// +optional
|
// +optional
|
||||||
SeedJobs []SeedJob `json:"seedJobs,omitempty"`
|
SeedJobs []SeedJob `json:"seedJobs,omitempty"`
|
||||||
|
|
||||||
// Notifications defines services which are used to inform about Jenkins status
|
// Notifications defines list of a services which are used to inform about Jenkins status
|
||||||
// Can be used to integrate chat services like Slack or Email services like Mailgun
|
// Can be used to integrate chat services like Slack, Microsoft MicrosoftTeams or Mailgun
|
||||||
Notifications []Notification `json:"notifications,omitempty"`
|
Notifications []Notification `json:"notifications,omitempty"`
|
||||||
|
|
||||||
// Service is Kubernetes service of Jenkins master HTTP pod
|
// Service is Kubernetes service of Jenkins master HTTP pod
|
||||||
|
|
@ -54,29 +54,40 @@ type JenkinsSpec struct {
|
||||||
ConfigurationAsCode ConfigurationAsCode `json:"configurationAsCode,omitempty"`
|
ConfigurationAsCode ConfigurationAsCode `json:"configurationAsCode,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Notification is info sending service about Jenkins Operator
|
// NotificationLogLevel defines logging level of Notification
|
||||||
|
type NotificationLogLevel string
|
||||||
|
|
||||||
|
const (
|
||||||
|
// NotificationLogLevelWarning - Only Warnings
|
||||||
|
NotificationLogLevelWarning NotificationLogLevel = "warning"
|
||||||
|
|
||||||
|
// NotificationLogLevelInfo - Only info
|
||||||
|
NotificationLogLevelInfo NotificationLogLevel = "info"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Notification is a service configuration used to send notifications about Jenkins status
|
||||||
type Notification struct {
|
type Notification struct {
|
||||||
LoggingLevel JenkinsNotificationLogLevel `json:"loggingLevel"`
|
LoggingLevel NotificationLogLevel `json:"loggingLevel"`
|
||||||
Verbose bool `json:"verbose"`
|
Verbose bool `json:"verbose"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Slack Slack `json:"slack,omitempty"`
|
Slack *Slack `json:"slack,omitempty"`
|
||||||
Teams Teams `json:"teams,omitempty"`
|
Teams *MicrosoftTeams `json:"teams,omitempty"`
|
||||||
Mailgun Mailgun `json:"mailgun,omitempty"`
|
Mailgun *Mailgun `json:"mailgun,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Slack is handler for Slack
|
// Slack is handler for Slack notification channel
|
||||||
type Slack struct {
|
type Slack struct {
|
||||||
// The web hook URL to Slack App
|
// The web hook URL to Slack App
|
||||||
URLSecretKeySelector SecretKeySelector `json:"urlSecretKeySelector"`
|
WebHookURLSecretKeySelector SecretKeySelector `json:"webHookURLSecretKeySelector"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Teams is handler for Microsoft Teams
|
// MicrosoftTeams is handler for Microsoft MicrosoftTeams notification channel
|
||||||
type Teams struct {
|
type MicrosoftTeams struct {
|
||||||
// The web hook URL to Teams App
|
// The web hook URL to MicrosoftTeams App
|
||||||
URLSecretKeySelector SecretKeySelector `json:"urlSecretKeySelector"`
|
WebHookURLSecretKeySelector SecretKeySelector `json:"webHookURLSecretKeySelector"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mailgun is handler for Mailgun email service
|
// Mailgun is handler for Mailgun email service notification channel
|
||||||
type Mailgun struct {
|
type Mailgun struct {
|
||||||
Domain string `json:"domain"`
|
Domain string `json:"domain"`
|
||||||
APIKeySecretKeySelector SecretKeySelector `json:"apiKeySecretKeySelector"`
|
APIKeySecretKeySelector SecretKeySelector `json:"apiKeySecretKeySelector"`
|
||||||
|
|
@ -87,9 +98,9 @@ type Mailgun struct {
|
||||||
// SecretKeySelector selects a key of a Secret.
|
// SecretKeySelector selects a key of a Secret.
|
||||||
type SecretKeySelector struct {
|
type SecretKeySelector struct {
|
||||||
// The name of the secret in the pod's namespace to select from.
|
// The name of the secret in the pod's namespace to select from.
|
||||||
corev1.LocalObjectReference `json:",inline" protobuf:"bytes,1,opt,name=localObjectReference"`
|
corev1.LocalObjectReference `json:"secret"`
|
||||||
// The key of the secret to select from. Must be a valid secret key.
|
// The key of the secret to select from. Must be a valid secret key.
|
||||||
Key string `json:"key" protobuf:"bytes,2,opt,name=key"`
|
Key string `json:"key"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Container defines Kubernetes container attributes
|
// Container defines Kubernetes container attributes
|
||||||
|
|
@ -485,17 +496,6 @@ const (
|
||||||
UsernamePasswordCredentialType JenkinsCredentialType = "usernamePassword"
|
UsernamePasswordCredentialType JenkinsCredentialType = "usernamePassword"
|
||||||
)
|
)
|
||||||
|
|
||||||
// JenkinsNotificationLogLevel defines type of Notification feature frequency of sending logger entries
|
|
||||||
type JenkinsNotificationLogLevel string
|
|
||||||
|
|
||||||
const (
|
|
||||||
// LogLevelWarning - Only Warnings
|
|
||||||
LogLevelWarning JenkinsNotificationLogLevel = "warning"
|
|
||||||
|
|
||||||
// LogLevelInfo - Only info
|
|
||||||
LogLevelInfo JenkinsNotificationLogLevel = "info"
|
|
||||||
)
|
|
||||||
|
|
||||||
// AllowedJenkinsCredentialMap contains all allowed Jenkins credentials types
|
// AllowedJenkinsCredentialMap contains all allowed Jenkins credentials types
|
||||||
var AllowedJenkinsCredentialMap = map[string]string{
|
var AllowedJenkinsCredentialMap = map[string]string{
|
||||||
string(NoJenkinsCredentialCredentialType): "",
|
string(NoJenkinsCredentialCredentialType): "",
|
||||||
|
|
|
||||||
|
|
@ -369,7 +369,9 @@ func (in *JenkinsSpec) DeepCopyInto(out *JenkinsSpec) {
|
||||||
if in.Notifications != nil {
|
if in.Notifications != nil {
|
||||||
in, out := &in.Notifications, &out.Notifications
|
in, out := &in.Notifications, &out.Notifications
|
||||||
*out = make([]Notification, len(*in))
|
*out = make([]Notification, len(*in))
|
||||||
copy(*out, *in)
|
for i := range *in {
|
||||||
|
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||||
|
}
|
||||||
}
|
}
|
||||||
in.Service.DeepCopyInto(&out.Service)
|
in.Service.DeepCopyInto(&out.Service)
|
||||||
in.SlaveService.DeepCopyInto(&out.SlaveService)
|
in.SlaveService.DeepCopyInto(&out.SlaveService)
|
||||||
|
|
@ -452,12 +454,41 @@ func (in *Mailgun) DeepCopy() *Mailgun {
|
||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
|
func (in *MicrosoftTeams) DeepCopyInto(out *MicrosoftTeams) {
|
||||||
|
*out = *in
|
||||||
|
out.WebHookURLSecretKeySelector = in.WebHookURLSecretKeySelector
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MicrosoftTeams.
|
||||||
|
func (in *MicrosoftTeams) DeepCopy() *MicrosoftTeams {
|
||||||
|
if in == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
out := new(MicrosoftTeams)
|
||||||
|
in.DeepCopyInto(out)
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
func (in *Notification) DeepCopyInto(out *Notification) {
|
func (in *Notification) DeepCopyInto(out *Notification) {
|
||||||
*out = *in
|
*out = *in
|
||||||
out.Slack = in.Slack
|
if in.Slack != nil {
|
||||||
out.Teams = in.Teams
|
in, out := &in.Slack, &out.Slack
|
||||||
out.Mailgun = in.Mailgun
|
*out = new(Slack)
|
||||||
|
**out = **in
|
||||||
|
}
|
||||||
|
if in.Teams != nil {
|
||||||
|
in, out := &in.Teams, &out.Teams
|
||||||
|
*out = new(MicrosoftTeams)
|
||||||
|
**out = **in
|
||||||
|
}
|
||||||
|
if in.Mailgun != nil {
|
||||||
|
in, out := &in.Mailgun, &out.Mailgun
|
||||||
|
*out = new(Mailgun)
|
||||||
|
**out = **in
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -591,7 +622,7 @@ func (in *Service) DeepCopy() *Service {
|
||||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
func (in *Slack) DeepCopyInto(out *Slack) {
|
func (in *Slack) DeepCopyInto(out *Slack) {
|
||||||
*out = *in
|
*out = *in
|
||||||
out.URLSecretKeySelector = in.URLSecretKeySelector
|
out.WebHookURLSecretKeySelector = in.WebHookURLSecretKeySelector
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -604,20 +635,3 @@ func (in *Slack) DeepCopy() *Slack {
|
||||||
in.DeepCopyInto(out)
|
in.DeepCopyInto(out)
|
||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
|
||||||
func (in *Teams) DeepCopyInto(out *Teams) {
|
|
||||||
*out = *in
|
|
||||||
out.URLSecretKeySelector = in.URLSecretKeySelector
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Teams.
|
|
||||||
func (in *Teams) DeepCopy() *Teams {
|
|
||||||
if in == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
out := new(Teams)
|
|
||||||
in.DeepCopyInto(out)
|
|
||||||
return out
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -127,14 +127,14 @@ func (r *ReconcileJenkinsBaseConfiguration) Reconcile() (reconcile.Result, jenki
|
||||||
return result, jenkinsClient, err
|
return result, jenkinsClient, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetJenkinsOpts put container JENKINS_OPTS env parameters in map and returns it
|
// GetJenkinsOpts gets JENKINS_OPTS env parameter, parses it's values and returns it as a map`
|
||||||
func GetJenkinsOpts(jenkins *v1alpha2.Jenkins) map[string]string {
|
func GetJenkinsOpts(jenkins v1alpha2.Jenkins) map[string]string {
|
||||||
envs := jenkins.Spec.Master.Containers[0].Env
|
envs := jenkins.Spec.Master.Containers[0].Env
|
||||||
jenkinsOpts := make(map[string]string)
|
jenkinsOpts := make(map[string]string)
|
||||||
|
|
||||||
for k, v := range envs {
|
for key, value := range envs {
|
||||||
if v.Name == "JENKINS_OPTS" {
|
if value.Name == "JENKINS_OPTS" {
|
||||||
jenkinsOptsEnv := envs[k]
|
jenkinsOptsEnv := envs[key]
|
||||||
jenkinsOptsWithDashes := jenkinsOptsEnv.Value
|
jenkinsOptsWithDashes := jenkinsOptsEnv.Value
|
||||||
if len(jenkinsOptsWithDashes) == 0 {
|
if len(jenkinsOptsWithDashes) == 0 {
|
||||||
return nil
|
return nil
|
||||||
|
|
@ -781,7 +781,7 @@ func (r *ReconcileJenkinsBaseConfiguration) ensureJenkinsClient(meta metav1.Obje
|
||||||
jenkinsURL, err := jenkinsclient.BuildJenkinsAPIUrl(
|
jenkinsURL, err := jenkinsclient.BuildJenkinsAPIUrl(
|
||||||
r.jenkins.ObjectMeta.Namespace, resources.GetJenkinsHTTPServiceName(r.jenkins), r.jenkins.Spec.Service.Port, r.local, r.minikube)
|
r.jenkins.ObjectMeta.Namespace, resources.GetJenkinsHTTPServiceName(r.jenkins), r.jenkins.Spec.Service.Port, r.local, r.minikube)
|
||||||
|
|
||||||
if prefix, ok := GetJenkinsOpts(r.jenkins)["prefix"]; ok {
|
if prefix, ok := GetJenkinsOpts(*r.jenkins)["prefix"]; ok {
|
||||||
jenkinsURL = jenkinsURL + prefix
|
jenkinsURL = jenkinsURL + prefix
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ import (
|
||||||
|
|
||||||
func TestGetJenkinsOpts(t *testing.T) {
|
func TestGetJenkinsOpts(t *testing.T) {
|
||||||
t.Run("JENKINS_OPTS is uninitialized", func(t *testing.T) {
|
t.Run("JENKINS_OPTS is uninitialized", func(t *testing.T) {
|
||||||
jenkins := &v1alpha2.Jenkins{
|
jenkins := v1alpha2.Jenkins{
|
||||||
Spec: v1alpha2.JenkinsSpec{
|
Spec: v1alpha2.JenkinsSpec{
|
||||||
Master: v1alpha2.JenkinsMaster{
|
Master: v1alpha2.JenkinsMaster{
|
||||||
Containers: []v1alpha2.Container{
|
Containers: []v1alpha2.Container{
|
||||||
|
|
@ -35,7 +35,7 @@ func TestGetJenkinsOpts(t *testing.T) {
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("JENKINS_OPTS is empty", func(t *testing.T) {
|
t.Run("JENKINS_OPTS is empty", func(t *testing.T) {
|
||||||
jenkins := &v1alpha2.Jenkins{
|
jenkins := v1alpha2.Jenkins{
|
||||||
Spec: v1alpha2.JenkinsSpec{
|
Spec: v1alpha2.JenkinsSpec{
|
||||||
Master: v1alpha2.JenkinsMaster{
|
Master: v1alpha2.JenkinsMaster{
|
||||||
Containers: []v1alpha2.Container{
|
Containers: []v1alpha2.Container{
|
||||||
|
|
@ -54,7 +54,7 @@ func TestGetJenkinsOpts(t *testing.T) {
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("JENKINS_OPTS have --prefix argument ", func(t *testing.T) {
|
t.Run("JENKINS_OPTS have --prefix argument ", func(t *testing.T) {
|
||||||
jenkins := &v1alpha2.Jenkins{
|
jenkins := v1alpha2.Jenkins{
|
||||||
Spec: v1alpha2.JenkinsSpec{
|
Spec: v1alpha2.JenkinsSpec{
|
||||||
Master: v1alpha2.JenkinsMaster{
|
Master: v1alpha2.JenkinsMaster{
|
||||||
Containers: []v1alpha2.Container{
|
Containers: []v1alpha2.Container{
|
||||||
|
|
@ -77,7 +77,7 @@ func TestGetJenkinsOpts(t *testing.T) {
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("JENKINS_OPTS have --prefix and --httpPort argument", func(t *testing.T) {
|
t.Run("JENKINS_OPTS have --prefix and --httpPort argument", func(t *testing.T) {
|
||||||
jenkins := &v1alpha2.Jenkins{
|
jenkins := v1alpha2.Jenkins{
|
||||||
Spec: v1alpha2.JenkinsSpec{
|
Spec: v1alpha2.JenkinsSpec{
|
||||||
Master: v1alpha2.JenkinsMaster{
|
Master: v1alpha2.JenkinsMaster{
|
||||||
Containers: []v1alpha2.Container{
|
Containers: []v1alpha2.Container{
|
||||||
|
|
@ -103,7 +103,7 @@ func TestGetJenkinsOpts(t *testing.T) {
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("JENKINS_OPTS have --httpPort argument", func(t *testing.T) {
|
t.Run("JENKINS_OPTS have --httpPort argument", func(t *testing.T) {
|
||||||
jenkins := &v1alpha2.Jenkins{
|
jenkins := v1alpha2.Jenkins{
|
||||||
Spec: v1alpha2.JenkinsSpec{
|
Spec: v1alpha2.JenkinsSpec{
|
||||||
Master: v1alpha2.JenkinsMaster{
|
Master: v1alpha2.JenkinsMaster{
|
||||||
Containers: []v1alpha2.Container{
|
Containers: []v1alpha2.Container{
|
||||||
|
|
@ -126,7 +126,7 @@ func TestGetJenkinsOpts(t *testing.T) {
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("JENKINS_OPTS have --httpPort=--8080 argument", func(t *testing.T) {
|
t.Run("JENKINS_OPTS have --httpPort=--8080 argument", func(t *testing.T) {
|
||||||
jenkins := &v1alpha2.Jenkins{
|
jenkins := v1alpha2.Jenkins{
|
||||||
Spec: v1alpha2.JenkinsSpec{
|
Spec: v1alpha2.JenkinsSpec{
|
||||||
Master: v1alpha2.JenkinsMaster{
|
Master: v1alpha2.JenkinsMaster{
|
||||||
Containers: []v1alpha2.Container{
|
Containers: []v1alpha2.Container{
|
||||||
|
|
|
||||||
|
|
@ -231,9 +231,9 @@ func NewJenkinsMasterContainer(jenkins *v1alpha2.Jenkins) corev1.Container {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
SecurityContext: jenkinsContainer.SecurityContext,
|
SecurityContext: jenkinsContainer.SecurityContext,
|
||||||
Env: envs,
|
Env: envs,
|
||||||
Resources: jenkinsContainer.Resources,
|
Resources: jenkinsContainer.Resources,
|
||||||
VolumeMounts: append(GetJenkinsMasterContainerBaseVolumeMounts(jenkins), jenkinsContainer.VolumeMounts...),
|
VolumeMounts: append(GetJenkinsMasterContainerBaseVolumeMounts(jenkins), jenkinsContainer.VolumeMounts...),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -61,40 +61,42 @@ func (r *ReconcileJenkinsBaseConfiguration) Validate(jenkins *v1alpha2.Jenkins)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *ReconcileJenkinsBaseConfiguration) validateImagePullSecrets() (bool, error) {
|
func (r *ReconcileJenkinsBaseConfiguration) validateImagePullSecrets() (bool, error) {
|
||||||
var err error
|
|
||||||
for _, sr := range r.jenkins.Spec.Master.ImagePullSecrets {
|
for _, sr := range r.jenkins.Spec.Master.ImagePullSecrets {
|
||||||
valid, err := r.validateImagePullSecret(sr.Name)
|
valid, err := r.validateImagePullSecret(sr.Name)
|
||||||
if err != nil || !valid {
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
if !valid {
|
||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true, err
|
return true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *ReconcileJenkinsBaseConfiguration) validateImagePullSecret(name string) (bool, error) {
|
func (r *ReconcileJenkinsBaseConfiguration) validateImagePullSecret(secretName string) (bool, error) {
|
||||||
secret := &corev1.Secret{}
|
secret := &corev1.Secret{}
|
||||||
err := r.k8sClient.Get(context.TODO(), types.NamespacedName{Name: name, Namespace: r.jenkins.ObjectMeta.Namespace}, secret)
|
err := r.k8sClient.Get(context.TODO(), types.NamespacedName{Name: secretName, Namespace: r.jenkins.ObjectMeta.Namespace}, secret)
|
||||||
if err != nil && apierrors.IsNotFound(err) {
|
if err != nil && apierrors.IsNotFound(err) {
|
||||||
r.logger.V(log.VWarn).Info(fmt.Sprintf("Secret %s not found defined in spec.master.imagePullSecrets", name))
|
r.logger.V(log.VWarn).Info(fmt.Sprintf("Secret %s not found defined in spec.master.imagePullSecrets", secretName))
|
||||||
return false, nil
|
return false, nil
|
||||||
} else if err != nil && !apierrors.IsNotFound(err) {
|
} else if err != nil && !apierrors.IsNotFound(err) {
|
||||||
return false, stackerr.WithStack(err)
|
return false, stackerr.WithStack(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if secret.Data["docker-server"] == nil {
|
if secret.Data["docker-server"] == nil {
|
||||||
r.logger.V(log.VWarn).Info(fmt.Sprintf("Secret '%s' defined in spec.master.imagePullSecrets doesn't have 'docker-server' key.", name))
|
r.logger.V(log.VWarn).Info(fmt.Sprintf("Secret '%s' defined in spec.master.imagePullSecrets doesn't have 'docker-server' key.", secretName))
|
||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
if secret.Data["docker-username"] == nil {
|
if secret.Data["docker-username"] == nil {
|
||||||
r.logger.V(log.VWarn).Info(fmt.Sprintf("Secret '%s' defined in spec.master.imagePullSecrets doesn't have 'docker-username' key.", name))
|
r.logger.V(log.VWarn).Info(fmt.Sprintf("Secret '%s' defined in spec.master.imagePullSecrets doesn't have 'docker-username' key.", secretName))
|
||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
if secret.Data["docker-password"] == nil {
|
if secret.Data["docker-password"] == nil {
|
||||||
r.logger.V(log.VWarn).Info(fmt.Sprintf("Secret '%s' defined in spec.master.imagePullSecrets doesn't have 'docker-password' key.", name))
|
r.logger.V(log.VWarn).Info(fmt.Sprintf("Secret '%s' defined in spec.master.imagePullSecrets doesn't have 'docker-password' key.", secretName))
|
||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
if secret.Data["docker-email"] == nil {
|
if secret.Data["docker-email"] == nil {
|
||||||
r.logger.V(log.VWarn).Info(fmt.Sprintf("Secret '%s' defined in spec.master.imagePullSecrets doesn't have 'docker-email' key.", name))
|
r.logger.V(log.VWarn).Info(fmt.Sprintf("Secret '%s' defined in spec.master.imagePullSecrets doesn't have 'docker-email' key.", secretName))
|
||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -40,16 +40,16 @@ const content = `
|
||||||
</body>
|
</body>
|
||||||
</html>`
|
</html>`
|
||||||
|
|
||||||
// MailGun is service for sending emails
|
// MailGun is a sending emails notification service
|
||||||
type MailGun struct {
|
type MailGun struct {
|
||||||
k8sClient k8sclient.Client
|
k8sClient k8sclient.Client
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m MailGun) getStatusColor(logLevel LoggingLevel) StatusColor {
|
func (m MailGun) getStatusColor(logLevel v1alpha2.NotificationLogLevel) StatusColor {
|
||||||
switch logLevel {
|
switch logLevel {
|
||||||
case LogInfo:
|
case v1alpha2.NotificationLogLevelInfo:
|
||||||
return "blue"
|
return "blue"
|
||||||
case LogWarn:
|
case v1alpha2.NotificationLogLevelWarning:
|
||||||
return "red"
|
return "red"
|
||||||
default:
|
default:
|
||||||
return "gray"
|
return "gray"
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ import (
|
||||||
k8sclient "sigs.k8s.io/controller-runtime/pkg/client"
|
k8sclient "sigs.k8s.io/controller-runtime/pkg/client"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Teams is Microsoft Teams Service
|
// Teams is a Microsoft MicrosoftTeams notification service
|
||||||
type Teams struct {
|
type Teams struct {
|
||||||
k8sClient k8sclient.Client
|
k8sClient k8sclient.Client
|
||||||
}
|
}
|
||||||
|
|
@ -40,11 +40,11 @@ type TeamsFact struct {
|
||||||
Value string `json:"value"`
|
Value string `json:"value"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t Teams) getStatusColor(logLevel LoggingLevel) StatusColor {
|
func (t Teams) getStatusColor(logLevel v1alpha2.NotificationLogLevel) StatusColor {
|
||||||
switch logLevel {
|
switch logLevel {
|
||||||
case LogInfo:
|
case v1alpha2.NotificationLogLevelInfo:
|
||||||
return "439FE0"
|
return "439FE0"
|
||||||
case LogWarn:
|
case v1alpha2.NotificationLogLevelWarning:
|
||||||
return "E81123"
|
return "E81123"
|
||||||
default:
|
default:
|
||||||
return "C8C8C8"
|
return "C8C8C8"
|
||||||
|
|
@ -55,7 +55,7 @@ func (t Teams) getStatusColor(logLevel LoggingLevel) StatusColor {
|
||||||
func (t Teams) Send(event Event, config v1alpha2.Notification) error {
|
func (t Teams) Send(event Event, config v1alpha2.Notification) error {
|
||||||
secret := &corev1.Secret{}
|
secret := &corev1.Secret{}
|
||||||
|
|
||||||
selector := config.Teams.URLSecretKeySelector
|
selector := config.Teams.WebHookURLSecretKeySelector
|
||||||
|
|
||||||
err := t.k8sClient.Get(context.TODO(), types.NamespacedName{Name: selector.Name, Namespace: event.Jenkins.Namespace}, secret)
|
err := t.k8sClient.Get(context.TODO(), types.NamespacedName{Name: selector.Name, Namespace: event.Jenkins.Namespace}, secret)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
||||||
|
|
@ -84,8 +84,8 @@ func TestTeams_Send(t *testing.T) {
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
err = teams.Send(event, v1alpha2.Notification{
|
err = teams.Send(event, v1alpha2.Notification{
|
||||||
Teams: v1alpha2.Teams{
|
Teams: &v1alpha2.MicrosoftTeams{
|
||||||
URLSecretKeySelector: v1alpha2.SecretKeySelector{
|
WebHookURLSecretKeySelector: v1alpha2.SecretKeySelector{
|
||||||
LocalObjectReference: corev1.LocalObjectReference{
|
LocalObjectReference: corev1.LocalObjectReference{
|
||||||
Name: testSecretName,
|
Name: testSecretName,
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -12,12 +12,6 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// LogWarn is warning log entry
|
|
||||||
LogWarn LoggingLevel = "warn"
|
|
||||||
|
|
||||||
// LogInfo is info log entry
|
|
||||||
LogInfo LoggingLevel = "info"
|
|
||||||
|
|
||||||
titleText = "Operator reconciled."
|
titleText = "Operator reconciled."
|
||||||
messageFieldName = "Message"
|
messageFieldName = "Message"
|
||||||
loggingLevelFieldName = "Logging Level"
|
loggingLevelFieldName = "Logging Level"
|
||||||
|
|
@ -33,7 +27,7 @@ var (
|
||||||
testNamespace = "default"
|
testNamespace = "default"
|
||||||
testMessage = "test-message"
|
testMessage = "test-message"
|
||||||
testMessageVerbose = "detail-test-message"
|
testMessageVerbose = "detail-test-message"
|
||||||
testLoggingLevel = LogWarn
|
testLoggingLevel = v1alpha2.NotificationLogLevelWarning
|
||||||
|
|
||||||
client = http.Client{}
|
client = http.Client{}
|
||||||
)
|
)
|
||||||
|
|
@ -48,7 +42,7 @@ type LoggingLevel string
|
||||||
type Event struct {
|
type Event struct {
|
||||||
Jenkins v1alpha2.Jenkins
|
Jenkins v1alpha2.Jenkins
|
||||||
ConfigurationType string
|
ConfigurationType string
|
||||||
LogLevel LoggingLevel
|
LogLevel v1alpha2.NotificationLogLevel
|
||||||
Message string
|
Message string
|
||||||
MessageVerbose string
|
MessageVerbose string
|
||||||
}
|
}
|
||||||
|
|
@ -65,11 +59,11 @@ func Listen(events chan Event, k8sClient k8sclient.Client) {
|
||||||
var err error
|
var err error
|
||||||
var svc service
|
var svc service
|
||||||
|
|
||||||
if notificationConfig.Slack != (v1alpha2.Slack{}) {
|
if notificationConfig.Slack != nil {
|
||||||
svc = Slack{k8sClient: k8sClient}
|
svc = Slack{k8sClient: k8sClient}
|
||||||
} else if notificationConfig.Teams != (v1alpha2.Teams{}) {
|
} else if notificationConfig.Teams != nil {
|
||||||
svc = Teams{k8sClient: k8sClient}
|
svc = Teams{k8sClient: k8sClient}
|
||||||
} else if notificationConfig.Mailgun != (v1alpha2.Mailgun{}) {
|
} else if notificationConfig.Mailgun != nil {
|
||||||
svc = MailGun{k8sClient: k8sClient}
|
svc = MailGun{k8sClient: k8sClient}
|
||||||
} else {
|
} else {
|
||||||
logger.V(log.VWarn).Info(fmt.Sprintf("Unexpected notification `%+v`", notificationConfig))
|
logger.V(log.VWarn).Info(fmt.Sprintf("Unexpected notification `%+v`", notificationConfig))
|
||||||
|
|
@ -93,7 +87,7 @@ func Listen(events chan Event, k8sClient k8sclient.Client) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func notify(svc service, event Event, manifest v1alpha2.Notification) error {
|
func notify(svc service, event Event, manifest v1alpha2.Notification) error {
|
||||||
if event.LogLevel == LogInfo && string(manifest.LoggingLevel) == string(LogWarn) {
|
if event.LogLevel == v1alpha2.NotificationLogLevelInfo && manifest.LoggingLevel == v1alpha2.NotificationLogLevelWarning {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ import (
|
||||||
k8sclient "sigs.k8s.io/controller-runtime/pkg/client"
|
k8sclient "sigs.k8s.io/controller-runtime/pkg/client"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Slack is messaging service
|
// Slack is a Slack notification service
|
||||||
type Slack struct {
|
type Slack struct {
|
||||||
k8sClient k8sclient.Client
|
k8sClient k8sclient.Client
|
||||||
}
|
}
|
||||||
|
|
@ -43,11 +43,11 @@ type SlackField struct {
|
||||||
Short bool `json:"short"`
|
Short bool `json:"short"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s Slack) getStatusColor(logLevel LoggingLevel) StatusColor {
|
func (s Slack) getStatusColor(logLevel v1alpha2.NotificationLogLevel) StatusColor {
|
||||||
switch logLevel {
|
switch logLevel {
|
||||||
case LogInfo:
|
case v1alpha2.NotificationLogLevelInfo:
|
||||||
return "#439FE0"
|
return "#439FE0"
|
||||||
case LogWarn:
|
case v1alpha2.NotificationLogLevelWarning:
|
||||||
return "danger"
|
return "danger"
|
||||||
default:
|
default:
|
||||||
return "#c8c8c8"
|
return "#c8c8c8"
|
||||||
|
|
@ -57,7 +57,7 @@ func (s Slack) getStatusColor(logLevel LoggingLevel) StatusColor {
|
||||||
// Send is function for sending directly to API
|
// Send is function for sending directly to API
|
||||||
func (s Slack) Send(event Event, config v1alpha2.Notification) error {
|
func (s Slack) Send(event Event, config v1alpha2.Notification) error {
|
||||||
secret := &corev1.Secret{}
|
secret := &corev1.Secret{}
|
||||||
selector := config.Slack.URLSecretKeySelector
|
selector := config.Slack.WebHookURLSecretKeySelector
|
||||||
|
|
||||||
err := s.k8sClient.Get(context.TODO(), types.NamespacedName{Name: selector.Name, Namespace: event.Jenkins.Namespace}, secret)
|
err := s.k8sClient.Get(context.TODO(), types.NamespacedName{Name: selector.Name, Namespace: event.Jenkins.Namespace}, secret)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
||||||
|
|
@ -84,8 +84,8 @@ func TestSlack_Send(t *testing.T) {
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
err = slack.Send(event, v1alpha2.Notification{
|
err = slack.Send(event, v1alpha2.Notification{
|
||||||
Slack: v1alpha2.Slack{
|
Slack: &v1alpha2.Slack{
|
||||||
URLSecretKeySelector: v1alpha2.SecretKeySelector{
|
WebHookURLSecretKeySelector: v1alpha2.SecretKeySelector{
|
||||||
LocalObjectReference: corev1.LocalObjectReference{
|
LocalObjectReference: corev1.LocalObjectReference{
|
||||||
Name: testSecretName,
|
Name: testSecretName,
|
||||||
},
|
},
|
||||||
|
|
@ -93,6 +93,5 @@ func TestSlack_Send(t *testing.T) {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue