Merge "Remove newline at EOF in hudson.model.UpdateCenter.xml"
diff --git a/README.rst b/README.rst
index 7dc19af..4d9b9a2 100644
--- a/README.rst
+++ b/README.rst
@@ -611,6 +611,16 @@
ssl: false
reply_to: reply_to@address.com
+Jenkins admin user email enforcement from client
+
+.. code-block:: yaml
+
+ jenkins:
+ client:
+ smtp:
+ admin_email: "My Jenkins <jenkins@myserver.com>"
+
+
Slack plugin configuration
.. code-block:: yaml
@@ -638,6 +648,18 @@
branch: master # optional, default master
implicit: true # optional default true
+Artifactory server enforcing
+
+.. code-block:: yaml
+
+ jenkins:
+ client:
+ artifactory:
+ my-artifactory-server:
+ enabled: true
+ url: https://path-to-my-library
+ credential_id: github
+
Usage
=====
diff --git a/_states/jenkins_artifactory.py b/_states/jenkins_artifactory.py
new file mode 100644
index 0000000..03a015c
--- /dev/null
+++ b/_states/jenkins_artifactory.py
@@ -0,0 +1,97 @@
+import logging
+logger = logging.getLogger(__name__)
+
+add_artifactory_groovy = u"""\
+import jenkins.model.*
+import org.jfrog.*
+import org.jfrog.hudson.*
+def inst = Jenkins.getInstance()
+def desc = inst.getDescriptor("org.jfrog.hudson.ArtifactoryBuilder")
+def server = desc.getArtifactoryServers().find{{it -> it.name.equals("{name}")}}
+if(server &&
+ server.getName().equals("{name}") &&
+ server.getUrl().equals("{serverUrl}") &&
+ server.getDeployerCredentialsConfig().getCredentialsId().equals("{credentialsId}") &&
+ server.getResolverCredentialsConfig().getCredentialsId().equals("{credentialsId}")){{
+ print("EXISTS")
+}}else{{
+ desc.getArtifactoryServers().removeIf{{it -> it.name.equals("{name}")}}
+ def newServer = new ArtifactoryServer(
+ "{name}",
+ "{serverUrl}",
+ new CredentialsConfig("", "", "{credentialsId}"),
+ new CredentialsConfig("", "", "{credentialsId}"),
+ 300,
+ false,
+ null)
+ desc.getArtifactoryServers().add(newServer)
+ desc.save()
+ print("ADDED/CHANGED")
+}}
+""" # noqa
+
+delete_artifactory_groovy = u"""\
+def inst = Jenkins.getInstance()
+def desc = inst.getDescriptor("org.jfrog.hudson.ArtifactoryBuilder")
+if(desc.getArtifactoryServers().removeIf{{it -> it.name.equals("{name}")}}){{
+ print("REMOVED")
+}}else{{
+ print("NOT PRESENT")
+}}
+""" # noqa
+
+
+def present(name, url, credential_id, **kwargs):
+ """
+ Jenkins artifactory present state method
+
+ :param name: artifactory server name
+ :param url: artifactory server url
+ :param credential_id: artifactory server credential id
+ :returns: salt-specified state dict
+ """
+ return _plugin_call(name, url, credential_id, add_artifactory_groovy, ["ADDED/CHANGED", "EXISTS"], **kwargs)
+
+
+def absent(name, **kwargs):
+ """
+ Jenkins artifactory present state method
+
+ :param name: artifactory server name
+ :returns: salt-specified state dict
+ """
+ return _plugin_call(name, None, None, delete_artifactory_groovy, ["REMOVED", "NOT PRESENT"], **kwargs)
+
+
+def _plugin_call(name, url, credentialsId, template, success_msgs, **kwargs):
+ test = __opts__['test'] # noqa
+ ret = {
+ 'name': name,
+ 'changes': {},
+ 'result': False,
+ 'comment': '',
+ }
+ result = False
+ if test:
+ status = success_msgs[0]
+ ret['changes'][name] = status
+ ret['comment'] = 'Jenkins artifactory server %s %s' % (
+ name, status.lower())
+ else:
+ call_result = __salt__['jenkins_common.call_groovy_script'](
+ template, {"name": name, "serverUrl": url, "credentialsId": credentialsId})
+ if call_result["code"] == 200 and call_result["msg"] in success_msgs:
+ status = call_result["msg"]
+ if status == success_msgs[0]:
+ ret['changes'][name] = status
+ ret['comment'] = 'Jenkins artifactory server %s %s' % (
+ name, status.lower())
+ result = True
+ else:
+ status = 'FAILED'
+ logger.error(
+ "Jenkins artifactory API call failure: %s", call_result["msg"])
+ ret['comment'] = 'Jenkins artifactory API call failure: %s' % (call_result[
+ "msg"])
+ ret['result'] = None if test else result
+ return ret
diff --git a/_states/jenkins_lib.py b/_states/jenkins_lib.py
index 6492623..10ef75f 100644
--- a/_states/jenkins_lib.py
+++ b/_states/jenkins_lib.py
@@ -28,8 +28,12 @@
LibraryConfiguration library = new LibraryConfiguration("{lib_name}", retriever)
library.setDefaultVersion("{branch}")
library.setImplicit({implicit})
- globalLibsDesc.get().getLibraries().removeIf{{ it.name.equals("{lib_name}")}}
- globalLibsDesc.get().getLibraries().add(library)
+ if(globalLibsDesc.get().getLibraries().isEmpty()){{
+ globalLibsDesc.get().setLibraries([library])
+ }}else{{
+ globalLibsDesc.get().getLibraries().removeIf{{ it.name.equals("{lib_name}")}}
+ globalLibsDesc.get().getLibraries().add(library)
+ }}
print("SUCCESS")
}}
""" # noqa
diff --git a/_states/jenkins_smtp.py b/_states/jenkins_smtp.py
index 48e19c4..969019c 100644
--- a/_states/jenkins_smtp.py
+++ b/_states/jenkins_smtp.py
@@ -2,25 +2,44 @@
logger = logging.getLogger(__name__)
set_smtp_groovy = """\
-def desc = Jenkins.getInstance().getDescriptor("hudson.tasks.Mailer")
-if(desc.getSmtpServer().equals("{host}") &&
- desc.getSmtpAuthUserName().equals("{username}") &&
- desc.getSmtpAuthPassword().toString().equals("{password}") &&
- desc.getSmtpPort().equals("{port}") &&
- desc.getUseSsl() == {ssl} &&
- desc.getCharset().equals("{charset}") &&
- (!{reply_to_exists} || desc.getReplyAddress().equals("{reply_to}"))){{
- print("EXISTS")
-}}else{{
- desc.setSmtpAuth("{username}", "{password}")
- desc.setSmtpHost("{host}")
- desc.setUseSsl({ssl})
- desc.setSmtpPort("{port}")
- desc.setCharset("{charset}")
- if({reply_to_exists}){{
- desc.setReplyToAddress("{reply_to}")
+def result = ""
+for(desc in [Jenkins.getInstance().getDescriptor("hudson.plugins.emailext.ExtendedEmailPublisher"),Jenkins.getInstance().getDescriptor("hudson.tasks.Mailer")]){{
+ if(desc.getSmtpServer().equals("{host}") &&
+ ((desc instanceof hudson.plugins.emailext.ExtendedEmailPublisherDescriptor && desc.getSmtpAuthUsername().equals("{username}")) ||
+ (desc instanceof hudson.tasks.Mailer$DescriptorImpl && desc.getSmtpAuthUserName().equals("{username}"))) &&
+ desc.getSmtpAuthPassword().toString().equals("{password}") &&
+ desc.getSmtpPort().equals("{port}") &&
+ desc.getUseSsl() == {ssl} &&
+ desc.getCharset().equals("{charset}") &&
+ (!{reply_to_exists} || desc.getReplyAddress().equals("{reply_to}"))){{
+ result = "EXISTS"
+ }}else{{
+ desc.setSmtpAuth("{username}", "{password}")
+ desc.setUseSsl({ssl})
+ if(desc instanceof hudson.plugins.emailext.ExtendedEmailPublisherDescriptor){{
+ desc.setSmtpServer("{host}")
+ }}else{{
+ desc.setSmtpHost("{host}")
+ }}
+ desc.setSmtpPort("{port}")
+ desc.setCharset("{charset}")
+ if({reply_to_exists}){{
+ desc.setReplyToAddress("{reply_to}")
+ }}
+ desc.save()
+ result = "SUCCESS"
}}
- desc.save()
+}}
+print(result)
+""" # noqa
+
+set_admin_email_groovy = """
+def jenkinsLocationConfiguration = JenkinsLocationConfiguration.get()
+if(jenkinsLocationConfiguration.getAdminAddress().equals("{email}")){{
+ print("EXISTS")
+}}else{{
+ jenkinsLocationConfiguration.setAdminAddress("{email}")
+ jenkinsLocationConfiguration.save()
print("SUCCESS")
}}
""" # noqa
@@ -73,3 +92,41 @@
"msg"])
ret['result'] = None if test else result
return ret
+
+
+def admin_email(name, email):
+ """
+ Jenkins Admin user email config state method
+
+ :param name: jenkins admin email
+ :returns: salt-specified state dict
+ """
+ test = __opts__['test'] # noqa
+ ret = {
+ 'name': name,
+ 'changes': {},
+ 'result': False,
+ 'comment': '',
+ }
+ result = False
+ if test:
+ status = "SUCCESS"
+ ret['changes'][name] = status
+ ret['comment'] = 'Jenkins admin email config %s %s' % (name, status.lower())
+ else:
+ call_result = __salt__['jenkins_common.call_groovy_script'](
+ set_admin_email_groovy, {"email": email})
+ if call_result["code"] == 200 and call_result["msg"] in ["SUCCESS", "EXISTS"]:
+ status = call_result["msg"]
+ if status == "SUCCESS":
+ ret['changes'][name] = status
+ ret['comment'] = 'Jenkins admin email config %s %s' % (name, status.lower())
+ result = True
+ else:
+ status = 'FAILED'
+ logger.error(
+ "Jenkins admin email API call failure: %s", call_result["msg"])
+ ret['comment'] = 'Jenkins admin email API call failure: %s' % (call_result[
+ "msg"])
+ ret['result'] = None if test else result
+ return ret
diff --git a/jenkins/client/_job.sls b/jenkins/client/_job.sls
index 003a11a..1a8e6df 100644
--- a/jenkins/client/_job.sls
+++ b/jenkins/client/_job.sls
@@ -20,7 +20,6 @@
- config: {{ client.dir.jenkins_jobs_root }}/{{ job_name }}.xml
- watch:
- file: jenkins_job_{{ job_name }}_definition
- - file: /etc/salt/minion.d/_jenkins.conf
{%- else %}
@@ -33,7 +32,5 @@
jenkins_job_{{ job_name }}_absent:
jenkins_job.absent:
- name: {{ job_name }}
- - watch:
- - file: /etc/salt/minion.d/_jenkins.conf
{%- endif %}
diff --git a/jenkins/client/artifactory.sls b/jenkins/client/artifactory.sls
new file mode 100644
index 0000000..7f06e20
--- /dev/null
+++ b/jenkins/client/artifactory.sls
@@ -0,0 +1,14 @@
+{% from "jenkins/map.jinja" import client with context %}
+{% for name, artifactory in client.get('artifactory',{}).iteritems() %}
+{% if artifactory.get('enabled', True) %}
+jenkins_artifactory_server_{{ name }}:
+ jenkins_artifactory.present:
+ - name: {{ artifactory.get('name', name) }}
+ - url: {{ artifactory.get('url', '') }}
+ - credential_id: {{ artifactory.get('credential_id', '') }}
+{% else %}
+jenkins_artifactory_server_{{ name }}_disable:
+ jenkins_artifactory.absent:
+ - name: {{ artifactory.get('name', name) }}
+{% endif %}
+{% endfor %}
\ No newline at end of file
diff --git a/jenkins/client/init.sls b/jenkins/client/init.sls
index 553fe6b..d93963f 100644
--- a/jenkins/client/init.sls
+++ b/jenkins/client/init.sls
@@ -44,17 +44,15 @@
{%- if client.approved_scripts is defined %}
- jenkins.client.approval
{%- endif %}
+{%- if client.artifactory is defined %}
+ - jenkins.client.artifactory
+{%- endif %}
jenkins_client_install:
pkg.installed:
- names: {{ client.pkgs }}
-/etc/salt/minion.d/_jenkins.conf:
- file.managed:
- - source: salt://jenkins/files/_jenkins.conf
- - template: jinja
-
jenkins_client_dirs:
file.directory:
- names:
diff --git a/jenkins/client/smtp.sls b/jenkins/client/smtp.sls
index ee3a577..ae378eb 100644
--- a/jenkins/client/smtp.sls
+++ b/jenkins/client/smtp.sls
@@ -10,3 +10,9 @@
- ssl: {{ client.smtp.get('ssl', '') }}
- charset: {{ client.smtp.get('charset', '') }}
{%- endif %}
+
+{%- if client.smtp is defined and client.smtp.admin_email is defined %}
+set_jenkins_admin_email:
+ jenkins_smtp.admin_email:
+ - email: {{ client.smtp.admin_email }}
+{%- endif %}
diff --git a/jenkins/files/_jenkins.conf b/jenkins/files/_jenkins.conf
deleted file mode 100644
index 0079d74..0000000
--- a/jenkins/files/_jenkins.conf
+++ /dev/null
@@ -1,9 +0,0 @@
-{%- from "jenkins/map.jinja" import client with context %}
-jenkins:
- url: "{{ client.master.get('proto', 'http') }}://{{ client.master.host }}:{{ client.master.port }}"
- {%- if client.master.api_key is defined %}
- api_key: {{ client.master.api_key }}
- {%- else %}
- user: {{ client.master.get('username', 'admin') }}
- password: {{ client.master.get('password', 'dummy') }}
- {%- endif %}
diff --git a/jenkins/master/service.sls b/jenkins/master/service.sls
index 8dcd8d7..b5a1215 100644
--- a/jenkins/master/service.sls
+++ b/jenkins/master/service.sls
@@ -89,8 +89,8 @@
jenkins_service_running:
cmd.wait:
- - name: "i=0; while true; do curl -s -f http://localhost:{{ master.http.port }} >/dev/null && exit 0; [ $i -gt 60 ] && exit 1; sleep 5; done"
+ - name: "i=0; while true; do curl -s -f http://localhost:{{ master.http.port }}/login >/dev/null && exit 0; [ $i -gt 60 ] && exit 1; sleep 5; done"
- watch:
- service: jenkins_master_service
-{%- endif %}
\ No newline at end of file
+{%- endif %}
diff --git a/jenkins/meta/salt.yml b/jenkins/meta/salt.yml
new file mode 100644
index 0000000..b46fdb5
--- /dev/null
+++ b/jenkins/meta/salt.yml
@@ -0,0 +1,13 @@
+minion:
+ {%- if pillar.get('jenkins', {}).get('client') %}
+ jenkins:
+ {%- from "jenkins/map.jinja" import client with context %}
+ jenkins:
+ url: "{{ client.master.get('proto', 'http') }}://{{ client.master.host }}:{{ client.master.port }}"
+ {%- if client.master.api_key is defined %}
+ api_key: {{ client.master.api_key }}
+ {%- else %}
+ user: {{ client.master.get('username', 'admin') }}
+ password: {{ client.master.get('password', 'dummy') }}
+ {%- endif %}
+ {%- endif %}