summaryrefslogtreecommitdiffstats
path: root/roles
diff options
context:
space:
mode:
Diffstat (limited to 'roles')
-rw-r--r--roles/ansible_tower/tasks/main.yaml3
-rw-r--r--roles/cockpit/defaults/main.yml5
-rw-r--r--roles/cockpit/meta/main.yml15
-rw-r--r--roles/cockpit/tasks/main.yml16
-rw-r--r--roles/docker_storage/README.md2
-rw-r--r--roles/docker_storage/meta/main.yml2
-rw-r--r--roles/etcd/README.md39
-rw-r--r--roles/etcd/defaults/main.yaml31
-rw-r--r--roles/etcd/handlers/main.yml3
-rw-r--r--roles/etcd/meta/main.yml20
-rw-r--r--roles/etcd/tasks/main.yml53
-rw-r--r--roles/etcd/templates/etcd.conf.j252
-rw-r--r--roles/etcd_ca/README.md34
-rw-r--r--roles/etcd_ca/meta/main.yml16
-rw-r--r--roles/etcd_ca/tasks/main.yml46
-rw-r--r--roles/etcd_ca/templates/openssl_append.j251
-rw-r--r--roles/etcd_ca/vars/main.yml3
-rw-r--r--roles/etcd_certificates/README.md34
-rw-r--r--roles/etcd_certificates/meta/main.yml16
-rw-r--r--roles/etcd_certificates/tasks/client.yml42
-rw-r--r--roles/etcd_certificates/tasks/main.yml9
-rw-r--r--roles/etcd_certificates/tasks/server.yml73
-rw-r--r--roles/etcd_certificates/vars/main.yml11
-rw-r--r--roles/fluentd_master/tasks/main.yml9
-rw-r--r--roles/lib_zabbix/README.md38
-rw-r--r--roles/lib_zabbix/library/__init__.py3
-rw-r--r--roles/lib_zabbix/library/zbx_action.py538
-rw-r--r--roles/lib_zabbix/library/zbx_application.py142
-rw-r--r--roles/lib_zabbix/library/zbx_discoveryrule.py205
-rw-r--r--roles/lib_zabbix/library/zbx_host.py163
-rw-r--r--roles/lib_zabbix/library/zbx_hostgroup.py116
-rw-r--r--roles/lib_zabbix/library/zbx_item.py283
-rw-r--r--roles/lib_zabbix/library/zbx_itemprototype.py276
-rw-r--r--roles/lib_zabbix/library/zbx_mediatype.py168
-rw-r--r--roles/lib_zabbix/library/zbx_template.py132
-rw-r--r--roles/lib_zabbix/library/zbx_trigger.py231
-rw-r--r--roles/lib_zabbix/library/zbx_triggerprototype.py177
-rw-r--r--roles/lib_zabbix/library/zbx_user.py190
-rw-r--r--roles/lib_zabbix/library/zbx_user_media.py283
-rw-r--r--roles/lib_zabbix/library/zbx_usergroup.py208
-rw-r--r--roles/lib_zabbix/tasks/create_template.yml101
-rw-r--r--roles/lib_zabbix/tasks/create_user.yml11
-rw-r--r--roles/nickhammond.logrotate/.travis.yml14
-rw-r--r--roles/nickhammond.logrotate/README.md71
-rw-r--r--roles/nickhammond.logrotate/meta/.galaxy_install_info1
-rw-r--r--roles/nickhammond.logrotate/meta/main.yml15
-rw-r--r--roles/nickhammond.logrotate/tasks/main.yml10
-rw-r--r--roles/nickhammond.logrotate/templates/logrotate.d.j216
-rw-r--r--roles/nickhammond.logrotate/tests/inventory1
-rw-r--r--roles/nickhammond.logrotate/tests/test.yml18
-rw-r--r--roles/openshift_ansible_inventory/README.md4
-rw-r--r--roles/openshift_ansible_inventory/meta/main.yml2
-rw-r--r--roles/openshift_ansible_inventory/templates/multi_ec2.yaml.j26
-rw-r--r--roles/openshift_cluster_metrics/README.md36
-rw-r--r--roles/openshift_cluster_metrics/files/cluster-metrics/grafana.yaml53
-rw-r--r--roles/openshift_cluster_metrics/files/cluster-metrics/heapster-serviceaccount.yaml4
-rw-r--r--roles/openshift_cluster_metrics/files/cluster-metrics/heapster.yaml30
-rw-r--r--roles/openshift_cluster_metrics/files/cluster-metrics/influxdb.yaml67
-rw-r--r--roles/openshift_cluster_metrics/tasks/main.yml50
-rw-r--r--roles/openshift_common/README.md10
-rw-r--r--roles/openshift_common/defaults/main.yml2
-rw-r--r--roles/openshift_common/tasks/main.yml6
-rw-r--r--roles/openshift_common/vars/main.yml2
-rw-r--r--roles/openshift_examples/README.md49
-rw-r--r--roles/openshift_examples/defaults/main.yml18
-rwxr-xr-xroles/openshift_examples/examples-sync.sh37
-rw-r--r--roles/openshift_examples/files/examples/db-templates/mongodb-ephemeral-template.json184
-rw-r--r--roles/openshift_examples/files/examples/db-templates/mongodb-persistent-template.json207
-rw-r--r--roles/openshift_examples/files/examples/db-templates/mysql-ephemeral-template.json173
-rw-r--r--roles/openshift_examples/files/examples/db-templates/mysql-persistent-template.json196
-rw-r--r--roles/openshift_examples/files/examples/db-templates/postgresql-ephemeral-template.json173
-rw-r--r--roles/openshift_examples/files/examples/db-templates/postgresql-persistent-template.json196
-rw-r--r--roles/openshift_examples/files/examples/image-streams/image-streams-centos7.json285
-rw-r--r--roles/openshift_examples/files/examples/image-streams/image-streams-rhel7.json254
-rw-r--r--roles/openshift_examples/files/examples/quickstart-templates/cakephp-mysql.json378
-rw-r--r--roles/openshift_examples/files/examples/quickstart-templates/cakephp.json275
-rw-r--r--roles/openshift_examples/files/examples/quickstart-templates/dancer-mysql.json348
-rw-r--r--roles/openshift_examples/files/examples/quickstart-templates/dancer.json211
-rw-r--r--roles/openshift_examples/files/examples/quickstart-templates/django-postgresql.json346
-rw-r--r--roles/openshift_examples/files/examples/quickstart-templates/django.json254
-rw-r--r--roles/openshift_examples/files/examples/quickstart-templates/jenkins-ephemeral-template.json150
-rw-r--r--roles/openshift_examples/files/examples/quickstart-templates/jenkins-persistent-template.json173
-rw-r--r--roles/openshift_examples/files/examples/quickstart-templates/nodejs-mongodb.json346
-rw-r--r--roles/openshift_examples/files/examples/quickstart-templates/nodejs.json248
-rw-r--r--roles/openshift_examples/files/examples/quickstart-templates/rails-postgresql.json402
-rw-r--r--roles/openshift_examples/files/examples/xpaas-streams/jboss-image-streams.json100
-rw-r--r--roles/openshift_examples/files/examples/xpaas-templates/amq6-persistent.json439
-rw-r--r--roles/openshift_examples/files/examples/xpaas-templates/amq6.json410
-rw-r--r--roles/openshift_examples/files/examples/xpaas-templates/eap6-amq-persistent-sti.json646
-rw-r--r--roles/openshift_examples/files/examples/xpaas-templates/eap6-amq-sti.json609
-rw-r--r--roles/openshift_examples/files/examples/xpaas-templates/eap6-basic-sti.json304
-rw-r--r--roles/openshift_examples/files/examples/xpaas-templates/eap6-https-sti.json408
-rw-r--r--roles/openshift_examples/files/examples/xpaas-templates/eap6-mongodb-persistent-sti.json645
-rw-r--r--roles/openshift_examples/files/examples/xpaas-templates/eap6-mongodb-sti.json608
-rw-r--r--roles/openshift_examples/files/examples/xpaas-templates/eap6-mysql-persistent-sti.json651
-rw-r--r--roles/openshift_examples/files/examples/xpaas-templates/eap6-mysql-sti.json614
-rw-r--r--roles/openshift_examples/files/examples/xpaas-templates/eap6-postgresql-persistent-sti.json627
-rw-r--r--roles/openshift_examples/files/examples/xpaas-templates/eap6-postgresql-sti.json590
-rw-r--r--roles/openshift_examples/files/examples/xpaas-templates/jws-tomcat7-basic-sti.json257
-rw-r--r--roles/openshift_examples/files/examples/xpaas-templates/jws-tomcat7-https-sti.json361
-rw-r--r--roles/openshift_examples/files/examples/xpaas-templates/jws-tomcat7-mongodb-persistent-sti.json599
-rw-r--r--roles/openshift_examples/files/examples/xpaas-templates/jws-tomcat7-mongodb-sti.json562
-rw-r--r--roles/openshift_examples/files/examples/xpaas-templates/jws-tomcat7-mysql-persistent-sti.json600
-rw-r--r--roles/openshift_examples/files/examples/xpaas-templates/jws-tomcat7-mysql-sti.json563
-rw-r--r--roles/openshift_examples/files/examples/xpaas-templates/jws-tomcat7-postgresql-persistent-sti.json576
-rw-r--r--roles/openshift_examples/files/examples/xpaas-templates/jws-tomcat7-postgresql-sti.json539
-rw-r--r--roles/openshift_examples/files/examples/xpaas-templates/jws-tomcat8-basic-sti.json257
-rw-r--r--roles/openshift_examples/files/examples/xpaas-templates/jws-tomcat8-https-sti.json361
-rw-r--r--roles/openshift_examples/files/examples/xpaas-templates/jws-tomcat8-mongodb-persistent-sti.json599
-rw-r--r--roles/openshift_examples/files/examples/xpaas-templates/jws-tomcat8-mongodb-sti.json562
-rw-r--r--roles/openshift_examples/files/examples/xpaas-templates/jws-tomcat8-mysql-persistent-sti.json600
-rw-r--r--roles/openshift_examples/files/examples/xpaas-templates/jws-tomcat8-mysql-sti.json563
-rw-r--r--roles/openshift_examples/files/examples/xpaas-templates/jws-tomcat8-postgresql-persistent-sti.json576
-rw-r--r--roles/openshift_examples/files/examples/xpaas-templates/jws-tomcat8-postgresql-sti.json539
-rw-r--r--roles/openshift_examples/meta/main.yml15
-rw-r--r--roles/openshift_examples/tasks/main.yml55
-rw-r--r--roles/openshift_expand_partition/README.md87
-rw-r--r--roles/openshift_expand_partition/defaults/main.yml18
-rw-r--r--roles/openshift_expand_partition/meta/main.yml17
-rw-r--r--roles/openshift_expand_partition/tasks/main.yml14
-rwxr-xr-xroles/openshift_facts/library/openshift_facts.py293
-rw-r--r--roles/openshift_facts/tasks/main.yml5
-rw-r--r--roles/openshift_manage_node/tasks/main.yml21
-rw-r--r--roles/openshift_master/README.md14
-rw-r--r--roles/openshift_master/defaults/main.yml16
-rw-r--r--roles/openshift_master/handlers/main.yml5
-rw-r--r--roles/openshift_master/meta/main.yml2
-rw-r--r--roles/openshift_master/tasks/main.yml114
-rw-r--r--roles/openshift_master/templates/master.yaml.v1.j260
-rw-r--r--roles/openshift_master/templates/scheduler.json.j23
-rw-r--r--roles/openshift_master/templates/v1_partials/oauthConfig.j217
-rw-r--r--roles/openshift_master/vars/main.yml3
-rw-r--r--roles/openshift_master_ca/README.md (renamed from roles/openshift_register_nodes/README.md)2
-rw-r--r--roles/openshift_master_ca/meta/main.yml16
-rw-r--r--roles/openshift_master_ca/tasks/main.yml21
-rw-r--r--roles/openshift_master_ca/vars/main.yml (renamed from roles/openshift_register_nodes/vars/main.yml)6
-rw-r--r--roles/openshift_master_certificates/README.md34
-rw-r--r--roles/openshift_master_certificates/meta/main.yml16
-rw-r--r--roles/openshift_master_certificates/tasks/main.yml47
-rw-r--r--roles/openshift_master_certificates/vars/main.yml3
-rw-r--r--roles/openshift_master_cluster/README.md34
-rw-r--r--roles/openshift_master_cluster/meta/main.yml16
-rw-r--r--roles/openshift_master_cluster/tasks/configure.yml44
-rw-r--r--roles/openshift_master_cluster/tasks/configure_deferred.yml8
-rw-r--r--roles/openshift_master_cluster/tasks/main.yml13
-rw-r--r--roles/openshift_node/README.md34
-rw-r--r--roles/openshift_node/defaults/main.yml9
-rw-r--r--roles/openshift_node/handlers/main.yml8
-rw-r--r--roles/openshift_node/tasks/main.yml111
-rw-r--r--roles/openshift_node/tasks/storage_plugins/ceph.yml5
-rw-r--r--roles/openshift_node/tasks/storage_plugins/glusterfs.yml12
-rw-r--r--roles/openshift_node/tasks/storage_plugins/main.yml13
-rw-r--r--roles/openshift_node/tasks/storage_plugins/nfs.yml7
-rw-r--r--roles/openshift_node/templates/node.yaml.v1.j227
-rw-r--r--roles/openshift_node/templates/partials/kubeletArguments.j25
-rw-r--r--roles/openshift_node/vars/main.yml3
-rw-r--r--roles/openshift_node_certificates/README.md34
-rw-r--r--roles/openshift_node_certificates/meta/main.yml (renamed from roles/openshift_register_nodes/meta/main.yml)1
-rw-r--r--roles/openshift_node_certificates/tasks/main.yml (renamed from roles/openshift_register_nodes/tasks/main.yml)21
-rw-r--r--roles/openshift_node_certificates/vars/main.yml7
-rwxr-xr-xroles/openshift_register_nodes/library/kubernetes_register_node.py513
-rw-r--r--roles/openshift_registry/README.md5
-rw-r--r--roles/openshift_registry/tasks/main.yml11
-rw-r--r--roles/openshift_registry/vars/main.yml3
-rw-r--r--roles/openshift_repos/README.md2
-rw-r--r--roles/openshift_repos/files/online/repos/enterprise-v3.repo6
-rw-r--r--roles/openshift_repos/vars/main.yml7
-rw-r--r--roles/openshift_router/README.md3
-rw-r--r--roles/openshift_router/tasks/main.yml11
-rw-r--r--roles/openshift_router/vars/main.yml3
-rw-r--r--roles/openshift_serviceaccounts/tasks/main.yml26
-rw-r--r--roles/openshift_serviceaccounts/templates/serviceaccount.j24
-rw-r--r--roles/openshift_storage_nfs_lvm/README.md108
-rw-r--r--roles/openshift_storage_nfs_lvm/defaults/main.yml10
-rw-r--r--roles/openshift_storage_nfs_lvm/handlers/main.yml3
-rw-r--r--roles/openshift_storage_nfs_lvm/meta/main.yml16
-rw-r--r--roles/openshift_storage_nfs_lvm/tasks/main.yml24
-rw-r--r--roles/openshift_storage_nfs_lvm/tasks/nfs.yml16
-rw-r--r--roles/openshift_storage_nfs_lvm/templates/nfs.json.j221
-rw-r--r--roles/os_zabbix/README.md40
-rw-r--r--roles/os_zabbix/defaults/main.yml1
-rw-r--r--roles/os_zabbix/handlers/main.yml1
-rwxr-xr-xroles/os_zabbix/library/zbxapi.py370
-rw-r--r--roles/os_zabbix/meta/main.yml9
-rw-r--r--roles/os_zabbix/tasks/main.yml81
-rw-r--r--roles/os_zabbix/vars/main.yml1
-rw-r--r--roles/os_zabbix/vars/template_app_zabbix_agent.yml23
-rw-r--r--roles/os_zabbix/vars/template_app_zabbix_server.yml412
-rw-r--r--roles/os_zabbix/vars/template_docker.yml94
-rw-r--r--roles/os_zabbix/vars/template_heartbeat.yml13
-rw-r--r--roles/os_zabbix/vars/template_openshift_master.yml58
-rw-r--r--roles/os_zabbix/vars/template_openshift_node.yml44
-rw-r--r--roles/os_zabbix/vars/template_ops_tools.yml23
-rw-r--r--roles/os_zabbix/vars/template_os_linux.yml260
-rw-r--r--roles/rhel_subscribe/tasks/enterprise.yml9
-rw-r--r--roles/rhel_subscribe/tasks/main.yml29
-rw-r--r--roles/rhel_unsubscribe/tasks/main.yml5
197 files changed, 26399 insertions, 1118 deletions
diff --git a/roles/ansible_tower/tasks/main.yaml b/roles/ansible_tower/tasks/main.yaml
index c110a3b70..b7757214d 100644
--- a/roles/ansible_tower/tasks/main.yaml
+++ b/roles/ansible_tower/tasks/main.yaml
@@ -9,6 +9,7 @@
- ansible
- telnet
- ack
+ - pylint
- name: download Tower setup
get_url: url=http://releases.ansible.com/ansible-tower/setup/ansible-tower-setup-2.1.1.tar.gz dest=/opt/ force=no
@@ -38,5 +39,3 @@
regexp: "^({{ item.option }})( *)="
line: '\1\2= {{ item.value }}'
with_items: config_changes | default([], true)
-
-
diff --git a/roles/cockpit/defaults/main.yml b/roles/cockpit/defaults/main.yml
new file mode 100644
index 000000000..ffd55f1dd
--- /dev/null
+++ b/roles/cockpit/defaults/main.yml
@@ -0,0 +1,5 @@
+---
+os_firewall_use_firewalld: false
+os_firewall_allow:
+- service: cockpit-ws
+ port: 9090/tcp
diff --git a/roles/cockpit/meta/main.yml b/roles/cockpit/meta/main.yml
new file mode 100644
index 000000000..1e3948b19
--- /dev/null
+++ b/roles/cockpit/meta/main.yml
@@ -0,0 +1,15 @@
+---
+galaxy_info:
+ author: Scott Dodson
+ description: Deploy and Enable cockpit-ws plus optional plugins
+ company: Red Hat, Inc.
+ license: Apache License, Version 2.0
+ min_ansible_version: 1.7
+ platforms:
+ - name: EL
+ versions:
+ - 7
+ categories:
+ - cloud
+dependencies:
+ - { role: os_firewall }
diff --git a/roles/cockpit/tasks/main.yml b/roles/cockpit/tasks/main.yml
new file mode 100644
index 000000000..875cbad21
--- /dev/null
+++ b/roles/cockpit/tasks/main.yml
@@ -0,0 +1,16 @@
+---
+- name: Install cockpit-ws
+ yum:
+ name: "{{ item }}"
+ state: present
+ with_items:
+ - cockpit-ws
+ - cockpit-shell
+ - cockpit-bridge
+ - "{{ cockpit_plugins }}"
+
+- name: Enable cockpit-ws
+ service:
+ name: cockpit.socket
+ enabled: true
+ state: started
diff --git a/roles/docker_storage/README.md b/roles/docker_storage/README.md
index 0d8f31afc..bf0158623 100644
--- a/roles/docker_storage/README.md
+++ b/roles/docker_storage/README.md
@@ -36,4 +36,4 @@ ASL 2.0
Author Information
------------------
-Openshift operations, Red Hat, Inc
+OpenShift operations, Red Hat, Inc
diff --git a/roles/docker_storage/meta/main.yml b/roles/docker_storage/meta/main.yml
index a5d51cd3a..f5b2d53cb 100644
--- a/roles/docker_storage/meta/main.yml
+++ b/roles/docker_storage/meta/main.yml
@@ -1,6 +1,6 @@
---
galaxy_info:
- author: Openshift
+ author: OpenShift
description: Setup docker_storage options
company: Red Hat, Inc
license: ASL 2.0
diff --git a/roles/etcd/README.md b/roles/etcd/README.md
new file mode 100644
index 000000000..49207c428
--- /dev/null
+++ b/roles/etcd/README.md
@@ -0,0 +1,39 @@
+Role Name
+=========
+
+Configures an etcd cluster for an arbitrary number of hosts
+
+Requirements
+------------
+
+This role assumes it's being deployed on a RHEL/Fedora based host with package
+named 'etcd' available via yum.
+
+Role Variables
+--------------
+
+TODO
+
+Dependencies
+------------
+
+None
+
+Example Playbook
+----------------
+
+ - hosts: etcd
+ roles:
+ - { etcd }
+
+License
+-------
+
+MIT
+
+Author Information
+------------------
+
+Scott Dodson <sdodson@redhat.com>
+Adapted from https://github.com/retr0h/ansible-etcd for use on RHEL/Fedora. We
+should at some point submit a PR to merge this with that module.
diff --git a/roles/etcd/defaults/main.yaml b/roles/etcd/defaults/main.yaml
new file mode 100644
index 000000000..0f216b84e
--- /dev/null
+++ b/roles/etcd/defaults/main.yaml
@@ -0,0 +1,31 @@
+---
+etcd_interface: "{{ ansible_default_ipv4.interface }}"
+etcd_client_port: 2379
+etcd_peer_port: 2380
+etcd_peers_group: etcd
+etcd_url_scheme: http
+etcd_peer_url_scheme: http
+etcd_conf_dir: /etc/etcd
+etcd_ca_file: "{{ etcd_conf_dir }}/ca.crt"
+etcd_cert_file: "{{ etcd_conf_dir }}/server.crt"
+etcd_key_file: "{{ etcd_conf_dir }}/server.key"
+etcd_peer_ca_file: "{{ etcd_conf_dir }}/ca.crt"
+etcd_peer_cert_file: "{{ etcd_conf_dir }}/peer.crt"
+etcd_peer_key_file: "{{ etcd_conf_dir }}/peer.key"
+
+etcd_initial_cluster_state: new
+etcd_initial_cluster_token: etcd-cluster-1
+
+etcd_initial_advertise_peer_urls: "{{ etcd_peer_url_scheme }}://{{ hostvars[inventory_hostname]['ansible_' + etcd_interface]['ipv4']['address'] }}:{{ etcd_peer_port }}"
+etcd_listen_peer_urls: "{{ etcd_peer_url_scheme }}://{{ hostvars[inventory_hostname]['ansible_' + etcd_interface]['ipv4']['address'] }}:{{ etcd_peer_port }}"
+etcd_advertise_client_urls: "{{ etcd_url_scheme }}://{{ hostvars[inventory_hostname]['ansible_' + etcd_interface]['ipv4']['address'] }}:{{ etcd_client_port }}"
+etcd_listen_client_urls: "{{ etcd_url_scheme }}://{{ hostvars[inventory_hostname]['ansible_' + etcd_interface]['ipv4']['address'] }}:{{ etcd_client_port }}"
+
+etcd_data_dir: /var/lib/etcd/
+
+os_firewall_use_firewalld: False
+os_firewall_allow:
+- service: etcd
+ port: "{{etcd_client_port}}/tcp"
+- service: etcd peering
+ port: "{{ etcd_peer_port }}/tcp"
diff --git a/roles/etcd/handlers/main.yml b/roles/etcd/handlers/main.yml
new file mode 100644
index 000000000..b897913f9
--- /dev/null
+++ b/roles/etcd/handlers/main.yml
@@ -0,0 +1,3 @@
+---
+- name: restart etcd
+ service: name=etcd state=restarted
diff --git a/roles/etcd/meta/main.yml b/roles/etcd/meta/main.yml
new file mode 100644
index 000000000..92d44ef4d
--- /dev/null
+++ b/roles/etcd/meta/main.yml
@@ -0,0 +1,20 @@
+---
+# This module is based on https://github.com/retr0h/ansible-etcd with most
+# changes centered around installing from a pre-existing rpm
+# TODO: Extend https://github.com/retr0h/ansible-etcd rather than forking
+galaxy_info:
+ author: Scott Dodson
+ description: etcd management
+ company: Red Hat, Inc.
+ license: Apache License, Version 2.0
+ min_ansible_version: 1.2
+ platforms:
+ - name: EL
+ versions:
+ - 7
+ categories:
+ - cloud
+ - system
+dependencies:
+- { role: os_firewall }
+- { role: openshift_repos }
diff --git a/roles/etcd/tasks/main.yml b/roles/etcd/tasks/main.yml
new file mode 100644
index 000000000..656901409
--- /dev/null
+++ b/roles/etcd/tasks/main.yml
@@ -0,0 +1,53 @@
+---
+- name: Install etcd
+ yum: pkg=etcd-2.* state=present
+
+- name: Validate permissions on the config dir
+ file:
+ path: "{{ etcd_conf_dir }}"
+ state: directory
+ owner: etcd
+ group: etcd
+ mode: 0700
+
+- name: Validate permissions on certificate files
+ file:
+ path: "{{ item }}"
+ mode: 0600
+ group: etcd
+ owner: etcd
+ when: etcd_url_scheme == 'https'
+ with_items:
+ - "{{ etcd_ca_file }}"
+ - "{{ etcd_cert_file }}"
+ - "{{ etcd_key_file }}"
+
+- name: Validate permissions on peer certificate files
+ file:
+ path: "{{ item }}"
+ mode: 0600
+ group: etcd
+ owner: etcd
+ when: etcd_peer_url_scheme == 'https'
+ with_items:
+ - "{{ etcd_peer_ca_file }}"
+ - "{{ etcd_peer_cert_file }}"
+ - "{{ etcd_peer_key_file }}"
+
+- name: Write etcd global config file
+ template:
+ src: etcd.conf.j2
+ dest: /etc/etcd/etcd.conf
+ backup: true
+ notify:
+ - restart etcd
+
+- name: Enable etcd
+ service:
+ name: etcd
+ state: started
+ enabled: yes
+ register: start_result
+
+- pause: seconds=30
+ when: start_result | changed
diff --git a/roles/etcd/templates/etcd.conf.j2 b/roles/etcd/templates/etcd.conf.j2
new file mode 100644
index 000000000..9ac23b1dd
--- /dev/null
+++ b/roles/etcd/templates/etcd.conf.j2
@@ -0,0 +1,52 @@
+{% macro initial_cluster() -%}
+{% for host in groups[etcd_peers_group] -%}
+{% if loop.last -%}
+{{ host }}={{ etcd_peer_url_scheme }}://{{ hostvars[host]['ansible_' + etcd_interface]['ipv4']['address'] }}:{{ etcd_peer_port }}
+{%- else -%}
+{{ host }}={{ etcd_peer_url_scheme }}://{{ hostvars[host]['ansible_' + etcd_interface]['ipv4']['address'] }}:{{ etcd_peer_port }},
+{%- endif -%}
+{% endfor -%}
+{% endmacro -%}
+
+{% if groups[etcd_peers_group] and groups[etcd_peers_group] | length > 1 %}
+ETCD_NAME={{ inventory_hostname }}
+ETCD_LISTEN_PEER_URLS={{ etcd_listen_peer_urls }}
+{% else %}
+ETCD_NAME=default
+{% endif %}
+ETCD_DATA_DIR={{ etcd_data_dir }}
+#ETCD_SNAPSHOT_COUNTER="10000"
+ETCD_HEARTBEAT_INTERVAL="500"
+ETCD_ELECTION_TIMEOUT="2500"
+ETCD_LISTEN_CLIENT_URLS={{ etcd_listen_client_urls }}
+#ETCD_MAX_SNAPSHOTS="5"
+#ETCD_MAX_WALS="5"
+#ETCD_CORS=""
+
+{% if groups[etcd_peers_group] and groups[etcd_peers_group] | length > 1 %}
+#[cluster]
+ETCD_INITIAL_ADVERTISE_PEER_URLS={{ etcd_initial_advertise_peer_urls }}
+ETCD_INITIAL_CLUSTER={{ initial_cluster() }}
+ETCD_INITIAL_CLUSTER_STATE={{ etcd_initial_cluster_state }}
+ETCD_INITIAL_CLUSTER_TOKEN={{ etcd_initial_cluster_token }}
+#ETCD_DISCOVERY=""
+#ETCD_DISCOVERY_SRV=""
+#ETCD_DISCOVERY_FALLBACK="proxy"
+#ETCD_DISCOVERY_PROXY=""
+{% endif %}
+ETCD_ADVERTISE_CLIENT_URLS={{ etcd_advertise_client_urls }}
+
+#[proxy]
+#ETCD_PROXY="off"
+
+#[security]
+{% if etcd_url_scheme == 'https' -%}
+ETCD_CA_FILE={{ etcd_ca_file }}
+ETCD_CERT_FILE={{ etcd_cert_file }}
+ETCD_KEY_FILE={{ etcd_key_file }}
+{% endif -%}
+{% if etcd_peer_url_scheme == 'https' -%}
+ETCD_PEER_CA_FILE={{ etcd_peer_ca_file }}
+ETCD_PEER_CERT_FILE={{ etcd_peer_cert_file }}
+ETCD_PEER_KEY_FILE={{ etcd_peer_key_file }}
+{% endif -%}
diff --git a/roles/etcd_ca/README.md b/roles/etcd_ca/README.md
new file mode 100644
index 000000000..60a880e30
--- /dev/null
+++ b/roles/etcd_ca/README.md
@@ -0,0 +1,34 @@
+etcd_ca
+========================
+
+TODO
+
+Requirements
+------------
+
+TODO
+
+Role Variables
+--------------
+
+TODO
+
+Dependencies
+------------
+
+TODO
+
+Example Playbook
+----------------
+
+TODO
+
+License
+-------
+
+Apache License Version 2.0
+
+Author Information
+------------------
+
+Scott Dodson (sdodson@redhat.com)
diff --git a/roles/etcd_ca/meta/main.yml b/roles/etcd_ca/meta/main.yml
new file mode 100644
index 000000000..fb9280c9e
--- /dev/null
+++ b/roles/etcd_ca/meta/main.yml
@@ -0,0 +1,16 @@
+---
+galaxy_info:
+ author: Jason DeTiberus
+ description:
+ company: Red Hat, Inc.
+ license: Apache License, Version 2.0
+ min_ansible_version: 1.9
+ platforms:
+ - name: EL
+ versions:
+ - 7
+ categories:
+ - cloud
+ - system
+dependencies:
+- { role: openshift_repos }
diff --git a/roles/etcd_ca/tasks/main.yml b/roles/etcd_ca/tasks/main.yml
new file mode 100644
index 000000000..625756867
--- /dev/null
+++ b/roles/etcd_ca/tasks/main.yml
@@ -0,0 +1,46 @@
+---
+- file:
+ path: "{{ etcd_ca_dir }}/{{ item }}"
+ state: directory
+ mode: 0700
+ owner: root
+ group: root
+ with_items:
+ - certs
+ - crl
+ - fragments
+
+- command: cp /etc/pki/tls/openssl.cnf ./
+ args:
+ chdir: "{{ etcd_ca_dir }}/fragments"
+ creates: "{{ etcd_ca_dir }}/fragments/openssl.cnf"
+
+- template:
+ dest: "{{ etcd_ca_dir }}/fragments/openssl_append.cnf"
+ src: openssl_append.j2
+ backup: true
+
+- assemble:
+ src: "{{ etcd_ca_dir }}/fragments"
+ dest: "{{ etcd_ca_dir }}/openssl.cnf"
+
+- command: touch index.txt
+ args:
+ chdir: "{{ etcd_ca_dir }}"
+ creates: "{{ etcd_ca_dir }}/index.txt"
+
+- copy:
+ dest: "{{ etcd_ca_dir }}/serial"
+ content: "01"
+ force: no
+
+- command: >
+ openssl req -config openssl.cnf -newkey rsa:4096
+ -keyout ca.key -new -out ca.crt -x509 -extensions etcd_v3_ca_self
+ -batch -nodes -subj /CN=etcd-signer@{{ ansible_date_time.epoch }}
+ -days 365
+ args:
+ chdir: "{{ etcd_ca_dir }}"
+ creates: "{{ etcd_ca_dir }}/ca.crt"
+ environment:
+ SAN: ''
diff --git a/roles/etcd_ca/templates/openssl_append.j2 b/roles/etcd_ca/templates/openssl_append.j2
new file mode 100644
index 000000000..de2adaead
--- /dev/null
+++ b/roles/etcd_ca/templates/openssl_append.j2
@@ -0,0 +1,51 @@
+
+[ etcd_v3_req ]
+basicConstraints = critical,CA:FALSE
+keyUsage = digitalSignature,keyEncipherment
+subjectAltName = ${ENV::SAN}
+
+[ etcd_ca ]
+dir = {{ etcd_ca_dir }}
+crl_dir = $dir/crl
+database = $dir/index.txt
+new_certs_dir = $dir/certs
+certificate = $dir/ca.crt
+serial = $dir/serial
+private_key = $dir/ca.key
+crl_number = $dir/crlnumber
+x509_extensions = etcd_v3_ca_client
+default_days = 365
+default_md = sha256
+preserve = no
+name_opt = ca_default
+cert_opt = ca_default
+policy = policy_anything
+unique_subject = no
+copy_extensions = copy
+
+[ etcd_v3_ca_self ]
+authorityKeyIdentifier = keyid,issuer
+basicConstraints = critical,CA:TRUE,pathlen:0
+keyUsage = critical,digitalSignature,keyEncipherment,keyCertSign
+subjectKeyIdentifier = hash
+
+[ etcd_v3_ca_peer ]
+authorityKeyIdentifier = keyid,issuer:always
+basicConstraints = critical,CA:FALSE
+extendedKeyUsage = clientAuth,serverAuth
+keyUsage = digitalSignature,keyEncipherment
+subjectKeyIdentifier = hash
+
+[ etcd_v3_ca_server ]
+authorityKeyIdentifier = keyid,issuer:always
+basicConstraints = critical,CA:FALSE
+extendedKeyUsage = serverAuth
+keyUsage = digitalSignature,keyEncipherment
+subjectKeyIdentifier = hash
+
+[ etcd_v3_ca_client ]
+authorityKeyIdentifier = keyid,issuer:always
+basicConstraints = critical,CA:FALSE
+extendedKeyUsage = clientAuth
+keyUsage = digitalSignature,keyEncipherment
+subjectKeyIdentifier = hash
diff --git a/roles/etcd_ca/vars/main.yml b/roles/etcd_ca/vars/main.yml
new file mode 100644
index 000000000..901e95027
--- /dev/null
+++ b/roles/etcd_ca/vars/main.yml
@@ -0,0 +1,3 @@
+---
+etcd_conf_dir: /etc/etcd
+etcd_ca_dir: /etc/etcd/ca
diff --git a/roles/etcd_certificates/README.md b/roles/etcd_certificates/README.md
new file mode 100644
index 000000000..95f8f8aab
--- /dev/null
+++ b/roles/etcd_certificates/README.md
@@ -0,0 +1,34 @@
+OpenShift etcd certificates
+========================
+
+TODO
+
+Requirements
+------------
+
+TODO
+
+Role Variables
+--------------
+
+TODO
+
+Dependencies
+------------
+
+TODO
+
+Example Playbook
+----------------
+
+TODO
+
+License
+-------
+
+Apache License Version 2.0
+
+Author Information
+------------------
+
+Scott Dodson (sdodson@redhat.com)
diff --git a/roles/etcd_certificates/meta/main.yml b/roles/etcd_certificates/meta/main.yml
new file mode 100644
index 000000000..41370fab4
--- /dev/null
+++ b/roles/etcd_certificates/meta/main.yml
@@ -0,0 +1,16 @@
+---
+galaxy_info:
+ author: Jason DeTiberus
+ description:
+ company: Red Hat, Inc.
+ license: Apache License, Version 2.0
+ min_ansible_version: 1.8
+ platforms:
+ - name: EL
+ versions:
+ - 7
+ categories:
+ - cloud
+ - system
+dependencies:
+- { role: etcd_ca }
diff --git a/roles/etcd_certificates/tasks/client.yml b/roles/etcd_certificates/tasks/client.yml
new file mode 100644
index 000000000..28f33f442
--- /dev/null
+++ b/roles/etcd_certificates/tasks/client.yml
@@ -0,0 +1,42 @@
+---
+- name: Ensure generated_certs directory present
+ file:
+ path: "{{ etcd_generated_certs_dir }}/{{ item.etcd_cert_subdir }}"
+ state: directory
+ mode: 0700
+ with_items: etcd_needing_client_certs
+
+- name: Create the client csr
+ command: >
+ openssl req -new -keyout {{ item.etcd_cert_prefix }}client.key
+ -config {{ etcd_openssl_conf }}
+ -out {{ item.etcd_cert_prefix }}client.csr
+ -reqexts {{ etcd_req_ext }} -batch -nodes
+ -subj /CN={{ item.openshift.common.hostname }}
+ args:
+ chdir: "{{ etcd_generated_certs_dir }}/{{ item.etcd_cert_subdir }}"
+ creates: "{{ etcd_generated_certs_dir ~ '/' ~ item.etcd_cert_subdir ~ '/'
+ ~ item.etcd_cert_prefix ~ 'client.csr' }}"
+ environment:
+ SAN: "IP:{{ item.openshift.common.ip }}"
+ with_items: etcd_needing_client_certs
+
+- name: Sign and create the client crt
+ command: >
+ openssl ca -name {{ etcd_ca_name }} -config {{ etcd_openssl_conf }}
+ -out {{ item.etcd_cert_prefix }}client.crt
+ -in {{ item.etcd_cert_prefix }}client.csr
+ -batch
+ args:
+ chdir: "{{ etcd_generated_certs_dir }}/{{ item.etcd_cert_subdir }}"
+ creates: "{{ etcd_generated_certs_dir ~ '/' ~ item.etcd_cert_subdir ~ '/'
+ ~ item.etcd_cert_prefix ~ 'client.crt' }}"
+ environment:
+ SAN: ''
+ with_items: etcd_needing_client_certs
+
+- file:
+ src: "{{ etcd_ca_cert }}"
+ dest: "{{ etcd_generated_certs_dir}}/{{ item.etcd_cert_subdir }}/{{ item.etcd_cert_prefix }}ca.crt"
+ state: hard
+ with_items: etcd_needing_client_certs
diff --git a/roles/etcd_certificates/tasks/main.yml b/roles/etcd_certificates/tasks/main.yml
new file mode 100644
index 000000000..da875e8ea
--- /dev/null
+++ b/roles/etcd_certificates/tasks/main.yml
@@ -0,0 +1,9 @@
+---
+- include: client.yml
+ when: etcd_needing_client_certs is defined and etcd_needing_client_certs
+
+- include: server.yml
+ when: etcd_needing_server_certs is defined and etcd_needing_server_certs
+
+
+
diff --git a/roles/etcd_certificates/tasks/server.yml b/roles/etcd_certificates/tasks/server.yml
new file mode 100644
index 000000000..727b7fa2c
--- /dev/null
+++ b/roles/etcd_certificates/tasks/server.yml
@@ -0,0 +1,73 @@
+---
+- name: Ensure generated_certs directory present
+ file:
+ path: "{{ etcd_generated_certs_dir }}/{{ item.etcd_cert_subdir }}"
+ state: directory
+ mode: 0700
+ with_items: etcd_needing_server_certs
+
+- name: Create the server csr
+ command: >
+ openssl req -new -keyout {{ item.etcd_cert_prefix }}server.key
+ -config {{ etcd_openssl_conf }}
+ -out {{ item.etcd_cert_prefix }}server.csr
+ -reqexts {{ etcd_req_ext }} -batch -nodes
+ -subj /CN={{ item.openshift.common.hostname }}
+ args:
+ chdir: "{{ etcd_generated_certs_dir }}/{{ item.etcd_cert_subdir }}"
+ creates: "{{ etcd_generated_certs_dir ~ '/' ~ item.etcd_cert_subdir ~ '/'
+ ~ item.etcd_cert_prefix ~ 'server.csr' }}"
+ environment:
+ SAN: "IP:{{ item.openshift.common.ip }}"
+ with_items: etcd_needing_server_certs
+
+- name: Sign and create the server crt
+ command: >
+ openssl ca -name {{ etcd_ca_name }} -config {{ etcd_openssl_conf }}
+ -out {{ item.etcd_cert_prefix }}server.crt
+ -in {{ item.etcd_cert_prefix }}server.csr
+ -extensions {{ etcd_ca_exts_server }} -batch
+ args:
+ chdir: "{{ etcd_generated_certs_dir }}/{{ item.etcd_cert_subdir }}"
+ creates: "{{ etcd_generated_certs_dir ~ '/' ~ item.etcd_cert_subdir ~ '/'
+ ~ item.etcd_cert_prefix ~ 'server.crt' }}"
+ environment:
+ SAN: ''
+ with_items: etcd_needing_server_certs
+
+- name: Create the peer csr
+ command: >
+ openssl req -new -keyout {{ item.etcd_cert_prefix }}peer.key
+ -config {{ etcd_openssl_conf }}
+ -out {{ item.etcd_cert_prefix }}peer.csr
+ -reqexts {{ etcd_req_ext }} -batch -nodes
+ -subj /CN={{ item.openshift.common.hostname }}
+ args:
+ chdir: "{{ etcd_generated_certs_dir }}/{{ item.etcd_cert_subdir }}"
+ creates: "{{ etcd_generated_certs_dir ~ '/' ~ item.etcd_cert_subdir ~ '/'
+ ~ item.etcd_cert_prefix ~ 'peer.csr' }}"
+ environment:
+ SAN: "IP:{{ item.openshift.common.ip }}"
+ with_items: etcd_needing_server_certs
+
+- name: Sign and create the peer crt
+ command: >
+ openssl ca -name {{ etcd_ca_name }} -config {{ etcd_openssl_conf }}
+ -out {{ item.etcd_cert_prefix }}peer.crt
+ -in {{ item.etcd_cert_prefix }}peer.csr
+ -extensions {{ etcd_ca_exts_peer }} -batch
+ args:
+ chdir: "{{ etcd_generated_certs_dir }}/{{ item.etcd_cert_subdir }}"
+ creates: "{{ etcd_generated_certs_dir ~ '/' ~ item.etcd_cert_subdir ~ '/'
+ ~ item.etcd_cert_prefix ~ 'peer.crt' }}"
+ environment:
+ SAN: ''
+ with_items: etcd_needing_server_certs
+
+- file:
+ src: "{{ etcd_ca_cert }}"
+ dest: "{{ etcd_generated_certs_dir}}/{{ item.etcd_cert_subdir }}/{{ item.etcd_cert_prefix }}ca.crt"
+ state: hard
+ with_items: etcd_needing_server_certs
+
+
diff --git a/roles/etcd_certificates/vars/main.yml b/roles/etcd_certificates/vars/main.yml
new file mode 100644
index 000000000..0eaeeb82b
--- /dev/null
+++ b/roles/etcd_certificates/vars/main.yml
@@ -0,0 +1,11 @@
+---
+etcd_conf_dir: /etc/etcd
+etcd_ca_dir: /etc/etcd/ca
+etcd_generated_certs_dir: /etc/etcd/generated_certs
+etcd_ca_cert: "{{ etcd_ca_dir }}/ca.crt"
+etcd_ca_key: "{{ etcd_ca_dir }}/ca.key"
+etcd_openssl_conf: "{{ etcd_ca_dir }}/openssl.cnf"
+etcd_ca_name: etcd_ca
+etcd_req_ext: etcd_v3_req
+etcd_ca_exts_peer: etcd_v3_ca_peer
+etcd_ca_exts_server: etcd_v3_ca_server
diff --git a/roles/fluentd_master/tasks/main.yml b/roles/fluentd_master/tasks/main.yml
index d828db52a..55cd94460 100644
--- a/roles/fluentd_master/tasks/main.yml
+++ b/roles/fluentd_master/tasks/main.yml
@@ -39,9 +39,16 @@
owner: 'td-agent'
mode: 0444
+- name: wait for etcd to start up
+ wait_for: port=4001 delay=10
+ when: embedded_etcd | bool
+
+- name: wait for etcd peer to start up
+ wait_for: port=7001 delay=10
+ when: embedded_etcd | bool
+
- name: ensure td-agent is running
service:
name: 'td-agent'
state: started
enabled: yes
-
diff --git a/roles/lib_zabbix/README.md b/roles/lib_zabbix/README.md
new file mode 100644
index 000000000..69debc698
--- /dev/null
+++ b/roles/lib_zabbix/README.md
@@ -0,0 +1,38 @@
+zabbix
+=========
+
+Automate zabbix tasks.
+
+Requirements
+------------
+
+This requires the openshift_tools rpm be installed for the zbxapi.py library. It can be found here: https://github.com/openshift/openshift-tools under openshift_tools/monitoring/zbxapi.py for now.
+
+Role Variables
+--------------
+
+None
+
+Dependencies
+------------
+
+This depeonds on the zbxapi.py library located here: https://github.com/openshift/openshift-tools under openshift_tools/monitoring/zbxapi.py for now.
+
+Example Playbook
+----------------
+
+ - zbx_host:
+ server: zab_server
+ user: zab_user
+ password: zab_password
+ name: 'myhost'
+
+License
+-------
+
+ASL 2.0
+
+Author Information
+------------------
+
+OpenShift operations, Red Hat, Inc
diff --git a/roles/lib_zabbix/library/__init__.py b/roles/lib_zabbix/library/__init__.py
new file mode 100644
index 000000000..0c7e19e41
--- /dev/null
+++ b/roles/lib_zabbix/library/__init__.py
@@ -0,0 +1,3 @@
+'''
+ZabbixAPI ansible module
+'''
diff --git a/roles/lib_zabbix/library/zbx_action.py b/roles/lib_zabbix/library/zbx_action.py
new file mode 100644
index 000000000..d64cebae1
--- /dev/null
+++ b/roles/lib_zabbix/library/zbx_action.py
@@ -0,0 +1,538 @@
+#!/usr/bin/env python
+'''
+ Ansible module for zabbix actions
+'''
+# vim: expandtab:tabstop=4:shiftwidth=4
+#
+# Zabbix action ansible module
+#
+#
+# Copyright 2015 Red Hat Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+# This is in place because each module looks similar to each other.
+# These need duplicate code as their behavior is very similar
+# but different for each zabbix class.
+# pylint: disable=duplicate-code
+
+# pylint: disable=import-error
+from openshift_tools.monitoring.zbxapi import ZabbixAPI, ZabbixConnection, ZabbixAPIError
+
+def exists(content, key='result'):
+ ''' Check if key exists in content or the size of content[key] > 0
+ '''
+ if not content.has_key(key):
+ return False
+
+ if not content[key]:
+ return False
+
+ return True
+
+def conditions_equal(zab_conditions, user_conditions):
+ '''Compare two lists of conditions'''
+ c_type = 'conditiontype'
+ _op = 'operator'
+ val = 'value'
+ if len(user_conditions) != len(zab_conditions):
+ return False
+
+ for zab_cond, user_cond in zip(zab_conditions, user_conditions):
+ if zab_cond[c_type] != str(user_cond[c_type]) or zab_cond[_op] != str(user_cond[_op]) or \
+ zab_cond[val] != str(user_cond[val]):
+ return False
+
+ return True
+
+def filter_differences(zabbix_filters, user_filters):
+ '''Determine the differences from user and zabbix for operations'''
+ rval = {}
+ for key, val in user_filters.items():
+
+ if key == 'conditions':
+ if not conditions_equal(zabbix_filters[key], val):
+ rval[key] = val
+
+ elif zabbix_filters[key] != str(val):
+ rval[key] = val
+
+ return rval
+
+# This logic is quite complex. We are comparing two lists of dictionaries.
+# The outer for-loops allow us to descend down into both lists at the same time
+# and then walk over the key,val pairs of the incoming user dict's changes
+# or updates. The if-statements are looking at different sub-object types and
+# comparing them. The other suggestion on how to write this is to write a recursive
+# compare function but for the time constraints and for complexity I decided to go
+# this route.
+# pylint: disable=too-many-branches
+def operation_differences(zabbix_ops, user_ops):
+ '''Determine the differences from user and zabbix for operations'''
+
+ # if they don't match, take the user options
+ if len(zabbix_ops) != len(user_ops):
+ return user_ops
+
+ rval = {}
+ for zab, user in zip(zabbix_ops, user_ops):
+ for key, val in user.items():
+ if key == 'opconditions':
+ for z_cond, u_cond in zip(zab[key], user[key]):
+ if not all([str(u_cond[op_key]) == z_cond[op_key] for op_key in \
+ ['conditiontype', 'operator', 'value']]):
+ rval[key] = val
+ break
+ elif key == 'opmessage':
+ # Verify each passed param matches
+ for op_msg_key, op_msg_val in val.items():
+ if zab[key][op_msg_key] != str(op_msg_val):
+ rval[key] = val
+ break
+
+ elif key == 'opmessage_grp':
+ zab_grp_ids = set([ugrp['usrgrpid'] for ugrp in zab[key]])
+ usr_grp_ids = set([ugrp['usrgrpid'] for ugrp in val])
+ if usr_grp_ids != zab_grp_ids:
+ rval[key] = val
+
+ elif key == 'opmessage_usr':
+ zab_usr_ids = set([usr['userid'] for usr in zab[key]])
+ usr_ids = set([usr['userid'] for usr in val])
+ if usr_ids != zab_usr_ids:
+ rval[key] = val
+
+ elif zab[key] != str(val):
+ rval[key] = val
+ return rval
+
+def get_users(zapi, users):
+ '''get the mediatype id from the mediatype name'''
+ rval_users = []
+
+ for user in users:
+ content = zapi.get_content('user',
+ 'get',
+ {'filter': {'alias': user}})
+ rval_users.append({'userid': content['result'][0]['userid']})
+
+ return rval_users
+
+def get_user_groups(zapi, groups):
+ '''get the mediatype id from the mediatype name'''
+ user_groups = []
+
+ content = zapi.get_content('usergroup',
+ 'get',
+ {'search': {'name': groups}})
+
+ for usr_grp in content['result']:
+ user_groups.append({'usrgrpid': usr_grp['usrgrpid']})
+
+ return user_groups
+
+def get_mediatype_id_by_name(zapi, m_name):
+ '''get the mediatype id from the mediatype name'''
+ content = zapi.get_content('mediatype',
+ 'get',
+ {'filter': {'description': m_name}})
+
+ return content['result'][0]['mediatypeid']
+
+def get_priority(priority):
+ ''' determine priority
+ '''
+ prior = 0
+ if 'info' in priority:
+ prior = 1
+ elif 'warn' in priority:
+ prior = 2
+ elif 'avg' == priority or 'ave' in priority:
+ prior = 3
+ elif 'high' in priority:
+ prior = 4
+ elif 'dis' in priority:
+ prior = 5
+
+ return prior
+
+def get_event_source(from_src):
+ '''Translate even str into value'''
+ choices = ['trigger', 'discovery', 'auto', 'internal']
+ rval = 0
+ try:
+ rval = choices.index(from_src)
+ except ValueError as _:
+ ZabbixAPIError('Value not found for event source [%s]' % from_src)
+
+ return rval
+
+def get_status(inc_status):
+ '''determine status for action'''
+ rval = 1
+ if inc_status == 'enabled':
+ rval = 0
+
+ return rval
+
+def get_condition_operator(inc_operator):
+ ''' determine the condition operator'''
+ vals = {'=': 0,
+ '<>': 1,
+ 'like': 2,
+ 'not like': 3,
+ 'in': 4,
+ '>=': 5,
+ '<=': 6,
+ 'not in': 7,
+ }
+
+ return vals[inc_operator]
+
+def get_host_id_by_name(zapi, host_name):
+ '''Get host id by name'''
+ content = zapi.get_content('host',
+ 'get',
+ {'filter': {'name': host_name}})
+
+ return content['result'][0]['hostid']
+
+def get_trigger_value(inc_trigger):
+ '''determine the proper trigger value'''
+ rval = 1
+ if inc_trigger == 'PROBLEM':
+ rval = 1
+ else:
+ rval = 0
+
+ return rval
+
+def get_template_id_by_name(zapi, t_name):
+ '''get the template id by name'''
+ content = zapi.get_content('template',
+ 'get',
+ {'filter': {'host': t_name}})
+
+ return content['result'][0]['templateid']
+
+
+def get_host_group_id_by_name(zapi, hg_name):
+ '''Get hostgroup id by name'''
+ content = zapi.get_content('hostgroup',
+ 'get',
+ {'filter': {'name': hg_name}})
+
+ return content['result'][0]['groupid']
+
+def get_condition_type(event_source, inc_condition):
+ '''determine the condition type'''
+ c_types = {}
+ if event_source == 'trigger':
+ c_types = {'host group': 0,
+ 'host': 1,
+ 'trigger': 2,
+ 'trigger name': 3,
+ 'trigger severity': 4,
+ 'trigger value': 5,
+ 'time period': 6,
+ 'host template': 13,
+ 'application': 15,
+ 'maintenance status': 16,
+ }
+
+ elif event_source == 'discovery':
+ c_types = {'host IP': 7,
+ 'discovered service type': 8,
+ 'discovered service port': 9,
+ 'discovery status': 10,
+ 'uptime or downtime duration': 11,
+ 'received value': 12,
+ 'discovery rule': 18,
+ 'discovery check': 19,
+ 'proxy': 20,
+ 'discovery object': 21,
+ }
+
+ elif event_source == 'auto':
+ c_types = {'proxy': 20,
+ 'host name': 22,
+ 'host metadata': 24,
+ }
+
+ elif event_source == 'internal':
+ c_types = {'host group': 0,
+ 'host': 1,
+ 'host template': 13,
+ 'application': 15,
+ 'event type': 23,
+ }
+ else:
+ raise ZabbixAPIError('Unkown event source %s' % event_source)
+
+ return c_types[inc_condition]
+
+def get_operation_type(inc_operation):
+ ''' determine the correct operation type'''
+ o_types = {'send message': 0,
+ 'remote command': 1,
+ 'add host': 2,
+ 'remove host': 3,
+ 'add to host group': 4,
+ 'remove from host group': 5,
+ 'link to template': 6,
+ 'unlink from template': 7,
+ 'enable host': 8,
+ 'disable host': 9,
+ }
+
+ return o_types[inc_operation]
+
+def get_action_operations(zapi, inc_operations):
+ '''Convert the operations into syntax for api'''
+ for operation in inc_operations:
+ operation['operationtype'] = get_operation_type(operation['operationtype'])
+ if operation['operationtype'] == 0: # send message. Need to fix the
+ operation['opmessage']['mediatypeid'] = \
+ get_mediatype_id_by_name(zapi, operation['opmessage']['mediatypeid'])
+ operation['opmessage_grp'] = get_user_groups(zapi, operation.get('opmessage_grp', []))
+ operation['opmessage_usr'] = get_users(zapi, operation.get('opmessage_usr', []))
+ if operation['opmessage']['default_msg']:
+ operation['opmessage']['default_msg'] = 1
+ else:
+ operation['opmessage']['default_msg'] = 0
+
+ # NOT supported for remote commands
+ elif operation['operationtype'] == 1:
+ continue
+
+ # Handle Operation conditions:
+ # Currently there is only 1 available which
+ # is 'event acknowledged'. In the future
+ # if there are any added we will need to pass this
+ # option to a function and return the correct conditiontype
+ if operation.has_key('opconditions'):
+ for condition in operation['opconditions']:
+ if condition['conditiontype'] == 'event acknowledged':
+ condition['conditiontype'] = 14
+
+ if condition['operator'] == '=':
+ condition['operator'] = 0
+
+ if condition['value'] == 'acknowledged':
+ condition['operator'] = 1
+ else:
+ condition['operator'] = 0
+
+
+ return inc_operations
+
+def get_operation_evaltype(inc_type):
+ '''get the operation evaltype'''
+ rval = 0
+ if inc_type == 'and/or':
+ rval = 0
+ elif inc_type == 'and':
+ rval = 1
+ elif inc_type == 'or':
+ rval = 2
+ elif inc_type == 'custom':
+ rval = 3
+
+ return rval
+
+def get_action_conditions(zapi, event_source, inc_conditions):
+ '''Convert the conditions into syntax for api'''
+
+ calc_type = inc_conditions.pop('calculation_type')
+ inc_conditions['evaltype'] = get_operation_evaltype(calc_type)
+ for cond in inc_conditions['conditions']:
+
+ cond['operator'] = get_condition_operator(cond['operator'])
+ # Based on conditiontype we need to set the proper value
+ # e.g. conditiontype = hostgroup then the value needs to be a hostgroup id
+ # e.g. conditiontype = host the value needs to be a host id
+ cond['conditiontype'] = get_condition_type(event_source, cond['conditiontype'])
+ if cond['conditiontype'] == 0:
+ cond['value'] = get_host_group_id_by_name(zapi, cond['value'])
+ elif cond['conditiontype'] == 1:
+ cond['value'] = get_host_id_by_name(zapi, cond['value'])
+ elif cond['conditiontype'] == 4:
+ cond['value'] = get_priority(cond['value'])
+
+ elif cond['conditiontype'] == 5:
+ cond['value'] = get_trigger_value(cond['value'])
+ elif cond['conditiontype'] == 13:
+ cond['value'] = get_template_id_by_name(zapi, cond['value'])
+ elif cond['conditiontype'] == 16:
+ cond['value'] = ''
+
+ return inc_conditions
+
+
+def get_send_recovery(send_recovery):
+ '''Get the integer value'''
+ rval = 0
+ if send_recovery:
+ rval = 1
+
+ return rval
+
+# The branches are needed for CRUD and error handling
+# pylint: disable=too-many-branches
+def main():
+ '''
+ ansible zabbix module for zbx_item
+ '''
+
+
+ module = AnsibleModule(
+ argument_spec=dict(
+ zbx_server=dict(default='https://localhost/zabbix/api_jsonrpc.php', type='str'),
+ zbx_user=dict(default=os.environ.get('ZABBIX_USER', None), type='str'),
+ zbx_password=dict(default=os.environ.get('ZABBIX_PASSWORD', None), type='str'),
+ zbx_debug=dict(default=False, type='bool'),
+
+ name=dict(default=None, type='str'),
+ event_source=dict(default='trigger', choices=['trigger', 'discovery', 'auto', 'internal'], type='str'),
+ action_subject=dict(default="{TRIGGER.NAME}: {TRIGGER.STATUS}", type='str'),
+ action_message=dict(default="{TRIGGER.NAME}: {TRIGGER.STATUS}\r\n" +
+ "Last value: {ITEM.LASTVALUE}\r\n\r\n{TRIGGER.URL}", type='str'),
+ reply_subject=dict(default="{TRIGGER.NAME}: {TRIGGER.STATUS}", type='str'),
+ reply_message=dict(default="Trigger: {TRIGGER.NAME}\r\nTrigger status: {TRIGGER.STATUS}\r\n" +
+ "Trigger severity: {TRIGGER.SEVERITY}\r\nTrigger URL: {TRIGGER.URL}\r\n\r\n" +
+ "Item values:\r\n\r\n1. {ITEM.NAME1} ({HOST.NAME1}:{ITEM.KEY1}): " +
+ "{ITEM.VALUE1}\r\n2. {ITEM.NAME2} ({HOST.NAME2}:{ITEM.KEY2}): " +
+ "{ITEM.VALUE2}\r\n3. {ITEM.NAME3} ({HOST.NAME3}:{ITEM.KEY3}): " +
+ "{ITEM.VALUE3}", type='str'),
+ send_recovery=dict(default=False, type='bool'),
+ status=dict(default=None, type='str'),
+ escalation_time=dict(default=60, type='int'),
+ conditions_filter=dict(default=None, type='dict'),
+ operations=dict(default=None, type='list'),
+ state=dict(default='present', type='str'),
+ ),
+ #supports_check_mode=True
+ )
+
+ zapi = ZabbixAPI(ZabbixConnection(module.params['zbx_server'],
+ module.params['zbx_user'],
+ module.params['zbx_password'],
+ module.params['zbx_debug']))
+
+ #Set the instance and the template for the rest of the calls
+ zbx_class_name = 'action'
+ state = module.params['state']
+
+ content = zapi.get_content(zbx_class_name,
+ 'get',
+ {'search': {'name': module.params['name']},
+ 'selectFilter': 'extend',
+ 'selectOperations': 'extend',
+ })
+
+ #******#
+ # GET
+ #******#
+ if state == 'list':
+ module.exit_json(changed=False, results=content['result'], state="list")
+
+ #******#
+ # DELETE
+ #******#
+ if state == 'absent':
+ if not exists(content):
+ module.exit_json(changed=False, state="absent")
+
+ content = zapi.get_content(zbx_class_name, 'delete', [content['result'][0]['itemid']])
+ module.exit_json(changed=True, results=content['result'], state="absent")
+
+ # Create and Update
+ if state == 'present':
+
+ conditions = get_action_conditions(zapi, module.params['event_source'], module.params['conditions_filter'])
+ operations = get_action_operations(zapi, module.params['operations'])
+ params = {'name': module.params['name'],
+ 'esc_period': module.params['escalation_time'],
+ 'eventsource': get_event_source(module.params['event_source']),
+ 'status': get_status(module.params['status']),
+ 'def_shortdata': module.params['action_subject'],
+ 'def_longdata': module.params['action_message'],
+ 'r_shortdata': module.params['reply_subject'],
+ 'r_longdata': module.params['reply_message'],
+ 'recovery_msg': get_send_recovery(module.params['send_recovery']),
+ 'filter': conditions,
+ 'operations': operations,
+ }
+
+ # Remove any None valued params
+ _ = [params.pop(key, None) for key in params.keys() if params[key] is None]
+
+ #******#
+ # CREATE
+ #******#
+ if not exists(content):
+ content = zapi.get_content(zbx_class_name, 'create', params)
+
+ if content.has_key('error'):
+ module.exit_json(failed=True, changed=True, results=content['error'], state="present")
+
+ module.exit_json(changed=True, results=content['result'], state='present')
+
+
+ ########
+ # UPDATE
+ ########
+ _ = params.pop('hostid', None)
+ differences = {}
+ zab_results = content['result'][0]
+ for key, value in params.items():
+
+ if key == 'operations':
+ ops = operation_differences(zab_results[key], value)
+ if ops:
+ differences[key] = ops
+
+ elif key == 'filter':
+ filters = filter_differences(zab_results[key], value)
+ if filters:
+ differences[key] = filters
+
+ elif zab_results[key] != value and zab_results[key] != str(value):
+ differences[key] = value
+
+ if not differences:
+ module.exit_json(changed=False, results=zab_results, state="present")
+
+ # We have differences and need to update.
+ # action update requires an id, filters, and operations
+ differences['actionid'] = zab_results['actionid']
+ differences['operations'] = params['operations']
+ differences['filter'] = params['filter']
+ content = zapi.get_content(zbx_class_name, 'update', differences)
+
+ if content.has_key('error'):
+ module.exit_json(failed=True, changed=False, results=content['error'], state="present")
+
+ module.exit_json(changed=True, results=content['result'], state="present")
+
+ module.exit_json(failed=True,
+ changed=False,
+ results='Unknown state passed. %s' % state,
+ state="unknown")
+
+# pylint: disable=redefined-builtin, unused-wildcard-import, wildcard-import, locally-disabled
+# import module snippets. This are required
+from ansible.module_utils.basic import *
+
+main()
diff --git a/roles/lib_zabbix/library/zbx_application.py b/roles/lib_zabbix/library/zbx_application.py
new file mode 100644
index 000000000..21e3d91f4
--- /dev/null
+++ b/roles/lib_zabbix/library/zbx_application.py
@@ -0,0 +1,142 @@
+#!/usr/bin/env python
+'''
+Ansible module for application
+'''
+# vim: expandtab:tabstop=4:shiftwidth=4
+#
+# Zabbix application ansible module
+#
+#
+# Copyright 2015 Red Hat Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+# This is in place because each module looks similar to each other.
+# These need duplicate code as their behavior is very similar
+# but different for each zabbix class.
+# pylint: disable=duplicate-code
+
+# pylint: disable=import-error
+from openshift_tools.monitoring.zbxapi import ZabbixAPI, ZabbixConnection
+
+def exists(content, key='result'):
+ ''' Check if key exists in content or the size of content[key] > 0
+ '''
+ if not content.has_key(key):
+ return False
+
+ if not content[key]:
+ return False
+
+ return True
+
+def get_template_ids(zapi, template_name):
+ '''
+ get related templates
+ '''
+ template_ids = []
+ # Fetch templates by name
+ content = zapi.get_content('template',
+ 'get',
+ {'search': {'host': template_name}})
+ if content.has_key('result'):
+ template_ids.append(content['result'][0]['templateid'])
+ return template_ids
+
+def main():
+ ''' Ansible module for application
+ '''
+
+ module = AnsibleModule(
+ argument_spec=dict(
+ zbx_server=dict(default='https://localhost/zabbix/api_jsonrpc.php', type='str'),
+ zbx_user=dict(default=os.environ.get('ZABBIX_USER', None), type='str'),
+ zbx_password=dict(default=os.environ.get('ZABBIX_PASSWORD', None), type='str'),
+ zbx_debug=dict(default=False, type='bool'),
+ name=dict(default=None, type='str', required=True),
+ template_name=dict(default=None, type='str'),
+ state=dict(default='present', type='str'),
+ ),
+ #supports_check_mode=True
+ )
+
+ zapi = ZabbixAPI(ZabbixConnection(module.params['zbx_server'],
+ module.params['zbx_user'],
+ module.params['zbx_password'],
+ module.params['zbx_debug']))
+
+ #Set the instance and the application for the rest of the calls
+ zbx_class_name = 'application'
+ idname = 'applicationid'
+ aname = module.params['name']
+ state = module.params['state']
+ # get a applicationid, see if it exists
+ tids = get_template_ids(zapi, module.params['template_name'])
+ content = zapi.get_content(zbx_class_name,
+ 'get',
+ {'search': {'name': aname},
+ 'templateids': tids[0],
+ })
+ if state == 'list':
+ module.exit_json(changed=False, results=content['result'], state="list")
+
+ if state == 'absent':
+ if not exists(content):
+ module.exit_json(changed=False, state="absent")
+
+ content = zapi.get_content(zbx_class_name, 'delete', [content['result'][0][idname]])
+ module.exit_json(changed=True, results=content['result'], state="absent")
+
+ if state == 'present':
+ params = {'hostid': tids[0],
+ 'name': aname,
+ }
+
+ if not exists(content):
+ # if we didn't find it, create it
+ content = zapi.get_content(zbx_class_name, 'create', params)
+ module.exit_json(changed=True, results=content['result'], state='present')
+ # already exists, we need to update it
+ # let's compare properties
+ differences = {}
+ zab_results = content['result'][0]
+ for key, value in params.items():
+ if key == 'templates' and zab_results.has_key('parentTemplates'):
+ if zab_results['parentTemplates'] != value:
+ differences[key] = value
+ elif zab_results[key] != str(value) and zab_results[key] != value:
+ differences[key] = value
+
+ if not differences:
+ module.exit_json(changed=False, results=content['result'], state="present")
+
+ # We have differences and need to update
+ differences[idname] = zab_results[idname]
+ content = zapi.get_content(zbx_class_name, 'update', differences)
+
+ if content.has_key('error'):
+ module.exit_json(failed=True, changed=False, results=content['error'], state="present")
+
+ module.exit_json(changed=True, results=content['result'], state="present")
+
+ module.exit_json(failed=True,
+ changed=False,
+ results='Unknown state passed. %s' % state,
+ state="unknown")
+
+# pylint: disable=redefined-builtin, unused-wildcard-import, wildcard-import, locally-disabled
+# import module snippets. This are required
+from ansible.module_utils.basic import *
+
+main()
diff --git a/roles/lib_zabbix/library/zbx_discoveryrule.py b/roles/lib_zabbix/library/zbx_discoveryrule.py
new file mode 100644
index 000000000..f52f350a5
--- /dev/null
+++ b/roles/lib_zabbix/library/zbx_discoveryrule.py
@@ -0,0 +1,205 @@
+#!/usr/bin/env python
+'''
+Zabbix discovery rule ansible module
+'''
+# vim: expandtab:tabstop=4:shiftwidth=4
+#
+# Copyright 2015 Red Hat Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+# This is in place because each module looks similar to each other.
+# These need duplicate code as their behavior is very similar
+# but different for each zabbix class.
+# pylint: disable=duplicate-code
+
+# pylint: disable=import-error
+from openshift_tools.monitoring.zbxapi import ZabbixAPI, ZabbixConnection
+
+def exists(content, key='result'):
+ ''' Check if key exists in content or the size of content[key] > 0
+ '''
+ if not content.has_key(key):
+ return False
+
+ if not content[key]:
+ return False
+
+ return True
+
+def get_template(zapi, template_name):
+ '''get a template by name
+ '''
+ content = zapi.get_content('template',
+ 'get',
+ {'search': {'host': template_name},
+ 'output': 'extend',
+ 'selectInterfaces': 'interfaceid',
+ })
+ if not content['result']:
+ return None
+ return content['result'][0]
+
+def get_type(vtype):
+ '''
+ Determine which type of discoverrule this is
+ '''
+ _types = {'agent': 0,
+ 'SNMPv1': 1,
+ 'trapper': 2,
+ 'simple': 3,
+ 'SNMPv2': 4,
+ 'internal': 5,
+ 'SNMPv3': 6,
+ 'active': 7,
+ 'external': 10,
+ 'database monitor': 11,
+ 'ipmi': 12,
+ 'ssh': 13,
+ 'telnet': 14,
+ 'JMX': 16,
+ }
+
+ for typ in _types.keys():
+ if vtype in typ or vtype == typ:
+ _vtype = _types[typ]
+ break
+ else:
+ _vtype = 2
+
+ return _vtype
+
+def main():
+ '''
+ Ansible module for zabbix discovery rules
+ '''
+
+
+ module = AnsibleModule(
+ argument_spec=dict(
+ zbx_server=dict(default='https://localhost/zabbix/api_jsonrpc.php', type='str'),
+ zbx_user=dict(default=os.environ.get('ZABBIX_USER', None), type='str'),
+ zbx_password=dict(default=os.environ.get('ZABBIX_PASSWORD', None), type='str'),
+ zbx_debug=dict(default=False, type='bool'),
+ name=dict(default=None, type='str'),
+ key=dict(default=None, type='str'),
+ description=dict(default=None, type='str'),
+ interfaceid=dict(default=None, type='int'),
+ ztype=dict(default='trapper', type='str'),
+ delay=dict(default=60, type='int'),
+ lifetime=dict(default=30, type='int'),
+ template_name=dict(default=[], type='list'),
+ state=dict(default='present', type='str'),
+ ),
+ #supports_check_mode=True
+ )
+
+ zapi = ZabbixAPI(ZabbixConnection(module.params['zbx_server'],
+ module.params['zbx_user'],
+ module.params['zbx_password'],
+ module.params['zbx_debug']))
+
+ #Set the instance and the template for the rest of the calls
+ zbx_class_name = 'discoveryrule'
+ idname = "itemid"
+ dname = module.params['name']
+ state = module.params['state']
+ template = get_template(zapi, module.params['template_name'])
+
+ # selectInterfaces doesn't appear to be working but is needed.
+ content = zapi.get_content(zbx_class_name,
+ 'get',
+ {'search': {'name': dname},
+ 'templateids': template['templateid'],
+ #'selectDServices': 'extend',
+ #'selectDChecks': 'extend',
+ #'selectDhosts': 'dhostid',
+ })
+
+ #******#
+ # GET
+ #******#
+ if state == 'list':
+ module.exit_json(changed=False, results=content['result'], state="list")
+
+ #******#
+ # DELETE
+ #******#
+ if state == 'absent':
+ if not exists(content):
+ module.exit_json(changed=False, state="absent")
+
+ content = zapi.get_content(zbx_class_name, 'delete', [content['result'][0][idname]])
+ module.exit_json(changed=True, results=content['result'], state="absent")
+
+
+ # Create and Update
+ if state == 'present':
+ params = {'name': dname,
+ 'key_': module.params['key'],
+ 'hostid': template['templateid'],
+ 'interfaceid': module.params['interfaceid'],
+ 'lifetime': module.params['lifetime'],
+ 'type': get_type(module.params['ztype']),
+ 'description': module.params['description'],
+ }
+ if params['type'] in [2, 5, 7, 11]:
+ params.pop('interfaceid')
+
+ # Remove any None valued params
+ _ = [params.pop(key, None) for key in params.keys() if params[key] is None]
+
+ #******#
+ # CREATE
+ #******#
+ if not exists(content):
+ content = zapi.get_content(zbx_class_name, 'create', params)
+
+ if content.has_key('error'):
+ module.exit_json(failed=True, changed=True, results=content['error'], state="present")
+
+ module.exit_json(changed=True, results=content['result'], state='present')
+
+ ########
+ # UPDATE
+ ########
+ differences = {}
+ zab_results = content['result'][0]
+ for key, value in params.items():
+
+ if zab_results[key] != value and zab_results[key] != str(value):
+ differences[key] = value
+
+ if not differences:
+ module.exit_json(changed=False, results=zab_results, state="present")
+
+ # We have differences and need to update
+ differences[idname] = zab_results[idname]
+ content = zapi.get_content(zbx_class_name, 'update', differences)
+
+ if content.has_key('error'):
+ module.exit_json(failed=True, changed=False, results=content['error'], state="present")
+
+ module.exit_json(changed=True, results=content['result'], state="present")
+
+ module.exit_json(failed=True,
+ changed=False,
+ results='Unknown state passed. %s' % state,
+ state="unknown")
+
+# pylint: disable=redefined-builtin, unused-wildcard-import, wildcard-import, locally-disabled
+# import module snippets. This are required
+from ansible.module_utils.basic import *
+
+main()
diff --git a/roles/lib_zabbix/library/zbx_host.py b/roles/lib_zabbix/library/zbx_host.py
new file mode 100644
index 000000000..e26c9caf3
--- /dev/null
+++ b/roles/lib_zabbix/library/zbx_host.py
@@ -0,0 +1,163 @@
+#!/usr/bin/env python
+'''
+Zabbix host ansible module
+'''
+# vim: expandtab:tabstop=4:shiftwidth=4
+#
+# Copyright 2015 Red Hat Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+# This is in place because each module looks similar to each other.
+# These need duplicate code as their behavior is very similar
+# but different for each zabbix class.
+# pylint: disable=duplicate-code
+
+# pylint: disable=import-error
+from openshift_tools.monitoring.zbxapi import ZabbixAPI, ZabbixConnection
+
+def exists(content, key='result'):
+ ''' Check if key exists in content or the size of content[key] > 0
+ '''
+ if not content.has_key(key):
+ return False
+
+ if not content[key]:
+ return False
+
+ return True
+
+def get_group_ids(zapi, hostgroup_names):
+ '''
+ get hostgroups
+ '''
+ # Fetch groups by name
+ group_ids = []
+ for hgr in hostgroup_names:
+ content = zapi.get_content('hostgroup', 'get', {'search': {'name': hgr}})
+ if content.has_key('result'):
+ group_ids.append({'groupid': content['result'][0]['groupid']})
+
+ return group_ids
+
+def get_template_ids(zapi, template_names):
+ '''
+ get related templates
+ '''
+ template_ids = []
+ # Fetch templates by name
+ for template_name in template_names:
+ content = zapi.get_content('template', 'get', {'search': {'host': template_name}})
+ if content.has_key('result'):
+ template_ids.append({'templateid': content['result'][0]['templateid']})
+ return template_ids
+
+def main():
+ '''
+ Ansible module for zabbix host
+ '''
+
+ module = AnsibleModule(
+ argument_spec=dict(
+ zbx_server=dict(default='https://localhost/zabbix/api_jsonrpc.php', type='str'),
+ zbx_user=dict(default=os.environ.get('ZABBIX_USER', None), type='str'),
+ zbx_password=dict(default=os.environ.get('ZABBIX_PASSWORD', None), type='str'),
+ zbx_debug=dict(default=False, type='bool'),
+ name=dict(default=None, type='str'),
+ hostgroup_names=dict(default=[], type='list'),
+ template_names=dict(default=[], type='list'),
+ state=dict(default='present', type='str'),
+ interfaces=dict(default=None, type='list'),
+ ),
+ #supports_check_mode=True
+ )
+
+ zapi = ZabbixAPI(ZabbixConnection(module.params['zbx_server'],
+ module.params['zbx_user'],
+ module.params['zbx_password'],
+ module.params['zbx_debug']))
+
+ #Set the instance and the template for the rest of the calls
+ zbx_class_name = 'host'
+ idname = "hostid"
+ hname = module.params['name']
+ state = module.params['state']
+
+ # selectInterfaces doesn't appear to be working but is needed.
+ content = zapi.get_content(zbx_class_name,
+ 'get',
+ {'search': {'host': hname},
+ 'selectGroups': 'groupid',
+ 'selectParentTemplates': 'templateid',
+ 'selectInterfaces': 'interfaceid',
+ })
+ if state == 'list':
+ module.exit_json(changed=False, results=content['result'], state="list")
+
+ if state == 'absent':
+ if not exists(content):
+ module.exit_json(changed=False, state="absent")
+
+ content = zapi.get_content(zbx_class_name, 'delete', [content['result'][0][idname]])
+ module.exit_json(changed=True, results=content['result'], state="absent")
+
+ if state == 'present':
+ ifs = module.params['interfaces'] or [{'type': 1, # interface type, 1 = agent
+ 'main': 1, # default interface? 1 = true
+ 'useip': 1, # default interface? 1 = true
+ 'ip': '127.0.0.1', # default interface? 1 = true
+ 'dns': '', # dns for host
+ 'port': '10050', # port for interface? 10050
+ }]
+ params = {'host': hname,
+ 'groups': get_group_ids(zapi, module.params['hostgroup_names']),
+ 'templates': get_template_ids(zapi, module.params['template_names']),
+ 'interfaces': ifs,
+ }
+
+ if not exists(content):
+ # if we didn't find it, create it
+ content = zapi.get_content(zbx_class_name, 'create', params)
+ module.exit_json(changed=True, results=content['result'], state='present')
+ # already exists, we need to update it
+ # let's compare properties
+ differences = {}
+ zab_results = content['result'][0]
+ for key, value in params.items():
+
+ if key == 'templates' and zab_results.has_key('parentTemplates'):
+ if zab_results['parentTemplates'] != value:
+ differences[key] = value
+
+ elif zab_results[key] != value and zab_results[key] != str(value):
+ differences[key] = value
+
+ if not differences:
+ module.exit_json(changed=False, results=zab_results, state="present")
+
+ # We have differences and need to update
+ differences[idname] = zab_results[idname]
+ content = zapi.get_content(zbx_class_name, 'update', differences)
+ module.exit_json(changed=True, results=content['result'], state="present")
+
+ module.exit_json(failed=True,
+ changed=False,
+ results='Unknown state passed. %s' % state,
+ state="unknown")
+
+# pylint: disable=redefined-builtin, unused-wildcard-import, wildcard-import, locally-disabled
+# import module snippets. This are required
+from ansible.module_utils.basic import *
+
+main()
diff --git a/roles/lib_zabbix/library/zbx_hostgroup.py b/roles/lib_zabbix/library/zbx_hostgroup.py
new file mode 100644
index 000000000..7f080af24
--- /dev/null
+++ b/roles/lib_zabbix/library/zbx_hostgroup.py
@@ -0,0 +1,116 @@
+#!/usr/bin/env python
+''' Ansible module for hostgroup
+'''
+# vim: expandtab:tabstop=4:shiftwidth=4
+#
+# Zabbix hostgroup ansible module
+#
+#
+# Copyright 2015 Red Hat Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+# This is in place because each module looks similar to each other.
+# These need duplicate code as their behavior is very similar
+# but different for each zabbix class.
+# pylint: disable=duplicate-code
+
+# pylint: disable=import-error
+from openshift_tools.monitoring.zbxapi import ZabbixAPI, ZabbixConnection
+
+def exists(content, key='result'):
+ ''' Check if key exists in content or the size of content[key] > 0
+ '''
+ if not content.has_key(key):
+ return False
+
+ if not content[key]:
+ return False
+
+ return True
+
+def main():
+ ''' ansible module for hostgroup
+ '''
+
+ module = AnsibleModule(
+ argument_spec=dict(
+ zbx_server=dict(default='https://localhost/zabbix/api_jsonrpc.php', type='str'),
+ zbx_user=dict(default=os.environ.get('ZABBIX_USER', None), type='str'),
+ zbx_password=dict(default=os.environ.get('ZABBIX_PASSWORD', None), type='str'),
+ zbx_debug=dict(default=False, type='bool'),
+ name=dict(default=None, type='str'),
+ state=dict(default='present', type='str'),
+ ),
+ #supports_check_mode=True
+ )
+
+ zapi = ZabbixAPI(ZabbixConnection(module.params['zbx_server'],
+ module.params['zbx_user'],
+ module.params['zbx_password'],
+ module.params['zbx_debug']))
+
+ #Set the instance and the template for the rest of the calls
+ zbx_class_name = 'hostgroup'
+ idname = "groupid"
+ hname = module.params['name']
+ state = module.params['state']
+
+ content = zapi.get_content(zbx_class_name,
+ 'get',
+ {'search': {'name': hname},
+ })
+ if state == 'list':
+ module.exit_json(changed=False, results=content['result'], state="list")
+
+ if state == 'absent':
+ if not exists(content):
+ module.exit_json(changed=False, state="absent")
+
+ content = zapi.get_content(zbx_class_name, 'delete', [content['result'][0][idname]])
+ module.exit_json(changed=True, results=content['result'], state="absent")
+
+ if state == 'present':
+ params = {'name': hname}
+
+ if not exists(content):
+ # if we didn't find it, create it
+ content = zapi.get_content(zbx_class_name, 'create', params)
+ module.exit_json(changed=True, results=content['result'], state='present')
+ # already exists, we need to update it
+ # let's compare properties
+ differences = {}
+ zab_results = content['result'][0]
+ for key, value in params.items():
+ if zab_results[key] != value and zab_results[key] != str(value):
+ differences[key] = value
+
+ if not differences:
+ module.exit_json(changed=False, results=zab_results, state="present")
+
+ # We have differences and need to update
+ differences[idname] = zab_results[idname]
+ content = zapi.get_content(zbx_class_name, 'update', differences)
+ module.exit_json(changed=True, results=content['result'], state="present")
+
+ module.exit_json(failed=True,
+ changed=False,
+ results='Unknown state passed. %s' % state,
+ state="unknown")
+
+# pylint: disable=redefined-builtin, unused-wildcard-import, wildcard-import, locally-disabled
+# import module snippets. This are required
+from ansible.module_utils.basic import *
+
+main()
diff --git a/roles/lib_zabbix/library/zbx_item.py b/roles/lib_zabbix/library/zbx_item.py
new file mode 100644
index 000000000..5dc3cff9b
--- /dev/null
+++ b/roles/lib_zabbix/library/zbx_item.py
@@ -0,0 +1,283 @@
+#!/usr/bin/env python
+'''
+ Ansible module for zabbix items
+'''
+# vim: expandtab:tabstop=4:shiftwidth=4
+#
+# Zabbix item ansible module
+#
+#
+# Copyright 2015 Red Hat Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+# This is in place because each module looks similar to each other.
+# These need duplicate code as their behavior is very similar
+# but different for each zabbix class.
+# pylint: disable=duplicate-code
+
+# pylint: disable=import-error
+from openshift_tools.monitoring.zbxapi import ZabbixAPI, ZabbixConnection
+
+def exists(content, key='result'):
+ ''' Check if key exists in content or the size of content[key] > 0
+ '''
+ if not content.has_key(key):
+ return False
+
+ if not content[key]:
+ return False
+
+ return True
+
+def get_value_type(value_type):
+ '''
+ Possible values:
+ 0 - numeric float;
+ 1 - character;
+ 2 - log;
+ 3 - numeric unsigned;
+ 4 - text
+ '''
+ vtype = 0
+ if 'int' in value_type:
+ vtype = 3
+ elif 'log' in value_type:
+ vtype = 2
+ elif 'char' in value_type:
+ vtype = 1
+ elif 'str' in value_type:
+ vtype = 4
+
+ return vtype
+
+def get_app_ids(application_names, app_name_ids):
+ ''' get application ids from names
+ '''
+ applications = []
+ if application_names:
+ for app in application_names:
+ applications.append(app_name_ids[app])
+
+ return applications
+
+def get_template_id(zapi, template_name):
+ '''
+ get related templates
+ '''
+ template_ids = []
+ app_ids = {}
+ # Fetch templates by name
+ content = zapi.get_content('template',
+ 'get',
+ {'search': {'host': template_name},
+ 'selectApplications': ['applicationid', 'name']})
+ if content.has_key('result'):
+ template_ids.append(content['result'][0]['templateid'])
+ for app in content['result'][0]['applications']:
+ app_ids[app['name']] = app['applicationid']
+
+ return template_ids, app_ids
+
+def get_multiplier(inval):
+ ''' Determine the multiplier
+ '''
+ if inval == None or inval == '':
+ return None, 0
+
+ rval = None
+ try:
+ rval = int(inval)
+ except ValueError:
+ pass
+
+ if rval:
+ return rval, 1
+
+ return rval, 0
+
+def get_zabbix_type(ztype):
+ '''
+ Determine which type of discoverrule this is
+ '''
+ _types = {'agent': 0,
+ 'SNMPv1': 1,
+ 'trapper': 2,
+ 'simple': 3,
+ 'SNMPv2': 4,
+ 'internal': 5,
+ 'SNMPv3': 6,
+ 'active': 7,
+ 'aggregate': 8,
+ 'web': 9,
+ 'external': 10,
+ 'database monitor': 11,
+ 'ipmi': 12,
+ 'ssh': 13,
+ 'telnet': 14,
+ 'calculated': 15,
+ 'JMX': 16,
+ 'SNMP trap': 17,
+ }
+
+ for typ in _types.keys():
+ if ztype in typ or ztype == typ:
+ _vtype = _types[typ]
+ break
+ else:
+ _vtype = 2
+
+ return _vtype
+
+# The branches are needed for CRUD and error handling
+# pylint: disable=too-many-branches
+def main():
+ '''
+ ansible zabbix module for zbx_item
+ '''
+
+ module = AnsibleModule(
+ argument_spec=dict(
+ zbx_server=dict(default='https://localhost/zabbix/api_jsonrpc.php', type='str'),
+ zbx_user=dict(default=os.environ.get('ZABBIX_USER', None), type='str'),
+ zbx_password=dict(default=os.environ.get('ZABBIX_PASSWORD', None), type='str'),
+ zbx_debug=dict(default=False, type='bool'),
+ name=dict(default=None, type='str'),
+ key=dict(default=None, type='str'),
+ template_name=dict(default=None, type='str'),
+ zabbix_type=dict(default='trapper', type='str'),
+ value_type=dict(default='int', type='str'),
+ interval=dict(default=60, type='int'),
+ delta=dict(default=0, type='int'),
+ multiplier=dict(default=None, type='str'),
+ description=dict(default=None, type='str'),
+ units=dict(default=None, type='str'),
+ applications=dict(default=None, type='list'),
+ state=dict(default='present', type='str'),
+ ),
+ #supports_check_mode=True
+ )
+
+ zapi = ZabbixAPI(ZabbixConnection(module.params['zbx_server'],
+ module.params['zbx_user'],
+ module.params['zbx_password'],
+ module.params['zbx_debug']))
+
+ #Set the instance and the template for the rest of the calls
+ zbx_class_name = 'item'
+ state = module.params['state']
+
+ templateid, app_name_ids = get_template_id(zapi, module.params['template_name'])
+
+ # Fail if a template was not found matching the name
+ if not templateid:
+ module.exit_json(failed=True,
+ changed=False,
+ results='Error: Could find template with name %s for item.' % module.params['template_name'],
+ state="Unkown")
+
+ content = zapi.get_content(zbx_class_name,
+ 'get',
+ {'search': {'key_': module.params['key']},
+ 'selectApplications': 'applicationid',
+ 'templateids': templateid,
+ })
+
+ #******#
+ # GET
+ #******#
+ if state == 'list':
+ module.exit_json(changed=False, results=content['result'], state="list")
+
+ #******#
+ # DELETE
+ #******#
+ if state == 'absent':
+ if not exists(content):
+ module.exit_json(changed=False, state="absent")
+
+ content = zapi.get_content(zbx_class_name, 'delete', [content['result'][0]['itemid']])
+ module.exit_json(changed=True, results=content['result'], state="absent")
+
+ # Create and Update
+ if state == 'present':
+
+ formula, use_multiplier = get_multiplier(module.params['multiplier'])
+ params = {'name': module.params.get('name', module.params['key']),
+ 'key_': module.params['key'],
+ 'hostid': templateid[0],
+ 'type': get_zabbix_type(module.params['zabbix_type']),
+ 'value_type': get_value_type(module.params['value_type']),
+ 'applications': get_app_ids(module.params['applications'], app_name_ids),
+ 'formula': formula,
+ 'multiplier': use_multiplier,
+ 'description': module.params['description'],
+ 'units': module.params['units'],
+ 'delay': module.params['interval'],
+ 'delta': module.params['delta'],
+ }
+
+ # Remove any None valued params
+ _ = [params.pop(key, None) for key in params.keys() if params[key] is None]
+
+ #******#
+ # CREATE
+ #******#
+ if not exists(content):
+ content = zapi.get_content(zbx_class_name, 'create', params)
+
+ if content.has_key('error'):
+ module.exit_json(failed=True, changed=True, results=content['error'], state="present")
+
+ module.exit_json(changed=True, results=content['result'], state='present')
+
+
+ ########
+ # UPDATE
+ ########
+ _ = params.pop('hostid', None)
+ differences = {}
+ zab_results = content['result'][0]
+ for key, value in params.items():
+
+ if key == 'applications':
+ app_ids = [item['applicationid'] for item in zab_results[key]]
+ if set(app_ids) != set(value):
+ differences[key] = value
+
+ elif zab_results[key] != value and zab_results[key] != str(value):
+ differences[key] = value
+
+ if not differences:
+ module.exit_json(changed=False, results=zab_results, state="present")
+
+ # We have differences and need to update
+ differences['itemid'] = zab_results['itemid']
+ content = zapi.get_content(zbx_class_name, 'update', differences)
+
+ if content.has_key('error'):
+ module.exit_json(failed=True, changed=False, results=content['error'], state="present")
+
+ module.exit_json(changed=True, results=content['result'], state="present")
+
+ module.exit_json(failed=True,
+ changed=False,
+ results='Unknown state passed. %s' % state,
+ state="unknown")
+
+# pylint: disable=redefined-builtin, unused-wildcard-import, wildcard-import, locally-disabled
+# import module snippets. This are required
+from ansible.module_utils.basic import *
+
+main()
diff --git a/roles/lib_zabbix/library/zbx_itemprototype.py b/roles/lib_zabbix/library/zbx_itemprototype.py
new file mode 100644
index 000000000..e7fd6fa21
--- /dev/null
+++ b/roles/lib_zabbix/library/zbx_itemprototype.py
@@ -0,0 +1,276 @@
+#!/usr/bin/env python
+'''
+Zabbix discovery rule ansible module
+'''
+# vim: expandtab:tabstop=4:shiftwidth=4
+#
+# Copyright 2015 Red Hat Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+# This is in place because each module looks similar to each other.
+# These need duplicate code as their behavior is very similar
+# but different for each zabbix class.
+# pylint: disable=duplicate-code
+
+# pylint: disable=import-error
+from openshift_tools.monitoring.zbxapi import ZabbixAPI, ZabbixConnection
+
+def exists(content, key='result'):
+ ''' Check if key exists in content or the size of content[key] > 0
+ '''
+ if not content.has_key(key):
+ return False
+
+ if not content[key]:
+ return False
+
+ return True
+
+def get_rule_id(zapi, discoveryrule_key, templateid):
+ '''get a discoveryrule by name
+ '''
+ content = zapi.get_content('discoveryrule',
+ 'get',
+ {'search': {'key_': discoveryrule_key},
+ 'output': 'extend',
+ 'templateids': templateid,
+ })
+ if not content['result']:
+ return None
+ return content['result'][0]['itemid']
+
+def get_template(zapi, template_name):
+ '''get a template by name
+ '''
+ if not template_name:
+ return None
+
+ content = zapi.get_content('template',
+ 'get',
+ {'search': {'host': template_name},
+ 'output': 'extend',
+ 'selectInterfaces': 'interfaceid',
+ })
+ if not content['result']:
+ return None
+ return content['result'][0]
+
+def get_type(ztype):
+ '''
+ Determine which type of discoverrule this is
+ '''
+ _types = {'agent': 0,
+ 'SNMPv1': 1,
+ 'trapper': 2,
+ 'simple': 3,
+ 'SNMPv2': 4,
+ 'internal': 5,
+ 'SNMPv3': 6,
+ 'active': 7,
+ 'aggregate': 8,
+ 'external': 10,
+ 'database monitor': 11,
+ 'ipmi': 12,
+ 'ssh': 13,
+ 'telnet': 14,
+ 'calculated': 15,
+ 'JMX': 16,
+ }
+
+ for typ in _types.keys():
+ if ztype in typ or ztype == typ:
+ _vtype = _types[typ]
+ break
+ else:
+ _vtype = 2
+
+ return _vtype
+
+def get_value_type(value_type):
+ '''
+ Possible values:
+ 0 - numeric float;
+ 1 - character;
+ 2 - log;
+ 3 - numeric unsigned;
+ 4 - text
+ '''
+ vtype = 0
+ if 'int' in value_type:
+ vtype = 3
+ elif 'char' in value_type:
+ vtype = 1
+ elif 'str' in value_type:
+ vtype = 4
+
+ return vtype
+
+def get_status(status):
+ ''' Determine status
+ '''
+ _status = 0
+ if status == 'disabled':
+ _status = 1
+ elif status == 'unsupported':
+ _status = 3
+
+ return _status
+
+def get_app_ids(zapi, application_names, templateid):
+ ''' get application ids from names
+ '''
+ app_ids = []
+ for app_name in application_names:
+ content = zapi.get_content('application', 'get', {'filter': {'name': app_name}, 'templateids': templateid})
+ if content.has_key('result'):
+ app_ids.append(content['result'][0]['applicationid'])
+ return app_ids
+
+# pylint: disable=too-many-branches
+def main():
+ '''
+ Ansible module for zabbix discovery rules
+ '''
+
+ module = AnsibleModule(
+ argument_spec=dict(
+ zbx_server=dict(default='https://localhost/zabbix/api_jsonrpc.php', type='str'),
+ zbx_user=dict(default=os.environ.get('ZABBIX_USER', None), type='str'),
+ zbx_password=dict(default=os.environ.get('ZABBIX_PASSWORD', None), type='str'),
+ zbx_debug=dict(default=False, type='bool'),
+ name=dict(default=None, type='str'),
+ key=dict(default=None, type='str'),
+ description=dict(default=None, type='str'),
+ interfaceid=dict(default=None, type='int'),
+ ztype=dict(default='trapper', type='str'),
+ value_type=dict(default='float', type='str'),
+ delay=dict(default=60, type='int'),
+ lifetime=dict(default=30, type='int'),
+ state=dict(default='present', type='str'),
+ status=dict(default='enabled', type='str'),
+ applications=dict(default=[], type='list'),
+ template_name=dict(default=None, type='str'),
+ discoveryrule_key=dict(default=None, type='str'),
+ ),
+ #supports_check_mode=True
+ )
+
+ zapi = ZabbixAPI(ZabbixConnection(module.params['zbx_server'],
+ module.params['zbx_user'],
+ module.params['zbx_password'],
+ module.params['zbx_debug']))
+
+ #Set the instance and the template for the rest of the calls
+ zbx_class_name = 'itemprototype'
+ idname = "itemid"
+ state = module.params['state']
+ template = get_template(zapi, module.params['template_name'])
+
+ # selectInterfaces doesn't appear to be working but is needed.
+ content = zapi.get_content(zbx_class_name,
+ 'get',
+ {'search': {'key_': module.params['key']},
+ 'selectApplications': 'applicationid',
+ 'selectDiscoveryRule': 'itemid',
+ 'templated': True,
+ })
+
+ #******#
+ # GET
+ #******#
+ if state == 'list':
+ module.exit_json(changed=False, results=content['result'], state="list")
+
+ #******#
+ # DELETE
+ #******#
+ if state == 'absent':
+ if not exists(content):
+ module.exit_json(changed=False, state="absent")
+
+ content = zapi.get_content(zbx_class_name, 'delete', [content['result'][0][idname]])
+ module.exit_json(changed=True, results=content['result'], state="absent")
+
+ # Create and Update
+ if state == 'present':
+ params = {'name': module.params['name'],
+ 'key_': module.params['key'],
+ 'hostid': template['templateid'],
+ 'interfaceid': module.params['interfaceid'],
+ 'ruleid': get_rule_id(zapi, module.params['discoveryrule_key'], template['templateid']),
+ 'type': get_type(module.params['ztype']),
+ 'value_type': get_value_type(module.params['value_type']),
+ 'applications': get_app_ids(zapi, module.params['applications'], template['templateid']),
+ 'description': module.params['description'],
+ }
+
+ if params['type'] in [2, 5, 7, 8, 11, 15]:
+ params.pop('interfaceid')
+
+ # Remove any None valued params
+ _ = [params.pop(key, None) for key in params.keys() if params[key] is None]
+
+ #******#
+ # CREATE
+ #******#
+ if not exists(content):
+ content = zapi.get_content(zbx_class_name, 'create', params)
+
+ if content.has_key('error'):
+ module.exit_json(failed=True, changed=False, results=content['error'], state="present")
+
+ module.exit_json(changed=True, results=content['result'], state='present')
+
+ #******#
+ # UPDATE
+ #******#
+ differences = {}
+ zab_results = content['result'][0]
+ for key, value in params.items():
+
+ if key == 'ruleid':
+ if value != zab_results['discoveryRule']['itemid']:
+ differences[key] = value
+
+ elif key == 'applications':
+ app_ids = [app['applicationid'] for app in zab_results[key]]
+ if set(app_ids) - set(value):
+ differences[key] = value
+
+ elif zab_results[key] != value and zab_results[key] != str(value):
+ differences[key] = value
+
+ if not differences:
+ module.exit_json(changed=False, results=zab_results, state="present")
+
+ # We have differences and need to update
+ differences[idname] = zab_results[idname]
+ content = zapi.get_content(zbx_class_name, 'update', differences)
+
+ if content.has_key('error'):
+ module.exit_json(failed=True, changed=False, results=content['error'], state="present")
+
+ module.exit_json(changed=True, results=content['result'], state="present")
+
+ module.exit_json(failed=True,
+ changed=False,
+ results='Unknown state passed. %s' % state,
+ state="unknown")
+
+# pylint: disable=redefined-builtin, unused-wildcard-import, wildcard-import, locally-disabled
+# import module snippets. This are required
+from ansible.module_utils.basic import *
+
+main()
diff --git a/roles/lib_zabbix/library/zbx_mediatype.py b/roles/lib_zabbix/library/zbx_mediatype.py
new file mode 100644
index 000000000..3be232ecf
--- /dev/null
+++ b/roles/lib_zabbix/library/zbx_mediatype.py
@@ -0,0 +1,168 @@
+#!/usr/bin/env python
+'''
+ Ansible module for mediatype
+'''
+# vim: expandtab:tabstop=4:shiftwidth=4
+#
+# Zabbix mediatype ansible module
+#
+#
+# Copyright 2015 Red Hat Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+# This is in place because each module looks similar to each other.
+# These need duplicate code as their behavior is very similar
+# but different for each zabbix class.
+# pylint: disable=duplicate-code
+
+# pylint: disable=import-error
+from openshift_tools.monitoring.zbxapi import ZabbixAPI, ZabbixConnection
+
+def exists(content, key='result'):
+ ''' Check if key exists in content or the size of content[key] > 0
+ '''
+ if not content.has_key(key):
+ return False
+
+ if not content[key]:
+ return False
+
+ return True
+
+def get_mtype(mtype):
+ '''
+ Transport used by the media type.
+ Possible values:
+ 0 - email;
+ 1 - script;
+ 2 - SMS;
+ 3 - Jabber;
+ 100 - Ez Texting.
+ '''
+ mtype = mtype.lower()
+ media_type = None
+ if mtype == 'script':
+ media_type = 1
+ elif mtype == 'sms':
+ media_type = 2
+ elif mtype == 'jabber':
+ media_type = 3
+ elif mtype == 'script':
+ media_type = 100
+ else:
+ media_type = 0
+
+ return media_type
+
+def main():
+ '''
+ Ansible zabbix module for mediatype
+ '''
+
+ module = AnsibleModule(
+ argument_spec=dict(
+ zbx_server=dict(default='https://localhost/zabbix/api_jsonrpc.php', type='str'),
+ zbx_user=dict(default=os.environ.get('ZABBIX_USER', None), type='str'),
+ zbx_password=dict(default=os.environ.get('ZABBIX_PASSWORD', None), type='str'),
+ zbx_debug=dict(default=False, type='bool'),
+ description=dict(default=None, type='str'),
+ mtype=dict(default=None, type='str'),
+ smtp_server=dict(default=None, type='str'),
+ smtp_helo=dict(default=None, type='str'),
+ smtp_email=dict(default=None, type='str'),
+ passwd=dict(default=None, type='str'),
+ path=dict(default=None, type='str'),
+ username=dict(default=None, type='str'),
+ status=dict(default='enabled', type='str'),
+ state=dict(default='present', type='str'),
+ ),
+ #supports_check_mode=True
+ )
+
+ zapi = ZabbixAPI(ZabbixConnection(module.params['zbx_server'],
+ module.params['zbx_user'],
+ module.params['zbx_password'],
+ module.params['zbx_debug']))
+
+ #Set the instance and the template for the rest of the calls
+ zbx_class_name = 'mediatype'
+ idname = "mediatypeid"
+ description = module.params['description']
+ state = module.params['state']
+
+ content = zapi.get_content(zbx_class_name, 'get', {'search': {'description': description}})
+ if state == 'list':
+ module.exit_json(changed=False, results=content['result'], state="list")
+
+ if state == 'absent':
+ if not exists(content):
+ module.exit_json(changed=False, state="absent")
+
+ content = zapi.get_content(zbx_class_name, 'delete', [content['result'][0][idname]])
+ module.exit_json(changed=True, results=content['result'], state="absent")
+
+ if state == 'present':
+ status = 1
+ if module.params['status']:
+ status = 0
+ params = {'description': description,
+ 'type': get_mtype(module.params['mtype']),
+ 'smtp_server': module.params['smtp_server'],
+ 'smtp_helo': module.params['smtp_helo'],
+ 'smtp_email': module.params['smtp_email'],
+ 'passwd': module.params['passwd'],
+ 'exec_path': module.params['path'],
+ 'username': module.params['username'],
+ 'status': status,
+ }
+
+ # Remove any None valued params
+ _ = [params.pop(key, None) for key in params.keys() if params[key] is None]
+
+ if not exists(content):
+ # if we didn't find it, create it
+ content = zapi.get_content(zbx_class_name, 'create', params)
+
+ if content.has_key('error'):
+ module.exit_json(failed=True, changed=False, results=content['error'], state="present")
+
+ module.exit_json(changed=True, results=content['result'], state='present')
+ # already exists, we need to update it
+ # let's compare properties
+ differences = {}
+ zab_results = content['result'][0]
+ for key, value in params.items():
+ if zab_results[key] != value and \
+ zab_results[key] != str(value):
+ differences[key] = value
+
+ if not differences:
+ module.exit_json(changed=False, results=zab_results, state="present")
+
+ # We have differences and need to update
+ differences[idname] = zab_results[idname]
+ content = zapi.get_content(zbx_class_name, 'update', differences)
+ module.exit_json(changed=True, results=content['result'], state="present")
+
+ module.exit_json(failed=True,
+ changed=False,
+ results='Unknown state passed. %s' % state,
+ state="unknown")
+
+# pylint: disable=redefined-builtin, unused-wildcard-import, wildcard-import, locally-disabled
+# import module snippets. This are required
+from ansible.module_utils.basic import *
+
+main()
diff --git a/roles/lib_zabbix/library/zbx_template.py b/roles/lib_zabbix/library/zbx_template.py
new file mode 100644
index 000000000..ff5714bdc
--- /dev/null
+++ b/roles/lib_zabbix/library/zbx_template.py
@@ -0,0 +1,132 @@
+#!/usr/bin/env python
+'''
+Ansible module for template
+'''
+# vim: expandtab:tabstop=4:shiftwidth=4
+#
+# Zabbix template ansible module
+#
+#
+# Copyright 2015 Red Hat Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+# This is in place because each module looks similar to each other.
+# These need duplicate code as their behavior is very similar
+# but different for each zabbix class.
+# pylint: disable=duplicate-code
+
+# pylint: disable=import-error
+from openshift_tools.monitoring.zbxapi import ZabbixAPI, ZabbixConnection
+
+def exists(content, key='result'):
+ ''' Check if key exists in content or the size of content[key] > 0
+ '''
+ if not content.has_key(key):
+ return False
+
+ if not content[key]:
+ return False
+
+ return True
+
+def main():
+ ''' Ansible module for template
+ '''
+
+ module = AnsibleModule(
+ argument_spec=dict(
+ zbx_server=dict(default='https://localhost/zabbix/api_jsonrpc.php', type='str'),
+ zbx_user=dict(default=os.environ.get('ZABBIX_USER', None), type='str'),
+ zbx_password=dict(default=os.environ.get('ZABBIX_PASSWORD', None), type='str'),
+ zbx_debug=dict(default=False, type='bool'),
+ name=dict(default=None, type='str'),
+ state=dict(default='present', type='str'),
+ ),
+ #supports_check_mode=True
+ )
+
+ zapi = ZabbixAPI(ZabbixConnection(module.params['zbx_server'],
+ module.params['zbx_user'],
+ module.params['zbx_password'],
+ module.params['zbx_debug']))
+
+ #Set the instance and the template for the rest of the calls
+ zbx_class_name = 'template'
+ idname = 'templateid'
+ tname = module.params['name']
+ state = module.params['state']
+ # get a template, see if it exists
+ content = zapi.get_content(zbx_class_name,
+ 'get',
+ {'search': {'host': tname},
+ 'selectParentTemplates': 'templateid',
+ 'selectGroups': 'groupid',
+ 'selectApplications': 'applicationid',
+ 'selectDiscoveries': 'extend',
+ })
+ if state == 'list':
+ module.exit_json(changed=False, results=content['result'], state="list")
+
+ if state == 'absent':
+ if not exists(content):
+ module.exit_json(changed=False, state="absent")
+
+ if not tname:
+ module.exit_json(failed=True,
+ changed=False,
+ results='Must specifiy a template name.',
+ state="absent")
+
+ content = zapi.get_content(zbx_class_name, 'delete', [content['result'][0][idname]])
+ module.exit_json(changed=True, results=content['result'], state="absent")
+
+ if state == 'present':
+ params = {'groups': module.params.get('groups', [{'groupid': '1'}]),
+ 'host': tname,
+ }
+
+ if not exists(content):
+ # if we didn't find it, create it
+ content = zapi.get_content(zbx_class_name, 'create', params)
+ module.exit_json(changed=True, results=content['result'], state='present')
+ # already exists, we need to update it
+ # let's compare properties
+ differences = {}
+ zab_results = content['result'][0]
+ for key, value in params.items():
+ if key == 'templates' and zab_results.has_key('parentTemplates'):
+ if zab_results['parentTemplates'] != value:
+ differences[key] = value
+ elif zab_results[key] != str(value) and zab_results[key] != value:
+ differences[key] = value
+
+ if not differences:
+ module.exit_json(changed=False, results=content['result'], state="present")
+
+ # We have differences and need to update
+ differences[idname] = zab_results[idname]
+ content = zapi.get_content(zbx_class_name, 'update', differences)
+ module.exit_json(changed=True, results=content['result'], state="present")
+
+ module.exit_json(failed=True,
+ changed=False,
+ results='Unknown state passed. %s' % state,
+ state="unknown")
+
+# pylint: disable=redefined-builtin, unused-wildcard-import, wildcard-import, locally-disabled
+# import module snippets. This are required
+from ansible.module_utils.basic import *
+
+main()
diff --git a/roles/lib_zabbix/library/zbx_trigger.py b/roles/lib_zabbix/library/zbx_trigger.py
new file mode 100644
index 000000000..ab7731faa
--- /dev/null
+++ b/roles/lib_zabbix/library/zbx_trigger.py
@@ -0,0 +1,231 @@
+#!/usr/bin/env python
+'''
+ansible module for zabbix triggers
+'''
+# vim: expandtab:tabstop=4:shiftwidth=4
+#
+# Zabbix trigger ansible module
+#
+#
+# Copyright 2015 Red Hat Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+# This is in place because each module looks similar to each other.
+# These need duplicate code as their behavior is very similar
+# but different for each zabbix class.
+# pylint: disable=duplicate-code
+
+# pylint: disable=import-error
+from openshift_tools.monitoring.zbxapi import ZabbixAPI, ZabbixConnection
+
+def exists(content, key='result'):
+ ''' Check if key exists in content or the size of content[key] > 0
+ '''
+ if not content.has_key(key):
+ return False
+
+ if not content[key]:
+ return False
+
+ return True
+
+def get_priority(priority):
+ ''' determine priority
+ '''
+ prior = 0
+ if 'info' in priority:
+ prior = 1
+ elif 'warn' in priority:
+ prior = 2
+ elif 'avg' == priority or 'ave' in priority:
+ prior = 3
+ elif 'high' in priority:
+ prior = 4
+ elif 'dis' in priority:
+ prior = 5
+
+ return prior
+
+def get_deps(zapi, deps):
+ ''' get trigger dependencies
+ '''
+ results = []
+ for desc in deps:
+ content = zapi.get_content('trigger',
+ 'get',
+ {'filter': {'description': desc},
+ 'expandExpression': True,
+ 'selectDependencies': 'triggerid',
+ })
+ if content.has_key('result'):
+ results.append({'triggerid': content['result'][0]['triggerid']})
+
+ return results
+
+
+def get_trigger_status(inc_status):
+ ''' Determine the trigger's status
+ 0 is enabled
+ 1 is disabled
+ '''
+ r_status = 0
+ if inc_status == 'disabled':
+ r_status = 1
+
+ return r_status
+
+def get_template_id(zapi, template_name):
+ '''
+ get related templates
+ '''
+ template_ids = []
+ app_ids = {}
+ # Fetch templates by name
+ content = zapi.get_content('template',
+ 'get',
+ {'search': {'host': template_name},
+ 'selectApplications': ['applicationid', 'name']})
+ if content.has_key('result'):
+ template_ids.append(content['result'][0]['templateid'])
+ for app in content['result'][0]['applications']:
+ app_ids[app['name']] = app['applicationid']
+
+ return template_ids, app_ids
+
+def main():
+ '''
+ Create a trigger in zabbix
+
+ Example:
+ "params": {
+ "description": "Processor load is too high on {HOST.NAME}",
+ "expression": "{Linux server:system.cpu.load[percpu,avg1].last()}>5",
+ "dependencies": [
+ {
+ "triggerid": "14062"
+ }
+ ]
+ },
+
+ '''
+
+ module = AnsibleModule(
+ argument_spec=dict(
+ zbx_server=dict(default='https://localhost/zabbix/api_jsonrpc.php', type='str'),
+ zbx_user=dict(default=os.environ.get('ZABBIX_USER', None), type='str'),
+ zbx_password=dict(default=os.environ.get('ZABBIX_PASSWORD', None), type='str'),
+ zbx_debug=dict(default=False, type='bool'),
+ expression=dict(default=None, type='str'),
+ name=dict(default=None, type='str'),
+ description=dict(default=None, type='str'),
+ dependencies=dict(default=[], type='list'),
+ priority=dict(default='avg', type='str'),
+ url=dict(default=None, type='str'),
+ status=dict(default=None, type='str'),
+ state=dict(default='present', type='str'),
+ template_name=dict(default=None, type='str'),
+ ),
+ #supports_check_mode=True
+ )
+
+ zapi = ZabbixAPI(ZabbixConnection(module.params['zbx_server'],
+ module.params['zbx_user'],
+ module.params['zbx_password'],
+ module.params['zbx_debug']))
+
+ #Set the instance and the template for the rest of the calls
+ zbx_class_name = 'trigger'
+ idname = "triggerid"
+ state = module.params['state']
+ tname = module.params['name']
+
+ templateid = None
+ if module.params['template_name']:
+ templateid, _ = get_template_id(zapi, module.params['template_name'])
+
+ content = zapi.get_content(zbx_class_name,
+ 'get',
+ {'filter': {'description': tname},
+ 'expandExpression': True,
+ 'selectDependencies': 'triggerid',
+ 'templateids': templateid,
+ })
+
+ # Get
+ if state == 'list':
+ module.exit_json(changed=False, results=content['result'], state="list")
+
+ # Delete
+ if state == 'absent':
+ if not exists(content):
+ module.exit_json(changed=False, state="absent")
+ content = zapi.get_content(zbx_class_name, 'delete', [content['result'][0][idname]])
+ module.exit_json(changed=True, results=content['result'], state="absent")
+
+ # Create and Update
+ if state == 'present':
+ params = {'description': tname,
+ 'comments': module.params['description'],
+ 'expression': module.params['expression'],
+ 'dependencies': get_deps(zapi, module.params['dependencies']),
+ 'priority': get_priority(module.params['priority']),
+ 'url': module.params['url'],
+ 'status': get_trigger_status(module.params['status']),
+ }
+
+ # Remove any None valued params
+ _ = [params.pop(key, None) for key in params.keys() if params[key] is None]
+
+ #******#
+ # CREATE
+ #******#
+ if not exists(content):
+ # if we didn't find it, create it
+ content = zapi.get_content(zbx_class_name, 'create', params)
+
+ if content.has_key('error'):
+ module.exit_json(failed=True, changed=True, results=content['error'], state="present")
+
+ module.exit_json(changed=True, results=content['result'], state='present')
+
+ ########
+ # UPDATE
+ ########
+ differences = {}
+ zab_results = content['result'][0]
+ for key, value in params.items():
+
+ if zab_results[key] != value and zab_results[key] != str(value):
+ differences[key] = value
+
+ if not differences:
+ module.exit_json(changed=False, results=zab_results, state="present")
+
+ # We have differences and need to update
+ differences[idname] = zab_results[idname]
+ content = zapi.get_content(zbx_class_name, 'update', differences)
+ module.exit_json(changed=True, results=content['result'], state="present")
+
+
+ module.exit_json(failed=True,
+ changed=False,
+ results='Unknown state passed. %s' % state,
+ state="unknown")
+
+# pylint: disable=redefined-builtin, unused-wildcard-import, wildcard-import, locally-disabled
+# import module snippets. This are required
+from ansible.module_utils.basic import *
+
+main()
diff --git a/roles/lib_zabbix/library/zbx_triggerprototype.py b/roles/lib_zabbix/library/zbx_triggerprototype.py
new file mode 100644
index 000000000..c1224b268
--- /dev/null
+++ b/roles/lib_zabbix/library/zbx_triggerprototype.py
@@ -0,0 +1,177 @@
+#!/usr/bin/env python
+'''
+ansible module for zabbix triggerprototypes
+'''
+# vim: expandtab:tabstop=4:shiftwidth=4
+#
+# Zabbix triggerprototypes ansible module
+#
+#
+# Copyright 2015 Red Hat Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+# This is in place because each module looks similar to each other.
+# These need duplicate code as their behavior is very similar
+# but different for each zabbix class.
+# pylint: disable=duplicate-code
+
+# pylint: disable=import-error
+from openshift_tools.monitoring.zbxapi import ZabbixAPI, ZabbixConnection
+
+def exists(content, key='result'):
+ ''' Check if key exists in content or the size of content[key] > 0
+ '''
+ if not content.has_key(key):
+ return False
+
+ if not content[key]:
+ return False
+
+ return True
+
+def get_priority(priority):
+ ''' determine priority
+ '''
+ prior = 0
+ if 'info' in priority:
+ prior = 1
+ elif 'warn' in priority:
+ prior = 2
+ elif 'avg' == priority or 'ave' in priority:
+ prior = 3
+ elif 'high' in priority:
+ prior = 4
+ elif 'dis' in priority:
+ prior = 5
+
+ return prior
+
+def get_trigger_status(inc_status):
+ ''' Determine the trigger's status
+ 0 is enabled
+ 1 is disabled
+ '''
+ r_status = 0
+ if inc_status == 'disabled':
+ r_status = 1
+
+ return r_status
+
+
+def main():
+ '''
+ Create a triggerprototype in zabbix
+ '''
+
+ module = AnsibleModule(
+ argument_spec=dict(
+ zbx_server=dict(default='https://localhost/zabbix/api_jsonrpc.php', type='str'),
+ zbx_user=dict(default=os.environ.get('ZABBIX_USER', None), type='str'),
+ zbx_password=dict(default=os.environ.get('ZABBIX_PASSWORD', None), type='str'),
+ zbx_debug=dict(default=False, type='bool'),
+ name=dict(default=None, type='str'),
+ expression=dict(default=None, type='str'),
+ description=dict(default=None, type='str'),
+ priority=dict(default='avg', type='str'),
+ url=dict(default=None, type='str'),
+ status=dict(default=None, type='str'),
+ state=dict(default='present', type='str'),
+ ),
+ #supports_check_mode=True
+ )
+
+ zapi = ZabbixAPI(ZabbixConnection(module.params['zbx_server'],
+ module.params['zbx_user'],
+ module.params['zbx_password'],
+ module.params['zbx_debug']))
+
+ #Set the instance and the template for the rest of the calls
+ zbx_class_name = 'triggerprototype'
+ idname = "triggerid"
+ state = module.params['state']
+ tname = module.params['name']
+
+ content = zapi.get_content(zbx_class_name,
+ 'get',
+ {'filter': {'description': tname},
+ 'expandExpression': True,
+ 'selectDependencies': 'triggerid',
+ })
+
+ # Get
+ if state == 'list':
+ module.exit_json(changed=False, results=content['result'], state="list")
+
+ # Delete
+ if state == 'absent':
+ if not exists(content):
+ module.exit_json(changed=False, state="absent")
+ content = zapi.get_content(zbx_class_name, 'delete', [content['result'][0][idname]])
+ module.exit_json(changed=True, results=content['result'], state="absent")
+
+ # Create and Update
+ if state == 'present':
+ params = {'description': tname,
+ 'comments': module.params['description'],
+ 'expression': module.params['expression'],
+ 'priority': get_priority(module.params['priority']),
+ 'url': module.params['url'],
+ 'status': get_trigger_status(module.params['status']),
+ }
+
+ # Remove any None valued params
+ _ = [params.pop(key, None) for key in params.keys() if params[key] is None]
+
+ #******#
+ # CREATE
+ #******#
+ if not exists(content):
+ # if we didn't find it, create it
+ content = zapi.get_content(zbx_class_name, 'create', params)
+
+ if content.has_key('error'):
+ module.exit_json(failed=True, changed=True, results=content['error'], state="present")
+
+ module.exit_json(changed=True, results=content['result'], state='present')
+
+ ########
+ # UPDATE
+ ########
+ differences = {}
+ zab_results = content['result'][0]
+ for key, value in params.items():
+
+ if zab_results[key] != value and zab_results[key] != str(value):
+ differences[key] = value
+
+ if not differences:
+ module.exit_json(changed=False, results=zab_results, state="present")
+
+ # We have differences and need to update
+ differences[idname] = zab_results[idname]
+ content = zapi.get_content(zbx_class_name, 'update', differences)
+ module.exit_json(changed=True, results=content['result'], state="present")
+
+
+ module.exit_json(failed=True,
+ changed=False,
+ results='Unknown state passed. %s' % state,
+ state="unknown")
+
+# pylint: disable=redefined-builtin, unused-wildcard-import, wildcard-import, locally-disabled
+# import module snippets. This are required
+from ansible.module_utils.basic import *
+
+main()
diff --git a/roles/lib_zabbix/library/zbx_user.py b/roles/lib_zabbix/library/zbx_user.py
new file mode 100644
index 000000000..62c85c1bf
--- /dev/null
+++ b/roles/lib_zabbix/library/zbx_user.py
@@ -0,0 +1,190 @@
+#!/usr/bin/env python
+'''
+ansible module for zabbix users
+'''
+# vim: expandtab:tabstop=4:shiftwidth=4
+#
+# Zabbix user ansible module
+#
+#
+# Copyright 2015 Red Hat Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# This is in place because each module looks similar to each other.
+# These need duplicate code as their behavior is very similar
+# but different for each zabbix class.
+# pylint: disable=duplicate-code
+
+# pylint: disable=import-error
+from openshift_tools.monitoring.zbxapi import ZabbixAPI, ZabbixConnection
+
+def exists(content, key='result'):
+ ''' Check if key exists in content or the size of content[key] > 0
+ '''
+ if not content.has_key(key):
+ return False
+
+ if not content[key]:
+ return False
+
+ return True
+
+def get_usergroups(zapi, usergroups):
+ ''' Get usergroups
+ '''
+ ugroups = []
+ for ugr in usergroups:
+ content = zapi.get_content('usergroup',
+ 'get',
+ {'search': {'name': ugr},
+ #'selectUsers': 'userid',
+ #'getRights': 'extend'
+ })
+ if content['result']:
+ ugroups.append({'usrgrpid': content['result'][0]['usrgrpid']})
+
+ return ugroups or None
+
+def get_passwd(passwd):
+ '''Determine if password is set, if not, return 'zabbix'
+ '''
+ if passwd:
+ return passwd
+
+ return 'zabbix'
+
+def get_usertype(user_type):
+ '''
+ Determine zabbix user account type
+ '''
+ if not user_type:
+ return None
+
+ utype = 1
+ if 'super' in user_type:
+ utype = 3
+ elif 'admin' in user_type or user_type == 'admin':
+ utype = 2
+
+ return utype
+
+def main():
+ '''
+ ansible zabbix module for users
+ '''
+
+ ##def user(self, name, state='present', params=None):
+
+ module = AnsibleModule(
+ argument_spec=dict(
+ zbx_server=dict(default='https://localhost/zabbix/api_jsonrpc.php', type='str'),
+ zbx_user=dict(default=os.environ.get('ZABBIX_USER', None), type='str'),
+ zbx_password=dict(default=os.environ.get('ZABBIX_PASSWORD', None), type='str'),
+ zbx_debug=dict(default=False, type='bool'),
+ login=dict(default=None, type='str'),
+ first_name=dict(default=None, type='str'),
+ last_name=dict(default=None, type='str'),
+ user_type=dict(default=None, type='str'),
+ password=dict(default=None, type='str'),
+ update_password=dict(default=False, type='bool'),
+ user_groups=dict(default=[], type='list'),
+ state=dict(default='present', type='str'),
+ ),
+ #supports_check_mode=True
+ )
+
+ zapi = ZabbixAPI(ZabbixConnection(module.params['zbx_server'],
+ module.params['zbx_user'],
+ module.params['zbx_password'],
+ module.params['zbx_debug']))
+
+ ## before we can create a user media and users with media types we need media
+ zbx_class_name = 'user'
+ idname = "userid"
+ state = module.params['state']
+
+ content = zapi.get_content(zbx_class_name,
+ 'get',
+ {'output': 'extend',
+ 'search': {'alias': module.params['login']},
+ "selectUsrgrps": 'usergrpid',
+ })
+ if state == 'list':
+ module.exit_json(changed=False, results=content['result'], state="list")
+
+ if state == 'absent':
+ if not exists(content) or len(content['result']) == 0:
+ module.exit_json(changed=False, state="absent")
+
+ content = zapi.get_content(zbx_class_name, 'delete', [content['result'][0][idname]])
+ module.exit_json(changed=True, results=content['result'], state="absent")
+
+ if state == 'present':
+
+ params = {'alias': module.params['login'],
+ 'passwd': get_passwd(module.params['password']),
+ 'usrgrps': get_usergroups(zapi, module.params['user_groups']),
+ 'name': module.params['first_name'],
+ 'surname': module.params['last_name'],
+ 'type': get_usertype(module.params['user_type']),
+ }
+
+ # Remove any None valued params
+ _ = [params.pop(key, None) for key in params.keys() if params[key] is None]
+
+ if not exists(content):
+ # if we didn't find it, create it
+ content = zapi.get_content(zbx_class_name, 'create', params)
+
+ if content.has_key('Error'):
+ module.exit_json(failed=True, changed=False, results=content, state='present')
+
+ module.exit_json(changed=True, results=content['result'], state='present')
+ # already exists, we need to update it
+ # let's compare properties
+ differences = {}
+
+ # Update password
+ if not module.params['update_password']:
+ params.pop('passwd', None)
+
+ zab_results = content['result'][0]
+ for key, value in params.items():
+
+ if key == 'usrgrps':
+ # this must be done as a list of ordered dictionaries fails comparison
+ if not all([_ in value for _ in zab_results[key]]):
+ differences[key] = value
+
+ elif zab_results[key] != value and zab_results[key] != str(value):
+ differences[key] = value
+
+ if not differences:
+ module.exit_json(changed=False, results=zab_results, state="present")
+
+ # We have differences and need to update
+ differences[idname] = zab_results[idname]
+ content = zapi.get_content(zbx_class_name, 'update', differences)
+ module.exit_json(changed=True, results=content['result'], state="present")
+
+ module.exit_json(failed=True,
+ changed=False,
+ results='Unknown state passed. %s' % state,
+ state="unknown")
+
+# pylint: disable=redefined-builtin, unused-wildcard-import, wildcard-import, locally-disabled
+# import module snippets. This are required
+from ansible.module_utils.basic import *
+
+main()
diff --git a/roles/lib_zabbix/library/zbx_user_media.py b/roles/lib_zabbix/library/zbx_user_media.py
new file mode 100644
index 000000000..8895c78c3
--- /dev/null
+++ b/roles/lib_zabbix/library/zbx_user_media.py
@@ -0,0 +1,283 @@
+#!/usr/bin/env python
+'''
+ Ansible module for user media
+'''
+# vim: expandtab:tabstop=4:shiftwidth=4
+#
+# Zabbix user media ansible module
+#
+#
+# Copyright 2015 Red Hat Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+# This is in place because each module looks similar to each other.
+# These need duplicate code as their behavior is very similar
+# but different for each zabbix class.
+# pylint: disable=duplicate-code
+
+# pylint: disable=import-error
+from openshift_tools.monitoring.zbxapi import ZabbixAPI, ZabbixConnection
+
+def exists(content, key='result'):
+ ''' Check if key exists in content or the size of content[key] > 0
+ '''
+ if not content.has_key(key):
+ return False
+
+ if not content[key]:
+ return False
+
+ return True
+
+def get_mtype(zapi, mtype):
+ '''Get mediatype
+
+ If passed an int, return it as the mediatypeid
+ if its a string, then try to fetch through a description
+ '''
+ if isinstance(mtype, int):
+ return mtype
+ try:
+ return int(mtype)
+ except ValueError:
+ pass
+
+ content = zapi.get_content('mediatype', 'get', {'filter': {'description': mtype}})
+ if content.has_key('result') and content['result']:
+ return content['result'][0]['mediatypeid']
+
+ return None
+
+def get_user(zapi, user):
+ ''' Get userids from user aliases
+ '''
+ content = zapi.get_content('user', 'get', {'filter': {'alias': user}})
+ if content['result']:
+ return content['result'][0]
+
+ return None
+
+def get_severity(severity):
+ ''' determine severity
+ '''
+ if isinstance(severity, int) or \
+ isinstance(severity, str):
+ return severity
+
+ val = 0
+ sev_map = {
+ 'not': 2**0,
+ 'inf': 2**1,
+ 'war': 2**2,
+ 'ave': 2**3,
+ 'avg': 2**3,
+ 'hig': 2**4,
+ 'dis': 2**5,
+ }
+ for level in severity:
+ val |= sev_map[level[:3].lower()]
+ return val
+
+def get_zbx_user_query_data(zapi, user_name):
+ ''' If name exists, retrieve it, and build query params.
+ '''
+ query = {}
+ if user_name:
+ zbx_user = get_user(zapi, user_name)
+ query = {'userid': zbx_user['userid']}
+
+ return query
+
+def find_media(medias, user_media):
+ ''' Find the user media in the list of medias
+ '''
+ for media in medias:
+ if all([media[key] == str(user_media[key]) for key in user_media.keys()]):
+ return media
+ return None
+
+def get_active(is_active):
+ '''Determine active value
+ 0 - enabled
+ 1 - disabled
+ '''
+ active = 1
+ if is_active:
+ active = 0
+
+ return active
+
+def get_mediatype(zapi, mediatype, mediatype_desc):
+ ''' Determine mediatypeid
+ '''
+ mtypeid = None
+ if mediatype:
+ mtypeid = get_mtype(zapi, mediatype)
+ elif mediatype_desc:
+ mtypeid = get_mtype(zapi, mediatype_desc)
+
+ return mtypeid
+
+def preprocess_medias(zapi, medias):
+ ''' Insert the correct information when processing medias '''
+ for media in medias:
+ # Fetch the mediatypeid from the media desc (name)
+ if media.has_key('mediatype'):
+ media['mediatypeid'] = get_mediatype(zapi, mediatype=None, mediatype_desc=media.pop('mediatype'))
+
+ media['active'] = get_active(media.get('active'))
+ media['severity'] = int(get_severity(media['severity']))
+
+ return medias
+
+# Disabling branching as the logic requires branches.
+# I've also added a few safeguards which required more branches.
+# pylint: disable=too-many-branches
+def main():
+ '''
+ Ansible zabbix module for mediatype
+ '''
+
+ module = AnsibleModule(
+ argument_spec=dict(
+ zbx_server=dict(default='https://localhost/zabbix/api_jsonrpc.php', type='str'),
+ zbx_user=dict(default=os.environ.get('ZABBIX_USER', None), type='str'),
+ zbx_password=dict(default=os.environ.get('ZABBIX_PASSWORD', None), type='str'),
+ zbx_debug=dict(default=False, type='bool'),
+ login=dict(default=None, type='str'),
+ active=dict(default=False, type='bool'),
+ medias=dict(default=None, type='list'),
+ mediaid=dict(default=None, type='int'),
+ mediatype=dict(default=None, type='str'),
+ mediatype_desc=dict(default=None, type='str'),
+ #d-d,hh:mm-hh:mm;d-d,hh:mm-hh:mm...
+ period=dict(default=None, type='str'),
+ sendto=dict(default=None, type='str'),
+ severity=dict(default=None, type='str'),
+ state=dict(default='present', type='str'),
+ ),
+ #supports_check_mode=True
+ )
+
+ zapi = ZabbixAPI(ZabbixConnection(module.params['zbx_server'],
+ module.params['zbx_user'],
+ module.params['zbx_password'],
+ module.params['zbx_debug']))
+
+ #Set the instance and the template for the rest of the calls
+ zbx_class_name = 'user'
+ idname = "mediaid"
+ state = module.params['state']
+
+ # User media is fetched through the usermedia.get
+ zbx_user_query = get_zbx_user_query_data(zapi, module.params['login'])
+ content = zapi.get_content('usermedia', 'get',
+ {'userids': [uid for user, uid in zbx_user_query.items()]})
+ #####
+ # Get
+ #####
+ if state == 'list':
+ module.exit_json(changed=False, results=content['result'], state="list")
+
+ ########
+ # Delete
+ ########
+ if state == 'absent':
+ if not exists(content) or len(content['result']) == 0:
+ module.exit_json(changed=False, state="absent")
+
+ if not module.params['login']:
+ module.exit_json(failed=True, changed=False, results='Must specifiy a user login.', state="absent")
+
+ content = zapi.get_content(zbx_class_name, 'deletemedia', [res[idname] for res in content['result']])
+
+ if content.has_key('error'):
+ module.exit_json(changed=False, results=content['error'], state="absent")
+
+ module.exit_json(changed=True, results=content['result'], state="absent")
+
+ # Create and Update
+ if state == 'present':
+ active = get_active(module.params['active'])
+ mtypeid = get_mediatype(zapi, module.params['mediatype'], module.params['mediatype_desc'])
+
+ medias = module.params['medias']
+ if medias == None:
+ medias = [{'mediatypeid': mtypeid,
+ 'sendto': module.params['sendto'],
+ 'active': active,
+ 'severity': int(get_severity(module.params['severity'])),
+ 'period': module.params['period'],
+ }]
+ else:
+ medias = preprocess_medias(zapi, medias)
+
+ params = {'users': [zbx_user_query],
+ 'medias': medias,
+ 'output': 'extend',
+ }
+
+ ########
+ # Create
+ ########
+ if not exists(content):
+ if not params['medias']:
+ module.exit_json(changed=False, results=content['result'], state='present')
+
+ # if we didn't find it, create it
+ content = zapi.get_content(zbx_class_name, 'addmedia', params)
+
+ if content.has_key('error'):
+ module.exit_json(failed=True, changed=False, results=content['error'], state="present")
+
+ module.exit_json(changed=True, results=content['result'], state='present')
+
+ # mediaid signifies an update
+ # If user params exists, check to see if they already exist in zabbix
+ # if they exist, then return as no update
+ # elif they do not exist, then take user params only
+ ########
+ # Update
+ ########
+ diff = {'medias': [], 'users': {}}
+ _ = [diff['medias'].append(media) for media in params['medias'] if not find_media(content['result'], media)]
+
+ if not diff['medias']:
+ module.exit_json(changed=False, results=content['result'], state="present")
+
+ for user in params['users']:
+ diff['users']['userid'] = user['userid']
+
+ # Medias have no real unique key so therefore we need to make it like the incoming user's request
+ diff['medias'] = medias
+
+ # We have differences and need to update
+ content = zapi.get_content(zbx_class_name, 'updatemedia', diff)
+
+ if content.has_key('error'):
+ module.exit_json(failed=True, changed=False, results=content['error'], state="present")
+
+ module.exit_json(changed=True, results=content['result'], state="present")
+
+ module.exit_json(failed=True,
+ changed=False,
+ results='Unknown state passed. %s' % state,
+ state="unknown")
+
+# pylint: disable=redefined-builtin, unused-wildcard-import, wildcard-import, locally-disabled
+# import module snippets. This are required
+from ansible.module_utils.basic import *
+
+main()
diff --git a/roles/lib_zabbix/library/zbx_usergroup.py b/roles/lib_zabbix/library/zbx_usergroup.py
new file mode 100644
index 000000000..297d8ef91
--- /dev/null
+++ b/roles/lib_zabbix/library/zbx_usergroup.py
@@ -0,0 +1,208 @@
+#!/usr/bin/env python
+'''
+zabbix ansible module for usergroups
+'''
+# vim: expandtab:tabstop=4:shiftwidth=4
+#
+# Zabbix usergroup ansible module
+#
+#
+# Copyright 2015 Red Hat Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+# This is in place because each module looks similar to each other.
+# These need duplicate code as their behavior is very similar
+# but different for each zabbix class.
+# pylint: disable=duplicate-code
+
+# pylint: disable=import-error
+from openshift_tools.monitoring.zbxapi import ZabbixAPI, ZabbixConnection
+
+def exists(content, key='result'):
+ ''' Check if key exists in content or the size of content[key] > 0
+ '''
+ if not content.has_key(key):
+ return False
+
+ if not content[key]:
+ return False
+
+ return True
+
+def get_rights(zapi, rights):
+ '''Get rights
+ '''
+ if rights == None:
+ return None
+
+ perms = []
+ for right in rights:
+ hstgrp = right.keys()[0]
+ perm = right.values()[0]
+ content = zapi.get_content('hostgroup', 'get', {'search': {'name': hstgrp}})
+ if content['result']:
+ permission = 0
+ if perm == 'ro':
+ permission = 2
+ elif perm == 'rw':
+ permission = 3
+ perms.append({'id': content['result'][0]['groupid'],
+ 'permission': permission})
+ return perms
+
+def get_gui_access(access):
+ ''' Return the gui_access for a usergroup
+ '''
+ access = access.lower()
+ if access == 'internal':
+ return 1
+ elif access == 'disabled':
+ return 2
+
+ return 0
+
+def get_debug_mode(mode):
+ ''' Return the debug_mode for a usergroup
+ '''
+ mode = mode.lower()
+ if mode == 'enabled':
+ return 1
+
+ return 0
+
+def get_user_status(status):
+ ''' Return the user_status for a usergroup
+ '''
+ status = status.lower()
+ if status == 'enabled':
+ return 0
+
+ return 1
+
+
+#def get_userids(zapi, users):
+# ''' Get userids from user aliases
+# '''
+# if not users:
+# return None
+#
+# userids = []
+# for alias in users:
+# content = zapi.get_content('user', 'get', {'search': {'alias': alias}})
+# if content['result']:
+# userids.append(content['result'][0]['userid'])
+#
+# return userids
+
+def main():
+ ''' Ansible module for usergroup
+ '''
+
+ ##def usergroup(self, name, rights=None, users=None, state='present', params=None):
+
+ module = AnsibleModule(
+ argument_spec=dict(
+ zbx_server=dict(default='https://localhost/zabbix/api_jsonrpc.php', type='str'),
+ zbx_user=dict(default=os.environ.get('ZABBIX_USER', None), type='str'),
+ zbx_password=dict(default=os.environ.get('ZABBIX_PASSWORD', None), type='str'),
+ zbx_debug=dict(default=False, type='bool'),
+ debug_mode=dict(default='disabled', type='str'),
+ gui_access=dict(default='default', type='str'),
+ status=dict(default='enabled', type='str'),
+ name=dict(default=None, type='str', required=True),
+ rights=dict(default=None, type='list'),
+ #users=dict(default=None, type='list'),
+ state=dict(default='present', type='str'),
+ ),
+ #supports_check_mode=True
+ )
+
+ zapi = ZabbixAPI(ZabbixConnection(module.params['zbx_server'],
+ module.params['zbx_user'],
+ module.params['zbx_password'],
+ module.params['zbx_debug']))
+
+ zbx_class_name = 'usergroup'
+ idname = "usrgrpid"
+ uname = module.params['name']
+ state = module.params['state']
+
+ content = zapi.get_content(zbx_class_name,
+ 'get',
+ {'search': {'name': uname},
+ 'selectUsers': 'userid',
+ })
+ if state == 'list':
+ module.exit_json(changed=False, results=content['result'], state="list")
+
+ if state == 'absent':
+ if not exists(content):
+ module.exit_json(changed=False, state="absent")
+
+ if not uname:
+ module.exit_json(failed=True, changed=False, results='Need to pass in a user.', state="error")
+
+ content = zapi.get_content(zbx_class_name, 'delete', [content['result'][0][idname]])
+ module.exit_json(changed=True, results=content['result'], state="absent")
+
+ if state == 'present':
+
+ params = {'name': uname,
+ 'rights': get_rights(zapi, module.params['rights']),
+ 'users_status': get_user_status(module.params['status']),
+ 'gui_access': get_gui_access(module.params['gui_access']),
+ 'debug_mode': get_debug_mode(module.params['debug_mode']),
+ #'userids': get_userids(zapi, module.params['users']),
+ }
+
+ _ = [params.pop(key, None) for key in params.keys() if params[key] == None]
+
+ if not exists(content):
+ # if we didn't find it, create it
+ content = zapi.get_content(zbx_class_name, 'create', params)
+ module.exit_json(changed=True, results=content['result'], state='present')
+ # already exists, we need to update it
+ # let's compare properties
+ differences = {}
+ zab_results = content['result'][0]
+ for key, value in params.items():
+ if key == 'rights':
+ differences['rights'] = value
+
+ #elif key == 'userids' and zab_results.has_key('users'):
+ #if zab_results['users'] != value:
+ #differences['userids'] = value
+
+ elif zab_results[key] != value and zab_results[key] != str(value):
+ differences[key] = value
+
+ if not differences:
+ module.exit_json(changed=False, results=zab_results, state="present")
+
+ # We have differences and need to update
+ differences[idname] = zab_results[idname]
+ content = zapi.get_content(zbx_class_name, 'update', differences)
+ module.exit_json(changed=True, results=content['result'], state="present")
+
+ module.exit_json(failed=True,
+ changed=False,
+ results='Unknown state passed. %s' % state,
+ state="unknown")
+
+# pylint: disable=redefined-builtin, unused-wildcard-import, wildcard-import, locally-disabled
+# import module snippets. This are required
+from ansible.module_utils.basic import *
+
+main()
diff --git a/roles/lib_zabbix/tasks/create_template.yml b/roles/lib_zabbix/tasks/create_template.yml
new file mode 100644
index 000000000..ac9cf756b
--- /dev/null
+++ b/roles/lib_zabbix/tasks/create_template.yml
@@ -0,0 +1,101 @@
+---
+- name: Template Create Template
+ zbx_template:
+ zbx_server: "{{ server }}"
+ zbx_user: "{{ user }}"
+ zbx_password: "{{ password }}"
+ name: "{{ template.name }}"
+ register: created_template
+
+
+- set_fact:
+ lzbx_item_applications: "{{ template.zitems | default([], True) | oo_select_keys_from_list(['applications']) | oo_flatten | unique }}"
+ lzbx_itemprototype_applications: "{{ template.zitemprototypes | default([], True) | oo_select_keys_from_list(['applications']) | oo_flatten | unique }}"
+
+- name: Create Application
+ zbx_application:
+ zbx_server: "{{ server }}"
+ zbx_user: "{{ user }}"
+ zbx_password: "{{ password }}"
+ name: "{{ item }}"
+ template_name: "{{ template.name }}"
+ with_items:
+ - "{{ lzbx_item_applications }}"
+ - "{{ lzbx_itemprototype_applications }}"
+ register: created_application
+ when: template.zitems is defined or template.zitemprototypes is defined
+
+- name: Create Items
+ zbx_item:
+ zbx_server: "{{ server }}"
+ zbx_user: "{{ user }}"
+ zbx_password: "{{ password }}"
+ key: "{{ item.key }}"
+ name: "{{ item.name | default(item.key, true) }}"
+ value_type: "{{ item.value_type | default('int') }}"
+ description: "{{ item.description | default('', True) }}"
+ multiplier: "{{ item.multiplier | default('', True) }}"
+ units: "{{ item.units | default('', True) }}"
+ template_name: "{{ template.name }}"
+ applications: "{{ item.applications }}"
+ zabbix_type: "{{ item.zabbix_type | default('trapper') }}"
+ interval: "{{ item.interval | default(60, True) }}"
+ delta: "{{ item.delta | default(0, True) }}"
+ with_items: template.zitems
+ register: created_items
+ when: template.zitems is defined
+
+- name: Create Triggers
+ zbx_trigger:
+ zbx_server: "{{ server }}"
+ zbx_user: "{{ user }}"
+ zbx_password: "{{ password }}"
+ name: "{{ item.name }}"
+ description: "{{ item.description | default('', True) }}"
+ dependencies: "{{ item.dependencies | default([], True) }}"
+ expression: "{{ item.expression }}"
+ priority: "{{ item.priority }}"
+ url: "{{ item.url | default(None, True) }}"
+ with_items: template.ztriggers
+ when: template.ztriggers is defined
+
+- name: Create Discoveryrules
+ zbx_discoveryrule:
+ zbx_server: "{{ server }}"
+ zbx_user: "{{ user }}"
+ zbx_password: "{{ password }}"
+ name: "{{ item.name }}"
+ key: "{{ item.key }}"
+ lifetime: "{{ item.lifetime }}"
+ template_name: "{{ template.name }}"
+ description: "{{ item.description | default('', True) }}"
+ with_items: template.zdiscoveryrules
+ when: template.zdiscoveryrules is defined
+
+- name: Create Item Prototypes
+ zbx_itemprototype:
+ zbx_server: "{{ server }}"
+ zbx_user: "{{ user }}"
+ zbx_password: "{{ password }}"
+ name: "{{ item.name }}"
+ key: "{{ item.key }}"
+ discoveryrule_key: "{{ item.discoveryrule_key }}"
+ value_type: "{{ item.value_type }}"
+ template_name: "{{ template.name }}"
+ applications: "{{ item.applications }}"
+ description: "{{ item.description | default('', True) }}"
+ with_items: template.zitemprototypes
+ when: template.zitemprototypes is defined
+
+- name: Create Trigger Prototypes
+ zbx_triggerprototype:
+ zbx_server: "{{ server }}"
+ zbx_user: "{{ user }}"
+ zbx_password: "{{ password }}"
+ name: "{{ item.name }}"
+ expression: "{{ item.expression }}"
+ url: "{{ item.url | default('', True) }}"
+ priority: "{{ item.priority | default('average', True) }}"
+ description: "{{ item.description | default('', True) }}"
+ with_items: template.ztriggerprototypes
+ when: template.ztriggerprototypes is defined
diff --git a/roles/lib_zabbix/tasks/create_user.yml b/roles/lib_zabbix/tasks/create_user.yml
new file mode 100644
index 000000000..1f752a9e1
--- /dev/null
+++ b/roles/lib_zabbix/tasks/create_user.yml
@@ -0,0 +1,11 @@
+---
+- name: Update zabbix credentialss for a user
+ zbx_user:
+ server: "{{ ozb_server }}"
+ user: "{{ ozb_user }}"
+ password: "{{ ozb_password }}"
+ alias: "{{ ozb_username }}"
+ passwd: "{{ ozb_new_password | default(ozb_password, true) }}"
+ register: user
+
+- debug: var=user.results
diff --git a/roles/nickhammond.logrotate/.travis.yml b/roles/nickhammond.logrotate/.travis.yml
new file mode 100644
index 000000000..161023def
--- /dev/null
+++ b/roles/nickhammond.logrotate/.travis.yml
@@ -0,0 +1,14 @@
+---
+language: python
+python: "2.7"
+before_install:
+ - sudo apt-get update -qq
+ - sudo apt-get install -qq python-apt python-pycurl
+install:
+ - pip install ansible
+script:
+ - "printf '[defaults]\nroles_path = ../' > ansible.cfg"
+ - ansible-playbook -i tests/inventory --syntax-check tests/test.yml
+ - ansible-playbook -i tests/inventory --connection=local --sudo -vvvv tests/test.yml
+notifications:
+ email: false
diff --git a/roles/nickhammond.logrotate/README.md b/roles/nickhammond.logrotate/README.md
new file mode 100644
index 000000000..602b5ef6c
--- /dev/null
+++ b/roles/nickhammond.logrotate/README.md
@@ -0,0 +1,71 @@
+[![Build Status](https://travis-ci.org/nickhammond/ansible-logrotate.svg?branch=master)](https://travis-ci.org/nickhammond/ansible-logrotate)
+
+Role Name
+========
+
+Installs logrotate and provides an easy way to setup additional logrotate scripts by specifying a list of directives.
+
+Requirements
+------------
+
+None
+
+Role Variables
+--------------
+
+**logrotate_scripts**: A list of logrotate scripts and the directives to use for the rotation.
+
+* name - The name of the script that goes into /etc/logrotate.d/
+* path - Path to point logrotate to for the log rotation
+* options - List of directives for logrotate, view the logrotate man page for specifics
+* scripts - Dict of scripts for logrotate (see Example below)
+
+```
+logrotate_scripts:
+ - name: rails
+ path: "/srv/current/log/*.log"
+ options:
+ - weekly
+ - size 25M
+ - missingok
+ - compress
+ - delaycompress
+ - copytruncate
+```
+
+Dependencies
+------------
+
+None
+
+Example Playbook
+-------------------------
+
+Setting up logrotate for additional Nginx logs, with postrotate script.
+
+```
+logrotate_scripts:
+ - name: nginx
+ path: /var/log/nginx/*.log
+ options:
+ - weekly
+ - size 25M
+ - rotate 7
+ - missingok
+ - compress
+ - delaycompress
+ - copytruncate
+ scripts:
+ postrotate: "[ -s /run/nginx.pid ] && kill USR1 `cat /run/nginx.pid`"
+
+```
+
+License
+-------
+
+BSD
+
+Author Information
+------------------
+
+Find [Nick Hammond]( http://www.nickhammond.com ) on [Twitter](http://twitter.com/nickhammond).
diff --git a/roles/nickhammond.logrotate/meta/.galaxy_install_info b/roles/nickhammond.logrotate/meta/.galaxy_install_info
new file mode 100644
index 000000000..0d76708c9
--- /dev/null
+++ b/roles/nickhammond.logrotate/meta/.galaxy_install_info
@@ -0,0 +1 @@
+{install_date: 'Thu Aug 27 15:26:31 2015', version: master}
diff --git a/roles/nickhammond.logrotate/meta/main.yml b/roles/nickhammond.logrotate/meta/main.yml
new file mode 100644
index 000000000..1717b6d3d
--- /dev/null
+++ b/roles/nickhammond.logrotate/meta/main.yml
@@ -0,0 +1,15 @@
+---
+galaxy_info:
+ author: Nick Hammond
+ description: Role to configure logrotate scripts
+ license: BSD
+ min_ansible_version: 1.5
+ platforms:
+ - name: Ubuntu
+ versions:
+ - lucid
+ - precise
+ - trusty
+ categories:
+ - system
+dependencies: []
diff --git a/roles/nickhammond.logrotate/tasks/main.yml b/roles/nickhammond.logrotate/tasks/main.yml
new file mode 100644
index 000000000..fda23e05e
--- /dev/null
+++ b/roles/nickhammond.logrotate/tasks/main.yml
@@ -0,0 +1,10 @@
+---
+- name: nickhammond.logrotate | Install logrotate
+ action: "{{ansible_pkg_mgr}} pkg=logrotate state=present"
+
+- name: nickhammond.logrotate | Setup logrotate.d scripts
+ template:
+ src: logrotate.d.j2
+ dest: /etc/logrotate.d/{{ item.name }}
+ with_items: logrotate_scripts
+ when: logrotate_scripts is defined
diff --git a/roles/nickhammond.logrotate/templates/logrotate.d.j2 b/roles/nickhammond.logrotate/templates/logrotate.d.j2
new file mode 100644
index 000000000..6453be6b2
--- /dev/null
+++ b/roles/nickhammond.logrotate/templates/logrotate.d.j2
@@ -0,0 +1,16 @@
+# {{ ansible_managed }}
+
+{{ item.path }} {
+ {% if item.options is defined -%}
+ {% for option in item.options -%}
+ {{ option }}
+ {% endfor -%}
+ {% endif %}
+ {%- if item.scripts is defined -%}
+ {%- for name, script in item.scripts.iteritems() -%}
+ {{ name }}
+ {{ script }}
+ endscript
+ {% endfor -%}
+ {% endif -%}
+}
diff --git a/roles/nickhammond.logrotate/tests/inventory b/roles/nickhammond.logrotate/tests/inventory
new file mode 100644
index 000000000..2fbb50c4a
--- /dev/null
+++ b/roles/nickhammond.logrotate/tests/inventory
@@ -0,0 +1 @@
+localhost
diff --git a/roles/nickhammond.logrotate/tests/test.yml b/roles/nickhammond.logrotate/tests/test.yml
new file mode 100644
index 000000000..e806b0a02
--- /dev/null
+++ b/roles/nickhammond.logrotate/tests/test.yml
@@ -0,0 +1,18 @@
+---
+- hosts: all
+ sudo: True
+ roles:
+ - ansible-logrotate
+ - role: ansible-logrotate
+ logrotate_scripts:
+ - name: nginx-options
+ path: /var/log/nginx/options.log
+ options:
+ - daily
+
+ - role: ansible-logrotate
+ logrotate_scripts:
+ - name: nginx-scripts
+ path: /var/log/nginx/scripts.log
+ scripts:
+ postrotate: "echo test"
diff --git a/roles/openshift_ansible_inventory/README.md b/roles/openshift_ansible_inventory/README.md
index 69a07effd..b62287c12 100644
--- a/roles/openshift_ansible_inventory/README.md
+++ b/roles/openshift_ansible_inventory/README.md
@@ -1,4 +1,4 @@
-Openshift Ansible Inventory
+OpenShift Ansible Inventory
=========
Install and configure openshift-ansible-inventory.
@@ -38,4 +38,4 @@ ASL 2.0
Author Information
------------------
-Openshift operations, Red Hat, Inc
+OpenShift operations, Red Hat, Inc
diff --git a/roles/openshift_ansible_inventory/meta/main.yml b/roles/openshift_ansible_inventory/meta/main.yml
index ff3df0a7d..7f7387e80 100644
--- a/roles/openshift_ansible_inventory/meta/main.yml
+++ b/roles/openshift_ansible_inventory/meta/main.yml
@@ -1,6 +1,6 @@
---
galaxy_info:
- author: Openshift
+ author: OpenShift
description: Install and configure openshift-ansible-inventory
company: Red Hat, Inc
license: ASL 2.0
diff --git a/roles/openshift_ansible_inventory/templates/multi_ec2.yaml.j2 b/roles/openshift_ansible_inventory/templates/multi_ec2.yaml.j2
index 8228ab915..ce8515e17 100644
--- a/roles/openshift_ansible_inventory/templates/multi_ec2.yaml.j2
+++ b/roles/openshift_ansible_inventory/templates/multi_ec2.yaml.j2
@@ -15,10 +15,10 @@ accounts:
env_vars:
AWS_ACCESS_KEY_ID: {{ account.env_vars.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: {{ account.env_vars.AWS_SECRET_ACCESS_KEY }}
-{% if account.all_group is defined and account.hostvars is defined%}
+{% if account.all_group is defined and account.extra_vars is defined%}
all_group: {{ account.all_group }}
- hostvars:
-{% for property, value in account.hostvars.items() %}
+ extra_vars:
+{% for property, value in account.extra_vars.items() %}
{{ property }}: {{ value }}
{% endfor %}
{% endif %}
diff --git a/roles/openshift_cluster_metrics/README.md b/roles/openshift_cluster_metrics/README.md
new file mode 100644
index 000000000..9fdfab8e3
--- /dev/null
+++ b/roles/openshift_cluster_metrics/README.md
@@ -0,0 +1,36 @@
+#openshift_cluster_metrics
+
+This role configures Cluster wide metrics. It does setting up three services:
+* Metrics are stored in InfluxDB for querying.
+* Heapster reads all nodes and pods from the master, then connects to eachs node's kubelet to retrieve pod metrics.
+* Grafan allows users to create dashboards of metrics from InfluxDB
+
+## Requirements
+
+Running OpenShift cluster
+
+## Role Variables
+
+```
+# Enable cluster metrics
+use_cluster_metrics=true
+```
+
+## Dependencies
+
+None
+
+## Example Playbook
+
+TODO
+
+## Security Note
+Opening up the read-only port exposes information about the running pods (such as namespace, pod name, labels, etc.) to unauthenticated clients. The requirement to open up this read-only port will be fixed in future versions.
+
+##License
+
+Apache License, Version 2.0
+
+## Author Information
+
+Diego Castro (diego.castro@getupcloud.com)
diff --git a/roles/openshift_cluster_metrics/files/cluster-metrics/grafana.yaml b/roles/openshift_cluster_metrics/files/cluster-metrics/grafana.yaml
new file mode 100644
index 000000000..bff422efc
--- /dev/null
+++ b/roles/openshift_cluster_metrics/files/cluster-metrics/grafana.yaml
@@ -0,0 +1,53 @@
+apiVersion: "v1"
+kind: "List"
+items:
+ -
+ apiVersion: "v1"
+ kind: "Service"
+ metadata:
+ labels:
+ provider: "fabric8"
+ component: "grafana"
+ name: "grafana"
+ spec:
+ ports:
+ -
+ port: 80
+ targetPort: "http"
+ selector:
+ provider: "fabric8"
+ component: "grafana"
+ -
+ apiVersion: "v1"
+ kind: "ReplicationController"
+ metadata:
+ labels:
+ provider: "fabric8"
+ component: "grafana"
+ name: "grafana"
+ spec:
+ replicas: 1
+ selector:
+ provider: "fabric8"
+ component: "grafana"
+ template:
+ metadata:
+ labels:
+ provider: "fabric8"
+ component: "grafana"
+ spec:
+ containers:
+ -
+ env:
+ -
+ name: "INFLUXDB_SERVICE_NAME"
+ value: "INFLUXDB_MONITORING"
+ -
+ name: "GRAFANA_DEFAULT_DASHBOARD"
+ value: "/dashboard/file/kubernetes.json"
+ image: "fabric8/grafana:1.9.1_2"
+ name: "grafana"
+ ports:
+ -
+ containerPort: 3000
+ name: "http" \ No newline at end of file
diff --git a/roles/openshift_cluster_metrics/files/cluster-metrics/heapster-serviceaccount.yaml b/roles/openshift_cluster_metrics/files/cluster-metrics/heapster-serviceaccount.yaml
new file mode 100644
index 000000000..1de2ad699
--- /dev/null
+++ b/roles/openshift_cluster_metrics/files/cluster-metrics/heapster-serviceaccount.yaml
@@ -0,0 +1,4 @@
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+ name: heapster \ No newline at end of file
diff --git a/roles/openshift_cluster_metrics/files/cluster-metrics/heapster.yaml b/roles/openshift_cluster_metrics/files/cluster-metrics/heapster.yaml
new file mode 100644
index 000000000..83e314074
--- /dev/null
+++ b/roles/openshift_cluster_metrics/files/cluster-metrics/heapster.yaml
@@ -0,0 +1,30 @@
+apiVersion: "v1"
+kind: "List"
+items:
+ -
+ apiVersion: "v1"
+ kind: "ReplicationController"
+ metadata:
+ labels:
+ provider: "fabric8"
+ component: "heapster"
+ name: "heapster"
+ spec:
+ replicas: 1
+ selector:
+ provider: "fabric8"
+ component: "heapster"
+ template:
+ metadata:
+ labels:
+ provider: "fabric8"
+ component: "heapster"
+ spec:
+ containers:
+ -
+ args:
+ - "-source=kubernetes:https://kubernetes.default.svc.cluster.local?auth=&insecure=true&useServiceAccount=true"
+ - "-sink=influxdb:http://influxdb-monitoring.default.svc.cluster.local:8086"
+ image: "kubernetes/heapster:V0.14.2"
+ name: "heapster"
+ serviceAccount: "heapster" \ No newline at end of file
diff --git a/roles/openshift_cluster_metrics/files/cluster-metrics/influxdb.yaml b/roles/openshift_cluster_metrics/files/cluster-metrics/influxdb.yaml
new file mode 100644
index 000000000..6f67c3d7c
--- /dev/null
+++ b/roles/openshift_cluster_metrics/files/cluster-metrics/influxdb.yaml
@@ -0,0 +1,67 @@
+apiVersion: "v1"
+kind: "List"
+items:
+ -
+ apiVersion: "v1"
+ kind: "Service"
+ metadata:
+ labels:
+ provider: "fabric8"
+ component: "influxdb-monitoring"
+ name: "influxdb-monitoring"
+ spec:
+ ports:
+ -
+ port: 8086
+ targetPort: "http"
+ selector:
+ provider: "fabric8"
+ component: "influxdb-monitoring"
+ -
+ apiVersion: "v1"
+ kind: "ReplicationController"
+ metadata:
+ labels:
+ provider: "fabric8"
+ component: "influxdb-monitoring"
+ name: "influxdb-monitoring"
+ spec:
+ replicas: 1
+ selector:
+ provider: "fabric8"
+ component: "influxdb-monitoring"
+ template:
+ metadata:
+ labels:
+ provider: "fabric8"
+ component: "influxdb-monitoring"
+ spec:
+ containers:
+ -
+ env:
+ -
+ name: "PRE_CREATE_DB"
+ value: "k8s;grafana"
+ image: "fabric8/influxdb:0.8.8"
+ name: "influxdb"
+ ports:
+ -
+ containerPort: 8090
+ name: "raft"
+ -
+ containerPort: 8099
+ name: "protobuf"
+ -
+ containerPort: 8083
+ name: "admin"
+ -
+ containerPort: 8086
+ name: "http"
+ volumeMounts:
+ -
+ mountPath: "/data"
+ name: "influxdb-data"
+ volumes:
+ -
+ emptyDir:
+ name: "influxdb-data" \ No newline at end of file
diff --git a/roles/openshift_cluster_metrics/tasks/main.yml b/roles/openshift_cluster_metrics/tasks/main.yml
new file mode 100644
index 000000000..3938aba4c
--- /dev/null
+++ b/roles/openshift_cluster_metrics/tasks/main.yml
@@ -0,0 +1,50 @@
+---
+
+- name: Install cluster metrics templates
+ copy:
+ src: cluster-metrics
+ dest: /etc/openshift/
+
+- name: Create InfluxDB Services
+ command: >
+ {{ openshift.common.client_binary }} create -f
+ /etc/openshift/cluster-metrics/influxdb.yaml
+ register: oex_influxdb_services
+ failed_when: "'already exists' not in oex_influxdb_services.stderr and oex_influxdb_services.rc != 0"
+ changed_when: false
+
+- name: Create Heapster Service Account
+ command: >
+ {{ openshift.common.client_binary }} create -f
+ /etc/openshift/cluster-metrics/heapster-serviceaccount.yaml
+ register: oex_heapster_serviceaccount
+ failed_when: "'already exists' not in oex_heapster_serviceaccount.stderr and oex_heapster_serviceaccount.rc != 0"
+ changed_when: false
+
+- name: Add cluster-reader role to Heapster
+ command: >
+ {{ openshift.common.admin_binary }} policy
+ add-cluster-role-to-user
+ cluster-reader
+ system:serviceaccount:default:heapster
+ register: oex_cluster_header_role
+ register: oex_cluster_header_role
+ failed_when: "'already exists' not in oex_cluster_header_role.stderr and oex_cluster_header_role.rc != 0"
+ changed_when: false
+
+- name: Create Heapster Services
+ command: >
+ {{ openshift.common.client_binary }} create -f
+ /etc/openshift/cluster-metrics/heapster.yaml
+ register: oex_heapster_services
+ failed_when: "'already exists' not in oex_heapster_services.stderr and oex_heapster_services.rc != 0"
+ changed_when: false
+
+- name: Create Grafana Services
+ command: >
+ {{ openshift.common.client_binary }} create -f
+ /etc/openshift/cluster-metrics/grafana.yaml
+ register: oex_grafana_services
+ failed_when: "'already exists' not in oex_grafana_services.stderr and oex_grafana_services.rc != 0"
+ changed_when: false
+
diff --git a/roles/openshift_common/README.md b/roles/openshift_common/README.md
index 14c2037e4..87306d4a6 100644
--- a/roles/openshift_common/README.md
+++ b/roles/openshift_common/README.md
@@ -1,13 +1,13 @@
-OpenShift Common
-================
+OpenShift/Atomic Enterprise Common
+===================================
-OpenShift common installation and configuration tasks.
+OpenShift/Atomic Enterprise common installation and configuration tasks.
Requirements
------------
A RHEL 7.1 host pre-configured with access to the rhel-7-server-rpms,
-rhel-7-server-extra-rpms, and rhel-7-server-ose-beta-rpms repos.
+rhel-7-server-extra-rpms, and rhel-7-server-ose-3.0-rpms repos.
Role Variables
--------------
@@ -15,7 +15,7 @@ Role Variables
| Name | Default value | |
|---------------------------|-------------------|---------------------------------------------|
| openshift_cluster_id | default | Cluster name if multiple OpenShift clusters |
-| openshift_debug_level | 0 | Global openshift debug log verbosity |
+| openshift_debug_level | 2 | Global openshift debug log verbosity |
| openshift_hostname | UNDEF | Internal hostname to use for this host (this value will set the hostname on the system) |
| openshift_ip | UNDEF | Internal IP address to use for this host |
| openshift_public_hostname | UNDEF | Public hostname to use for this host |
diff --git a/roles/openshift_common/defaults/main.yml b/roles/openshift_common/defaults/main.yml
index 4d3e0fe9e..267c03605 100644
--- a/roles/openshift_common/defaults/main.yml
+++ b/roles/openshift_common/defaults/main.yml
@@ -1,3 +1,3 @@
---
openshift_cluster_id: 'default'
-openshift_debug_level: 0
+openshift_debug_level: 2
diff --git a/roles/openshift_common/tasks/main.yml b/roles/openshift_common/tasks/main.yml
index f76dd84ed..73bd28630 100644
--- a/roles/openshift_common/tasks/main.yml
+++ b/roles/openshift_common/tasks/main.yml
@@ -1,10 +1,10 @@
---
-- name: Set common OpenShift facts
+- name: Set common Cluster facts
openshift_facts:
role: common
local_facts:
cluster_id: "{{ openshift_cluster_id | default('default') }}"
- debug_level: "{{ openshift_debug_level | default(0) }}"
+ debug_level: "{{ openshift_debug_level | default(2) }}"
hostname: "{{ openshift_hostname | default(None) }}"
ip: "{{ openshift_ip | default(None) }}"
public_hostname: "{{ openshift_public_hostname | default(None) }}"
@@ -12,7 +12,7 @@
use_openshift_sdn: "{{ openshift_use_openshift_sdn | default(None) }}"
sdn_network_plugin_name: "{{ os_sdn_network_plugin_name | default(None) }}"
deployment_type: "{{ openshift_deployment_type }}"
+ use_fluentd: "{{ openshift_use_fluentd | default(None) }}"
- name: Set hostname
hostname: name={{ openshift.common.hostname }}
-
diff --git a/roles/openshift_common/vars/main.yml b/roles/openshift_common/vars/main.yml
index 8e7d71154..50816d319 100644
--- a/roles/openshift_common/vars/main.yml
+++ b/roles/openshift_common/vars/main.yml
@@ -5,5 +5,3 @@
# chains with the public zone (or the zone associated with the correct
# interfaces)
os_firewall_use_firewalld: False
-
-openshift_data_dir: /var/lib/openshift
diff --git a/roles/openshift_examples/README.md b/roles/openshift_examples/README.md
new file mode 100644
index 000000000..7d8735a0a
--- /dev/null
+++ b/roles/openshift_examples/README.md
@@ -0,0 +1,49 @@
+OpenShift Examples
+================
+
+Installs example image streams, db-templates, and quickstart-templates by copying
+examples from this module to your first master and importing them with oc create -n into the openshift namespace
+
+The examples-sync.sh script can be used to pull the latest content from github
+and stage it for updating the ansible repo. This script is not used directly by
+ansible.
+
+Requirements
+------------
+
+Role Variables
+--------------
+
+| Name | Default value | |
+|-------------------------------------|-----------------------------------------------------|------------------------------------------|
+| openshift_examples_load_centos | true when openshift_deployment_typenot 'enterprise' | Load centos image streams |
+| openshift_examples_load_rhel | true if openshift_deployment_type is 'enterprise' | Load rhel image streams |
+| openshift_examples_load_db_templates| true | Loads databcase templates |
+| openshift_examples_load_quickstarts | true | Loads quickstarts ie: nodejs, rails, etc |
+| openshift_examples_load_xpaas | false | Loads xpass streams and templates |
+
+
+Dependencies
+------------
+
+Example Playbook
+----------------
+
+TODO
+----
+Currently we use `oc create -f` against various files and we accept non zero return code as a success
+if (and only iff) stderr also contains the string 'already exists'. This means that if one object in the file exists already
+but others fail to create you won't be aware of the failure. This also means that we do not currently support
+updating existing objects.
+
+We should add the ability to compare existing image streams against those we're being asked to load and update if necessary.
+
+License
+-------
+
+Apache License, Version 2.0
+
+Author Information
+------------------
+
+Scott Dodson (sdodson@redhat.com)
diff --git a/roles/openshift_examples/defaults/main.yml b/roles/openshift_examples/defaults/main.yml
new file mode 100644
index 000000000..2043985ec
--- /dev/null
+++ b/roles/openshift_examples/defaults/main.yml
@@ -0,0 +1,18 @@
+---
+# By default install rhel and xpaas streams on enterprise installs
+openshift_examples_load_centos: "{{ openshift_deployment_type not in ['enterprise','openshift-enterprise','atomic-enterprise','online'] }}"
+openshift_examples_load_rhel: "{{ openshift_deployment_type in ['enterprise','openshift-enterprise','atomic-enterprise','online'] }}"
+openshift_examples_load_db_templates: true
+openshift_examples_load_xpaas: "{{ openshift_deployment_type in ['enterprise','openshift-enterprise','atomic-enterprise','online'] }}"
+openshift_examples_load_quickstarts: true
+
+examples_base: /usr/share/openshift/examples
+image_streams_base: "{{ examples_base }}/image-streams"
+centos_image_streams: "{{ image_streams_base}}/image-streams-centos7.json"
+rhel_image_streams: "{{ image_streams_base}}/image-streams-rhel7.json"
+db_templates_base: "{{ examples_base }}/db-templates"
+xpaas_image_streams: "{{ examples_base }}/xpaas-streams/jboss-image-streams.json"
+xpaas_templates_base: "{{ examples_base }}/xpaas-templates"
+quickstarts_base: "{{ examples_base }}/quickstart-templates"
+
+openshift_examples_import_command: "create"
diff --git a/roles/openshift_examples/examples-sync.sh b/roles/openshift_examples/examples-sync.sh
new file mode 100755
index 000000000..21137e31b
--- /dev/null
+++ b/roles/openshift_examples/examples-sync.sh
@@ -0,0 +1,37 @@
+#!/bin/bash
+
+# Utility script to update the ansible repo with the latest templates and image
+# streams from several github repos
+#
+# This script should be run from openshift-ansible/roles/openshift_examples
+
+EXAMPLES_BASE=$(pwd)/files/examples
+find files/examples -name '*.json' -delete
+TEMP=`mktemp -d`
+pushd $TEMP
+wget https://github.com/openshift/origin/archive/master.zip -O origin-master.zip
+wget https://github.com/openshift/django-ex/archive/master.zip -O django-ex-master.zip
+wget https://github.com/openshift/rails-ex/archive/master.zip -O rails-ex-master.zip
+wget https://github.com/openshift/nodejs-ex/archive/master.zip -O nodejs-ex-master.zip
+wget https://github.com/openshift/dancer-ex/archive/master.zip -O dancer-ex-master.zip
+wget https://github.com/openshift/cakephp-ex/archive/master.zip -O cakephp-ex-master.zip
+wget https://github.com/jboss-openshift/application-templates/archive/ose-v1.0.2.zip -O application-templates-master.zip
+unzip origin-master.zip
+unzip django-ex-master.zip
+unzip rails-ex-master.zip
+unzip nodejs-ex-master.zip
+unzip dancer-ex-master.zip
+unzip cakephp-ex-master.zip
+unzip application-templates-master.zip
+cp origin-master/examples/db-templates/* ${EXAMPLES_BASE}/db-templates/
+cp origin-master/examples/jenkins/jenkins-*template.json ${EXAMPLES_BASE}/quickstart-templates/
+cp origin-master/examples/image-streams/* ${EXAMPLES_BASE}/image-streams/
+cp django-ex-master/openshift/templates/* ${EXAMPLES_BASE}/quickstart-templates/
+cp rails-ex-master/openshift/templates/* ${EXAMPLES_BASE}/quickstart-templates/
+cp nodejs-ex-master/openshift/templates/* ${EXAMPLES_BASE}/quickstart-templates/
+cp dancer-ex-master/openshift/templates/* ${EXAMPLES_BASE}/quickstart-templates/
+cp cakephp-ex-master/openshift/templates/* ${EXAMPLES_BASE}/quickstart-templates/
+mv application-templates-master/jboss-image-streams.json ${EXAMPLES_BASE}/xpaas-streams/
+find application-templates-master/ -name '*.json' ! -wholename '*secret*' -exec mv {} ${EXAMPLES_BASE}/xpaas-templates/ \;
+popd
+git diff files/examples
diff --git a/roles/openshift_examples/files/examples/db-templates/mongodb-ephemeral-template.json b/roles/openshift_examples/files/examples/db-templates/mongodb-ephemeral-template.json
new file mode 100644
index 000000000..6b90fa54e
--- /dev/null
+++ b/roles/openshift_examples/files/examples/db-templates/mongodb-ephemeral-template.json
@@ -0,0 +1,184 @@
+{
+ "kind": "Template",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "mongodb-ephemeral",
+ "creationTimestamp": null,
+ "annotations": {
+ "description": "MongoDB database service, without persistent storage. WARNING: Any data stored will be lost upon pod destruction. Only use this template for testing",
+ "iconClass": "icon-mongodb",
+ "tags": "database,mongodb"
+ }
+ },
+ "objects": [
+ {
+ "kind": "Service",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "${DATABASE_SERVICE_NAME}",
+ "creationTimestamp": null
+ },
+ "spec": {
+ "ports": [
+ {
+ "name": "mongo",
+ "protocol": "TCP",
+ "port": 27017,
+ "targetPort": 27017,
+ "nodePort": 0
+ }
+ ],
+ "selector": {
+ "name": "${DATABASE_SERVICE_NAME}"
+ },
+ "portalIP": "",
+ "type": "ClusterIP",
+ "sessionAffinity": "None"
+ },
+ "status": {
+ "loadBalancer": {}
+ }
+ },
+ {
+ "kind": "DeploymentConfig",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "${DATABASE_SERVICE_NAME}",
+ "creationTimestamp": null
+ },
+ "spec": {
+ "strategy": {
+ "type": "Recreate",
+ "resources": {}
+ },
+ "triggers": [
+ {
+ "type": "ImageChange",
+ "imageChangeParams": {
+ "automatic": true,
+ "containerNames": [
+ "mongodb"
+ ],
+ "from": {
+ "kind": "ImageStreamTag",
+ "name": "mongodb:latest",
+ "namespace": "openshift"
+ },
+ "lastTriggeredImage": ""
+ }
+ },
+ {
+ "type": "ConfigChange"
+ }
+ ],
+ "replicas": 1,
+ "selector": {
+ "name": "${DATABASE_SERVICE_NAME}"
+ },
+ "template": {
+ "metadata": {
+ "creationTimestamp": null,
+ "labels": {
+ "name": "${DATABASE_SERVICE_NAME}"
+ }
+ },
+ "spec": {
+ "containers": [
+ {
+ "name": "mongodb",
+ "image": "mongodb",
+ "ports": [
+ {
+ "containerPort": 27017,
+ "protocol": "TCP"
+ }
+ ],
+ "env": [
+ {
+ "name": "MONGODB_USER",
+ "value": "${MONGODB_USER}"
+ },
+ {
+ "name": "MONGODB_PASSWORD",
+ "value": "${MONGODB_PASSWORD}"
+ },
+ {
+ "name": "MONGODB_DATABASE",
+ "value": "${MONGODB_DATABASE}"
+ },
+ {
+ "name": "MONGODB_ADMIN_PASSWORD",
+ "value": "${MONGODB_ADMIN_PASSWORD}"
+ }
+ ],
+ "resources": {},
+ "volumeMounts": [
+ {
+ "name": "${DATABASE_SERVICE_NAME}-data",
+ "mountPath": "/var/lib/mongodb/data"
+ }
+ ],
+ "terminationMessagePath": "/dev/termination-log",
+ "imagePullPolicy": "IfNotPresent",
+ "capabilities": {},
+ "securityContext": {
+ "capabilities": {},
+ "privileged": false
+ }
+ }
+ ],
+ "volumes": [
+ {
+ "name": "${DATABASE_SERVICE_NAME}-data",
+ "emptyDir": {
+ "medium": ""
+ }
+ }
+ ],
+ "restartPolicy": "Always",
+ "dnsPolicy": "ClusterFirst"
+ }
+ }
+ },
+ "status": {}
+ }
+ ],
+ "parameters": [
+ {
+ "name": "DATABASE_SERVICE_NAME",
+ "description": "Database service name",
+ "value": "mongodb",
+ "required": true
+ },
+ {
+ "name": "MONGODB_USER",
+ "description": "Username for MongoDB user that will be used for accessing the database",
+ "generate": "expression",
+ "from": "user[A-Z0-9]{3}",
+ "required": true
+ },
+ {
+ "name": "MONGODB_PASSWORD",
+ "description": "Password for the MongoDB user",
+ "generate": "expression",
+ "from": "[a-zA-Z0-9]{16}",
+ "required": true
+ },
+ {
+ "name": "MONGODB_DATABASE",
+ "description": "Database name",
+ "value": "sampledb",
+ "required": true
+ },
+ {
+ "name": "MONGODB_ADMIN_PASSWORD",
+ "description": "Password for the database admin user",
+ "generate": "expression",
+ "from": "[a-zA-Z0-9]{16}",
+ "required": true
+ }
+ ],
+ "labels": {
+ "template": "mongodb-ephemeral-template"
+ }
+}
diff --git a/roles/openshift_examples/files/examples/db-templates/mongodb-persistent-template.json b/roles/openshift_examples/files/examples/db-templates/mongodb-persistent-template.json
new file mode 100644
index 000000000..97b315600
--- /dev/null
+++ b/roles/openshift_examples/files/examples/db-templates/mongodb-persistent-template.json
@@ -0,0 +1,207 @@
+{
+ "kind": "Template",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "mongodb-persistent",
+ "creationTimestamp": null,
+ "annotations": {
+ "description": "MongoDB database service, with persistent storage. Scaling to more than one replica is not supported",
+ "iconClass": "icon-mongodb",
+ "tags": "database,mongodb"
+ }
+ },
+ "objects": [
+ {
+ "kind": "Service",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "${DATABASE_SERVICE_NAME}",
+ "creationTimestamp": null
+ },
+ "spec": {
+ "ports": [
+ {
+ "name": "mongo",
+ "protocol": "TCP",
+ "port": 27017,
+ "targetPort": 27017,
+ "nodePort": 0
+ }
+ ],
+ "selector": {
+ "name": "${DATABASE_SERVICE_NAME}"
+ },
+ "portalIP": "",
+ "type": "ClusterIP",
+ "sessionAffinity": "None"
+ },
+ "status": {
+ "loadBalancer": {}
+ }
+ },
+ {
+ "kind": "PersistentVolumeClaim",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "${DATABASE_SERVICE_NAME}"
+ },
+ "spec": {
+ "accessModes": [
+ "ReadWriteOnce"
+ ],
+ "resources": {
+ "requests": {
+ "storage": "${VOLUME_CAPACITY}"
+ }
+ }
+ }
+ },
+ {
+ "kind": "DeploymentConfig",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "${DATABASE_SERVICE_NAME}",
+ "creationTimestamp": null
+ },
+ "spec": {
+ "strategy": {
+ "type": "Recreate",
+ "resources": {}
+ },
+ "triggers": [
+ {
+ "type": "ImageChange",
+ "imageChangeParams": {
+ "automatic": true,
+ "containerNames": [
+ "mongodb"
+ ],
+ "from": {
+ "kind": "ImageStreamTag",
+ "name": "mongodb:latest",
+ "namespace": "openshift"
+ },
+ "lastTriggeredImage": ""
+ }
+ },
+ {
+ "type": "ConfigChange"
+ }
+ ],
+ "replicas": 1,
+ "selector": {
+ "name": "${DATABASE_SERVICE_NAME}"
+ },
+ "template": {
+ "metadata": {
+ "creationTimestamp": null,
+ "labels": {
+ "name": "${DATABASE_SERVICE_NAME}"
+ }
+ },
+ "spec": {
+ "containers": [
+ {
+ "name": "mongodb",
+ "image": "mongodb",
+ "ports": [
+ {
+ "containerPort": 27017,
+ "protocol": "TCP"
+ }
+ ],
+ "env": [
+ {
+ "name": "MONGODB_USER",
+ "value": "${MONGODB_USER}"
+ },
+ {
+ "name": "MONGODB_PASSWORD",
+ "value": "${MONGODB_PASSWORD}"
+ },
+ {
+ "name": "MONGODB_DATABASE",
+ "value": "${MONGODB_DATABASE}"
+ },
+ {
+ "name": "MONGODB_ADMIN_PASSWORD",
+ "value": "${MONGODB_ADMIN_PASSWORD}"
+ }
+ ],
+ "resources": {},
+ "volumeMounts": [
+ {
+ "name": "${DATABASE_SERVICE_NAME}-data",
+ "mountPath": "/var/lib/mongodb/data"
+ }
+ ],
+ "terminationMessagePath": "/dev/termination-log",
+ "imagePullPolicy": "IfNotPresent",
+ "capabilities": {},
+ "securityContext": {
+ "capabilities": {},
+ "privileged": false
+ }
+ }
+ ],
+ "volumes": [
+ {
+ "name": "${DATABASE_SERVICE_NAME}-data",
+ "persistentVolumeClaim": {
+ "claimName": "${DATABASE_SERVICE_NAME}"
+ }
+ }
+ ],
+ "restartPolicy": "Always",
+ "dnsPolicy": "ClusterFirst"
+ }
+ }
+ },
+ "status": {}
+ }
+ ],
+ "parameters": [
+ {
+ "name": "DATABASE_SERVICE_NAME",
+ "description": "Database service name",
+ "value": "mongodb",
+ "required": true
+ },
+ {
+ "name": "MONGODB_USER",
+ "description": "Username for MongoDB user that will be used for accessing the database",
+ "generate": "expression",
+ "from": "user[A-Z0-9]{3}",
+ "required": true
+ },
+ {
+ "name": "MONGODB_PASSWORD",
+ "description": "Password for the MongoDB user",
+ "generate": "expression",
+ "from": "[a-zA-Z0-9]{16}",
+ "required": true
+ },
+ {
+ "name": "MONGODB_DATABASE",
+ "description": "Database name",
+ "value": "sampledb",
+ "required": true
+ },
+ {
+ "name": "MONGODB_ADMIN_PASSWORD",
+ "description": "Password for the database admin user",
+ "generate": "expression",
+ "from": "[a-zA-Z0-9]{16}",
+ "required": true
+ },
+ {
+ "name": "VOLUME_CAPACITY",
+ "description": "Volume space available for data, e.g. 512Mi, 2Gi",
+ "value": "512Mi",
+ "required": true
+ }
+ ],
+ "labels": {
+ "template": "mongodb-persistent-template"
+ }
+}
diff --git a/roles/openshift_examples/files/examples/db-templates/mysql-ephemeral-template.json b/roles/openshift_examples/files/examples/db-templates/mysql-ephemeral-template.json
new file mode 100644
index 000000000..b384a5992
--- /dev/null
+++ b/roles/openshift_examples/files/examples/db-templates/mysql-ephemeral-template.json
@@ -0,0 +1,173 @@
+{
+ "kind": "Template",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "mysql-ephemeral",
+ "creationTimestamp": null,
+ "annotations": {
+ "description": "MySQL database service, without persistent storage. WARNING: Any data stored will be lost upon pod destruction. Only use this template for testing",
+ "iconClass": "icon-mysql-database",
+ "tags": "database,mysql"
+ }
+ },
+ "objects": [
+ {
+ "kind": "Service",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "${DATABASE_SERVICE_NAME}",
+ "creationTimestamp": null
+ },
+ "spec": {
+ "ports": [
+ {
+ "name": "mysql",
+ "protocol": "TCP",
+ "port": 3306,
+ "targetPort": 3306,
+ "nodePort": 0
+ }
+ ],
+ "selector": {
+ "name": "${DATABASE_SERVICE_NAME}"
+ },
+ "portalIP": "",
+ "type": "ClusterIP",
+ "sessionAffinity": "None"
+ },
+ "status": {
+ "loadBalancer": {}
+ }
+ },
+ {
+ "kind": "DeploymentConfig",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "${DATABASE_SERVICE_NAME}",
+ "creationTimestamp": null
+ },
+ "spec": {
+ "strategy": {
+ "type": "Recreate",
+ "resources": {}
+ },
+ "triggers": [
+ {
+ "type": "ImageChange",
+ "imageChangeParams": {
+ "automatic": true,
+ "containerNames": [
+ "mysql"
+ ],
+ "from": {
+ "kind": "ImageStreamTag",
+ "name": "mysql:latest",
+ "namespace": "openshift"
+ },
+ "lastTriggeredImage": ""
+ }
+ },
+ {
+ "type": "ConfigChange"
+ }
+ ],
+ "replicas": 1,
+ "selector": {
+ "name": "${DATABASE_SERVICE_NAME}"
+ },
+ "template": {
+ "metadata": {
+ "creationTimestamp": null,
+ "labels": {
+ "name": "${DATABASE_SERVICE_NAME}"
+ }
+ },
+ "spec": {
+ "containers": [
+ {
+ "name": "mysql",
+ "image": "mysql",
+ "ports": [
+ {
+ "containerPort": 3306,
+ "protocol": "TCP"
+ }
+ ],
+ "env": [
+ {
+ "name": "MYSQL_USER",
+ "value": "${MYSQL_USER}"
+ },
+ {
+ "name": "MYSQL_PASSWORD",
+ "value": "${MYSQL_PASSWORD}"
+ },
+ {
+ "name": "MYSQL_DATABASE",
+ "value": "${MYSQL_DATABASE}"
+ }
+ ],
+ "resources": {},
+ "volumeMounts": [
+ {
+ "name": "${DATABASE_SERVICE_NAME}-data",
+ "mountPath": "/var/lib/mysql/data"
+ }
+ ],
+ "terminationMessagePath": "/dev/termination-log",
+ "imagePullPolicy": "IfNotPresent",
+ "capabilities": {},
+ "securityContext": {
+ "capabilities": {},
+ "privileged": false
+ }
+ }
+ ],
+ "volumes": [
+ {
+ "name": "${DATABASE_SERVICE_NAME}-data",
+ "emptyDir": {
+ "medium": ""
+ }
+ }
+ ],
+ "restartPolicy": "Always",
+ "dnsPolicy": "ClusterFirst"
+ }
+ }
+ },
+ "status": {}
+ }
+ ],
+ "parameters": [
+ {
+ "name": "DATABASE_SERVICE_NAME",
+ "description": "Database service name",
+ "value": "mysql",
+ "required": true
+ },
+ {
+ "name": "MYSQL_USER",
+ "description": "Username for MySQL user that will be used for accessing the database",
+ "generate": "expression",
+ "from": "user[A-Z0-9]{3}",
+ "required": true
+ },
+ {
+ "name": "MYSQL_PASSWORD",
+ "description": "Password for the MySQL user",
+ "generate": "expression",
+ "from": "[a-zA-Z0-9]{16}",
+ "required": true
+ },
+ {
+ "name": "MYSQL_DATABASE",
+ "description": "Database name",
+ "value": "sampledb",
+ "required": true
+ }
+ ],
+ "labels": {
+ "template": "mysql-ephemeral-template"
+ }
+}
diff --git a/roles/openshift_examples/files/examples/db-templates/mysql-persistent-template.json b/roles/openshift_examples/files/examples/db-templates/mysql-persistent-template.json
new file mode 100644
index 000000000..6e19f48f5
--- /dev/null
+++ b/roles/openshift_examples/files/examples/db-templates/mysql-persistent-template.json
@@ -0,0 +1,196 @@
+{
+ "kind": "Template",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "mysql-persistent",
+ "creationTimestamp": null,
+ "annotations": {
+ "description": "MySQL database service, with persistent storage. Scaling to more than one replica is not supported",
+ "iconClass": "icon-mysql-database",
+ "tags": "database,mysql"
+ }
+ },
+ "objects": [
+ {
+ "kind": "Service",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "${DATABASE_SERVICE_NAME}",
+ "creationTimestamp": null
+ },
+ "spec": {
+ "ports": [
+ {
+ "name": "mysql",
+ "protocol": "TCP",
+ "port": 3306,
+ "targetPort": 3306,
+ "nodePort": 0
+ }
+ ],
+ "selector": {
+ "name": "${DATABASE_SERVICE_NAME}"
+ },
+ "portalIP": "",
+ "type": "ClusterIP",
+ "sessionAffinity": "None"
+ },
+ "status": {
+ "loadBalancer": {}
+ }
+ },
+ {
+ "kind": "PersistentVolumeClaim",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "${DATABASE_SERVICE_NAME}"
+ },
+ "spec": {
+ "accessModes": [
+ "ReadWriteOnce"
+ ],
+ "resources": {
+ "requests": {
+ "storage": "${VOLUME_CAPACITY}"
+ }
+ }
+ }
+ },
+ {
+ "kind": "DeploymentConfig",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "${DATABASE_SERVICE_NAME}",
+ "creationTimestamp": null
+ },
+ "spec": {
+ "strategy": {
+ "type": "Recreate",
+ "resources": {}
+ },
+ "triggers": [
+ {
+ "type": "ImageChange",
+ "imageChangeParams": {
+ "automatic": true,
+ "containerNames": [
+ "mysql"
+ ],
+ "from": {
+ "kind": "ImageStreamTag",
+ "name": "mysql:latest",
+ "namespace": "openshift"
+ },
+ "lastTriggeredImage": ""
+ }
+ },
+ {
+ "type": "ConfigChange"
+ }
+ ],
+ "replicas": 1,
+ "selector": {
+ "name": "${DATABASE_SERVICE_NAME}"
+ },
+ "template": {
+ "metadata": {
+ "creationTimestamp": null,
+ "labels": {
+ "name": "${DATABASE_SERVICE_NAME}"
+ }
+ },
+ "spec": {
+ "containers": [
+ {
+ "name": "mysql",
+ "image": "mysql",
+ "ports": [
+ {
+ "containerPort": 3306,
+ "protocol": "TCP"
+ }
+ ],
+ "env": [
+ {
+ "name": "MYSQL_USER",
+ "value": "${MYSQL_USER}"
+ },
+ {
+ "name": "MYSQL_PASSWORD",
+ "value": "${MYSQL_PASSWORD}"
+ },
+ {
+ "name": "MYSQL_DATABASE",
+ "value": "${MYSQL_DATABASE}"
+ }
+ ],
+ "resources": {},
+ "volumeMounts": [
+ {
+ "name": "${DATABASE_SERVICE_NAME}-data",
+ "mountPath": "/var/lib/mysql/data"
+ }
+ ],
+ "terminationMessagePath": "/dev/termination-log",
+ "imagePullPolicy": "IfNotPresent",
+ "capabilities": {},
+ "securityContext": {
+ "capabilities": {},
+ "privileged": false
+ }
+ }
+ ],
+ "volumes": [
+ {
+ "name": "${DATABASE_SERVICE_NAME}-data",
+ "persistentVolumeClaim": {
+ "claimName": "${DATABASE_SERVICE_NAME}"
+ }
+ }
+ ],
+ "restartPolicy": "Always",
+ "dnsPolicy": "ClusterFirst"
+ }
+ }
+ },
+ "status": {}
+ }
+ ],
+ "parameters": [
+ {
+ "name": "DATABASE_SERVICE_NAME",
+ "description": "Database service name",
+ "value": "mysql",
+ "required": true
+ },
+ {
+ "name": "MYSQL_USER",
+ "description": "Username for MySQL user that will be used for accessing the database",
+ "generate": "expression",
+ "from": "user[A-Z0-9]{3}",
+ "required": true
+ },
+ {
+ "name": "MYSQL_PASSWORD",
+ "description": "Password for the MySQL user",
+ "generate": "expression",
+ "from": "[a-zA-Z0-9]{16}",
+ "required": true
+ },
+ {
+ "name": "MYSQL_DATABASE",
+ "description": "Database name",
+ "value": "sampledb",
+ "required": true
+ },
+ {
+ "name": "VOLUME_CAPACITY",
+ "description": "Volume space available for data, e.g. 512Mi, 2Gi",
+ "value": "512Mi",
+ "required": true
+ }
+ ],
+ "labels": {
+ "template": "mysql-persistent-template"
+ }
+}
diff --git a/roles/openshift_examples/files/examples/db-templates/postgresql-ephemeral-template.json b/roles/openshift_examples/files/examples/db-templates/postgresql-ephemeral-template.json
new file mode 100644
index 000000000..60d6b8519
--- /dev/null
+++ b/roles/openshift_examples/files/examples/db-templates/postgresql-ephemeral-template.json
@@ -0,0 +1,173 @@
+{
+ "kind": "Template",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "postgresql-ephemeral",
+ "creationTimestamp": null,
+ "annotations": {
+ "description": "PostgreSQL database service, without persistent storage. WARNING: Any data stored will be lost upon pod destruction. Only use this template for testing",
+ "iconClass": "icon-postgresql",
+ "tags": "database,postgresql"
+ }
+ },
+ "objects": [
+ {
+ "kind": "Service",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "${DATABASE_SERVICE_NAME}",
+ "creationTimestamp": null
+ },
+ "spec": {
+ "ports": [
+ {
+ "name": "postgresql",
+ "protocol": "TCP",
+ "port": 5432,
+ "targetPort": 5432,
+ "nodePort": 0
+ }
+ ],
+ "selector": {
+ "name": "${DATABASE_SERVICE_NAME}"
+ },
+ "portalIP": "",
+ "type": "ClusterIP",
+ "sessionAffinity": "None"
+ },
+ "status": {
+ "loadBalancer": {}
+ }
+ },
+ {
+ "kind": "DeploymentConfig",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "${DATABASE_SERVICE_NAME}",
+ "creationTimestamp": null
+ },
+ "spec": {
+ "strategy": {
+ "type": "Recreate",
+ "resources": {}
+ },
+ "triggers": [
+ {
+ "type": "ImageChange",
+ "imageChangeParams": {
+ "automatic": true,
+ "containerNames": [
+ "postgresql"
+ ],
+ "from": {
+ "kind": "ImageStreamTag",
+ "name": "postgresql:latest",
+ "namespace": "openshift"
+ },
+ "lastTriggeredImage": ""
+ }
+ },
+ {
+ "type": "ConfigChange"
+ }
+ ],
+ "replicas": 1,
+ "selector": {
+ "name": "${DATABASE_SERVICE_NAME}"
+ },
+ "template": {
+ "metadata": {
+ "creationTimestamp": null,
+ "labels": {
+ "name": "${DATABASE_SERVICE_NAME}"
+ }
+ },
+ "spec": {
+ "containers": [
+ {
+ "name": "postgresql",
+ "image": "postgresql",
+ "ports": [
+ {
+ "containerPort": 5432,
+ "protocol": "TCP"
+ }
+ ],
+ "env": [
+ {
+ "name": "POSTGRESQL_USER",
+ "value": "${POSTGRESQL_USER}"
+ },
+ {
+ "name": "POSTGRESQL_PASSWORD",
+ "value": "${POSTGRESQL_PASSWORD}"
+ },
+ {
+ "name": "POSTGRESQL_DATABASE",
+ "value": "${POSTGRESQL_DATABASE}"
+ }
+ ],
+ "resources": {},
+ "volumeMounts": [
+ {
+ "name": "${DATABASE_SERVICE_NAME}-data",
+ "mountPath": "/var/lib/pgsql/data"
+ }
+ ],
+ "terminationMessagePath": "/dev/termination-log",
+ "imagePullPolicy": "IfNotPresent",
+ "capabilities": {},
+ "securityContext": {
+ "capabilities": {},
+ "privileged": false
+ }
+ }
+ ],
+ "volumes": [
+ {
+ "name": "${DATABASE_SERVICE_NAME}-data",
+ "emptyDir": {
+ "medium": ""
+ }
+ }
+ ],
+ "restartPolicy": "Always",
+ "dnsPolicy": "ClusterFirst"
+ }
+ }
+ },
+ "status": {}
+ }
+ ],
+ "parameters": [
+ {
+ "name": "DATABASE_SERVICE_NAME",
+ "description": "Database service name",
+ "value": "postgresql",
+ "required": true
+ },
+ {
+ "name": "POSTGRESQL_USER",
+ "description": "Username for PostgreSQL user that will be used for accessing the database",
+ "generate": "expression",
+ "from": "user[A-Z0-9]{3}",
+ "required": true
+ },
+ {
+ "name": "POSTGRESQL_PASSWORD",
+ "description": "Password for the PostgreSQL user",
+ "generate": "expression",
+ "from": "[a-zA-Z0-9]{16}",
+ "required": true
+ },
+ {
+ "name": "POSTGRESQL_DATABASE",
+ "description": "Database name",
+ "value": "sampledb",
+ "required": true
+ }
+ ],
+ "labels": {
+ "template": "postgresql-ephemeral-template"
+ }
+}
diff --git a/roles/openshift_examples/files/examples/db-templates/postgresql-persistent-template.json b/roles/openshift_examples/files/examples/db-templates/postgresql-persistent-template.json
new file mode 100644
index 000000000..91cd7453e
--- /dev/null
+++ b/roles/openshift_examples/files/examples/db-templates/postgresql-persistent-template.json
@@ -0,0 +1,196 @@
+{
+ "kind": "Template",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "postgresql-persistent",
+ "creationTimestamp": null,
+ "annotations": {
+ "description": "PostgreSQL database service, with persistent storage. Scaling to more than one replica is not supported",
+ "iconClass": "icon-postgresql",
+ "tags": "database,postgresql"
+ }
+ },
+ "objects": [
+ {
+ "kind": "Service",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "${DATABASE_SERVICE_NAME}",
+ "creationTimestamp": null
+ },
+ "spec": {
+ "ports": [
+ {
+ "name": "postgresql",
+ "protocol": "TCP",
+ "port": 5432,
+ "targetPort": 5432,
+ "nodePort": 0
+ }
+ ],
+ "selector": {
+ "name": "${DATABASE_SERVICE_NAME}"
+ },
+ "portalIP": "",
+ "type": "ClusterIP",
+ "sessionAffinity": "None"
+ },
+ "status": {
+ "loadBalancer": {}
+ }
+ },
+ {
+ "kind": "PersistentVolumeClaim",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "${DATABASE_SERVICE_NAME}"
+ },
+ "spec": {
+ "accessModes": [
+ "ReadWriteOnce"
+ ],
+ "resources": {
+ "requests": {
+ "storage": "${VOLUME_CAPACITY}"
+ }
+ }
+ }
+ },
+ {
+ "kind": "DeploymentConfig",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "${DATABASE_SERVICE_NAME}",
+ "creationTimestamp": null
+ },
+ "spec": {
+ "strategy": {
+ "type": "Recreate",
+ "resources": {}
+ },
+ "triggers": [
+ {
+ "type": "ImageChange",
+ "imageChangeParams": {
+ "automatic": true,
+ "containerNames": [
+ "postgresql"
+ ],
+ "from": {
+ "kind": "ImageStreamTag",
+ "name": "postgresql:latest",
+ "namespace": "openshift"
+ },
+ "lastTriggeredImage": ""
+ }
+ },
+ {
+ "type": "ConfigChange"
+ }
+ ],
+ "replicas": 1,
+ "selector": {
+ "name": "${DATABASE_SERVICE_NAME}"
+ },
+ "template": {
+ "metadata": {
+ "creationTimestamp": null,
+ "labels": {
+ "name": "${DATABASE_SERVICE_NAME}"
+ }
+ },
+ "spec": {
+ "containers": [
+ {
+ "name": "postgresql",
+ "image": "postgresql",
+ "ports": [
+ {
+ "containerPort": 5432,
+ "protocol": "TCP"
+ }
+ ],
+ "env": [
+ {
+ "name": "POSTGRESQL_USER",
+ "value": "${POSTGRESQL_USER}"
+ },
+ {
+ "name": "POSTGRESQL_PASSWORD",
+ "value": "${POSTGRESQL_PASSWORD}"
+ },
+ {
+ "name": "POSTGRESQL_DATABASE",
+ "value": "${POSTGRESQL_DATABASE}"
+ }
+ ],
+ "resources": {},
+ "volumeMounts": [
+ {
+ "name": "${DATABASE_SERVICE_NAME}-data",
+ "mountPath": "/var/lib/pgsql/data"
+ }
+ ],
+ "terminationMessagePath": "/dev/termination-log",
+ "imagePullPolicy": "IfNotPresent",
+ "capabilities": {},
+ "securityContext": {
+ "capabilities": {},
+ "privileged": false
+ }
+ }
+ ],
+ "volumes": [
+ {
+ "name": "${DATABASE_SERVICE_NAME}-data",
+ "persistentVolumeClaim": {
+ "claimName": "${DATABASE_SERVICE_NAME}"
+ }
+ }
+ ],
+ "restartPolicy": "Always",
+ "dnsPolicy": "ClusterFirst"
+ }
+ }
+ },
+ "status": {}
+ }
+ ],
+ "parameters": [
+ {
+ "name": "DATABASE_SERVICE_NAME",
+ "description": "Database service name",
+ "value": "postgresql",
+ "required": true
+ },
+ {
+ "name": "POSTGRESQL_USER",
+ "description": "Username for PostgreSQL user that will be used for accessing the database",
+ "generate": "expression",
+ "from": "user[A-Z0-9]{3}",
+ "required": true
+ },
+ {
+ "name": "POSTGRESQL_PASSWORD",
+ "description": "Password for the PostgreSQL user",
+ "generate": "expression",
+ "from": "[a-zA-Z0-9]{16}",
+ "required": true
+ },
+ {
+ "name": "POSTGRESQL_DATABASE",
+ "description": "Database name",
+ "value": "sampledb",
+ "required": true
+ },
+ {
+ "name": "VOLUME_CAPACITY",
+ "description": "Volume space available for data, e.g. 512Mi, 2Gi",
+ "value": "512Mi",
+ "required": true
+ }
+ ],
+ "labels": {
+ "template": "postgresql-persistent-template"
+ }
+}
diff --git a/roles/openshift_examples/files/examples/image-streams/image-streams-centos7.json b/roles/openshift_examples/files/examples/image-streams/image-streams-centos7.json
new file mode 100644
index 000000000..268d680f4
--- /dev/null
+++ b/roles/openshift_examples/files/examples/image-streams/image-streams-centos7.json
@@ -0,0 +1,285 @@
+{
+ "kind": "ImageStreamList",
+ "apiVersion": "v1",
+ "metadata": {},
+ "items": [
+ {
+ "kind": "ImageStream",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "ruby",
+ "creationTimestamp": null
+ },
+ "spec": {
+ "dockerImageRepository": "openshift/ruby-20-centos7",
+ "tags": [
+ {
+ "name": "latest"
+ },
+ {
+ "name": "2.0",
+ "annotations": {
+ "description": "Build and run Ruby 2.0 applications",
+ "iconClass": "icon-ruby",
+ "tags": "builder,ruby",
+ "supports": "ruby:2.0,ruby",
+ "version": "2.0",
+ "sampleRepo": "https://github.com/openshift/ruby-ex.git"
+ },
+ "from": {
+ "Kind": "ImageStreamTag",
+ "Name": "latest"
+ }
+ }
+ ]
+ }
+ },
+ {
+ "kind": "ImageStream",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "nodejs",
+ "creationTimestamp": null
+ },
+ "spec": {
+ "dockerImageRepository": "openshift/nodejs-010-centos7",
+ "tags": [
+ {
+ "name": "latest"
+ },
+ {
+ "name": "0.10",
+ "annotations": {
+ "description": "Build and run NodeJS 0.10 applications",
+ "iconClass": "icon-nodejs",
+ "tags": "builder,nodejs",
+ "supports":"nodejs:0.10,nodejs:0.1,nodejs",
+ "version": "0.10",
+ "sampleRepo": "https://github.com/openshift/nodejs-ex.git"
+ },
+ "from": {
+ "Kind": "ImageStreamTag",
+ "Name": "latest"
+ }
+ }
+ ]
+ }
+ },
+ {
+ "kind": "ImageStream",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "perl",
+ "creationTimestamp": null
+ },
+ "spec": {
+ "dockerImageRepository": "openshift/perl-516-centos7",
+ "tags": [
+ {
+ "name": "latest"
+ },
+ {
+ "name": "5.16",
+ "annotations": {
+ "description": "Build and run Perl 5.16 applications",
+ "iconClass": "icon-perl",
+ "tags": "builder,perl",
+ "supports":"perl:5.16,perl",
+ "version": "5.16",
+ "sampleRepo": "https://github.com/openshift/dancer-ex.git"
+ },
+ "from": {
+ "Kind": "ImageStreamTag",
+ "Name": "latest"
+ }
+ }
+ ]
+ }
+ },
+ {
+ "kind": "ImageStream",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "php",
+ "creationTimestamp": null
+ },
+ "spec": {
+ "dockerImageRepository": "openshift/php-55-centos7",
+ "tags": [
+ {
+ "name": "latest"
+ },
+ {
+ "name": "5.5",
+ "annotations": {
+ "description": "Build and run PHP 5.5 applications",
+ "iconClass": "icon-php",
+ "tags": "builder,php",
+ "supports":"php:5.5,php",
+ "version": "5.5",
+ "sampleRepo": "https://github.com/openshift/cakephp-ex.git"
+ },
+ "from": {
+ "Kind": "ImageStreamTag",
+ "Name": "latest"
+ }
+ }
+ ]
+ }
+ },
+ {
+ "kind": "ImageStream",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "python",
+ "creationTimestamp": null
+ },
+ "spec": {
+ "dockerImageRepository": "openshift/python-33-centos7",
+ "tags": [
+ {
+ "name": "latest"
+ },
+ {
+ "name": "3.3",
+ "annotations": {
+ "description": "Build and run Python 3.3 applications",
+ "iconClass": "icon-python",
+ "tags": "builder,python",
+ "supports":"python:3.3,python",
+ "version": "3.3",
+ "sampleRepo": "https://github.com/openshift/django-ex.git"
+ },
+ "from": {
+ "Kind": "ImageStreamTag",
+ "Name": "latest"
+ }
+ }
+ ]
+ }
+ },
+ {
+ "kind": "ImageStream",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "wildfly",
+ "creationTimestamp": null
+ },
+ "spec": {
+ "dockerImageRepository": "openshift/wildfly-81-centos7",
+ "tags": [
+ {
+ "name": "latest"
+ },
+ {
+ "name": "8.1",
+ "annotations": {
+ "description": "Build and run Java applications on Wildfly 8.1",
+ "iconClass": "icon-wildfly",
+ "tags": "builder,wildfly,java",
+ "supports":"wildfly:8.1,jee,java",
+ "version": "8.1",
+ "sampleRepo": "https://github.com/bparees/openshift-jee-sample.git"
+ },
+ "from": {
+ "Kind": "ImageStreamTag",
+ "Name": "latest"
+ }
+ }
+ ]
+ }
+ },
+ {
+ "kind": "ImageStream",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "mysql",
+ "creationTimestamp": null
+ },
+ "spec": {
+ "dockerImageRepository": "openshift/mysql-55-centos7",
+ "tags": [
+ {
+ "name": "latest"
+ },
+ {
+ "name": "5.5",
+ "from": {
+ "Kind": "ImageStreamTag",
+ "Name": "latest"
+ }
+ }
+ ]
+ }
+ },
+ {
+ "kind": "ImageStream",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "postgresql",
+ "creationTimestamp": null
+ },
+ "spec": {
+ "dockerImageRepository": "openshift/postgresql-92-centos7",
+ "tags": [
+ {
+ "name": "latest"
+ },
+ {
+ "name": "9.2",
+ "from": {
+ "Kind": "ImageStreamTag",
+ "Name": "latest"
+ }
+ }
+ ]
+ }
+ },
+ {
+ "kind": "ImageStream",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "mongodb",
+ "creationTimestamp": null
+ },
+ "spec": {
+ "dockerImageRepository": "openshift/mongodb-24-centos7",
+ "tags": [
+ {
+ "name": "latest"
+ },
+ {
+ "name": "2.4",
+ "from": {
+ "Kind": "ImageStreamTag",
+ "Name": "latest"
+ }
+ }
+ ]
+ }
+ },
+ {
+ "kind": "ImageStream",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "jenkins",
+ "creationTimestamp": null
+ },
+ "spec": {
+ "dockerImageRepository": "openshift/jenkins-1-centos7",
+ "tags": [
+ {
+ "name": "latest"
+ },
+ {
+ "name": "1",
+ "from": {
+ "Kind": "ImageStreamTag",
+ "Name": "latest"
+ }
+ }
+ ]
+ }
+ }
+ ]
+}
diff --git a/roles/openshift_examples/files/examples/image-streams/image-streams-rhel7.json b/roles/openshift_examples/files/examples/image-streams/image-streams-rhel7.json
new file mode 100644
index 000000000..aa62ebd53
--- /dev/null
+++ b/roles/openshift_examples/files/examples/image-streams/image-streams-rhel7.json
@@ -0,0 +1,254 @@
+{
+ "kind": "ImageStreamList",
+ "apiVersion": "v1",
+ "metadata": {},
+ "items": [
+ {
+ "kind": "ImageStream",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "ruby",
+ "creationTimestamp": null
+ },
+ "spec": {
+ "dockerImageRepository": "registry.access.redhat.com/openshift3/ruby-20-rhel7",
+ "tags": [
+ {
+ "name": "latest"
+ },
+ {
+ "name": "2.0",
+ "annotations": {
+ "description": "Build and run Ruby 2.0 applications",
+ "iconClass": "icon-ruby",
+ "tags": "builder,ruby",
+ "supports": "ruby:2.0,ruby",
+ "version": "2.0",
+ "sampleRepo": "https://github.com/openshift/ruby-ex.git"
+ },
+ "from": {
+ "Kind": "ImageStreamTag",
+ "Name": "latest"
+ }
+ }
+ ]
+ }
+ },
+ {
+ "kind": "ImageStream",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "nodejs",
+ "creationTimestamp": null
+ },
+ "spec": {
+ "dockerImageRepository": "registry.access.redhat.com/openshift3/nodejs-010-rhel7",
+ "tags": [
+ {
+ "name": "latest"
+ },
+ {
+ "name": "0.10",
+ "annotations": {
+ "description": "Build and run NodeJS 0.10 applications",
+ "iconClass": "icon-nodejs",
+ "tags": "builder,nodejs",
+ "supports":"nodejs:0.10,nodejs:0.1,nodejs",
+ "version": "0.10",
+ "sampleRepo": "https://github.com/openshift/nodejs-ex.git"
+ },
+ "from": {
+ "Kind": "ImageStreamTag",
+ "Name": "latest"
+ }
+ }
+ ]
+ }
+ },
+ {
+ "kind": "ImageStream",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "perl",
+ "creationTimestamp": null
+ },
+ "spec": {
+ "dockerImageRepository": "registry.access.redhat.com/openshift3/perl-516-rhel7",
+ "tags": [
+ {
+ "name": "latest"
+ },
+ {
+ "name": "5.16",
+ "annotations": {
+ "description": "Build and run Perl 5.16 applications",
+ "iconClass": "icon-perl",
+ "tags": "builder,perl",
+ "supports":"perl:5.16,perl",
+ "version": "5.16",
+ "sampleRepo": "https://github.com/openshift/dancer-ex.git"
+ },
+ "from": {
+ "Kind": "ImageStreamTag",
+ "Name": "latest"
+ }
+ }
+ ]
+ }
+ },
+ {
+ "kind": "ImageStream",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "php",
+ "creationTimestamp": null
+ },
+ "spec": {
+ "dockerImageRepository": "registry.access.redhat.com/openshift3/php-55-rhel7",
+ "tags": [
+ {
+ "name": "latest"
+ },
+ {
+ "name": "5.5",
+ "annotations": {
+ "description": "Build and run PHP 5.5 applications",
+ "iconClass": "icon-php",
+ "tags": "builder,php",
+ "supports":"php:5.5,php",
+ "version": "5.5",
+ "sampleRepo": "https://github.com/openshift/cakephp-ex.git"
+ },
+ "from": {
+ "Kind": "ImageStreamTag",
+ "Name": "latest"
+ }
+ }
+ ]
+ }
+ },
+ {
+ "kind": "ImageStream",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "python",
+ "creationTimestamp": null
+ },
+ "spec": {
+ "dockerImageRepository": "registry.access.redhat.com/openshift3/python-33-rhel7",
+ "tags": [
+ {
+ "name": "latest"
+ },
+ {
+ "name": "3.3",
+ "annotations": {
+ "description": "Build and run Python 3.3 applications",
+ "iconClass": "icon-python",
+ "tags": "builder,python",
+ "supports":"python:3.3,python",
+ "version": "3.3",
+ "sampleRepo": "https://github.com/openshift/django-ex.git"
+ },
+ "from": {
+ "Kind": "ImageStreamTag",
+ "Name": "latest"
+ }
+ }
+ ]
+ }
+ },
+ {
+ "kind": "ImageStream",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "mysql",
+ "creationTimestamp": null
+ },
+ "spec": {
+ "dockerImageRepository": "registry.access.redhat.com/openshift3/mysql-55-rhel7",
+ "tags": [
+ {
+ "name": "latest"
+ },
+ {
+ "name": "5.5",
+ "from": {
+ "Kind": "ImageStreamTag",
+ "Name": "latest"
+ }
+ }
+ ]
+ }
+ },
+ {
+ "kind": "ImageStream",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "postgresql",
+ "creationTimestamp": null
+ },
+ "spec": {
+ "dockerImageRepository": "registry.access.redhat.com/openshift3/postgresql-92-rhel7",
+ "tags": [
+ {
+ "name": "latest"
+ },
+ {
+ "name": "9.2",
+ "from": {
+ "Kind": "ImageStreamTag",
+ "Name": "latest"
+ }
+ }
+ ]
+ }
+ },
+ {
+ "kind": "ImageStream",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "mongodb",
+ "creationTimestamp": null
+ },
+ "spec": {
+ "dockerImageRepository": "registry.access.redhat.com/openshift3/mongodb-24-rhel7",
+ "tags": [
+ {
+ "name": "latest"
+ },
+ {
+ "name": "2.4",
+ "from": {
+ "Kind": "ImageStreamTag",
+ "Name": "latest"
+ }
+ }
+ ]
+ }
+ },
+ {
+ "kind": "ImageStream",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "jenkins",
+ "creationTimestamp": null
+ },
+ "spec": {
+ "dockerImageRepository": "registry.access.redhat.com/openshift3/jenkins-1-rhel7",
+ "tags": [
+ {
+ "name": "latest"
+ },
+ {
+ "name": "1",
+ "from": {
+ "Kind": "ImageStreamTag",
+ "Name": "latest"
+ }
+ }
+ ]
+ }
+ }
+ ]
+}
diff --git a/roles/openshift_examples/files/examples/quickstart-templates/cakephp-mysql.json b/roles/openshift_examples/files/examples/quickstart-templates/cakephp-mysql.json
new file mode 100644
index 000000000..da5679444
--- /dev/null
+++ b/roles/openshift_examples/files/examples/quickstart-templates/cakephp-mysql.json
@@ -0,0 +1,378 @@
+{
+ "kind": "Template",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "cakephp-mysql-example",
+ "annotations": {
+ "description": "An example CakePHP application with a MySQL database",
+ "tags": "instant-app,php,cakephp,mysql",
+ "iconClass": "icon-php"
+ }
+ },
+ "labels": {
+ "template": "cakephp-mysql-example"
+ },
+ "objects": [
+ {
+ "kind": "Service",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "cakephp-mysql-example",
+ "annotations": {
+ "description": "Exposes and load balances the application pods"
+ }
+ },
+ "spec": {
+ "ports": [
+ {
+ "name": "web",
+ "port": 8080,
+ "targetPort": 8080
+ }
+ ],
+ "selector": {
+ "name": "cakephp-mysql-example"
+ }
+ }
+ },
+ {
+ "kind": "Route",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "cakephp-mysql-example"
+ },
+ "spec": {
+ "host": "${APPLICATION_DOMAIN}",
+ "to": {
+ "kind": "Service",
+ "name": "cakephp-mysql-example"
+ }
+ }
+ },
+ {
+ "kind": "ImageStream",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "cakephp-mysql-example",
+ "annotations": {
+ "description": "Keeps track of changes in the application image"
+ }
+ }
+ },
+ {
+ "kind": "BuildConfig",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "cakephp-mysql-example",
+ "annotations": {
+ "description": "Defines how to build the application"
+ }
+ },
+ "spec": {
+ "source": {
+ "type": "Git",
+ "git": {
+ "uri": "${SOURCE_REPOSITORY_URL}",
+ "ref": "${SOURCE_REPOSITORY_REF}"
+ },
+ "contextDir": "${CONTEXT_DIR}"
+ },
+ "strategy": {
+ "type": "Source",
+ "sourceStrategy": {
+ "from": {
+ "kind": "ImageStreamTag",
+ "namespace": "openshift",
+ "name": "php:5.5"
+ }
+ }
+ },
+ "output": {
+ "to": {
+ "kind": "ImageStreamTag",
+ "name": "cakephp-mysql-example:latest"
+ }
+ },
+ "triggers": [
+ {
+ "type": "ImageChange"
+ },
+ {
+ "type": "GitHub",
+ "github": {
+ "secret": "${GITHUB_WEBHOOK_SECRET}"
+ }
+ }
+ ]
+ }
+ },
+ {
+ "kind": "DeploymentConfig",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "cakephp-mysql-example",
+ "annotations": {
+ "description": "Defines how to deploy the application server"
+ }
+ },
+ "spec": {
+ "strategy": {
+ "type": "Rolling",
+ "recreateParams": {
+ "pre": {
+ "failurePolicy": "Abort",
+ "execNewPod": {
+ "command": [
+ "./migrate-database.sh"
+ ],
+ "containerName": "cakephp-mysql-example"
+ }
+ }
+ }
+ },
+ "triggers": [
+ {
+ "type": "ImageChange",
+ "imageChangeParams": {
+ "automatic": true,
+ "containerNames": [
+ "cakephp-mysql-example"
+ ],
+ "from": {
+ "kind": "ImageStreamTag",
+ "name": "cakephp-mysql-example:latest"
+ }
+ }
+ },
+ {
+ "type": "ConfigChange"
+ }
+ ],
+ "replicas": 1,
+ "selector": {
+ "name": "cakephp-mysql-example"
+ },
+ "template": {
+ "metadata": {
+ "name": "cakephp-mysql-example",
+ "labels": {
+ "name": "cakephp-mysql-example"
+ }
+ },
+ "spec": {
+ "containers": [
+ {
+ "name": "cakephp-mysql-example",
+ "image": "cakephp-mysql-example",
+ "ports": [
+ {
+ "containerPort": 8080
+ }
+ ],
+ "env": [
+ {
+ "name": "DATABASE_SERVICE_NAME",
+ "value": "${DATABASE_SERVICE_NAME}"
+ },
+ {
+ "name": "DATABASE_ENGINE",
+ "value": "${DATABASE_ENGINE}"
+ },
+ {
+ "name": "DATABASE_NAME",
+ "value": "${DATABASE_NAME}"
+ },
+ {
+ "name": "DATABASE_USER",
+ "value": "${DATABASE_USER}"
+ },
+ {
+ "name": "DATABASE_PASSWORD",
+ "value": "${DATABASE_PASSWORD}"
+ },
+ {
+ "name": "CAKEPHP_SECRET_TOKEN",
+ "value": "${CAKEPHP_SECRET_TOKEN}"
+ },
+ {
+ "name": "CAKEPHP_SECURITY_SALT",
+ "value": "${CAKEPHP_SECURITY_SALT}"
+ },
+ {
+ "name": "CAKEPHP_SECURITY_CIPHER_SEED",
+ "value": "${CAKEPHP_SECURITY_CIPHER_SEED}"
+ },
+ {
+ "name": "OPCACHE_REVALIDATE_FREQ",
+ "value": "${OPCACHE_REVALIDATE_FREQ}"
+ }
+ ]
+ }
+ ]
+ }
+ }
+ }
+ },
+ {
+ "kind": "Service",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "${DATABASE_SERVICE_NAME}",
+ "annotations": {
+ "description": "Exposes the database server"
+ }
+ },
+ "spec": {
+ "ports": [
+ {
+ "name": "mysql",
+ "port": 3306,
+ "targetPort": 3306
+ }
+ ],
+ "selector": {
+ "name": "${DATABASE_SERVICE_NAME}"
+ }
+ }
+ },
+ {
+ "kind": "DeploymentConfig",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "${DATABASE_SERVICE_NAME}",
+ "annotations": {
+ "description": "Defines how to deploy the database"
+ }
+ },
+ "spec": {
+ "strategy": {
+ "type": "Recreate"
+ },
+ "triggers": [
+ {
+ "type": "ConfigChange"
+ }
+ ],
+ "replicas": 1,
+ "selector": {
+ "name": "${DATABASE_SERVICE_NAME}"
+ },
+ "template": {
+ "metadata": {
+ "name": "${DATABASE_SERVICE_NAME}",
+ "labels": {
+ "name": "${DATABASE_SERVICE_NAME}"
+ }
+ },
+ "spec": {
+ "containers": [
+ {
+ "name": "mysql",
+ "image": "${MYSQL_IMAGE}",
+ "ports": [
+ {
+ "containerPort": 3306
+ }
+ ],
+ "env": [
+ {
+ "name": "MYSQL_USER",
+ "value": "${DATABASE_USER}"
+ },
+ {
+ "name": "MYSQL_PASSWORD",
+ "value": "${DATABASE_PASSWORD}"
+ },
+ {
+ "name": "MYSQL_DATABASE",
+ "value": "${DATABASE_NAME}"
+ }
+ ]
+ }
+ ]
+ }
+ }
+ }
+ }
+ ],
+ "parameters": [
+ {
+ "name": "SOURCE_REPOSITORY_URL",
+ "description": "The URL of the repository with your application source code",
+ "value": "https://github.com/openshift/cakephp-ex.git"
+ },
+ {
+ "name": "SOURCE_REPOSITORY_REF",
+ "description": "Set this to a branch name, tag or other ref of your repository if you are not using the default branch"
+ },
+ {
+ "name": "CONTEXT_DIR",
+ "description": "Set this to the relative path to your project if it is not in the root of your repository"
+ },
+ {
+ "name": "APPLICATION_DOMAIN",
+ "description": "The exposed hostname that will route to the CakePHP service, if left blank a value will be defaulted.",
+ "value": ""
+ },
+ {
+ "name": "GITHUB_WEBHOOK_SECRET",
+ "description": "A secret string used to configure the GitHub webhook",
+ "generate": "expression",
+ "from": "[a-zA-Z0-9]{40}"
+ },
+ {
+ "name": "DATABASE_SERVICE_NAME",
+ "description": "Database service name",
+ "value": "mysql"
+ },
+ {
+ "name": "DATABASE_ENGINE",
+ "description": "Database engine: postgresql, mysql or sqlite (default)",
+ "value": "mysql"
+ },
+ {
+ "name": "DATABASE_NAME",
+ "description": "Database name",
+ "value": "default"
+ },
+ {
+ "name": "DATABASE_USER",
+ "description": "Database user name",
+ "value": "cakephp"
+ },
+ {
+ "name": "DATABASE_PASSWORD",
+ "description": "Database user password",
+ "generate": "expression",
+ "from": "[a-zA-Z0-9]{16}"
+ },
+ {
+ "name": "MYSQL_IMAGE",
+ "description": "Image to use for mysql",
+ "value": "openshift/mysql-55-centos7"
+ },
+ {
+ "name": "CAKEPHP_SECRET_TOKEN",
+ "description": "Set this to a long random string",
+ "generate": "expression",
+ "from": "[\\w]{50}"
+ },
+ {
+ "name": "CAKEPHP_SECURITY_SALT",
+ "description": "Security salt for session hash",
+ "generate": "expression",
+ "from": "[a-zA-Z0-9]{40}"
+ },
+ {
+ "name": "CAKEPHP_SECURITY_CIPHER_SEED",
+ "description": "Security cipher seed for session hash",
+ "generate": "expression",
+ "from": "[0-9]{30}"
+ },
+ {
+ "name": "OPCACHE_REVALIDATE_FREQ",
+ "description": "The How often to check script timestamps for updates, in seconds. 0 will result in OPcache checking for updates on every request.",
+ "value": "2"
+ }
+ ]
+}
diff --git a/roles/openshift_examples/files/examples/quickstart-templates/cakephp.json b/roles/openshift_examples/files/examples/quickstart-templates/cakephp.json
new file mode 100644
index 000000000..f426e1dd6
--- /dev/null
+++ b/roles/openshift_examples/files/examples/quickstart-templates/cakephp.json
@@ -0,0 +1,275 @@
+{
+ "kind": "Template",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "cakephp-example",
+ "annotations": {
+ "description": "An example CakePHP application with no database",
+ "tags": "instant-app,php,cakephp",
+ "iconClass": "icon-php"
+ }
+ },
+ "labels": {
+ "template": "cakephp-example"
+ },
+ "objects": [
+ {
+ "kind": "Service",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "cakephp-example",
+ "annotations": {
+ "description": "Exposes and load balances the application pods"
+ }
+ },
+ "spec": {
+ "ports": [
+ {
+ "name": "web",
+ "port": 8080,
+ "targetPort": 8080
+ }
+ ],
+ "selector": {
+ "name": "cakephp-example"
+ }
+ }
+ },
+ {
+ "kind": "Route",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "cakephp-example"
+ },
+ "spec": {
+ "host": "${APPLICATION_DOMAIN}",
+ "to": {
+ "kind": "Service",
+ "name": "cakephp-example"
+ }
+ }
+ },
+ {
+ "kind": "ImageStream",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "cakephp-example",
+ "annotations": {
+ "description": "Keeps track of changes in the application image"
+ }
+ }
+ },
+ {
+ "kind": "BuildConfig",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "cakephp-example",
+ "annotations": {
+ "description": "Defines how to build the application"
+ }
+ },
+ "spec": {
+ "source": {
+ "type": "Git",
+ "git": {
+ "uri": "${SOURCE_REPOSITORY_URL}",
+ "ref": "${SOURCE_REPOSITORY_REF}"
+ },
+ "contextDir": "${CONTEXT_DIR}"
+ },
+ "strategy": {
+ "type": "Source",
+ "sourceStrategy": {
+ "from": {
+ "kind": "ImageStreamTag",
+ "namespace": "openshift",
+ "name": "php:5.5"
+ }
+ }
+ },
+ "output": {
+ "to": {
+ "kind": "ImageStreamTag",
+ "name": "cakephp-example:latest"
+ }
+ },
+ "triggers": [
+ {
+ "type": "ImageChange"
+ },
+ {
+ "type": "GitHub",
+ "github": {
+ "secret": "${GITHUB_WEBHOOK_SECRET}"
+ }
+ }
+ ]
+ }
+ },
+ {
+ "kind": "DeploymentConfig",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "cakephp-example",
+ "annotations": {
+ "description": "Defines how to deploy the application server"
+ }
+ },
+ "spec": {
+ "strategy": {
+ "type": "Rolling"
+ },
+ "triggers": [
+ {
+ "type": "ImageChange",
+ "imageChangeParams": {
+ "automatic": true,
+ "containerNames": [
+ "cakephp-example"
+ ],
+ "from": {
+ "kind": "ImageStreamTag",
+ "name": "cakephp-example:latest"
+ }
+ }
+ },
+ {
+ "type": "ConfigChange"
+ }
+ ],
+ "replicas": 1,
+ "selector": {
+ "name": "cakephp-example"
+ },
+ "template": {
+ "metadata": {
+ "name": "cakephp-example",
+ "labels": {
+ "name": "cakephp-example"
+ }
+ },
+ "spec": {
+ "containers": [
+ {
+ "name": "cakephp-example",
+ "image": "cakephp-example",
+ "ports": [
+ {
+ "containerPort": 8080
+ }
+ ],
+ "env": [
+ {
+ "name": "DATABASE_SERVICE_NAME",
+ "value": "${DATABASE_SERVICE_NAME}"
+ },
+ {
+ "name": "DATABASE_ENGINE",
+ "value": "${DATABASE_ENGINE}"
+ },
+ {
+ "name": "DATABASE_NAME",
+ "value": "${DATABASE_NAME}"
+ },
+ {
+ "name": "DATABASE_USER",
+ "value": "${DATABASE_USER}"
+ },
+ {
+ "name": "DATABASE_PASSWORD",
+ "value": "${DATABASE_PASSWORD}"
+ },
+ {
+ "name": "CAKEPHP_SECRET_TOKEN",
+ "value": "${CAKEPHP_SECRET_TOKEN}"
+ },
+ {
+ "name": "CAKEPHP_SECURITY_SALT",
+ "value": "${CAKEPHP_SECURITY_SALT}"
+ },
+ {
+ "name": "CAKEPHP_SECURITY_CIPHER_SEED",
+ "value": "${CAKEPHP_SECURITY_CIPHER_SEED}"
+ },
+ {
+ "name": "OPCACHE_REVALIDATE_FREQ",
+ "value": "${OPCACHE_REVALIDATE_FREQ}"
+ }
+ ]
+ }
+ ]
+ }
+ }
+ }
+ }
+ ],
+ "parameters": [
+ {
+ "name": "SOURCE_REPOSITORY_URL",
+ "description": "The URL of the repository with your application source code",
+ "value": "https://github.com/openshift/cakephp-ex.git"
+ },
+ {
+ "name": "SOURCE_REPOSITORY_REF",
+ "description": "Set this to a branch name, tag or other ref of your repository if you are not using the default branch"
+ },
+ {
+ "name": "CONTEXT_DIR",
+ "description": "Set this to the relative path to your project if it is not in the root of your repository"
+ },
+ {
+ "name": "APPLICATION_DOMAIN",
+ "description": "The exposed hostname that will route to the CakePHP service, if left blank a value will be defaulted.",
+ "value": ""
+ },
+ {
+ "name": "GITHUB_WEBHOOK_SECRET",
+ "description": "A secret string used to configure the GitHub webhook",
+ "generate": "expression",
+ "from": "[a-zA-Z0-9]{40}"
+ },
+ {
+ "name": "DATABASE_SERVICE_NAME",
+ "description": "Database service name"
+ },
+ {
+ "name": "DATABASE_ENGINE",
+ "description": "Database engine: postgresql, mysql or sqlite (default)"
+ },
+ {
+ "name": "DATABASE_NAME",
+ "description": "Database name"
+ },
+ {
+ "name": "DATABASE_USER",
+ "description": "Database user name"
+ },
+ {
+ "name": "DATABASE_PASSWORD",
+ "description": "Database user password"
+ },
+ {
+ "name": "CAKEPHP_SECRET_TOKEN",
+ "description": "Set this to a long random string",
+ "generate": "expression",
+ "from": "[\\w]{50}"
+ },
+ {
+ "name": "CAKEPHP_SECURITY_SALT",
+ "description": "Security salt for session hash",
+ "generate": "expression",
+ "from": "[a-zA-Z0-9]{40}"
+ },
+ {
+ "name": "CAKEPHP_SECURITY_CIPHER_SEED",
+ "description": "Security cipher seed for session hash",
+ "generate": "expression",
+ "from": "[0-9]{30}"
+ },
+ {
+ "name": "OPCACHE_REVALIDATE_FREQ",
+ "description": "The How often to check script timestamps for updates, in seconds. 0 will result in OPcache checking for updates on every request.",
+ "value": "2"
+ }
+ ]
+}
diff --git a/roles/openshift_examples/files/examples/quickstart-templates/dancer-mysql.json b/roles/openshift_examples/files/examples/quickstart-templates/dancer-mysql.json
new file mode 100644
index 000000000..55f655102
--- /dev/null
+++ b/roles/openshift_examples/files/examples/quickstart-templates/dancer-mysql.json
@@ -0,0 +1,348 @@
+{
+ "kind": "Template",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "dancer-mysql-example",
+ "annotations": {
+ "description": "An example Dancer application with a MySQL database",
+ "tags": "instant-app,perl,dancer,mysql",
+ "iconClass": "icon-perl"
+ }
+ },
+ "labels": {
+ "template": "dancer-mysql-example"
+ },
+ "objects": [
+ {
+ "kind": "Service",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "dancer-mysql-example",
+ "annotations": {
+ "description": "Exposes and load balances the application pods"
+ }
+ },
+ "spec": {
+ "ports": [
+ {
+ "name": "web",
+ "port": 8080,
+ "targetPort": 8080
+ }
+ ],
+ "selector": {
+ "name": "dancer-mysql-example"
+ }
+ }
+ },
+ {
+ "kind": "Route",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "dancer-mysql-example"
+ },
+ "spec": {
+ "host": "${APPLICATION_DOMAIN}",
+ "to": {
+ "kind": "Service",
+ "name": "dancer-mysql-example"
+ }
+ }
+ },
+ {
+ "kind": "ImageStream",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "dancer-mysql-example",
+ "annotations": {
+ "description": "Keeps track of changes in the application image"
+ }
+ }
+ },
+ {
+ "kind": "BuildConfig",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "dancer-mysql-example",
+ "annotations": {
+ "description": "Defines how to build the application"
+ }
+ },
+ "spec": {
+ "source": {
+ "type": "Git",
+ "git": {
+ "uri": "${SOURCE_REPOSITORY_URL}",
+ "ref": "${SOURCE_REPOSITORY_REF}"
+ },
+ "contextDir": "${CONTEXT_DIR}"
+ },
+ "strategy": {
+ "type": "Source",
+ "sourceStrategy": {
+ "from": {
+ "kind": "ImageStreamTag",
+ "namespace": "openshift",
+ "name": "perl:5.16"
+ }
+ }
+ },
+ "output": {
+ "to": {
+ "kind": "ImageStreamTag",
+ "name": "dancer-mysql-example:latest"
+ }
+ },
+ "triggers": [
+ {
+ "type": "ImageChange"
+ },
+ {
+ "type": "GitHub",
+ "github": {
+ "secret": "${GITHUB_WEBHOOK_SECRET}"
+ }
+ }
+ ]
+ }
+ },
+ {
+ "kind": "DeploymentConfig",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "dancer-mysql-example",
+ "annotations": {
+ "description": "Defines how to deploy the application server"
+ }
+ },
+ "spec": {
+ "triggers": [
+ {
+ "type": "ImageChange",
+ "imageChangeParams": {
+ "automatic": true,
+ "containerNames": [
+ "dancer-mysql-example"
+ ],
+ "from": {
+ "kind": "ImageStreamTag",
+ "name": "dancer-mysql-example:latest"
+ }
+ }
+ },
+ {
+ "type": "ConfigChange"
+ }
+ ],
+ "replicas": 1,
+ "selector": {
+ "name": "dancer-mysql-example"
+ },
+ "template": {
+ "metadata": {
+ "name": "dancer-mysql-example",
+ "labels": {
+ "name": "dancer-mysql-example"
+ }
+ },
+ "spec": {
+ "containers": [
+ {
+ "name": "dancer-mysql-example",
+ "image": "dancer-mysql-example",
+ "ports": [
+ {
+ "containerPort": 8080
+ }
+ ],
+ "env": [
+ {
+ "name": "DATABASE_SERVICE_NAME",
+ "value": "${DATABASE_SERVICE_NAME}"
+ },
+ {
+ "name": "MYSQL_USER",
+ "value": "${DATABASE_USER}"
+ },
+ {
+ "name": "MYSQL_PASSWORD",
+ "value": "${DATABASE_PASSWORD}"
+ },
+ {
+ "name": "MYSQL_DATABASE",
+ "value": "${DATABASE_NAME}"
+ },
+ {
+ "name": "SECRET_KEY_BASE",
+ "value": "${SECRET_KEY_BASE}"
+ },
+ {
+ "name": "PERL_APACHE2_RELOAD",
+ "value": "${PERL_APACHE2_RELOAD}"
+ }
+ ]
+ }
+ ]
+ }
+ }
+ }
+ },
+ {
+ "kind": "Service",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "${DATABASE_SERVICE_NAME}",
+ "annotations": {
+ "description": "Exposes the database server"
+ }
+ },
+ "spec": {
+ "ports": [
+ {
+ "name": "mysql",
+ "port": 3306,
+ "targetPort": 3306
+ }
+ ],
+ "selector": {
+ "name": "${DATABASE_SERVICE_NAME}"
+ }
+ }
+ },
+ {
+ "kind": "DeploymentConfig",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "${DATABASE_SERVICE_NAME}",
+ "annotations": {
+ "description": "Defines how to deploy the database"
+ }
+ },
+ "spec": {
+ "strategy": {
+ "type": "Recreate"
+ },
+ "triggers": [
+ {
+ "type": "ConfigChange"
+ }
+ ],
+ "replicas": 1,
+ "selector": {
+ "name": "${DATABASE_SERVICE_NAME}"
+ },
+ "template": {
+ "metadata": {
+ "name": "${DATABASE_SERVICE_NAME}",
+ "labels": {
+ "name": "${DATABASE_SERVICE_NAME}"
+ }
+ },
+ "spec": {
+ "containers": [
+ {
+ "name": "mysql",
+ "image": "${MYSQL_IMAGE}",
+ "ports": [
+ {
+ "containerPort": 3306
+ }
+ ],
+ "env": [
+ {
+ "name": "MYSQL_USER",
+ "value": "${DATABASE_USER}"
+ },
+ {
+ "name": "MYSQL_PASSWORD",
+ "value": "${DATABASE_PASSWORD}"
+ },
+ {
+ "name": "MYSQL_DATABASE",
+ "value": "${DATABASE_NAME}"
+ }
+ ]
+ }
+ ]
+ }
+ }
+ }
+ }
+ ],
+ "parameters": [
+ {
+ "name": "SOURCE_REPOSITORY_URL",
+ "description": "The URL of the repository with your application source code",
+ "value": "https://github.com/openshift/dancer-ex.git"
+ },
+ {
+ "name": "SOURCE_REPOSITORY_REF",
+ "description": "Set this to a branch name, tag or other ref of your repository if you are not using the default branch"
+ },
+ {
+ "name": "CONTEXT_DIR",
+ "description": "Set this to the relative path to your project if it is not in the root of your repository"
+ },
+ {
+ "name": "APPLICATION_DOMAIN",
+ "description": "The exposed hostname that will route to the Dancer service, if left blank a value will be defaulted.",
+ "value": ""
+ },
+ {
+ "name": "GITHUB_WEBHOOK_SECRET",
+ "description": "A secret string used to configure the GitHub webhook",
+ "generate": "expression",
+ "from": "[a-zA-Z0-9]{40}"
+ },
+ {
+ "name": "ADMIN_USERNAME",
+ "description": "administrator username",
+ "generate": "expression",
+ "from": "admin[A-Z0-9]{3}"
+ },
+ {
+ "name": "ADMIN_PASSWORD",
+ "description": "administrator password",
+ "generate": "expression",
+ "from": "[a-zA-Z0-9]{8}"
+ },
+ {
+ "name": "DATABASE_SERVICE_NAME",
+ "description": "Database service name",
+ "value": "database"
+ },
+ {
+ "name": "DATABASE_USER",
+ "description": "database username",
+ "generate": "expression",
+ "from": "user[A-Z0-9]{3}"
+ },
+ {
+ "name": "DATABASE_PASSWORD",
+ "description": "database password",
+ "generate": "expression",
+ "from": "[a-zA-Z0-9]{8}"
+ },
+ {
+ "name": "DATABASE_NAME",
+ "description": "database name",
+ "value": "sampledb"
+ },
+ {
+ "name": "MYSQL_IMAGE",
+ "description": "Image to use for mysql",
+ "value": "openshift/mysql-55-centos7"
+ },
+ {
+ "name": "PERL_APACHE2_RELOAD",
+ "description": "Set this to \"true\" to enable automatic reloading of modified Perl modules",
+ "value": ""
+ },
+ {
+ "name": "SECRET_KEY_BASE",
+ "description": "Your secret key for verifying the integrity of signed cookies",
+ "generate": "expression",
+ "from": "[a-z0-9]{127}"
+ }
+ ]
+}
diff --git a/roles/openshift_examples/files/examples/quickstart-templates/dancer.json b/roles/openshift_examples/files/examples/quickstart-templates/dancer.json
new file mode 100644
index 000000000..3ee19be83
--- /dev/null
+++ b/roles/openshift_examples/files/examples/quickstart-templates/dancer.json
@@ -0,0 +1,211 @@
+{
+ "kind": "Template",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "dancer-example",
+ "annotations": {
+ "description": "An example Dancer application with no database",
+ "tags": "instant-app,perl,dancer",
+ "iconClass": "icon-perl"
+ }
+ },
+ "labels": {
+ "template": "dancer-example"
+ },
+ "objects": [
+ {
+ "kind": "Service",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "dancer-example",
+ "annotations": {
+ "description": "Exposes and load balances the application pods"
+ }
+ },
+ "spec": {
+ "ports": [
+ {
+ "name": "web",
+ "port": 8080,
+ "targetPort": 8080
+ }
+ ],
+ "selector": {
+ "name": "dancer-example"
+ }
+ }
+ },
+ {
+ "kind": "Route",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "dancer-example"
+ },
+ "spec": {
+ "host": "${APPLICATION_DOMAIN}",
+ "to": {
+ "kind": "Service",
+ "name": "dancer-example"
+ }
+ }
+ },
+ {
+ "kind": "ImageStream",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "dancer-example",
+ "annotations": {
+ "description": "Keeps track of changes in the application image"
+ }
+ }
+ },
+ {
+ "kind": "BuildConfig",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "dancer-example",
+ "annotations": {
+ "description": "Defines how to build the application"
+ }
+ },
+ "spec": {
+ "source": {
+ "type": "Git",
+ "git": {
+ "uri": "${SOURCE_REPOSITORY_URL}",
+ "ref": "${SOURCE_REPOSITORY_REF}"
+ },
+ "contextDir": "${CONTEXT_DIR}"
+ },
+ "strategy": {
+ "type": "Source",
+ "sourceStrategy": {
+ "from": {
+ "kind": "ImageStreamTag",
+ "namespace": "openshift",
+ "name": "perl:5.16"
+ }
+ }
+ },
+ "output": {
+ "to": {
+ "kind": "ImageStreamTag",
+ "name": "dancer-example:latest"
+ }
+ },
+ "triggers": [
+ {
+ "type": "ImageChange"
+ },
+ {
+ "type": "GitHub",
+ "github": {
+ "secret": "${GITHUB_WEBHOOK_SECRET}"
+ }
+ }
+ ]
+ }
+ },
+ {
+ "kind": "DeploymentConfig",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "dancer-example",
+ "annotations": {
+ "description": "Defines how to deploy the application server"
+ }
+ },
+ "spec": {
+ "strategy": {
+ "type": "Rolling"
+ },
+ "triggers": [
+ {
+ "type": "ImageChange",
+ "imageChangeParams": {
+ "automatic": true,
+ "containerNames": [
+ "dancer-example"
+ ],
+ "from": {
+ "kind": "ImageStreamTag",
+ "name": "dancer-example:latest"
+ }
+ }
+ },
+ {
+ "type": "ConfigChange"
+ }
+ ],
+ "replicas": 1,
+ "selector": {
+ "name": "dancer-example"
+ },
+ "template": {
+ "metadata": {
+ "name": "dancer-example",
+ "labels": {
+ "name": "dancer-example"
+ }
+ },
+ "spec": {
+ "containers": [
+ {
+ "name": "dancer-example",
+ "image": "dancer-example",
+ "ports": [
+ {
+ "containerPort": 8080
+ }
+ ],
+ "env": [
+ {
+ "name": "PERL_APACHE2_RELOAD",
+ "value": "${PERL_APACHE2_RELOAD}"
+ }
+ ]
+ }
+ ]
+ }
+ }
+ }
+ }
+ ],
+ "parameters": [
+ {
+ "name": "SOURCE_REPOSITORY_URL",
+ "description": "The URL of the repository with your application source code",
+ "value": "https://github.com/openshift/dancer-ex.git"
+ },
+ {
+ "name": "SOURCE_REPOSITORY_REF",
+ "description": "Set this to a branch name, tag or other ref of your repository if you are not using the default branch"
+ },
+ {
+ "name": "CONTEXT_DIR",
+ "description": "Set this to the relative path to your project if it is not in the root of your repository"
+ },
+ {
+ "name": "APPLICATION_DOMAIN",
+ "description": "The exposed hostname that will route to the Dancer service, if left blank a value will be defaulted.",
+ "value": ""
+ },
+ {
+ "name": "GITHUB_WEBHOOK_SECRET",
+ "description": "A secret string used to configure the GitHub webhook",
+ "generate": "expression",
+ "from": "[a-zA-Z0-9]{40}"
+ },
+ {
+ "name": "SECRET_KEY_BASE",
+ "description": "Your secret key for verifying the integrity of signed cookies",
+ "generate": "expression",
+ "from": "[a-z0-9]{127}"
+ },
+ {
+ "name": "PERL_APACHE2_RELOAD",
+ "description": "Set this to \"true\" to enable automatic reloading of modified Perl modules",
+ "value": ""
+ }
+ ]
+}
diff --git a/roles/openshift_examples/files/examples/quickstart-templates/django-postgresql.json b/roles/openshift_examples/files/examples/quickstart-templates/django-postgresql.json
new file mode 100644
index 000000000..749064e98
--- /dev/null
+++ b/roles/openshift_examples/files/examples/quickstart-templates/django-postgresql.json
@@ -0,0 +1,346 @@
+{
+ "kind": "Template",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "django-psql-example",
+ "annotations": {
+ "description": "An example Django application with a PostgreSQL database",
+ "tags": "instant-app,python,django,postgresql",
+ "iconClass": "icon-python"
+ }
+ },
+ "labels": {
+ "template": "django-psql-example"
+ },
+ "objects": [
+ {
+ "kind": "Service",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "django-psql-example",
+ "annotations": {
+ "description": "Exposes and load balances the application pods"
+ }
+ },
+ "spec": {
+ "ports": [
+ {
+ "name": "web",
+ "port": 8080,
+ "targetPort": 8080
+ }
+ ],
+ "selector": {
+ "name": "django-psql-example"
+ }
+ }
+ },
+ {
+ "kind": "Route",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "django-psql-example"
+ },
+ "spec": {
+ "host": "${APPLICATION_DOMAIN}",
+ "to": {
+ "kind": "Service",
+ "name": "django-psql-example"
+ }
+ }
+ },
+ {
+ "kind": "ImageStream",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "django-psql-example",
+ "annotations": {
+ "description": "Keeps track of changes in the application image"
+ }
+ }
+ },
+ {
+ "kind": "BuildConfig",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "django-psql-example",
+ "annotations": {
+ "description": "Defines how to build the application"
+ }
+ },
+ "spec": {
+ "source": {
+ "type": "Git",
+ "git": {
+ "uri": "${SOURCE_REPOSITORY_URL}",
+ "ref": "${SOURCE_REPOSITORY_REF}"
+ },
+ "contextDir": "${CONTEXT_DIR}"
+ },
+ "strategy": {
+ "type": "Source",
+ "sourceStrategy": {
+ "from": {
+ "kind": "ImageStreamTag",
+ "namespace": "openshift",
+ "name": "python:3.3"
+ }
+ }
+ },
+ "output": {
+ "to": {
+ "kind": "ImageStreamTag",
+ "name": "django-psql-example:latest"
+ }
+ },
+ "triggers": [
+ {
+ "type": "ImageChange"
+ },
+ {
+ "type": "GitHub",
+ "github": {
+ "secret": "${GITHUB_WEBHOOK_SECRET}"
+ }
+ }
+ ]
+ }
+ },
+ {
+ "kind": "DeploymentConfig",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "django-psql-example",
+ "annotations": {
+ "description": "Defines how to deploy the application server"
+ }
+ },
+ "spec": {
+ "strategy": {
+ "type": "Rolling"
+ },
+ "triggers": [
+ {
+ "type": "ImageChange",
+ "imageChangeParams": {
+ "automatic": true,
+ "containerNames": [
+ "django-psql-example"
+ ],
+ "from": {
+ "kind": "ImageStreamTag",
+ "name": "django-psql-example:latest"
+ }
+ }
+ },
+ {
+ "type": "ConfigChange"
+ }
+ ],
+ "replicas": 1,
+ "selector": {
+ "name": "django-psql-example"
+ },
+ "template": {
+ "metadata": {
+ "name": "django-psql-example",
+ "labels": {
+ "name": "django-psql-example"
+ }
+ },
+ "spec": {
+ "containers": [
+ {
+ "name": "django-psql-example",
+ "image": "django-psql-example",
+ "ports": [
+ {
+ "containerPort": 8080
+ }
+ ],
+ "env": [
+ {
+ "name": "DATABASE_SERVICE_NAME",
+ "value": "${DATABASE_SERVICE_NAME}"
+ },
+ {
+ "name": "DATABASE_ENGINE",
+ "value": "${DATABASE_ENGINE}"
+ },
+ {
+ "name": "DATABASE_NAME",
+ "value": "${DATABASE_NAME}"
+ },
+ {
+ "name": "DATABASE_USER",
+ "value": "${DATABASE_USER}"
+ },
+ {
+ "name": "DATABASE_PASSWORD",
+ "value": "${DATABASE_PASSWORD}"
+ },
+ {
+ "name": "APP_CONFIG",
+ "value": "${APP_CONFIG}"
+ },
+ {
+ "name": "DJANGO_SECRET_KEY",
+ "value": "${DJANGO_SECRET_KEY}"
+ }
+ ]
+ }
+ ]
+ }
+ }
+ }
+ },
+ {
+ "kind": "Service",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "${DATABASE_SERVICE_NAME}",
+ "annotations": {
+ "description": "Exposes the database server"
+ }
+ },
+ "spec": {
+ "ports": [
+ {
+ "name": "postgresql",
+ "port": 5432,
+ "targetPort": 5432
+ }
+ ],
+ "selector": {
+ "name": "${DATABASE_SERVICE_NAME}"
+ }
+ }
+ },
+ {
+ "kind": "DeploymentConfig",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "${DATABASE_SERVICE_NAME}",
+ "annotations": {
+ "description": "Defines how to deploy the database"
+ }
+ },
+ "spec": {
+ "strategy": {
+ "type": "Recreate"
+ },
+ "triggers": [
+ {
+ "type": "ConfigChange"
+ }
+ ],
+ "replicas": 1,
+ "selector": {
+ "name": "${DATABASE_SERVICE_NAME}"
+ },
+ "template": {
+ "metadata": {
+ "name": "${DATABASE_SERVICE_NAME}",
+ "labels": {
+ "name": "${DATABASE_SERVICE_NAME}"
+ }
+ },
+ "spec": {
+ "containers": [
+ {
+ "name": "postgresql",
+ "image": "${POSTGRESQL_IMAGE}",
+ "ports": [
+ {
+ "containerPort": 5432
+ }
+ ],
+ "env": [
+ {
+ "name": "POSTGRESQL_USER",
+ "value": "${DATABASE_USER}"
+ },
+ {
+ "name": "POSTGRESQL_PASSWORD",
+ "value": "${DATABASE_PASSWORD}"
+ },
+ {
+ "name": "POSTGRESQL_DATABASE",
+ "value": "${DATABASE_NAME}"
+ }
+ ]
+ }
+ ]
+ }
+ }
+ }
+ }
+ ],
+ "parameters": [
+ {
+ "name": "SOURCE_REPOSITORY_URL",
+ "description": "The URL of the repository with your application source code",
+ "value": "https://github.com/openshift/django-ex.git"
+ },
+ {
+ "name": "SOURCE_REPOSITORY_REF",
+ "description": "Set this to a branch name, tag or other ref of your repository if you are not using the default branch"
+ },
+ {
+ "name": "CONTEXT_DIR",
+ "description": "Set this to the relative path to your project if it is not in the root of your repository"
+ },
+ {
+ "name": "APPLICATION_DOMAIN",
+ "description": "The exposed hostname that will route to the Django service, if left blank a value will be defaulted.",
+ "value": ""
+ },
+ {
+ "name": "GITHUB_WEBHOOK_SECRET",
+ "description": "A secret string used to configure the GitHub webhook",
+ "generate": "expression",
+ "from": "[a-zA-Z0-9]{40}"
+ },
+ {
+ "name": "DATABASE_SERVICE_NAME",
+ "description": "Database service name",
+ "value": "postgresql"
+ },
+ {
+ "name": "DATABASE_ENGINE",
+ "description": "Database engine: postgresql, mysql or sqlite (default)",
+ "value": "postgresql"
+ },
+ {
+ "name": "DATABASE_NAME",
+ "description": "Database name",
+ "value": "default"
+ },
+ {
+ "name": "DATABASE_USER",
+ "description": "Database user name",
+ "value": "django"
+ },
+ {
+ "name": "DATABASE_PASSWORD",
+ "description": "Database user password",
+ "generate": "expression",
+ "from": "[a-zA-Z0-9]{16}"
+ },
+ {
+ "name": "POSTGRESQL_IMAGE",
+ "description": "Image to use for postgresql",
+ "value": "openshift/postgresql-92-centos7"
+ },
+ {
+ "name": "APP_CONFIG",
+ "description": "Relative path to Gunicorn configuration file (optional)"
+ },
+ {
+ "name": "DJANGO_SECRET_KEY",
+ "description": "Set this to a long random string",
+ "generate": "expression",
+ "from": "[\\w]{50}"
+ }
+ ]
+}
diff --git a/roles/openshift_examples/files/examples/quickstart-templates/django.json b/roles/openshift_examples/files/examples/quickstart-templates/django.json
new file mode 100644
index 000000000..143a942ab
--- /dev/null
+++ b/roles/openshift_examples/files/examples/quickstart-templates/django.json
@@ -0,0 +1,254 @@
+{
+ "kind": "Template",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "django-example",
+ "annotations": {
+ "description": "An example Django application with no database",
+ "tags": "instant-app,python,django",
+ "iconClass": "icon-python"
+ }
+ },
+ "labels": {
+ "template": "django-example"
+ },
+ "objects": [
+ {
+ "kind": "Service",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "django-example",
+ "annotations": {
+ "description": "Exposes and load balances the application pods"
+ }
+ },
+ "spec": {
+ "ports": [
+ {
+ "name": "web",
+ "port": 8080,
+ "targetPort": 8080
+ }
+ ],
+ "selector": {
+ "name": "django-example"
+ }
+ }
+ },
+ {
+ "kind": "Route",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "django-example"
+ },
+ "spec": {
+ "host": "${APPLICATION_DOMAIN}",
+ "to": {
+ "kind": "Service",
+ "name": "django-example"
+ }
+ }
+ },
+ {
+ "kind": "ImageStream",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "django-example",
+ "annotations": {
+ "description": "Keeps track of changes in the application image"
+ }
+ }
+ },
+ {
+ "kind": "BuildConfig",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "django-example",
+ "annotations": {
+ "description": "Defines how to build the application"
+ }
+ },
+ "spec": {
+ "source": {
+ "type": "Git",
+ "git": {
+ "uri": "${SOURCE_REPOSITORY_URL}",
+ "ref": "${SOURCE_REPOSITORY_REF}"
+ },
+ "contextDir": "${CONTEXT_DIR}"
+ },
+ "strategy": {
+ "type": "Source",
+ "sourceStrategy": {
+ "from": {
+ "kind": "ImageStreamTag",
+ "namespace": "openshift",
+ "name": "python:3.3"
+ }
+ }
+ },
+ "output": {
+ "to": {
+ "kind": "ImageStreamTag",
+ "name": "django-example:latest"
+ }
+ },
+ "triggers": [
+ {
+ "type": "ImageChange"
+ },
+ {
+ "type": "GitHub",
+ "github": {
+ "secret": "${GITHUB_WEBHOOK_SECRET}"
+ }
+ }
+ ]
+ }
+ },
+ {
+ "kind": "DeploymentConfig",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "django-example",
+ "annotations": {
+ "description": "Defines how to deploy the application server"
+ }
+ },
+ "spec": {
+ "strategy": {
+ "type": "Rolling"
+ },
+ "triggers": [
+ {
+ "type": "ImageChange",
+ "imageChangeParams": {
+ "automatic": true,
+ "containerNames": [
+ "django-example"
+ ],
+ "from": {
+ "kind": "ImageStreamTag",
+ "name": "django-example:latest"
+ }
+ }
+ },
+ {
+ "type": "ConfigChange"
+ }
+ ],
+ "replicas": 1,
+ "selector": {
+ "name": "django-example"
+ },
+ "template": {
+ "metadata": {
+ "name": "django-example",
+ "labels": {
+ "name": "django-example"
+ }
+ },
+ "spec": {
+ "containers": [
+ {
+ "name": "django-example",
+ "image": "django-example",
+ "ports": [
+ {
+ "containerPort": 8080
+ }
+ ],
+ "env": [
+ {
+ "name": "DATABASE_SERVICE_NAME",
+ "value": "${DATABASE_SERVICE_NAME}"
+ },
+ {
+ "name": "DATABASE_ENGINE",
+ "value": "${DATABASE_ENGINE}"
+ },
+ {
+ "name": "DATABASE_NAME",
+ "value": "${DATABASE_NAME}"
+ },
+ {
+ "name": "DATABASE_USER",
+ "value": "${DATABASE_USER}"
+ },
+ {
+ "name": "DATABASE_PASSWORD",
+ "value": "${DATABASE_PASSWORD}"
+ },
+ {
+ "name": "APP_CONFIG",
+ "value": "${APP_CONFIG}"
+ },
+ {
+ "name": "DJANGO_SECRET_KEY",
+ "value": "${DJANGO_SECRET_KEY}"
+ }
+ ]
+ }
+ ]
+ }
+ }
+ }
+ }
+ ],
+ "parameters": [
+ {
+ "name": "SOURCE_REPOSITORY_URL",
+ "description": "The URL of the repository with your application source code",
+ "value": "https://github.com/openshift/django-ex.git"
+ },
+ {
+ "name": "SOURCE_REPOSITORY_REF",
+ "description": "Set this to a branch name, tag or other ref of your repository if you are not using the default branch"
+ },
+ {
+ "name": "CONTEXT_DIR",
+ "description": "Set this to the relative path to your project if it is not in the root of your repository"
+ },
+ {
+ "name": "APPLICATION_DOMAIN",
+ "description": "The exposed hostname that will route to the Django service, if left blank a value will be defaulted.",
+ "value": ""
+ },
+ {
+ "name": "GITHUB_WEBHOOK_SECRET",
+ "description": "A secret string used to configure the GitHub webhook",
+ "generate": "expression",
+ "from": "[a-zA-Z0-9]{40}"
+ },
+ {
+ "name": "DATABASE_SERVICE_NAME",
+ "description": "Database service name"
+ },
+ {
+ "name": "DATABASE_ENGINE",
+ "description": "Database engine: postgresql, mysql or sqlite (default)"
+ },
+ {
+ "name": "DATABASE_NAME",
+ "description": "Database name"
+ },
+ {
+ "name": "DATABASE_USER",
+ "description": "Database user name"
+ },
+ {
+ "name": "DATABASE_PASSWORD",
+ "description": "Database user password"
+ },
+ {
+ "name": "APP_CONFIG",
+ "description": "Relative path to Gunicorn configuration file (optional)"
+ },
+ {
+ "name": "DJANGO_SECRET_KEY",
+ "description": "Set this to a long random string",
+ "generate": "expression",
+ "from": "[\\w]{50}"
+ }
+ ]
+}
diff --git a/roles/openshift_examples/files/examples/quickstart-templates/jenkins-ephemeral-template.json b/roles/openshift_examples/files/examples/quickstart-templates/jenkins-ephemeral-template.json
new file mode 100644
index 000000000..14bd032af
--- /dev/null
+++ b/roles/openshift_examples/files/examples/quickstart-templates/jenkins-ephemeral-template.json
@@ -0,0 +1,150 @@
+{
+ "kind": "Template",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "jenkins-ephemeral",
+ "creationTimestamp": null,
+ "annotations": {
+ "description": "Jenkins service, without persistent storage. WARNING: Any data stored will be lost upon pod destruction. Only use this template for testing",
+ "iconClass": "icon-jenkins",
+ "tags": "database,jenkins"
+ }
+ },
+ "objects": [
+ {
+ "kind": "Service",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "${JENKINS_SERVICE_NAME}",
+ "creationTimestamp": null
+ },
+ "spec": {
+ "ports": [
+ {
+ "name": "web",
+ "protocol": "TCP",
+ "port": 8080,
+ "targetPort": 8080,
+ "nodePort": 0
+ }
+ ],
+ "selector": {
+ "name": "${JENKINS_SERVICE_NAME}"
+ },
+ "portalIP": "",
+ "type": "ClusterIP",
+ "sessionAffinity": "None"
+ }
+ },
+ {
+ "kind": "Route",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "jenkins",
+ "creationTimestamp": null
+ },
+ "spec": {
+ "to": {
+ "kind": "Service",
+ "name": "${JENKINS_SERVICE_NAME}"
+ },
+ "tls": {
+ "termination": "edge",
+ "certificate": "-----BEGIN CERTIFICATE-----\nMIIDIjCCAgqgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBoTELMAkGA1UEBhMCVVMx\nCzAJBgNVBAgMAlNDMRUwEwYDVQQHDAxEZWZhdWx0IENpdHkxHDAaBgNVBAoME0Rl\nZmF1bHQgQ29tcGFueSBMdGQxEDAOBgNVBAsMB1Rlc3QgQ0ExGjAYBgNVBAMMEXd3\ndy5leGFtcGxlY2EuY29tMSIwIAYJKoZIhvcNAQkBFhNleGFtcGxlQGV4YW1wbGUu\nY29tMB4XDTE1MDExMjE0MTk0MVoXDTE2MDExMjE0MTk0MVowfDEYMBYGA1UEAwwP\nd3d3LmV4YW1wbGUuY29tMQswCQYDVQQIDAJTQzELMAkGA1UEBhMCVVMxIjAgBgkq\nhkiG9w0BCQEWE2V4YW1wbGVAZXhhbXBsZS5jb20xEDAOBgNVBAoMB0V4YW1wbGUx\nEDAOBgNVBAsMB0V4YW1wbGUwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMrv\ngu6ZTTefNN7jjiZbS/xvQjyXjYMN7oVXv76jbX8gjMOmg9m0xoVZZFAE4XyQDuCm\n47VRx5Qrf/YLXmB2VtCFvB0AhXr5zSeWzPwaAPrjA4ebG+LUo24ziS8KqNxrFs1M\nmNrQUgZyQC6XIe1JHXc9t+JlL5UZyZQC1IfaJulDAgMBAAGjDTALMAkGA1UdEwQC\nMAAwDQYJKoZIhvcNAQEFBQADggEBAFCi7ZlkMnESvzlZCvv82Pq6S46AAOTPXdFd\nTMvrh12E1sdVALF1P1oYFJzG1EiZ5ezOx88fEDTW+Lxb9anw5/KJzwtWcfsupf1m\nV7J0D3qKzw5C1wjzYHh9/Pz7B1D0KthQRATQCfNf8s6bbFLaw/dmiIUhHLtIH5Qc\nyfrejTZbOSP77z8NOWir+BWWgIDDB2//3AkDIQvT20vmkZRhkqSdT7et4NmXOX/j\njhPti4b2Fie0LeuvgaOdKjCpQQNrYthZHXeVlOLRhMTSk3qUczenkKTOhvP7IS9q\n+Dzv5hqgSfvMG392KWh5f8xXfJNs4W5KLbZyl901MeReiLrPH3w=\n-----END CERTIFICATE-----",
+ "key": "-----BEGIN PRIVATE KEY-----\nMIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBAMrvgu6ZTTefNN7j\njiZbS/xvQjyXjYMN7oVXv76jbX8gjMOmg9m0xoVZZFAE4XyQDuCm47VRx5Qrf/YL\nXmB2VtCFvB0AhXr5zSeWzPwaAPrjA4ebG+LUo24ziS8KqNxrFs1MmNrQUgZyQC6X\nIe1JHXc9t+JlL5UZyZQC1IfaJulDAgMBAAECgYEAnxOjEj/vrLNLMZE1Q9H7PZVF\nWdP/JQVNvQ7tCpZ3ZdjxHwkvf//aQnuxS5yX2Rnf37BS/TZu+TIkK4373CfHomSx\nUTAn2FsLmOJljupgGcoeLx5K5nu7B7rY5L1NHvdpxZ4YjeISrRtEPvRakllENU5y\ngJE8c2eQOx08ZSRE4TkCQQD7dws2/FldqwdjJucYijsJVuUdoTqxP8gWL6bB251q\nelP2/a6W2elqOcWId28560jG9ZS3cuKvnmu/4LG88vZFAkEAzphrH3673oTsHN+d\nuBd5uyrlnGjWjuiMKv2TPITZcWBjB8nJDSvLneHF59MYwejNNEof2tRjgFSdImFH\nmi995wJBAMtPjW6wiqRz0i41VuT9ZgwACJBzOdvzQJfHgSD9qgFb1CU/J/hpSRIM\nkYvrXK9MbvQFvG6x4VuyT1W8mpe1LK0CQAo8VPpffhFdRpF7psXLK/XQ/0VLkG3O\nKburipLyBg/u9ZkaL0Ley5zL5dFBjTV2Qkx367Ic2b0u9AYTCcgi2DsCQQD3zZ7B\nv7BOm7MkylKokY2MduFFXU0Bxg6pfZ7q3rvg8gqhUFbaMStPRYg6myiDiW/JfLhF\nTcFT4touIo7oriFJ\n-----END PRIVATE KEY-----",
+ "caCertificate": "-----BEGIN CERTIFICATE-----\nMIIEFzCCAv+gAwIBAgIJALK1iUpF2VQLMA0GCSqGSIb3DQEBBQUAMIGhMQswCQYD\nVQQGEwJVUzELMAkGA1UECAwCU0MxFTATBgNVBAcMDERlZmF1bHQgQ2l0eTEcMBoG\nA1UECgwTRGVmYXVsdCBDb21wYW55IEx0ZDEQMA4GA1UECwwHVGVzdCBDQTEaMBgG\nA1UEAwwRd3d3LmV4YW1wbGVjYS5jb20xIjAgBgkqhkiG9w0BCQEWE2V4YW1wbGVA\nZXhhbXBsZS5jb20wHhcNMTUwMTEyMTQxNTAxWhcNMjUwMTA5MTQxNTAxWjCBoTEL\nMAkGA1UEBhMCVVMxCzAJBgNVBAgMAlNDMRUwEwYDVQQHDAxEZWZhdWx0IENpdHkx\nHDAaBgNVBAoME0RlZmF1bHQgQ29tcGFueSBMdGQxEDAOBgNVBAsMB1Rlc3QgQ0Ex\nGjAYBgNVBAMMEXd3dy5leGFtcGxlY2EuY29tMSIwIAYJKoZIhvcNAQkBFhNleGFt\ncGxlQGV4YW1wbGUuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA\nw2rK1J2NMtQj0KDug7g7HRKl5jbf0QMkMKyTU1fBtZ0cCzvsF4CqV11LK4BSVWaK\nrzkaXe99IVJnH8KdOlDl5Dh/+cJ3xdkClSyeUT4zgb6CCBqg78ePp+nN11JKuJlV\nIG1qdJpB1J5O/kCLsGcTf7RS74MtqMFo96446Zvt7YaBhWPz6gDaO/TUzfrNcGLA\nEfHVXkvVWqb3gqXUztZyVex/gtP9FXQ7gxTvJml7UkmT0VAFjtZnCqmFxpLZFZ15\n+qP9O7Q2MpsGUO/4vDAuYrKBeg1ZdPSi8gwqUP2qWsGd9MIWRv3thI2903BczDc7\nr8WaIbm37vYZAS9G56E4+wIDAQABo1AwTjAdBgNVHQ4EFgQUugLrSJshOBk5TSsU\nANs4+SmJUGwwHwYDVR0jBBgwFoAUugLrSJshOBk5TSsUANs4+SmJUGwwDAYDVR0T\nBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEAaMJ33zAMV4korHo5aPfayV3uHoYZ\n1ChzP3eSsF+FjoscpoNSKs91ZXZF6LquzoNezbfiihK4PYqgwVD2+O0/Ty7UjN4S\nqzFKVR4OS/6lCJ8YncxoFpTntbvjgojf1DEataKFUN196PAANc3yz8cWHF4uvjPv\nWkgFqbIjb+7D1YgglNyovXkRDlRZl0LD1OQ0ZWhd4Ge1qx8mmmanoBeYZ9+DgpFC\nj9tQAbS867yeOryNe7sEOIpXAAqK/DTu0hB6+ySsDfMo4piXCc2aA/eI2DCuw08e\nw17Dz9WnupZjVdwTKzDhFgJZMLDqn37HQnT6EemLFqbcR0VPEnfyhDtZIQ==\n-----END CERTIFICATE-----"
+ }
+ }
+ },
+ {
+ "kind": "DeploymentConfig",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "${JENKINS_SERVICE_NAME}",
+ "creationTimestamp": null
+ },
+ "spec": {
+ "strategy": {
+ "type": "Recreate",
+ "resources": {}
+ },
+ "triggers": [
+ {
+ "type": "ConfigChange"
+ }
+ ],
+ "replicas": 1,
+ "selector": {
+ "name": "${JENKINS_SERVICE_NAME}"
+ },
+ "template": {
+ "metadata": {
+ "creationTimestamp": null,
+ "labels": {
+ "name": "${JENKINS_SERVICE_NAME}"
+ }
+ },
+ "spec": {
+ "containers": [
+ {
+ "name": "jenkins",
+ "image": "${JENKINS_IMAGE}",
+ "env": [
+ {
+ "name": "JENKINS_PASSWORD",
+ "value": "${JENKINS_PASSWORD}"
+ }
+ ],
+ "resources": {},
+ "volumeMounts": [
+ {
+ "name": "${JENKINS_SERVICE_NAME}-data",
+ "mountPath": "/var/lib/jenkins"
+ }
+ ],
+ "terminationMessagePath": "/dev/termination-log",
+ "imagePullPolicy": "IfNotPresent",
+ "capabilities": {},
+ "securityContext": {
+ "capabilities": {},
+ "privileged": false
+ }
+ }
+ ],
+ "volumes": [
+ {
+ "name": "${JENKINS_SERVICE_NAME}-data",
+ "emptyDir": {
+ "medium": ""
+ }
+ }
+ ],
+ "restartPolicy": "Always",
+ "dnsPolicy": "ClusterFirst"
+ }
+ }
+ }
+ }
+ ],
+ "parameters": [
+ {
+ "name": "JENKINS_SERVICE_NAME",
+ "description": "Jenkins service name",
+ "value": "jenkins"
+ },
+ {
+ "name": "JENKINS_IMAGE",
+ "description": "Jenkins Docker image to use",
+ "value": "openshift/jenkins-1-centos7"
+ },
+ {
+ "name": "JENKINS_PASSWORD",
+ "description": "Password for the Jenkins user",
+ "generate": "expression",
+ "value": "password"
+ }
+ ],
+ "labels": {
+ "template": "jenkins-ephemeral-template"
+ }
+}
diff --git a/roles/openshift_examples/files/examples/quickstart-templates/jenkins-persistent-template.json b/roles/openshift_examples/files/examples/quickstart-templates/jenkins-persistent-template.json
new file mode 100644
index 000000000..fa31de486
--- /dev/null
+++ b/roles/openshift_examples/files/examples/quickstart-templates/jenkins-persistent-template.json
@@ -0,0 +1,173 @@
+{
+ "kind": "Template",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "jenkins-persistent",
+ "creationTimestamp": null,
+ "annotations": {
+ "description": "Jenkins service, with persistent storage.",
+ "iconClass": "icon-jenkins",
+ "tags": "database,jenkins"
+ }
+ },
+ "objects": [
+ {
+ "kind": "Service",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "${JENKINS_SERVICE_NAME}",
+ "creationTimestamp": null
+ },
+ "spec": {
+ "ports": [
+ {
+ "name": "web",
+ "protocol": "TCP",
+ "port": 8080,
+ "targetPort": 8080,
+ "nodePort": 0
+ }
+ ],
+ "selector": {
+ "name": "${JENKINS_SERVICE_NAME}"
+ },
+ "portalIP": "",
+ "type": "ClusterIP",
+ "sessionAffinity": "None"
+ }
+ },
+ {
+ "kind": "Route",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "jenkins",
+ "creationTimestamp": null
+ },
+ "spec": {
+ "to": {
+ "kind": "Service",
+ "name": "${JENKINS_SERVICE_NAME}"
+ },
+ "tls": {
+ "termination": "edge",
+ "certificate": "-----BEGIN CERTIFICATE-----\nMIIDIjCCAgqgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBoTELMAkGA1UEBhMCVVMx\nCzAJBgNVBAgMAlNDMRUwEwYDVQQHDAxEZWZhdWx0IENpdHkxHDAaBgNVBAoME0Rl\nZmF1bHQgQ29tcGFueSBMdGQxEDAOBgNVBAsMB1Rlc3QgQ0ExGjAYBgNVBAMMEXd3\ndy5leGFtcGxlY2EuY29tMSIwIAYJKoZIhvcNAQkBFhNleGFtcGxlQGV4YW1wbGUu\nY29tMB4XDTE1MDExMjE0MTk0MVoXDTE2MDExMjE0MTk0MVowfDEYMBYGA1UEAwwP\nd3d3LmV4YW1wbGUuY29tMQswCQYDVQQIDAJTQzELMAkGA1UEBhMCVVMxIjAgBgkq\nhkiG9w0BCQEWE2V4YW1wbGVAZXhhbXBsZS5jb20xEDAOBgNVBAoMB0V4YW1wbGUx\nEDAOBgNVBAsMB0V4YW1wbGUwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMrv\ngu6ZTTefNN7jjiZbS/xvQjyXjYMN7oVXv76jbX8gjMOmg9m0xoVZZFAE4XyQDuCm\n47VRx5Qrf/YLXmB2VtCFvB0AhXr5zSeWzPwaAPrjA4ebG+LUo24ziS8KqNxrFs1M\nmNrQUgZyQC6XIe1JHXc9t+JlL5UZyZQC1IfaJulDAgMBAAGjDTALMAkGA1UdEwQC\nMAAwDQYJKoZIhvcNAQEFBQADggEBAFCi7ZlkMnESvzlZCvv82Pq6S46AAOTPXdFd\nTMvrh12E1sdVALF1P1oYFJzG1EiZ5ezOx88fEDTW+Lxb9anw5/KJzwtWcfsupf1m\nV7J0D3qKzw5C1wjzYHh9/Pz7B1D0KthQRATQCfNf8s6bbFLaw/dmiIUhHLtIH5Qc\nyfrejTZbOSP77z8NOWir+BWWgIDDB2//3AkDIQvT20vmkZRhkqSdT7et4NmXOX/j\njhPti4b2Fie0LeuvgaOdKjCpQQNrYthZHXeVlOLRhMTSk3qUczenkKTOhvP7IS9q\n+Dzv5hqgSfvMG392KWh5f8xXfJNs4W5KLbZyl901MeReiLrPH3w=\n-----END CERTIFICATE-----",
+ "key": "-----BEGIN PRIVATE KEY-----\nMIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBAMrvgu6ZTTefNN7j\njiZbS/xvQjyXjYMN7oVXv76jbX8gjMOmg9m0xoVZZFAE4XyQDuCm47VRx5Qrf/YL\nXmB2VtCFvB0AhXr5zSeWzPwaAPrjA4ebG+LUo24ziS8KqNxrFs1MmNrQUgZyQC6X\nIe1JHXc9t+JlL5UZyZQC1IfaJulDAgMBAAECgYEAnxOjEj/vrLNLMZE1Q9H7PZVF\nWdP/JQVNvQ7tCpZ3ZdjxHwkvf//aQnuxS5yX2Rnf37BS/TZu+TIkK4373CfHomSx\nUTAn2FsLmOJljupgGcoeLx5K5nu7B7rY5L1NHvdpxZ4YjeISrRtEPvRakllENU5y\ngJE8c2eQOx08ZSRE4TkCQQD7dws2/FldqwdjJucYijsJVuUdoTqxP8gWL6bB251q\nelP2/a6W2elqOcWId28560jG9ZS3cuKvnmu/4LG88vZFAkEAzphrH3673oTsHN+d\nuBd5uyrlnGjWjuiMKv2TPITZcWBjB8nJDSvLneHF59MYwejNNEof2tRjgFSdImFH\nmi995wJBAMtPjW6wiqRz0i41VuT9ZgwACJBzOdvzQJfHgSD9qgFb1CU/J/hpSRIM\nkYvrXK9MbvQFvG6x4VuyT1W8mpe1LK0CQAo8VPpffhFdRpF7psXLK/XQ/0VLkG3O\nKburipLyBg/u9ZkaL0Ley5zL5dFBjTV2Qkx367Ic2b0u9AYTCcgi2DsCQQD3zZ7B\nv7BOm7MkylKokY2MduFFXU0Bxg6pfZ7q3rvg8gqhUFbaMStPRYg6myiDiW/JfLhF\nTcFT4touIo7oriFJ\n-----END PRIVATE KEY-----",
+ "caCertificate": "-----BEGIN CERTIFICATE-----\nMIIEFzCCAv+gAwIBAgIJALK1iUpF2VQLMA0GCSqGSIb3DQEBBQUAMIGhMQswCQYD\nVQQGEwJVUzELMAkGA1UECAwCU0MxFTATBgNVBAcMDERlZmF1bHQgQ2l0eTEcMBoG\nA1UECgwTRGVmYXVsdCBDb21wYW55IEx0ZDEQMA4GA1UECwwHVGVzdCBDQTEaMBgG\nA1UEAwwRd3d3LmV4YW1wbGVjYS5jb20xIjAgBgkqhkiG9w0BCQEWE2V4YW1wbGVA\nZXhhbXBsZS5jb20wHhcNMTUwMTEyMTQxNTAxWhcNMjUwMTA5MTQxNTAxWjCBoTEL\nMAkGA1UEBhMCVVMxCzAJBgNVBAgMAlNDMRUwEwYDVQQHDAxEZWZhdWx0IENpdHkx\nHDAaBgNVBAoME0RlZmF1bHQgQ29tcGFueSBMdGQxEDAOBgNVBAsMB1Rlc3QgQ0Ex\nGjAYBgNVBAMMEXd3dy5leGFtcGxlY2EuY29tMSIwIAYJKoZIhvcNAQkBFhNleGFt\ncGxlQGV4YW1wbGUuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA\nw2rK1J2NMtQj0KDug7g7HRKl5jbf0QMkMKyTU1fBtZ0cCzvsF4CqV11LK4BSVWaK\nrzkaXe99IVJnH8KdOlDl5Dh/+cJ3xdkClSyeUT4zgb6CCBqg78ePp+nN11JKuJlV\nIG1qdJpB1J5O/kCLsGcTf7RS74MtqMFo96446Zvt7YaBhWPz6gDaO/TUzfrNcGLA\nEfHVXkvVWqb3gqXUztZyVex/gtP9FXQ7gxTvJml7UkmT0VAFjtZnCqmFxpLZFZ15\n+qP9O7Q2MpsGUO/4vDAuYrKBeg1ZdPSi8gwqUP2qWsGd9MIWRv3thI2903BczDc7\nr8WaIbm37vYZAS9G56E4+wIDAQABo1AwTjAdBgNVHQ4EFgQUugLrSJshOBk5TSsU\nANs4+SmJUGwwHwYDVR0jBBgwFoAUugLrSJshOBk5TSsUANs4+SmJUGwwDAYDVR0T\nBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEAaMJ33zAMV4korHo5aPfayV3uHoYZ\n1ChzP3eSsF+FjoscpoNSKs91ZXZF6LquzoNezbfiihK4PYqgwVD2+O0/Ty7UjN4S\nqzFKVR4OS/6lCJ8YncxoFpTntbvjgojf1DEataKFUN196PAANc3yz8cWHF4uvjPv\nWkgFqbIjb+7D1YgglNyovXkRDlRZl0LD1OQ0ZWhd4Ge1qx8mmmanoBeYZ9+DgpFC\nj9tQAbS867yeOryNe7sEOIpXAAqK/DTu0hB6+ySsDfMo4piXCc2aA/eI2DCuw08e\nw17Dz9WnupZjVdwTKzDhFgJZMLDqn37HQnT6EemLFqbcR0VPEnfyhDtZIQ==\n-----END CERTIFICATE-----"
+ }
+ }
+ },
+ {
+ "kind": "PersistentVolumeClaim",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "${JENKINS_SERVICE_NAME}"
+ },
+ "spec": {
+ "accessModes": [
+ "ReadWriteOnce"
+ ],
+ "resources": {
+ "requests": {
+ "storage": "${VOLUME_CAPACITY}"
+ }
+ }
+ }
+ },
+ {
+ "kind": "DeploymentConfig",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "${JENKINS_SERVICE_NAME}",
+ "creationTimestamp": null
+ },
+ "spec": {
+ "strategy": {
+ "type": "Recreate",
+ "resources": {}
+ },
+ "triggers": [
+ {
+ "type": "ConfigChange"
+ }
+ ],
+ "replicas": 1,
+ "selector": {
+ "name": "${JENKINS_SERVICE_NAME}"
+ },
+ "template": {
+ "metadata": {
+ "creationTimestamp": null,
+ "labels": {
+ "name": "${JENKINS_SERVICE_NAME}"
+ }
+ },
+ "spec": {
+ "containers": [
+ {
+ "name": "jenkins",
+ "image": "${JENKINS_IMAGE}",
+ "env": [
+ {
+ "name": "JENKINS_PASSWORD",
+ "value": "${JENKINS_PASSWORD}"
+ }
+ ],
+ "resources": {},
+ "volumeMounts": [
+ {
+ "name": "${JENKINS_SERVICE_NAME}-data",
+ "mountPath": "/var/lib/jenkins"
+ }
+ ],
+ "terminationMessagePath": "/dev/termination-log",
+ "imagePullPolicy": "IfNotPresent",
+ "capabilities": {},
+ "securityContext": {
+ "capabilities": {},
+ "privileged": false
+ }
+ }
+ ],
+ "volumes": [
+ {
+ "name": "${JENKINS_SERVICE_NAME}-data",
+ "persistentVolumeClaim": {
+ "claimName": "${JENKINS_SERVICE_NAME}"
+ }
+ }
+ ],
+ "restartPolicy": "Always",
+ "dnsPolicy": "ClusterFirst"
+ }
+ }
+ }
+ }
+ ],
+ "parameters": [
+ {
+ "name": "JENKINS_SERVICE_NAME",
+ "description": "Jenkins service name",
+ "value": "jenkins"
+ },
+ {
+ "name": "JENKINS_PASSWORD",
+ "description": "Password for the Jenkins user",
+ "generate": "expression",
+ "value": "password"
+ },
+ {
+ "name": "JENKINS_IMAGE",
+ "description": "Jenkins Docker image to use",
+ "value": "openshift/jenkins-1-centos7"
+ },
+ {
+ "name": "VOLUME_CAPACITY",
+ "description": "Volume space available for data, e.g. 512Mi, 2Gi",
+ "value": "512Mi",
+ "required": true
+ }
+ ],
+ "labels": {
+ "template": "jenkins-persistent-template"
+ }
+}
diff --git a/roles/openshift_examples/files/examples/quickstart-templates/nodejs-mongodb.json b/roles/openshift_examples/files/examples/quickstart-templates/nodejs-mongodb.json
new file mode 100644
index 000000000..8760b074c
--- /dev/null
+++ b/roles/openshift_examples/files/examples/quickstart-templates/nodejs-mongodb.json
@@ -0,0 +1,346 @@
+{
+ "kind": "Template",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "nodejs-mongodb-example",
+ "annotations": {
+ "description": "An example Node.js application with a MongoDB database",
+ "tags": "instant-app,nodejs,mongodb",
+ "iconClass": "icon-nodejs"
+ }
+ },
+ "labels": {
+ "template": "nodejs-mongodb-example"
+ },
+ "objects": [
+ {
+ "kind": "Service",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "nodejs-mongodb-example",
+ "annotations": {
+ "description": "Exposes and load balances the application pods"
+ }
+ },
+ "spec": {
+ "ports": [
+ {
+ "name": "web",
+ "port": 8080,
+ "targetPort": 8080
+ }
+ ],
+ "selector": {
+ "name": "nodejs-mongodb-example"
+ }
+ }
+ },
+ {
+ "kind": "Route",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "nodejs-mongodb-example"
+ },
+ "spec": {
+ "host": "${APPLICATION_DOMAIN}",
+ "to": {
+ "kind": "Service",
+ "name": "nodejs-mongodb-example"
+ }
+ }
+ },
+ {
+ "kind": "ImageStream",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "nodejs-mongodb-example",
+ "annotations": {
+ "description": "Keeps track of changes in the application image"
+ }
+ }
+ },
+ {
+ "kind": "BuildConfig",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "nodejs-mongodb-example",
+ "annotations": {
+ "description": "Defines how to build the application"
+ }
+ },
+ "spec": {
+ "source": {
+ "type": "Git",
+ "git": {
+ "uri": "${SOURCE_REPOSITORY_URL}",
+ "ref": "${SOURCE_REPOSITORY_REF}"
+ },
+ "contextDir": "${CONTEXT_DIR}"
+ },
+ "strategy": {
+ "type": "Source",
+ "sourceStrategy": {
+ "from": {
+ "kind": "ImageStreamTag",
+ "namespace": "openshift",
+ "name": "nodejs:0.10"
+ }
+ }
+ },
+ "output": {
+ "to": {
+ "kind": "ImageStreamTag",
+ "name": "nodejs-mongodb-example:latest"
+ }
+ },
+ "triggers": [
+ {
+ "type": "ImageChange"
+ },
+ {
+ "type": "GitHub",
+ "github": {
+ "secret": "${GITHUB_WEBHOOK_SECRET}"
+ }
+ },
+ {
+ "type": "Generic",
+ "generic": {
+ "secret": "${GENERIC_WEBHOOK_SECRET}"
+ }
+ }
+ ]
+ }
+ },
+ {
+ "kind": "DeploymentConfig",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "nodejs-mongodb-example",
+ "annotations": {
+ "description": "Defines how to deploy the application server"
+ }
+ },
+ "spec": {
+ "strategy": {
+ "type": "Rolling"
+ },
+ "triggers": [
+ {
+ "type": "ImageChange",
+ "imageChangeParams": {
+ "automatic": true,
+ "containerNames": [
+ "nodejs-mongodb-example"
+ ],
+ "from": {
+ "kind": "ImageStreamTag",
+ "name": "nodejs-mongodb-example:latest"
+ }
+ }
+ },
+ {
+ "type": "ConfigChange"
+ }
+ ],
+ "replicas": 1,
+ "selector": {
+ "name": "nodejs-mongodb-example"
+ },
+ "template": {
+ "metadata": {
+ "name": "nodejs-mongodb-example",
+ "labels": {
+ "name": "nodejs-mongodb-example"
+ }
+ },
+ "spec": {
+ "containers": [
+ {
+ "name": "nodejs-mongodb-example",
+ "image": "nodejs-mongodb-example",
+ "ports": [
+ {
+ "containerPort": 8080
+ }
+ ],
+ "env": [
+ {
+ "name": "DATABASE_SERVICE_NAME",
+ "value": "${DATABASE_SERVICE_NAME}"
+ },
+ {
+ "name": "MONGODB_USER",
+ "value": "${DATABASE_USER}"
+ },
+ {
+ "name": "MONGODB_PASSWORD",
+ "value": "${DATABASE_PASSWORD}"
+ },
+ {
+ "name": "MONGODB_DATABASE",
+ "value": "${DATABASE_NAME}"
+ },
+ {
+ "name": "MONGODB_ADMIN_PASSWORD",
+ "value": "${DATABASE_ADMIN_PASSWORD}"
+ }
+ ]
+ }
+ ]
+ }
+ }
+ }
+ },
+ {
+ "kind": "Service",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "${DATABASE_SERVICE_NAME}",
+ "annotations": {
+ "description": "Exposes the database server"
+ }
+ },
+ "spec": {
+ "ports": [
+ {
+ "name": "mongodb",
+ "port": 27017,
+ "targetPort": 27017
+ }
+ ],
+ "selector": {
+ "name": "${DATABASE_SERVICE_NAME}"
+ }
+ }
+ },
+ {
+ "kind": "DeploymentConfig",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "${DATABASE_SERVICE_NAME}",
+ "annotations": {
+ "description": "Defines how to deploy the database"
+ }
+ },
+ "spec": {
+ "strategy": {
+ "type": "Recreate"
+ },
+ "triggers": [
+ {
+ "type": "ConfigChange"
+ }
+ ],
+ "replicas": 1,
+ "selector": {
+ "name": "${DATABASE_SERVICE_NAME}"
+ },
+ "template": {
+ "metadata": {
+ "name": "${DATABASE_SERVICE_NAME}",
+ "labels": {
+ "name": "${DATABASE_SERVICE_NAME}"
+ }
+ },
+ "spec": {
+ "containers": [
+ {
+ "name": "mongodb",
+ "image": "${MONGODB_IMAGE}",
+ "ports": [
+ {
+ "containerPort": 27017
+ }
+ ],
+ "env": [
+ {
+ "name": "MONGODB_USER",
+ "value": "${DATABASE_USER}"
+ },
+ {
+ "name": "MONGODB_PASSWORD",
+ "value": "${DATABASE_PASSWORD}"
+ },
+ {
+ "name": "MONGODB_DATABASE",
+ "value": "${DATABASE_NAME}"
+ },
+ {
+ "name": "MONGODB_ADMIN_PASSWORD",
+ "value": "${DATABASE_ADMIN_PASSWORD}"
+ }
+ ]
+ }
+ ]
+ }
+ }
+ }
+ }
+ ],
+ "parameters": [
+ {
+ "name": "SOURCE_REPOSITORY_URL",
+ "description": "The URL of the repository with your application source code",
+ "value": "https://github.com/openshift/nodejs-ex.git"
+ },
+ {
+ "name": "SOURCE_REPOSITORY_REF",
+ "description": "Set this to a branch name, tag or other ref of your repository if you are not using the default branch"
+ },
+ {
+ "name": "CONTEXT_DIR",
+ "description": "Set this to the relative path to your project if it is not in the root of your repository"
+ },
+ {
+ "name": "APPLICATION_DOMAIN",
+ "description": "The exposed hostname that will route to the Node.js service, if left blank a value will be defaulted.",
+ "value": ""
+ },
+ {
+ "name": "GITHUB_WEBHOOK_SECRET",
+ "description": "A secret string used to configure the GitHub webhook",
+ "generate": "expression",
+ "from": "[a-zA-Z0-9]{40}"
+ },
+ {
+ "name": "GENERIC_WEBHOOK_SECRET",
+ "description": "A secret string used to configure the Generic webhook",
+ "generate": "expression",
+ "from": "[a-zA-Z0-9]{40}"
+ },
+ {
+ "name": "DATABASE_SERVICE_NAME",
+ "description": "Database service name",
+ "value": "mongodb"
+ },
+ {
+ "name": "DATABASE_USER",
+ "description": "Username for MongoDB user that will be used for accessing the database",
+ "generate": "expression",
+ "from": "user[A-Z0-9]{3}"
+ },
+ {
+ "name": "DATABASE_PASSWORD",
+ "description": "Password for the MongoDB user",
+ "generate": "expression",
+ "from": "[a-zA-Z0-9]{16}"
+ },
+ {
+ "name": "DATABASE_NAME",
+ "description": "Database name",
+ "value": "sampledb"
+ },
+ {
+ "name": "DATABASE_ADMIN_PASSWORD",
+ "description": "Password for the database admin user",
+ "generate": "expression",
+ "from": "[a-zA-Z0-9]{16}"
+ },
+ {
+ "name": "MONGODB_IMAGE",
+ "description": "Image to use for mongodb",
+ "value": "openshift/mongodb-24-centos7"
+ }
+ ]
+}
diff --git a/roles/openshift_examples/files/examples/quickstart-templates/nodejs.json b/roles/openshift_examples/files/examples/quickstart-templates/nodejs.json
new file mode 100644
index 000000000..e047266e3
--- /dev/null
+++ b/roles/openshift_examples/files/examples/quickstart-templates/nodejs.json
@@ -0,0 +1,248 @@
+{
+ "kind": "Template",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "nodejs-example",
+ "annotations": {
+ "description": "An example Node.js application with no database",
+ "tags": "instant-app,nodejs",
+ "iconClass": "icon-nodejs"
+ }
+ },
+ "labels": {
+ "template": "nodejs-example"
+ },
+ "objects": [
+ {
+ "kind": "Service",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "nodejs-example",
+ "annotations": {
+ "description": "Exposes and load balances the application pods"
+ }
+ },
+ "spec": {
+ "ports": [
+ {
+ "name": "web",
+ "port": 8080,
+ "targetPort": 8080
+ }
+ ],
+ "selector": {
+ "name": "nodejs-example"
+ }
+ }
+ },
+ {
+ "kind": "Route",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "nodejs-example"
+ },
+ "spec": {
+ "host": "${APPLICATION_DOMAIN}",
+ "to": {
+ "kind": "Service",
+ "name": "nodejs-example"
+ }
+ }
+ },
+ {
+ "kind": "ImageStream",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "nodejs-example",
+ "annotations": {
+ "description": "Keeps track of changes in the application image"
+ }
+ }
+ },
+ {
+ "kind": "BuildConfig",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "nodejs-example",
+ "annotations": {
+ "description": "Defines how to build the application"
+ }
+ },
+ "spec": {
+ "source": {
+ "type": "Git",
+ "git": {
+ "uri": "${SOURCE_REPOSITORY_URL}",
+ "ref": "${SOURCE_REPOSITORY_REF}"
+ },
+ "contextDir": "${CONTEXT_DIR}"
+ },
+ "strategy": {
+ "type": "Source",
+ "sourceStrategy": {
+ "from": {
+ "kind": "ImageStreamTag",
+ "namespace": "openshift",
+ "name": "nodejs:0.10"
+ }
+ }
+ },
+ "output": {
+ "to": {
+ "kind": "ImageStreamTag",
+ "name": "nodejs-example:latest"
+ }
+ },
+ "triggers": [
+ {
+ "type": "ImageChange"
+ },
+ {
+ "type": "GitHub",
+ "github": {
+ "secret": "${GITHUB_WEBHOOK_SECRET}"
+ }
+ },
+ {
+ "type": "Generic",
+ "generic": {
+ "secret": "${GENERIC_WEBHOOK_SECRET}"
+ }
+ }
+ ]
+ }
+ },
+ {
+ "kind": "DeploymentConfig",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "nodejs-example",
+ "annotations": {
+ "description": "Defines how to deploy the application server"
+ }
+ },
+ "spec": {
+ "strategy": {
+ "type": "Rolling"
+ },
+ "triggers": [
+ {
+ "type": "ImageChange",
+ "imageChangeParams": {
+ "automatic": true,
+ "containerNames": [
+ "nodejs-example"
+ ],
+ "from": {
+ "kind": "ImageStreamTag",
+ "name": "nodejs-example:latest"
+ }
+ }
+ },
+ {
+ "type": "ConfigChange"
+ }
+ ],
+ "replicas": 1,
+ "selector": {
+ "name": "nodejs-example"
+ },
+ "template": {
+ "metadata": {
+ "name": "nodejs-example",
+ "labels": {
+ "name": "nodejs-example"
+ }
+ },
+ "spec": {
+ "containers": [
+ {
+ "name": "nodejs-example",
+ "image": "nodejs-example",
+ "ports": [
+ {
+ "containerPort": 8080
+ }
+ ],
+ "env": [
+ {
+ "name": "DATABASE_SERVICE_NAME",
+ "value": "${DATABASE_SERVICE_NAME}"
+ },
+ {
+ "name": "MONGODB_USER",
+ "value": "${MONGODB_USER}"
+ },
+ {
+ "name": "MONGODB_PASSWORD",
+ "value": "${MONGODB_PASSWORD}"
+ },
+ {
+ "name": "MONGODB_DATABASE",
+ "value": "${MONGODB_DATABASE}"
+ },
+ {
+ "name": "MONGODB_ADMIN_PASSWORD",
+ "value": "${MONGODB_ADMIN_PASSWORD}"
+ }
+ ]
+ }
+ ]
+ }
+ }
+ }
+ }
+ ],
+ "parameters": [
+ {
+ "name": "SOURCE_REPOSITORY_URL",
+ "description": "The URL of the repository with your application source code",
+ "value": "https://github.com/openshift/nodejs-ex.git"
+ },
+ {
+ "name": "SOURCE_REPOSITORY_REF",
+ "description": "Set this to a branch name, tag or other ref of your repository if you are not using the default branch"
+ },
+ {
+ "name": "CONTEXT_DIR",
+ "description": "Set this to the relative path to your project if it is not in the root of your repository"
+ },
+ {
+ "name": "APPLICATION_DOMAIN",
+ "description": "The exposed hostname that will route to the Node.js service, if left blank a value will be defaulted.",
+ "value": ""
+ },
+ {
+ "name": "GITHUB_WEBHOOK_SECRET",
+ "description": "A secret string used to configure the GitHub webhook",
+ "generate": "expression",
+ "from": "[a-zA-Z0-9]{40}"
+ },
+ {
+ "name": "GENERIC_WEBHOOK_SECRET",
+ "description": "A secret string used to configure the Generic webhook",
+ "generate": "expression",
+ "from": "[a-zA-Z0-9]{40}"
+ },
+ {
+ "name": "DATABASE_SERVICE_NAME",
+ "description": "Database service name"
+ },
+ {
+ "name": "MONGODB_USER",
+ "description": "Username for MongoDB user that will be used for accessing the database"
+ },
+ {
+ "name": "MONGODB_PASSWORD",
+ "description": "Password for the MongoDB user"
+ },
+ {
+ "name": "MONGODB_DATABASE",
+ "description": "Database name"
+ },
+ {
+ "name": "MONGODB_ADMIN_PASSWORD",
+ "description": "Password for the database admin user"
+ }
+ ]
+}
diff --git a/roles/openshift_examples/files/examples/quickstart-templates/rails-postgresql.json b/roles/openshift_examples/files/examples/quickstart-templates/rails-postgresql.json
new file mode 100644
index 000000000..b98282528
--- /dev/null
+++ b/roles/openshift_examples/files/examples/quickstart-templates/rails-postgresql.json
@@ -0,0 +1,402 @@
+{
+ "kind": "Template",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "rails-postgresql-example",
+ "annotations": {
+ "description": "An example Rails application with a PostgreSQL database",
+ "tags": "instant-app,ruby,rails,postgresql",
+ "iconClass": "icon-ruby"
+ }
+ },
+ "labels": {
+ "template": "rails-postgresql-example"
+ },
+ "objects": [
+ {
+ "kind": "Service",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "rails-postgresql-example",
+ "annotations": {
+ "description": "Exposes and load balances the application pods"
+ }
+ },
+ "spec": {
+ "ports": [
+ {
+ "name": "web",
+ "port": 8080,
+ "targetPort": 8080
+ }
+ ],
+ "selector": {
+ "name": "rails-postgresql-example"
+ }
+ }
+ },
+ {
+ "kind": "Route",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "rails-postgresql-example"
+ },
+ "spec": {
+ "host": "${APPLICATION_DOMAIN}",
+ "to": {
+ "kind": "Service",
+ "name": "rails-postgresql-example"
+ }
+ }
+ },
+ {
+ "kind": "ImageStream",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "rails-postgresql-example",
+ "annotations": {
+ "description": "Keeps track of changes in the application image"
+ }
+ }
+ },
+ {
+ "kind": "BuildConfig",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "rails-postgresql-example",
+ "annotations": {
+ "description": "Defines how to build the application"
+ }
+ },
+ "spec": {
+ "source": {
+ "type": "Git",
+ "git": {
+ "uri": "${SOURCE_REPOSITORY_URL}",
+ "ref": "${SOURCE_REPOSITORY_REF}"
+ },
+ "contextDir": "${CONTEXT_DIR}"
+ },
+ "strategy": {
+ "type": "Source",
+ "sourceStrategy": {
+ "from": {
+ "kind": "ImageStreamTag",
+ "namespace": "openshift",
+ "name": "ruby:2.0"
+ }
+ }
+ },
+ "output": {
+ "to": {
+ "kind": "ImageStreamTag",
+ "name": "rails-postgresql-example:latest"
+ }
+ },
+ "triggers": [
+ {
+ "type": "ImageChange"
+ },
+ {
+ "type": "GitHub",
+ "github": {
+ "secret": "${GITHUB_WEBHOOK_SECRET}"
+ }
+ }
+ ]
+ }
+ },
+ {
+ "kind": "DeploymentConfig",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "rails-postgresql-example",
+ "annotations": {
+ "description": "Defines how to deploy the application server"
+ }
+ },
+ "spec": {
+ "strategy": {
+ "type": "Recreate",
+ "recreateParams": {
+ "pre": {
+ "failurePolicy": "Abort",
+ "execNewPod": {
+ "command": [
+ "./migrate-database.sh"
+ ],
+ "containerName": "rails-postgresql-example"
+ }
+ }
+ }
+ },
+ "triggers": [
+ {
+ "type": "ImageChange",
+ "imageChangeParams": {
+ "automatic": true,
+ "containerNames": [
+ "rails-postgresql-example"
+ ],
+ "from": {
+ "kind": "ImageStreamTag",
+ "name": "rails-postgresql-example:latest"
+ }
+ }
+ },
+ {
+ "type": "ConfigChange"
+ }
+ ],
+ "replicas": 1,
+ "selector": {
+ "name": "rails-postgresql-example"
+ },
+ "template": {
+ "metadata": {
+ "name": "rails-postgresql-example",
+ "labels": {
+ "name": "rails-postgresql-example"
+ }
+ },
+ "spec": {
+ "containers": [
+ {
+ "name": "rails-postgresql-example",
+ "image": "rails-postgresql-example",
+ "ports": [
+ {
+ "containerPort": 8080
+ }
+ ],
+ "env": [
+ {
+ "name": "DATABASE_SERVICE_NAME",
+ "value": "${DATABASE_SERVICE_NAME}"
+ },
+ {
+ "name": "POSTGRESQL_USER",
+ "value": "${DATABASE_USER}"
+ },
+ {
+ "name": "POSTGRESQL_PASSWORD",
+ "value": "${DATABASE_PASSWORD}"
+ },
+ {
+ "name": "POSTGRESQL_DATABASE",
+ "value": "${DATABASE_NAME}"
+ },
+ {
+ "name": "SECRET_KEY_BASE",
+ "value": "${SECRET_KEY_BASE}"
+ },
+ {
+ "name": "POSTGRESQL_MAX_CONNECTIONS",
+ "value": "${POSTGRESQL_MAX_CONNECTIONS}"
+ },
+ {
+ "name": "POSTGRESQL_SHARED_BUFFERS",
+ "value": "${POSTGRESQL_SHARED_BUFFERS}"
+ },
+ {
+ "name": "SECRET_KEY_BASE",
+ "value": "${SECRET_KEY_BASE}"
+ },
+ {
+ "name": "APPLICATION_DOMAIN",
+ "value": "${APPLICATION_DOMAIN}"
+ },
+ {
+ "name": "APPLICATION_USER",
+ "value": "${APPLICATION_USER}"
+ },
+ {
+ "name": "APPLICATION_PASSWORD",
+ "value": "${APPLICATION_PASSWORD}"
+ },
+ {
+ "name": "RAILS_ENV",
+ "value": "${RAILS_ENV}"
+ }
+ ]
+ }
+ ]
+ }
+ }
+ }
+ },
+ {
+ "kind": "Service",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "${DATABASE_SERVICE_NAME}",
+ "annotations": {
+ "description": "Exposes the database server"
+ }
+ },
+ "spec": {
+ "ports": [
+ {
+ "name": "postgresql",
+ "port": 5432,
+ "targetPort": 5432
+ }
+ ],
+ "selector": {
+ "name": "${DATABASE_SERVICE_NAME}"
+ }
+ }
+ },
+ {
+ "kind": "DeploymentConfig",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "${DATABASE_SERVICE_NAME}",
+ "annotations": {
+ "description": "Defines how to deploy the database"
+ }
+ },
+ "spec": {
+ "strategy": {
+ "type": "Recreate"
+ },
+ "triggers": [
+ {
+ "type": "ConfigChange"
+ }
+ ],
+ "replicas": 1,
+ "selector": {
+ "name": "${DATABASE_SERVICE_NAME}"
+ },
+ "template": {
+ "metadata": {
+ "name": "${DATABASE_SERVICE_NAME}",
+ "labels": {
+ "name": "${DATABASE_SERVICE_NAME}"
+ }
+ },
+ "spec": {
+ "containers": [
+ {
+ "name": "postgresql",
+ "image": "${POSTGRESQL_IMAGE}",
+ "ports": [
+ {
+ "containerPort": 5432
+ }
+ ],
+ "env": [
+ {
+ "name": "POSTGRESQL_USER",
+ "value": "${DATABASE_USER}"
+ },
+ {
+ "name": "POSTGRESQL_PASSWORD",
+ "value": "${DATABASE_PASSWORD}"
+ },
+ {
+ "name": "POSTGRESQL_DATABASE",
+ "value": "${DATABASE_NAME}"
+ },
+ {
+ "name": "POSTGRESQL_MAX_CONNECTIONS",
+ "value": "${POSTGRESQL_MAX_CONNECTIONS}"
+ },
+ {
+ "name": "POSTGRESQL_SHARED_BUFFERS",
+ "value": "${POSTGRESQL_SHARED_BUFFERS}"
+ }
+ ]
+ }
+ ]
+ }
+ }
+ }
+ }
+ ],
+ "parameters": [
+ {
+ "name": "SOURCE_REPOSITORY_URL",
+ "description": "The URL of the repository with your application source code",
+ "value": "https://github.com/openshift/rails-ex.git"
+ },
+ {
+ "name": "SOURCE_REPOSITORY_REF",
+ "description": "Set this to a branch name, tag or other ref of your repository if you are not using the default branch"
+ },
+ {
+ "name": "CONTEXT_DIR",
+ "description": "Set this to the relative path to your project if it is not in the root of your repository"
+ },
+ {
+ "name": "APPLICATION_DOMAIN",
+ "description": "The exposed hostname that will route to the Rails service, if left blank a value will be defaulted.",
+ "value": ""
+ },
+ {
+ "name": "GITHUB_WEBHOOK_SECRET",
+ "description": "A secret string used to configure the GitHub webhook",
+ "generate": "expression",
+ "from": "[a-zA-Z0-9]{40}"
+ },
+ {
+ "name": "SECRET_KEY_BASE",
+ "description": "Your secret key for verifying the integrity of signed cookies",
+ "generate": "expression",
+ "from": "[a-z0-9]{127}"
+ },
+ {
+ "name": "APPLICATION_USER",
+ "description": "The application user that is used within the sample application to authorize access on pages",
+ "value": "openshift"
+ },
+ {
+ "name": "APPLICATION_PASSWORD",
+ "description": "The application password that is used within the sample application to authorize access on pages",
+ "value": "secret"
+ },
+ {
+ "name": "RAILS_ENV",
+ "description": "Environment under which the sample application will run. Could be set to production, development or test",
+ "value": "production"
+ },
+ {
+ "name": "DATABASE_SERVICE_NAME",
+ "description": "Database service name",
+ "value": "postgresql"
+ },
+ {
+ "name": "DATABASE_USER",
+ "description": "database username",
+ "generate": "expression",
+ "from": "user[A-Z0-9]{3}"
+ },
+ {
+ "name": "DATABASE_PASSWORD",
+ "description": "database password",
+ "generate": "expression",
+ "from": "[a-zA-Z0-9]{8}"
+ },
+ {
+ "name": "DATABASE_NAME",
+ "description": "database name",
+ "value": "root"
+ },
+ {
+ "name": "POSTGRESQL_IMAGE",
+ "description": "Image to use for postgresql",
+ "value": "openshift/postgresql-92-centos7"
+ },
+ {
+ "name": "POSTGRESQL_MAX_CONNECTIONS",
+ "description": "database max connections",
+ "value": "10"
+ },
+ {
+ "name": "POSTGRESQL_SHARED_BUFFERS",
+ "description": "database shared buffers",
+ "value": "12MB"
+ }
+ ]
+}
diff --git a/roles/openshift_examples/files/examples/xpaas-streams/jboss-image-streams.json b/roles/openshift_examples/files/examples/xpaas-streams/jboss-image-streams.json
new file mode 100644
index 000000000..37e6269fe
--- /dev/null
+++ b/roles/openshift_examples/files/examples/xpaas-streams/jboss-image-streams.json
@@ -0,0 +1,100 @@
+{
+ "kind": "List",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "jboss-image-streams",
+ "annotations": {
+ "description": "ImageStream definitions for JBoss Middleware products."
+ }
+ },
+ "items": [
+ {
+ "kind": "ImageStream",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "jboss-webserver3-tomcat7-openshift"
+ },
+ "spec": {
+ "dockerImageRepository": "registry.access.redhat.com/jboss-webserver-3/tomcat7-openshift",
+ "tags": [
+ {
+ "name": "3.0",
+ "annotations": {
+ "description": "JBoss Web Server v3 Tomcat 7 STI images.",
+ "iconClass": "icon-jboss",
+ "tags": "java",
+ "supports":"tomcat7:3.0,java",
+ "version": "3.0"
+ }
+ }
+ ]
+ }
+ },
+ {
+ "kind": "ImageStream",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "jboss-webserver3-tomcat8-openshift"
+ },
+ "spec": {
+ "dockerImageRepository": "registry.access.redhat.com/jboss-webserver-3/tomcat8-openshift",
+ "tags": [
+ {
+ "name": "3.0",
+ "annotations": {
+ "description": "JBoss Web Server v3 Tomcat 8 STI images.",
+ "iconClass": "icon-jboss",
+ "tags": "java",
+ "supports":"tomcat8:3.0,java",
+ "version": "3.0"
+ }
+ }
+ ]
+ }
+ },
+ {
+ "kind": "ImageStream",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "jboss-eap6-openshift"
+ },
+ "spec": {
+ "dockerImageRepository": "registry.access.redhat.com/jboss-eap-6/eap-openshift",
+ "tags": [
+ {
+ "name": "6.4",
+ "annotations": {
+ "description": "JBoss EAP 6 STI images.",
+ "iconClass": "icon-jboss",
+ "tags": "javaee",
+ "supports":"eap:6.4,jee,java",
+ "version": "6.4"
+ }
+ }
+ ]
+ }
+ },
+ {
+ "kind": "ImageStream",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "jboss-amq-6"
+ },
+ "spec": {
+ "dockerImageRepository": "registry.access.redhat.com/jboss-amq-6/amq-openshift",
+ "tags": [
+ {
+ "name": "6.2",
+ "annotations": {
+ "description": "JBoss ActiveMQ 6 broker image.",
+ "iconClass": "icon-jboss",
+ "tags": "javaee",
+ "supports":"amq:6.2,jee,java",
+ "version": "6.2"
+ }
+ }
+ ]
+ }
+ }
+ ]
+}
diff --git a/roles/openshift_examples/files/examples/xpaas-templates/amq6-persistent.json b/roles/openshift_examples/files/examples/xpaas-templates/amq6-persistent.json
new file mode 100644
index 000000000..5cbc7ee7e
--- /dev/null
+++ b/roles/openshift_examples/files/examples/xpaas-templates/amq6-persistent.json
@@ -0,0 +1,439 @@
+{
+ "kind": "Template",
+ "apiVersion": "v1",
+ "metadata": {
+ "annotations": {
+ "description": "Application template for ActiveMQ brokers using persistent storage."
+ },
+ "name": "amq6-persistent"
+ },
+ "labels": {
+ "template": "amq6-persistent"
+ },
+ "parameters": [
+ {
+ "description": "ActiveMQ Release version, e.g. 6.2, etc.",
+ "name": "AMQ_RELEASE",
+ "value": "6.2"
+ },
+ {
+ "description": "The name for the application.",
+ "name": "APPLICATION_NAME",
+ "value": "broker"
+ },
+ {
+ "description": "Protocol to configure. Only openwire is supported by EAP. amqp, amqp+ssl, mqtt, stomp, stomp+ssl, and ssl are not supported by EAP",
+ "name": "MQ_PROTOCOL",
+ "value": "openwire"
+ },
+ {
+ "description": "Queue names",
+ "name": "MQ_QUEUES",
+ "value": ""
+ },
+ {
+ "description": "Topic names",
+ "name": "MQ_TOPICS",
+ "value": ""
+ },
+ {
+ "description": "Size of persistent storage for database volume.",
+ "name": "VOLUME_CAPACITY",
+ "value": "512Mi"
+ },
+ {
+ "description": "Broker user name",
+ "name": "MQ_USERNAME",
+ "from": "user[a-zA-Z0-9]{3}",
+ "generate": "expression"
+ },
+ {
+ "description": "Broker user password",
+ "name": "MQ_PASSWORD",
+ "from": "[a-zA-Z0-9]{8}",
+ "generate": "expression"
+ },
+ {
+ "description": "ActiveMQ Admin User",
+ "name": "AMQ_ADMIN_USERNAME",
+ "from": "user[a-zA-Z0-9]{3}",
+ "generate": "expression"
+ },
+ {
+ "description": "ActiveMQ Admin Password",
+ "name": "AMQ_ADMIN_PASSWORD",
+ "from": "[a-zA-Z0-9]{8}",
+ "generate": "expression"
+ },
+ {
+ "description": "Name of a secret containing SSL related files",
+ "name": "AMQ_SECRET",
+ "value": "amq-app-secret"
+ },
+ {
+ "description": "SSL trust store filename",
+ "name": "AMQ_TRUSTSTORE",
+ "value": "broker.ts"
+ },
+ {
+ "description": "SSL key store filename",
+ "name": "AMQ_KEYSTORE",
+ "value": "broker.ks"
+ }
+ ],
+ "objects": [
+ {
+ "kind": "Service",
+ "apiVersion": "v1",
+ "spec": {
+ "ports": [
+ {
+ "port": 5672,
+ "targetPort": 5672
+ }
+ ],
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}-amq"
+ }
+ },
+ "metadata": {
+ "name": "${APPLICATION_NAME}-amq-amqp",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "The broker's amqp port."
+ }
+ }
+ },
+ {
+ "kind": "Service",
+ "apiVersion": "v1",
+ "spec": {
+ "ports": [
+ {
+ "port": 5671,
+ "targetPort": 5671
+ }
+ ],
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}-amq"
+ }
+ },
+ "metadata": {
+ "name": "${APPLICATION_NAME}-amq-amqp-ssl",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "The broker's amqp ssl port."
+ }
+ }
+ },
+ {
+ "kind": "Service",
+ "apiVersion": "v1",
+ "spec": {
+ "ports": [
+ {
+ "port": 1883,
+ "targetPort": 1883
+ }
+ ],
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}-amq"
+ }
+ },
+ "metadata": {
+ "name": "${APPLICATION_NAME}-amq-mqtt",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "The broker's mqtt port."
+ }
+ }
+ },
+ {
+ "kind": "Service",
+ "apiVersion": "v1",
+ "spec": {
+ "ports": [
+ {
+ "port": 61613,
+ "targetPort": 61613
+ }
+ ],
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}-amq"
+ }
+ },
+ "metadata": {
+ "name": "${APPLICATION_NAME}-amq-stomp",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "The broker's stomp port."
+ }
+ }
+ },
+ {
+ "kind": "Service",
+ "apiVersion": "v1",
+ "spec": {
+ "ports": [
+ {
+ "port": 61612,
+ "targetPort": 61612
+ }
+ ],
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}-amq"
+ }
+ },
+ "metadata": {
+ "name": "${APPLICATION_NAME}-amq-stomp-ssl",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "The broker's stomp ssl port."
+ }
+ }
+ },
+ {
+ "kind": "Service",
+ "apiVersion": "v1",
+ "spec": {
+ "ports": [
+ {
+ "port": 61616,
+ "targetPort": 61616
+ }
+ ],
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}-amq"
+ }
+ },
+ "metadata": {
+ "name": "${APPLICATION_NAME}-amq-tcp",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "The broker's tcp (openwire) port."
+ }
+ }
+ },
+ {
+ "kind": "Service",
+ "apiVersion": "v1",
+ "spec": {
+ "ports": [
+ {
+ "port": 61617,
+ "targetPort": 61617
+ }
+ ],
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}-amq"
+ }
+ },
+ "metadata": {
+ "name": "${APPLICATION_NAME}-amq-tcp-ssl",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "The broker's tcp ssl (openwire) port."
+ }
+ }
+ },
+ {
+ "kind": "DeploymentConfig",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "${APPLICATION_NAME}-amq",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "strategy": {
+ "type": "Recreate"
+ },
+ "triggers": [
+ {
+ "type": "ImageChange",
+ "imageChangeParams": {
+ "automatic": true,
+ "containerNames": [
+ "${APPLICATION_NAME}-amq"
+ ],
+ "from": {
+ "kind": "ImageStreamTag",
+ "namespace": "openshift",
+ "name": "jboss-amq-6:${AMQ_RELEASE}"
+ }
+ }
+ }
+ ],
+ "replicas": 1,
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}-amq"
+ },
+ "template": {
+ "metadata": {
+ "name": "${APPLICATION_NAME}-amq",
+ "labels": {
+ "deploymentConfig": "${APPLICATION_NAME}-amq",
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "serviceAccount": "amq-service-account",
+ "containers": [
+ {
+ "name": "${APPLICATION_NAME}-amq",
+ "image": "jboss-amq-6",
+ "imagePullPolicy": "Always",
+ "volumeMounts": [
+ {
+ "name": "broker-secret-volume",
+ "mountPath": "/etc/amq-secret-volume",
+ "readOnly": true
+ },
+ {
+ "mountPath": "/opt/amq/data/kahadb",
+ "name": "${APPLICATION_NAME}-amq-pvol"
+ }
+ ],
+ "readinessProbe": {
+ "exec": {
+ "command": [
+ "/bin/bash",
+ "-c",
+ "curl -s -L -u ${AMQ_ADMIN_USERNAME}:${AMQ_ADMIN_PASSWORD} 'http://localhost:8161/hawtio/jolokia/read/org.apache.activemq:type=Broker,brokerName=*,service=Health/CurrentStatus' | grep -q '\"CurrentStatus\" *: *\"Good\"'"
+ ]
+ }
+ },
+ "ports": [
+ {
+ "name": "amqp",
+ "containerPort": 5672,
+ "protocol": "TCP"
+ },
+ {
+ "name": "amqp-ssl",
+ "containerPort": 5671,
+ "protocol": "TCP"
+ },
+ {
+ "name": "mqtt",
+ "containerPort": 1883,
+ "protocol": "TCP"
+ },
+ {
+ "name": "stomp",
+ "containerPort": 61613,
+ "protocol": "TCP"
+ },
+ {
+ "name": "stomp-ssl",
+ "containerPort": 61612,
+ "protocol": "TCP"
+ },
+ {
+ "name": "tcp",
+ "containerPort": 61616,
+ "protocol": "TCP"
+ },
+ {
+ "name": "tcp-ssl",
+ "containerPort": 61617,
+ "protocol": "TCP"
+ }
+ ],
+ "env": [
+ {
+ "name": "AMQ_USER",
+ "value": "${MQ_USERNAME}"
+ },
+ {
+ "name": "AMQ_PASSWORD",
+ "value": "${MQ_PASSWORD}"
+ },
+ {
+ "name": "AMQ_PROTOCOLS",
+ "value": "${MQ_PROTOCOL}"
+ },
+ {
+ "name": "AMQ_QUEUES",
+ "value": "${MQ_QUEUES}"
+ },
+ {
+ "name": "AMQ_TOPICS",
+ "value": "${MQ_TOPICS}"
+ },
+ {
+ "name": "AMQ_ADMIN_USERNAME",
+ "value": "${AMQ_ADMIN_USERNAME}"
+ },
+ {
+ "name": "AMQ_ADMIN_PASSWORD",
+ "value": "${AMQ_ADMIN_PASSWORD}"
+ },
+ {
+ "name": "AMQ_KEYSTORE_TRUSTSTORE_DIR",
+ "value": "/etc/amq-secret-volume"
+ },
+ {
+ "name": "AMQ_TRUSTSTORE",
+ "value": "${AMQ_TRUSTSTORE}"
+ },
+ {
+ "name": "AMQ_KEYSTORE",
+ "value": "${AMQ_KEYSTORE}"
+ }
+ ]
+ }
+ ],
+ "volumes": [
+ {
+ "name": "broker-secret-volume",
+ "secret": {
+ "secretName": "${AMQ_SECRET}"
+ }
+ },
+ {
+ "name": "${APPLICATION_NAME}-amq-pvol",
+ "persistentVolumeClaim": {
+ "claimName": "${APPLICATION_NAME}-amq-claim"
+ }
+ }
+ ]
+ }
+ }
+ }
+ },
+ {
+ "apiVersion": "v1",
+ "kind": "PersistentVolumeClaim",
+ "metadata": {
+ "name": "${APPLICATION_NAME}-amq-claim",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "accessModes": [ "ReadWriteOnce" ],
+ "resources": {
+ "requests": {
+ "storage": "${VOLUME_CAPACITY}"
+ }
+ }
+ }
+ }
+ ]
+}
diff --git a/roles/openshift_examples/files/examples/xpaas-templates/amq6.json b/roles/openshift_examples/files/examples/xpaas-templates/amq6.json
new file mode 100644
index 000000000..7decdfe52
--- /dev/null
+++ b/roles/openshift_examples/files/examples/xpaas-templates/amq6.json
@@ -0,0 +1,410 @@
+{
+ "kind": "Template",
+ "apiVersion": "v1",
+ "metadata": {
+ "annotations": {
+ "description": "Application template for ActiveMQ brokers."
+ },
+ "name": "amq6"
+ },
+ "labels": {
+ "template": "amq6"
+ },
+ "parameters": [
+ {
+ "description": "ActiveMQ Release version, e.g. 6.2, etc.",
+ "name": "AMQ_RELEASE",
+ "value": "6.2"
+ },
+ {
+ "description": "The name for the application.",
+ "name": "APPLICATION_NAME",
+ "value": "broker"
+ },
+ {
+ "description": "Protocol to configure. Only openwire is supported by EAP. amqp, amqp+ssl, mqtt, stomp, stomp+ssl, and ssl are not supported by EAP",
+ "name": "MQ_PROTOCOL",
+ "value": "openwire"
+ },
+ {
+ "description": "Queue names",
+ "name": "MQ_QUEUES",
+ "value": ""
+ },
+ {
+ "description": "Topic names",
+ "name": "MQ_TOPICS",
+ "value": ""
+ },
+ {
+ "description": "Broker user name",
+ "name": "MQ_USERNAME",
+ "from": "user[a-zA-Z0-9]{3}",
+ "generate": "expression"
+ },
+ {
+ "description": "Broker user password",
+ "name": "MQ_PASSWORD",
+ "from": "[a-zA-Z0-9]{8}",
+ "generate": "expression"
+ },
+ {
+ "description": "ActiveMQ Admin User",
+ "name": "AMQ_ADMIN_USERNAME",
+ "from": "user[a-zA-Z0-9]{3}",
+ "generate": "expression"
+ },
+ {
+ "description": "ActiveMQ Admin Password",
+ "name": "AMQ_ADMIN_PASSWORD",
+ "from": "[a-zA-Z0-9]{8}",
+ "generate": "expression"
+ },
+ {
+ "description": "Name of a secret containing SSL related files",
+ "name": "AMQ_SECRET",
+ "value": "amq-app-secret"
+ },
+ {
+ "description": "SSL trust store filename",
+ "name": "AMQ_TRUSTSTORE",
+ "value": "broker.ts"
+ },
+ {
+ "description": "SSL key store filename",
+ "name": "AMQ_KEYSTORE",
+ "value": "broker.ks"
+ }
+ ],
+ "objects": [
+ {
+ "kind": "Service",
+ "apiVersion": "v1",
+ "spec": {
+ "ports": [
+ {
+ "port": 5672,
+ "targetPort": 5672
+ }
+ ],
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}-amq"
+ }
+ },
+ "metadata": {
+ "name": "${APPLICATION_NAME}-amq-amqp",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "The broker's amqp port."
+ }
+ }
+ },
+ {
+ "kind": "Service",
+ "apiVersion": "v1",
+ "spec": {
+ "ports": [
+ {
+ "port": 5671,
+ "targetPort": 5671
+ }
+ ],
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}-amq"
+ }
+ },
+ "metadata": {
+ "name": "${APPLICATION_NAME}-amq-amqp-ssl",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "The broker's amqp ssl port."
+ }
+ }
+ },
+ {
+ "kind": "Service",
+ "apiVersion": "v1",
+ "spec": {
+ "ports": [
+ {
+ "port": 1883,
+ "targetPort": 1883
+ }
+ ],
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}-amq"
+ }
+ },
+ "metadata": {
+ "name": "${APPLICATION_NAME}-amq-mqtt",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "The broker's mqtt port."
+ }
+ }
+ },
+ {
+ "kind": "Service",
+ "apiVersion": "v1",
+ "spec": {
+ "ports": [
+ {
+ "port": 61613,
+ "targetPort": 61613
+ }
+ ],
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}-amq"
+ }
+ },
+ "metadata": {
+ "name": "${APPLICATION_NAME}-amq-stomp",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "The broker's stomp port."
+ }
+ }
+ },
+ {
+ "kind": "Service",
+ "apiVersion": "v1",
+ "spec": {
+ "ports": [
+ {
+ "port": 61612,
+ "targetPort": 61612
+ }
+ ],
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}-amq"
+ }
+ },
+ "metadata": {
+ "name": "${APPLICATION_NAME}-amq-stomp-ssl",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "The broker's stomp ssl port."
+ }
+ }
+ },
+ {
+ "kind": "Service",
+ "apiVersion": "v1",
+ "spec": {
+ "ports": [
+ {
+ "port": 61616,
+ "targetPort": 61616
+ }
+ ],
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}-amq"
+ }
+ },
+ "metadata": {
+ "name": "${APPLICATION_NAME}-amq-tcp",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "The broker's tcp (openwire) port."
+ }
+ }
+ },
+ {
+ "kind": "Service",
+ "apiVersion": "v1",
+ "spec": {
+ "ports": [
+ {
+ "port": 61617,
+ "targetPort": 61617
+ }
+ ],
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}-amq"
+ }
+ },
+ "metadata": {
+ "name": "${APPLICATION_NAME}-amq-tcp-ssl",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "The broker's tcp ssl (openwire) port."
+ }
+ }
+ },
+ {
+ "kind": "DeploymentConfig",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "${APPLICATION_NAME}-amq",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "strategy": {
+ "type": "Recreate"
+ },
+ "triggers": [
+ {
+ "type": "ImageChange",
+ "imageChangeParams": {
+ "automatic": true,
+ "containerNames": [
+ "${APPLICATION_NAME}-amq"
+ ],
+ "from": {
+ "kind": "ImageStreamTag",
+ "namespace": "openshift",
+ "name": "jboss-amq-6:${AMQ_RELEASE}"
+ }
+ }
+ }
+ ],
+ "replicas": 1,
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}-amq"
+ },
+ "template": {
+ "metadata": {
+ "name": "${APPLICATION_NAME}-amq",
+ "labels": {
+ "deploymentConfig": "${APPLICATION_NAME}-amq",
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "serviceAccount": "amq-service-account",
+ "containers": [
+ {
+ "name": "${APPLICATION_NAME}-amq",
+ "image": "jboss-amq-6",
+ "imagePullPolicy": "Always",
+ "volumeMounts": [
+ {
+ "name": "broker-secret-volume",
+ "mountPath": "/etc/amq-secret-volume",
+ "readOnly": true
+ }
+ ],
+ "readinessProbe": {
+ "exec": {
+ "command": [
+ "/bin/bash",
+ "-c",
+ "curl -s -L -u ${AMQ_ADMIN_USERNAME}:${AMQ_ADMIN_PASSWORD} 'http://localhost:8161/hawtio/jolokia/read/org.apache.activemq:type=Broker,brokerName=*,service=Health/CurrentStatus' | grep -q '\"CurrentStatus\" *: *\"Good\"'"
+ ]
+ }
+ },
+ "ports": [
+ {
+ "name": "amqp",
+ "containerPort": 5672,
+ "protocol": "TCP"
+ },
+ {
+ "name": "amqp-ssl",
+ "containerPort": 5671,
+ "protocol": "TCP"
+ },
+ {
+ "name": "mqtt",
+ "containerPort": 1883,
+ "protocol": "TCP"
+ },
+ {
+ "name": "stomp",
+ "containerPort": 61613,
+ "protocol": "TCP"
+ },
+ {
+ "name": "stomp-ssl",
+ "containerPort": 61612,
+ "protocol": "TCP"
+ },
+ {
+ "name": "tcp",
+ "containerPort": 61616,
+ "protocol": "TCP"
+ },
+ {
+ "name": "tcp-ssl",
+ "containerPort": 61617,
+ "protocol": "TCP"
+ }
+ ],
+ "env": [
+ {
+ "name": "AMQ_USER",
+ "value": "${MQ_USERNAME}"
+ },
+ {
+ "name": "AMQ_PASSWORD",
+ "value": "${MQ_PASSWORD}"
+ },
+ {
+ "name": "AMQ_PROTOCOLS",
+ "value": "${MQ_PROTOCOL}"
+ },
+ {
+ "name": "AMQ_QUEUES",
+ "value": "${MQ_QUEUES}"
+ },
+ {
+ "name": "AMQ_TOPICS",
+ "value": "${MQ_TOPICS}"
+ },
+ {
+ "name": "AMQ_ADMIN_USERNAME",
+ "value": "${AMQ_ADMIN_USERNAME}"
+ },
+ {
+ "name": "AMQ_ADMIN_PASSWORD",
+ "value": "${AMQ_ADMIN_PASSWORD}"
+ },
+ {
+ "name": "AMQ_MESH_SERVICE_NAME",
+ "value": "${APPLICATION_NAME}-amq-tcp"
+ },
+ {
+ "name": "AMQ_KEYSTORE_TRUSTSTORE_DIR",
+ "value": "/etc/amq-secret-volume"
+ },
+ {
+ "name": "AMQ_TRUSTSTORE",
+ "value": "${AMQ_TRUSTSTORE}"
+ },
+ {
+ "name": "AMQ_KEYSTORE",
+ "value": "${AMQ_KEYSTORE}"
+ }
+ ]
+ }
+ ],
+ "volumes": [
+ {
+ "name": "broker-secret-volume",
+ "secret": {
+ "secretName": "${AMQ_SECRET}"
+ }
+ }
+ ]
+ }
+ }
+ }
+ }
+ ]
+}
diff --git a/roles/openshift_examples/files/examples/xpaas-templates/eap6-amq-persistent-sti.json b/roles/openshift_examples/files/examples/xpaas-templates/eap6-amq-persistent-sti.json
new file mode 100644
index 000000000..b64acae8b
--- /dev/null
+++ b/roles/openshift_examples/files/examples/xpaas-templates/eap6-amq-persistent-sti.json
@@ -0,0 +1,646 @@
+{
+ "kind": "Template",
+ "apiVersion": "v1",
+ "metadata": {
+ "annotations": {
+ "description": "Application template for EAP 6 A-MQ applications with persistent storage built using STI.",
+ "iconClass" : "icon-jboss"
+ },
+ "name": "eap6-amq-persistent-sti"
+ },
+ "labels": {
+ "template": "eap6-amq-persistent-sti"
+ },
+ "parameters": [
+ {
+ "description": "EAP Release version, e.g. 6.4, etc.",
+ "name": "EAP_RELEASE",
+ "value": "6.4"
+ },
+ {
+ "description": "ActiveMQ Release version, e.g. 6.2, etc.",
+ "name": "AMQ_RELEASE",
+ "value": "6.2"
+ },
+ {
+ "description": "The name for the application.",
+ "name": "APPLICATION_NAME",
+ "value": "eap-app"
+ },
+ {
+ "description": "Custom hostname for service routes. Leave blank for default hostname, e.g.: <application-name>.<project>.<default-domain-suffix>",
+ "name": "APPLICATION_HOSTNAME",
+ "value": ""
+ },
+ {
+ "description": "Git source URI for application",
+ "name": "GIT_URI"
+ },
+ {
+ "description": "Git branch/tag reference",
+ "name": "GIT_REF",
+ "value": "master"
+ },
+ {
+ "description": "Path within Git project to build; empty for root project directory.",
+ "name": "GIT_CONTEXT_DIR",
+ "value": ""
+ },
+ {
+ "description": "Size of persistent storage for database volume.",
+ "name": "VOLUME_CAPACITY",
+ "value": "512Mi"
+ },
+ {
+ "description": "JNDI name for connection factory used by applications to connect to the broker, e.g. java:/ConnectionFactory",
+ "name": "MQ_JNDI",
+ "value": "java:/ConnectionFactory"
+ },
+ {
+ "description": "Protocol to configure. Only openwire is supported by EAP. amqp, amqp+ssl, mqtt, stomp, stomp+ssl, and ssl are not supported by EAP",
+ "name": "MQ_PROTOCOL",
+ "value": "openwire"
+ },
+ {
+ "description": "Queue names",
+ "name": "MQ_QUEUES",
+ "value": ""
+ },
+ {
+ "description": "Topic names",
+ "name": "MQ_TOPICS",
+ "value": ""
+ },
+ {
+ "description": "The name of the secret containing the keystore file",
+ "name": "EAP_HTTPS_SECRET",
+ "value": "eap-app-secret"
+ },
+ {
+ "description": "The name of the keystore file within the secret",
+ "name": "EAP_HTTPS_KEYSTORE",
+ "value": "keystore.jks"
+ },
+ {
+ "description": "The name associated with the server certificate",
+ "name": "EAP_HTTPS_NAME",
+ "value": ""
+ },
+ {
+ "description": "The password for the keystore and certificate",
+ "name": "EAP_HTTPS_PASSWORD",
+ "value": ""
+ },
+ {
+ "description": "Broker user name",
+ "name": "MQ_USERNAME",
+ "from": "user[a-zA-Z0-9]{3}",
+ "generate": "expression"
+ },
+ {
+ "description": "Broker user password",
+ "name": "MQ_PASSWORD",
+ "from": "[a-zA-Z0-9]{8}",
+ "generate": "expression"
+ },
+ {
+ "description": "ActiveMQ Admin User",
+ "name": "AMQ_ADMIN_USERNAME",
+ "from": "user[a-zA-Z0-9]{3}",
+ "generate": "expression"
+ },
+ {
+ "description": "ActiveMQ Admin Password",
+ "name": "AMQ_ADMIN_PASSWORD",
+ "from": "[a-zA-Z0-9]{8}",
+ "generate": "expression"
+ },
+ {
+ "description": "Github trigger secret",
+ "name": "GITHUB_TRIGGER_SECRET",
+ "from": "[a-zA-Z0-9]{8}",
+ "generate": "expression"
+ },
+ {
+ "description": "Generic build trigger secret",
+ "name": "GENERIC_TRIGGER_SECRET",
+ "from": "[a-zA-Z0-9]{8}",
+ "generate": "expression"
+ }
+ ],
+ "objects": [
+ {
+ "kind": "Service",
+ "apiVersion": "v1",
+ "spec": {
+ "ports": [
+ {
+ "port": 8080,
+ "targetPort": 8080
+ }
+ ],
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}"
+ }
+ },
+ "metadata": {
+ "name": "${APPLICATION_NAME}",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "The web server's http port."
+ }
+ }
+ },
+ {
+ "kind": "Service",
+ "apiVersion": "v1",
+ "spec": {
+ "ports": [
+ {
+ "port": 8443,
+ "targetPort": 8443
+ }
+ ],
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}"
+ }
+ },
+ "metadata": {
+ "name": "secure-${APPLICATION_NAME}",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "The web server's https port."
+ }
+ }
+ },
+ {
+ "kind": "Service",
+ "apiVersion": "v1",
+ "spec": {
+ "ports": [
+ {
+ "port": 8888,
+ "targetPort": 8888
+ }
+ ],
+ "portalIP": "None",
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}"
+ }
+ },
+ "metadata": {
+ "name": "${APPLICATION_NAME}-ping",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "Ping service for clustered applications."
+ }
+ }
+ },
+ {
+ "kind": "Service",
+ "apiVersion": "v1",
+ "spec": {
+ "ports": [
+ {
+ "port": 61616,
+ "targetPort": 61616
+ }
+ ],
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}-amq"
+ }
+ },
+ "metadata": {
+ "name": "${APPLICATION_NAME}-amq-tcp",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "The broker's tcp (openwire) port."
+ }
+ }
+ },
+ {
+ "kind": "Route",
+ "apiVersion": "v1",
+ "id": "${APPLICATION_NAME}-http-route",
+ "metadata": {
+ "name": "${APPLICATION_NAME}-http-route",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "Route for application's http service."
+ }
+ },
+ "spec": {
+ "host": "${APPLICATION_HOSTNAME}",
+ "to": {
+ "name": "${APPLICATION_NAME}"
+ }
+ }
+ },
+ {
+ "kind": "Route",
+ "apiVersion": "v1",
+ "id": "${APPLICATION_NAME}-https-route",
+ "metadata": {
+ "name": "${APPLICATION_NAME}-https-route",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "Route for application's https service."
+ }
+ },
+ "spec": {
+ "host": "${APPLICATION_HOSTNAME}",
+ "to": {
+ "name": "secure-${APPLICATION_NAME}"
+ },
+ "tls": {
+ "termination" : "passthrough"
+ }
+ }
+ },
+ {
+ "kind": "ImageStream",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "${APPLICATION_NAME}",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ }
+ }
+ },
+ {
+ "kind": "BuildConfig",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "${APPLICATION_NAME}",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "source": {
+ "type": "Git",
+ "git": {
+ "uri": "${GIT_URI}",
+ "ref": "${GIT_REF}"
+ },
+ "contextDir":"${GIT_CONTEXT_DIR}"
+ },
+ "strategy": {
+ "type": "Source",
+ "sourceStrategy": {
+ "from": {
+ "kind": "ImageStreamTag",
+ "namespace": "openshift",
+ "name": "jboss-eap6-openshift:${EAP_RELEASE}"
+ }
+ }
+ },
+ "output": {
+ "to": {
+ "kind": "ImageStreamTag",
+ "name": "${APPLICATION_NAME}:latest"
+ }
+ },
+ "triggers": [
+ {
+ "type": "GitHub",
+ "github": {
+ "secret": "${GITHUB_TRIGGER_SECRET}"
+ }
+ },
+ {
+ "type": "Generic",
+ "generic": {
+ "secret": "${GENERIC_TRIGGER_SECRET}"
+ }
+ },
+ {
+ "type": "ImageChange",
+ "imageChange": {}
+ }
+ ]
+ }
+ },
+ {
+ "kind": "DeploymentConfig",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "${APPLICATION_NAME}",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "strategy": {
+ "type": "Recreate"
+ },
+ "triggers": [
+ {
+ "type": "ImageChange",
+ "imageChangeParams": {
+ "automatic": true,
+ "containerNames": [
+ "${APPLICATION_NAME}"
+ ],
+ "from": {
+ "kind": "ImageStream",
+ "name": "${APPLICATION_NAME}"
+ }
+ }
+ }
+ ],
+ "replicas": 1,
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}"
+ },
+ "template": {
+ "metadata": {
+ "name": "${APPLICATION_NAME}",
+ "labels": {
+ "deploymentConfig": "${APPLICATION_NAME}",
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "serviceAccount": "eap-service-account",
+ "containers": [
+ {
+ "name": "${APPLICATION_NAME}",
+ "image": "${APPLICATION_NAME}",
+ "imagePullPolicy": "Always",
+ "volumeMounts": [
+ {
+ "name": "eap-keystore-volume",
+ "mountPath": "/etc/eap-secret-volume",
+ "readOnly": true
+ }
+ ],
+ "readinessProbe": {
+ "exec": {
+ "command": [
+ "/bin/bash",
+ "-c",
+ "/opt/eap/bin/readinessProbe.sh"
+ ]
+ }
+ },
+ "ports": [
+ {
+ "name": "http",
+ "containerPort": 8080,
+ "protocol": "TCP"
+ },
+ {
+ "name": "https",
+ "containerPort": 8443,
+ "protocol": "TCP"
+ },
+ {
+ "name": "ping",
+ "containerPort": 8888,
+ "protocol": "TCP"
+ }
+ ],
+ "env": [
+ {
+ "name": "MQ_SERVICE_PREFIX_MAPPING",
+ "value": "${APPLICATION_NAME}-amq=MQ"
+ },
+ {
+ "name": "MQ_JNDI",
+ "value": "${MQ_JNDI}"
+ },
+ {
+ "name": "MQ_USERNAME",
+ "value": "${MQ_USERNAME}"
+ },
+ {
+ "name": "MQ_PASSWORD",
+ "value": "${MQ_PASSWORD}"
+ },
+ {
+ "name": "MQ_PROTOCOL",
+ "value": "tcp"
+ },
+ {
+ "name": "MQ_QUEUES",
+ "value": "${MQ_QUEUES}"
+ },
+ {
+ "name": "MQ_TOPICS",
+ "value": "${MQ_TOPICS}"
+ },
+ {
+ "name": "OPENSHIFT_DNS_PING_SERVICE_NAME",
+ "value": "${APPLICATION_NAME}-ping"
+ },
+ {
+ "name": "OPENSHIFT_DNS_PING_SERVICE_PORT",
+ "value": "8888"
+ },
+ {
+ "name": "EAP_HTTPS_KEYSTORE_DIR",
+ "value": "/etc/eap-secret-volume"
+ },
+ {
+ "name": "EAP_HTTPS_KEYSTORE",
+ "value": "${EAP_HTTPS_KEYSTORE}"
+ },
+ {
+ "name": "EAP_HTTPS_NAME",
+ "value": "${EAP_HTTPS_NAME}"
+ },
+ {
+ "name": "EAP_HTTPS_PASSWORD",
+ "value": "${EAP_HTTPS_PASSWORD}"
+ }
+ ]
+ }
+ ],
+ "volumes": [
+ {
+ "name": "eap-keystore-volume",
+ "secret": {
+ "secretName": "${EAP_HTTPS_SECRET}"
+ }
+ }
+ ]
+ }
+ }
+ }
+ },
+ {
+ "kind": "DeploymentConfig",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "${APPLICATION_NAME}-amq",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "strategy": {
+ "type": "Recreate"
+ },
+ "triggers": [
+ {
+ "type": "ImageChange",
+ "imageChangeParams": {
+ "automatic": true,
+ "containerNames": [
+ "${APPLICATION_NAME}-amq"
+ ],
+ "from": {
+ "kind": "ImageStreamTag",
+ "namespace": "openshift",
+ "name": "jboss-amq-6:${AMQ_RELEASE}"
+ }
+ }
+ }
+ ],
+ "replicas": 1,
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}-amq"
+ },
+ "template": {
+ "metadata": {
+ "name": "${APPLICATION_NAME}-amq",
+ "labels": {
+ "deploymentConfig": "${APPLICATION_NAME}-amq",
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "containers": [
+ {
+ "name": "${APPLICATION_NAME}-amq",
+ "image": "jboss-amq-6",
+ "imagePullPolicy": "Always",
+ "readinessProbe": {
+ "exec": {
+ "command": [
+ "/bin/bash",
+ "-c",
+ "curl -s -L -u ${AMQ_ADMIN_USERNAME}:${AMQ_ADMIN_PASSWORD} 'http://localhost:8161/hawtio/jolokia/read/org.apache.activemq:type=Broker,brokerName=*,service=Health/CurrentStatus' | grep -q '\"CurrentStatus\" *: *\"Good\"'"
+ ]
+ }
+ },
+ "ports": [
+ {
+ "name": "amqp",
+ "containerPort": 5672,
+ "protocol": "TCP"
+ },
+ {
+ "name": "amqp-ssl",
+ "containerPort": 5671,
+ "protocol": "TCP"
+ },
+ {
+ "name": "mqtt",
+ "containerPort": 1883,
+ "protocol": "TCP"
+ },
+ {
+ "name": "stomp",
+ "containerPort": 61613,
+ "protocol": "TCP"
+ },
+ {
+ "name": "stomp-ssl",
+ "containerPort": 61612,
+ "protocol": "TCP"
+ },
+ {
+ "name": "tcp",
+ "containerPort": 61616,
+ "protocol": "TCP"
+ },
+ {
+ "name": "tcp-ssl",
+ "containerPort": 61617,
+ "protocol": "TCP"
+ }
+ ],
+ "volumeMounts": [
+ {
+ "mountPath": "/opt/amq/data/kahadb",
+ "name": "${APPLICATION_NAME}-amq-pvol"
+ }
+ ],
+ "env": [
+ {
+ "name": "AMQ_USER",
+ "value": "${MQ_USERNAME}"
+ },
+ {
+ "name": "AMQ_PASSWORD",
+ "value": "${MQ_PASSWORD}"
+ },
+ {
+ "name": "AMQ_PROTOCOLS",
+ "value": "${MQ_PROTOCOL}"
+ },
+ {
+ "name": "AMQ_QUEUES",
+ "value": "${MQ_QUEUES}"
+ },
+ {
+ "name": "AMQ_TOPICS",
+ "value": "${MQ_TOPICS}"
+ },
+ {
+ "name": "AMQ_ADMIN_USERNAME",
+ "value": "${AMQ_ADMIN_USERNAME}"
+ },
+ {
+ "name": "AMQ_ADMIN_PASSWORD",
+ "value": "${AMQ_ADMIN_PASSWORD}"
+ }
+ ]
+ }
+ ],
+ "volumes": [
+ {
+ "name": "${APPLICATION_NAME}-amq-pvol",
+ "persistentVolumeClaim": {
+ "claimName": "${APPLICATION_NAME}-amq-claim"
+ }
+ }
+ ]
+ }
+ }
+ }
+ },
+ {
+ "apiVersion": "v1",
+ "kind": "PersistentVolumeClaim",
+ "metadata": {
+ "name": "${APPLICATION_NAME}-amq-claim",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "accessModes": [ "ReadWriteOnce" ],
+ "resources": {
+ "requests": {
+ "storage": "${VOLUME_CAPACITY}"
+ }
+ }
+ }
+ }
+ ]
+}
diff --git a/roles/openshift_examples/files/examples/xpaas-templates/eap6-amq-sti.json b/roles/openshift_examples/files/examples/xpaas-templates/eap6-amq-sti.json
new file mode 100644
index 000000000..20b234bd0
--- /dev/null
+++ b/roles/openshift_examples/files/examples/xpaas-templates/eap6-amq-sti.json
@@ -0,0 +1,609 @@
+{
+ "kind": "Template",
+ "apiVersion": "v1",
+ "metadata": {
+ "annotations": {
+ "description": "Application template for EAP 6 A-MQ applications built using STI.",
+ "iconClass" : "icon-jboss"
+ },
+ "name": "eap6-amq-sti"
+ },
+ "labels": {
+ "template": "eap6-amq-sti"
+ },
+ "parameters": [
+ {
+ "description": "EAP Release version, e.g. 6.4, etc.",
+ "name": "EAP_RELEASE",
+ "value": "6.4"
+ },
+ {
+ "description": "ActiveMQ Release version, e.g. 6.2, etc.",
+ "name": "AMQ_RELEASE",
+ "value": "6.2"
+ },
+ {
+ "description": "The name for the application.",
+ "name": "APPLICATION_NAME",
+ "value": "eap-app"
+ },
+ {
+ "description": "Custom hostname for service routes. Leave blank for default hostname, e.g.: <application-name>.<project>.<default-domain-suffix>",
+ "name": "APPLICATION_HOSTNAME",
+ "value": ""
+ },
+ {
+ "description": "Git source URI for application",
+ "name": "GIT_URI"
+ },
+ {
+ "description": "Git branch/tag reference",
+ "name": "GIT_REF",
+ "value": "master"
+ },
+ {
+ "description": "Path within Git project to build; empty for root project directory.",
+ "name": "GIT_CONTEXT_DIR",
+ "value": ""
+ },
+ {
+ "description": "JNDI name for connection factory used by applications to connect to the broker, e.g. java:/ConnectionFactory",
+ "name": "MQ_JNDI",
+ "value": "java:/ConnectionFactory"
+ },
+ {
+ "description": "Protocol to configure. Only openwire is supported by EAP. amqp, amqp+ssl, mqtt, stomp, stomp+ssl, and ssl are not supported by EAP",
+ "name": "MQ_PROTOCOL",
+ "value": "openwire"
+ },
+ {
+ "description": "Queue names",
+ "name": "MQ_QUEUES",
+ "value": ""
+ },
+ {
+ "description": "Topic names",
+ "name": "MQ_TOPICS",
+ "value": ""
+ },
+ {
+ "description": "The name of the secret containing the keystore file",
+ "name": "EAP_HTTPS_SECRET",
+ "value": "eap-app-secret"
+ },
+ {
+ "description": "The name of the keystore file within the secret",
+ "name": "EAP_HTTPS_KEYSTORE",
+ "value": "keystore.jks"
+ },
+ {
+ "description": "The name associated with the server certificate",
+ "name": "EAP_HTTPS_NAME",
+ "value": ""
+ },
+ {
+ "description": "The password for the keystore and certificate",
+ "name": "EAP_HTTPS_PASSWORD",
+ "value": ""
+ },
+ {
+ "description": "Broker user name",
+ "name": "MQ_USERNAME",
+ "from": "user[a-zA-Z0-9]{3}",
+ "generate": "expression"
+ },
+ {
+ "description": "Broker user password",
+ "name": "MQ_PASSWORD",
+ "from": "[a-zA-Z0-9]{8}",
+ "generate": "expression"
+ },
+ {
+ "description": "ActiveMQ Admin User",
+ "name": "AMQ_ADMIN_USERNAME",
+ "from": "user[a-zA-Z0-9]{3}",
+ "generate": "expression"
+ },
+ {
+ "description": "ActiveMQ Admin Password",
+ "name": "AMQ_ADMIN_PASSWORD",
+ "from": "[a-zA-Z0-9]{8}",
+ "generate": "expression"
+ },
+ {
+ "description": "Github trigger secret",
+ "name": "GITHUB_TRIGGER_SECRET",
+ "from": "[a-zA-Z0-9]{8}",
+ "generate": "expression"
+ },
+ {
+ "description": "Generic build trigger secret",
+ "name": "GENERIC_TRIGGER_SECRET",
+ "from": "[a-zA-Z0-9]{8}",
+ "generate": "expression"
+ }
+ ],
+ "objects": [
+ {
+ "kind": "Service",
+ "apiVersion": "v1",
+ "spec": {
+ "ports": [
+ {
+ "port": 8080,
+ "targetPort": 8080
+ }
+ ],
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}"
+ }
+ },
+ "metadata": {
+ "name": "${APPLICATION_NAME}",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "The web server's http port."
+ }
+ }
+ },
+ {
+ "kind": "Service",
+ "apiVersion": "v1",
+ "spec": {
+ "ports": [
+ {
+ "port": 8443,
+ "targetPort": 8443
+ }
+ ],
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}"
+ }
+ },
+ "metadata": {
+ "name": "secure-${APPLICATION_NAME}",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "The web server's https port."
+ }
+ }
+ },
+ {
+ "kind": "Service",
+ "apiVersion": "v1",
+ "spec": {
+ "ports": [
+ {
+ "port": 8888,
+ "targetPort": 8888
+ }
+ ],
+ "portalIP": "None",
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}"
+ }
+ },
+ "metadata": {
+ "name": "${APPLICATION_NAME}-ping",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "Ping service for clustered applications."
+ }
+ }
+ },
+ {
+ "kind": "Service",
+ "apiVersion": "v1",
+ "spec": {
+ "ports": [
+ {
+ "port": 61616,
+ "targetPort": 61616
+ }
+ ],
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}-amq"
+ }
+ },
+ "metadata": {
+ "name": "${APPLICATION_NAME}-amq-tcp",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "The broker's tcp (openwire) port."
+ }
+ }
+ },
+ {
+ "kind": "Route",
+ "apiVersion": "v1",
+ "id": "${APPLICATION_NAME}-http-route",
+ "metadata": {
+ "name": "${APPLICATION_NAME}-http-route",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "Route for application's http service."
+ }
+ },
+ "spec": {
+ "host": "${APPLICATION_HOSTNAME}",
+ "to": {
+ "name": "${APPLICATION_NAME}"
+ }
+ }
+ },
+ {
+ "kind": "Route",
+ "apiVersion": "v1",
+ "id": "${APPLICATION_NAME}-https-route",
+ "metadata": {
+ "name": "${APPLICATION_NAME}-https-route",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "Route for application's https service."
+ }
+ },
+ "spec": {
+ "host": "${APPLICATION_HOSTNAME}",
+ "to": {
+ "name": "secure-${APPLICATION_NAME}"
+ },
+ "tls": {
+ "termination" : "passthrough"
+ }
+ }
+ },
+ {
+ "kind": "ImageStream",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "${APPLICATION_NAME}",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ }
+ }
+ },
+ {
+ "kind": "BuildConfig",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "${APPLICATION_NAME}",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "source": {
+ "type": "Git",
+ "git": {
+ "uri": "${GIT_URI}",
+ "ref": "${GIT_REF}"
+ },
+ "contextDir":"${GIT_CONTEXT_DIR}"
+ },
+ "strategy": {
+ "type": "Source",
+ "sourceStrategy": {
+ "from": {
+ "kind": "ImageStreamTag",
+ "namespace": "openshift",
+ "name": "jboss-eap6-openshift:${EAP_RELEASE}"
+ }
+ }
+ },
+ "output": {
+ "to": {
+ "kind": "ImageStreamTag",
+ "name": "${APPLICATION_NAME}:latest"
+ }
+ },
+ "triggers": [
+ {
+ "type": "GitHub",
+ "github": {
+ "secret": "${GITHUB_TRIGGER_SECRET}"
+ }
+ },
+ {
+ "type": "Generic",
+ "generic": {
+ "secret": "${GENERIC_TRIGGER_SECRET}"
+ }
+ },
+ {
+ "type": "ImageChange",
+ "imageChange": {}
+ }
+ ]
+ }
+ },
+ {
+ "kind": "DeploymentConfig",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "${APPLICATION_NAME}",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "strategy": {
+ "type": "Recreate"
+ },
+ "triggers": [
+ {
+ "type": "ImageChange",
+ "imageChangeParams": {
+ "automatic": true,
+ "containerNames": [
+ "${APPLICATION_NAME}"
+ ],
+ "from": {
+ "kind": "ImageStream",
+ "name": "${APPLICATION_NAME}"
+ }
+ }
+ }
+ ],
+ "replicas": 1,
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}"
+ },
+ "template": {
+ "metadata": {
+ "name": "${APPLICATION_NAME}",
+ "labels": {
+ "deploymentConfig": "${APPLICATION_NAME}",
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "serviceAccount": "eap-service-account",
+ "containers": [
+ {
+ "name": "${APPLICATION_NAME}",
+ "image": "${APPLICATION_NAME}",
+ "imagePullPolicy": "Always",
+ "volumeMounts": [
+ {
+ "name": "eap-keystore-volume",
+ "mountPath": "/etc/eap-secret-volume",
+ "readOnly": true
+ }
+ ],
+ "readinessProbe": {
+ "exec": {
+ "command": [
+ "/bin/bash",
+ "-c",
+ "/opt/eap/bin/readinessProbe.sh"
+ ]
+ }
+ },
+ "ports": [
+ {
+ "name": "http",
+ "containerPort": 8080,
+ "protocol": "TCP"
+ },
+ {
+ "name": "https",
+ "containerPort": 8443,
+ "protocol": "TCP"
+ },
+ {
+ "name": "ping",
+ "containerPort": 8888,
+ "protocol": "TCP"
+ }
+ ],
+ "env": [
+ {
+ "name": "MQ_SERVICE_PREFIX_MAPPING",
+ "value": "${APPLICATION_NAME}-amq=MQ"
+ },
+ {
+ "name": "MQ_JNDI",
+ "value": "${MQ_JNDI}"
+ },
+ {
+ "name": "MQ_USERNAME",
+ "value": "${MQ_USERNAME}"
+ },
+ {
+ "name": "MQ_PASSWORD",
+ "value": "${MQ_PASSWORD}"
+ },
+ {
+ "name": "MQ_PROTOCOL",
+ "value": "tcp"
+ },
+ {
+ "name": "MQ_QUEUES",
+ "value": "${MQ_QUEUES}"
+ },
+ {
+ "name": "MQ_TOPICS",
+ "value": "${MQ_TOPICS}"
+ },
+ {
+ "name": "OPENSHIFT_DNS_PING_SERVICE_NAME",
+ "value": "${APPLICATION_NAME}-ping"
+ },
+ {
+ "name": "OPENSHIFT_DNS_PING_SERVICE_PORT",
+ "value": "8888"
+ },
+ {
+ "name": "EAP_HTTPS_KEYSTORE_DIR",
+ "value": "/etc/eap-secret-volume"
+ },
+ {
+ "name": "EAP_HTTPS_KEYSTORE",
+ "value": "${EAP_HTTPS_KEYSTORE}"
+ },
+ {
+ "name": "EAP_HTTPS_NAME",
+ "value": "${EAP_HTTPS_NAME}"
+ },
+ {
+ "name": "EAP_HTTPS_PASSWORD",
+ "value": "${EAP_HTTPS_PASSWORD}"
+ }
+ ]
+ }
+ ],
+ "volumes": [
+ {
+ "name": "eap-keystore-volume",
+ "secret": {
+ "secretName": "${EAP_HTTPS_SECRET}"
+ }
+ }
+ ]
+ }
+ }
+ }
+ },
+ {
+ "kind": "DeploymentConfig",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "${APPLICATION_NAME}-amq",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "strategy": {
+ "type": "Recreate"
+ },
+ "triggers": [
+ {
+ "type": "ImageChange",
+ "imageChangeParams": {
+ "automatic": true,
+ "containerNames": [
+ "${APPLICATION_NAME}-amq"
+ ],
+ "from": {
+ "kind": "ImageStreamTag",
+ "namespace": "openshift",
+ "name": "jboss-amq-6:${AMQ_RELEASE}"
+ }
+ }
+ }
+ ],
+ "replicas": 1,
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}-amq"
+ },
+ "template": {
+ "metadata": {
+ "name": "${APPLICATION_NAME}-amq",
+ "labels": {
+ "deploymentConfig": "${APPLICATION_NAME}-amq",
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "containers": [
+ {
+ "name": "${APPLICATION_NAME}-amq",
+ "image": "jboss-amq-6",
+ "imagePullPolicy": "Always",
+ "readinessProbe": {
+ "exec": {
+ "command": [
+ "/bin/bash",
+ "-c",
+ "curl -s -L -u ${AMQ_ADMIN_USERNAME}:${AMQ_ADMIN_PASSWORD} 'http://localhost:8161/hawtio/jolokia/read/org.apache.activemq:type=Broker,brokerName=*,service=Health/CurrentStatus' | grep -q '\"CurrentStatus\" *: *\"Good\"'"
+ ]
+ }
+ },
+ "ports": [
+ {
+ "name": "amqp",
+ "containerPort": 5672,
+ "protocol": "TCP"
+ },
+ {
+ "name": "amqp-ssl",
+ "containerPort": 5671,
+ "protocol": "TCP"
+ },
+ {
+ "name": "mqtt",
+ "containerPort": 1883,
+ "protocol": "TCP"
+ },
+ {
+ "name": "stomp",
+ "containerPort": 61613,
+ "protocol": "TCP"
+ },
+ {
+ "name": "stomp-ssl",
+ "containerPort": 61612,
+ "protocol": "TCP"
+ },
+ {
+ "name": "tcp",
+ "containerPort": 61616,
+ "protocol": "TCP"
+ },
+ {
+ "name": "tcp-ssl",
+ "containerPort": 61617,
+ "protocol": "TCP"
+ }
+ ],
+ "env": [
+ {
+ "name": "AMQ_USER",
+ "value": "${MQ_USERNAME}"
+ },
+ {
+ "name": "AMQ_PASSWORD",
+ "value": "${MQ_PASSWORD}"
+ },
+ {
+ "name": "AMQ_PROTOCOLS",
+ "value": "${MQ_PROTOCOL}"
+ },
+ {
+ "name": "AMQ_QUEUES",
+ "value": "${MQ_QUEUES}"
+ },
+ {
+ "name": "AMQ_TOPICS",
+ "value": "${MQ_TOPICS}"
+ },
+ {
+ "name": "AMQ_ADMIN_USERNAME",
+ "value": "${AMQ_ADMIN_USERNAME}"
+ },
+ {
+ "name": "AMQ_ADMIN_PASSWORD",
+ "value": "${AMQ_ADMIN_PASSWORD}"
+ }
+ ]
+ }
+ ]
+ }
+ }
+ }
+ }
+ ]
+}
diff --git a/roles/openshift_examples/files/examples/xpaas-templates/eap6-basic-sti.json b/roles/openshift_examples/files/examples/xpaas-templates/eap6-basic-sti.json
new file mode 100644
index 000000000..146bfb1ee
--- /dev/null
+++ b/roles/openshift_examples/files/examples/xpaas-templates/eap6-basic-sti.json
@@ -0,0 +1,304 @@
+{
+ "kind": "Template",
+ "apiVersion": "v1",
+ "metadata": {
+ "annotations": {
+ "iconClass" : "icon-jboss",
+ "description": "Application template for EAP 6 applications built using STI."
+ },
+ "name": "eap6-basic-sti"
+ },
+ "labels": {
+ "template": "eap6-basic-sti"
+ },
+ "parameters": [
+ {
+ "description": "EAP Release version, e.g. 6.4, etc.",
+ "name": "EAP_RELEASE",
+ "value": "6.4"
+ },
+ {
+ "description": "The name for the application.",
+ "name": "APPLICATION_NAME",
+ "value": "eap-app"
+ },
+ {
+ "description": "Custom hostname for service routes. Leave blank for default hostname, e.g.: <application-name>.<project>.<default-domain-suffix>",
+ "name": "APPLICATION_HOSTNAME",
+ "value": ""
+ },
+ {
+ "description": "Git source URI for application",
+ "name": "GIT_URI",
+ "value": "https://github.com/jboss-developer/jboss-eap-quickstarts"
+ },
+ {
+ "description": "Git branch/tag reference",
+ "name": "GIT_REF",
+ "value": "6.4.x"
+ },
+ {
+ "description": "Path within Git project to build; empty for root project directory.",
+ "name": "GIT_CONTEXT_DIR",
+ "value": "kitchensink"
+ },
+ {
+ "description": "Queue names",
+ "name": "HORNETQ_QUEUES",
+ "value": ""
+ },
+ {
+ "description": "Topic names",
+ "name": "HORNETQ_TOPICS",
+ "value": ""
+ },
+ {
+ "description": "HornetQ cluster admin password",
+ "name": "HORNETQ_CLUSTER_PASSWORD",
+ "from": "[a-zA-Z0-9]{8}",
+ "generate": "expression"
+ },
+ {
+ "description": "Github trigger secret",
+ "name": "GITHUB_TRIGGER_SECRET",
+ "from": "[a-zA-Z0-9]{8}",
+ "generate": "expression"
+ },
+ {
+ "description": "Generic build trigger secret",
+ "name": "GENERIC_TRIGGER_SECRET",
+ "from": "[a-zA-Z0-9]{8}",
+ "generate": "expression"
+ }
+ ],
+ "objects": [
+ {
+ "kind": "Service",
+ "apiVersion": "v1",
+ "spec": {
+ "ports": [
+ {
+ "port": 8080,
+ "targetPort": 8080
+ }
+ ],
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}"
+ }
+ },
+ "metadata": {
+ "name": "${APPLICATION_NAME}",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "The web server's http port."
+ }
+ }
+ },
+ {
+ "kind": "Service",
+ "apiVersion": "v1",
+ "spec": {
+ "ports": [
+ {
+ "port": 8888,
+ "targetPort": 8888
+ }
+ ],
+ "portalIP": "None",
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}"
+ }
+ },
+ "metadata": {
+ "name": "${APPLICATION_NAME}-ping",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "Ping service for clustered applications."
+ }
+ }
+ },
+ {
+ "kind": "Route",
+ "apiVersion": "v1",
+ "id": "${APPLICATION_NAME}-http-route",
+ "metadata": {
+ "name": "${APPLICATION_NAME}-http-route",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "Route for application's http service."
+ }
+ },
+ "spec": {
+ "host": "${APPLICATION_HOSTNAME}",
+ "to": {
+ "name": "${APPLICATION_NAME}"
+ }
+ }
+ },
+ {
+ "kind": "ImageStream",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "${APPLICATION_NAME}",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ }
+ }
+ },
+ {
+ "kind": "BuildConfig",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "${APPLICATION_NAME}",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "source": {
+ "type": "Git",
+ "git": {
+ "uri": "${GIT_URI}",
+ "ref": "${GIT_REF}"
+ },
+ "contextDir":"${GIT_CONTEXT_DIR}"
+ },
+ "strategy": {
+ "type": "Source",
+ "sourceStrategy": {
+ "from": {
+ "kind": "ImageStreamTag",
+ "namespace": "openshift",
+ "name": "jboss-eap6-openshift:${EAP_RELEASE}"
+ }
+ }
+ },
+ "output": {
+ "to": {
+ "kind": "ImageStreamTag",
+ "name": "${APPLICATION_NAME}:latest"
+ }
+ },
+ "triggers": [
+ {
+ "type": "GitHub",
+ "github": {
+ "secret": "${GITHUB_TRIGGER_SECRET}"
+ }
+ },
+ {
+ "type": "Generic",
+ "generic": {
+ "secret": "${GENERIC_TRIGGER_SECRET}"
+ }
+ },
+ {
+ "type": "ImageChange",
+ "imageChange": {}
+ }
+ ]
+ }
+ },
+ {
+ "kind": "DeploymentConfig",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "${APPLICATION_NAME}",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "strategy": {
+ "type": "Recreate"
+ },
+ "triggers": [
+ {
+ "type": "ImageChange",
+ "imageChangeParams": {
+ "automatic": true,
+ "containerNames": [
+ "${APPLICATION_NAME}"
+ ],
+ "from": {
+ "kind": "ImageStream",
+ "name": "${APPLICATION_NAME}"
+ }
+ }
+ }
+ ],
+ "replicas": 1,
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}"
+ },
+ "template": {
+ "metadata": {
+ "name": "${APPLICATION_NAME}",
+ "labels": {
+ "deploymentConfig": "${APPLICATION_NAME}",
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "containers": [
+ {
+ "name": "${APPLICATION_NAME}",
+ "image": "${APPLICATION_NAME}",
+ "imagePullPolicy": "Always",
+ "readinessProbe": {
+ "exec": {
+ "command": [
+ "/bin/bash",
+ "-c",
+ "/opt/eap/bin/readinessProbe.sh"
+ ]
+ }
+ },
+ "ports": [
+ {
+ "name": "http",
+ "containerPort": 8080,
+ "protocol": "TCP"
+ },
+ {
+ "name": "ping",
+ "containerPort": 8888,
+ "protocol": "TCP"
+ }
+ ],
+ "env": [
+ {
+ "name": "OPENSHIFT_DNS_PING_SERVICE_NAME",
+ "value": "${APPLICATION_NAME}-ping"
+ },
+ {
+ "name": "OPENSHIFT_DNS_PING_SERVICE_PORT",
+ "value": "8888"
+ },
+ {
+ "name": "HORNETQ_CLUSTER_PASSWORD",
+ "value": "${HORNETQ_CLUSTER_PASSWORD}"
+ },
+ {
+ "name": "HORNETQ_QUEUES",
+ "value": "${HORNETQ_QUEUES}"
+ },
+ {
+ "name": "HORNETQ_TOPICS",
+ "value": "${HORNETQ_TOPICS}"
+ }
+ ]
+ }
+ ]
+ }
+ }
+ }
+ }
+ ]
+}
diff --git a/roles/openshift_examples/files/examples/xpaas-templates/eap6-https-sti.json b/roles/openshift_examples/files/examples/xpaas-templates/eap6-https-sti.json
new file mode 100644
index 000000000..5df36ccc2
--- /dev/null
+++ b/roles/openshift_examples/files/examples/xpaas-templates/eap6-https-sti.json
@@ -0,0 +1,408 @@
+{
+ "kind": "Template",
+ "apiVersion": "v1",
+ "metadata": {
+ "annotations": {
+ "iconClass" : "icon-jboss",
+ "description": "Application template for EAP 6 applications built using STI."
+ },
+ "name": "eap6-https-sti"
+ },
+ "labels": {
+ "template": "eap6-https-sti"
+ },
+ "parameters": [
+ {
+ "description": "EAP Release version, e.g. 6.4, etc.",
+ "name": "EAP_RELEASE",
+ "value": "6.4"
+ },
+ {
+ "description": "The name for the application.",
+ "name": "APPLICATION_NAME",
+ "value": "eap-app"
+ },
+ {
+ "description": "Custom hostname for service routes. Leave blank for default hostname, e.g.: <application-name>.<project>.<default-domain-suffix>",
+ "name": "APPLICATION_HOSTNAME",
+ "value": ""
+ },
+ {
+ "description": "Git source URI for application",
+ "name": "GIT_URI",
+ "value": "https://github.com/jboss-developer/jboss-eap-quickstarts"
+ },
+ {
+ "description": "Git branch/tag reference",
+ "name": "GIT_REF",
+ "value": "6.4.x"
+ },
+ {
+ "description": "Path within Git project to build; empty for root project directory.",
+ "name": "GIT_CONTEXT_DIR",
+ "value": "kitchensink"
+ },
+ {
+ "description": "Queue names",
+ "name": "HORNETQ_QUEUES",
+ "value": ""
+ },
+ {
+ "description": "Topic names",
+ "name": "HORNETQ_TOPICS",
+ "value": ""
+ },
+ {
+ "description": "The name of the secret containing the keystore file",
+ "name": "EAP_HTTPS_SECRET",
+ "value": "eap-app-secret"
+ },
+ {
+ "description": "The name of the keystore file within the secret",
+ "name": "EAP_HTTPS_KEYSTORE",
+ "value": "keystore.jks"
+ },
+ {
+ "description": "The name associated with the server certificate",
+ "name": "EAP_HTTPS_NAME",
+ "value": ""
+ },
+ {
+ "description": "The password for the keystore and certificate",
+ "name": "EAP_HTTPS_PASSWORD",
+ "value": ""
+ },
+ {
+ "description": "HornetQ cluster admin password",
+ "name": "HORNETQ_CLUSTER_PASSWORD",
+ "from": "[a-zA-Z0-9]{8}",
+ "generate": "expression"
+ },
+ {
+ "description": "Github trigger secret",
+ "name": "GITHUB_TRIGGER_SECRET",
+ "from": "[a-zA-Z0-9]{8}",
+ "generate": "expression"
+ },
+ {
+ "description": "Generic build trigger secret",
+ "name": "GENERIC_TRIGGER_SECRET",
+ "from": "[a-zA-Z0-9]{8}",
+ "generate": "expression"
+ }
+ ],
+ "objects": [
+ {
+ "kind": "Service",
+ "apiVersion": "v1",
+ "spec": {
+ "ports": [
+ {
+ "port": 8080,
+ "targetPort": 8080
+ }
+ ],
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}"
+ }
+ },
+ "metadata": {
+ "name": "${APPLICATION_NAME}",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "The web server's http port."
+ }
+ }
+ },
+ {
+ "kind": "Service",
+ "apiVersion": "v1",
+ "spec": {
+ "ports": [
+ {
+ "port": 8443,
+ "targetPort": 8443
+ }
+ ],
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}"
+ }
+ },
+ "metadata": {
+ "name": "secure-${APPLICATION_NAME}",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "The web server's https port."
+ }
+ }
+ },
+ {
+ "kind": "Service",
+ "apiVersion": "v1",
+ "spec": {
+ "ports": [
+ {
+ "port": 8888,
+ "targetPort": 8888
+ }
+ ],
+ "portalIP": "None",
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}"
+ }
+ },
+ "metadata": {
+ "name": "${APPLICATION_NAME}-ping",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "Ping service for clustered applications."
+ }
+ }
+ },
+ {
+ "kind": "Route",
+ "apiVersion": "v1",
+ "id": "${APPLICATION_NAME}-http-route",
+ "metadata": {
+ "name": "${APPLICATION_NAME}-http-route",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "Route for application's http service."
+ }
+ },
+ "spec": {
+ "host": "${APPLICATION_HOSTNAME}",
+ "to": {
+ "name": "${APPLICATION_NAME}"
+ }
+ }
+ },
+ {
+ "kind": "Route",
+ "apiVersion": "v1",
+ "id": "${APPLICATION_NAME}-https-route",
+ "metadata": {
+ "name": "${APPLICATION_NAME}-https-route",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "Route for application's https service."
+ }
+ },
+ "spec": {
+ "host": "${APPLICATION_HOSTNAME}",
+ "to": {
+ "name": "secure-${APPLICATION_NAME}"
+ },
+ "tls": {
+ "termination" : "passthrough"
+ }
+ }
+ },
+ {
+ "kind": "ImageStream",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "${APPLICATION_NAME}",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ }
+ }
+ },
+ {
+ "kind": "BuildConfig",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "${APPLICATION_NAME}",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "source": {
+ "type": "Git",
+ "git": {
+ "uri": "${GIT_URI}",
+ "ref": "${GIT_REF}"
+ },
+ "contextDir":"${GIT_CONTEXT_DIR}"
+ },
+ "strategy": {
+ "type": "Source",
+ "sourceStrategy": {
+ "from": {
+ "kind": "ImageStreamTag",
+ "namespace": "openshift",
+ "name": "jboss-eap6-openshift:${EAP_RELEASE}"
+ }
+ }
+ },
+ "output": {
+ "to": {
+ "kind": "ImageStreamTag",
+ "name": "${APPLICATION_NAME}:latest"
+ }
+ },
+ "triggers": [
+ {
+ "type": "GitHub",
+ "github": {
+ "secret": "${GITHUB_TRIGGER_SECRET}"
+ }
+ },
+ {
+ "type": "Generic",
+ "generic": {
+ "secret": "${GENERIC_TRIGGER_SECRET}"
+ }
+ },
+ {
+ "type": "ImageChange",
+ "imageChange": {}
+ }
+ ]
+ }
+ },
+ {
+ "kind": "DeploymentConfig",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "${APPLICATION_NAME}",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "strategy": {
+ "type": "Recreate"
+ },
+ "triggers": [
+ {
+ "type": "ImageChange",
+ "imageChangeParams": {
+ "automatic": true,
+ "containerNames": [
+ "${APPLICATION_NAME}"
+ ],
+ "from": {
+ "kind": "ImageStream",
+ "name": "${APPLICATION_NAME}"
+ }
+ }
+ }
+ ],
+ "replicas": 1,
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}"
+ },
+ "template": {
+ "metadata": {
+ "name": "${APPLICATION_NAME}",
+ "labels": {
+ "deploymentConfig": "${APPLICATION_NAME}",
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "serviceAccount": "eap-service-account",
+ "containers": [
+ {
+ "name": "${APPLICATION_NAME}",
+ "image": "${APPLICATION_NAME}",
+ "imagePullPolicy": "Always",
+ "volumeMounts": [
+ {
+ "name": "eap-keystore-volume",
+ "mountPath": "/etc/eap-secret-volume",
+ "readOnly": true
+ }
+ ],
+ "readinessProbe": {
+ "exec": {
+ "command": [
+ "/bin/bash",
+ "-c",
+ "/opt/eap/bin/readinessProbe.sh"
+ ]
+ }
+ },
+ "ports": [
+ {
+ "name": "http",
+ "containerPort": 8080,
+ "protocol": "TCP"
+ },
+ {
+ "name": "https",
+ "containerPort": 8443,
+ "protocol": "TCP"
+ },
+ {
+ "name": "ping",
+ "containerPort": 8888,
+ "protocol": "TCP"
+ }
+ ],
+ "env": [
+ {
+ "name": "OPENSHIFT_DNS_PING_SERVICE_NAME",
+ "value": "${APPLICATION_NAME}-ping"
+ },
+ {
+ "name": "OPENSHIFT_DNS_PING_SERVICE_PORT",
+ "value": "8888"
+ },
+ {
+ "name": "EAP_HTTPS_KEYSTORE_DIR",
+ "value": "/etc/eap-secret-volume"
+ },
+ {
+ "name": "EAP_HTTPS_KEYSTORE",
+ "value": "${EAP_HTTPS_KEYSTORE}"
+ },
+ {
+ "name": "EAP_HTTPS_NAME",
+ "value": "${EAP_HTTPS_NAME}"
+ },
+ {
+ "name": "EAP_HTTPS_PASSWORD",
+ "value": "${EAP_HTTPS_PASSWORD}"
+ },
+ {
+ "name": "HORNETQ_CLUSTER_PASSWORD",
+ "value": "${HORNETQ_CLUSTER_PASSWORD}"
+ },
+ {
+ "name": "HORNETQ_QUEUES",
+ "value": "${HORNETQ_QUEUES}"
+ },
+ {
+ "name": "HORNETQ_TOPICS",
+ "value": "${HORNETQ_TOPICS}"
+ }
+ ]
+ }
+ ],
+ "volumes": [
+ {
+ "name": "eap-keystore-volume",
+ "secret": {
+ "secretName": "${EAP_HTTPS_SECRET}"
+ }
+ }
+ ]
+ }
+ }
+ }
+ }
+ ]
+}
diff --git a/roles/openshift_examples/files/examples/xpaas-templates/eap6-mongodb-persistent-sti.json b/roles/openshift_examples/files/examples/xpaas-templates/eap6-mongodb-persistent-sti.json
new file mode 100644
index 000000000..289ab284f
--- /dev/null
+++ b/roles/openshift_examples/files/examples/xpaas-templates/eap6-mongodb-persistent-sti.json
@@ -0,0 +1,645 @@
+{
+ "kind": "Template",
+ "apiVersion": "v1",
+ "metadata": {
+ "annotations": {
+ "description": "Application template for EAP 6 MongDB applications with persistent storage built using STI.",
+ "iconClass" : "icon-jboss"
+ },
+ "name": "eap6-mongodb-persistent-sti"
+ },
+ "labels": {
+ "template": "eap6-mongodb-persistent-sti"
+ },
+ "parameters": [
+ {
+ "description": "EAP Release version, e.g. 6.4, etc.",
+ "name": "EAP_RELEASE",
+ "value": "6.4"
+ },
+ {
+ "description": "The name for the application.",
+ "name": "APPLICATION_NAME",
+ "value": "eap-app"
+ },
+ {
+ "description": "Custom hostname for service routes. Leave blank for default hostname, e.g.: <application-name>.<project>.<default-domain-suffix>",
+ "name": "APPLICATION_HOSTNAME",
+ "value": ""
+ },
+ {
+ "description": "Git source URI for application",
+ "name": "GIT_URI"
+ },
+ {
+ "description": "Git branch/tag reference",
+ "name": "GIT_REF",
+ "value": "master"
+ },
+ {
+ "description": "Path within Git project to build; empty for root project directory.",
+ "name": "GIT_CONTEXT_DIR",
+ "value": ""
+ },
+ {
+ "description": "Database JNDI name used by application to resolve the datasource, e.g. java:/jboss/datasources/mongodb",
+ "name": "DB_JNDI",
+ "value": ""
+ },
+ {
+ "description": "Database name",
+ "name": "DB_DATABASE",
+ "value": "root"
+ },
+ {
+ "description": "Size of persistent storage for database volume.",
+ "name": "VOLUME_CAPACITY",
+ "value": "512Mi"
+ },
+ {
+ "description": "Queue names",
+ "name": "HORNETQ_QUEUES",
+ "value": ""
+ },
+ {
+ "description": "Topic names",
+ "name": "HORNETQ_TOPICS",
+ "value": ""
+ },
+ {
+ "description": "The name of the secret containing the keystore file",
+ "name": "EAP_HTTPS_SECRET",
+ "value": "eap-app-secret"
+ },
+ {
+ "description": "The name of the keystore file within the secret",
+ "name": "EAP_HTTPS_KEYSTORE",
+ "value": "keystore.jks"
+ },
+ {
+ "description": "The name associated with the server certificate",
+ "name": "EAP_HTTPS_NAME",
+ "value": ""
+ },
+ {
+ "description": "The password for the keystore and certificate",
+ "name": "EAP_HTTPS_PASSWORD",
+ "value": ""
+ },
+ {
+ "description": "Sets xa-pool/min-pool-size for the configured datasource.",
+ "name": "DB_MIN_POOL_SIZE"
+ },
+ {
+ "description": "Sets xa-pool/max-pool-size for the configured datasource.",
+ "name": "DB_MAX_POOL_SIZE"
+ },
+ {
+ "description": "Sets transaction-isolation for the configured datasource.",
+ "name": "DB_TX_ISOLATION"
+ },
+ {
+ "description": "Disable data file preallocation.",
+ "name": "MONGODB_NOPREALLOC"
+ },
+ {
+ "description": "Set MongoDB to use a smaller default data file size.",
+ "name": "MONGODB_SMALLFILES"
+ },
+ {
+ "description": "Runs MongoDB in a quiet mode that attempts to limit the amount of output.",
+ "name": "MONGODB_QUIET"
+ },
+ {
+ "description": "HornetQ cluster admin password",
+ "name": "HORNETQ_CLUSTER_PASSWORD",
+ "from": "[a-zA-Z0-9]{8}",
+ "generate": "expression"
+ },
+ {
+ "description": "Database user name",
+ "name": "DB_USERNAME",
+ "from": "user[a-zA-Z0-9]{3}",
+ "generate": "expression"
+ },
+ {
+ "description": "Database user password",
+ "name": "DB_PASSWORD",
+ "from": "[a-zA-Z0-9]{8}",
+ "generate": "expression"
+ },
+ {
+ "description": "Database admin password",
+ "name": "DB_ADMIN_PASSWORD",
+ "from": "[a-zA-Z0-9]{8}",
+ "generate": "expression"
+ },
+ {
+ "description": "Github trigger secret",
+ "name": "GITHUB_TRIGGER_SECRET",
+ "from": "[a-zA-Z0-9]{8}",
+ "generate": "expression"
+ },
+ {
+ "description": "Generic build trigger secret",
+ "name": "GENERIC_TRIGGER_SECRET",
+ "from": "[a-zA-Z0-9]{8}",
+ "generate": "expression"
+ }
+ ],
+ "objects": [
+ {
+ "kind": "Service",
+ "apiVersion": "v1",
+ "spec": {
+ "ports": [
+ {
+ "port": 8080,
+ "targetPort": 8080
+ }
+ ],
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}"
+ }
+ },
+ "metadata": {
+ "name": "${APPLICATION_NAME}",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "The web server's http port."
+ }
+ }
+ },
+ {
+ "kind": "Service",
+ "apiVersion": "v1",
+ "spec": {
+ "ports": [
+ {
+ "port": 8443,
+ "targetPort": 8443
+ }
+ ],
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}"
+ }
+ },
+ "metadata": {
+ "name": "secure-${APPLICATION_NAME}",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "The web server's https port."
+ }
+ }
+ },
+ {
+ "kind": "Service",
+ "apiVersion": "v1",
+ "spec": {
+ "ports": [
+ {
+ "port": 8888,
+ "targetPort": 8888
+ }
+ ],
+ "portalIP": "None",
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}"
+ }
+ },
+ "metadata": {
+ "name": "${APPLICATION_NAME}-ping",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "Ping service for clustered applications."
+ }
+ }
+ },
+ {
+ "kind": "Service",
+ "apiVersion": "v1",
+ "spec": {
+ "ports": [
+ {
+ "port": 27017,
+ "targetPort": 27017
+ }
+ ],
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}-mongodb"
+ }
+ },
+ "metadata": {
+ "name": "${APPLICATION_NAME}-mongodb",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "The database server's port."
+ }
+ }
+ },
+ {
+ "kind": "Route",
+ "apiVersion": "v1",
+ "id": "${APPLICATION_NAME}-http-route",
+ "metadata": {
+ "name": "${APPLICATION_NAME}-http-route",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "Route for application's http service."
+ }
+ },
+ "spec": {
+ "host": "${APPLICATION_HOSTNAME}",
+ "to": {
+ "name": "${APPLICATION_NAME}"
+ }
+ }
+ },
+ {
+ "kind": "Route",
+ "apiVersion": "v1",
+ "id": "${APPLICATION_NAME}-https-route",
+ "metadata": {
+ "name": "${APPLICATION_NAME}-https-route",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "Route for application's https service."
+ }
+ },
+ "spec": {
+ "host": "${APPLICATION_HOSTNAME}",
+ "to": {
+ "name": "secure-${APPLICATION_NAME}"
+ },
+ "tls": {
+ "termination" : "passthrough"
+ }
+ }
+ },
+ {
+ "kind": "ImageStream",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "${APPLICATION_NAME}",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ }
+ }
+ },
+ {
+ "kind": "BuildConfig",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "${APPLICATION_NAME}",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "source": {
+ "type": "Git",
+ "git": {
+ "uri": "${GIT_URI}",
+ "ref": "${GIT_REF}"
+ },
+ "contextDir":"${GIT_CONTEXT_DIR}"
+ },
+ "strategy": {
+ "type": "Source",
+ "sourceStrategy": {
+ "from": {
+ "kind": "ImageStreamTag",
+ "namespace": "openshift",
+ "name": "jboss-eap6-openshift:${EAP_RELEASE}"
+ }
+ }
+ },
+ "output": {
+ "to": {
+ "kind": "ImageStreamTag",
+ "name": "${APPLICATION_NAME}:latest"
+ }
+ },
+ "triggers": [
+ {
+ "type": "GitHub",
+ "github": {
+ "secret": "${GITHUB_TRIGGER_SECRET}"
+ }
+ },
+ {
+ "type": "Generic",
+ "generic": {
+ "secret": "${GENERIC_TRIGGER_SECRET}"
+ }
+ },
+ {
+ "type": "ImageChange",
+ "imageChange": {}
+ }
+ ]
+ }
+ },
+ {
+ "kind": "DeploymentConfig",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "${APPLICATION_NAME}",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "strategy": {
+ "type": "Recreate"
+ },
+ "triggers": [
+ {
+ "type": "ImageChange",
+ "imageChangeParams": {
+ "automatic": true,
+ "containerNames": [
+ "${APPLICATION_NAME}"
+ ],
+ "from": {
+ "kind": "ImageStream",
+ "name": "${APPLICATION_NAME}"
+ }
+ }
+ }
+ ],
+ "replicas": 1,
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}"
+ },
+ "template": {
+ "metadata": {
+ "name": "${APPLICATION_NAME}",
+ "labels": {
+ "deploymentConfig": "${APPLICATION_NAME}",
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "serviceAccount": "eap-service-account",
+ "containers": [
+ {
+ "name": "${APPLICATION_NAME}",
+ "image": "${APPLICATION_NAME}",
+ "imagePullPolicy": "Always",
+ "volumeMounts": [
+ {
+ "name": "eap-keystore-volume",
+ "mountPath": "/etc/eap-secret-volume",
+ "readOnly": true
+ }
+ ],
+ "readinessProbe": {
+ "exec": {
+ "command": [
+ "/bin/bash",
+ "-c",
+ "/opt/eap/bin/readinessProbe.sh"
+ ]
+ }
+ },
+ "ports": [
+ {
+ "name": "http",
+ "containerPort": 8080,
+ "protocol": "TCP"
+ },
+ {
+ "name": "https",
+ "containerPort": 8443,
+ "protocol": "TCP"
+ },
+ {
+ "name": "ping",
+ "containerPort": 8888,
+ "protocol": "TCP"
+ }
+ ],
+ "env": [
+ {
+ "name": "DB_SERVICE_PREFIX_MAPPING",
+ "value": "${APPLICATION_NAME}-mongodb=DB"
+ },
+ {
+ "name": "DB_JNDI",
+ "value": "${DB_JNDI}"
+ },
+ {
+ "name": "DB_USERNAME",
+ "value": "${DB_USERNAME}"
+ },
+ {
+ "name": "DB_PASSWORD",
+ "value": "${DB_PASSWORD}"
+ },
+ {
+ "name": "DB_DATABASE",
+ "value": "${DB_DATABASE}"
+ },
+ {
+ "name": "DB_ADMIN_PASSWORD",
+ "value": "${DB_ADMIN_PASSWORD}"
+ },
+ {
+ "name": "DB_MIN_POOL_SIZE",
+ "value": "${DB_MIN_POOL_SIZE}"
+ },
+ {
+ "name": "DB_MAX_POOL_SIZE",
+ "value": "${DB_MAX_POOL_SIZE}"
+ },
+ {
+ "name": "DB_TX_ISOLATION",
+ "value": "${DB_TX_ISOLATION}"
+ },
+ {
+ "name": "OPENSHIFT_DNS_PING_SERVICE_NAME",
+ "value": "${APPLICATION_NAME}-ping"
+ },
+ {
+ "name": "OPENSHIFT_DNS_PING_SERVICE_PORT",
+ "value": "8888"
+ },
+ {
+ "name": "EAP_HTTPS_KEYSTORE_DIR",
+ "value": "/etc/eap-secret-volume"
+ },
+ {
+ "name": "EAP_HTTPS_KEYSTORE",
+ "value": "${EAP_HTTPS_KEYSTORE}"
+ },
+ {
+ "name": "EAP_HTTPS_NAME",
+ "value": "${EAP_HTTPS_NAME}"
+ },
+ {
+ "name": "EAP_HTTPS_PASSWORD",
+ "value": "${EAP_HTTPS_PASSWORD}"
+ },
+ {
+ "name": "HORNETQ_CLUSTER_PASSWORD",
+ "value": "${HORNETQ_CLUSTER_PASSWORD}"
+ },
+ {
+ "name": "HORNETQ_QUEUES",
+ "value": "${HORNETQ_QUEUES}"
+ },
+ {
+ "name": "HORNETQ_TOPICS",
+ "value": "${HORNETQ_TOPICS}"
+ }
+ ]
+ }
+ ],
+ "volumes": [
+ {
+ "name": "eap-keystore-volume",
+ "secret": {
+ "secretName": "${EAP_HTTPS_SECRET}"
+ }
+ }
+ ]
+ }
+ }
+ }
+ },
+ {
+ "kind": "DeploymentConfig",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "${APPLICATION_NAME}-mongodb",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "strategy": {
+ "type": "Recreate"
+ },
+ "triggers": [
+ {
+ "type": "ImageChange",
+ "imageChangeParams": {
+ "automatic": true,
+ "containerNames": [
+ "${APPLICATION_NAME}-mongodb"
+ ],
+ "from": {
+ "kind": "ImageStreamTag",
+ "namespace": "openshift",
+ "name": "mongodb:latest"
+ }
+ }
+ }
+ ],
+ "replicas": 1,
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}-mongodb"
+ },
+ "template": {
+ "metadata": {
+ "name": "${APPLICATION_NAME}-mongodb",
+ "labels": {
+ "deploymentConfig": "${APPLICATION_NAME}-mongodb",
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "containers": [
+ {
+ "name": "${APPLICATION_NAME}-mongodb",
+ "image": "mongodb",
+ "imagePullPolicy": "Always",
+ "ports": [
+ {
+ "containerPort": 27017,
+ "protocol": "TCP"
+ }
+ ],
+ "volumeMounts": [
+ {
+ "mountPath": "/var/lib/mongodb/data",
+ "name": "${APPLICATION_NAME}-mongodb-pvol"
+ }
+ ],
+ "env": [
+ {
+ "name": "MONGODB_USER",
+ "value": "${DB_USERNAME}"
+ },
+ {
+ "name": "MONGODB_PASSWORD",
+ "value": "${DB_PASSWORD}"
+ },
+ {
+ "name": "MONGODB_DATABASE",
+ "value": "${DB_DATABASE}"
+ },
+ {
+ "name": "MONGODB_ADMIN_PASSWORD",
+ "value": "${DB_ADMIN_PASSWORD}"
+ },
+ {
+ "name": "MONGODB_NOPREALLOC",
+ "value": "${MONGODB_NOPREALLOC}"
+ },
+ {
+ "name": "MONGODB_SMALLFILES",
+ "value": "${MONGODB_SMALLFILES}"
+ },
+ {
+ "name": "MONGODB_QUIET",
+ "value": "${MONGODB_QUIET}"
+ }
+ ]
+ }
+ ],
+ "volumes": [
+ {
+ "name": "${APPLICATION_NAME}-mongodb-pvol",
+ "persistentVolumeClaim": {
+ "claimName": "${APPLICATION_NAME}-mongodb-claim"
+ }
+ }
+ ]
+ }
+ }
+ }
+ },
+ {
+ "apiVersion": "v1",
+ "kind": "PersistentVolumeClaim",
+ "metadata": {
+ "name": "${APPLICATION_NAME}-mongodb-claim",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "accessModes": [ "ReadWriteOnce" ],
+ "resources": {
+ "requests": {
+ "storage": "${VOLUME_CAPACITY}"
+ }
+ }
+ }
+ }
+ ]
+}
diff --git a/roles/openshift_examples/files/examples/xpaas-templates/eap6-mongodb-sti.json b/roles/openshift_examples/files/examples/xpaas-templates/eap6-mongodb-sti.json
new file mode 100644
index 000000000..22b301aa9
--- /dev/null
+++ b/roles/openshift_examples/files/examples/xpaas-templates/eap6-mongodb-sti.json
@@ -0,0 +1,608 @@
+{
+ "kind": "Template",
+ "apiVersion": "v1",
+ "metadata": {
+ "annotations": {
+ "description": "Application template for EAP 6 MongDB applications built using STI.",
+ "iconClass" : "icon-jboss"
+ },
+ "name": "eap6-mongodb-sti"
+ },
+ "labels": {
+ "template": "eap6-mongodb-sti"
+ },
+ "parameters": [
+ {
+ "description": "EAP Release version, e.g. 6.4, etc.",
+ "name": "EAP_RELEASE",
+ "value": "6.4"
+ },
+ {
+ "description": "The name for the application.",
+ "name": "APPLICATION_NAME",
+ "value": "eap-app"
+ },
+ {
+ "description": "Custom hostname for service routes. Leave blank for default hostname, e.g.: <application-name>.<project>.<default-domain-suffix>",
+ "name": "APPLICATION_HOSTNAME",
+ "value": ""
+ },
+ {
+ "description": "Git source URI for application",
+ "name": "GIT_URI"
+ },
+ {
+ "description": "Git branch/tag reference",
+ "name": "GIT_REF",
+ "value": "master"
+ },
+ {
+ "description": "Path within Git project to build; empty for root project directory.",
+ "name": "GIT_CONTEXT_DIR",
+ "value": ""
+ },
+ {
+ "description": "Database JNDI name used by application to resolve the datasource, e.g. java:/jboss/datasources/mongodb",
+ "name": "DB_JNDI",
+ "value": ""
+ },
+ {
+ "description": "Database name",
+ "name": "DB_DATABASE",
+ "value": "root"
+ },
+ {
+ "description": "Queue names",
+ "name": "HORNETQ_QUEUES",
+ "value": ""
+ },
+ {
+ "description": "Topic names",
+ "name": "HORNETQ_TOPICS",
+ "value": ""
+ },
+ {
+ "description": "The name of the secret containing the keystore file",
+ "name": "EAP_HTTPS_SECRET",
+ "value": "eap-app-secret"
+ },
+ {
+ "description": "The name of the keystore file within the secret",
+ "name": "EAP_HTTPS_KEYSTORE",
+ "value": "keystore.jks"
+ },
+ {
+ "description": "The name associated with the server certificate",
+ "name": "EAP_HTTPS_NAME",
+ "value": ""
+ },
+ {
+ "description": "The password for the keystore and certificate",
+ "name": "EAP_HTTPS_PASSWORD",
+ "value": ""
+ },
+ {
+ "description": "Sets xa-pool/min-pool-size for the configured datasource.",
+ "name": "DB_MIN_POOL_SIZE"
+ },
+ {
+ "description": "Sets xa-pool/max-pool-size for the configured datasource.",
+ "name": "DB_MAX_POOL_SIZE"
+ },
+ {
+ "description": "Sets transaction-isolation for the configured datasource.",
+ "name": "DB_TX_ISOLATION"
+ },
+ {
+ "description": "Disable data file preallocation.",
+ "name": "MONGODB_NOPREALLOC"
+ },
+ {
+ "description": "Set MongoDB to use a smaller default data file size.",
+ "name": "MONGODB_SMALLFILES"
+ },
+ {
+ "description": "Runs MongoDB in a quiet mode that attempts to limit the amount of output.",
+ "name": "MONGODB_QUIET"
+ },
+ {
+ "description": "HornetQ cluster admin password",
+ "name": "HORNETQ_CLUSTER_PASSWORD",
+ "from": "[a-zA-Z0-9]{8}",
+ "generate": "expression"
+ },
+ {
+ "description": "Database user name",
+ "name": "DB_USERNAME",
+ "from": "user[a-zA-Z0-9]{3}",
+ "generate": "expression"
+ },
+ {
+ "description": "Database user password",
+ "name": "DB_PASSWORD",
+ "from": "[a-zA-Z0-9]{8}",
+ "generate": "expression"
+ },
+ {
+ "description": "Database admin password",
+ "name": "DB_ADMIN_PASSWORD",
+ "from": "[a-zA-Z0-9]{8}",
+ "generate": "expression"
+ },
+ {
+ "description": "Github trigger secret",
+ "name": "GITHUB_TRIGGER_SECRET",
+ "from": "[a-zA-Z0-9]{8}",
+ "generate": "expression"
+ },
+ {
+ "description": "Generic build trigger secret",
+ "name": "GENERIC_TRIGGER_SECRET",
+ "from": "[a-zA-Z0-9]{8}",
+ "generate": "expression"
+ }
+ ],
+ "objects": [
+ {
+ "kind": "Service",
+ "apiVersion": "v1",
+ "spec": {
+ "ports": [
+ {
+ "port": 8080,
+ "targetPort": 8080
+ }
+ ],
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}"
+ }
+ },
+ "metadata": {
+ "name": "${APPLICATION_NAME}",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "The web server's http port."
+ }
+ }
+ },
+ {
+ "kind": "Service",
+ "apiVersion": "v1",
+ "spec": {
+ "ports": [
+ {
+ "port": 8443,
+ "targetPort": 8443
+ }
+ ],
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}"
+ }
+ },
+ "metadata": {
+ "name": "secure-${APPLICATION_NAME}",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "The web server's https port."
+ }
+ }
+ },
+ {
+ "kind": "Service",
+ "apiVersion": "v1",
+ "spec": {
+ "ports": [
+ {
+ "port": 8888,
+ "targetPort": 8888
+ }
+ ],
+ "portalIP": "None",
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}"
+ }
+ },
+ "metadata": {
+ "name": "${APPLICATION_NAME}-ping",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "Ping service for clustered applications."
+ }
+ }
+ },
+ {
+ "kind": "Service",
+ "apiVersion": "v1",
+ "spec": {
+ "ports": [
+ {
+ "port": 27017,
+ "targetPort": 27017
+ }
+ ],
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}-mongodb"
+ }
+ },
+ "metadata": {
+ "name": "${APPLICATION_NAME}-mongodb",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "The database server's port."
+ }
+ }
+ },
+ {
+ "kind": "Route",
+ "apiVersion": "v1",
+ "id": "${APPLICATION_NAME}-http-route",
+ "metadata": {
+ "name": "${APPLICATION_NAME}-http-route",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "Route for application's http service."
+ }
+ },
+ "spec": {
+ "host": "${APPLICATION_HOSTNAME}",
+ "to": {
+ "name": "${APPLICATION_NAME}"
+ }
+ }
+ },
+ {
+ "kind": "Route",
+ "apiVersion": "v1",
+ "id": "${APPLICATION_NAME}-https-route",
+ "metadata": {
+ "name": "${APPLICATION_NAME}-https-route",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "Route for application's https service."
+ }
+ },
+ "spec": {
+ "host": "${APPLICATION_HOSTNAME}",
+ "to": {
+ "name": "secure-${APPLICATION_NAME}"
+ },
+ "tls": {
+ "termination" : "passthrough"
+ }
+ }
+ },
+ {
+ "kind": "ImageStream",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "${APPLICATION_NAME}",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ }
+ }
+ },
+ {
+ "kind": "BuildConfig",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "${APPLICATION_NAME}",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "source": {
+ "type": "Git",
+ "git": {
+ "uri": "${GIT_URI}",
+ "ref": "${GIT_REF}"
+ },
+ "contextDir":"${GIT_CONTEXT_DIR}"
+ },
+ "strategy": {
+ "type": "Source",
+ "sourceStrategy": {
+ "from": {
+ "kind": "ImageStreamTag",
+ "namespace": "openshift",
+ "name": "jboss-eap6-openshift:${EAP_RELEASE}"
+ }
+ }
+ },
+ "output": {
+ "to": {
+ "kind": "ImageStreamTag",
+ "name": "${APPLICATION_NAME}:latest"
+ }
+ },
+ "triggers": [
+ {
+ "type": "GitHub",
+ "github": {
+ "secret": "${GITHUB_TRIGGER_SECRET}"
+ }
+ },
+ {
+ "type": "Generic",
+ "generic": {
+ "secret": "${GENERIC_TRIGGER_SECRET}"
+ }
+ },
+ {
+ "type": "ImageChange",
+ "imageChange": {}
+ }
+ ]
+ }
+ },
+ {
+ "kind": "DeploymentConfig",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "${APPLICATION_NAME}",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "strategy": {
+ "type": "Recreate"
+ },
+ "triggers": [
+ {
+ "type": "ImageChange",
+ "imageChangeParams": {
+ "automatic": true,
+ "containerNames": [
+ "${APPLICATION_NAME}"
+ ],
+ "from": {
+ "kind": "ImageStream",
+ "name": "${APPLICATION_NAME}"
+ }
+ }
+ }
+ ],
+ "replicas": 1,
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}"
+ },
+ "template": {
+ "metadata": {
+ "name": "${APPLICATION_NAME}",
+ "labels": {
+ "deploymentConfig": "${APPLICATION_NAME}",
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "serviceAccount": "eap-service-account",
+ "containers": [
+ {
+ "name": "${APPLICATION_NAME}",
+ "image": "${APPLICATION_NAME}",
+ "imagePullPolicy": "Always",
+ "volumeMounts": [
+ {
+ "name": "eap-keystore-volume",
+ "mountPath": "/etc/eap-secret-volume",
+ "readOnly": true
+ }
+ ],
+ "readinessProbe": {
+ "exec": {
+ "command": [
+ "/bin/bash",
+ "-c",
+ "/opt/eap/bin/readinessProbe.sh"
+ ]
+ }
+ },
+ "ports": [
+ {
+ "name": "http",
+ "containerPort": 8080,
+ "protocol": "TCP"
+ },
+ {
+ "name": "https",
+ "containerPort": 8443,
+ "protocol": "TCP"
+ },
+ {
+ "name": "ping",
+ "containerPort": 8888,
+ "protocol": "TCP"
+ }
+ ],
+ "env": [
+ {
+ "name": "DB_SERVICE_PREFIX_MAPPING",
+ "value": "${APPLICATION_NAME}-mongodb=DB"
+ },
+ {
+ "name": "DB_JNDI",
+ "value": "${DB_JNDI}"
+ },
+ {
+ "name": "DB_USERNAME",
+ "value": "${DB_USERNAME}"
+ },
+ {
+ "name": "DB_PASSWORD",
+ "value": "${DB_PASSWORD}"
+ },
+ {
+ "name": "DB_DATABASE",
+ "value": "${DB_DATABASE}"
+ },
+ {
+ "name": "DB_ADMIN_PASSWORD",
+ "value": "${DB_ADMIN_PASSWORD}"
+ },
+ {
+ "name": "DB_MIN_POOL_SIZE",
+ "value": "${DB_MIN_POOL_SIZE}"
+ },
+ {
+ "name": "DB_MAX_POOL_SIZE",
+ "value": "${DB_MAX_POOL_SIZE}"
+ },
+ {
+ "name": "DB_TX_ISOLATION",
+ "value": "${DB_TX_ISOLATION}"
+ },
+ {
+ "name": "OPENSHIFT_DNS_PING_SERVICE_NAME",
+ "value": "${APPLICATION_NAME}-ping"
+ },
+ {
+ "name": "OPENSHIFT_DNS_PING_SERVICE_PORT",
+ "value": "8888"
+ },
+ {
+ "name": "EAP_HTTPS_KEYSTORE_DIR",
+ "value": "/etc/eap-secret-volume"
+ },
+ {
+ "name": "EAP_HTTPS_KEYSTORE",
+ "value": "${EAP_HTTPS_KEYSTORE}"
+ },
+ {
+ "name": "EAP_HTTPS_NAME",
+ "value": "${EAP_HTTPS_NAME}"
+ },
+ {
+ "name": "EAP_HTTPS_PASSWORD",
+ "value": "${EAP_HTTPS_PASSWORD}"
+ },
+ {
+ "name": "HORNETQ_CLUSTER_PASSWORD",
+ "value": "${HORNETQ_CLUSTER_PASSWORD}"
+ },
+ {
+ "name": "HORNETQ_QUEUES",
+ "value": "${HORNETQ_QUEUES}"
+ },
+ {
+ "name": "HORNETQ_TOPICS",
+ "value": "${HORNETQ_TOPICS}"
+ }
+ ]
+ }
+ ],
+ "volumes": [
+ {
+ "name": "eap-keystore-volume",
+ "secret": {
+ "secretName": "${EAP_HTTPS_SECRET}"
+ }
+ }
+ ]
+ }
+ }
+ }
+ },
+ {
+ "kind": "DeploymentConfig",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "${APPLICATION_NAME}-mongodb",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "strategy": {
+ "type": "Recreate"
+ },
+ "triggers": [
+ {
+ "type": "ImageChange",
+ "imageChangeParams": {
+ "automatic": true,
+ "containerNames": [
+ "${APPLICATION_NAME}-mongodb"
+ ],
+ "from": {
+ "kind": "ImageStreamTag",
+ "namespace": "openshift",
+ "name": "mongodb:latest"
+ }
+ }
+ }
+ ],
+ "replicas": 1,
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}-mongodb"
+ },
+ "template": {
+ "metadata": {
+ "name": "${APPLICATION_NAME}-mongodb",
+ "labels": {
+ "deploymentConfig": "${APPLICATION_NAME}-mongodb",
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "containers": [
+ {
+ "name": "${APPLICATION_NAME}-mongodb",
+ "image": "mongodb",
+ "imagePullPolicy": "Always",
+ "ports": [
+ {
+ "containerPort": 27017,
+ "protocol": "TCP"
+ }
+ ],
+ "env": [
+ {
+ "name": "MONGODB_USER",
+ "value": "${DB_USERNAME}"
+ },
+ {
+ "name": "MONGODB_PASSWORD",
+ "value": "${DB_PASSWORD}"
+ },
+ {
+ "name": "MONGODB_DATABASE",
+ "value": "${DB_DATABASE}"
+ },
+ {
+ "name": "MONGODB_ADMIN_PASSWORD",
+ "value": "${DB_ADMIN_PASSWORD}"
+ },
+ {
+ "name": "MONGODB_NOPREALLOC",
+ "value": "${MONGODB_NOPREALLOC}"
+ },
+ {
+ "name": "MONGODB_SMALLFILES",
+ "value": "${MONGODB_SMALLFILES}"
+ },
+ {
+ "name": "MONGODB_QUIET",
+ "value": "${MONGODB_QUIET}"
+ }
+ ]
+ }
+ ]
+ }
+ }
+ }
+ }
+ ]
+}
diff --git a/roles/openshift_examples/files/examples/xpaas-templates/eap6-mysql-persistent-sti.json b/roles/openshift_examples/files/examples/xpaas-templates/eap6-mysql-persistent-sti.json
new file mode 100644
index 000000000..648a53199
--- /dev/null
+++ b/roles/openshift_examples/files/examples/xpaas-templates/eap6-mysql-persistent-sti.json
@@ -0,0 +1,651 @@
+{
+ "kind": "Template",
+ "apiVersion": "v1",
+ "metadata": {
+ "annotations": {
+ "description": "Application template for EAP 6 MySQL applications with persistent storage built using STI.",
+ "iconClass" : "icon-jboss"
+ },
+ "name": "eap6-mysql-persistent-sti"
+ },
+ "labels": {
+ "template": "eap6-mysql-persistent-sti"
+ },
+ "parameters": [
+ {
+ "description": "EAP Release version, e.g. 6.4, etc.",
+ "name": "EAP_RELEASE",
+ "value": "6.4"
+ },
+ {
+ "description": "The name for the application.",
+ "name": "APPLICATION_NAME",
+ "value": "eap-app"
+ },
+ {
+ "description": "Custom hostname for service routes. Leave blank for default hostname, e.g.: <application-name>.<project>.<default-domain-suffix>",
+ "name": "APPLICATION_HOSTNAME",
+ "value": ""
+ },
+ {
+ "description": "Git source URI for application",
+ "name": "GIT_URI"
+ },
+ {
+ "description": "Git branch/tag reference",
+ "name": "GIT_REF",
+ "value": "master"
+ },
+ {
+ "description": "Path within Git project to build; empty for root project directory.",
+ "name": "GIT_CONTEXT_DIR",
+ "value": ""
+ },
+ {
+ "description": "Database JNDI name used by application to resolve the datasource, e.g. java:/jboss/datasources/mysql",
+ "name": "DB_JNDI",
+ "value": ""
+ },
+ {
+ "description": "Database name",
+ "name": "DB_DATABASE",
+ "value": "root"
+ },
+ {
+ "description": "Size of persistent storage for database volume.",
+ "name": "VOLUME_CAPACITY",
+ "value": "512Mi"
+ },
+ {
+ "description": "Queue names",
+ "name": "HORNETQ_QUEUES",
+ "value": ""
+ },
+ {
+ "description": "Topic names",
+ "name": "HORNETQ_TOPICS",
+ "value": ""
+ },
+ {
+ "description": "The name of the secret containing the keystore file",
+ "name": "EAP_HTTPS_SECRET",
+ "value": "eap-app-secret"
+ },
+ {
+ "description": "The name of the keystore file within the secret",
+ "name": "EAP_HTTPS_KEYSTORE",
+ "value": "keystore.jks"
+ },
+ {
+ "description": "The name associated with the server certificate",
+ "name": "EAP_HTTPS_NAME",
+ "value": ""
+ },
+ {
+ "description": "The password for the keystore and certificate",
+ "name": "EAP_HTTPS_PASSWORD",
+ "value": ""
+ },
+ {
+ "description": "Sets xa-pool/min-pool-size for the configured datasource.",
+ "name": "DB_MIN_POOL_SIZE"
+ },
+ {
+ "description": "Sets xa-pool/max-pool-size for the configured datasource.",
+ "name": "DB_MAX_POOL_SIZE"
+ },
+ {
+ "description": "Sets transaction-isolation for the configured datasource.",
+ "name": "DB_TX_ISOLATION"
+ },
+ {
+ "description": "Sets how the table names are stored and compared.",
+ "name": "MYSQL_LOWER_CASE_TABLE_NAMES"
+ },
+ {
+ "description": "The maximum permitted number of simultaneous client connections.",
+ "name": "MYSQL_MAX_CONNECTIONS"
+ },
+ {
+ "description": "The minimum length of the word to be included in a FULLTEXT index.",
+ "name": "MYSQL_FT_MIN_WORD_LEN"
+ },
+ {
+ "description": "The maximum length of the word to be included in a FULLTEXT index.",
+ "name": "MYSQL_FT_MAX_WORD_LEN"
+ },
+ {
+ "description": "Controls the innodb_use_native_aio setting value if the native AIO is broken.",
+ "name": "MYSQL_AIO"
+ },
+ {
+ "description": "HornetQ cluster admin password",
+ "name": "HORNETQ_CLUSTER_PASSWORD",
+ "from": "[a-zA-Z0-9]{8}",
+ "generate": "expression"
+ },
+ {
+ "description": "Database user name",
+ "name": "DB_USERNAME",
+ "from": "user[a-zA-Z0-9]{3}",
+ "generate": "expression"
+ },
+ {
+ "description": "Database user password",
+ "name": "DB_PASSWORD",
+ "from": "[a-zA-Z0-9]{8}",
+ "generate": "expression"
+ },
+ {
+ "description": "Github trigger secret",
+ "name": "GITHUB_TRIGGER_SECRET",
+ "from": "[a-zA-Z0-9]{8}",
+ "generate": "expression"
+ },
+ {
+ "description": "Generic build trigger secret",
+ "name": "GENERIC_TRIGGER_SECRET",
+ "from": "[a-zA-Z0-9]{8}",
+ "generate": "expression"
+ }
+ ],
+ "objects": [
+ {
+ "kind": "Service",
+ "apiVersion": "v1",
+ "spec": {
+ "ports": [
+ {
+ "port": 8080,
+ "targetPort": 8080
+ }
+ ],
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}"
+ }
+ },
+ "metadata": {
+ "name": "${APPLICATION_NAME}",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "The web server's http port."
+ }
+ }
+ },
+ {
+ "kind": "Service",
+ "apiVersion": "v1",
+ "spec": {
+ "ports": [
+ {
+ "port": 8443,
+ "targetPort": 8443
+ }
+ ],
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}"
+ }
+ },
+ "metadata": {
+ "name": "secure-${APPLICATION_NAME}",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "The web server's https port."
+ }
+ }
+ },
+ {
+ "kind": "Service",
+ "apiVersion": "v1",
+ "spec": {
+ "ports": [
+ {
+ "port": 8888,
+ "targetPort": 8888
+ }
+ ],
+ "portalIP": "None",
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}"
+ }
+ },
+ "metadata": {
+ "name": "${APPLICATION_NAME}-ping",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "Ping service for clustered applications."
+ }
+ }
+ },
+ {
+ "kind": "Service",
+ "apiVersion": "v1",
+ "spec": {
+ "ports": [
+ {
+ "port": 3306,
+ "targetPort": 3306
+ }
+ ],
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}-mysql"
+ }
+ },
+ "metadata": {
+ "name": "${APPLICATION_NAME}-mysql",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "The database server's port."
+ }
+ }
+ },
+ {
+ "kind": "Route",
+ "apiVersion": "v1",
+ "id": "${APPLICATION_NAME}-http-route",
+ "metadata": {
+ "name": "${APPLICATION_NAME}-http-route",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "Route for application's http service."
+ }
+ },
+ "spec": {
+ "host": "${APPLICATION_HOSTNAME}",
+ "to": {
+ "name": "${APPLICATION_NAME}"
+ }
+ }
+ },
+ {
+ "kind": "Route",
+ "apiVersion": "v1",
+ "id": "${APPLICATION_NAME}-https-route",
+ "metadata": {
+ "name": "${APPLICATION_NAME}-https-route",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "Route for application's https service."
+ }
+ },
+ "spec": {
+ "host": "${APPLICATION_HOSTNAME}",
+ "to": {
+ "name": "secure-${APPLICATION_NAME}"
+ },
+ "tls": {
+ "termination" : "passthrough"
+ }
+ }
+ },
+ {
+ "kind": "ImageStream",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "${APPLICATION_NAME}",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ }
+ }
+ },
+ {
+ "kind": "BuildConfig",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "${APPLICATION_NAME}",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "source": {
+ "type": "Git",
+ "git": {
+ "uri": "${GIT_URI}",
+ "ref": "${GIT_REF}"
+ },
+ "contextDir":"${GIT_CONTEXT_DIR}"
+ },
+ "strategy": {
+ "type": "Source",
+ "sourceStrategy": {
+ "from": {
+ "kind": "ImageStreamTag",
+ "namespace": "openshift",
+ "name": "jboss-eap6-openshift:${EAP_RELEASE}"
+ }
+ }
+ },
+ "output": {
+ "to": {
+ "kind": "ImageStreamTag",
+ "name": "${APPLICATION_NAME}:latest"
+ }
+ },
+ "triggers": [
+ {
+ "type": "GitHub",
+ "github": {
+ "secret": "${GITHUB_TRIGGER_SECRET}"
+ }
+ },
+ {
+ "type": "Generic",
+ "generic": {
+ "secret": "${GENERIC_TRIGGER_SECRET}"
+ }
+ },
+ {
+ "type": "ImageChange",
+ "imageChange": {}
+ }
+ ]
+ }
+ },
+ {
+ "kind": "DeploymentConfig",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "${APPLICATION_NAME}",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "strategy": {
+ "type": "Recreate"
+ },
+ "triggers": [
+ {
+ "type": "ImageChange",
+ "imageChangeParams": {
+ "automatic": true,
+ "containerNames": [
+ "${APPLICATION_NAME}"
+ ],
+ "from": {
+ "kind": "ImageStream",
+ "name": "${APPLICATION_NAME}"
+ }
+ }
+ }
+ ],
+ "replicas": 1,
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}"
+ },
+ "template": {
+ "metadata": {
+ "name": "${APPLICATION_NAME}",
+ "labels": {
+ "deploymentConfig": "${APPLICATION_NAME}",
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "serviceAccount": "eap-service-account",
+ "containers": [
+ {
+ "name": "${APPLICATION_NAME}",
+ "image": "${APPLICATION_NAME}",
+ "imagePullPolicy": "Always",
+ "volumeMounts": [
+ {
+ "name": "eap-keystore-volume",
+ "mountPath": "/etc/eap-secret-volume",
+ "readOnly": true
+ }
+ ],
+ "readinessProbe": {
+ "exec": {
+ "command": [
+ "/bin/bash",
+ "-c",
+ "/opt/eap/bin/readinessProbe.sh"
+ ]
+ }
+ },
+ "ports": [
+ {
+ "name": "http",
+ "containerPort": 8080,
+ "protocol": "TCP"
+ },
+ {
+ "name": "https",
+ "containerPort": 8443,
+ "protocol": "TCP"
+ },
+ {
+ "name": "ping",
+ "containerPort": 8888,
+ "protocol": "TCP"
+ }
+ ],
+ "env": [
+ {
+ "name": "DB_SERVICE_PREFIX_MAPPING",
+ "value": "${APPLICATION_NAME}-mysql=DB"
+ },
+ {
+ "name": "DB_JNDI",
+ "value": "${DB_JNDI}"
+ },
+ {
+ "name": "DB_USERNAME",
+ "value": "${DB_USERNAME}"
+ },
+ {
+ "name": "DB_PASSWORD",
+ "value": "${DB_PASSWORD}"
+ },
+ {
+ "name": "DB_DATABASE",
+ "value": "${DB_DATABASE}"
+ },
+ {
+ "name": "TX_DATABASE_PREFIX_MAPPING",
+ "value": "${APPLICATION_NAME}-mysql=DB"
+ },
+ {
+ "name": "DB_MIN_POOL_SIZE",
+ "value": "${DB_MIN_POOL_SIZE}"
+ },
+ {
+ "name": "DB_MAX_POOL_SIZE",
+ "value": "${DB_MAX_POOL_SIZE}"
+ },
+ {
+ "name": "DB_TX_ISOLATION",
+ "value": "${DB_TX_ISOLATION}"
+ },
+ {
+ "name": "OPENSHIFT_DNS_PING_SERVICE_NAME",
+ "value": "${APPLICATION_NAME}-ping"
+ },
+ {
+ "name": "OPENSHIFT_DNS_PING_SERVICE_PORT",
+ "value": "8888"
+ },
+ {
+ "name": "EAP_HTTPS_KEYSTORE_DIR",
+ "value": "/etc/eap-secret-volume"
+ },
+ {
+ "name": "EAP_HTTPS_KEYSTORE",
+ "value": "${EAP_HTTPS_KEYSTORE}"
+ },
+ {
+ "name": "EAP_HTTPS_NAME",
+ "value": "${EAP_HTTPS_NAME}"
+ },
+ {
+ "name": "EAP_HTTPS_PASSWORD",
+ "value": "${EAP_HTTPS_PASSWORD}"
+ },
+ {
+ "name": "HORNETQ_CLUSTER_PASSWORD",
+ "value": "${HORNETQ_CLUSTER_PASSWORD}"
+ },
+ {
+ "name": "HORNETQ_QUEUES",
+ "value": "${HORNETQ_QUEUES}"
+ },
+ {
+ "name": "HORNETQ_TOPICS",
+ "value": "${HORNETQ_TOPICS}"
+ }
+ ]
+ }
+ ],
+ "volumes": [
+ {
+ "name": "eap-keystore-volume",
+ "secret": {
+ "secretName": "${EAP_HTTPS_SECRET}"
+ }
+ }
+ ]
+ }
+ }
+ }
+ },
+ {
+ "kind": "DeploymentConfig",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "${APPLICATION_NAME}-mysql",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "strategy": {
+ "type": "Recreate"
+ },
+ "triggers": [
+ {
+ "type": "ImageChange",
+ "imageChangeParams": {
+ "automatic": true,
+ "containerNames": [
+ "${APPLICATION_NAME}-mysql"
+ ],
+ "from": {
+ "kind": "ImageStreamTag",
+ "namespace": "openshift",
+ "name": "mysql:latest"
+ }
+ }
+ }
+ ],
+ "replicas": 1,
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}-mysql"
+ },
+ "template": {
+ "metadata": {
+ "name": "${APPLICATION_NAME}-mysql",
+ "labels": {
+ "deploymentConfig": "${APPLICATION_NAME}-mysql",
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "containers": [
+ {
+ "name": "${APPLICATION_NAME}-mysql",
+ "image": "mysql",
+ "imagePullPolicy": "Always",
+ "ports": [
+ {
+ "containerPort": 3306,
+ "protocol": "TCP"
+ }
+ ],
+ "volumeMounts": [
+ {
+ "mountPath": "/var/lib/mysql/data",
+ "name": "${APPLICATION_NAME}-mysql-pvol"
+ }
+ ],
+ "env": [
+ {
+ "name": "MYSQL_USER",
+ "value": "${DB_USERNAME}"
+ },
+ {
+ "name": "MYSQL_PASSWORD",
+ "value": "${DB_PASSWORD}"
+ },
+ {
+ "name": "MYSQL_DATABASE",
+ "value": "${DB_DATABASE}"
+ },
+ {
+ "name": "MYSQL_LOWER_CASE_TABLE_NAMES",
+ "value": "${MYSQL_LOWER_CASE_TABLE_NAMES}"
+ },
+ {
+ "name": "MYSQL_MAX_CONNECTIONS",
+ "value": "${MYSQL_MAX_CONNECTIONS}"
+ },
+ {
+ "name": "MYSQL_FT_MIN_WORD_LEN",
+ "value": "${MYSQL_FT_MIN_WORD_LEN}"
+ },
+ {
+ "name": "MYSQL_FT_MAX_WORD_LEN",
+ "value": "${MYSQL_FT_MAX_WORD_LEN}"
+ },
+ {
+ "name": "MYSQL_AIO",
+ "value": "${MYSQL_AIO}"
+ }
+ ]
+ }
+ ],
+ "volumes": [
+ {
+ "name": "${APPLICATION_NAME}-mysql-pvol",
+ "persistentVolumeClaim": {
+ "claimName": "${APPLICATION_NAME}-mysql-claim"
+ }
+ }
+ ]
+ }
+ }
+ }
+ },
+ {
+ "apiVersion": "v1",
+ "kind": "PersistentVolumeClaim",
+ "metadata": {
+ "name": "${APPLICATION_NAME}-mysql-claim",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "accessModes": [ "ReadWriteOnce" ],
+ "resources": {
+ "requests": {
+ "storage": "${VOLUME_CAPACITY}"
+ }
+ }
+ }
+ }
+ ]
+}
diff --git a/roles/openshift_examples/files/examples/xpaas-templates/eap6-mysql-sti.json b/roles/openshift_examples/files/examples/xpaas-templates/eap6-mysql-sti.json
new file mode 100644
index 000000000..83d5c8b18
--- /dev/null
+++ b/roles/openshift_examples/files/examples/xpaas-templates/eap6-mysql-sti.json
@@ -0,0 +1,614 @@
+{
+ "kind": "Template",
+ "apiVersion": "v1",
+ "metadata": {
+ "annotations": {
+ "description": "Application template for EAP 6 MySQL applications built using STI.",
+ "iconClass" : "icon-jboss"
+ },
+ "name": "eap6-mysql-sti"
+ },
+ "labels": {
+ "template": "eap6-mysql-sti"
+ },
+ "parameters": [
+ {
+ "description": "EAP Release version, e.g. 6.4, etc.",
+ "name": "EAP_RELEASE",
+ "value": "6.4"
+ },
+ {
+ "description": "The name for the application.",
+ "name": "APPLICATION_NAME",
+ "value": "eap-app"
+ },
+ {
+ "description": "Custom hostname for service routes. Leave blank for default hostname, e.g.: <application-name>.<project>.<default-domain-suffix>",
+ "name": "APPLICATION_HOSTNAME",
+ "value": ""
+ },
+ {
+ "description": "Git source URI for application",
+ "name": "GIT_URI"
+ },
+ {
+ "description": "Git branch/tag reference",
+ "name": "GIT_REF",
+ "value": "master"
+ },
+ {
+ "description": "Path within Git project to build; empty for root project directory.",
+ "name": "GIT_CONTEXT_DIR",
+ "value": ""
+ },
+ {
+ "description": "Database JNDI name used by application to resolve the datasource, e.g. java:/jboss/datasources/mysql",
+ "name": "DB_JNDI",
+ "value": ""
+ },
+ {
+ "description": "Database name",
+ "name": "DB_DATABASE",
+ "value": "root"
+ },
+ {
+ "description": "Queue names",
+ "name": "HORNETQ_QUEUES",
+ "value": ""
+ },
+ {
+ "description": "Topic names",
+ "name": "HORNETQ_TOPICS",
+ "value": ""
+ },
+ {
+ "description": "The name of the secret containing the keystore file",
+ "name": "EAP_HTTPS_SECRET",
+ "value": "eap-app-secret"
+ },
+ {
+ "description": "The name of the keystore file within the secret",
+ "name": "EAP_HTTPS_KEYSTORE",
+ "value": "keystore.jks"
+ },
+ {
+ "description": "The name associated with the server certificate",
+ "name": "EAP_HTTPS_NAME",
+ "value": ""
+ },
+ {
+ "description": "The password for the keystore and certificate",
+ "name": "EAP_HTTPS_PASSWORD",
+ "value": ""
+ },
+ {
+ "description": "Sets xa-pool/min-pool-size for the configured datasource.",
+ "name": "DB_MIN_POOL_SIZE"
+ },
+ {
+ "description": "Sets xa-pool/max-pool-size for the configured datasource.",
+ "name": "DB_MAX_POOL_SIZE"
+ },
+ {
+ "description": "Sets transaction-isolation for the configured datasource.",
+ "name": "DB_TX_ISOLATION"
+ },
+ {
+ "description": "Sets how the table names are stored and compared.",
+ "name": "MYSQL_LOWER_CASE_TABLE_NAMES"
+ },
+ {
+ "description": "The maximum permitted number of simultaneous client connections.",
+ "name": "MYSQL_MAX_CONNECTIONS"
+ },
+ {
+ "description": "The minimum length of the word to be included in a FULLTEXT index.",
+ "name": "MYSQL_FT_MIN_WORD_LEN"
+ },
+ {
+ "description": "The maximum length of the word to be included in a FULLTEXT index.",
+ "name": "MYSQL_FT_MAX_WORD_LEN"
+ },
+ {
+ "description": "Controls the innodb_use_native_aio setting value if the native AIO is broken.",
+ "name": "MYSQL_AIO"
+ },
+ {
+ "description": "HornetQ cluster admin password",
+ "name": "HORNETQ_CLUSTER_PASSWORD",
+ "from": "[a-zA-Z0-9]{8}",
+ "generate": "expression"
+ },
+ {
+ "description": "Database user name",
+ "name": "DB_USERNAME",
+ "from": "user[a-zA-Z0-9]{3}",
+ "generate": "expression"
+ },
+ {
+ "description": "Database user password",
+ "name": "DB_PASSWORD",
+ "from": "[a-zA-Z0-9]{8}",
+ "generate": "expression"
+ },
+ {
+ "description": "Github trigger secret",
+ "name": "GITHUB_TRIGGER_SECRET",
+ "from": "[a-zA-Z0-9]{8}",
+ "generate": "expression"
+ },
+ {
+ "description": "Generic build trigger secret",
+ "name": "GENERIC_TRIGGER_SECRET",
+ "from": "[a-zA-Z0-9]{8}",
+ "generate": "expression"
+ }
+ ],
+ "objects": [
+ {
+ "kind": "Service",
+ "apiVersion": "v1",
+ "spec": {
+ "ports": [
+ {
+ "port": 8080,
+ "targetPort": 8080
+ }
+ ],
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}"
+ }
+ },
+ "metadata": {
+ "name": "${APPLICATION_NAME}",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "The web server's http port."
+ }
+ }
+ },
+ {
+ "kind": "Service",
+ "apiVersion": "v1",
+ "spec": {
+ "ports": [
+ {
+ "port": 8443,
+ "targetPort": 8443
+ }
+ ],
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}"
+ }
+ },
+ "metadata": {
+ "name": "secure-${APPLICATION_NAME}",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "The web server's https port."
+ }
+ }
+ },
+ {
+ "kind": "Service",
+ "apiVersion": "v1",
+ "spec": {
+ "ports": [
+ {
+ "port": 8888,
+ "targetPort": 8888
+ }
+ ],
+ "portalIP": "None",
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}"
+ }
+ },
+ "metadata": {
+ "name": "${APPLICATION_NAME}-ping",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "Ping service for clustered applications."
+ }
+ }
+ },
+ {
+ "kind": "Service",
+ "apiVersion": "v1",
+ "spec": {
+ "ports": [
+ {
+ "port": 3306,
+ "targetPort": 3306
+ }
+ ],
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}-mysql"
+ }
+ },
+ "metadata": {
+ "name": "${APPLICATION_NAME}-mysql",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "The database server's port."
+ }
+ }
+ },
+ {
+ "kind": "Route",
+ "apiVersion": "v1",
+ "id": "${APPLICATION_NAME}-http-route",
+ "metadata": {
+ "name": "${APPLICATION_NAME}-http-route",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "Route for application's http service."
+ }
+ },
+ "spec": {
+ "host": "${APPLICATION_HOSTNAME}",
+ "to": {
+ "name": "${APPLICATION_NAME}"
+ }
+ }
+ },
+ {
+ "kind": "Route",
+ "apiVersion": "v1",
+ "id": "${APPLICATION_NAME}-https-route",
+ "metadata": {
+ "name": "${APPLICATION_NAME}-https-route",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "Route for application's https service."
+ }
+ },
+ "spec": {
+ "host": "${APPLICATION_HOSTNAME}",
+ "to": {
+ "name": "secure-${APPLICATION_NAME}"
+ },
+ "tls": {
+ "termination" : "passthrough"
+ }
+ }
+ },
+ {
+ "kind": "ImageStream",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "${APPLICATION_NAME}",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ }
+ }
+ },
+ {
+ "kind": "BuildConfig",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "${APPLICATION_NAME}",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "source": {
+ "type": "Git",
+ "git": {
+ "uri": "${GIT_URI}",
+ "ref": "${GIT_REF}"
+ },
+ "contextDir":"${GIT_CONTEXT_DIR}"
+ },
+ "strategy": {
+ "type": "Source",
+ "sourceStrategy": {
+ "from": {
+ "kind": "ImageStreamTag",
+ "namespace": "openshift",
+ "name": "jboss-eap6-openshift:${EAP_RELEASE}"
+ }
+ }
+ },
+ "output": {
+ "to": {
+ "kind": "ImageStreamTag",
+ "name": "${APPLICATION_NAME}:latest"
+ }
+ },
+ "triggers": [
+ {
+ "type": "GitHub",
+ "github": {
+ "secret": "${GITHUB_TRIGGER_SECRET}"
+ }
+ },
+ {
+ "type": "Generic",
+ "generic": {
+ "secret": "${GENERIC_TRIGGER_SECRET}"
+ }
+ },
+ {
+ "type": "ImageChange",
+ "imageChange": {}
+ }
+ ]
+ }
+ },
+ {
+ "kind": "DeploymentConfig",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "${APPLICATION_NAME}",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "strategy": {
+ "type": "Recreate"
+ },
+ "triggers": [
+ {
+ "type": "ImageChange",
+ "imageChangeParams": {
+ "automatic": true,
+ "containerNames": [
+ "${APPLICATION_NAME}"
+ ],
+ "from": {
+ "kind": "ImageStream",
+ "name": "${APPLICATION_NAME}"
+ }
+ }
+ }
+ ],
+ "replicas": 1,
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}"
+ },
+ "template": {
+ "metadata": {
+ "name": "${APPLICATION_NAME}",
+ "labels": {
+ "deploymentConfig": "${APPLICATION_NAME}",
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "serviceAccount": "eap-service-account",
+ "containers": [
+ {
+ "name": "${APPLICATION_NAME}",
+ "image": "${APPLICATION_NAME}",
+ "imagePullPolicy": "Always",
+ "volumeMounts": [
+ {
+ "name": "eap-keystore-volume",
+ "mountPath": "/etc/eap-secret-volume",
+ "readOnly": true
+ }
+ ],
+ "readinessProbe": {
+ "exec": {
+ "command": [
+ "/bin/bash",
+ "-c",
+ "/opt/eap/bin/readinessProbe.sh"
+ ]
+ }
+ },
+ "ports": [
+ {
+ "name": "http",
+ "containerPort": 8080,
+ "protocol": "TCP"
+ },
+ {
+ "name": "https",
+ "containerPort": 8443,
+ "protocol": "TCP"
+ },
+ {
+ "name": "ping",
+ "containerPort": 8888,
+ "protocol": "TCP"
+ }
+ ],
+ "env": [
+ {
+ "name": "DB_SERVICE_PREFIX_MAPPING",
+ "value": "${APPLICATION_NAME}-mysql=DB"
+ },
+ {
+ "name": "DB_JNDI",
+ "value": "${DB_JNDI}"
+ },
+ {
+ "name": "DB_USERNAME",
+ "value": "${DB_USERNAME}"
+ },
+ {
+ "name": "DB_PASSWORD",
+ "value": "${DB_PASSWORD}"
+ },
+ {
+ "name": "DB_DATABASE",
+ "value": "${DB_DATABASE}"
+ },
+ {
+ "name": "TX_DATABASE_PREFIX_MAPPING",
+ "value": "${APPLICATION_NAME}-mysql=DB"
+ },
+ {
+ "name": "DB_MIN_POOL_SIZE",
+ "value": "${DB_MIN_POOL_SIZE}"
+ },
+ {
+ "name": "DB_MAX_POOL_SIZE",
+ "value": "${DB_MAX_POOL_SIZE}"
+ },
+ {
+ "name": "DB_TX_ISOLATION",
+ "value": "${DB_TX_ISOLATION}"
+ },
+ {
+ "name": "OPENSHIFT_DNS_PING_SERVICE_NAME",
+ "value": "${APPLICATION_NAME}-ping"
+ },
+ {
+ "name": "OPENSHIFT_DNS_PING_SERVICE_PORT",
+ "value": "8888"
+ },
+ {
+ "name": "EAP_HTTPS_KEYSTORE_DIR",
+ "value": "/etc/eap-secret-volume"
+ },
+ {
+ "name": "EAP_HTTPS_KEYSTORE",
+ "value": "${EAP_HTTPS_KEYSTORE}"
+ },
+ {
+ "name": "EAP_HTTPS_NAME",
+ "value": "${EAP_HTTPS_NAME}"
+ },
+ {
+ "name": "EAP_HTTPS_PASSWORD",
+ "value": "${EAP_HTTPS_PASSWORD}"
+ },
+ {
+ "name": "HORNETQ_CLUSTER_PASSWORD",
+ "value": "${HORNETQ_CLUSTER_PASSWORD}"
+ },
+ {
+ "name": "HORNETQ_QUEUES",
+ "value": "${HORNETQ_QUEUES}"
+ },
+ {
+ "name": "HORNETQ_TOPICS",
+ "value": "${HORNETQ_TOPICS}"
+ }
+ ]
+ }
+ ],
+ "volumes": [
+ {
+ "name": "eap-keystore-volume",
+ "secret": {
+ "secretName": "${EAP_HTTPS_SECRET}"
+ }
+ }
+ ]
+ }
+ }
+ }
+ },
+ {
+ "kind": "DeploymentConfig",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "${APPLICATION_NAME}-mysql",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "strategy": {
+ "type": "Recreate"
+ },
+ "triggers": [
+ {
+ "type": "ImageChange",
+ "imageChangeParams": {
+ "automatic": true,
+ "containerNames": [
+ "${APPLICATION_NAME}-mysql"
+ ],
+ "from": {
+ "kind": "ImageStreamTag",
+ "namespace": "openshift",
+ "name": "mysql:latest"
+ }
+ }
+ }
+ ],
+ "replicas": 1,
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}-mysql"
+ },
+ "template": {
+ "metadata": {
+ "name": "${APPLICATION_NAME}-mysql",
+ "labels": {
+ "deploymentConfig": "${APPLICATION_NAME}-mysql",
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "containers": [
+ {
+ "name": "${APPLICATION_NAME}-mysql",
+ "image": "mysql",
+ "imagePullPolicy": "Always",
+ "ports": [
+ {
+ "containerPort": 3306,
+ "protocol": "TCP"
+ }
+ ],
+ "env": [
+ {
+ "name": "MYSQL_USER",
+ "value": "${DB_USERNAME}"
+ },
+ {
+ "name": "MYSQL_PASSWORD",
+ "value": "${DB_PASSWORD}"
+ },
+ {
+ "name": "MYSQL_DATABASE",
+ "value": "${DB_DATABASE}"
+ },
+ {
+ "name": "MYSQL_LOWER_CASE_TABLE_NAMES",
+ "value": "${MYSQL_LOWER_CASE_TABLE_NAMES}"
+ },
+ {
+ "name": "MYSQL_MAX_CONNECTIONS",
+ "value": "${MYSQL_MAX_CONNECTIONS}"
+ },
+ {
+ "name": "MYSQL_FT_MIN_WORD_LEN",
+ "value": "${MYSQL_FT_MIN_WORD_LEN}"
+ },
+ {
+ "name": "MYSQL_FT_MAX_WORD_LEN",
+ "value": "${MYSQL_FT_MAX_WORD_LEN}"
+ },
+ {
+ "name": "MYSQL_AIO",
+ "value": "${MYSQL_AIO}"
+ }
+ ]
+ }
+ ]
+ }
+ }
+ }
+ }
+ ]
+}
diff --git a/roles/openshift_examples/files/examples/xpaas-templates/eap6-postgresql-persistent-sti.json b/roles/openshift_examples/files/examples/xpaas-templates/eap6-postgresql-persistent-sti.json
new file mode 100644
index 000000000..53b953b7e
--- /dev/null
+++ b/roles/openshift_examples/files/examples/xpaas-templates/eap6-postgresql-persistent-sti.json
@@ -0,0 +1,627 @@
+{
+ "kind": "Template",
+ "apiVersion": "v1",
+ "metadata": {
+ "annotations": {
+ "description": "Application template for EAP 6 PostgreSQL applications with persistent storage built using STI.",
+ "iconClass" : "icon-jboss"
+ },
+ "name": "eap6-postgresql-persistent-sti"
+ },
+ "labels": {
+ "template": "eap6-postgresql-persistent-sti"
+ },
+ "parameters": [
+ {
+ "description": "EAP Release version, e.g. 6.4, etc.",
+ "name": "EAP_RELEASE",
+ "value": "6.4"
+ },
+ {
+ "description": "The name for the application.",
+ "name": "APPLICATION_NAME",
+ "value": "eap-app"
+ },
+ {
+ "description": "Custom hostname for service routes. Leave blank for default hostname, e.g.: <application-name>.<project>.<default-domain-suffix>",
+ "name": "APPLICATION_HOSTNAME",
+ "value": ""
+ },
+ {
+ "description": "Git source URI for application",
+ "name": "GIT_URI"
+ },
+ {
+ "description": "Git branch/tag reference",
+ "name": "GIT_REF",
+ "value": "master"
+ },
+ {
+ "description": "Path within Git project to build; empty for root project directory.",
+ "name": "GIT_CONTEXT_DIR",
+ "value": ""
+ },
+ {
+ "description": "Database JNDI name used by application to resolve the datasource, e.g. java:/jboss/datasources/postgresql",
+ "name": "DB_JNDI",
+ "value": ""
+ },
+ {
+ "description": "Database name",
+ "name": "DB_DATABASE",
+ "value": "root"
+ },
+ {
+ "description": "Size of persistent storage for database volume.",
+ "name": "VOLUME_CAPACITY",
+ "value": "512Mi"
+ },
+ {
+ "description": "Queue names",
+ "name": "HORNETQ_QUEUES",
+ "value": ""
+ },
+ {
+ "description": "Topic names",
+ "name": "HORNETQ_TOPICS",
+ "value": ""
+ },
+ {
+ "description": "The name of the secret containing the keystore file",
+ "name": "EAP_HTTPS_SECRET",
+ "value": "eap-app-secret"
+ },
+ {
+ "description": "The name of the keystore file within the secret",
+ "name": "EAP_HTTPS_KEYSTORE",
+ "value": "keystore.jks"
+ },
+ {
+ "description": "The name associated with the server certificate",
+ "name": "EAP_HTTPS_NAME",
+ "value": ""
+ },
+ {
+ "description": "The password for the keystore and certificate",
+ "name": "EAP_HTTPS_PASSWORD",
+ "value": ""
+ },
+ {
+ "description": "Sets xa-pool/min-pool-size for the configured datasource.",
+ "name": "DB_MIN_POOL_SIZE"
+ },
+ {
+ "description": "Sets xa-pool/max-pool-size for the configured datasource.",
+ "name": "DB_MAX_POOL_SIZE"
+ },
+ {
+ "description": "Sets transaction-isolation for the configured datasource.",
+ "name": "DB_TX_ISOLATION"
+ },
+ {
+ "description": "The maximum number of client connections allowed. This also sets the maximum number of prepared transactions.",
+ "name": "POSTGRESQL_MAX_CONNECTIONS"
+ },
+ {
+ "description": "Configures how much memory is dedicated to PostgreSQL for caching data.",
+ "name": "POSTGRESQL_SHARED_BUFFERS"
+ },
+ {
+ "description": "HornetQ cluster admin password",
+ "name": "HORNETQ_CLUSTER_PASSWORD",
+ "from": "[a-zA-Z0-9]{8}",
+ "generate": "expression"
+ },
+ {
+ "description": "Database user name",
+ "name": "DB_USERNAME",
+ "from": "user[a-zA-Z0-9]{3}",
+ "generate": "expression"
+ },
+ {
+ "description": "Database user password",
+ "name": "DB_PASSWORD",
+ "from": "[a-zA-Z0-9]{8}",
+ "generate": "expression"
+ },
+ {
+ "description": "Github trigger secret",
+ "name": "GITHUB_TRIGGER_SECRET",
+ "from": "[a-zA-Z0-9]{8}",
+ "generate": "expression"
+ },
+ {
+ "description": "Generic build trigger secret",
+ "name": "GENERIC_TRIGGER_SECRET",
+ "from": "[a-zA-Z0-9]{8}",
+ "generate": "expression"
+ }
+ ],
+ "objects": [
+ {
+ "kind": "Service",
+ "apiVersion": "v1",
+ "spec": {
+ "ports": [
+ {
+ "port": 8080,
+ "targetPort": 8080
+ }
+ ],
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}"
+ }
+ },
+ "metadata": {
+ "name": "${APPLICATION_NAME}",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "The web server's http port."
+ }
+ }
+ },
+ {
+ "kind": "Service",
+ "apiVersion": "v1",
+ "spec": {
+ "ports": [
+ {
+ "port": 8443,
+ "targetPort": 8443
+ }
+ ],
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}"
+ }
+ },
+ "metadata": {
+ "name": "secure-${APPLICATION_NAME}",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "The web server's https port."
+ }
+ }
+ },
+ {
+ "kind": "Service",
+ "apiVersion": "v1",
+ "spec": {
+ "ports": [
+ {
+ "port": 8888,
+ "targetPort": 8888
+ }
+ ],
+ "portalIP": "None",
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}"
+ }
+ },
+ "metadata": {
+ "name": "${APPLICATION_NAME}-ping",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "Ping service for clustered applications."
+ }
+ }
+ },
+ {
+ "kind": "Service",
+ "apiVersion": "v1",
+ "spec": {
+ "ports": [
+ {
+ "port": 5432,
+ "targetPort": 5432
+ }
+ ],
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}-postgresql"
+ }
+ },
+ "metadata": {
+ "name": "${APPLICATION_NAME}-postgresql",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "The database server's port."
+ }
+ }
+ },
+ {
+ "kind": "Route",
+ "apiVersion": "v1",
+ "id": "${APPLICATION_NAME}-http-route",
+ "metadata": {
+ "name": "${APPLICATION_NAME}-http-route",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "Route for application's http service."
+ }
+ },
+ "spec": {
+ "host": "${APPLICATION_HOSTNAME}",
+ "to": {
+ "name": "${APPLICATION_NAME}"
+ }
+ }
+ },
+ {
+ "kind": "Route",
+ "apiVersion": "v1",
+ "id": "${APPLICATION_NAME}-https-route",
+ "metadata": {
+ "name": "${APPLICATION_NAME}-https-route",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "Route for application's https service."
+ }
+ },
+ "spec": {
+ "host": "${APPLICATION_HOSTNAME}",
+ "to": {
+ "name": "secure-${APPLICATION_NAME}"
+ },
+ "tls": {
+ "termination" : "passthrough"
+ }
+ }
+ },
+ {
+ "kind": "ImageStream",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "${APPLICATION_NAME}",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ }
+ }
+ },
+ {
+ "kind": "BuildConfig",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "${APPLICATION_NAME}",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "source": {
+ "type": "Git",
+ "git": {
+ "uri": "${GIT_URI}",
+ "ref": "${GIT_REF}"
+ },
+ "contextDir":"${GIT_CONTEXT_DIR}"
+ },
+ "strategy": {
+ "type": "Source",
+ "sourceStrategy": {
+ "from": {
+ "kind": "ImageStreamTag",
+ "namespace": "openshift",
+ "name": "jboss-eap6-openshift:${EAP_RELEASE}"
+ }
+ }
+ },
+ "output": {
+ "to": {
+ "kind": "ImageStreamTag",
+ "name": "${APPLICATION_NAME}:latest"
+ }
+ },
+ "triggers": [
+ {
+ "type": "GitHub",
+ "github": {
+ "secret": "${GITHUB_TRIGGER_SECRET}"
+ }
+ },
+ {
+ "type": "Generic",
+ "generic": {
+ "secret": "${GENERIC_TRIGGER_SECRET}"
+ }
+ },
+ {
+ "type": "ImageChange",
+ "imageChange": {}
+ }
+ ]
+ }
+ },
+ {
+ "kind": "DeploymentConfig",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "${APPLICATION_NAME}",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "strategy": {
+ "type": "Recreate"
+ },
+ "triggers": [
+ {
+ "type": "ImageChange",
+ "imageChangeParams": {
+ "automatic": true,
+ "containerNames": [
+ "${APPLICATION_NAME}"
+ ],
+ "from": {
+ "kind": "ImageStream",
+ "name": "${APPLICATION_NAME}"
+ }
+ }
+ }
+ ],
+ "replicas": 1,
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}"
+ },
+ "template": {
+ "metadata": {
+ "name": "${APPLICATION_NAME}",
+ "labels": {
+ "deploymentConfig": "${APPLICATION_NAME}",
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "serviceAccount": "eap-service-account",
+ "containers": [
+ {
+ "name": "${APPLICATION_NAME}",
+ "image": "${APPLICATION_NAME}",
+ "imagePullPolicy": "Always",
+ "volumeMounts": [
+ {
+ "name": "eap-keystore-volume",
+ "mountPath": "/etc/eap-secret-volume",
+ "readOnly": true
+ }
+ ],
+ "readinessProbe": {
+ "exec": {
+ "command": [
+ "/bin/bash",
+ "-c",
+ "/opt/eap/bin/readinessProbe.sh"
+ ]
+ }
+ },
+ "ports": [
+ {
+ "name": "http",
+ "containerPort": 8080,
+ "protocol": "TCP"
+ },
+ {
+ "name": "https",
+ "containerPort": 8443,
+ "protocol": "TCP"
+ },
+ {
+ "name": "ping",
+ "containerPort": 8888,
+ "protocol": "TCP"
+ }
+ ],
+ "env": [
+ {
+ "name": "DB_SERVICE_PREFIX_MAPPING",
+ "value": "${APPLICATION_NAME}-postgresql=DB"
+ },
+ {
+ "name": "DB_JNDI",
+ "value": "${DB_JNDI}"
+ },
+ {
+ "name": "DB_USERNAME",
+ "value": "${DB_USERNAME}"
+ },
+ {
+ "name": "DB_PASSWORD",
+ "value": "${DB_PASSWORD}"
+ },
+ {
+ "name": "DB_DATABASE",
+ "value": "${DB_DATABASE}"
+ },
+ {
+ "name": "TX_DATABASE_PREFIX_MAPPING",
+ "value": "${APPLICATION_NAME}-postgresql=DB"
+ },
+ {
+ "name": "DB_MIN_POOL_SIZE",
+ "value": "${DB_MIN_POOL_SIZE}"
+ },
+ {
+ "name": "DB_MAX_POOL_SIZE",
+ "value": "${DB_MAX_POOL_SIZE}"
+ },
+ {
+ "name": "DB_TX_ISOLATION",
+ "value": "${DB_TX_ISOLATION}"
+ },
+ {
+ "name": "OPENSHIFT_DNS_PING_SERVICE_NAME",
+ "value": "${APPLICATION_NAME}-ping"
+ },
+ {
+ "name": "OPENSHIFT_DNS_PING_SERVICE_PORT",
+ "value": "8888"
+ },
+ {
+ "name": "EAP_HTTPS_KEYSTORE_DIR",
+ "value": "/etc/eap-secret-volume"
+ },
+ {
+ "name": "EAP_HTTPS_KEYSTORE",
+ "value": "${EAP_HTTPS_KEYSTORE}"
+ },
+ {
+ "name": "EAP_HTTPS_NAME",
+ "value": "${EAP_HTTPS_NAME}"
+ },
+ {
+ "name": "EAP_HTTPS_PASSWORD",
+ "value": "${EAP_HTTPS_PASSWORD}"
+ },
+ {
+ "name": "HORNETQ_CLUSTER_PASSWORD",
+ "value": "${HORNETQ_CLUSTER_PASSWORD}"
+ },
+ {
+ "name": "HORNETQ_QUEUES",
+ "value": "${HORNETQ_QUEUES}"
+ },
+ {
+ "name": "HORNETQ_TOPICS",
+ "value": "${HORNETQ_TOPICS}"
+ }
+ ]
+ }
+ ],
+ "volumes": [
+ {
+ "name": "eap-keystore-volume",
+ "secret": {
+ "secretName": "${EAP_HTTPS_SECRET}"
+ }
+ }
+ ]
+ }
+ }
+ }
+ },
+ {
+ "kind": "DeploymentConfig",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "${APPLICATION_NAME}-postgresql",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "strategy": {
+ "type": "Recreate"
+ },
+ "triggers": [
+ {
+ "type": "ImageChange",
+ "imageChangeParams": {
+ "automatic": true,
+ "containerNames": [
+ "${APPLICATION_NAME}-postgresql"
+ ],
+ "from": {
+ "kind": "ImageStreamTag",
+ "namespace": "openshift",
+ "name": "postgresql:latest"
+ }
+ }
+ }
+ ],
+ "replicas": 1,
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}-postgresql"
+ },
+ "template": {
+ "metadata": {
+ "name": "${APPLICATION_NAME}-postgresql",
+ "labels": {
+ "deploymentConfig": "${APPLICATION_NAME}-postgresql",
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "containers": [
+ {
+ "name": "${APPLICATION_NAME}-postgresql",
+ "image": "postgresql",
+ "imagePullPolicy": "Always",
+ "ports": [
+ {
+ "containerPort": 5432,
+ "protocol": "TCP"
+ }
+ ],
+ "volumeMounts": [
+ {
+ "mountPath": "/var/lib/pgsql/data",
+ "name": "${APPLICATION_NAME}-postgresql-pvol"
+ }
+ ],
+ "env": [
+ {
+ "name": "POSTGRESQL_USER",
+ "value": "${DB_USERNAME}"
+ },
+ {
+ "name": "POSTGRESQL_PASSWORD",
+ "value": "${DB_PASSWORD}"
+ },
+ {
+ "name": "POSTGRESQL_DATABASE",
+ "value": "${DB_DATABASE}"
+ },
+ {
+ "name": "POSTGRESQL_MAX_CONNECTIONS",
+ "value": "${POSTGRESQL_MAX_CONNECTIONS}"
+ },
+ {
+ "name": "POSTGRESQL_SHARED_BUFFERS",
+ "value": "${POSTGRESQL_SHARED_BUFFERS}"
+ }
+ ]
+ }
+ ],
+ "volumes": [
+ {
+ "name": "${APPLICATION_NAME}-postgresql-pvol",
+ "persistentVolumeClaim": {
+ "claimName": "${APPLICATION_NAME}-postgresql-claim"
+ }
+ }
+ ]
+ }
+ }
+ }
+ },
+ {
+ "apiVersion": "v1",
+ "kind": "PersistentVolumeClaim",
+ "metadata": {
+ "name": "${APPLICATION_NAME}-postgresql-claim",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "accessModes": [ "ReadWriteOnce" ],
+ "resources": {
+ "requests": {
+ "storage": "${VOLUME_CAPACITY}"
+ }
+ }
+ }
+ }
+ ]
+}
diff --git a/roles/openshift_examples/files/examples/xpaas-templates/eap6-postgresql-sti.json b/roles/openshift_examples/files/examples/xpaas-templates/eap6-postgresql-sti.json
new file mode 100644
index 000000000..9d660cb42
--- /dev/null
+++ b/roles/openshift_examples/files/examples/xpaas-templates/eap6-postgresql-sti.json
@@ -0,0 +1,590 @@
+{
+ "kind": "Template",
+ "apiVersion": "v1",
+ "metadata": {
+ "annotations": {
+ "description": "Application template for EAP 6 PostgreSQL applications built using STI.",
+ "iconClass" : "icon-jboss"
+ },
+ "name": "eap6-postgresql-sti"
+ },
+ "labels": {
+ "template": "eap6-postgresql-sti"
+ },
+ "parameters": [
+ {
+ "description": "EAP Release version, e.g. 6.4, etc.",
+ "name": "EAP_RELEASE",
+ "value": "6.4"
+ },
+ {
+ "description": "The name for the application.",
+ "name": "APPLICATION_NAME",
+ "value": "eap-app"
+ },
+ {
+ "description": "Custom hostname for service routes. Leave blank for default hostname, e.g.: <application-name>.<project>.<default-domain-suffix>",
+ "name": "APPLICATION_HOSTNAME",
+ "value": ""
+ },
+ {
+ "description": "Git source URI for application",
+ "name": "GIT_URI"
+ },
+ {
+ "description": "Git branch/tag reference",
+ "name": "GIT_REF",
+ "value": "master"
+ },
+ {
+ "description": "Path within Git project to build; empty for root project directory.",
+ "name": "GIT_CONTEXT_DIR",
+ "value": ""
+ },
+ {
+ "description": "Database JNDI name used by application to resolve the datasource, e.g. java:/jboss/datasources/postgresql",
+ "name": "DB_JNDI",
+ "value": ""
+ },
+ {
+ "description": "Database name",
+ "name": "DB_DATABASE",
+ "value": "root"
+ },
+ {
+ "description": "Queue names",
+ "name": "HORNETQ_QUEUES",
+ "value": ""
+ },
+ {
+ "description": "Topic names",
+ "name": "HORNETQ_TOPICS",
+ "value": ""
+ },
+ {
+ "description": "The name of the secret containing the keystore file",
+ "name": "EAP_HTTPS_SECRET",
+ "value": "eap-app-secret"
+ },
+ {
+ "description": "The name of the keystore file within the secret",
+ "name": "EAP_HTTPS_KEYSTORE",
+ "value": "keystore.jks"
+ },
+ {
+ "description": "The name associated with the server certificate",
+ "name": "EAP_HTTPS_NAME",
+ "value": ""
+ },
+ {
+ "description": "The password for the keystore and certificate",
+ "name": "EAP_HTTPS_PASSWORD",
+ "value": ""
+ },
+ {
+ "description": "Sets xa-pool/min-pool-size for the configured datasource.",
+ "name": "DB_MIN_POOL_SIZE"
+ },
+ {
+ "description": "Sets xa-pool/max-pool-size for the configured datasource.",
+ "name": "DB_MAX_POOL_SIZE"
+ },
+ {
+ "description": "Sets transaction-isolation for the configured datasource.",
+ "name": "DB_TX_ISOLATION"
+ },
+ {
+ "description": "The maximum number of client connections allowed. This also sets the maximum number of prepared transactions.",
+ "name": "POSTGRESQL_MAX_CONNECTIONS"
+ },
+ {
+ "description": "Configures how much memory is dedicated to PostgreSQL for caching data.",
+ "name": "POSTGRESQL_SHARED_BUFFERS"
+ },
+ {
+ "description": "HornetQ cluster admin password",
+ "name": "HORNETQ_CLUSTER_PASSWORD",
+ "from": "[a-zA-Z0-9]{8}",
+ "generate": "expression"
+ },
+ {
+ "description": "Database user name",
+ "name": "DB_USERNAME",
+ "from": "user[a-zA-Z0-9]{3}",
+ "generate": "expression"
+ },
+ {
+ "description": "Database user password",
+ "name": "DB_PASSWORD",
+ "from": "[a-zA-Z0-9]{8}",
+ "generate": "expression"
+ },
+ {
+ "description": "Github trigger secret",
+ "name": "GITHUB_TRIGGER_SECRET",
+ "from": "[a-zA-Z0-9]{8}",
+ "generate": "expression"
+ },
+ {
+ "description": "Generic build trigger secret",
+ "name": "GENERIC_TRIGGER_SECRET",
+ "from": "[a-zA-Z0-9]{8}",
+ "generate": "expression"
+ }
+ ],
+ "objects": [
+ {
+ "kind": "Service",
+ "apiVersion": "v1",
+ "spec": {
+ "ports": [
+ {
+ "port": 8080,
+ "targetPort": 8080
+ }
+ ],
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}"
+ }
+ },
+ "metadata": {
+ "name": "${APPLICATION_NAME}",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "The web server's http port."
+ }
+ }
+ },
+ {
+ "kind": "Service",
+ "apiVersion": "v1",
+ "spec": {
+ "ports": [
+ {
+ "port": 8443,
+ "targetPort": 8443
+ }
+ ],
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}"
+ }
+ },
+ "metadata": {
+ "name": "secure-${APPLICATION_NAME}",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "The web server's https port."
+ }
+ }
+ },
+ {
+ "kind": "Service",
+ "apiVersion": "v1",
+ "spec": {
+ "ports": [
+ {
+ "port": 8888,
+ "targetPort": 8888
+ }
+ ],
+ "portalIP": "None",
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}"
+ }
+ },
+ "metadata": {
+ "name": "${APPLICATION_NAME}-ping",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "Ping service for clustered applications."
+ }
+ }
+ },
+ {
+ "kind": "Service",
+ "apiVersion": "v1",
+ "spec": {
+ "ports": [
+ {
+ "port": 5432,
+ "targetPort": 5432
+ }
+ ],
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}-postgresql"
+ }
+ },
+ "metadata": {
+ "name": "${APPLICATION_NAME}-postgresql",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "The database server's port."
+ }
+ }
+ },
+ {
+ "kind": "Route",
+ "apiVersion": "v1",
+ "id": "${APPLICATION_NAME}-http-route",
+ "metadata": {
+ "name": "${APPLICATION_NAME}-http-route",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "Route for application's http service."
+ }
+ },
+ "spec": {
+ "host": "${APPLICATION_HOSTNAME}",
+ "to": {
+ "name": "${APPLICATION_NAME}"
+ }
+ }
+ },
+ {
+ "kind": "Route",
+ "apiVersion": "v1",
+ "id": "${APPLICATION_NAME}-https-route",
+ "metadata": {
+ "name": "${APPLICATION_NAME}-https-route",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "Route for application's https service."
+ }
+ },
+ "spec": {
+ "host": "${APPLICATION_HOSTNAME}",
+ "to": {
+ "name": "secure-${APPLICATION_NAME}"
+ },
+ "tls": {
+ "termination" : "passthrough"
+ }
+ }
+ },
+ {
+ "kind": "ImageStream",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "${APPLICATION_NAME}",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ }
+ }
+ },
+ {
+ "kind": "BuildConfig",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "${APPLICATION_NAME}",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "source": {
+ "type": "Git",
+ "git": {
+ "uri": "${GIT_URI}",
+ "ref": "${GIT_REF}"
+ },
+ "contextDir":"${GIT_CONTEXT_DIR}"
+ },
+ "strategy": {
+ "type": "Source",
+ "sourceStrategy": {
+ "from": {
+ "kind": "ImageStreamTag",
+ "namespace": "openshift",
+ "name": "jboss-eap6-openshift:${EAP_RELEASE}"
+ }
+ }
+ },
+ "output": {
+ "to": {
+ "kind": "ImageStreamTag",
+ "name": "${APPLICATION_NAME}:latest"
+ }
+ },
+ "triggers": [
+ {
+ "type": "GitHub",
+ "github": {
+ "secret": "${GITHUB_TRIGGER_SECRET}"
+ }
+ },
+ {
+ "type": "Generic",
+ "generic": {
+ "secret": "${GENERIC_TRIGGER_SECRET}"
+ }
+ },
+ {
+ "type": "ImageChange",
+ "imageChange": {}
+ }
+ ]
+ }
+ },
+ {
+ "kind": "DeploymentConfig",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "${APPLICATION_NAME}",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "strategy": {
+ "type": "Recreate"
+ },
+ "triggers": [
+ {
+ "type": "ImageChange",
+ "imageChangeParams": {
+ "automatic": true,
+ "containerNames": [
+ "${APPLICATION_NAME}"
+ ],
+ "from": {
+ "kind": "ImageStream",
+ "name": "${APPLICATION_NAME}"
+ }
+ }
+ }
+ ],
+ "replicas": 1,
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}"
+ },
+ "template": {
+ "metadata": {
+ "name": "${APPLICATION_NAME}",
+ "labels": {
+ "deploymentConfig": "${APPLICATION_NAME}",
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "serviceAccount": "eap-service-account",
+ "containers": [
+ {
+ "name": "${APPLICATION_NAME}",
+ "image": "${APPLICATION_NAME}",
+ "imagePullPolicy": "Always",
+ "volumeMounts": [
+ {
+ "name": "eap-keystore-volume",
+ "mountPath": "/etc/eap-secret-volume",
+ "readOnly": true
+ }
+ ],
+ "readinessProbe": {
+ "exec": {
+ "command": [
+ "/bin/bash",
+ "-c",
+ "/opt/eap/bin/readinessProbe.sh"
+ ]
+ }
+ },
+ "ports": [
+ {
+ "name": "http",
+ "containerPort": 8080,
+ "protocol": "TCP"
+ },
+ {
+ "name": "https",
+ "containerPort": 8443,
+ "protocol": "TCP"
+ },
+ {
+ "name": "ping",
+ "containerPort": 8888,
+ "protocol": "TCP"
+ }
+ ],
+ "env": [
+ {
+ "name": "DB_SERVICE_PREFIX_MAPPING",
+ "value": "${APPLICATION_NAME}-postgresql=DB"
+ },
+ {
+ "name": "DB_JNDI",
+ "value": "${DB_JNDI}"
+ },
+ {
+ "name": "DB_USERNAME",
+ "value": "${DB_USERNAME}"
+ },
+ {
+ "name": "DB_PASSWORD",
+ "value": "${DB_PASSWORD}"
+ },
+ {
+ "name": "DB_DATABASE",
+ "value": "${DB_DATABASE}"
+ },
+ {
+ "name": "TX_DATABASE_PREFIX_MAPPING",
+ "value": "${APPLICATION_NAME}-postgresql=DB"
+ },
+ {
+ "name": "DB_MIN_POOL_SIZE",
+ "value": "${DB_MIN_POOL_SIZE}"
+ },
+ {
+ "name": "DB_MAX_POOL_SIZE",
+ "value": "${DB_MAX_POOL_SIZE}"
+ },
+ {
+ "name": "DB_TX_ISOLATION",
+ "value": "${DB_TX_ISOLATION}"
+ },
+ {
+ "name": "OPENSHIFT_DNS_PING_SERVICE_NAME",
+ "value": "${APPLICATION_NAME}-ping"
+ },
+ {
+ "name": "OPENSHIFT_DNS_PING_SERVICE_PORT",
+ "value": "8888"
+ },
+ {
+ "name": "EAP_HTTPS_KEYSTORE_DIR",
+ "value": "/etc/eap-secret-volume"
+ },
+ {
+ "name": "EAP_HTTPS_KEYSTORE",
+ "value": "${EAP_HTTPS_KEYSTORE}"
+ },
+ {
+ "name": "EAP_HTTPS_NAME",
+ "value": "${EAP_HTTPS_NAME}"
+ },
+ {
+ "name": "EAP_HTTPS_PASSWORD",
+ "value": "${EAP_HTTPS_PASSWORD}"
+ },
+ {
+ "name": "HORNETQ_CLUSTER_PASSWORD",
+ "value": "${HORNETQ_CLUSTER_PASSWORD}"
+ },
+ {
+ "name": "HORNETQ_QUEUES",
+ "value": "${HORNETQ_QUEUES}"
+ },
+ {
+ "name": "HORNETQ_TOPICS",
+ "value": "${HORNETQ_TOPICS}"
+ }
+ ]
+ }
+ ],
+ "volumes": [
+ {
+ "name": "eap-keystore-volume",
+ "secret": {
+ "secretName": "${EAP_HTTPS_SECRET}"
+ }
+ }
+ ]
+ }
+ }
+ }
+ },
+ {
+ "kind": "DeploymentConfig",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "${APPLICATION_NAME}-postgresql",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "strategy": {
+ "type": "Recreate"
+ },
+ "triggers": [
+ {
+ "type": "ImageChange",
+ "imageChangeParams": {
+ "automatic": true,
+ "containerNames": [
+ "${APPLICATION_NAME}-postgresql"
+ ],
+ "from": {
+ "kind": "ImageStreamTag",
+ "namespace": "openshift",
+ "name": "postgresql:latest"
+ }
+ }
+ }
+ ],
+ "replicas": 1,
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}-postgresql"
+ },
+ "template": {
+ "metadata": {
+ "name": "${APPLICATION_NAME}-postgresql",
+ "labels": {
+ "deploymentConfig": "${APPLICATION_NAME}-postgresql",
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "containers": [
+ {
+ "name": "${APPLICATION_NAME}-postgresql",
+ "image": "postgresql",
+ "imagePullPolicy": "Always",
+ "ports": [
+ {
+ "containerPort": 5432,
+ "protocol": "TCP"
+ }
+ ],
+ "env": [
+ {
+ "name": "POSTGRESQL_USER",
+ "value": "${DB_USERNAME}"
+ },
+ {
+ "name": "POSTGRESQL_PASSWORD",
+ "value": "${DB_PASSWORD}"
+ },
+ {
+ "name": "POSTGRESQL_DATABASE",
+ "value": "${DB_DATABASE}"
+ },
+ {
+ "name": "POSTGRESQL_MAX_CONNECTIONS",
+ "value": "${POSTGRESQL_MAX_CONNECTIONS}"
+ },
+ {
+ "name": "POSTGRESQL_SHARED_BUFFERS",
+ "value": "${POSTGRESQL_SHARED_BUFFERS}"
+ }
+ ]
+ }
+ ]
+ }
+ }
+ }
+ }
+ ]
+}
diff --git a/roles/openshift_examples/files/examples/xpaas-templates/jws-tomcat7-basic-sti.json b/roles/openshift_examples/files/examples/xpaas-templates/jws-tomcat7-basic-sti.json
new file mode 100644
index 000000000..d74c2dfe3
--- /dev/null
+++ b/roles/openshift_examples/files/examples/xpaas-templates/jws-tomcat7-basic-sti.json
@@ -0,0 +1,257 @@
+{
+ "kind": "Template",
+ "apiVersion": "v1",
+ "metadata": {
+ "annotations": {
+ "iconClass" : "icon-tomcat",
+ "description": "Application template for JWS applications built using STI."
+ },
+ "name": "jws-tomcat7-basic-sti"
+ },
+ "labels": {
+ "template": "jws-tomcat7-basic-sti"
+ },
+ "parameters": [
+ {
+ "description": "JWS Release version, e.g. 3.0, 2.1, etc.",
+ "name": "JWS_RELEASE",
+ "value": "3.0"
+ },
+ {
+ "description": "The name for the application.",
+ "name": "APPLICATION_NAME",
+ "value": "jws-app"
+ },
+ {
+ "description": "Custom hostname for service routes. Leave blank for default hostname, e.g.: <application-name>.<project>.<default-domain-suffix>",
+ "name": "APPLICATION_HOSTNAME",
+ "value": ""
+ },
+ {
+ "description": "Git source URI for application",
+ "name": "GIT_URI"
+ },
+ {
+ "description": "Git branch/tag reference",
+ "name": "GIT_REF",
+ "value": "master"
+ },
+ {
+ "description": "Path within Git project to build; empty for root project directory.",
+ "name": "GIT_CONTEXT_DIR",
+ "value": ""
+ },
+ {
+ "description": "JWS Admin User",
+ "name": "JWS_ADMIN_USERNAME",
+ "from": "[a-zA-Z0-9]{8}",
+ "generate": "expression"
+ },
+ {
+ "description": "JWS Admin Password",
+ "name": "JWS_ADMIN_PASSWORD",
+ "from": "[a-zA-Z0-9]{8}",
+ "generate": "expression"
+ },
+ {
+ "description": "Github trigger secret",
+ "name": "GITHUB_TRIGGER_SECRET",
+ "from": "[a-zA-Z0-9]{8}",
+ "generate": "expression"
+ },
+ {
+ "description": "Generic build trigger secret",
+ "name": "GENERIC_TRIGGER_SECRET",
+ "from": "[a-zA-Z0-9]{8}",
+ "generate": "expression"
+ }
+ ],
+ "objects": [
+ {
+ "kind": "Service",
+ "apiVersion": "v1",
+ "spec": {
+ "ports": [
+ {
+ "port": 8080,
+ "targetPort": 8080
+ }
+ ],
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}"
+ }
+ },
+ "metadata": {
+ "name": "${APPLICATION_NAME}",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "The web server's http port."
+ }
+ }
+ },
+ {
+ "kind": "Route",
+ "apiVersion": "v1",
+ "id": "${APPLICATION_NAME}-http-route",
+ "metadata": {
+ "name": "${APPLICATION_NAME}-http-route",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "Route for application's http service."
+ }
+ },
+ "spec": {
+ "host": "${APPLICATION_HOSTNAME}",
+ "to": {
+ "name": "${APPLICATION_NAME}"
+ }
+ }
+ },
+ {
+ "kind": "ImageStream",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "${APPLICATION_NAME}",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ }
+ }
+ },
+ {
+ "kind": "BuildConfig",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "${APPLICATION_NAME}",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "source": {
+ "type": "Git",
+ "git": {
+ "uri": "${GIT_URI}",
+ "ref": "${GIT_REF}"
+ },
+ "contextDir":"${GIT_CONTEXT_DIR}"
+ },
+ "strategy": {
+ "type": "Source",
+ "sourceStrategy": {
+ "from": {
+ "kind": "ImageStreamTag",
+ "namespace": "openshift",
+ "name": "jboss-webserver3-tomcat7-openshift:${JWS_RELEASE}"
+ }
+ }
+ },
+ "output": {
+ "to": {
+ "kind": "ImageStreamTag",
+ "name": "${APPLICATION_NAME}:latest"
+ }
+ },
+ "triggers": [
+ {
+ "type": "GitHub",
+ "github": {
+ "secret": "${GITHUB_TRIGGER_SECRET}"
+ }
+ },
+ {
+ "type": "Generic",
+ "generic": {
+ "secret": "${GENERIC_TRIGGER_SECRET}"
+ }
+ },
+ {
+ "type": "ImageChange",
+ "imageChange": {}
+ }
+ ]
+ }
+ },
+ {
+ "kind": "DeploymentConfig",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "${APPLICATION_NAME}",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "strategy": {
+ "type": "Recreate"
+ },
+ "triggers": [
+ {
+ "type": "ImageChange",
+ "imageChangeParams": {
+ "automatic": true,
+ "containerNames": [
+ "${APPLICATION_NAME}"
+ ],
+ "from": {
+ "kind": "ImageStream",
+ "name": "${APPLICATION_NAME}"
+ }
+ }
+ }
+ ],
+ "replicas": 1,
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}"
+ },
+ "template": {
+ "metadata": {
+ "name": "${APPLICATION_NAME}",
+ "labels": {
+ "deploymentConfig": "${APPLICATION_NAME}",
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "containers": [
+ {
+ "name": "${APPLICATION_NAME}",
+ "image": "${APPLICATION_NAME}",
+ "imagePullPolicy": "Always",
+ "readinessProbe": {
+ "exec": {
+ "command": [
+ "/bin/bash",
+ "-c",
+ "curl -s -u ${JWS_ADMIN_USERNAME}:${JWS_ADMIN_PASSWORD} 'http://localhost:8080/manager/jmxproxy/?get=Catalina%3Atype%3DServer&att=stateName' |grep -iq 'stateName *= *STARTED'"
+ ]
+ }
+ },
+ "ports": [
+ {
+ "name": "http",
+ "containerPort": 8080,
+ "protocol": "TCP"
+ }
+ ],
+ "env": [
+ {
+ "name": "JWS_ADMIN_USERNAME",
+ "value": "${JWS_ADMIN_USERNAME}"
+ },
+ {
+ "name": "JWS_ADMIN_PASSWORD",
+ "value": "${JWS_ADMIN_PASSWORD}"
+ }
+ ]
+ }
+ ]
+ }
+ }
+ }
+ }
+ ]
+}
diff --git a/roles/openshift_examples/files/examples/xpaas-templates/jws-tomcat7-https-sti.json b/roles/openshift_examples/files/examples/xpaas-templates/jws-tomcat7-https-sti.json
new file mode 100644
index 000000000..b94142135
--- /dev/null
+++ b/roles/openshift_examples/files/examples/xpaas-templates/jws-tomcat7-https-sti.json
@@ -0,0 +1,361 @@
+{
+ "kind": "Template",
+ "apiVersion": "v1",
+ "metadata": {
+ "annotations": {
+ "iconClass" : "icon-tomcat",
+ "description": "Application template for JWS applications built using STI."
+ },
+ "name": "jws-tomcat7-basic-sti"
+ },
+ "labels": {
+ "template": "jws-tomcat7-basic-sti"
+ },
+ "parameters": [
+ {
+ "description": "JWS Release version, e.g. 3.0, 2.1, etc.",
+ "name": "JWS_RELEASE",
+ "value": "3.0"
+ },
+ {
+ "description": "The name for the application.",
+ "name": "APPLICATION_NAME",
+ "value": "jws-app"
+ },
+ {
+ "description": "Custom hostname for service routes. Leave blank for default hostname, e.g.: <application-name>.<project>.<default-domain-suffix>",
+ "name": "APPLICATION_HOSTNAME",
+ "value": ""
+ },
+ {
+ "description": "Git source URI for application",
+ "name": "GIT_URI"
+ },
+ {
+ "description": "Git branch/tag reference",
+ "name": "GIT_REF",
+ "value": "master"
+ },
+ {
+ "description": "Path within Git project to build; empty for root project directory.",
+ "name": "GIT_CONTEXT_DIR",
+ "value": ""
+ },
+ {
+ "description": "The name of the secret containing the certificate files",
+ "name": "JWS_HTTPS_SECRET",
+ "value": "jws-app-secret"
+ },
+ {
+ "description": "The name of the certificate file within the secret",
+ "name": "JWS_HTTPS_CERTIFICATE",
+ "value": "server.crt"
+ },
+ {
+ "description": "The name of the certificate key file within the secret",
+ "name": "JWS_HTTPS_CERTIFICATE_KEY",
+ "value": "server.key"
+ },
+ {
+ "description": "The certificate password",
+ "name": "JWS_HTTPS_CERTIFICATE_PASSWORD",
+ "value": ""
+ },
+ {
+ "description": "JWS Admin User",
+ "name": "JWS_ADMIN_USERNAME",
+ "from": "[a-zA-Z0-9]{8}",
+ "generate": "expression"
+ },
+ {
+ "description": "JWS Admin Password",
+ "name": "JWS_ADMIN_PASSWORD",
+ "from": "[a-zA-Z0-9]{8}",
+ "generate": "expression"
+ },
+ {
+ "description": "Github trigger secret",
+ "name": "GITHUB_TRIGGER_SECRET",
+ "from": "[a-zA-Z0-9]{8}",
+ "generate": "expression"
+ },
+ {
+ "description": "Generic build trigger secret",
+ "name": "GENERIC_TRIGGER_SECRET",
+ "from": "[a-zA-Z0-9]{8}",
+ "generate": "expression"
+ }
+ ],
+ "objects": [
+ {
+ "kind": "Service",
+ "apiVersion": "v1",
+ "spec": {
+ "ports": [
+ {
+ "port": 8080,
+ "targetPort": 8080
+ }
+ ],
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}"
+ }
+ },
+ "metadata": {
+ "name": "${APPLICATION_NAME}",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "The web server's http port."
+ }
+ }
+ },
+ {
+ "kind": "Service",
+ "apiVersion": "v1",
+ "spec": {
+ "ports": [
+ {
+ "port": 8443,
+ "targetPort": 8443
+ }
+ ],
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}"
+ }
+ },
+ "metadata": {
+ "name": "secure-${APPLICATION_NAME}",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "The web server's https port."
+ }
+ }
+ },
+ {
+ "kind": "Route",
+ "apiVersion": "v1",
+ "id": "${APPLICATION_NAME}-http-route",
+ "metadata": {
+ "name": "${APPLICATION_NAME}-http-route",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "Route for application's http service."
+ }
+ },
+ "spec": {
+ "host": "${APPLICATION_HOSTNAME}",
+ "to": {
+ "name": "${APPLICATION_NAME}"
+ }
+ }
+ },
+ {
+ "kind": "Route",
+ "apiVersion": "v1",
+ "id": "${APPLICATION_NAME}-https-route",
+ "metadata": {
+ "name": "${APPLICATION_NAME}-https-route",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "Route for application's https service."
+ }
+ },
+ "spec": {
+ "host": "${APPLICATION_HOSTNAME}",
+ "to": {
+ "name": "secure-${APPLICATION_NAME}"
+ },
+ "tls": {
+ "termination" : "passthrough"
+ }
+ }
+ },
+ {
+ "kind": "ImageStream",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "${APPLICATION_NAME}",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ }
+ }
+ },
+ {
+ "kind": "BuildConfig",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "${APPLICATION_NAME}",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "source": {
+ "type": "Git",
+ "git": {
+ "uri": "${GIT_URI}",
+ "ref": "${GIT_REF}"
+ },
+ "contextDir":"${GIT_CONTEXT_DIR}"
+ },
+ "strategy": {
+ "type": "Source",
+ "sourceStrategy": {
+ "from": {
+ "kind": "ImageStreamTag",
+ "namespace": "openshift",
+ "name": "jboss-webserver3-tomcat7-openshift:${JWS_RELEASE}"
+ }
+ }
+ },
+ "output": {
+ "to": {
+ "kind": "ImageStreamTag",
+ "name": "${APPLICATION_NAME}:latest"
+ }
+ },
+ "triggers": [
+ {
+ "type": "GitHub",
+ "github": {
+ "secret": "${GITHUB_TRIGGER_SECRET}"
+ }
+ },
+ {
+ "type": "Generic",
+ "generic": {
+ "secret": "${GENERIC_TRIGGER_SECRET}"
+ }
+ },
+ {
+ "type": "ImageChange",
+ "imageChange": {}
+ }
+ ]
+ }
+ },
+ {
+ "kind": "DeploymentConfig",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "${APPLICATION_NAME}",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "strategy": {
+ "type": "Recreate"
+ },
+ "triggers": [
+ {
+ "type": "ImageChange",
+ "imageChangeParams": {
+ "automatic": true,
+ "containerNames": [
+ "${APPLICATION_NAME}"
+ ],
+ "from": {
+ "kind": "ImageStream",
+ "name": "${APPLICATION_NAME}"
+ }
+ }
+ }
+ ],
+ "replicas": 1,
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}"
+ },
+ "template": {
+ "metadata": {
+ "name": "${APPLICATION_NAME}",
+ "labels": {
+ "deploymentConfig": "${APPLICATION_NAME}",
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "serviceAccount": "jws-service-account",
+ "containers": [
+ {
+ "name": "${APPLICATION_NAME}",
+ "image": "${APPLICATION_NAME}",
+ "imagePullPolicy": "Always",
+ "readinessProbe": {
+ "exec": {
+ "command": [
+ "/bin/bash",
+ "-c",
+ "curl -s -u ${JWS_ADMIN_USERNAME}:${JWS_ADMIN_PASSWORD} 'http://localhost:8080/manager/jmxproxy/?get=Catalina%3Atype%3DServer&att=stateName' |grep -iq 'stateName *= *STARTED'"
+ ]
+ }
+ },
+ "volumeMounts": [
+ {
+ "name": "jws-certificate-volume",
+ "mountPath": "/etc/jws-secret-volume",
+ "readOnly": true
+ }
+ ],
+ "ports": [
+ {
+ "name": "http",
+ "containerPort": 8080,
+ "protocol": "TCP"
+ },
+ {
+ "name": "https",
+ "containerPort": 8443,
+ "protocol": "TCP"
+ }
+ ],
+ "env": [
+ {
+ "name": "JWS_HTTPS_CERTIFICATE_DIR",
+ "value": "/etc/jws-secret-volume"
+ },
+ {
+ "name": "JWS_HTTPS_CERTIFICATE",
+ "value": "${JWS_HTTPS_CERTIFICATE}"
+ },
+ {
+ "name": "JWS_HTTPS_CERTIFICATE_KEY",
+ "value": "${JWS_HTTPS_CERTIFICATE_KEY}"
+ },
+ {
+ "name": "JWS_HTTPS_CERTIFICATE_PASSWORD",
+ "value": "${JWS_HTTPS_CERTIFICATE_PASSWORD}"
+ },
+ {
+ "name": "JWS_ADMIN_USERNAME",
+ "value": "${JWS_ADMIN_USERNAME}"
+ },
+ {
+ "name": "JWS_ADMIN_PASSWORD",
+ "value": "${JWS_ADMIN_PASSWORD}"
+ }
+ ]
+ }
+ ],
+ "volumes": [
+ {
+ "name": "jws-certificate-volume",
+ "secret": {
+ "secretName": "${JWS_HTTPS_SECRET}"
+ }
+ }
+ ]
+ }
+ }
+ }
+ }
+ ]
+}
diff --git a/roles/openshift_examples/files/examples/xpaas-templates/jws-tomcat7-mongodb-persistent-sti.json b/roles/openshift_examples/files/examples/xpaas-templates/jws-tomcat7-mongodb-persistent-sti.json
new file mode 100644
index 000000000..0c7b7d8e3
--- /dev/null
+++ b/roles/openshift_examples/files/examples/xpaas-templates/jws-tomcat7-mongodb-persistent-sti.json
@@ -0,0 +1,599 @@
+{
+ "kind": "Template",
+ "apiVersion": "v1",
+ "metadata": {
+ "annotations": {
+ "iconClass" : "icon-tomcat",
+ "description": "Application template for JWS MongoDB applications with persistent storage built using STI."
+ },
+ "name": "jws-tomcat7-mongodb-persistent-sti"
+ },
+ "labels": {
+ "template": "jws-tomcat7-mongodb-persistent-sti"
+ },
+ "parameters": [
+ {
+ "description": "JWS Release version, e.g. 3.0, 2.1, etc.",
+ "name": "JWS_RELEASE",
+ "value": "3.0"
+ },
+ {
+ "description": "The name for the application.",
+ "name": "APPLICATION_NAME",
+ "value": "jws-app"
+ },
+ {
+ "description": "Custom hostname for service routes. Leave blank for default hostname, e.g.: <application-name>.<project>.<default-domain-suffix>",
+ "name": "APPLICATION_HOSTNAME",
+ "value": ""
+ },
+ {
+ "description": "Git source URI for application",
+ "name": "GIT_URI"
+ },
+ {
+ "description": "Git branch/tag reference",
+ "name": "GIT_REF",
+ "value": "master"
+ },
+ {
+ "description": "Path within Git project to build; empty for root project directory.",
+ "name": "GIT_CONTEXT_DIR",
+ "value": ""
+ },
+ {
+ "description": "Database JNDI name used by application to resolve the datasource, e.g. java:/jboss/datasources/mongodb",
+ "name": "DB_JNDI",
+ "value": ""
+ },
+ {
+ "description": "Database name",
+ "name": "DB_DATABASE",
+ "value": "root"
+ },
+ {
+ "description": "Size of persistent storage for database volume.",
+ "name": "VOLUME_CAPACITY",
+ "value": "512Mi"
+ },
+ {
+ "description": "The name of the secret containing the certificate files",
+ "name": "JWS_HTTPS_SECRET",
+ "value": "jws-app-secret"
+ },
+ {
+ "description": "The name of the certificate file within the secret",
+ "name": "JWS_HTTPS_CERTIFICATE",
+ "value": "server.crt"
+ },
+ {
+ "description": "The name of the certificate key file within the secret",
+ "name": "JWS_HTTPS_CERTIFICATE_KEY",
+ "value": "server.key"
+ },
+ {
+ "description": "The certificate password",
+ "name": "JWS_HTTPS_CERTIFICATE_PASSWORD",
+ "value": ""
+ },
+ {
+ "description": "Sets xa-pool/min-pool-size for the configured datasource.",
+ "name": "DB_MIN_POOL_SIZE"
+ },
+ {
+ "description": "Sets xa-pool/max-pool-size for the configured datasource.",
+ "name": "DB_MAX_POOL_SIZE"
+ },
+ {
+ "description": "Sets transaction-isolation for the configured datasource.",
+ "name": "DB_TX_ISOLATION"
+ },
+ {
+ "description": "Disable data file preallocation.",
+ "name": "MONGODB_NOPREALLOC"
+ },
+ {
+ "description": "Set MongoDB to use a smaller default data file size.",
+ "name": "MONGODB_SMALLFILES"
+ },
+ {
+ "description": "Runs MongoDB in a quiet mode that attempts to limit the amount of output.",
+ "name": "MONGODB_QUIET"
+ },
+ {
+ "description": "Database user name",
+ "name": "DB_USERNAME",
+ "from": "user[a-zA-Z0-9]{3}",
+ "generate": "expression"
+ },
+ {
+ "description": "Database user password",
+ "name": "DB_PASSWORD",
+ "from": "[a-zA-Z0-9]{8}",
+ "generate": "expression"
+ },
+ {
+ "description": "Database admin password",
+ "name": "DB_ADMIN_PASSWORD",
+ "from": "[a-zA-Z0-9]{8}",
+ "generate": "expression"
+ },
+ {
+ "description": "JWS Admin User",
+ "name": "JWS_ADMIN_USERNAME",
+ "from": "[a-zA-Z0-9]{8}",
+ "generate": "expression"
+ },
+ {
+ "description": "JWS Admin Password",
+ "name": "JWS_ADMIN_PASSWORD",
+ "from": "[a-zA-Z0-9]{8}",
+ "generate": "expression"
+ },
+ {
+ "description": "Github trigger secret",
+ "name": "GITHUB_TRIGGER_SECRET",
+ "from": "[a-zA-Z0-9]{8}",
+ "generate": "expression"
+ },
+ {
+ "description": "Generic build trigger secret",
+ "name": "GENERIC_TRIGGER_SECRET",
+ "from": "[a-zA-Z0-9]{8}",
+ "generate": "expression"
+ }
+ ],
+ "objects": [
+ {
+ "kind": "Service",
+ "apiVersion": "v1",
+ "spec": {
+ "ports": [
+ {
+ "port": 8080,
+ "targetPort": 8080
+ }
+ ],
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}"
+ }
+ },
+ "metadata": {
+ "name": "${APPLICATION_NAME}",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "The web server's http port."
+ }
+ }
+ },
+ {
+ "kind": "Service",
+ "apiVersion": "v1",
+ "spec": {
+ "ports": [
+ {
+ "port": 8443,
+ "targetPort": 8443
+ }
+ ],
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}"
+ }
+ },
+ "metadata": {
+ "name": "secure-${APPLICATION_NAME}",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "The web server's https port."
+ }
+ }
+ },
+ {
+ "kind": "Service",
+ "apiVersion": "v1",
+ "spec": {
+ "ports": [
+ {
+ "port": 27017,
+ "targetPort": 27017
+ }
+ ],
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}-mongodb"
+ }
+ },
+ "metadata": {
+ "name": "${APPLICATION_NAME}-mongodb",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "The database server's port."
+ }
+ }
+ },
+ {
+ "kind": "Route",
+ "apiVersion": "v1",
+ "id": "${APPLICATION_NAME}-http-route",
+ "metadata": {
+ "name": "${APPLICATION_NAME}-http-route",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "Route for application's http service."
+ }
+ },
+ "spec": {
+ "host": "${APPLICATION_HOSTNAME}",
+ "to": {
+ "name": "${APPLICATION_NAME}"
+ }
+ }
+ },
+ {
+ "kind": "Route",
+ "apiVersion": "v1",
+ "id": "${APPLICATION_NAME}-https-route",
+ "metadata": {
+ "name": "${APPLICATION_NAME}-https-route",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "Route for application's https service."
+ }
+ },
+ "spec": {
+ "host": "${APPLICATION_HOSTNAME}",
+ "to": {
+ "name": "secure-${APPLICATION_NAME}"
+ },
+ "tls": {
+ "termination" : "passthrough"
+ }
+ }
+ },
+ {
+ "kind": "ImageStream",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "${APPLICATION_NAME}",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ }
+ }
+ },
+ {
+ "kind": "BuildConfig",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "${APPLICATION_NAME}",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "source": {
+ "type": "Git",
+ "git": {
+ "uri": "${GIT_URI}",
+ "ref": "${GIT_REF}"
+ },
+ "contextDir":"${GIT_CONTEXT_DIR}"
+ },
+ "strategy": {
+ "type": "Source",
+ "sourceStrategy": {
+ "from": {
+ "kind": "ImageStreamTag",
+ "namespace": "openshift",
+ "name": "jboss-webserver3-tomcat7-openshift:${JWS_RELEASE}"
+ }
+ }
+ },
+ "output": {
+ "to": {
+ "kind": "ImageStreamTag",
+ "name": "${APPLICATION_NAME}:latest"
+ }
+ },
+ "triggers": [
+ {
+ "type": "GitHub",
+ "github": {
+ "secret": "${GITHUB_TRIGGER_SECRET}"
+ }
+ },
+ {
+ "type": "Generic",
+ "generic": {
+ "secret": "${GENERIC_TRIGGER_SECRET}"
+ }
+ },
+ {
+ "type": "ImageChange",
+ "imageChange": {}
+ }
+ ]
+ }
+ },
+ {
+ "kind": "DeploymentConfig",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "${APPLICATION_NAME}",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "strategy": {
+ "type": "Recreate"
+ },
+ "triggers": [
+ {
+ "type": "ImageChange",
+ "imageChangeParams": {
+ "automatic": true,
+ "containerNames": [
+ "${APPLICATION_NAME}"
+ ],
+ "from": {
+ "kind": "ImageStream",
+ "name": "${APPLICATION_NAME}"
+ }
+ }
+ }
+ ],
+ "replicas": 1,
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}"
+ },
+ "template": {
+ "metadata": {
+ "name": "${APPLICATION_NAME}",
+ "labels": {
+ "deploymentConfig": "${APPLICATION_NAME}",
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "serviceAccount": "jws-service-account",
+ "containers": [
+ {
+ "name": "${APPLICATION_NAME}",
+ "image": "${APPLICATION_NAME}",
+ "imagePullPolicy": "Always",
+ "readinessProbe": {
+ "exec": {
+ "command": [
+ "/bin/bash",
+ "-c",
+ "curl -s -u ${JWS_ADMIN_USERNAME}:${JWS_ADMIN_PASSWORD} 'http://localhost:8080/manager/jmxproxy/?get=Catalina%3Atype%3DServer&att=stateName' |grep -iq 'stateName *= *STARTED'"
+ ]
+ }
+ },
+ "volumeMounts": [
+ {
+ "name": "jws-certificate-volume",
+ "mountPath": "/etc/jws-secret-volume",
+ "readOnly": true
+ }
+ ],
+ "ports": [
+ {
+ "name": "http",
+ "containerPort": 8080,
+ "protocol": "TCP"
+ },
+ {
+ "name": "https",
+ "containerPort": 8443,
+ "protocol": "TCP"
+ }
+ ],
+ "env": [
+ {
+ "name": "DB_SERVICE_PREFIX_MAPPING",
+ "value": "${APPLICATION_NAME}-mongodb=DB"
+ },
+ {
+ "name": "DB_JNDI",
+ "value": "${DB_JNDI}"
+ },
+ {
+ "name": "DB_USERNAME",
+ "value": "${DB_USERNAME}"
+ },
+ {
+ "name": "DB_PASSWORD",
+ "value": "${DB_PASSWORD}"
+ },
+ {
+ "name": "DB_DATABASE",
+ "value": "${DB_DATABASE}"
+ },
+ {
+ "name": "DB_ADMIN_PASSWORD",
+ "value": "${DB_ADMIN_PASSWORD}"
+ },
+ {
+ "name": "DB_MIN_POOL_SIZE",
+ "value": "${DB_MIN_POOL_SIZE}"
+ },
+ {
+ "name": "DB_MAX_POOL_SIZE",
+ "value": "${DB_MAX_POOL_SIZE}"
+ },
+ {
+ "name": "DB_TX_ISOLATION",
+ "value": "${DB_TX_ISOLATION}"
+ },
+ {
+ "name": "JWS_HTTPS_CERTIFICATE_DIR",
+ "value": "/etc/jws-secret-volume"
+ },
+ {
+ "name": "JWS_HTTPS_CERTIFICATE",
+ "value": "${JWS_HTTPS_CERTIFICATE}"
+ },
+ {
+ "name": "JWS_HTTPS_CERTIFICATE_KEY",
+ "value": "${JWS_HTTPS_CERTIFICATE_KEY}"
+ },
+ {
+ "name": "JWS_HTTPS_CERTIFICATE_PASSWORD",
+ "value": "${JWS_HTTPS_CERTIFICATE_PASSWORD}"
+ },
+ {
+ "name": "JWS_ADMIN_USERNAME",
+ "value": "${JWS_ADMIN_USERNAME}"
+ },
+ {
+ "name": "JWS_ADMIN_PASSWORD",
+ "value": "${JWS_ADMIN_PASSWORD}"
+ }
+ ]
+ }
+ ],
+ "volumes": [
+ {
+ "name": "jws-certificate-volume",
+ "secret": {
+ "secretName": "${JWS_HTTPS_SECRET}"
+ }
+ }
+ ]
+ }
+ }
+ }
+ },
+ {
+ "kind": "DeploymentConfig",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "${APPLICATION_NAME}-mongodb",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "strategy": {
+ "type": "Recreate"
+ },
+ "triggers": [
+ {
+ "type": "ImageChange",
+ "imageChangeParams": {
+ "automatic": true,
+ "containerNames": [
+ "${APPLICATION_NAME}-mongodb"
+ ],
+ "from": {
+ "kind": "ImageStreamTag",
+ "namespace": "openshift",
+ "name": "mongodb:latest"
+ }
+ }
+ }
+ ],
+ "replicas": 1,
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}-mongodb"
+ },
+ "template": {
+ "metadata": {
+ "name": "${APPLICATION_NAME}-mongodb",
+ "labels": {
+ "deploymentConfig": "${APPLICATION_NAME}-mongodb",
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "containers": [
+ {
+ "name": "${APPLICATION_NAME}-mongodb",
+ "image": "mongodb",
+ "imagePullPolicy": "Always",
+ "ports": [
+ {
+ "containerPort": 27017,
+ "protocol": "TCP"
+ }
+ ],
+ "volumeMounts": [
+ {
+ "mountPath": "/var/lib/mongodb/data",
+ "name": "${APPLICATION_NAME}-mongodb-pvol"
+ }
+ ],
+ "env": [
+ {
+ "name": "MONGODB_USER",
+ "value": "${DB_USERNAME}"
+ },
+ {
+ "name": "MONGODB_PASSWORD",
+ "value": "${DB_PASSWORD}"
+ },
+ {
+ "name": "MONGODB_DATABASE",
+ "value": "${DB_DATABASE}"
+ },
+ {
+ "name": "MONGODB_ADMIN_PASSWORD",
+ "value": "${DB_ADMIN_PASSWORD}"
+ },
+ {
+ "name": "MONGODB_NOPREALLOC",
+ "value": "${MONGODB_NOPREALLOC}"
+ },
+ {
+ "name": "MONGODB_SMALLFILES",
+ "value": "${MONGODB_SMALLFILES}"
+ },
+ {
+ "name": "MONGODB_QUIET",
+ "value": "${MONGODB_QUIET}"
+ }
+ ]
+ }
+ ],
+ "volumes": [
+ {
+ "name": "${APPLICATION_NAME}-mongodb-pvol",
+ "persistentVolumeClaim": {
+ "claimName": "${APPLICATION_NAME}-mongodb-claim"
+ }
+ }
+ ]
+ }
+ }
+ }
+ },
+ {
+ "apiVersion": "v1",
+ "kind": "PersistentVolumeClaim",
+ "metadata": {
+ "name": "${APPLICATION_NAME}-mongodb-claim",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "accessModes": [ "ReadWriteOnce" ],
+ "resources": {
+ "requests": {
+ "storage": "${VOLUME_CAPACITY}"
+ }
+ }
+ }
+ }
+ ]
+}
diff --git a/roles/openshift_examples/files/examples/xpaas-templates/jws-tomcat7-mongodb-sti.json b/roles/openshift_examples/files/examples/xpaas-templates/jws-tomcat7-mongodb-sti.json
new file mode 100644
index 000000000..892f27fe3
--- /dev/null
+++ b/roles/openshift_examples/files/examples/xpaas-templates/jws-tomcat7-mongodb-sti.json
@@ -0,0 +1,562 @@
+{
+ "kind": "Template",
+ "apiVersion": "v1",
+ "metadata": {
+ "annotations": {
+ "iconClass" : "icon-tomcat",
+ "description": "Application template for JWS MongoDB applications built using STI."
+ },
+ "name": "jws-tomcat7-mongodb-sti"
+ },
+ "labels": {
+ "template": "jws-tomcat7-mongodb-sti"
+ },
+ "parameters": [
+ {
+ "description": "JWS Release version, e.g. 3.0, 2.1, etc.",
+ "name": "JWS_RELEASE",
+ "value": "3.0"
+ },
+ {
+ "description": "The name for the application.",
+ "name": "APPLICATION_NAME",
+ "value": "jws-app"
+ },
+ {
+ "description": "Custom hostname for service routes. Leave blank for default hostname, e.g.: <application-name>.<project>.<default-domain-suffix>",
+ "name": "APPLICATION_HOSTNAME",
+ "value": ""
+ },
+ {
+ "description": "Git source URI for application",
+ "name": "GIT_URI"
+ },
+ {
+ "description": "Git branch/tag reference",
+ "name": "GIT_REF",
+ "value": "master"
+ },
+ {
+ "description": "Path within Git project to build; empty for root project directory.",
+ "name": "GIT_CONTEXT_DIR",
+ "value": ""
+ },
+ {
+ "description": "Database JNDI name used by application to resolve the datasource, e.g. java:/jboss/datasources/mongodb",
+ "name": "DB_JNDI",
+ "value": ""
+ },
+ {
+ "description": "Database name",
+ "name": "DB_DATABASE",
+ "value": "root"
+ },
+ {
+ "description": "The name of the secret containing the certificate files",
+ "name": "JWS_HTTPS_SECRET",
+ "value": "jws-app-secret"
+ },
+ {
+ "description": "The name of the certificate file within the secret",
+ "name": "JWS_HTTPS_CERTIFICATE",
+ "value": "server.crt"
+ },
+ {
+ "description": "The name of the certificate key file within the secret",
+ "name": "JWS_HTTPS_CERTIFICATE_KEY",
+ "value": "server.key"
+ },
+ {
+ "description": "The certificate password",
+ "name": "JWS_HTTPS_CERTIFICATE_PASSWORD",
+ "value": ""
+ },
+ {
+ "description": "Sets xa-pool/min-pool-size for the configured datasource.",
+ "name": "DB_MIN_POOL_SIZE"
+ },
+ {
+ "description": "Sets xa-pool/max-pool-size for the configured datasource.",
+ "name": "DB_MAX_POOL_SIZE"
+ },
+ {
+ "description": "Sets transaction-isolation for the configured datasource.",
+ "name": "DB_TX_ISOLATION"
+ },
+ {
+ "description": "Disable data file preallocation.",
+ "name": "MONGODB_NOPREALLOC"
+ },
+ {
+ "description": "Set MongoDB to use a smaller default data file size.",
+ "name": "MONGODB_SMALLFILES"
+ },
+ {
+ "description": "Runs MongoDB in a quiet mode that attempts to limit the amount of output.",
+ "name": "MONGODB_QUIET"
+ },
+ {
+ "description": "Database user name",
+ "name": "DB_USERNAME",
+ "from": "user[a-zA-Z0-9]{3}",
+ "generate": "expression"
+ },
+ {
+ "description": "Database user password",
+ "name": "DB_PASSWORD",
+ "from": "[a-zA-Z0-9]{8}",
+ "generate": "expression"
+ },
+ {
+ "description": "Database admin password",
+ "name": "DB_ADMIN_PASSWORD",
+ "from": "[a-zA-Z0-9]{8}",
+ "generate": "expression"
+ },
+ {
+ "description": "JWS Admin User",
+ "name": "JWS_ADMIN_USERNAME",
+ "from": "[a-zA-Z0-9]{8}",
+ "generate": "expression"
+ },
+ {
+ "description": "JWS Admin Password",
+ "name": "JWS_ADMIN_PASSWORD",
+ "from": "[a-zA-Z0-9]{8}",
+ "generate": "expression"
+ },
+ {
+ "description": "Github trigger secret",
+ "name": "GITHUB_TRIGGER_SECRET",
+ "from": "[a-zA-Z0-9]{8}",
+ "generate": "expression"
+ },
+ {
+ "description": "Generic build trigger secret",
+ "name": "GENERIC_TRIGGER_SECRET",
+ "from": "[a-zA-Z0-9]{8}",
+ "generate": "expression"
+ }
+ ],
+ "objects": [
+ {
+ "kind": "Service",
+ "apiVersion": "v1",
+ "spec": {
+ "ports": [
+ {
+ "port": 8080,
+ "targetPort": 8080
+ }
+ ],
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}"
+ }
+ },
+ "metadata": {
+ "name": "${APPLICATION_NAME}",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "The web server's http port."
+ }
+ }
+ },
+ {
+ "kind": "Service",
+ "apiVersion": "v1",
+ "spec": {
+ "ports": [
+ {
+ "port": 8443,
+ "targetPort": 8443
+ }
+ ],
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}"
+ }
+ },
+ "metadata": {
+ "name": "secure-${APPLICATION_NAME}",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "The web server's https port."
+ }
+ }
+ },
+ {
+ "kind": "Service",
+ "apiVersion": "v1",
+ "spec": {
+ "ports": [
+ {
+ "port": 27017,
+ "targetPort": 27017
+ }
+ ],
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}-mongodb"
+ }
+ },
+ "metadata": {
+ "name": "${APPLICATION_NAME}-mongodb",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "The database server's port."
+ }
+ }
+ },
+ {
+ "kind": "Route",
+ "apiVersion": "v1",
+ "id": "${APPLICATION_NAME}-http-route",
+ "metadata": {
+ "name": "${APPLICATION_NAME}-http-route",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "Route for application's http service."
+ }
+ },
+ "spec": {
+ "host": "${APPLICATION_HOSTNAME}",
+ "to": {
+ "name": "${APPLICATION_NAME}"
+ }
+ }
+ },
+ {
+ "kind": "Route",
+ "apiVersion": "v1",
+ "id": "${APPLICATION_NAME}-https-route",
+ "metadata": {
+ "name": "${APPLICATION_NAME}-https-route",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "Route for application's https service."
+ }
+ },
+ "spec": {
+ "host": "${APPLICATION_HOSTNAME}",
+ "to": {
+ "name": "secure-${APPLICATION_NAME}"
+ },
+ "tls": {
+ "termination" : "passthrough"
+ }
+ }
+ },
+ {
+ "kind": "ImageStream",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "${APPLICATION_NAME}",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ }
+ }
+ },
+ {
+ "kind": "BuildConfig",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "${APPLICATION_NAME}",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "source": {
+ "type": "Git",
+ "git": {
+ "uri": "${GIT_URI}",
+ "ref": "${GIT_REF}"
+ },
+ "contextDir":"${GIT_CONTEXT_DIR}"
+ },
+ "strategy": {
+ "type": "Source",
+ "sourceStrategy": {
+ "from": {
+ "kind": "ImageStreamTag",
+ "namespace": "openshift",
+ "name": "jboss-webserver3-tomcat7-openshift:${JWS_RELEASE}"
+ }
+ }
+ },
+ "output": {
+ "to": {
+ "kind": "ImageStreamTag",
+ "name": "${APPLICATION_NAME}:latest"
+ }
+ },
+ "triggers": [
+ {
+ "type": "GitHub",
+ "github": {
+ "secret": "${GITHUB_TRIGGER_SECRET}"
+ }
+ },
+ {
+ "type": "Generic",
+ "generic": {
+ "secret": "${GENERIC_TRIGGER_SECRET}"
+ }
+ },
+ {
+ "type": "ImageChange",
+ "imageChange": {}
+ }
+ ]
+ }
+ },
+ {
+ "kind": "DeploymentConfig",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "${APPLICATION_NAME}",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "strategy": {
+ "type": "Recreate"
+ },
+ "triggers": [
+ {
+ "type": "ImageChange",
+ "imageChangeParams": {
+ "automatic": true,
+ "containerNames": [
+ "${APPLICATION_NAME}"
+ ],
+ "from": {
+ "kind": "ImageStream",
+ "name": "${APPLICATION_NAME}"
+ }
+ }
+ }
+ ],
+ "replicas": 1,
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}"
+ },
+ "template": {
+ "metadata": {
+ "name": "${APPLICATION_NAME}",
+ "labels": {
+ "deploymentConfig": "${APPLICATION_NAME}",
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "serviceAccount": "jws-service-account",
+ "containers": [
+ {
+ "name": "${APPLICATION_NAME}",
+ "image": "${APPLICATION_NAME}",
+ "imagePullPolicy": "Always",
+ "readinessProbe": {
+ "exec": {
+ "command": [
+ "/bin/bash",
+ "-c",
+ "curl -s -u ${JWS_ADMIN_USERNAME}:${JWS_ADMIN_PASSWORD} 'http://localhost:8080/manager/jmxproxy/?get=Catalina%3Atype%3DServer&att=stateName' |grep -iq 'stateName *= *STARTED'"
+ ]
+ }
+ },
+ "volumeMounts": [
+ {
+ "name": "jws-certificate-volume",
+ "mountPath": "/etc/jws-secret-volume",
+ "readOnly": true
+ }
+ ],
+ "ports": [
+ {
+ "name": "http",
+ "containerPort": 8080,
+ "protocol": "TCP"
+ },
+ {
+ "name": "https",
+ "containerPort": 8443,
+ "protocol": "TCP"
+ }
+ ],
+ "env": [
+ {
+ "name": "DB_SERVICE_PREFIX_MAPPING",
+ "value": "${APPLICATION_NAME}-mongodb=DB"
+ },
+ {
+ "name": "DB_JNDI",
+ "value": "${DB_JNDI}"
+ },
+ {
+ "name": "DB_USERNAME",
+ "value": "${DB_USERNAME}"
+ },
+ {
+ "name": "DB_PASSWORD",
+ "value": "${DB_PASSWORD}"
+ },
+ {
+ "name": "DB_DATABASE",
+ "value": "${DB_DATABASE}"
+ },
+ {
+ "name": "DB_ADMIN_PASSWORD",
+ "value": "${DB_ADMIN_PASSWORD}"
+ },
+ {
+ "name": "DB_MIN_POOL_SIZE",
+ "value": "${DB_MIN_POOL_SIZE}"
+ },
+ {
+ "name": "DB_MAX_POOL_SIZE",
+ "value": "${DB_MAX_POOL_SIZE}"
+ },
+ {
+ "name": "DB_TX_ISOLATION",
+ "value": "${DB_TX_ISOLATION}"
+ },
+ {
+ "name": "JWS_HTTPS_CERTIFICATE_DIR",
+ "value": "/etc/jws-secret-volume"
+ },
+ {
+ "name": "JWS_HTTPS_CERTIFICATE",
+ "value": "${JWS_HTTPS_CERTIFICATE}"
+ },
+ {
+ "name": "JWS_HTTPS_CERTIFICATE_KEY",
+ "value": "${JWS_HTTPS_CERTIFICATE_KEY}"
+ },
+ {
+ "name": "JWS_HTTPS_CERTIFICATE_PASSWORD",
+ "value": "${JWS_HTTPS_CERTIFICATE_PASSWORD}"
+ },
+ {
+ "name": "JWS_ADMIN_USERNAME",
+ "value": "${JWS_ADMIN_USERNAME}"
+ },
+ {
+ "name": "JWS_ADMIN_PASSWORD",
+ "value": "${JWS_ADMIN_PASSWORD}"
+ }
+ ]
+ }
+ ],
+ "volumes": [
+ {
+ "name": "jws-certificate-volume",
+ "secret": {
+ "secretName": "${JWS_HTTPS_SECRET}"
+ }
+ }
+ ]
+ }
+ }
+ }
+ },
+ {
+ "kind": "DeploymentConfig",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "${APPLICATION_NAME}-mongodb",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "strategy": {
+ "type": "Recreate"
+ },
+ "triggers": [
+ {
+ "type": "ImageChange",
+ "imageChangeParams": {
+ "automatic": true,
+ "containerNames": [
+ "${APPLICATION_NAME}-mongodb"
+ ],
+ "from": {
+ "kind": "ImageStreamTag",
+ "namespace": "openshift",
+ "name": "mongodb:latest"
+ }
+ }
+ }
+ ],
+ "replicas": 1,
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}-mongodb"
+ },
+ "template": {
+ "metadata": {
+ "name": "${APPLICATION_NAME}-mongodb",
+ "labels": {
+ "deploymentConfig": "${APPLICATION_NAME}-mongodb",
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "containers": [
+ {
+ "name": "${APPLICATION_NAME}-mongodb",
+ "image": "mongodb",
+ "imagePullPolicy": "Always",
+ "ports": [
+ {
+ "containerPort": 27017,
+ "protocol": "TCP"
+ }
+ ],
+ "env": [
+ {
+ "name": "MONGODB_USER",
+ "value": "${DB_USERNAME}"
+ },
+ {
+ "name": "MONGODB_PASSWORD",
+ "value": "${DB_PASSWORD}"
+ },
+ {
+ "name": "MONGODB_DATABASE",
+ "value": "${DB_DATABASE}"
+ },
+ {
+ "name": "MONGODB_ADMIN_PASSWORD",
+ "value": "${DB_ADMIN_PASSWORD}"
+ },
+ {
+ "name": "MONGODB_NOPREALLOC",
+ "value": "${MONGODB_NOPREALLOC}"
+ },
+ {
+ "name": "MONGODB_SMALLFILES",
+ "value": "${MONGODB_SMALLFILES}"
+ },
+ {
+ "name": "MONGODB_QUIET",
+ "value": "${MONGODB_QUIET}"
+ }
+ ]
+ }
+ ]
+ }
+ }
+ }
+ }
+ ]
+}
diff --git a/roles/openshift_examples/files/examples/xpaas-templates/jws-tomcat7-mysql-persistent-sti.json b/roles/openshift_examples/files/examples/xpaas-templates/jws-tomcat7-mysql-persistent-sti.json
new file mode 100644
index 000000000..547449010
--- /dev/null
+++ b/roles/openshift_examples/files/examples/xpaas-templates/jws-tomcat7-mysql-persistent-sti.json
@@ -0,0 +1,600 @@
+{
+ "kind": "Template",
+ "apiVersion": "v1",
+ "metadata": {
+ "annotations": {
+ "iconClass" : "icon-tomcat",
+ "description": "Application template for JWS MySQL applications with persistent storage built using STI."
+ },
+ "name": "jws-tomcat7-mysql-persistent-sti"
+ },
+ "labels": {
+ "template": "jws-tomcat7-mysql-persistent-sti"
+ },
+ "parameters": [
+ {
+ "description": "JWS Release version, e.g. 3.0, 2.1, etc.",
+ "name": "JWS_RELEASE",
+ "value": "3.0"
+ },
+ {
+ "description": "The name for the application.",
+ "name": "APPLICATION_NAME",
+ "value": "jws-app"
+ },
+ {
+ "description": "Custom hostname for service routes. Leave blank for default hostname, e.g.: <application-name>.<project>.<default-domain-suffix>",
+ "name": "APPLICATION_HOSTNAME",
+ "value": ""
+ },
+ {
+ "description": "Git source URI for application",
+ "name": "GIT_URI"
+ },
+ {
+ "description": "Git branch/tag reference",
+ "name": "GIT_REF",
+ "value": "master"
+ },
+ {
+ "description": "Path within Git project to build; empty for root project directory.",
+ "name": "GIT_CONTEXT_DIR",
+ "value": ""
+ },
+ {
+ "description": "Database JNDI name used by application to resolve the datasource, e.g. java:/jboss/datasources/mongodb",
+ "name": "DB_JNDI",
+ "value": ""
+ },
+ {
+ "description": "Database name",
+ "name": "DB_DATABASE",
+ "value": "root"
+ },
+ {
+ "description": "Size of persistent storage for database volume.",
+ "name": "VOLUME_CAPACITY",
+ "value": "512Mi"
+ },
+ {
+ "description": "The name of the secret containing the certificate files",
+ "name": "JWS_HTTPS_SECRET",
+ "value": "jws-app-secret"
+ },
+ {
+ "description": "The name of the certificate file within the secret",
+ "name": "JWS_HTTPS_CERTIFICATE",
+ "value": "server.crt"
+ },
+ {
+ "description": "The name of the certificate key file within the secret",
+ "name": "JWS_HTTPS_CERTIFICATE_KEY",
+ "value": "server.key"
+ },
+ {
+ "description": "The certificate password",
+ "name": "JWS_HTTPS_CERTIFICATE_PASSWORD",
+ "value": ""
+ },
+ {
+ "description": "Sets xa-pool/min-pool-size for the configured datasource.",
+ "name": "DB_MIN_POOL_SIZE"
+ },
+ {
+ "description": "Sets xa-pool/max-pool-size for the configured datasource.",
+ "name": "DB_MAX_POOL_SIZE"
+ },
+ {
+ "description": "Sets transaction-isolation for the configured datasource.",
+ "name": "DB_TX_ISOLATION"
+ },
+ {
+ "description": "Sets how the table names are stored and compared.",
+ "name": "MYSQL_LOWER_CASE_TABLE_NAMES"
+ },
+ {
+ "description": "The maximum permitted number of simultaneous client connections.",
+ "name": "MYSQL_MAX_CONNECTIONS"
+ },
+ {
+ "description": "The minimum length of the word to be included in a FULLTEXT index.",
+ "name": "MYSQL_FT_MIN_WORD_LEN"
+ },
+ {
+ "description": "The maximum length of the word to be included in a FULLTEXT index.",
+ "name": "MYSQL_FT_MAX_WORD_LEN"
+ },
+ {
+ "description": "Controls the innodb_use_native_aio setting value if the native AIO is broken.",
+ "name": "MYSQL_AIO"
+ },
+ {
+ "description": "Database user name",
+ "name": "DB_USERNAME",
+ "from": "user[a-zA-Z0-9]{3}",
+ "generate": "expression"
+ },
+ {
+ "description": "Database user password",
+ "name": "DB_PASSWORD",
+ "from": "[a-zA-Z0-9]{8}",
+ "generate": "expression"
+ },
+ {
+ "description": "JWS Admin User",
+ "name": "JWS_ADMIN_USERNAME",
+ "from": "[a-zA-Z0-9]{8}",
+ "generate": "expression"
+ },
+ {
+ "description": "JWS Admin Password",
+ "name": "JWS_ADMIN_PASSWORD",
+ "from": "[a-zA-Z0-9]{8}",
+ "generate": "expression"
+ },
+ {
+ "description": "Github trigger secret",
+ "name": "GITHUB_TRIGGER_SECRET",
+ "from": "[a-zA-Z0-9]{8}",
+ "generate": "expression"
+ },
+ {
+ "description": "Generic build trigger secret",
+ "name": "GENERIC_TRIGGER_SECRET",
+ "from": "[a-zA-Z0-9]{8}",
+ "generate": "expression"
+ }
+ ],
+ "objects": [
+ {
+ "kind": "Service",
+ "apiVersion": "v1",
+ "spec": {
+ "ports": [
+ {
+ "port": 8080,
+ "targetPort": 8080
+ }
+ ],
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}"
+ }
+ },
+ "metadata": {
+ "name": "${APPLICATION_NAME}",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "The web server's http port."
+ }
+ }
+ },
+ {
+ "kind": "Service",
+ "apiVersion": "v1",
+ "spec": {
+ "ports": [
+ {
+ "port": 8443,
+ "targetPort": 8443
+ }
+ ],
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}"
+ }
+ },
+ "metadata": {
+ "name": "secure-${APPLICATION_NAME}",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "The web server's https port."
+ }
+ }
+ },
+ {
+ "kind": "Service",
+ "apiVersion": "v1",
+ "spec": {
+ "ports": [
+ {
+ "port": 3306,
+ "targetPort": 3306
+ }
+ ],
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}-mysql"
+ }
+ },
+ "metadata": {
+ "name": "${APPLICATION_NAME}-mysql",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "The database server's port."
+ }
+ }
+ },
+ {
+ "kind": "Route",
+ "apiVersion": "v1",
+ "id": "${APPLICATION_NAME}-http-route",
+ "metadata": {
+ "name": "${APPLICATION_NAME}-http-route",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "Route for application's http service."
+ }
+ },
+ "spec": {
+ "host": "${APPLICATION_HOSTNAME}",
+ "to": {
+ "name": "${APPLICATION_NAME}"
+ }
+ }
+ },
+ {
+ "kind": "Route",
+ "apiVersion": "v1",
+ "id": "${APPLICATION_NAME}-https-route",
+ "metadata": {
+ "name": "${APPLICATION_NAME}-https-route",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "Route for application's https service."
+ }
+ },
+ "spec": {
+ "host": "${APPLICATION_HOSTNAME}",
+ "to": {
+ "name": "secure-${APPLICATION_NAME}"
+ },
+ "tls": {
+ "termination" : "passthrough"
+ }
+ }
+ },
+ {
+ "kind": "ImageStream",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "${APPLICATION_NAME}",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ }
+ }
+ },
+ {
+ "kind": "BuildConfig",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "${APPLICATION_NAME}",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "source": {
+ "type": "Git",
+ "git": {
+ "uri": "${GIT_URI}",
+ "ref": "${GIT_REF}"
+ },
+ "contextDir":"${GIT_CONTEXT_DIR}"
+ },
+ "strategy": {
+ "type": "Source",
+ "sourceStrategy": {
+ "from": {
+ "kind": "ImageStreamTag",
+ "namespace": "openshift",
+ "name": "jboss-webserver3-tomcat7-openshift:${JWS_RELEASE}"
+ }
+ }
+ },
+ "output": {
+ "to": {
+ "kind": "ImageStreamTag",
+ "name": "${APPLICATION_NAME}:latest"
+ }
+ },
+ "triggers": [
+ {
+ "type": "GitHub",
+ "github": {
+ "secret": "${GITHUB_TRIGGER_SECRET}"
+ }
+ },
+ {
+ "type": "Generic",
+ "generic": {
+ "secret": "${GENERIC_TRIGGER_SECRET}"
+ }
+ },
+ {
+ "type": "ImageChange",
+ "imageChange": {}
+ }
+ ]
+ }
+ },
+ {
+ "kind": "DeploymentConfig",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "${APPLICATION_NAME}",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "strategy": {
+ "type": "Recreate"
+ },
+ "triggers": [
+ {
+ "type": "ImageChange",
+ "imageChangeParams": {
+ "automatic": true,
+ "containerNames": [
+ "${APPLICATION_NAME}"
+ ],
+ "from": {
+ "kind": "ImageStream",
+ "name": "${APPLICATION_NAME}"
+ }
+ }
+ }
+ ],
+ "replicas": 1,
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}"
+ },
+ "template": {
+ "metadata": {
+ "name": "${APPLICATION_NAME}",
+ "labels": {
+ "deploymentConfig": "${APPLICATION_NAME}",
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "serviceAccount": "jws-service-account",
+ "containers": [
+ {
+ "name": "${APPLICATION_NAME}",
+ "image": "${APPLICATION_NAME}",
+ "imagePullPolicy": "Always",
+ "readinessProbe": {
+ "exec": {
+ "command": [
+ "/bin/bash",
+ "-c",
+ "curl -s -u ${JWS_ADMIN_USERNAME}:${JWS_ADMIN_PASSWORD} 'http://localhost:8080/manager/jmxproxy/?get=Catalina%3Atype%3DServer&att=stateName' |grep -iq 'stateName *= *STARTED'"
+ ]
+ }
+ },
+ "volumeMounts": [
+ {
+ "name": "jws-certificate-volume",
+ "mountPath": "/etc/jws-secret-volume",
+ "readOnly": true
+ }
+ ],
+ "ports": [
+ {
+ "name": "http",
+ "containerPort": 8080,
+ "protocol": "TCP"
+ },
+ {
+ "name": "https",
+ "containerPort": 8443,
+ "protocol": "TCP"
+ }
+ ],
+ "env": [
+ {
+ "name": "DB_SERVICE_PREFIX_MAPPING",
+ "value": "${APPLICATION_NAME}-mysql=DB"
+ },
+ {
+ "name": "DB_JNDI",
+ "value": "${DB_JNDI}"
+ },
+ {
+ "name": "DB_USERNAME",
+ "value": "${DB_USERNAME}"
+ },
+ {
+ "name": "DB_PASSWORD",
+ "value": "${DB_PASSWORD}"
+ },
+ {
+ "name": "DB_DATABASE",
+ "value": "${DB_DATABASE}"
+ },
+ {
+ "name": "DB_MIN_POOL_SIZE",
+ "value": "${DB_MIN_POOL_SIZE}"
+ },
+ {
+ "name": "DB_MAX_POOL_SIZE",
+ "value": "${DB_MAX_POOL_SIZE}"
+ },
+ {
+ "name": "DB_TX_ISOLATION",
+ "value": "${DB_TX_ISOLATION}"
+ },
+ {
+ "name": "JWS_HTTPS_CERTIFICATE_DIR",
+ "value": "/etc/jws-secret-volume"
+ },
+ {
+ "name": "JWS_HTTPS_CERTIFICATE",
+ "value": "${JWS_HTTPS_CERTIFICATE}"
+ },
+ {
+ "name": "JWS_HTTPS_CERTIFICATE_KEY",
+ "value": "${JWS_HTTPS_CERTIFICATE_KEY}"
+ },
+ {
+ "name": "JWS_HTTPS_CERTIFICATE_PASSWORD",
+ "value": "${JWS_HTTPS_CERTIFICATE_PASSWORD}"
+ },
+ {
+ "name": "JWS_ADMIN_USERNAME",
+ "value": "${JWS_ADMIN_USERNAME}"
+ },
+ {
+ "name": "JWS_ADMIN_PASSWORD",
+ "value": "${JWS_ADMIN_PASSWORD}"
+ }
+ ]
+ }
+ ],
+ "volumes": [
+ {
+ "name": "jws-certificate-volume",
+ "secret": {
+ "secretName": "${JWS_HTTPS_SECRET}"
+ }
+ }
+ ]
+ }
+ }
+ }
+ },
+ {
+ "kind": "DeploymentConfig",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "${APPLICATION_NAME}-mysql",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "strategy": {
+ "type": "Recreate"
+ },
+ "triggers": [
+ {
+ "type": "ImageChange",
+ "imageChangeParams": {
+ "automatic": true,
+ "containerNames": [
+ "${APPLICATION_NAME}-mysql"
+ ],
+ "from": {
+ "kind": "ImageStreamTag",
+ "namespace": "openshift",
+ "name": "mysql:latest"
+ }
+ }
+ }
+ ],
+ "replicas": 1,
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}-mysql"
+ },
+ "template": {
+ "metadata": {
+ "name": "${APPLICATION_NAME}-mysql",
+ "labels": {
+ "deploymentConfig": "${APPLICATION_NAME}-mysql",
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "containers": [
+ {
+ "name": "${APPLICATION_NAME}-mysql",
+ "image": "mysql",
+ "ports": [
+ {
+ "containerPort": 3306,
+ "protocol": "TCP"
+ }
+ ],
+ "volumeMounts": [
+ {
+ "mountPath": "/var/lib/mysql/data",
+ "name": "${APPLICATION_NAME}-mysql-pvol"
+ }
+ ],
+ "env": [
+ {
+ "name": "MYSQL_USER",
+ "value": "${DB_USERNAME}"
+ },
+ {
+ "name": "MYSQL_PASSWORD",
+ "value": "${DB_PASSWORD}"
+ },
+ {
+ "name": "MYSQL_DATABASE",
+ "value": "${DB_DATABASE}"
+ },
+ {
+ "name": "MYSQL_LOWER_CASE_TABLE_NAMES",
+ "value": "${MYSQL_LOWER_CASE_TABLE_NAMES}"
+ },
+ {
+ "name": "MYSQL_MAX_CONNECTIONS",
+ "value": "${MYSQL_MAX_CONNECTIONS}"
+ },
+ {
+ "name": "MYSQL_FT_MIN_WORD_LEN",
+ "value": "${MYSQL_FT_MIN_WORD_LEN}"
+ },
+ {
+ "name": "MYSQL_FT_MAX_WORD_LEN",
+ "value": "${MYSQL_FT_MAX_WORD_LEN}"
+ },
+ {
+ "name": "MYSQL_AIO",
+ "value": "${MYSQL_AIO}"
+ }
+ ]
+ }
+ ],
+ "volumes": [
+ {
+ "name": "${APPLICATION_NAME}-mysql-pvol",
+ "persistentVolumeClaim": {
+ "claimName": "${APPLICATION_NAME}-mysql-claim"
+ }
+ }
+ ]
+ }
+ }
+ }
+ },
+ {
+ "apiVersion": "v1",
+ "kind": "PersistentVolumeClaim",
+ "metadata": {
+ "name": "${APPLICATION_NAME}-mysql-claim",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "accessModes": [ "ReadWriteOnce" ],
+ "resources": {
+ "requests": {
+ "storage": "${VOLUME_CAPACITY}"
+ }
+ }
+ }
+ }
+ ]
+}
diff --git a/roles/openshift_examples/files/examples/xpaas-templates/jws-tomcat7-mysql-sti.json b/roles/openshift_examples/files/examples/xpaas-templates/jws-tomcat7-mysql-sti.json
new file mode 100644
index 000000000..2ae59ec71
--- /dev/null
+++ b/roles/openshift_examples/files/examples/xpaas-templates/jws-tomcat7-mysql-sti.json
@@ -0,0 +1,563 @@
+{
+ "kind": "Template",
+ "apiVersion": "v1",
+ "metadata": {
+ "annotations": {
+ "iconClass" : "icon-tomcat",
+ "description": "Application template for JWS MySQL applications built using STI."
+ },
+ "name": "jws-tomcat7-mysql-sti"
+ },
+ "labels": {
+ "template": "jws-tomcat7-mysql-sti"
+ },
+ "parameters": [
+ {
+ "description": "JWS Release version, e.g. 3.0, 2.1, etc.",
+ "name": "JWS_RELEASE",
+ "value": "3.0"
+ },
+ {
+ "description": "The name for the application.",
+ "name": "APPLICATION_NAME",
+ "value": "jws-app"
+ },
+ {
+ "description": "Custom hostname for service routes. Leave blank for default hostname, e.g.: <application-name>.<project>.<default-domain-suffix>",
+ "name": "APPLICATION_HOSTNAME",
+ "value": ""
+ },
+ {
+ "description": "Git source URI for application",
+ "name": "GIT_URI"
+ },
+ {
+ "description": "Git branch/tag reference",
+ "name": "GIT_REF",
+ "value": "master"
+ },
+ {
+ "description": "Path within Git project to build; empty for root project directory.",
+ "name": "GIT_CONTEXT_DIR",
+ "value": ""
+ },
+ {
+ "description": "Database JNDI name used by application to resolve the datasource, e.g. java:/jboss/datasources/mongodb",
+ "name": "DB_JNDI",
+ "value": ""
+ },
+ {
+ "description": "Database name",
+ "name": "DB_DATABASE",
+ "value": "root"
+ },
+ {
+ "description": "The name of the secret containing the certificate files",
+ "name": "JWS_HTTPS_SECRET",
+ "value": "jws-app-secret"
+ },
+ {
+ "description": "The name of the certificate file within the secret",
+ "name": "JWS_HTTPS_CERTIFICATE",
+ "value": "server.crt"
+ },
+ {
+ "description": "The name of the certificate key file within the secret",
+ "name": "JWS_HTTPS_CERTIFICATE_KEY",
+ "value": "server.key"
+ },
+ {
+ "description": "The certificate password",
+ "name": "JWS_HTTPS_CERTIFICATE_PASSWORD",
+ "value": ""
+ },
+ {
+ "description": "Sets xa-pool/min-pool-size for the configured datasource.",
+ "name": "DB_MIN_POOL_SIZE"
+ },
+ {
+ "description": "Sets xa-pool/max-pool-size for the configured datasource.",
+ "name": "DB_MAX_POOL_SIZE"
+ },
+ {
+ "description": "Sets transaction-isolation for the configured datasource.",
+ "name": "DB_TX_ISOLATION"
+ },
+ {
+ "description": "Sets how the table names are stored and compared.",
+ "name": "MYSQL_LOWER_CASE_TABLE_NAMES"
+ },
+ {
+ "description": "The maximum permitted number of simultaneous client connections.",
+ "name": "MYSQL_MAX_CONNECTIONS"
+ },
+ {
+ "description": "The minimum length of the word to be included in a FULLTEXT index.",
+ "name": "MYSQL_FT_MIN_WORD_LEN"
+ },
+ {
+ "description": "The maximum length of the word to be included in a FULLTEXT index.",
+ "name": "MYSQL_FT_MAX_WORD_LEN"
+ },
+ {
+ "description": "Controls the innodb_use_native_aio setting value if the native AIO is broken.",
+ "name": "MYSQL_AIO"
+ },
+ {
+ "description": "Database user name",
+ "name": "DB_USERNAME",
+ "from": "user[a-zA-Z0-9]{3}",
+ "generate": "expression"
+ },
+ {
+ "description": "Database user password",
+ "name": "DB_PASSWORD",
+ "from": "[a-zA-Z0-9]{8}",
+ "generate": "expression"
+ },
+ {
+ "description": "JWS Admin User",
+ "name": "JWS_ADMIN_USERNAME",
+ "from": "[a-zA-Z0-9]{8}",
+ "generate": "expression"
+ },
+ {
+ "description": "JWS Admin Password",
+ "name": "JWS_ADMIN_PASSWORD",
+ "from": "[a-zA-Z0-9]{8}",
+ "generate": "expression"
+ },
+ {
+ "description": "Github trigger secret",
+ "name": "GITHUB_TRIGGER_SECRET",
+ "from": "[a-zA-Z0-9]{8}",
+ "generate": "expression"
+ },
+ {
+ "description": "Generic build trigger secret",
+ "name": "GENERIC_TRIGGER_SECRET",
+ "from": "[a-zA-Z0-9]{8}",
+ "generate": "expression"
+ }
+ ],
+ "objects": [
+ {
+ "kind": "Service",
+ "apiVersion": "v1",
+ "spec": {
+ "ports": [
+ {
+ "port": 8080,
+ "targetPort": 8080
+ }
+ ],
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}"
+ }
+ },
+ "metadata": {
+ "name": "${APPLICATION_NAME}",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "The web server's http port."
+ }
+ }
+ },
+ {
+ "kind": "Service",
+ "apiVersion": "v1",
+ "spec": {
+ "ports": [
+ {
+ "port": 8443,
+ "targetPort": 8443
+ }
+ ],
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}"
+ }
+ },
+ "metadata": {
+ "name": "secure-${APPLICATION_NAME}",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "The web server's https port."
+ }
+ }
+ },
+ {
+ "kind": "Service",
+ "apiVersion": "v1",
+ "spec": {
+ "ports": [
+ {
+ "port": 3306,
+ "targetPort": 3306
+ }
+ ],
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}-mysql"
+ }
+ },
+ "metadata": {
+ "name": "${APPLICATION_NAME}-mysql",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "The database server's port."
+ }
+ }
+ },
+ {
+ "kind": "Route",
+ "apiVersion": "v1",
+ "id": "${APPLICATION_NAME}-http-route",
+ "metadata": {
+ "name": "${APPLICATION_NAME}-http-route",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "Route for application's http service."
+ }
+ },
+ "spec": {
+ "host": "${APPLICATION_HOSTNAME}",
+ "to": {
+ "name": "${APPLICATION_NAME}"
+ }
+ }
+ },
+ {
+ "kind": "Route",
+ "apiVersion": "v1",
+ "id": "${APPLICATION_NAME}-https-route",
+ "metadata": {
+ "name": "${APPLICATION_NAME}-https-route",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "Route for application's https service."
+ }
+ },
+ "spec": {
+ "host": "${APPLICATION_HOSTNAME}",
+ "to": {
+ "name": "secure-${APPLICATION_NAME}"
+ },
+ "tls": {
+ "termination" : "passthrough"
+ }
+ }
+ },
+ {
+ "kind": "ImageStream",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "${APPLICATION_NAME}",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ }
+ }
+ },
+ {
+ "kind": "BuildConfig",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "${APPLICATION_NAME}",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "source": {
+ "type": "Git",
+ "git": {
+ "uri": "${GIT_URI}",
+ "ref": "${GIT_REF}"
+ },
+ "contextDir":"${GIT_CONTEXT_DIR}"
+ },
+ "strategy": {
+ "type": "Source",
+ "sourceStrategy": {
+ "from": {
+ "kind": "ImageStreamTag",
+ "namespace": "openshift",
+ "name": "jboss-webserver3-tomcat7-openshift:${JWS_RELEASE}"
+ }
+ }
+ },
+ "output": {
+ "to": {
+ "kind": "ImageStreamTag",
+ "name": "${APPLICATION_NAME}:latest"
+ }
+ },
+ "triggers": [
+ {
+ "type": "GitHub",
+ "github": {
+ "secret": "${GITHUB_TRIGGER_SECRET}"
+ }
+ },
+ {
+ "type": "Generic",
+ "generic": {
+ "secret": "${GENERIC_TRIGGER_SECRET}"
+ }
+ },
+ {
+ "type": "ImageChange",
+ "imageChange": {}
+ }
+ ]
+ }
+ },
+ {
+ "kind": "DeploymentConfig",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "${APPLICATION_NAME}",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "strategy": {
+ "type": "Recreate"
+ },
+ "triggers": [
+ {
+ "type": "ImageChange",
+ "imageChangeParams": {
+ "automatic": true,
+ "containerNames": [
+ "${APPLICATION_NAME}"
+ ],
+ "from": {
+ "kind": "ImageStream",
+ "name": "${APPLICATION_NAME}"
+ }
+ }
+ }
+ ],
+ "replicas": 1,
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}"
+ },
+ "template": {
+ "metadata": {
+ "name": "${APPLICATION_NAME}",
+ "labels": {
+ "deploymentConfig": "${APPLICATION_NAME}",
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "serviceAccount": "jws-service-account",
+ "containers": [
+ {
+ "name": "${APPLICATION_NAME}",
+ "image": "${APPLICATION_NAME}",
+ "imagePullPolicy": "Always",
+ "readinessProbe": {
+ "exec": {
+ "command": [
+ "/bin/bash",
+ "-c",
+ "curl -s -u ${JWS_ADMIN_USERNAME}:${JWS_ADMIN_PASSWORD} 'http://localhost:8080/manager/jmxproxy/?get=Catalina%3Atype%3DServer&att=stateName' |grep -iq 'stateName *= *STARTED'"
+ ]
+ }
+ },
+ "volumeMounts": [
+ {
+ "name": "jws-certificate-volume",
+ "mountPath": "/etc/jws-secret-volume",
+ "readOnly": true
+ }
+ ],
+ "ports": [
+ {
+ "name": "http",
+ "containerPort": 8080,
+ "protocol": "TCP"
+ },
+ {
+ "name": "https",
+ "containerPort": 8443,
+ "protocol": "TCP"
+ }
+ ],
+ "env": [
+ {
+ "name": "DB_SERVICE_PREFIX_MAPPING",
+ "value": "${APPLICATION_NAME}-mysql=DB"
+ },
+ {
+ "name": "DB_JNDI",
+ "value": "${DB_JNDI}"
+ },
+ {
+ "name": "DB_USERNAME",
+ "value": "${DB_USERNAME}"
+ },
+ {
+ "name": "DB_PASSWORD",
+ "value": "${DB_PASSWORD}"
+ },
+ {
+ "name": "DB_DATABASE",
+ "value": "${DB_DATABASE}"
+ },
+ {
+ "name": "DB_MIN_POOL_SIZE",
+ "value": "${DB_MIN_POOL_SIZE}"
+ },
+ {
+ "name": "DB_MAX_POOL_SIZE",
+ "value": "${DB_MAX_POOL_SIZE}"
+ },
+ {
+ "name": "DB_TX_ISOLATION",
+ "value": "${DB_TX_ISOLATION}"
+ },
+ {
+ "name": "JWS_HTTPS_CERTIFICATE_DIR",
+ "value": "/etc/jws-secret-volume"
+ },
+ {
+ "name": "JWS_HTTPS_CERTIFICATE",
+ "value": "${JWS_HTTPS_CERTIFICATE}"
+ },
+ {
+ "name": "JWS_HTTPS_CERTIFICATE_KEY",
+ "value": "${JWS_HTTPS_CERTIFICATE_KEY}"
+ },
+ {
+ "name": "JWS_HTTPS_CERTIFICATE_PASSWORD",
+ "value": "${JWS_HTTPS_CERTIFICATE_PASSWORD}"
+ },
+ {
+ "name": "JWS_ADMIN_USERNAME",
+ "value": "${JWS_ADMIN_USERNAME}"
+ },
+ {
+ "name": "JWS_ADMIN_PASSWORD",
+ "value": "${JWS_ADMIN_PASSWORD}"
+ }
+ ]
+ }
+ ],
+ "volumes": [
+ {
+ "name": "jws-certificate-volume",
+ "secret": {
+ "secretName": "${JWS_HTTPS_SECRET}"
+ }
+ }
+ ]
+ }
+ }
+ }
+ },
+ {
+ "kind": "DeploymentConfig",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "${APPLICATION_NAME}-mysql",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "strategy": {
+ "type": "Recreate"
+ },
+ "triggers": [
+ {
+ "type": "ImageChange",
+ "imageChangeParams": {
+ "automatic": true,
+ "containerNames": [
+ "${APPLICATION_NAME}-mysql"
+ ],
+ "from": {
+ "kind": "ImageStreamTag",
+ "namespace": "openshift",
+ "name": "mysql:latest"
+ }
+ }
+ }
+ ],
+ "replicas": 1,
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}-mysql"
+ },
+ "template": {
+ "metadata": {
+ "name": "${APPLICATION_NAME}-mysql",
+ "labels": {
+ "deploymentConfig": "${APPLICATION_NAME}-mysql",
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "containers": [
+ {
+ "name": "${APPLICATION_NAME}-mysql",
+ "image": "mysql",
+ "ports": [
+ {
+ "containerPort": 3306,
+ "protocol": "TCP"
+ }
+ ],
+ "env": [
+ {
+ "name": "MYSQL_USER",
+ "value": "${DB_USERNAME}"
+ },
+ {
+ "name": "MYSQL_PASSWORD",
+ "value": "${DB_PASSWORD}"
+ },
+ {
+ "name": "MYSQL_DATABASE",
+ "value": "${DB_DATABASE}"
+ },
+ {
+ "name": "MYSQL_LOWER_CASE_TABLE_NAMES",
+ "value": "${MYSQL_LOWER_CASE_TABLE_NAMES}"
+ },
+ {
+ "name": "MYSQL_MAX_CONNECTIONS",
+ "value": "${MYSQL_MAX_CONNECTIONS}"
+ },
+ {
+ "name": "MYSQL_FT_MIN_WORD_LEN",
+ "value": "${MYSQL_FT_MIN_WORD_LEN}"
+ },
+ {
+ "name": "MYSQL_FT_MAX_WORD_LEN",
+ "value": "${MYSQL_FT_MAX_WORD_LEN}"
+ },
+ {
+ "name": "MYSQL_AIO",
+ "value": "${MYSQL_AIO}"
+ }
+ ]
+ }
+ ]
+ }
+ }
+ }
+ }
+ ]
+}
diff --git a/roles/openshift_examples/files/examples/xpaas-templates/jws-tomcat7-postgresql-persistent-sti.json b/roles/openshift_examples/files/examples/xpaas-templates/jws-tomcat7-postgresql-persistent-sti.json
new file mode 100644
index 000000000..b871b48d0
--- /dev/null
+++ b/roles/openshift_examples/files/examples/xpaas-templates/jws-tomcat7-postgresql-persistent-sti.json
@@ -0,0 +1,576 @@
+{
+ "kind": "Template",
+ "apiVersion": "v1",
+ "metadata": {
+ "annotations": {
+ "iconClass" : "icon-tomcat",
+ "description": "Application template for JWS PostgreSQL applications with persistent storage built using STI."
+ },
+ "name": "jws-tomcat7-postgresql-persistent-sti"
+ },
+ "labels": {
+ "template": "jws-tomcat7-postgresql-persistent-sti"
+ },
+ "parameters": [
+ {
+ "description": "JWS Release version, e.g. 3.0, 2.1, etc.",
+ "name": "JWS_RELEASE",
+ "value": "3.0"
+ },
+ {
+ "description": "The name for the application.",
+ "name": "APPLICATION_NAME",
+ "value": "jws-app"
+ },
+ {
+ "description": "Custom hostname for service routes. Leave blank for default hostname, e.g.: <application-name>.<project>.<default-domain-suffix>",
+ "name": "APPLICATION_HOSTNAME",
+ "value": ""
+ },
+ {
+ "description": "Git source URI for application",
+ "name": "GIT_URI"
+ },
+ {
+ "description": "Git branch/tag reference",
+ "name": "GIT_REF",
+ "value": "master"
+ },
+ {
+ "description": "Path within Git project to build; empty for root project directory.",
+ "name": "GIT_CONTEXT_DIR",
+ "value": ""
+ },
+ {
+ "description": "Database JNDI name used by application to resolve the datasource, e.g. java:/jboss/datasources/mongodb",
+ "name": "DB_JNDI",
+ "value": ""
+ },
+ {
+ "description": "Database name",
+ "name": "DB_DATABASE",
+ "value": "root"
+ },
+ {
+ "description": "Size of persistent storage for database volume.",
+ "name": "VOLUME_CAPACITY",
+ "value": "512Mi"
+ },
+ {
+ "description": "The name of the secret containing the certificate files",
+ "name": "JWS_HTTPS_SECRET",
+ "value": "jws-app-secret"
+ },
+ {
+ "description": "The name of the certificate file within the secret",
+ "name": "JWS_HTTPS_CERTIFICATE",
+ "value": "server.crt"
+ },
+ {
+ "description": "The name of the certificate key file within the secret",
+ "name": "JWS_HTTPS_CERTIFICATE_KEY",
+ "value": "server.key"
+ },
+ {
+ "description": "The certificate password",
+ "name": "JWS_HTTPS_CERTIFICATE_PASSWORD",
+ "value": ""
+ },
+ {
+ "description": "Sets xa-pool/min-pool-size for the configured datasource.",
+ "name": "DB_MIN_POOL_SIZE"
+ },
+ {
+ "description": "Sets xa-pool/max-pool-size for the configured datasource.",
+ "name": "DB_MAX_POOL_SIZE"
+ },
+ {
+ "description": "Sets transaction-isolation for the configured datasource.",
+ "name": "DB_TX_ISOLATION"
+ },
+ {
+ "description": "The maximum number of client connections allowed. This also sets the maximum number of prepared transactions.",
+ "name": "POSTGRESQL_MAX_CONNECTIONS"
+ },
+ {
+ "description": "Configures how much memory is dedicated to PostgreSQL for caching data.",
+ "name": "POSTGRESQL_SHARED_BUFFERS"
+ },
+ {
+ "description": "Database user name",
+ "name": "DB_USERNAME",
+ "from": "user[a-zA-Z0-9]{3}",
+ "generate": "expression"
+ },
+ {
+ "description": "Database user password",
+ "name": "DB_PASSWORD",
+ "from": "[a-zA-Z0-9]{8}",
+ "generate": "expression"
+ },
+ {
+ "description": "JWS Admin User",
+ "name": "JWS_ADMIN_USERNAME",
+ "from": "[a-zA-Z0-9]{8}",
+ "generate": "expression"
+ },
+ {
+ "description": "JWS Admin Password",
+ "name": "JWS_ADMIN_PASSWORD",
+ "from": "[a-zA-Z0-9]{8}",
+ "generate": "expression"
+ },
+ {
+ "description": "Github trigger secret",
+ "name": "GITHUB_TRIGGER_SECRET",
+ "from": "[a-zA-Z0-9]{8}",
+ "generate": "expression"
+ },
+ {
+ "description": "Generic build trigger secret",
+ "name": "GENERIC_TRIGGER_SECRET",
+ "from": "[a-zA-Z0-9]{8}",
+ "generate": "expression"
+ }
+ ],
+ "objects": [
+ {
+ "kind": "Service",
+ "apiVersion": "v1",
+ "spec": {
+ "ports": [
+ {
+ "port": 8080,
+ "targetPort": 8080
+ }
+ ],
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}"
+ }
+ },
+ "metadata": {
+ "name": "${APPLICATION_NAME}",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "The web server's http port."
+ }
+ }
+ },
+ {
+ "kind": "Service",
+ "apiVersion": "v1",
+ "spec": {
+ "ports": [
+ {
+ "port": 8443,
+ "targetPort": 8443
+ }
+ ],
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}"
+ }
+ },
+ "metadata": {
+ "name": "secure-${APPLICATION_NAME}",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "The web server's https port."
+ }
+ }
+ },
+ {
+ "kind": "Service",
+ "apiVersion": "v1",
+ "spec": {
+ "ports": [
+ {
+ "port": 5432,
+ "targetPort": 5432
+ }
+ ],
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}-postgresql"
+ }
+ },
+ "metadata": {
+ "name": "${APPLICATION_NAME}-postgresql",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "The database server's port."
+ }
+ }
+ },
+ {
+ "kind": "Route",
+ "apiVersion": "v1",
+ "id": "${APPLICATION_NAME}-http-route",
+ "metadata": {
+ "name": "${APPLICATION_NAME}-http-route",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "Route for application's http service."
+ }
+ },
+ "spec": {
+ "host": "${APPLICATION_HOSTNAME}",
+ "to": {
+ "name": "${APPLICATION_NAME}"
+ }
+ }
+ },
+ {
+ "kind": "Route",
+ "apiVersion": "v1",
+ "id": "${APPLICATION_NAME}-https-route",
+ "metadata": {
+ "name": "${APPLICATION_NAME}-https-route",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "Route for application's https service."
+ }
+ },
+ "spec": {
+ "host": "${APPLICATION_HOSTNAME}",
+ "to": {
+ "name": "secure-${APPLICATION_NAME}"
+ },
+ "tls": {
+ "termination" : "passthrough"
+ }
+ }
+ },
+ {
+ "kind": "ImageStream",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "${APPLICATION_NAME}",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ }
+ }
+ },
+ {
+ "kind": "BuildConfig",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "${APPLICATION_NAME}",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "source": {
+ "type": "Git",
+ "git": {
+ "uri": "${GIT_URI}",
+ "ref": "${GIT_REF}"
+ },
+ "contextDir":"${GIT_CONTEXT_DIR}"
+ },
+ "strategy": {
+ "type": "Source",
+ "sourceStrategy": {
+ "from": {
+ "kind": "ImageStreamTag",
+ "namespace": "openshift",
+ "name": "jboss-webserver3-tomcat7-openshift:${JWS_RELEASE}"
+ }
+ }
+ },
+ "output": {
+ "to": {
+ "kind": "ImageStreamTag",
+ "name": "${APPLICATION_NAME}:latest"
+ }
+ },
+ "triggers": [
+ {
+ "type": "GitHub",
+ "github": {
+ "secret": "${GITHUB_TRIGGER_SECRET}"
+ }
+ },
+ {
+ "type": "Generic",
+ "generic": {
+ "secret": "${GENERIC_TRIGGER_SECRET}"
+ }
+ },
+ {
+ "type": "ImageChange",
+ "imageChange": {}
+ }
+ ]
+ }
+ },
+ {
+ "kind": "DeploymentConfig",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "${APPLICATION_NAME}",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "strategy": {
+ "type": "Recreate"
+ },
+ "triggers": [
+ {
+ "type": "ImageChange",
+ "imageChangeParams": {
+ "automatic": true,
+ "containerNames": [
+ "${APPLICATION_NAME}"
+ ],
+ "from": {
+ "kind": "ImageStream",
+ "name": "${APPLICATION_NAME}"
+ }
+ }
+ }
+ ],
+ "replicas": 1,
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}"
+ },
+ "template": {
+ "metadata": {
+ "name": "${APPLICATION_NAME}",
+ "labels": {
+ "deploymentConfig": "${APPLICATION_NAME}",
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "serviceAccount": "jws-service-account",
+ "containers": [
+ {
+ "name": "${APPLICATION_NAME}",
+ "image": "${APPLICATION_NAME}",
+ "imagePullPolicy": "Always",
+ "readinessProbe": {
+ "exec": {
+ "command": [
+ "/bin/bash",
+ "-c",
+ "curl -s -u ${JWS_ADMIN_USERNAME}:${JWS_ADMIN_PASSWORD} 'http://localhost:8080/manager/jmxproxy/?get=Catalina%3Atype%3DServer&att=stateName' |grep -iq 'stateName *= *STARTED'"
+ ]
+ }
+ },
+ "volumeMounts": [
+ {
+ "name": "jws-certificate-volume",
+ "mountPath": "/etc/jws-secret-volume",
+ "readOnly": true
+ }
+ ],
+ "ports": [
+ {
+ "name": "http",
+ "containerPort": 8080,
+ "protocol": "TCP"
+ },
+ {
+ "name": "https",
+ "containerPort": 8443,
+ "protocol": "TCP"
+ }
+ ],
+ "env": [
+ {
+ "name": "DB_SERVICE_PREFIX_MAPPING",
+ "value": "${APPLICATION_NAME}-postgresql=DB"
+ },
+ {
+ "name": "DB_JNDI",
+ "value": "${DB_JNDI}"
+ },
+ {
+ "name": "DB_USERNAME",
+ "value": "${DB_USERNAME}"
+ },
+ {
+ "name": "DB_PASSWORD",
+ "value": "${DB_PASSWORD}"
+ },
+ {
+ "name": "DB_DATABASE",
+ "value": "${DB_DATABASE}"
+ },
+ {
+ "name": "DB_MIN_POOL_SIZE",
+ "value": "${DB_MIN_POOL_SIZE}"
+ },
+ {
+ "name": "DB_MAX_POOL_SIZE",
+ "value": "${DB_MAX_POOL_SIZE}"
+ },
+ {
+ "name": "DB_TX_ISOLATION",
+ "value": "${DB_TX_ISOLATION}"
+ },
+ {
+ "name": "JWS_HTTPS_CERTIFICATE_DIR",
+ "value": "/etc/jws-secret-volume"
+ },
+ {
+ "name": "JWS_HTTPS_CERTIFICATE",
+ "value": "${JWS_HTTPS_CERTIFICATE}"
+ },
+ {
+ "name": "JWS_HTTPS_CERTIFICATE_KEY",
+ "value": "${JWS_HTTPS_CERTIFICATE_KEY}"
+ },
+ {
+ "name": "JWS_HTTPS_CERTIFICATE_PASSWORD",
+ "value": "${JWS_HTTPS_CERTIFICATE_PASSWORD}"
+ },
+ {
+ "name": "JWS_ADMIN_USERNAME",
+ "value": "${JWS_ADMIN_USERNAME}"
+ },
+ {
+ "name": "JWS_ADMIN_PASSWORD",
+ "value": "${JWS_ADMIN_PASSWORD}"
+ }
+ ]
+ }
+ ],
+ "volumes": [
+ {
+ "name": "jws-certificate-volume",
+ "secret": {
+ "secretName": "${JWS_HTTPS_SECRET}"
+ }
+ }
+ ]
+ }
+ }
+ }
+ },
+ {
+ "kind": "DeploymentConfig",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "${APPLICATION_NAME}-postgresql",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "strategy": {
+ "type": "Recreate"
+ },
+ "triggers": [
+ {
+ "type": "ImageChange",
+ "imageChangeParams": {
+ "automatic": true,
+ "containerNames": [
+ "${APPLICATION_NAME}-postgresql"
+ ],
+ "from": {
+ "kind": "ImageStreamTag",
+ "namespace": "openshift",
+ "name": "postgresql:latest"
+ }
+ }
+ }
+ ],
+ "replicas": 1,
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}-postgresql"
+ },
+ "template": {
+ "metadata": {
+ "name": "${APPLICATION_NAME}-postgresql",
+ "labels": {
+ "deploymentConfig": "${APPLICATION_NAME}-postgresql",
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "containers": [
+ {
+ "name": "${APPLICATION_NAME}-postgresql",
+ "image": "postgresql",
+ "ports": [
+ {
+ "containerPort": 5432,
+ "protocol": "TCP"
+ }
+ ],
+ "volumeMounts": [
+ {
+ "mountPath": "/var/lib/pgsql/data",
+ "name": "${APPLICATION_NAME}-postgresql-pvol"
+ }
+ ],
+ "env": [
+ {
+ "name": "POSTGRESQL_USER",
+ "value": "${DB_USERNAME}"
+ },
+ {
+ "name": "POSTGRESQL_PASSWORD",
+ "value": "${DB_PASSWORD}"
+ },
+ {
+ "name": "POSTGRESQL_DATABASE",
+ "value": "${DB_DATABASE}"
+ },
+ {
+ "name": "POSTGRESQL_MAX_CONNECTIONS",
+ "value": "${POSTGRESQL_MAX_CONNECTIONS}"
+ },
+ {
+ "name": "POSTGRESQL_SHARED_BUFFERS",
+ "value": "${POSTGRESQL_SHARED_BUFFERS}"
+ }
+ ]
+ }
+ ],
+ "volumes": [
+ {
+ "name": "${APPLICATION_NAME}-postgresql-pvol",
+ "persistentVolumeClaim": {
+ "claimName": "${APPLICATION_NAME}-postgresql-claim"
+ }
+ }
+ ]
+ }
+ }
+ }
+ },
+ {
+ "apiVersion": "v1",
+ "kind": "PersistentVolumeClaim",
+ "metadata": {
+ "name": "${APPLICATION_NAME}-postgresql-claim",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "accessModes": [ "ReadWriteOnce" ],
+ "resources": {
+ "requests": {
+ "storage": "${VOLUME_CAPACITY}"
+ }
+ }
+ }
+ }
+ ]
+}
diff --git a/roles/openshift_examples/files/examples/xpaas-templates/jws-tomcat7-postgresql-sti.json b/roles/openshift_examples/files/examples/xpaas-templates/jws-tomcat7-postgresql-sti.json
new file mode 100644
index 000000000..384ff1b8f
--- /dev/null
+++ b/roles/openshift_examples/files/examples/xpaas-templates/jws-tomcat7-postgresql-sti.json
@@ -0,0 +1,539 @@
+{
+ "kind": "Template",
+ "apiVersion": "v1",
+ "metadata": {
+ "annotations": {
+ "iconClass" : "icon-tomcat",
+ "description": "Application template for JWS PostgreSQL applications built using STI."
+ },
+ "name": "jws-tomcat7-postgresql-sti"
+ },
+ "labels": {
+ "template": "jws-tomcat7-postgresql-sti"
+ },
+ "parameters": [
+ {
+ "description": "JWS Release version, e.g. 3.0, 2.1, etc.",
+ "name": "JWS_RELEASE",
+ "value": "3.0"
+ },
+ {
+ "description": "The name for the application.",
+ "name": "APPLICATION_NAME",
+ "value": "jws-app"
+ },
+ {
+ "description": "Custom hostname for service routes. Leave blank for default hostname, e.g.: <application-name>.<project>.<default-domain-suffix>",
+ "name": "APPLICATION_HOSTNAME",
+ "value": ""
+ },
+ {
+ "description": "Git source URI for application",
+ "name": "GIT_URI"
+ },
+ {
+ "description": "Git branch/tag reference",
+ "name": "GIT_REF",
+ "value": "master"
+ },
+ {
+ "description": "Path within Git project to build; empty for root project directory.",
+ "name": "GIT_CONTEXT_DIR",
+ "value": ""
+ },
+ {
+ "description": "Database JNDI name used by application to resolve the datasource, e.g. java:/jboss/datasources/mongodb",
+ "name": "DB_JNDI",
+ "value": ""
+ },
+ {
+ "description": "Database name",
+ "name": "DB_DATABASE",
+ "value": "root"
+ },
+ {
+ "description": "The name of the secret containing the certificate files",
+ "name": "JWS_HTTPS_SECRET",
+ "value": "jws-app-secret"
+ },
+ {
+ "description": "The name of the certificate file within the secret",
+ "name": "JWS_HTTPS_CERTIFICATE",
+ "value": "server.crt"
+ },
+ {
+ "description": "The name of the certificate key file within the secret",
+ "name": "JWS_HTTPS_CERTIFICATE_KEY",
+ "value": "server.key"
+ },
+ {
+ "description": "The certificate password",
+ "name": "JWS_HTTPS_CERTIFICATE_PASSWORD",
+ "value": ""
+ },
+ {
+ "description": "Sets xa-pool/min-pool-size for the configured datasource.",
+ "name": "DB_MIN_POOL_SIZE"
+ },
+ {
+ "description": "Sets xa-pool/max-pool-size for the configured datasource.",
+ "name": "DB_MAX_POOL_SIZE"
+ },
+ {
+ "description": "Sets transaction-isolation for the configured datasource.",
+ "name": "DB_TX_ISOLATION"
+ },
+ {
+ "description": "The maximum number of client connections allowed. This also sets the maximum number of prepared transactions.",
+ "name": "POSTGRESQL_MAX_CONNECTIONS"
+ },
+ {
+ "description": "Configures how much memory is dedicated to PostgreSQL for caching data.",
+ "name": "POSTGRESQL_SHARED_BUFFERS"
+ },
+ {
+ "description": "Database user name",
+ "name": "DB_USERNAME",
+ "from": "user[a-zA-Z0-9]{3}",
+ "generate": "expression"
+ },
+ {
+ "description": "Database user password",
+ "name": "DB_PASSWORD",
+ "from": "[a-zA-Z0-9]{8}",
+ "generate": "expression"
+ },
+ {
+ "description": "JWS Admin User",
+ "name": "JWS_ADMIN_USERNAME",
+ "from": "[a-zA-Z0-9]{8}",
+ "generate": "expression"
+ },
+ {
+ "description": "JWS Admin Password",
+ "name": "JWS_ADMIN_PASSWORD",
+ "from": "[a-zA-Z0-9]{8}",
+ "generate": "expression"
+ },
+ {
+ "description": "Github trigger secret",
+ "name": "GITHUB_TRIGGER_SECRET",
+ "from": "[a-zA-Z0-9]{8}",
+ "generate": "expression"
+ },
+ {
+ "description": "Generic build trigger secret",
+ "name": "GENERIC_TRIGGER_SECRET",
+ "from": "[a-zA-Z0-9]{8}",
+ "generate": "expression"
+ }
+ ],
+ "objects": [
+ {
+ "kind": "Service",
+ "apiVersion": "v1",
+ "spec": {
+ "ports": [
+ {
+ "port": 8080,
+ "targetPort": 8080
+ }
+ ],
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}"
+ }
+ },
+ "metadata": {
+ "name": "${APPLICATION_NAME}",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "The web server's http port."
+ }
+ }
+ },
+ {
+ "kind": "Service",
+ "apiVersion": "v1",
+ "spec": {
+ "ports": [
+ {
+ "port": 8443,
+ "targetPort": 8443
+ }
+ ],
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}"
+ }
+ },
+ "metadata": {
+ "name": "secure-${APPLICATION_NAME}",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "The web server's https port."
+ }
+ }
+ },
+ {
+ "kind": "Service",
+ "apiVersion": "v1",
+ "spec": {
+ "ports": [
+ {
+ "port": 5432,
+ "targetPort": 5432
+ }
+ ],
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}-postgresql"
+ }
+ },
+ "metadata": {
+ "name": "${APPLICATION_NAME}-postgresql",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "The database server's port."
+ }
+ }
+ },
+ {
+ "kind": "Route",
+ "apiVersion": "v1",
+ "id": "${APPLICATION_NAME}-http-route",
+ "metadata": {
+ "name": "${APPLICATION_NAME}-http-route",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "Route for application's http service."
+ }
+ },
+ "spec": {
+ "host": "${APPLICATION_HOSTNAME}",
+ "to": {
+ "name": "${APPLICATION_NAME}"
+ }
+ }
+ },
+ {
+ "kind": "Route",
+ "apiVersion": "v1",
+ "id": "${APPLICATION_NAME}-https-route",
+ "metadata": {
+ "name": "${APPLICATION_NAME}-https-route",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "Route for application's https service."
+ }
+ },
+ "spec": {
+ "host": "${APPLICATION_HOSTNAME}",
+ "to": {
+ "name": "secure-${APPLICATION_NAME}"
+ },
+ "tls": {
+ "termination" : "passthrough"
+ }
+ }
+ },
+ {
+ "kind": "ImageStream",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "${APPLICATION_NAME}",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ }
+ }
+ },
+ {
+ "kind": "BuildConfig",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "${APPLICATION_NAME}",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "source": {
+ "type": "Git",
+ "git": {
+ "uri": "${GIT_URI}",
+ "ref": "${GIT_REF}"
+ },
+ "contextDir":"${GIT_CONTEXT_DIR}"
+ },
+ "strategy": {
+ "type": "Source",
+ "sourceStrategy": {
+ "from": {
+ "kind": "ImageStreamTag",
+ "namespace": "openshift",
+ "name": "jboss-webserver3-tomcat7-openshift:${JWS_RELEASE}"
+ }
+ }
+ },
+ "output": {
+ "to": {
+ "kind": "ImageStreamTag",
+ "name": "${APPLICATION_NAME}:latest"
+ }
+ },
+ "triggers": [
+ {
+ "type": "GitHub",
+ "github": {
+ "secret": "${GITHUB_TRIGGER_SECRET}"
+ }
+ },
+ {
+ "type": "Generic",
+ "generic": {
+ "secret": "${GENERIC_TRIGGER_SECRET}"
+ }
+ },
+ {
+ "type": "ImageChange",
+ "imageChange": {}
+ }
+ ]
+ }
+ },
+ {
+ "kind": "DeploymentConfig",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "${APPLICATION_NAME}",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "strategy": {
+ "type": "Recreate"
+ },
+ "triggers": [
+ {
+ "type": "ImageChange",
+ "imageChangeParams": {
+ "automatic": true,
+ "containerNames": [
+ "${APPLICATION_NAME}"
+ ],
+ "from": {
+ "kind": "ImageStream",
+ "name": "${APPLICATION_NAME}"
+ }
+ }
+ }
+ ],
+ "replicas": 1,
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}"
+ },
+ "template": {
+ "metadata": {
+ "name": "${APPLICATION_NAME}",
+ "labels": {
+ "deploymentConfig": "${APPLICATION_NAME}",
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "serviceAccount": "jws-service-account",
+ "containers": [
+ {
+ "name": "${APPLICATION_NAME}",
+ "image": "${APPLICATION_NAME}",
+ "imagePullPolicy": "Always",
+ "readinessProbe": {
+ "exec": {
+ "command": [
+ "/bin/bash",
+ "-c",
+ "curl -s -u ${JWS_ADMIN_USERNAME}:${JWS_ADMIN_PASSWORD} 'http://localhost:8080/manager/jmxproxy/?get=Catalina%3Atype%3DServer&att=stateName' |grep -iq 'stateName *= *STARTED'"
+ ]
+ }
+ },
+ "volumeMounts": [
+ {
+ "name": "jws-certificate-volume",
+ "mountPath": "/etc/jws-secret-volume",
+ "readOnly": true
+ }
+ ],
+ "ports": [
+ {
+ "name": "http",
+ "containerPort": 8080,
+ "protocol": "TCP"
+ },
+ {
+ "name": "https",
+ "containerPort": 8443,
+ "protocol": "TCP"
+ }
+ ],
+ "env": [
+ {
+ "name": "DB_SERVICE_PREFIX_MAPPING",
+ "value": "${APPLICATION_NAME}-postgresql=DB"
+ },
+ {
+ "name": "DB_JNDI",
+ "value": "${DB_JNDI}"
+ },
+ {
+ "name": "DB_USERNAME",
+ "value": "${DB_USERNAME}"
+ },
+ {
+ "name": "DB_PASSWORD",
+ "value": "${DB_PASSWORD}"
+ },
+ {
+ "name": "DB_DATABASE",
+ "value": "${DB_DATABASE}"
+ },
+ {
+ "name": "DB_MIN_POOL_SIZE",
+ "value": "${DB_MIN_POOL_SIZE}"
+ },
+ {
+ "name": "DB_MAX_POOL_SIZE",
+ "value": "${DB_MAX_POOL_SIZE}"
+ },
+ {
+ "name": "DB_TX_ISOLATION",
+ "value": "${DB_TX_ISOLATION}"
+ },
+ {
+ "name": "JWS_HTTPS_CERTIFICATE_DIR",
+ "value": "/etc/jws-secret-volume"
+ },
+ {
+ "name": "JWS_HTTPS_CERTIFICATE",
+ "value": "${JWS_HTTPS_CERTIFICATE}"
+ },
+ {
+ "name": "JWS_HTTPS_CERTIFICATE_KEY",
+ "value": "${JWS_HTTPS_CERTIFICATE_KEY}"
+ },
+ {
+ "name": "JWS_HTTPS_CERTIFICATE_PASSWORD",
+ "value": "${JWS_HTTPS_CERTIFICATE_PASSWORD}"
+ },
+ {
+ "name": "JWS_ADMIN_USERNAME",
+ "value": "${JWS_ADMIN_USERNAME}"
+ },
+ {
+ "name": "JWS_ADMIN_PASSWORD",
+ "value": "${JWS_ADMIN_PASSWORD}"
+ }
+ ]
+ }
+ ],
+ "volumes": [
+ {
+ "name": "jws-certificate-volume",
+ "secret": {
+ "secretName": "${JWS_HTTPS_SECRET}"
+ }
+ }
+ ]
+ }
+ }
+ }
+ },
+ {
+ "kind": "DeploymentConfig",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "${APPLICATION_NAME}-postgresql",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "strategy": {
+ "type": "Recreate"
+ },
+ "triggers": [
+ {
+ "type": "ImageChange",
+ "imageChangeParams": {
+ "automatic": true,
+ "containerNames": [
+ "${APPLICATION_NAME}-postgresql"
+ ],
+ "from": {
+ "kind": "ImageStreamTag",
+ "namespace": "openshift",
+ "name": "postgresql:latest"
+ }
+ }
+ }
+ ],
+ "replicas": 1,
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}-postgresql"
+ },
+ "template": {
+ "metadata": {
+ "name": "${APPLICATION_NAME}-postgresql",
+ "labels": {
+ "deploymentConfig": "${APPLICATION_NAME}-postgresql",
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "containers": [
+ {
+ "name": "${APPLICATION_NAME}-postgresql",
+ "image": "postgresql",
+ "ports": [
+ {
+ "containerPort": 5432,
+ "protocol": "TCP"
+ }
+ ],
+ "env": [
+ {
+ "name": "POSTGRESQL_USER",
+ "value": "${DB_USERNAME}"
+ },
+ {
+ "name": "POSTGRESQL_PASSWORD",
+ "value": "${DB_PASSWORD}"
+ },
+ {
+ "name": "POSTGRESQL_DATABASE",
+ "value": "${DB_DATABASE}"
+ },
+ {
+ "name": "POSTGRESQL_MAX_CONNECTIONS",
+ "value": "${POSTGRESQL_MAX_CONNECTIONS}"
+ },
+ {
+ "name": "POSTGRESQL_SHARED_BUFFERS",
+ "value": "${POSTGRESQL_SHARED_BUFFERS}"
+ }
+ ]
+ }
+ ]
+ }
+ }
+ }
+ }
+ ]
+}
diff --git a/roles/openshift_examples/files/examples/xpaas-templates/jws-tomcat8-basic-sti.json b/roles/openshift_examples/files/examples/xpaas-templates/jws-tomcat8-basic-sti.json
new file mode 100644
index 000000000..3c7812b69
--- /dev/null
+++ b/roles/openshift_examples/files/examples/xpaas-templates/jws-tomcat8-basic-sti.json
@@ -0,0 +1,257 @@
+{
+ "kind": "Template",
+ "apiVersion": "v1",
+ "metadata": {
+ "annotations": {
+ "iconClass" : "icon-tomcat",
+ "description": "Application template for JWS applications built using STI."
+ },
+ "name": "jws-tomcat8-basic-sti"
+ },
+ "labels": {
+ "template": "jws-tomcat8-basic-sti"
+ },
+ "parameters": [
+ {
+ "description": "JWS Release version, e.g. 3.0, 2.1, etc.",
+ "name": "JWS_RELEASE",
+ "value": "3.0"
+ },
+ {
+ "description": "The name for the application.",
+ "name": "APPLICATION_NAME",
+ "value": "jws-app"
+ },
+ {
+ "description": "Custom hostname for service routes. Leave blank for default hostname, e.g.: <application-name>.<project>.<default-domain-suffix>",
+ "name": "APPLICATION_HOSTNAME",
+ "value": ""
+ },
+ {
+ "description": "Git source URI for application",
+ "name": "GIT_URI"
+ },
+ {
+ "description": "Git branch/tag reference",
+ "name": "GIT_REF",
+ "value": "master"
+ },
+ {
+ "description": "Path within Git project to build; empty for root project directory.",
+ "name": "GIT_CONTEXT_DIR",
+ "value": ""
+ },
+ {
+ "description": "JWS Admin User",
+ "name": "JWS_ADMIN_USERNAME",
+ "from": "[a-zA-Z0-9]{8}",
+ "generate": "expression"
+ },
+ {
+ "description": "JWS Admin Password",
+ "name": "JWS_ADMIN_PASSWORD",
+ "from": "[a-zA-Z0-9]{8}",
+ "generate": "expression"
+ },
+ {
+ "description": "Github trigger secret",
+ "name": "GITHUB_TRIGGER_SECRET",
+ "from": "[a-zA-Z0-9]{8}",
+ "generate": "expression"
+ },
+ {
+ "description": "Generic build trigger secret",
+ "name": "GENERIC_TRIGGER_SECRET",
+ "from": "[a-zA-Z0-9]{8}",
+ "generate": "expression"
+ }
+ ],
+ "objects": [
+ {
+ "kind": "Service",
+ "apiVersion": "v1",
+ "spec": {
+ "ports": [
+ {
+ "port": 8080,
+ "targetPort": 8080
+ }
+ ],
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}"
+ }
+ },
+ "metadata": {
+ "name": "${APPLICATION_NAME}",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "The web server's http port."
+ }
+ }
+ },
+ {
+ "kind": "Route",
+ "apiVersion": "v1",
+ "id": "${APPLICATION_NAME}-http-route",
+ "metadata": {
+ "name": "${APPLICATION_NAME}-http-route",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "Route for application's http service."
+ }
+ },
+ "spec": {
+ "host": "${APPLICATION_HOSTNAME}",
+ "to": {
+ "name": "${APPLICATION_NAME}"
+ }
+ }
+ },
+ {
+ "kind": "ImageStream",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "${APPLICATION_NAME}",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ }
+ }
+ },
+ {
+ "kind": "BuildConfig",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "${APPLICATION_NAME}",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "source": {
+ "type": "Git",
+ "git": {
+ "uri": "${GIT_URI}",
+ "ref": "${GIT_REF}"
+ },
+ "contextDir":"${GIT_CONTEXT_DIR}"
+ },
+ "strategy": {
+ "type": "Source",
+ "sourceStrategy": {
+ "from": {
+ "kind": "ImageStreamTag",
+ "namespace": "openshift",
+ "name": "jboss-webserver3-tomcat8-openshift:${JWS_RELEASE}"
+ }
+ }
+ },
+ "output": {
+ "to": {
+ "kind": "ImageStreamTag",
+ "name": "${APPLICATION_NAME}:latest"
+ }
+ },
+ "triggers": [
+ {
+ "type": "GitHub",
+ "github": {
+ "secret": "${GITHUB_TRIGGER_SECRET}"
+ }
+ },
+ {
+ "type": "Generic",
+ "generic": {
+ "secret": "${GENERIC_TRIGGER_SECRET}"
+ }
+ },
+ {
+ "type": "ImageChange",
+ "imageChange": {}
+ }
+ ]
+ }
+ },
+ {
+ "kind": "DeploymentConfig",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "${APPLICATION_NAME}",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "strategy": {
+ "type": "Recreate"
+ },
+ "triggers": [
+ {
+ "type": "ImageChange",
+ "imageChangeParams": {
+ "automatic": true,
+ "containerNames": [
+ "${APPLICATION_NAME}"
+ ],
+ "from": {
+ "kind": "ImageStream",
+ "name": "${APPLICATION_NAME}"
+ }
+ }
+ }
+ ],
+ "replicas": 1,
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}"
+ },
+ "template": {
+ "metadata": {
+ "name": "${APPLICATION_NAME}",
+ "labels": {
+ "deploymentConfig": "${APPLICATION_NAME}",
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "containers": [
+ {
+ "name": "${APPLICATION_NAME}",
+ "image": "${APPLICATION_NAME}",
+ "imagePullPolicy": "Always",
+ "readinessProbe": {
+ "exec": {
+ "command": [
+ "/bin/bash",
+ "-c",
+ "curl -s -u ${JWS_ADMIN_USERNAME}:${JWS_ADMIN_PASSWORD} 'http://localhost:8080/manager/jmxproxy/?get=Catalina%3Atype%3DServer&att=stateName' |grep -iq 'stateName *= *STARTED'"
+ ]
+ }
+ },
+ "ports": [
+ {
+ "name": "http",
+ "containerPort": 8080,
+ "protocol": "TCP"
+ }
+ ],
+ "env": [
+ {
+ "name": "JWS_ADMIN_USERNAME",
+ "value": "${JWS_ADMIN_USERNAME}"
+ },
+ {
+ "name": "JWS_ADMIN_PASSWORD",
+ "value": "${JWS_ADMIN_PASSWORD}"
+ }
+ ]
+ }
+ ]
+ }
+ }
+ }
+ }
+ ]
+}
diff --git a/roles/openshift_examples/files/examples/xpaas-templates/jws-tomcat8-https-sti.json b/roles/openshift_examples/files/examples/xpaas-templates/jws-tomcat8-https-sti.json
new file mode 100644
index 000000000..d725e0606
--- /dev/null
+++ b/roles/openshift_examples/files/examples/xpaas-templates/jws-tomcat8-https-sti.json
@@ -0,0 +1,361 @@
+{
+ "kind": "Template",
+ "apiVersion": "v1",
+ "metadata": {
+ "annotations": {
+ "iconClass" : "icon-tomcat",
+ "description": "Application template for JWS applications built using STI."
+ },
+ "name": "jws-tomcat8-basic-sti"
+ },
+ "labels": {
+ "template": "jws-tomcat8-basic-sti"
+ },
+ "parameters": [
+ {
+ "description": "JWS Release version, e.g. 3.0, 2.1, etc.",
+ "name": "JWS_RELEASE",
+ "value": "3.0"
+ },
+ {
+ "description": "The name for the application.",
+ "name": "APPLICATION_NAME",
+ "value": "jws-app"
+ },
+ {
+ "description": "Custom hostname for service routes. Leave blank for default hostname, e.g.: <application-name>.<project>.<default-domain-suffix>",
+ "name": "APPLICATION_HOSTNAME",
+ "value": ""
+ },
+ {
+ "description": "Git source URI for application",
+ "name": "GIT_URI"
+ },
+ {
+ "description": "Git branch/tag reference",
+ "name": "GIT_REF",
+ "value": "master"
+ },
+ {
+ "description": "Path within Git project to build; empty for root project directory.",
+ "name": "GIT_CONTEXT_DIR",
+ "value": ""
+ },
+ {
+ "description": "The name of the secret containing the certificate files",
+ "name": "JWS_HTTPS_SECRET",
+ "value": "jws-app-secret"
+ },
+ {
+ "description": "The name of the certificate file within the secret",
+ "name": "JWS_HTTPS_CERTIFICATE",
+ "value": "server.crt"
+ },
+ {
+ "description": "The name of the certificate key file within the secret",
+ "name": "JWS_HTTPS_CERTIFICATE_KEY",
+ "value": "server.key"
+ },
+ {
+ "description": "The certificate password",
+ "name": "JWS_HTTPS_CERTIFICATE_PASSWORD",
+ "value": ""
+ },
+ {
+ "description": "JWS Admin User",
+ "name": "JWS_ADMIN_USERNAME",
+ "from": "[a-zA-Z0-9]{8}",
+ "generate": "expression"
+ },
+ {
+ "description": "JWS Admin Password",
+ "name": "JWS_ADMIN_PASSWORD",
+ "from": "[a-zA-Z0-9]{8}",
+ "generate": "expression"
+ },
+ {
+ "description": "Github trigger secret",
+ "name": "GITHUB_TRIGGER_SECRET",
+ "from": "[a-zA-Z0-9]{8}",
+ "generate": "expression"
+ },
+ {
+ "description": "Generic build trigger secret",
+ "name": "GENERIC_TRIGGER_SECRET",
+ "from": "[a-zA-Z0-9]{8}",
+ "generate": "expression"
+ }
+ ],
+ "objects": [
+ {
+ "kind": "Service",
+ "apiVersion": "v1",
+ "spec": {
+ "ports": [
+ {
+ "port": 8080,
+ "targetPort": 8080
+ }
+ ],
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}"
+ }
+ },
+ "metadata": {
+ "name": "${APPLICATION_NAME}",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "The web server's http port."
+ }
+ }
+ },
+ {
+ "kind": "Service",
+ "apiVersion": "v1",
+ "spec": {
+ "ports": [
+ {
+ "port": 8443,
+ "targetPort": 8443
+ }
+ ],
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}"
+ }
+ },
+ "metadata": {
+ "name": "secure-${APPLICATION_NAME}",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "The web server's https port."
+ }
+ }
+ },
+ {
+ "kind": "Route",
+ "apiVersion": "v1",
+ "id": "${APPLICATION_NAME}-http-route",
+ "metadata": {
+ "name": "${APPLICATION_NAME}-http-route",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "Route for application's http service."
+ }
+ },
+ "spec": {
+ "host": "${APPLICATION_HOSTNAME}",
+ "to": {
+ "name": "${APPLICATION_NAME}"
+ }
+ }
+ },
+ {
+ "kind": "Route",
+ "apiVersion": "v1",
+ "id": "${APPLICATION_NAME}-https-route",
+ "metadata": {
+ "name": "${APPLICATION_NAME}-https-route",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "Route for application's https service."
+ }
+ },
+ "spec": {
+ "host": "${APPLICATION_HOSTNAME}",
+ "to": {
+ "name": "secure-${APPLICATION_NAME}"
+ },
+ "tls": {
+ "termination" : "passthrough"
+ }
+ }
+ },
+ {
+ "kind": "ImageStream",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "${APPLICATION_NAME}",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ }
+ }
+ },
+ {
+ "kind": "BuildConfig",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "${APPLICATION_NAME}",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "source": {
+ "type": "Git",
+ "git": {
+ "uri": "${GIT_URI}",
+ "ref": "${GIT_REF}"
+ },
+ "contextDir":"${GIT_CONTEXT_DIR}"
+ },
+ "strategy": {
+ "type": "Source",
+ "sourceStrategy": {
+ "from": {
+ "kind": "ImageStreamTag",
+ "namespace": "openshift",
+ "name": "jboss-webserver3-tomcat8-openshift:${JWS_RELEASE}"
+ }
+ }
+ },
+ "output": {
+ "to": {
+ "kind": "ImageStreamTag",
+ "name": "${APPLICATION_NAME}:latest"
+ }
+ },
+ "triggers": [
+ {
+ "type": "GitHub",
+ "github": {
+ "secret": "${GITHUB_TRIGGER_SECRET}"
+ }
+ },
+ {
+ "type": "Generic",
+ "generic": {
+ "secret": "${GENERIC_TRIGGER_SECRET}"
+ }
+ },
+ {
+ "type": "ImageChange",
+ "imageChange": {}
+ }
+ ]
+ }
+ },
+ {
+ "kind": "DeploymentConfig",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "${APPLICATION_NAME}",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "strategy": {
+ "type": "Recreate"
+ },
+ "triggers": [
+ {
+ "type": "ImageChange",
+ "imageChangeParams": {
+ "automatic": true,
+ "containerNames": [
+ "${APPLICATION_NAME}"
+ ],
+ "from": {
+ "kind": "ImageStream",
+ "name": "${APPLICATION_NAME}"
+ }
+ }
+ }
+ ],
+ "replicas": 1,
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}"
+ },
+ "template": {
+ "metadata": {
+ "name": "${APPLICATION_NAME}",
+ "labels": {
+ "deploymentConfig": "${APPLICATION_NAME}",
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "serviceAccount": "jws-service-account",
+ "containers": [
+ {
+ "name": "${APPLICATION_NAME}",
+ "image": "${APPLICATION_NAME}",
+ "imagePullPolicy": "Always",
+ "readinessProbe": {
+ "exec": {
+ "command": [
+ "/bin/bash",
+ "-c",
+ "curl -s -u ${JWS_ADMIN_USERNAME}:${JWS_ADMIN_PASSWORD} 'http://localhost:8080/manager/jmxproxy/?get=Catalina%3Atype%3DServer&att=stateName' |grep -iq 'stateName *= *STARTED'"
+ ]
+ }
+ },
+ "volumeMounts": [
+ {
+ "name": "jws-certificate-volume",
+ "mountPath": "/etc/jws-secret-volume",
+ "readOnly": true
+ }
+ ],
+ "ports": [
+ {
+ "name": "http",
+ "containerPort": 8080,
+ "protocol": "TCP"
+ },
+ {
+ "name": "https",
+ "containerPort": 8443,
+ "protocol": "TCP"
+ }
+ ],
+ "env": [
+ {
+ "name": "JWS_HTTPS_CERTIFICATE_DIR",
+ "value": "/etc/jws-secret-volume"
+ },
+ {
+ "name": "JWS_HTTPS_CERTIFICATE",
+ "value": "${JWS_HTTPS_CERTIFICATE}"
+ },
+ {
+ "name": "JWS_HTTPS_CERTIFICATE_KEY",
+ "value": "${JWS_HTTPS_CERTIFICATE_KEY}"
+ },
+ {
+ "name": "JWS_HTTPS_CERTIFICATE_PASSWORD",
+ "value": "${JWS_HTTPS_CERTIFICATE_PASSWORD}"
+ },
+ {
+ "name": "JWS_ADMIN_USERNAME",
+ "value": "${JWS_ADMIN_USERNAME}"
+ },
+ {
+ "name": "JWS_ADMIN_PASSWORD",
+ "value": "${JWS_ADMIN_PASSWORD}"
+ }
+ ]
+ }
+ ],
+ "volumes": [
+ {
+ "name": "jws-certificate-volume",
+ "secret": {
+ "secretName": "${JWS_HTTPS_SECRET}"
+ }
+ }
+ ]
+ }
+ }
+ }
+ }
+ ]
+}
diff --git a/roles/openshift_examples/files/examples/xpaas-templates/jws-tomcat8-mongodb-persistent-sti.json b/roles/openshift_examples/files/examples/xpaas-templates/jws-tomcat8-mongodb-persistent-sti.json
new file mode 100644
index 000000000..cf35d0024
--- /dev/null
+++ b/roles/openshift_examples/files/examples/xpaas-templates/jws-tomcat8-mongodb-persistent-sti.json
@@ -0,0 +1,599 @@
+{
+ "kind": "Template",
+ "apiVersion": "v1",
+ "metadata": {
+ "annotations": {
+ "iconClass" : "icon-tomcat",
+ "description": "Application template for JWS MongoDB applications with persistent storage built using STI."
+ },
+ "name": "jws-tomcat8-mongodb-persistent-sti"
+ },
+ "labels": {
+ "template": "jws-tomcat8-mongodb-persistent-sti"
+ },
+ "parameters": [
+ {
+ "description": "JWS Release version, e.g. 3.0, 2.1, etc.",
+ "name": "JWS_RELEASE",
+ "value": "3.0"
+ },
+ {
+ "description": "The name for the application.",
+ "name": "APPLICATION_NAME",
+ "value": "jws-app"
+ },
+ {
+ "description": "Custom hostname for service routes. Leave blank for default hostname, e.g.: <application-name>.<project>.<default-domain-suffix>",
+ "name": "APPLICATION_HOSTNAME",
+ "value": ""
+ },
+ {
+ "description": "Git source URI for application",
+ "name": "GIT_URI"
+ },
+ {
+ "description": "Git branch/tag reference",
+ "name": "GIT_REF",
+ "value": "master"
+ },
+ {
+ "description": "Path within Git project to build; empty for root project directory.",
+ "name": "GIT_CONTEXT_DIR",
+ "value": ""
+ },
+ {
+ "description": "Database JNDI name used by application to resolve the datasource, e.g. java:/jboss/datasources/mongodb",
+ "name": "DB_JNDI",
+ "value": ""
+ },
+ {
+ "description": "Database name",
+ "name": "DB_DATABASE",
+ "value": "root"
+ },
+ {
+ "description": "Size of persistent storage for database volume.",
+ "name": "VOLUME_CAPACITY",
+ "value": "512Mi"
+ },
+ {
+ "description": "The name of the secret containing the certificate files",
+ "name": "JWS_HTTPS_SECRET",
+ "value": "jws-app-secret"
+ },
+ {
+ "description": "The name of the certificate file within the secret",
+ "name": "JWS_HTTPS_CERTIFICATE",
+ "value": "server.crt"
+ },
+ {
+ "description": "The name of the certificate key file within the secret",
+ "name": "JWS_HTTPS_CERTIFICATE_KEY",
+ "value": "server.key"
+ },
+ {
+ "description": "The certificate password",
+ "name": "JWS_HTTPS_CERTIFICATE_PASSWORD",
+ "value": ""
+ },
+ {
+ "description": "Sets xa-pool/min-pool-size for the configured datasource.",
+ "name": "DB_MIN_POOL_SIZE"
+ },
+ {
+ "description": "Sets xa-pool/max-pool-size for the configured datasource.",
+ "name": "DB_MAX_POOL_SIZE"
+ },
+ {
+ "description": "Sets transaction-isolation for the configured datasource.",
+ "name": "DB_TX_ISOLATION"
+ },
+ {
+ "description": "Disable data file preallocation.",
+ "name": "MONGODB_NOPREALLOC"
+ },
+ {
+ "description": "Set MongoDB to use a smaller default data file size.",
+ "name": "MONGODB_SMALLFILES"
+ },
+ {
+ "description": "Runs MongoDB in a quiet mode that attempts to limit the amount of output.",
+ "name": "MONGODB_QUIET"
+ },
+ {
+ "description": "Database user name",
+ "name": "DB_USERNAME",
+ "from": "user[a-zA-Z0-9]{3}",
+ "generate": "expression"
+ },
+ {
+ "description": "Database user password",
+ "name": "DB_PASSWORD",
+ "from": "[a-zA-Z0-9]{8}",
+ "generate": "expression"
+ },
+ {
+ "description": "Database admin password",
+ "name": "DB_ADMIN_PASSWORD",
+ "from": "[a-zA-Z0-9]{8}",
+ "generate": "expression"
+ },
+ {
+ "description": "JWS Admin User",
+ "name": "JWS_ADMIN_USERNAME",
+ "from": "[a-zA-Z0-9]{8}",
+ "generate": "expression"
+ },
+ {
+ "description": "JWS Admin Password",
+ "name": "JWS_ADMIN_PASSWORD",
+ "from": "[a-zA-Z0-9]{8}",
+ "generate": "expression"
+ },
+ {
+ "description": "Github trigger secret",
+ "name": "GITHUB_TRIGGER_SECRET",
+ "from": "[a-zA-Z0-9]{8}",
+ "generate": "expression"
+ },
+ {
+ "description": "Generic build trigger secret",
+ "name": "GENERIC_TRIGGER_SECRET",
+ "from": "[a-zA-Z0-9]{8}",
+ "generate": "expression"
+ }
+ ],
+ "objects": [
+ {
+ "kind": "Service",
+ "apiVersion": "v1",
+ "spec": {
+ "ports": [
+ {
+ "port": 8080,
+ "targetPort": 8080
+ }
+ ],
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}"
+ }
+ },
+ "metadata": {
+ "name": "${APPLICATION_NAME}",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "The web server's http port."
+ }
+ }
+ },
+ {
+ "kind": "Service",
+ "apiVersion": "v1",
+ "spec": {
+ "ports": [
+ {
+ "port": 8443,
+ "targetPort": 8443
+ }
+ ],
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}"
+ }
+ },
+ "metadata": {
+ "name": "secure-${APPLICATION_NAME}",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "The web server's https port."
+ }
+ }
+ },
+ {
+ "kind": "Service",
+ "apiVersion": "v1",
+ "spec": {
+ "ports": [
+ {
+ "port": 27017,
+ "targetPort": 27017
+ }
+ ],
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}-mongodb"
+ }
+ },
+ "metadata": {
+ "name": "${APPLICATION_NAME}-mongodb",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "The database server's port."
+ }
+ }
+ },
+ {
+ "kind": "Route",
+ "apiVersion": "v1",
+ "id": "${APPLICATION_NAME}-http-route",
+ "metadata": {
+ "name": "${APPLICATION_NAME}-http-route",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "Route for application's http service."
+ }
+ },
+ "spec": {
+ "host": "${APPLICATION_HOSTNAME}",
+ "to": {
+ "name": "${APPLICATION_NAME}"
+ }
+ }
+ },
+ {
+ "kind": "Route",
+ "apiVersion": "v1",
+ "id": "${APPLICATION_NAME}-https-route",
+ "metadata": {
+ "name": "${APPLICATION_NAME}-https-route",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "Route for application's https service."
+ }
+ },
+ "spec": {
+ "host": "${APPLICATION_HOSTNAME}",
+ "to": {
+ "name": "secure-${APPLICATION_NAME}"
+ },
+ "tls": {
+ "termination" : "passthrough"
+ }
+ }
+ },
+ {
+ "kind": "ImageStream",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "${APPLICATION_NAME}",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ }
+ }
+ },
+ {
+ "kind": "BuildConfig",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "${APPLICATION_NAME}",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "source": {
+ "type": "Git",
+ "git": {
+ "uri": "${GIT_URI}",
+ "ref": "${GIT_REF}"
+ },
+ "contextDir":"${GIT_CONTEXT_DIR}"
+ },
+ "strategy": {
+ "type": "Source",
+ "sourceStrategy": {
+ "from": {
+ "kind": "ImageStreamTag",
+ "namespace": "openshift",
+ "name": "jboss-webserver3-tomcat8-openshift:${JWS_RELEASE}"
+ }
+ }
+ },
+ "output": {
+ "to": {
+ "kind": "ImageStreamTag",
+ "name": "${APPLICATION_NAME}:latest"
+ }
+ },
+ "triggers": [
+ {
+ "type": "GitHub",
+ "github": {
+ "secret": "${GITHUB_TRIGGER_SECRET}"
+ }
+ },
+ {
+ "type": "Generic",
+ "generic": {
+ "secret": "${GENERIC_TRIGGER_SECRET}"
+ }
+ },
+ {
+ "type": "ImageChange",
+ "imageChange": {}
+ }
+ ]
+ }
+ },
+ {
+ "kind": "DeploymentConfig",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "${APPLICATION_NAME}",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "strategy": {
+ "type": "Recreate"
+ },
+ "triggers": [
+ {
+ "type": "ImageChange",
+ "imageChangeParams": {
+ "automatic": true,
+ "containerNames": [
+ "${APPLICATION_NAME}"
+ ],
+ "from": {
+ "kind": "ImageStream",
+ "name": "${APPLICATION_NAME}"
+ }
+ }
+ }
+ ],
+ "replicas": 1,
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}"
+ },
+ "template": {
+ "metadata": {
+ "name": "${APPLICATION_NAME}",
+ "labels": {
+ "deploymentConfig": "${APPLICATION_NAME}",
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "serviceAccount": "jws-service-account",
+ "containers": [
+ {
+ "name": "${APPLICATION_NAME}",
+ "image": "${APPLICATION_NAME}",
+ "imagePullPolicy": "Always",
+ "readinessProbe": {
+ "exec": {
+ "command": [
+ "/bin/bash",
+ "-c",
+ "curl -s -u ${JWS_ADMIN_USERNAME}:${JWS_ADMIN_PASSWORD} 'http://localhost:8080/manager/jmxproxy/?get=Catalina%3Atype%3DServer&att=stateName' |grep -iq 'stateName *= *STARTED'"
+ ]
+ }
+ },
+ "volumeMounts": [
+ {
+ "name": "jws-certificate-volume",
+ "mountPath": "/etc/jws-secret-volume",
+ "readOnly": true
+ }
+ ],
+ "ports": [
+ {
+ "name": "http",
+ "containerPort": 8080,
+ "protocol": "TCP"
+ },
+ {
+ "name": "https",
+ "containerPort": 8443,
+ "protocol": "TCP"
+ }
+ ],
+ "env": [
+ {
+ "name": "DB_SERVICE_PREFIX_MAPPING",
+ "value": "${APPLICATION_NAME}-mongodb=DB"
+ },
+ {
+ "name": "DB_JNDI",
+ "value": "${DB_JNDI}"
+ },
+ {
+ "name": "DB_USERNAME",
+ "value": "${DB_USERNAME}"
+ },
+ {
+ "name": "DB_PASSWORD",
+ "value": "${DB_PASSWORD}"
+ },
+ {
+ "name": "DB_DATABASE",
+ "value": "${DB_DATABASE}"
+ },
+ {
+ "name": "DB_ADMIN_PASSWORD",
+ "value": "${DB_ADMIN_PASSWORD}"
+ },
+ {
+ "name": "DB_MIN_POOL_SIZE",
+ "value": "${DB_MIN_POOL_SIZE}"
+ },
+ {
+ "name": "DB_MAX_POOL_SIZE",
+ "value": "${DB_MAX_POOL_SIZE}"
+ },
+ {
+ "name": "DB_TX_ISOLATION",
+ "value": "${DB_TX_ISOLATION}"
+ },
+ {
+ "name": "JWS_HTTPS_CERTIFICATE_DIR",
+ "value": "/etc/jws-secret-volume"
+ },
+ {
+ "name": "JWS_HTTPS_CERTIFICATE",
+ "value": "${JWS_HTTPS_CERTIFICATE}"
+ },
+ {
+ "name": "JWS_HTTPS_CERTIFICATE_KEY",
+ "value": "${JWS_HTTPS_CERTIFICATE_KEY}"
+ },
+ {
+ "name": "JWS_HTTPS_CERTIFICATE_PASSWORD",
+ "value": "${JWS_HTTPS_CERTIFICATE_PASSWORD}"
+ },
+ {
+ "name": "JWS_ADMIN_USERNAME",
+ "value": "${JWS_ADMIN_USERNAME}"
+ },
+ {
+ "name": "JWS_ADMIN_PASSWORD",
+ "value": "${JWS_ADMIN_PASSWORD}"
+ }
+ ]
+ }
+ ],
+ "volumes": [
+ {
+ "name": "jws-certificate-volume",
+ "secret": {
+ "secretName": "${JWS_HTTPS_SECRET}"
+ }
+ }
+ ]
+ }
+ }
+ }
+ },
+ {
+ "kind": "DeploymentConfig",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "${APPLICATION_NAME}-mongodb",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "strategy": {
+ "type": "Recreate"
+ },
+ "triggers": [
+ {
+ "type": "ImageChange",
+ "imageChangeParams": {
+ "automatic": true,
+ "containerNames": [
+ "${APPLICATION_NAME}-mongodb"
+ ],
+ "from": {
+ "kind": "ImageStreamTag",
+ "namespace": "openshift",
+ "name": "mongodb:latest"
+ }
+ }
+ }
+ ],
+ "replicas": 1,
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}-mongodb"
+ },
+ "template": {
+ "metadata": {
+ "name": "${APPLICATION_NAME}-mongodb",
+ "labels": {
+ "deploymentConfig": "${APPLICATION_NAME}-mongodb",
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "containers": [
+ {
+ "name": "${APPLICATION_NAME}-mongodb",
+ "image": "mongodb",
+ "imagePullPolicy": "Always",
+ "ports": [
+ {
+ "containerPort": 27017,
+ "protocol": "TCP"
+ }
+ ],
+ "volumeMounts": [
+ {
+ "mountPath": "/var/lib/mongodb/data",
+ "name": "${APPLICATION_NAME}-mongodb-pvol"
+ }
+ ],
+ "env": [
+ {
+ "name": "MONGODB_USER",
+ "value": "${DB_USERNAME}"
+ },
+ {
+ "name": "MONGODB_PASSWORD",
+ "value": "${DB_PASSWORD}"
+ },
+ {
+ "name": "MONGODB_DATABASE",
+ "value": "${DB_DATABASE}"
+ },
+ {
+ "name": "MONGODB_ADMIN_PASSWORD",
+ "value": "${DB_ADMIN_PASSWORD}"
+ },
+ {
+ "name": "MONGODB_NOPREALLOC",
+ "value": "${MONGODB_NOPREALLOC}"
+ },
+ {
+ "name": "MONGODB_SMALLFILES",
+ "value": "${MONGODB_SMALLFILES}"
+ },
+ {
+ "name": "MONGODB_QUIET",
+ "value": "${MONGODB_QUIET}"
+ }
+ ]
+ }
+ ],
+ "volumes": [
+ {
+ "name": "${APPLICATION_NAME}-mongodb-pvol",
+ "persistentVolumeClaim": {
+ "claimName": "${APPLICATION_NAME}-mongodb-claim"
+ }
+ }
+ ]
+ }
+ }
+ }
+ },
+ {
+ "apiVersion": "v1",
+ "kind": "PersistentVolumeClaim",
+ "metadata": {
+ "name": "${APPLICATION_NAME}-mongodb-claim",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "accessModes": [ "ReadWriteOnce" ],
+ "resources": {
+ "requests": {
+ "storage": "${VOLUME_CAPACITY}"
+ }
+ }
+ }
+ }
+ ]
+}
diff --git a/roles/openshift_examples/files/examples/xpaas-templates/jws-tomcat8-mongodb-sti.json b/roles/openshift_examples/files/examples/xpaas-templates/jws-tomcat8-mongodb-sti.json
new file mode 100644
index 000000000..a993024f4
--- /dev/null
+++ b/roles/openshift_examples/files/examples/xpaas-templates/jws-tomcat8-mongodb-sti.json
@@ -0,0 +1,562 @@
+{
+ "kind": "Template",
+ "apiVersion": "v1",
+ "metadata": {
+ "annotations": {
+ "iconClass" : "icon-tomcat",
+ "description": "Application template for JWS MongoDB applications built using STI."
+ },
+ "name": "jws-tomcat8-mongodb-sti"
+ },
+ "labels": {
+ "template": "jws-tomcat8-mongodb-sti"
+ },
+ "parameters": [
+ {
+ "description": "JWS Release version, e.g. 3.0, 2.1, etc.",
+ "name": "JWS_RELEASE",
+ "value": "3.0"
+ },
+ {
+ "description": "The name for the application.",
+ "name": "APPLICATION_NAME",
+ "value": "jws-app"
+ },
+ {
+ "description": "Custom hostname for service routes. Leave blank for default hostname, e.g.: <application-name>.<project>.<default-domain-suffix>",
+ "name": "APPLICATION_HOSTNAME",
+ "value": ""
+ },
+ {
+ "description": "Git source URI for application",
+ "name": "GIT_URI"
+ },
+ {
+ "description": "Git branch/tag reference",
+ "name": "GIT_REF",
+ "value": "master"
+ },
+ {
+ "description": "Path within Git project to build; empty for root project directory.",
+ "name": "GIT_CONTEXT_DIR",
+ "value": ""
+ },
+ {
+ "description": "Database JNDI name used by application to resolve the datasource, e.g. java:/jboss/datasources/mongodb",
+ "name": "DB_JNDI",
+ "value": ""
+ },
+ {
+ "description": "Database name",
+ "name": "DB_DATABASE",
+ "value": "root"
+ },
+ {
+ "description": "The name of the secret containing the certificate files",
+ "name": "JWS_HTTPS_SECRET",
+ "value": "jws-app-secret"
+ },
+ {
+ "description": "The name of the certificate file within the secret",
+ "name": "JWS_HTTPS_CERTIFICATE",
+ "value": "server.crt"
+ },
+ {
+ "description": "The name of the certificate key file within the secret",
+ "name": "JWS_HTTPS_CERTIFICATE_KEY",
+ "value": "server.key"
+ },
+ {
+ "description": "The certificate password",
+ "name": "JWS_HTTPS_CERTIFICATE_PASSWORD",
+ "value": ""
+ },
+ {
+ "description": "Sets xa-pool/min-pool-size for the configured datasource.",
+ "name": "DB_MIN_POOL_SIZE"
+ },
+ {
+ "description": "Sets xa-pool/max-pool-size for the configured datasource.",
+ "name": "DB_MAX_POOL_SIZE"
+ },
+ {
+ "description": "Sets transaction-isolation for the configured datasource.",
+ "name": "DB_TX_ISOLATION"
+ },
+ {
+ "description": "Disable data file preallocation.",
+ "name": "MONGODB_NOPREALLOC"
+ },
+ {
+ "description": "Set MongoDB to use a smaller default data file size.",
+ "name": "MONGODB_SMALLFILES"
+ },
+ {
+ "description": "Runs MongoDB in a quiet mode that attempts to limit the amount of output.",
+ "name": "MONGODB_QUIET"
+ },
+ {
+ "description": "Database user name",
+ "name": "DB_USERNAME",
+ "from": "user[a-zA-Z0-9]{3}",
+ "generate": "expression"
+ },
+ {
+ "description": "Database user password",
+ "name": "DB_PASSWORD",
+ "from": "[a-zA-Z0-9]{8}",
+ "generate": "expression"
+ },
+ {
+ "description": "Database admin password",
+ "name": "DB_ADMIN_PASSWORD",
+ "from": "[a-zA-Z0-9]{8}",
+ "generate": "expression"
+ },
+ {
+ "description": "JWS Admin User",
+ "name": "JWS_ADMIN_USERNAME",
+ "from": "[a-zA-Z0-9]{8}",
+ "generate": "expression"
+ },
+ {
+ "description": "JWS Admin Password",
+ "name": "JWS_ADMIN_PASSWORD",
+ "from": "[a-zA-Z0-9]{8}",
+ "generate": "expression"
+ },
+ {
+ "description": "Github trigger secret",
+ "name": "GITHUB_TRIGGER_SECRET",
+ "from": "[a-zA-Z0-9]{8}",
+ "generate": "expression"
+ },
+ {
+ "description": "Generic build trigger secret",
+ "name": "GENERIC_TRIGGER_SECRET",
+ "from": "[a-zA-Z0-9]{8}",
+ "generate": "expression"
+ }
+ ],
+ "objects": [
+ {
+ "kind": "Service",
+ "apiVersion": "v1",
+ "spec": {
+ "ports": [
+ {
+ "port": 8080,
+ "targetPort": 8080
+ }
+ ],
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}"
+ }
+ },
+ "metadata": {
+ "name": "${APPLICATION_NAME}",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "The web server's http port."
+ }
+ }
+ },
+ {
+ "kind": "Service",
+ "apiVersion": "v1",
+ "spec": {
+ "ports": [
+ {
+ "port": 8443,
+ "targetPort": 8443
+ }
+ ],
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}"
+ }
+ },
+ "metadata": {
+ "name": "secure-${APPLICATION_NAME}",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "The web server's https port."
+ }
+ }
+ },
+ {
+ "kind": "Service",
+ "apiVersion": "v1",
+ "spec": {
+ "ports": [
+ {
+ "port": 27017,
+ "targetPort": 27017
+ }
+ ],
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}-mongodb"
+ }
+ },
+ "metadata": {
+ "name": "${APPLICATION_NAME}-mongodb",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "The database server's port."
+ }
+ }
+ },
+ {
+ "kind": "Route",
+ "apiVersion": "v1",
+ "id": "${APPLICATION_NAME}-http-route",
+ "metadata": {
+ "name": "${APPLICATION_NAME}-http-route",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "Route for application's http service."
+ }
+ },
+ "spec": {
+ "host": "${APPLICATION_HOSTNAME}",
+ "to": {
+ "name": "${APPLICATION_NAME}"
+ }
+ }
+ },
+ {
+ "kind": "Route",
+ "apiVersion": "v1",
+ "id": "${APPLICATION_NAME}-https-route",
+ "metadata": {
+ "name": "${APPLICATION_NAME}-https-route",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "Route for application's https service."
+ }
+ },
+ "spec": {
+ "host": "${APPLICATION_HOSTNAME}",
+ "to": {
+ "name": "secure-${APPLICATION_NAME}"
+ },
+ "tls": {
+ "termination" : "passthrough"
+ }
+ }
+ },
+ {
+ "kind": "ImageStream",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "${APPLICATION_NAME}",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ }
+ }
+ },
+ {
+ "kind": "BuildConfig",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "${APPLICATION_NAME}",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "source": {
+ "type": "Git",
+ "git": {
+ "uri": "${GIT_URI}",
+ "ref": "${GIT_REF}"
+ },
+ "contextDir":"${GIT_CONTEXT_DIR}"
+ },
+ "strategy": {
+ "type": "Source",
+ "sourceStrategy": {
+ "from": {
+ "kind": "ImageStreamTag",
+ "namespace": "openshift",
+ "name": "jboss-webserver3-tomcat8-openshift:${JWS_RELEASE}"
+ }
+ }
+ },
+ "output": {
+ "to": {
+ "kind": "ImageStreamTag",
+ "name": "${APPLICATION_NAME}:latest"
+ }
+ },
+ "triggers": [
+ {
+ "type": "GitHub",
+ "github": {
+ "secret": "${GITHUB_TRIGGER_SECRET}"
+ }
+ },
+ {
+ "type": "Generic",
+ "generic": {
+ "secret": "${GENERIC_TRIGGER_SECRET}"
+ }
+ },
+ {
+ "type": "ImageChange",
+ "imageChange": {}
+ }
+ ]
+ }
+ },
+ {
+ "kind": "DeploymentConfig",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "${APPLICATION_NAME}",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "strategy": {
+ "type": "Recreate"
+ },
+ "triggers": [
+ {
+ "type": "ImageChange",
+ "imageChangeParams": {
+ "automatic": true,
+ "containerNames": [
+ "${APPLICATION_NAME}"
+ ],
+ "from": {
+ "kind": "ImageStream",
+ "name": "${APPLICATION_NAME}"
+ }
+ }
+ }
+ ],
+ "replicas": 1,
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}"
+ },
+ "template": {
+ "metadata": {
+ "name": "${APPLICATION_NAME}",
+ "labels": {
+ "deploymentConfig": "${APPLICATION_NAME}",
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "serviceAccount": "jws-service-account",
+ "containers": [
+ {
+ "name": "${APPLICATION_NAME}",
+ "image": "${APPLICATION_NAME}",
+ "imagePullPolicy": "Always",
+ "readinessProbe": {
+ "exec": {
+ "command": [
+ "/bin/bash",
+ "-c",
+ "curl -s -u ${JWS_ADMIN_USERNAME}:${JWS_ADMIN_PASSWORD} 'http://localhost:8080/manager/jmxproxy/?get=Catalina%3Atype%3DServer&att=stateName' |grep -iq 'stateName *= *STARTED'"
+ ]
+ }
+ },
+ "volumeMounts": [
+ {
+ "name": "jws-certificate-volume",
+ "mountPath": "/etc/jws-secret-volume",
+ "readOnly": true
+ }
+ ],
+ "ports": [
+ {
+ "name": "http",
+ "containerPort": 8080,
+ "protocol": "TCP"
+ },
+ {
+ "name": "https",
+ "containerPort": 8443,
+ "protocol": "TCP"
+ }
+ ],
+ "env": [
+ {
+ "name": "DB_SERVICE_PREFIX_MAPPING",
+ "value": "${APPLICATION_NAME}-mongodb=DB"
+ },
+ {
+ "name": "DB_JNDI",
+ "value": "${DB_JNDI}"
+ },
+ {
+ "name": "DB_USERNAME",
+ "value": "${DB_USERNAME}"
+ },
+ {
+ "name": "DB_PASSWORD",
+ "value": "${DB_PASSWORD}"
+ },
+ {
+ "name": "DB_DATABASE",
+ "value": "${DB_DATABASE}"
+ },
+ {
+ "name": "DB_ADMIN_PASSWORD",
+ "value": "${DB_ADMIN_PASSWORD}"
+ },
+ {
+ "name": "DB_MIN_POOL_SIZE",
+ "value": "${DB_MIN_POOL_SIZE}"
+ },
+ {
+ "name": "DB_MAX_POOL_SIZE",
+ "value": "${DB_MAX_POOL_SIZE}"
+ },
+ {
+ "name": "DB_TX_ISOLATION",
+ "value": "${DB_TX_ISOLATION}"
+ },
+ {
+ "name": "JWS_HTTPS_CERTIFICATE_DIR",
+ "value": "/etc/jws-secret-volume"
+ },
+ {
+ "name": "JWS_HTTPS_CERTIFICATE",
+ "value": "${JWS_HTTPS_CERTIFICATE}"
+ },
+ {
+ "name": "JWS_HTTPS_CERTIFICATE_KEY",
+ "value": "${JWS_HTTPS_CERTIFICATE_KEY}"
+ },
+ {
+ "name": "JWS_HTTPS_CERTIFICATE_PASSWORD",
+ "value": "${JWS_HTTPS_CERTIFICATE_PASSWORD}"
+ },
+ {
+ "name": "JWS_ADMIN_USERNAME",
+ "value": "${JWS_ADMIN_USERNAME}"
+ },
+ {
+ "name": "JWS_ADMIN_PASSWORD",
+ "value": "${JWS_ADMIN_PASSWORD}"
+ }
+ ]
+ }
+ ],
+ "volumes": [
+ {
+ "name": "jws-certificate-volume",
+ "secret": {
+ "secretName": "${JWS_HTTPS_SECRET}"
+ }
+ }
+ ]
+ }
+ }
+ }
+ },
+ {
+ "kind": "DeploymentConfig",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "${APPLICATION_NAME}-mongodb",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "strategy": {
+ "type": "Recreate"
+ },
+ "triggers": [
+ {
+ "type": "ImageChange",
+ "imageChangeParams": {
+ "automatic": true,
+ "containerNames": [
+ "${APPLICATION_NAME}-mongodb"
+ ],
+ "from": {
+ "kind": "ImageStreamTag",
+ "namespace": "openshift",
+ "name": "mongodb:latest"
+ }
+ }
+ }
+ ],
+ "replicas": 1,
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}-mongodb"
+ },
+ "template": {
+ "metadata": {
+ "name": "${APPLICATION_NAME}-mongodb",
+ "labels": {
+ "deploymentConfig": "${APPLICATION_NAME}-mongodb",
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "containers": [
+ {
+ "name": "${APPLICATION_NAME}-mongodb",
+ "image": "mongodb",
+ "imagePullPolicy": "Always",
+ "ports": [
+ {
+ "containerPort": 27017,
+ "protocol": "TCP"
+ }
+ ],
+ "env": [
+ {
+ "name": "MONGODB_USER",
+ "value": "${DB_USERNAME}"
+ },
+ {
+ "name": "MONGODB_PASSWORD",
+ "value": "${DB_PASSWORD}"
+ },
+ {
+ "name": "MONGODB_DATABASE",
+ "value": "${DB_DATABASE}"
+ },
+ {
+ "name": "MONGODB_ADMIN_PASSWORD",
+ "value": "${DB_ADMIN_PASSWORD}"
+ },
+ {
+ "name": "MONGODB_NOPREALLOC",
+ "value": "${MONGODB_NOPREALLOC}"
+ },
+ {
+ "name": "MONGODB_SMALLFILES",
+ "value": "${MONGODB_SMALLFILES}"
+ },
+ {
+ "name": "MONGODB_QUIET",
+ "value": "${MONGODB_QUIET}"
+ }
+ ]
+ }
+ ]
+ }
+ }
+ }
+ }
+ ]
+}
diff --git a/roles/openshift_examples/files/examples/xpaas-templates/jws-tomcat8-mysql-persistent-sti.json b/roles/openshift_examples/files/examples/xpaas-templates/jws-tomcat8-mysql-persistent-sti.json
new file mode 100644
index 000000000..0692817bf
--- /dev/null
+++ b/roles/openshift_examples/files/examples/xpaas-templates/jws-tomcat8-mysql-persistent-sti.json
@@ -0,0 +1,600 @@
+{
+ "kind": "Template",
+ "apiVersion": "v1",
+ "metadata": {
+ "annotations": {
+ "iconClass" : "icon-tomcat",
+ "description": "Application template for JWS MySQL applications with persistent storage built using STI."
+ },
+ "name": "jws-tomcat8-mysql-persistent-sti"
+ },
+ "labels": {
+ "template": "jws-tomcat8-mysql-persistent-sti"
+ },
+ "parameters": [
+ {
+ "description": "JWS Release version, e.g. 3.0, 2.1, etc.",
+ "name": "JWS_RELEASE",
+ "value": "3.0"
+ },
+ {
+ "description": "The name for the application.",
+ "name": "APPLICATION_NAME",
+ "value": "jws-app"
+ },
+ {
+ "description": "Custom hostname for service routes. Leave blank for default hostname, e.g.: <application-name>.<project>.<default-domain-suffix>",
+ "name": "APPLICATION_HOSTNAME",
+ "value": ""
+ },
+ {
+ "description": "Git source URI for application",
+ "name": "GIT_URI"
+ },
+ {
+ "description": "Git branch/tag reference",
+ "name": "GIT_REF",
+ "value": "master"
+ },
+ {
+ "description": "Path within Git project to build; empty for root project directory.",
+ "name": "GIT_CONTEXT_DIR",
+ "value": ""
+ },
+ {
+ "description": "Database JNDI name used by application to resolve the datasource, e.g. java:/jboss/datasources/mongodb",
+ "name": "DB_JNDI",
+ "value": ""
+ },
+ {
+ "description": "Database name",
+ "name": "DB_DATABASE",
+ "value": "root"
+ },
+ {
+ "description": "Size of persistent storage for database volume.",
+ "name": "VOLUME_CAPACITY",
+ "value": "512Mi"
+ },
+ {
+ "description": "The name of the secret containing the certificate files",
+ "name": "JWS_HTTPS_SECRET",
+ "value": "jws-app-secret"
+ },
+ {
+ "description": "The name of the certificate file within the secret",
+ "name": "JWS_HTTPS_CERTIFICATE",
+ "value": "server.crt"
+ },
+ {
+ "description": "The name of the certificate key file within the secret",
+ "name": "JWS_HTTPS_CERTIFICATE_KEY",
+ "value": "server.key"
+ },
+ {
+ "description": "The certificate password",
+ "name": "JWS_HTTPS_CERTIFICATE_PASSWORD",
+ "value": ""
+ },
+ {
+ "description": "Sets xa-pool/min-pool-size for the configured datasource.",
+ "name": "DB_MIN_POOL_SIZE"
+ },
+ {
+ "description": "Sets xa-pool/max-pool-size for the configured datasource.",
+ "name": "DB_MAX_POOL_SIZE"
+ },
+ {
+ "description": "Sets transaction-isolation for the configured datasource.",
+ "name": "DB_TX_ISOLATION"
+ },
+ {
+ "description": "Sets how the table names are stored and compared.",
+ "name": "MYSQL_LOWER_CASE_TABLE_NAMES"
+ },
+ {
+ "description": "The maximum permitted number of simultaneous client connections.",
+ "name": "MYSQL_MAX_CONNECTIONS"
+ },
+ {
+ "description": "The minimum length of the word to be included in a FULLTEXT index.",
+ "name": "MYSQL_FT_MIN_WORD_LEN"
+ },
+ {
+ "description": "The maximum length of the word to be included in a FULLTEXT index.",
+ "name": "MYSQL_FT_MAX_WORD_LEN"
+ },
+ {
+ "description": "Controls the innodb_use_native_aio setting value if the native AIO is broken.",
+ "name": "MYSQL_AIO"
+ },
+ {
+ "description": "Database user name",
+ "name": "DB_USERNAME",
+ "from": "user[a-zA-Z0-9]{3}",
+ "generate": "expression"
+ },
+ {
+ "description": "Database user password",
+ "name": "DB_PASSWORD",
+ "from": "[a-zA-Z0-9]{8}",
+ "generate": "expression"
+ },
+ {
+ "description": "JWS Admin User",
+ "name": "JWS_ADMIN_USERNAME",
+ "from": "[a-zA-Z0-9]{8}",
+ "generate": "expression"
+ },
+ {
+ "description": "JWS Admin Password",
+ "name": "JWS_ADMIN_PASSWORD",
+ "from": "[a-zA-Z0-9]{8}",
+ "generate": "expression"
+ },
+ {
+ "description": "Github trigger secret",
+ "name": "GITHUB_TRIGGER_SECRET",
+ "from": "[a-zA-Z0-9]{8}",
+ "generate": "expression"
+ },
+ {
+ "description": "Generic build trigger secret",
+ "name": "GENERIC_TRIGGER_SECRET",
+ "from": "[a-zA-Z0-9]{8}",
+ "generate": "expression"
+ }
+ ],
+ "objects": [
+ {
+ "kind": "Service",
+ "apiVersion": "v1",
+ "spec": {
+ "ports": [
+ {
+ "port": 8080,
+ "targetPort": 8080
+ }
+ ],
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}"
+ }
+ },
+ "metadata": {
+ "name": "${APPLICATION_NAME}",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "The web server's http port."
+ }
+ }
+ },
+ {
+ "kind": "Service",
+ "apiVersion": "v1",
+ "spec": {
+ "ports": [
+ {
+ "port": 8443,
+ "targetPort": 8443
+ }
+ ],
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}"
+ }
+ },
+ "metadata": {
+ "name": "secure-${APPLICATION_NAME}",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "The web server's https port."
+ }
+ }
+ },
+ {
+ "kind": "Service",
+ "apiVersion": "v1",
+ "spec": {
+ "ports": [
+ {
+ "port": 3306,
+ "targetPort": 3306
+ }
+ ],
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}-mysql"
+ }
+ },
+ "metadata": {
+ "name": "${APPLICATION_NAME}-mysql",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "The database server's port."
+ }
+ }
+ },
+ {
+ "kind": "Route",
+ "apiVersion": "v1",
+ "id": "${APPLICATION_NAME}-http-route",
+ "metadata": {
+ "name": "${APPLICATION_NAME}-http-route",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "Route for application's http service."
+ }
+ },
+ "spec": {
+ "host": "${APPLICATION_HOSTNAME}",
+ "to": {
+ "name": "${APPLICATION_NAME}"
+ }
+ }
+ },
+ {
+ "kind": "Route",
+ "apiVersion": "v1",
+ "id": "${APPLICATION_NAME}-https-route",
+ "metadata": {
+ "name": "${APPLICATION_NAME}-https-route",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "Route for application's https service."
+ }
+ },
+ "spec": {
+ "host": "${APPLICATION_HOSTNAME}",
+ "to": {
+ "name": "secure-${APPLICATION_NAME}"
+ },
+ "tls": {
+ "termination" : "passthrough"
+ }
+ }
+ },
+ {
+ "kind": "ImageStream",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "${APPLICATION_NAME}",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ }
+ }
+ },
+ {
+ "kind": "BuildConfig",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "${APPLICATION_NAME}",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "source": {
+ "type": "Git",
+ "git": {
+ "uri": "${GIT_URI}",
+ "ref": "${GIT_REF}"
+ },
+ "contextDir":"${GIT_CONTEXT_DIR}"
+ },
+ "strategy": {
+ "type": "Source",
+ "sourceStrategy": {
+ "from": {
+ "kind": "ImageStreamTag",
+ "namespace": "openshift",
+ "name": "jboss-webserver3-tomcat8-openshift:${JWS_RELEASE}"
+ }
+ }
+ },
+ "output": {
+ "to": {
+ "kind": "ImageStreamTag",
+ "name": "${APPLICATION_NAME}:latest"
+ }
+ },
+ "triggers": [
+ {
+ "type": "GitHub",
+ "github": {
+ "secret": "${GITHUB_TRIGGER_SECRET}"
+ }
+ },
+ {
+ "type": "Generic",
+ "generic": {
+ "secret": "${GENERIC_TRIGGER_SECRET}"
+ }
+ },
+ {
+ "type": "ImageChange",
+ "imageChange": {}
+ }
+ ]
+ }
+ },
+ {
+ "kind": "DeploymentConfig",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "${APPLICATION_NAME}",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "strategy": {
+ "type": "Recreate"
+ },
+ "triggers": [
+ {
+ "type": "ImageChange",
+ "imageChangeParams": {
+ "automatic": true,
+ "containerNames": [
+ "${APPLICATION_NAME}"
+ ],
+ "from": {
+ "kind": "ImageStream",
+ "name": "${APPLICATION_NAME}"
+ }
+ }
+ }
+ ],
+ "replicas": 1,
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}"
+ },
+ "template": {
+ "metadata": {
+ "name": "${APPLICATION_NAME}",
+ "labels": {
+ "deploymentConfig": "${APPLICATION_NAME}",
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "serviceAccount": "jws-service-account",
+ "containers": [
+ {
+ "name": "${APPLICATION_NAME}",
+ "image": "${APPLICATION_NAME}",
+ "imagePullPolicy": "Always",
+ "readinessProbe": {
+ "exec": {
+ "command": [
+ "/bin/bash",
+ "-c",
+ "curl -s -u ${JWS_ADMIN_USERNAME}:${JWS_ADMIN_PASSWORD} 'http://localhost:8080/manager/jmxproxy/?get=Catalina%3Atype%3DServer&att=stateName' |grep -iq 'stateName *= *STARTED'"
+ ]
+ }
+ },
+ "volumeMounts": [
+ {
+ "name": "jws-certificate-volume",
+ "mountPath": "/etc/jws-secret-volume",
+ "readOnly": true
+ }
+ ],
+ "ports": [
+ {
+ "name": "http",
+ "containerPort": 8080,
+ "protocol": "TCP"
+ },
+ {
+ "name": "https",
+ "containerPort": 8443,
+ "protocol": "TCP"
+ }
+ ],
+ "env": [
+ {
+ "name": "DB_SERVICE_PREFIX_MAPPING",
+ "value": "${APPLICATION_NAME}-mysql=DB"
+ },
+ {
+ "name": "DB_JNDI",
+ "value": "${DB_JNDI}"
+ },
+ {
+ "name": "DB_USERNAME",
+ "value": "${DB_USERNAME}"
+ },
+ {
+ "name": "DB_PASSWORD",
+ "value": "${DB_PASSWORD}"
+ },
+ {
+ "name": "DB_DATABASE",
+ "value": "${DB_DATABASE}"
+ },
+ {
+ "name": "DB_MIN_POOL_SIZE",
+ "value": "${DB_MIN_POOL_SIZE}"
+ },
+ {
+ "name": "DB_MAX_POOL_SIZE",
+ "value": "${DB_MAX_POOL_SIZE}"
+ },
+ {
+ "name": "DB_TX_ISOLATION",
+ "value": "${DB_TX_ISOLATION}"
+ },
+ {
+ "name": "JWS_HTTPS_CERTIFICATE_DIR",
+ "value": "/etc/jws-secret-volume"
+ },
+ {
+ "name": "JWS_HTTPS_CERTIFICATE",
+ "value": "${JWS_HTTPS_CERTIFICATE}"
+ },
+ {
+ "name": "JWS_HTTPS_CERTIFICATE_KEY",
+ "value": "${JWS_HTTPS_CERTIFICATE_KEY}"
+ },
+ {
+ "name": "JWS_HTTPS_CERTIFICATE_PASSWORD",
+ "value": "${JWS_HTTPS_CERTIFICATE_PASSWORD}"
+ },
+ {
+ "name": "JWS_ADMIN_USERNAME",
+ "value": "${JWS_ADMIN_USERNAME}"
+ },
+ {
+ "name": "JWS_ADMIN_PASSWORD",
+ "value": "${JWS_ADMIN_PASSWORD}"
+ }
+ ]
+ }
+ ],
+ "volumes": [
+ {
+ "name": "jws-certificate-volume",
+ "secret": {
+ "secretName": "${JWS_HTTPS_SECRET}"
+ }
+ }
+ ]
+ }
+ }
+ }
+ },
+ {
+ "kind": "DeploymentConfig",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "${APPLICATION_NAME}-mysql",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "strategy": {
+ "type": "Recreate"
+ },
+ "triggers": [
+ {
+ "type": "ImageChange",
+ "imageChangeParams": {
+ "automatic": true,
+ "containerNames": [
+ "${APPLICATION_NAME}-mysql"
+ ],
+ "from": {
+ "kind": "ImageStreamTag",
+ "namespace": "openshift",
+ "name": "mysql:latest"
+ }
+ }
+ }
+ ],
+ "replicas": 1,
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}-mysql"
+ },
+ "template": {
+ "metadata": {
+ "name": "${APPLICATION_NAME}-mysql",
+ "labels": {
+ "deploymentConfig": "${APPLICATION_NAME}-mysql",
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "containers": [
+ {
+ "name": "${APPLICATION_NAME}-mysql",
+ "image": "mysql",
+ "ports": [
+ {
+ "containerPort": 3306,
+ "protocol": "TCP"
+ }
+ ],
+ "volumeMounts": [
+ {
+ "mountPath": "/var/lib/mysql/data",
+ "name": "${APPLICATION_NAME}-mysql-pvol"
+ }
+ ],
+ "env": [
+ {
+ "name": "MYSQL_USER",
+ "value": "${DB_USERNAME}"
+ },
+ {
+ "name": "MYSQL_PASSWORD",
+ "value": "${DB_PASSWORD}"
+ },
+ {
+ "name": "MYSQL_DATABASE",
+ "value": "${DB_DATABASE}"
+ },
+ {
+ "name": "MYSQL_LOWER_CASE_TABLE_NAMES",
+ "value": "${MYSQL_LOWER_CASE_TABLE_NAMES}"
+ },
+ {
+ "name": "MYSQL_MAX_CONNECTIONS",
+ "value": "${MYSQL_MAX_CONNECTIONS}"
+ },
+ {
+ "name": "MYSQL_FT_MIN_WORD_LEN",
+ "value": "${MYSQL_FT_MIN_WORD_LEN}"
+ },
+ {
+ "name": "MYSQL_FT_MAX_WORD_LEN",
+ "value": "${MYSQL_FT_MAX_WORD_LEN}"
+ },
+ {
+ "name": "MYSQL_AIO",
+ "value": "${MYSQL_AIO}"
+ }
+ ]
+ }
+ ],
+ "volumes": [
+ {
+ "name": "${APPLICATION_NAME}-mysql-pvol",
+ "persistentVolumeClaim": {
+ "claimName": "${APPLICATION_NAME}-mysql-claim"
+ }
+ }
+ ]
+ }
+ }
+ }
+ },
+ {
+ "apiVersion": "v1",
+ "kind": "PersistentVolumeClaim",
+ "metadata": {
+ "name": "${APPLICATION_NAME}-mysql-claim",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "accessModes": [ "ReadWriteOnce" ],
+ "resources": {
+ "requests": {
+ "storage": "${VOLUME_CAPACITY}"
+ }
+ }
+ }
+ }
+ ]
+}
diff --git a/roles/openshift_examples/files/examples/xpaas-templates/jws-tomcat8-mysql-sti.json b/roles/openshift_examples/files/examples/xpaas-templates/jws-tomcat8-mysql-sti.json
new file mode 100644
index 000000000..226a983b7
--- /dev/null
+++ b/roles/openshift_examples/files/examples/xpaas-templates/jws-tomcat8-mysql-sti.json
@@ -0,0 +1,563 @@
+{
+ "kind": "Template",
+ "apiVersion": "v1",
+ "metadata": {
+ "annotations": {
+ "iconClass" : "icon-tomcat",
+ "description": "Application template for JWS MySQL applications built using STI."
+ },
+ "name": "jws-tomcat8-mysql-sti"
+ },
+ "labels": {
+ "template": "jws-tomcat8-mysql-sti"
+ },
+ "parameters": [
+ {
+ "description": "JWS Release version, e.g. 3.0, 2.1, etc.",
+ "name": "JWS_RELEASE",
+ "value": "3.0"
+ },
+ {
+ "description": "The name for the application.",
+ "name": "APPLICATION_NAME",
+ "value": "jws-app"
+ },
+ {
+ "description": "Custom hostname for service routes. Leave blank for default hostname, e.g.: <application-name>.<project>.<default-domain-suffix>",
+ "name": "APPLICATION_HOSTNAME",
+ "value": ""
+ },
+ {
+ "description": "Git source URI for application",
+ "name": "GIT_URI"
+ },
+ {
+ "description": "Git branch/tag reference",
+ "name": "GIT_REF",
+ "value": "master"
+ },
+ {
+ "description": "Path within Git project to build; empty for root project directory.",
+ "name": "GIT_CONTEXT_DIR",
+ "value": ""
+ },
+ {
+ "description": "Database JNDI name used by application to resolve the datasource, e.g. java:/jboss/datasources/mongodb",
+ "name": "DB_JNDI",
+ "value": ""
+ },
+ {
+ "description": "Database name",
+ "name": "DB_DATABASE",
+ "value": "root"
+ },
+ {
+ "description": "The name of the secret containing the certificate files",
+ "name": "JWS_HTTPS_SECRET",
+ "value": "jws-app-secret"
+ },
+ {
+ "description": "The name of the certificate file within the secret",
+ "name": "JWS_HTTPS_CERTIFICATE",
+ "value": "server.crt"
+ },
+ {
+ "description": "The name of the certificate key file within the secret",
+ "name": "JWS_HTTPS_CERTIFICATE_KEY",
+ "value": "server.key"
+ },
+ {
+ "description": "The certificate password",
+ "name": "JWS_HTTPS_CERTIFICATE_PASSWORD",
+ "value": ""
+ },
+ {
+ "description": "Sets xa-pool/min-pool-size for the configured datasource.",
+ "name": "DB_MIN_POOL_SIZE"
+ },
+ {
+ "description": "Sets xa-pool/max-pool-size for the configured datasource.",
+ "name": "DB_MAX_POOL_SIZE"
+ },
+ {
+ "description": "Sets transaction-isolation for the configured datasource.",
+ "name": "DB_TX_ISOLATION"
+ },
+ {
+ "description": "Sets how the table names are stored and compared.",
+ "name": "MYSQL_LOWER_CASE_TABLE_NAMES"
+ },
+ {
+ "description": "The maximum permitted number of simultaneous client connections.",
+ "name": "MYSQL_MAX_CONNECTIONS"
+ },
+ {
+ "description": "The minimum length of the word to be included in a FULLTEXT index.",
+ "name": "MYSQL_FT_MIN_WORD_LEN"
+ },
+ {
+ "description": "The maximum length of the word to be included in a FULLTEXT index.",
+ "name": "MYSQL_FT_MAX_WORD_LEN"
+ },
+ {
+ "description": "Controls the innodb_use_native_aio setting value if the native AIO is broken.",
+ "name": "MYSQL_AIO"
+ },
+ {
+ "description": "Database user name",
+ "name": "DB_USERNAME",
+ "from": "user[a-zA-Z0-9]{3}",
+ "generate": "expression"
+ },
+ {
+ "description": "Database user password",
+ "name": "DB_PASSWORD",
+ "from": "[a-zA-Z0-9]{8}",
+ "generate": "expression"
+ },
+ {
+ "description": "JWS Admin User",
+ "name": "JWS_ADMIN_USERNAME",
+ "from": "[a-zA-Z0-9]{8}",
+ "generate": "expression"
+ },
+ {
+ "description": "JWS Admin Password",
+ "name": "JWS_ADMIN_PASSWORD",
+ "from": "[a-zA-Z0-9]{8}",
+ "generate": "expression"
+ },
+ {
+ "description": "Github trigger secret",
+ "name": "GITHUB_TRIGGER_SECRET",
+ "from": "[a-zA-Z0-9]{8}",
+ "generate": "expression"
+ },
+ {
+ "description": "Generic build trigger secret",
+ "name": "GENERIC_TRIGGER_SECRET",
+ "from": "[a-zA-Z0-9]{8}",
+ "generate": "expression"
+ }
+ ],
+ "objects": [
+ {
+ "kind": "Service",
+ "apiVersion": "v1",
+ "spec": {
+ "ports": [
+ {
+ "port": 8080,
+ "targetPort": 8080
+ }
+ ],
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}"
+ }
+ },
+ "metadata": {
+ "name": "${APPLICATION_NAME}",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "The web server's http port."
+ }
+ }
+ },
+ {
+ "kind": "Service",
+ "apiVersion": "v1",
+ "spec": {
+ "ports": [
+ {
+ "port": 8443,
+ "targetPort": 8443
+ }
+ ],
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}"
+ }
+ },
+ "metadata": {
+ "name": "secure-${APPLICATION_NAME}",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "The web server's https port."
+ }
+ }
+ },
+ {
+ "kind": "Service",
+ "apiVersion": "v1",
+ "spec": {
+ "ports": [
+ {
+ "port": 3306,
+ "targetPort": 3306
+ }
+ ],
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}-mysql"
+ }
+ },
+ "metadata": {
+ "name": "${APPLICATION_NAME}-mysql",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "The database server's port."
+ }
+ }
+ },
+ {
+ "kind": "Route",
+ "apiVersion": "v1",
+ "id": "${APPLICATION_NAME}-http-route",
+ "metadata": {
+ "name": "${APPLICATION_NAME}-http-route",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "Route for application's http service."
+ }
+ },
+ "spec": {
+ "host": "${APPLICATION_HOSTNAME}",
+ "to": {
+ "name": "${APPLICATION_NAME}"
+ }
+ }
+ },
+ {
+ "kind": "Route",
+ "apiVersion": "v1",
+ "id": "${APPLICATION_NAME}-https-route",
+ "metadata": {
+ "name": "${APPLICATION_NAME}-https-route",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "Route for application's https service."
+ }
+ },
+ "spec": {
+ "host": "${APPLICATION_HOSTNAME}",
+ "to": {
+ "name": "secure-${APPLICATION_NAME}"
+ },
+ "tls": {
+ "termination" : "passthrough"
+ }
+ }
+ },
+ {
+ "kind": "ImageStream",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "${APPLICATION_NAME}",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ }
+ }
+ },
+ {
+ "kind": "BuildConfig",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "${APPLICATION_NAME}",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "source": {
+ "type": "Git",
+ "git": {
+ "uri": "${GIT_URI}",
+ "ref": "${GIT_REF}"
+ },
+ "contextDir":"${GIT_CONTEXT_DIR}"
+ },
+ "strategy": {
+ "type": "Source",
+ "sourceStrategy": {
+ "from": {
+ "kind": "ImageStreamTag",
+ "namespace": "openshift",
+ "name": "jboss-webserver3-tomcat8-openshift:${JWS_RELEASE}"
+ }
+ }
+ },
+ "output": {
+ "to": {
+ "kind": "ImageStreamTag",
+ "name": "${APPLICATION_NAME}:latest"
+ }
+ },
+ "triggers": [
+ {
+ "type": "GitHub",
+ "github": {
+ "secret": "${GITHUB_TRIGGER_SECRET}"
+ }
+ },
+ {
+ "type": "Generic",
+ "generic": {
+ "secret": "${GENERIC_TRIGGER_SECRET}"
+ }
+ },
+ {
+ "type": "ImageChange",
+ "imageChange": {}
+ }
+ ]
+ }
+ },
+ {
+ "kind": "DeploymentConfig",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "${APPLICATION_NAME}",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "strategy": {
+ "type": "Recreate"
+ },
+ "triggers": [
+ {
+ "type": "ImageChange",
+ "imageChangeParams": {
+ "automatic": true,
+ "containerNames": [
+ "${APPLICATION_NAME}"
+ ],
+ "from": {
+ "kind": "ImageStream",
+ "name": "${APPLICATION_NAME}"
+ }
+ }
+ }
+ ],
+ "replicas": 1,
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}"
+ },
+ "template": {
+ "metadata": {
+ "name": "${APPLICATION_NAME}",
+ "labels": {
+ "deploymentConfig": "${APPLICATION_NAME}",
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "serviceAccount": "jws-service-account",
+ "containers": [
+ {
+ "name": "${APPLICATION_NAME}",
+ "image": "${APPLICATION_NAME}",
+ "imagePullPolicy": "Always",
+ "readinessProbe": {
+ "exec": {
+ "command": [
+ "/bin/bash",
+ "-c",
+ "curl -s -u ${JWS_ADMIN_USERNAME}:${JWS_ADMIN_PASSWORD} 'http://localhost:8080/manager/jmxproxy/?get=Catalina%3Atype%3DServer&att=stateName' |grep -iq 'stateName *= *STARTED'"
+ ]
+ }
+ },
+ "volumeMounts": [
+ {
+ "name": "jws-certificate-volume",
+ "mountPath": "/etc/jws-secret-volume",
+ "readOnly": true
+ }
+ ],
+ "ports": [
+ {
+ "name": "http",
+ "containerPort": 8080,
+ "protocol": "TCP"
+ },
+ {
+ "name": "https",
+ "containerPort": 8443,
+ "protocol": "TCP"
+ }
+ ],
+ "env": [
+ {
+ "name": "DB_SERVICE_PREFIX_MAPPING",
+ "value": "${APPLICATION_NAME}-mysql=DB"
+ },
+ {
+ "name": "DB_JNDI",
+ "value": "${DB_JNDI}"
+ },
+ {
+ "name": "DB_USERNAME",
+ "value": "${DB_USERNAME}"
+ },
+ {
+ "name": "DB_PASSWORD",
+ "value": "${DB_PASSWORD}"
+ },
+ {
+ "name": "DB_DATABASE",
+ "value": "${DB_DATABASE}"
+ },
+ {
+ "name": "DB_MIN_POOL_SIZE",
+ "value": "${DB_MIN_POOL_SIZE}"
+ },
+ {
+ "name": "DB_MAX_POOL_SIZE",
+ "value": "${DB_MAX_POOL_SIZE}"
+ },
+ {
+ "name": "DB_TX_ISOLATION",
+ "value": "${DB_TX_ISOLATION}"
+ },
+ {
+ "name": "JWS_HTTPS_CERTIFICATE_DIR",
+ "value": "/etc/jws-secret-volume"
+ },
+ {
+ "name": "JWS_HTTPS_CERTIFICATE",
+ "value": "${JWS_HTTPS_CERTIFICATE}"
+ },
+ {
+ "name": "JWS_HTTPS_CERTIFICATE_KEY",
+ "value": "${JWS_HTTPS_CERTIFICATE_KEY}"
+ },
+ {
+ "name": "JWS_HTTPS_CERTIFICATE_PASSWORD",
+ "value": "${JWS_HTTPS_CERTIFICATE_PASSWORD}"
+ },
+ {
+ "name": "JWS_ADMIN_USERNAME",
+ "value": "${JWS_ADMIN_USERNAME}"
+ },
+ {
+ "name": "JWS_ADMIN_PASSWORD",
+ "value": "${JWS_ADMIN_PASSWORD}"
+ }
+ ]
+ }
+ ],
+ "volumes": [
+ {
+ "name": "jws-certificate-volume",
+ "secret": {
+ "secretName": "${JWS_HTTPS_SECRET}"
+ }
+ }
+ ]
+ }
+ }
+ }
+ },
+ {
+ "kind": "DeploymentConfig",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "${APPLICATION_NAME}-mysql",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "strategy": {
+ "type": "Recreate"
+ },
+ "triggers": [
+ {
+ "type": "ImageChange",
+ "imageChangeParams": {
+ "automatic": true,
+ "containerNames": [
+ "${APPLICATION_NAME}-mysql"
+ ],
+ "from": {
+ "kind": "ImageStreamTag",
+ "namespace": "openshift",
+ "name": "mysql:latest"
+ }
+ }
+ }
+ ],
+ "replicas": 1,
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}-mysql"
+ },
+ "template": {
+ "metadata": {
+ "name": "${APPLICATION_NAME}-mysql",
+ "labels": {
+ "deploymentConfig": "${APPLICATION_NAME}-mysql",
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "containers": [
+ {
+ "name": "${APPLICATION_NAME}-mysql",
+ "image": "mysql",
+ "ports": [
+ {
+ "containerPort": 3306,
+ "protocol": "TCP"
+ }
+ ],
+ "env": [
+ {
+ "name": "MYSQL_USER",
+ "value": "${DB_USERNAME}"
+ },
+ {
+ "name": "MYSQL_PASSWORD",
+ "value": "${DB_PASSWORD}"
+ },
+ {
+ "name": "MYSQL_DATABASE",
+ "value": "${DB_DATABASE}"
+ },
+ {
+ "name": "MYSQL_LOWER_CASE_TABLE_NAMES",
+ "value": "${MYSQL_LOWER_CASE_TABLE_NAMES}"
+ },
+ {
+ "name": "MYSQL_MAX_CONNECTIONS",
+ "value": "${MYSQL_MAX_CONNECTIONS}"
+ },
+ {
+ "name": "MYSQL_FT_MIN_WORD_LEN",
+ "value": "${MYSQL_FT_MIN_WORD_LEN}"
+ },
+ {
+ "name": "MYSQL_FT_MAX_WORD_LEN",
+ "value": "${MYSQL_FT_MAX_WORD_LEN}"
+ },
+ {
+ "name": "MYSQL_AIO",
+ "value": "${MYSQL_AIO}"
+ }
+ ]
+ }
+ ]
+ }
+ }
+ }
+ }
+ ]
+}
diff --git a/roles/openshift_examples/files/examples/xpaas-templates/jws-tomcat8-postgresql-persistent-sti.json b/roles/openshift_examples/files/examples/xpaas-templates/jws-tomcat8-postgresql-persistent-sti.json
new file mode 100644
index 000000000..b4644ac08
--- /dev/null
+++ b/roles/openshift_examples/files/examples/xpaas-templates/jws-tomcat8-postgresql-persistent-sti.json
@@ -0,0 +1,576 @@
+{
+ "kind": "Template",
+ "apiVersion": "v1",
+ "metadata": {
+ "annotations": {
+ "iconClass" : "icon-tomcat",
+ "description": "Application template for JWS PostgreSQL applications with persistent storage built using STI."
+ },
+ "name": "jws-tomcat8-postgresql-persistent-sti"
+ },
+ "labels": {
+ "template": "jws-tomcat8-postgresql-persistent-sti"
+ },
+ "parameters": [
+ {
+ "description": "JWS Release version, e.g. 3.0, 2.1, etc.",
+ "name": "JWS_RELEASE",
+ "value": "3.0"
+ },
+ {
+ "description": "The name for the application.",
+ "name": "APPLICATION_NAME",
+ "value": "jws-app"
+ },
+ {
+ "description": "Custom hostname for service routes. Leave blank for default hostname, e.g.: <application-name>.<project>.<default-domain-suffix>",
+ "name": "APPLICATION_HOSTNAME",
+ "value": ""
+ },
+ {
+ "description": "Git source URI for application",
+ "name": "GIT_URI"
+ },
+ {
+ "description": "Git branch/tag reference",
+ "name": "GIT_REF",
+ "value": "master"
+ },
+ {
+ "description": "Path within Git project to build; empty for root project directory.",
+ "name": "GIT_CONTEXT_DIR",
+ "value": ""
+ },
+ {
+ "description": "Database JNDI name used by application to resolve the datasource, e.g. java:/jboss/datasources/mongodb",
+ "name": "DB_JNDI",
+ "value": ""
+ },
+ {
+ "description": "Database name",
+ "name": "DB_DATABASE",
+ "value": "root"
+ },
+ {
+ "description": "Size of persistent storage for database volume.",
+ "name": "VOLUME_CAPACITY",
+ "value": "512Mi"
+ },
+ {
+ "description": "The name of the secret containing the certificate files",
+ "name": "JWS_HTTPS_SECRET",
+ "value": "jws-app-secret"
+ },
+ {
+ "description": "The name of the certificate file within the secret",
+ "name": "JWS_HTTPS_CERTIFICATE",
+ "value": "server.crt"
+ },
+ {
+ "description": "The name of the certificate key file within the secret",
+ "name": "JWS_HTTPS_CERTIFICATE_KEY",
+ "value": "server.key"
+ },
+ {
+ "description": "The certificate password",
+ "name": "JWS_HTTPS_CERTIFICATE_PASSWORD",
+ "value": ""
+ },
+ {
+ "description": "Sets xa-pool/min-pool-size for the configured datasource.",
+ "name": "DB_MIN_POOL_SIZE"
+ },
+ {
+ "description": "Sets xa-pool/max-pool-size for the configured datasource.",
+ "name": "DB_MAX_POOL_SIZE"
+ },
+ {
+ "description": "Sets transaction-isolation for the configured datasource.",
+ "name": "DB_TX_ISOLATION"
+ },
+ {
+ "description": "The maximum number of client connections allowed. This also sets the maximum number of prepared transactions.",
+ "name": "POSTGRESQL_MAX_CONNECTIONS"
+ },
+ {
+ "description": "Configures how much memory is dedicated to PostgreSQL for caching data.",
+ "name": "POSTGRESQL_SHARED_BUFFERS"
+ },
+ {
+ "description": "Database user name",
+ "name": "DB_USERNAME",
+ "from": "user[a-zA-Z0-9]{3}",
+ "generate": "expression"
+ },
+ {
+ "description": "Database user password",
+ "name": "DB_PASSWORD",
+ "from": "[a-zA-Z0-9]{8}",
+ "generate": "expression"
+ },
+ {
+ "description": "JWS Admin User",
+ "name": "JWS_ADMIN_USERNAME",
+ "from": "[a-zA-Z0-9]{8}",
+ "generate": "expression"
+ },
+ {
+ "description": "JWS Admin Password",
+ "name": "JWS_ADMIN_PASSWORD",
+ "from": "[a-zA-Z0-9]{8}",
+ "generate": "expression"
+ },
+ {
+ "description": "Github trigger secret",
+ "name": "GITHUB_TRIGGER_SECRET",
+ "from": "[a-zA-Z0-9]{8}",
+ "generate": "expression"
+ },
+ {
+ "description": "Generic build trigger secret",
+ "name": "GENERIC_TRIGGER_SECRET",
+ "from": "[a-zA-Z0-9]{8}",
+ "generate": "expression"
+ }
+ ],
+ "objects": [
+ {
+ "kind": "Service",
+ "apiVersion": "v1",
+ "spec": {
+ "ports": [
+ {
+ "port": 8080,
+ "targetPort": 8080
+ }
+ ],
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}"
+ }
+ },
+ "metadata": {
+ "name": "${APPLICATION_NAME}",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "The web server's http port."
+ }
+ }
+ },
+ {
+ "kind": "Service",
+ "apiVersion": "v1",
+ "spec": {
+ "ports": [
+ {
+ "port": 8443,
+ "targetPort": 8443
+ }
+ ],
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}"
+ }
+ },
+ "metadata": {
+ "name": "secure-${APPLICATION_NAME}",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "The web server's https port."
+ }
+ }
+ },
+ {
+ "kind": "Service",
+ "apiVersion": "v1",
+ "spec": {
+ "ports": [
+ {
+ "port": 5432,
+ "targetPort": 5432
+ }
+ ],
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}-postgresql"
+ }
+ },
+ "metadata": {
+ "name": "${APPLICATION_NAME}-postgresql",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "The database server's port."
+ }
+ }
+ },
+ {
+ "kind": "Route",
+ "apiVersion": "v1",
+ "id": "${APPLICATION_NAME}-http-route",
+ "metadata": {
+ "name": "${APPLICATION_NAME}-http-route",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "Route for application's http service."
+ }
+ },
+ "spec": {
+ "host": "${APPLICATION_HOSTNAME}",
+ "to": {
+ "name": "${APPLICATION_NAME}"
+ }
+ }
+ },
+ {
+ "kind": "Route",
+ "apiVersion": "v1",
+ "id": "${APPLICATION_NAME}-https-route",
+ "metadata": {
+ "name": "${APPLICATION_NAME}-https-route",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "Route for application's https service."
+ }
+ },
+ "spec": {
+ "host": "${APPLICATION_HOSTNAME}",
+ "to": {
+ "name": "secure-${APPLICATION_NAME}"
+ },
+ "tls": {
+ "termination" : "passthrough"
+ }
+ }
+ },
+ {
+ "kind": "ImageStream",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "${APPLICATION_NAME}",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ }
+ }
+ },
+ {
+ "kind": "BuildConfig",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "${APPLICATION_NAME}",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "source": {
+ "type": "Git",
+ "git": {
+ "uri": "${GIT_URI}",
+ "ref": "${GIT_REF}"
+ },
+ "contextDir":"${GIT_CONTEXT_DIR}"
+ },
+ "strategy": {
+ "type": "Source",
+ "sourceStrategy": {
+ "from": {
+ "kind": "ImageStreamTag",
+ "namespace": "openshift",
+ "name": "jboss-webserver3-tomcat8-openshift:${JWS_RELEASE}"
+ }
+ }
+ },
+ "output": {
+ "to": {
+ "kind": "ImageStreamTag",
+ "name": "${APPLICATION_NAME}:latest"
+ }
+ },
+ "triggers": [
+ {
+ "type": "GitHub",
+ "github": {
+ "secret": "${GITHUB_TRIGGER_SECRET}"
+ }
+ },
+ {
+ "type": "Generic",
+ "generic": {
+ "secret": "${GENERIC_TRIGGER_SECRET}"
+ }
+ },
+ {
+ "type": "ImageChange",
+ "imageChange": {}
+ }
+ ]
+ }
+ },
+ {
+ "kind": "DeploymentConfig",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "${APPLICATION_NAME}",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "strategy": {
+ "type": "Recreate"
+ },
+ "triggers": [
+ {
+ "type": "ImageChange",
+ "imageChangeParams": {
+ "automatic": true,
+ "containerNames": [
+ "${APPLICATION_NAME}"
+ ],
+ "from": {
+ "kind": "ImageStream",
+ "name": "${APPLICATION_NAME}"
+ }
+ }
+ }
+ ],
+ "replicas": 1,
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}"
+ },
+ "template": {
+ "metadata": {
+ "name": "${APPLICATION_NAME}",
+ "labels": {
+ "deploymentConfig": "${APPLICATION_NAME}",
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "serviceAccount": "jws-service-account",
+ "containers": [
+ {
+ "name": "${APPLICATION_NAME}",
+ "image": "${APPLICATION_NAME}",
+ "imagePullPolicy": "Always",
+ "readinessProbe": {
+ "exec": {
+ "command": [
+ "/bin/bash",
+ "-c",
+ "curl -s -u ${JWS_ADMIN_USERNAME}:${JWS_ADMIN_PASSWORD} 'http://localhost:8080/manager/jmxproxy/?get=Catalina%3Atype%3DServer&att=stateName' |grep -iq 'stateName *= *STARTED'"
+ ]
+ }
+ },
+ "volumeMounts": [
+ {
+ "name": "jws-certificate-volume",
+ "mountPath": "/etc/jws-secret-volume",
+ "readOnly": true
+ }
+ ],
+ "ports": [
+ {
+ "name": "http",
+ "containerPort": 8080,
+ "protocol": "TCP"
+ },
+ {
+ "name": "https",
+ "containerPort": 8443,
+ "protocol": "TCP"
+ }
+ ],
+ "env": [
+ {
+ "name": "DB_SERVICE_PREFIX_MAPPING",
+ "value": "${APPLICATION_NAME}-postgresql=DB"
+ },
+ {
+ "name": "DB_JNDI",
+ "value": "${DB_JNDI}"
+ },
+ {
+ "name": "DB_USERNAME",
+ "value": "${DB_USERNAME}"
+ },
+ {
+ "name": "DB_PASSWORD",
+ "value": "${DB_PASSWORD}"
+ },
+ {
+ "name": "DB_DATABASE",
+ "value": "${DB_DATABASE}"
+ },
+ {
+ "name": "DB_MIN_POOL_SIZE",
+ "value": "${DB_MIN_POOL_SIZE}"
+ },
+ {
+ "name": "DB_MAX_POOL_SIZE",
+ "value": "${DB_MAX_POOL_SIZE}"
+ },
+ {
+ "name": "DB_TX_ISOLATION",
+ "value": "${DB_TX_ISOLATION}"
+ },
+ {
+ "name": "JWS_HTTPS_CERTIFICATE_DIR",
+ "value": "/etc/jws-secret-volume"
+ },
+ {
+ "name": "JWS_HTTPS_CERTIFICATE",
+ "value": "${JWS_HTTPS_CERTIFICATE}"
+ },
+ {
+ "name": "JWS_HTTPS_CERTIFICATE_KEY",
+ "value": "${JWS_HTTPS_CERTIFICATE_KEY}"
+ },
+ {
+ "name": "JWS_HTTPS_CERTIFICATE_PASSWORD",
+ "value": "${JWS_HTTPS_CERTIFICATE_PASSWORD}"
+ },
+ {
+ "name": "JWS_ADMIN_USERNAME",
+ "value": "${JWS_ADMIN_USERNAME}"
+ },
+ {
+ "name": "JWS_ADMIN_PASSWORD",
+ "value": "${JWS_ADMIN_PASSWORD}"
+ }
+ ]
+ }
+ ],
+ "volumes": [
+ {
+ "name": "jws-certificate-volume",
+ "secret": {
+ "secretName": "${JWS_HTTPS_SECRET}"
+ }
+ }
+ ]
+ }
+ }
+ }
+ },
+ {
+ "kind": "DeploymentConfig",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "${APPLICATION_NAME}-postgresql",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "strategy": {
+ "type": "Recreate"
+ },
+ "triggers": [
+ {
+ "type": "ImageChange",
+ "imageChangeParams": {
+ "automatic": true,
+ "containerNames": [
+ "${APPLICATION_NAME}-postgresql"
+ ],
+ "from": {
+ "kind": "ImageStreamTag",
+ "namespace": "openshift",
+ "name": "postgresql:latest"
+ }
+ }
+ }
+ ],
+ "replicas": 1,
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}-postgresql"
+ },
+ "template": {
+ "metadata": {
+ "name": "${APPLICATION_NAME}-postgresql",
+ "labels": {
+ "deploymentConfig": "${APPLICATION_NAME}-postgresql",
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "containers": [
+ {
+ "name": "${APPLICATION_NAME}-postgresql",
+ "image": "postgresql",
+ "ports": [
+ {
+ "containerPort": 5432,
+ "protocol": "TCP"
+ }
+ ],
+ "volumeMounts": [
+ {
+ "mountPath": "/var/lib/pgsql/data",
+ "name": "${APPLICATION_NAME}-postgresql-pvol"
+ }
+ ],
+ "env": [
+ {
+ "name": "POSTGRESQL_USER",
+ "value": "${DB_USERNAME}"
+ },
+ {
+ "name": "POSTGRESQL_PASSWORD",
+ "value": "${DB_PASSWORD}"
+ },
+ {
+ "name": "POSTGRESQL_DATABASE",
+ "value": "${DB_DATABASE}"
+ },
+ {
+ "name": "POSTGRESQL_MAX_CONNECTIONS",
+ "value": "${POSTGRESQL_MAX_CONNECTIONS}"
+ },
+ {
+ "name": "POSTGRESQL_SHARED_BUFFERS",
+ "value": "${POSTGRESQL_SHARED_BUFFERS}"
+ }
+ ]
+ }
+ ],
+ "volumes": [
+ {
+ "name": "${APPLICATION_NAME}-postgresql-pvol",
+ "persistentVolumeClaim": {
+ "claimName": "${APPLICATION_NAME}-postgresql-claim"
+ }
+ }
+ ]
+ }
+ }
+ }
+ },
+ {
+ "apiVersion": "v1",
+ "kind": "PersistentVolumeClaim",
+ "metadata": {
+ "name": "${APPLICATION_NAME}-postgresql-claim",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "accessModes": [ "ReadWriteOnce" ],
+ "resources": {
+ "requests": {
+ "storage": "${VOLUME_CAPACITY}"
+ }
+ }
+ }
+ }
+ ]
+}
diff --git a/roles/openshift_examples/files/examples/xpaas-templates/jws-tomcat8-postgresql-sti.json b/roles/openshift_examples/files/examples/xpaas-templates/jws-tomcat8-postgresql-sti.json
new file mode 100644
index 000000000..b46f23225
--- /dev/null
+++ b/roles/openshift_examples/files/examples/xpaas-templates/jws-tomcat8-postgresql-sti.json
@@ -0,0 +1,539 @@
+{
+ "kind": "Template",
+ "apiVersion": "v1",
+ "metadata": {
+ "annotations": {
+ "iconClass" : "icon-tomcat",
+ "description": "Application template for JWS PostgreSQL applications built using STI."
+ },
+ "name": "jws-tomcat8-postgresql-sti"
+ },
+ "labels": {
+ "template": "jws-tomcat8-postgresql-sti"
+ },
+ "parameters": [
+ {
+ "description": "JWS Release version, e.g. 3.0, 2.1, etc.",
+ "name": "JWS_RELEASE",
+ "value": "3.0"
+ },
+ {
+ "description": "The name for the application.",
+ "name": "APPLICATION_NAME",
+ "value": "jws-app"
+ },
+ {
+ "description": "Custom hostname for service routes. Leave blank for default hostname, e.g.: <application-name>.<project>.<default-domain-suffix>",
+ "name": "APPLICATION_HOSTNAME",
+ "value": ""
+ },
+ {
+ "description": "Git source URI for application",
+ "name": "GIT_URI"
+ },
+ {
+ "description": "Git branch/tag reference",
+ "name": "GIT_REF",
+ "value": "master"
+ },
+ {
+ "description": "Path within Git project to build; empty for root project directory.",
+ "name": "GIT_CONTEXT_DIR",
+ "value": ""
+ },
+ {
+ "description": "Database JNDI name used by application to resolve the datasource, e.g. java:/jboss/datasources/mongodb",
+ "name": "DB_JNDI",
+ "value": ""
+ },
+ {
+ "description": "Database name",
+ "name": "DB_DATABASE",
+ "value": "root"
+ },
+ {
+ "description": "The name of the secret containing the certificate files",
+ "name": "JWS_HTTPS_SECRET",
+ "value": "jws-app-secret"
+ },
+ {
+ "description": "The name of the certificate file within the secret",
+ "name": "JWS_HTTPS_CERTIFICATE",
+ "value": "server.crt"
+ },
+ {
+ "description": "The name of the certificate key file within the secret",
+ "name": "JWS_HTTPS_CERTIFICATE_KEY",
+ "value": "server.key"
+ },
+ {
+ "description": "The certificate password",
+ "name": "JWS_HTTPS_CERTIFICATE_PASSWORD",
+ "value": ""
+ },
+ {
+ "description": "Sets xa-pool/min-pool-size for the configured datasource.",
+ "name": "DB_MIN_POOL_SIZE"
+ },
+ {
+ "description": "Sets xa-pool/max-pool-size for the configured datasource.",
+ "name": "DB_MAX_POOL_SIZE"
+ },
+ {
+ "description": "Sets transaction-isolation for the configured datasource.",
+ "name": "DB_TX_ISOLATION"
+ },
+ {
+ "description": "The maximum number of client connections allowed. This also sets the maximum number of prepared transactions.",
+ "name": "POSTGRESQL_MAX_CONNECTIONS"
+ },
+ {
+ "description": "Configures how much memory is dedicated to PostgreSQL for caching data.",
+ "name": "POSTGRESQL_SHARED_BUFFERS"
+ },
+ {
+ "description": "Database user name",
+ "name": "DB_USERNAME",
+ "from": "user[a-zA-Z0-9]{3}",
+ "generate": "expression"
+ },
+ {
+ "description": "Database user password",
+ "name": "DB_PASSWORD",
+ "from": "[a-zA-Z0-9]{8}",
+ "generate": "expression"
+ },
+ {
+ "description": "JWS Admin User",
+ "name": "JWS_ADMIN_USERNAME",
+ "from": "[a-zA-Z0-9]{8}",
+ "generate": "expression"
+ },
+ {
+ "description": "JWS Admin Password",
+ "name": "JWS_ADMIN_PASSWORD",
+ "from": "[a-zA-Z0-9]{8}",
+ "generate": "expression"
+ },
+ {
+ "description": "Github trigger secret",
+ "name": "GITHUB_TRIGGER_SECRET",
+ "from": "[a-zA-Z0-9]{8}",
+ "generate": "expression"
+ },
+ {
+ "description": "Generic build trigger secret",
+ "name": "GENERIC_TRIGGER_SECRET",
+ "from": "[a-zA-Z0-9]{8}",
+ "generate": "expression"
+ }
+ ],
+ "objects": [
+ {
+ "kind": "Service",
+ "apiVersion": "v1",
+ "spec": {
+ "ports": [
+ {
+ "port": 8080,
+ "targetPort": 8080
+ }
+ ],
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}"
+ }
+ },
+ "metadata": {
+ "name": "${APPLICATION_NAME}",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "The web server's http port."
+ }
+ }
+ },
+ {
+ "kind": "Service",
+ "apiVersion": "v1",
+ "spec": {
+ "ports": [
+ {
+ "port": 8443,
+ "targetPort": 8443
+ }
+ ],
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}"
+ }
+ },
+ "metadata": {
+ "name": "secure-${APPLICATION_NAME}",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "The web server's https port."
+ }
+ }
+ },
+ {
+ "kind": "Service",
+ "apiVersion": "v1",
+ "spec": {
+ "ports": [
+ {
+ "port": 5432,
+ "targetPort": 5432
+ }
+ ],
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}-postgresql"
+ }
+ },
+ "metadata": {
+ "name": "${APPLICATION_NAME}-postgresql",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "The database server's port."
+ }
+ }
+ },
+ {
+ "kind": "Route",
+ "apiVersion": "v1",
+ "id": "${APPLICATION_NAME}-http-route",
+ "metadata": {
+ "name": "${APPLICATION_NAME}-http-route",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "Route for application's http service."
+ }
+ },
+ "spec": {
+ "host": "${APPLICATION_HOSTNAME}",
+ "to": {
+ "name": "${APPLICATION_NAME}"
+ }
+ }
+ },
+ {
+ "kind": "Route",
+ "apiVersion": "v1",
+ "id": "${APPLICATION_NAME}-https-route",
+ "metadata": {
+ "name": "${APPLICATION_NAME}-https-route",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ },
+ "annotations": {
+ "description": "Route for application's https service."
+ }
+ },
+ "spec": {
+ "host": "${APPLICATION_HOSTNAME}",
+ "to": {
+ "name": "secure-${APPLICATION_NAME}"
+ },
+ "tls": {
+ "termination" : "passthrough"
+ }
+ }
+ },
+ {
+ "kind": "ImageStream",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "${APPLICATION_NAME}",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ }
+ }
+ },
+ {
+ "kind": "BuildConfig",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "${APPLICATION_NAME}",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "source": {
+ "type": "Git",
+ "git": {
+ "uri": "${GIT_URI}",
+ "ref": "${GIT_REF}"
+ },
+ "contextDir":"${GIT_CONTEXT_DIR}"
+ },
+ "strategy": {
+ "type": "Source",
+ "sourceStrategy": {
+ "from": {
+ "kind": "ImageStreamTag",
+ "namespace": "openshift",
+ "name": "jboss-webserver3-tomcat8-openshift:${JWS_RELEASE}"
+ }
+ }
+ },
+ "output": {
+ "to": {
+ "kind": "ImageStreamTag",
+ "name": "${APPLICATION_NAME}:latest"
+ }
+ },
+ "triggers": [
+ {
+ "type": "GitHub",
+ "github": {
+ "secret": "${GITHUB_TRIGGER_SECRET}"
+ }
+ },
+ {
+ "type": "Generic",
+ "generic": {
+ "secret": "${GENERIC_TRIGGER_SECRET}"
+ }
+ },
+ {
+ "type": "ImageChange",
+ "imageChange": {}
+ }
+ ]
+ }
+ },
+ {
+ "kind": "DeploymentConfig",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "${APPLICATION_NAME}",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "strategy": {
+ "type": "Recreate"
+ },
+ "triggers": [
+ {
+ "type": "ImageChange",
+ "imageChangeParams": {
+ "automatic": true,
+ "containerNames": [
+ "${APPLICATION_NAME}"
+ ],
+ "from": {
+ "kind": "ImageStream",
+ "name": "${APPLICATION_NAME}"
+ }
+ }
+ }
+ ],
+ "replicas": 1,
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}"
+ },
+ "template": {
+ "metadata": {
+ "name": "${APPLICATION_NAME}",
+ "labels": {
+ "deploymentConfig": "${APPLICATION_NAME}",
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "serviceAccount": "jws-service-account",
+ "containers": [
+ {
+ "name": "${APPLICATION_NAME}",
+ "image": "${APPLICATION_NAME}",
+ "imagePullPolicy": "Always",
+ "readinessProbe": {
+ "exec": {
+ "command": [
+ "/bin/bash",
+ "-c",
+ "curl -s -u ${JWS_ADMIN_USERNAME}:${JWS_ADMIN_PASSWORD} 'http://localhost:8080/manager/jmxproxy/?get=Catalina%3Atype%3DServer&att=stateName' |grep -iq 'stateName *= *STARTED'"
+ ]
+ }
+ },
+ "volumeMounts": [
+ {
+ "name": "jws-certificate-volume",
+ "mountPath": "/etc/jws-secret-volume",
+ "readOnly": true
+ }
+ ],
+ "ports": [
+ {
+ "name": "http",
+ "containerPort": 8080,
+ "protocol": "TCP"
+ },
+ {
+ "name": "https",
+ "containerPort": 8443,
+ "protocol": "TCP"
+ }
+ ],
+ "env": [
+ {
+ "name": "DB_SERVICE_PREFIX_MAPPING",
+ "value": "${APPLICATION_NAME}-postgresql=DB"
+ },
+ {
+ "name": "DB_JNDI",
+ "value": "${DB_JNDI}"
+ },
+ {
+ "name": "DB_USERNAME",
+ "value": "${DB_USERNAME}"
+ },
+ {
+ "name": "DB_PASSWORD",
+ "value": "${DB_PASSWORD}"
+ },
+ {
+ "name": "DB_DATABASE",
+ "value": "${DB_DATABASE}"
+ },
+ {
+ "name": "DB_MIN_POOL_SIZE",
+ "value": "${DB_MIN_POOL_SIZE}"
+ },
+ {
+ "name": "DB_MAX_POOL_SIZE",
+ "value": "${DB_MAX_POOL_SIZE}"
+ },
+ {
+ "name": "DB_TX_ISOLATION",
+ "value": "${DB_TX_ISOLATION}"
+ },
+ {
+ "name": "JWS_HTTPS_CERTIFICATE_DIR",
+ "value": "/etc/jws-secret-volume"
+ },
+ {
+ "name": "JWS_HTTPS_CERTIFICATE",
+ "value": "${JWS_HTTPS_CERTIFICATE}"
+ },
+ {
+ "name": "JWS_HTTPS_CERTIFICATE_KEY",
+ "value": "${JWS_HTTPS_CERTIFICATE_KEY}"
+ },
+ {
+ "name": "JWS_HTTPS_CERTIFICATE_PASSWORD",
+ "value": "${JWS_HTTPS_CERTIFICATE_PASSWORD}"
+ },
+ {
+ "name": "JWS_ADMIN_USERNAME",
+ "value": "${JWS_ADMIN_USERNAME}"
+ },
+ {
+ "name": "JWS_ADMIN_PASSWORD",
+ "value": "${JWS_ADMIN_PASSWORD}"
+ }
+ ]
+ }
+ ],
+ "volumes": [
+ {
+ "name": "jws-certificate-volume",
+ "secret": {
+ "secretName": "${JWS_HTTPS_SECRET}"
+ }
+ }
+ ]
+ }
+ }
+ }
+ },
+ {
+ "kind": "DeploymentConfig",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "${APPLICATION_NAME}-postgresql",
+ "labels": {
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "strategy": {
+ "type": "Recreate"
+ },
+ "triggers": [
+ {
+ "type": "ImageChange",
+ "imageChangeParams": {
+ "automatic": true,
+ "containerNames": [
+ "${APPLICATION_NAME}-postgresql"
+ ],
+ "from": {
+ "kind": "ImageStreamTag",
+ "namespace": "openshift",
+ "name": "postgresql:latest"
+ }
+ }
+ }
+ ],
+ "replicas": 1,
+ "selector": {
+ "deploymentConfig": "${APPLICATION_NAME}-postgresql"
+ },
+ "template": {
+ "metadata": {
+ "name": "${APPLICATION_NAME}-postgresql",
+ "labels": {
+ "deploymentConfig": "${APPLICATION_NAME}-postgresql",
+ "application": "${APPLICATION_NAME}"
+ }
+ },
+ "spec": {
+ "containers": [
+ {
+ "name": "${APPLICATION_NAME}-postgresql",
+ "image": "postgresql",
+ "ports": [
+ {
+ "containerPort": 5432,
+ "protocol": "TCP"
+ }
+ ],
+ "env": [
+ {
+ "name": "POSTGRESQL_USER",
+ "value": "${DB_USERNAME}"
+ },
+ {
+ "name": "POSTGRESQL_PASSWORD",
+ "value": "${DB_PASSWORD}"
+ },
+ {
+ "name": "POSTGRESQL_DATABASE",
+ "value": "${DB_DATABASE}"
+ },
+ {
+ "name": "POSTGRESQL_MAX_CONNECTIONS",
+ "value": "${POSTGRESQL_MAX_CONNECTIONS}"
+ },
+ {
+ "name": "POSTGRESQL_SHARED_BUFFERS",
+ "value": "${POSTGRESQL_SHARED_BUFFERS}"
+ }
+ ]
+ }
+ ]
+ }
+ }
+ }
+ }
+ ]
+}
diff --git a/roles/openshift_examples/meta/main.yml b/roles/openshift_examples/meta/main.yml
new file mode 100644
index 000000000..5cfda1c89
--- /dev/null
+++ b/roles/openshift_examples/meta/main.yml
@@ -0,0 +1,15 @@
+---
+galaxy_info:
+ author: Scott Dodson
+ description: OpenShift Examples
+ company: Red Hat, Inc.
+ license: Apache License, Version 2.0
+ min_ansible_version: 1.7
+ platforms:
+ - name: EL
+ versions:
+ - 7
+ categories:
+ - cloud
+dependencies:
+- role: openshift_common
diff --git a/roles/openshift_examples/tasks/main.yml b/roles/openshift_examples/tasks/main.yml
new file mode 100644
index 000000000..40b7a5d6e
--- /dev/null
+++ b/roles/openshift_examples/tasks/main.yml
@@ -0,0 +1,55 @@
+---
+- name: Copy openshift examples
+ copy:
+ src: examples
+ dest: /usr/share/openshift
+
+# RHEL and Centos image streams are mutually exclusive
+- name: Import RHEL streams
+ command: >
+ {{ openshift.common.client_binary }} {{ openshift_examples_import_command }} -n openshift -f {{ rhel_image_streams }}
+ when: openshift_examples_load_rhel
+ register: oex_import_rhel_streams
+ failed_when: "'already exists' not in oex_import_rhel_streams.stderr and oex_import_rhel_streams.rc != 0"
+ changed_when: false
+
+- name: Import Centos Image streams
+ command: >
+ {{ openshift.common.client_binary }} {{ openshift_examples_import_command }} -n openshift -f {{ centos_image_streams }}
+ when: openshift_examples_load_centos | bool
+ register: oex_import_centos_streams
+ failed_when: "'already exists' not in oex_import_centos_streams.stderr and oex_import_centos_streams.rc != 0"
+ changed_when: false
+
+- name: Import db templates
+ command: >
+ {{ openshift.common.client_binary }} {{ openshift_examples_import_command }} -n openshift -f {{ db_templates_base }}
+ when: openshift_examples_load_db_templates | bool
+ register: oex_import_db_templates
+ failed_when: "'already exists' not in oex_import_db_templates.stderr and oex_import_db_templates.rc != 0"
+ changed_when: false
+
+- name: Import quickstart-templates
+ command: >
+ {{ openshift.common.client_binary }} {{ openshift_examples_import_command }} -n openshift -f {{ quickstarts_base }}
+ when: openshift_examples_load_quickstarts | bool
+ register: oex_import_quickstarts
+ failed_when: "'already exists' not in oex_import_quickstarts.stderr and oex_import_quickstarts.rc != 0"
+ changed_when: false
+
+
+- name: Import xPaas image streams
+ command: >
+ {{ openshift.common.client_binary }} {{ openshift_examples_import_command }} -n openshift -f {{ xpaas_image_streams }}
+ when: openshift_examples_load_xpaas | bool
+ register: oex_import_xpaas_streams
+ failed_when: "'already exists' not in oex_import_xpaas_streams.stderr and oex_import_xpaas_streams.rc != 0"
+ changed_when: false
+
+- name: Import xPaas templates
+ command: >
+ {{ openshift.common.client_binary }} {{ openshift_examples_import_command }} -n openshift -f {{ xpaas_templates_base }}
+ when: openshift_examples_load_xpaas | bool
+ register: oex_import_xpaas_templates
+ failed_when: "'already exists' not in oex_import_xpaas_templates.stderr and oex_import_xpaas_templates.rc != 0"
+ changed_when: false
diff --git a/roles/openshift_expand_partition/README.md b/roles/openshift_expand_partition/README.md
new file mode 100644
index 000000000..cd394e1ba
--- /dev/null
+++ b/roles/openshift_expand_partition/README.md
@@ -0,0 +1,87 @@
+# openshift_expand_partition
+
+This role is useful to expand a partition, and it's file system to
+fully utilize the disk it is on. It does this by first expanding the
+partition, and then expanding the file system on the partition.
+
+## Requirements
+
+* A machine with a disk that is not fully utilized
+
+* cloud-utils-growpart rpm (either installed or avialable via yum)
+
+* The partition you are expanding needs to be at the end of the partition list
+
+## Role Variables
+
+```
+# The following variables are if you want to expand
+# /dev/xvda3 that has a filesystem xfs
+
+# oep_drive
+# Drive that has the partition we wish to expand.
+oep_drive: "/dev/xvda"
+
+# oep_partition
+# Partition that we wish to expand.
+oep_partition: 3
+
+# oep_file_system
+# What file system is on the partition
+# Currently only xfs, and ext(2,3,4) are supported
+# For ext2, ext3, or ext4 just use ext
+oep_file_system: "xfs"
+
+```
+
+## Dependencies
+
+growpart
+
+## Example Playbook
+
+With this playbook, the partition /dev/xvda3 will expand to fill the free
+space on /dev/xvda, and the file system will be expanded to fill the new
+partition space.
+
+ - hosts: mynodes
+ sudo: no
+ remote_user: root
+ gather_facts: no
+ roles:
+ - role: openshift_expand_partition
+ oep_drive: "/dev/xvda"
+ oep_partition: 3
+ oep_file_system: "xfs"
+
+
+## Full example
+
+
+* Create an `inventory` file:
+ ```
+ [mynodes]
+ 10.0.0.1
+ 10.0.0.2
+ ```
+
+* Create an ansible playbook, say `expandvar.yaml`:
+ ```
+ - hosts: mynodes
+ sudo: no
+ remote_user: root
+ gather_facts: no
+ roles:
+ - role: openshift_expand_partition
+ oep_drive: "/dev/xvda"
+ oep_partition: 3
+ oep_file_system: "xfs"
+
+* Run the playbook:
+ ```
+ ansible-playbook -i inventory expandvar.yml
+ ```
+
+## License
+
+Apache 2.0
diff --git a/roles/openshift_expand_partition/defaults/main.yml b/roles/openshift_expand_partition/defaults/main.yml
new file mode 100644
index 000000000..cce9bd951
--- /dev/null
+++ b/roles/openshift_expand_partition/defaults/main.yml
@@ -0,0 +1,18 @@
+---
+# oep_drive
+# Drive that has the partition we wish to expand.
+oep_drive: "/dev/xvda"
+
+# oep_partition
+# Partition that we wish to expand.
+oep_partition: 3
+
+# oep_partition_mount_point
+# Where the partition is mounted
+oep_partition_mount_point: /var
+
+# oep_file_system
+# What file system is on the partition
+# Currently only xfs, and ext(2,3,4) are supported
+# For ext2, ext3, or ext4 just use ext
+oep_file_system: "xfs"
diff --git a/roles/openshift_expand_partition/meta/main.yml b/roles/openshift_expand_partition/meta/main.yml
new file mode 100644
index 000000000..c2a38be17
--- /dev/null
+++ b/roles/openshift_expand_partition/meta/main.yml
@@ -0,0 +1,17 @@
+---
+galaxy_info:
+ author: Troy Dawson
+ description: Expand partition and filesystem to fill free space on disks.
+ company: Red Hat, Inc.
+ license: license (Apache)
+ min_ansible_version: 1.4
+ platforms:
+ - name: EL
+ versions:
+ - 7
+ - name: Fedora
+ versions:
+ - all
+ categories:
+ - openshift
+ - cloud
diff --git a/roles/openshift_expand_partition/tasks/main.yml b/roles/openshift_expand_partition/tasks/main.yml
new file mode 100644
index 000000000..8bc399070
--- /dev/null
+++ b/roles/openshift_expand_partition/tasks/main.yml
@@ -0,0 +1,14 @@
+---
+- name: Ensure growpart is installed
+ yum: pkg=cloud-utils-growpart state=present
+
+- name: Grow the partitions
+ command: "growpart {{oep_drive}} {{oep_partition}}"
+
+- name: Expand the filesystem - xfs
+ command: "xfs_growfs {{oep_drive}}{{oep_partition}}"
+ when: oep_file_system == "xfs"
+
+- name: Expand the filesystem - ext(2,3,4)
+ command: "resize2fs {{oep_drive}}{{oep_partition}}"
+ when: oep_file_system == "ext"
diff --git a/roles/openshift_facts/library/openshift_facts.py b/roles/openshift_facts/library/openshift_facts.py
index cb67a13de..795f38341 100755
--- a/roles/openshift_facts/library/openshift_facts.py
+++ b/roles/openshift_facts/library/openshift_facts.py
@@ -1,12 +1,16 @@
#!/usr/bin/python
+# pylint: disable=too-many-lines
# -*- coding: utf-8 -*-
# vim: expandtab:tabstop=4:shiftwidth=4
+# Reason: Disable pylint too-many-lines because we don't want to split up this file.
+# Status: Permanently disabled to keep this module as self-contained as possible.
+
"""Ansible module for retrieving and setting openshift related facts"""
DOCUMENTATION = '''
---
module: openshift_facts
-short_description: OpenShift Facts
+short_description: Cluster Facts
author: Jason DeTiberus
requirements: [ ]
'''
@@ -16,6 +20,8 @@ EXAMPLES = '''
import ConfigParser
import copy
import os
+from distutils.util import strtobool
+from distutils.version import LooseVersion
def hostname_valid(hostname):
@@ -242,8 +248,8 @@ def normalize_openstack_facts(metadata, facts):
# metadata api, should be updated if neutron exposes this.
facts['zone'] = metadata['availability_zone']
-
- facts['network']['ip'] = metadata['ec2_compat']['local-ipv4']
+ local_ipv4 = metadata['ec2_compat']['local-ipv4'].split(',')[0]
+ facts['network']['ip'] = local_ipv4
facts['network']['public_ip'] = metadata['ec2_compat']['public-ipv4']
# TODO: verify local hostname makes sense and is resolvable
@@ -283,45 +289,105 @@ def normalize_provider_facts(provider, metadata):
facts = normalize_openstack_facts(metadata, facts)
return facts
-def set_registry_url_if_unset(facts):
- """ Set registry_url fact if not already present in facts dict
+def set_fluentd_facts_if_unset(facts):
+ """ Set fluentd facts if not already present in facts dict
+ dict: the facts dict updated with the generated fluentd facts if
+ missing
+ Args:
+ facts (dict): existing facts
+ Returns:
+ dict: the facts dict updated with the generated fluentd
+ facts if they were not already present
+
+ """
+ if 'common' in facts:
+ if 'use_fluentd' not in facts['common']:
+ use_fluentd = False
+ facts['common']['use_fluentd'] = use_fluentd
+ return facts
+def set_node_schedulability(facts):
+ """ Set schedulable facts if not already present in facts dict
Args:
facts (dict): existing facts
Returns:
- dict: the facts dict updated with the generated identity providers
+ dict: the facts dict updated with the generated schedulable
facts if they were not already present
+
"""
- for role in ('master', 'node'):
- if role in facts:
+ if 'node' in facts:
+ if 'schedulable' not in facts['node']:
+ if 'master' in facts:
+ facts['node']['schedulable'] = False
+ else:
+ facts['node']['schedulable'] = True
+ return facts
+
+def set_master_selectors(facts):
+ """ Set selectors facts if not already present in facts dict
+ Args:
+ facts (dict): existing facts
+ Returns:
+ dict: the facts dict updated with the generated selectors
+ facts if they were not already present
+
+ """
+ if 'master' in facts:
+ if 'infra_nodes' in facts['master']:
deployment_type = facts['common']['deployment_type']
- if 'registry_url' not in facts[role]:
- registry_url = "openshift/origin-${component}:${version}"
- if deployment_type == 'enterprise':
- registry_url = "openshift3_beta/ose-${component}:${version}"
- elif deployment_type == 'online':
- registry_url = ("docker-registry.ops.rhcloud.com/"
- "openshift3_beta/ose-${component}:${version}")
- facts[role]['registry_url'] = registry_url
+ if deployment_type == 'online':
+ selector = "type=infra"
+ else:
+ selector = "region=infra"
+ if 'router_selector' not in facts['master']:
+ facts['master']['router_selector'] = selector
+ if 'registry_selector' not in facts['master']:
+ facts['master']['registry_selector'] = selector
return facts
-def set_fluentd_facts_if_unset(facts):
- """ Set fluentd facts if not already present in facts dict
- dict: the facts dict updated with the generated fluentd facts if
+def set_metrics_facts_if_unset(facts):
+ """ Set cluster metrics facts if not already present in facts dict
+ dict: the facts dict updated with the generated cluster metrics facts if
missing
Args:
facts (dict): existing facts
Returns:
- dict: the facts dict updated with the generated fluentd
+ dict: the facts dict updated with the generated cluster metrics
facts if they were not already present
"""
if 'common' in facts:
- deployment_type = facts['common']['deployment_type']
- if 'use_fluentd' not in facts['common']:
- use_fluentd = True if deployment_type == 'online' else False
- facts['common']['use_fluentd'] = use_fluentd
+ if 'use_cluster_metrics' not in facts['common']:
+ use_cluster_metrics = False
+ facts['common']['use_cluster_metrics'] = use_cluster_metrics
+ return facts
+
+def set_project_cfg_facts_if_unset(facts):
+ """ Set Project Configuration facts if not already present in facts dict
+ dict:
+ Args:
+ facts (dict): existing facts
+ Returns:
+ dict: the facts dict updated with the generated Project Configuration
+ facts if they were not already present
+
+ """
+
+ config = {
+ 'default_node_selector': '',
+ 'project_request_message': '',
+ 'project_request_template': '',
+ 'mcs_allocator_range': 's0:/2',
+ 'mcs_labels_per_project': 5,
+ 'uid_allocator_range': '1000000000-1999999999/10000'
+ }
+
+ if 'master' in facts:
+ for key, value in config.items():
+ if key not in facts['master']:
+ facts['master'][key] = value
+
return facts
def set_identity_providers_if_unset(facts):
@@ -366,32 +432,135 @@ def set_url_facts_if_unset(facts):
console_port = facts['master']['console_port']
console_path = facts['master']['console_path']
etcd_use_ssl = facts['master']['etcd_use_ssl']
- etcd_port = facts['master']['etcd_port'],
+ etcd_hosts = facts['master']['etcd_hosts']
+ etcd_port = facts['master']['etcd_port']
hostname = facts['common']['hostname']
public_hostname = facts['common']['public_hostname']
+ cluster_hostname = facts['master'].get('cluster_hostname')
+ cluster_public_hostname = facts['master'].get('cluster_public_hostname')
if 'etcd_urls' not in facts['master']:
- facts['master']['etcd_urls'] = [format_url(etcd_use_ssl, hostname,
- etcd_port)]
+ etcd_urls = []
+ if etcd_hosts != '':
+ facts['master']['etcd_port'] = etcd_port
+ facts['master']['embedded_etcd'] = False
+ for host in etcd_hosts:
+ etcd_urls.append(format_url(etcd_use_ssl, host,
+ etcd_port))
+ else:
+ etcd_urls = [format_url(etcd_use_ssl, hostname,
+ etcd_port)]
+ facts['master']['etcd_urls'] = etcd_urls
if 'api_url' not in facts['master']:
- facts['master']['api_url'] = format_url(api_use_ssl, hostname,
+ api_hostname = cluster_hostname if cluster_hostname else hostname
+ facts['master']['api_url'] = format_url(api_use_ssl, api_hostname,
api_port)
if 'public_api_url' not in facts['master']:
+ api_public_hostname = cluster_public_hostname if cluster_public_hostname else public_hostname
facts['master']['public_api_url'] = format_url(api_use_ssl,
- public_hostname,
+ api_public_hostname,
api_port)
if 'console_url' not in facts['master']:
+ console_hostname = cluster_hostname if cluster_hostname else hostname
facts['master']['console_url'] = format_url(console_use_ssl,
- hostname,
+ console_hostname,
console_port,
console_path)
if 'public_console_url' not in facts['master']:
+ console_public_hostname = cluster_public_hostname if cluster_public_hostname else public_hostname
facts['master']['public_console_url'] = format_url(console_use_ssl,
- public_hostname,
+ console_public_hostname,
console_port,
console_path)
return facts
+def set_aggregate_facts(facts):
+ """ Set aggregate facts
+
+ Args:
+ facts (dict): existing facts
+ Returns:
+ dict: the facts dict updated with aggregated facts
+ """
+ all_hostnames = set()
+ if 'common' in facts:
+ all_hostnames.add(facts['common']['hostname'])
+ all_hostnames.add(facts['common']['public_hostname'])
+
+ if 'master' in facts:
+ if 'cluster_hostname' in facts['master']:
+ all_hostnames.add(facts['master']['cluster_hostname'])
+ if 'cluster_public_hostname' in facts['master']:
+ all_hostnames.add(facts['master']['cluster_public_hostname'])
+
+ facts['common']['all_hostnames'] = list(all_hostnames)
+
+ return facts
+
+def set_deployment_facts_if_unset(facts):
+ """ Set Facts that vary based on deployment_type. This currently
+ includes common.service_type, common.config_base, master.registry_url,
+ node.registry_url, node.storage_plugin_deps
+
+ Args:
+ facts (dict): existing facts
+ Returns:
+ dict: the facts dict updated with the generated deployment_type
+ facts
+ """
+ # Perhaps re-factor this as a map?
+ # pylint: disable=too-many-branches
+ if 'common' in facts:
+ deployment_type = facts['common']['deployment_type']
+ if 'service_type' not in facts['common']:
+ service_type = 'atomic-openshift'
+ if deployment_type == 'origin':
+ service_type = 'origin'
+ elif deployment_type in ['enterprise', 'online']:
+ service_type = 'openshift'
+ facts['common']['service_type'] = service_type
+ if 'config_base' not in facts['common']:
+ config_base = '/etc/origin'
+ if deployment_type in ['enterprise', 'online']:
+ config_base = '/etc/openshift'
+ facts['common']['config_base'] = config_base
+ if 'data_dir' not in facts['common']:
+ data_dir = '/var/lib/origin'
+ if deployment_type in ['enterprise', 'online']:
+ data_dir = '/var/lib/openshift'
+ facts['common']['data_dir'] = data_dir
+ facts['common']['version'] = version = get_openshift_version()
+ if version is not None:
+ if deployment_type == 'origin':
+ version_gt_3_1_or_1_1 = LooseVersion(version) > LooseVersion('1.0.6')
+ else:
+ version_gt_3_1_or_1_1 = LooseVersion(version) > LooseVersion('3.0.2')
+ else:
+ version_gt_3_1_or_1_1 = True
+ facts['common']['version_greater_than_3_1_or_1_1'] = version_gt_3_1_or_1_1
+
+ for role in ('master', 'node'):
+ if role in facts:
+ deployment_type = facts['common']['deployment_type']
+ if 'registry_url' not in facts[role]:
+ registry_url = 'openshift/origin-${component}:${version}'
+ if deployment_type in ['enterprise', 'online', 'openshift-enterprise']:
+ registry_url = 'openshift3/ose-${component}:${version}'
+ elif deployment_type == 'atomic-enterprise':
+ registry_url = 'aep3/aep-${component}:${version}'
+ facts[role]['registry_url'] = registry_url
+
+ if 'node' in facts:
+ deployment_type = facts['common']['deployment_type']
+ if 'storage_plugin_deps' not in facts['node']:
+ if deployment_type in ['openshift-enterprise', 'atomic-enterprise']:
+ facts['node']['storage_plugin_deps'] = ['ceph', 'glusterfs']
+ else:
+ facts['node']['storage_plugin_deps'] = []
+
+ return facts
+
+
def set_sdn_facts_if_unset(facts):
""" Set sdn facts if not already present in facts dict
@@ -402,8 +571,10 @@ def set_sdn_facts_if_unset(facts):
were not already present
"""
if 'common' in facts:
+ use_sdn = facts['common']['use_openshift_sdn']
+ if not (use_sdn == '' or isinstance(use_sdn, bool)):
+ facts['common']['use_openshift_sdn'] = bool(strtobool(str(use_sdn)))
if 'sdn_network_plugin_name' not in facts['common']:
- use_sdn = facts['common']['use_openshift_sdn']
plugin = 'redhat/openshift-ovs-subnet' if use_sdn else ''
facts['common']['sdn_network_plugin_name'] = plugin
@@ -413,6 +584,10 @@ def set_sdn_facts_if_unset(facts):
if 'sdn_host_subnet_length' not in facts['master']:
facts['master']['sdn_host_subnet_length'] = '8'
+ if 'node' in facts:
+ if 'sdn_mtu' not in facts['node']:
+ facts['node']['sdn_mtu'] = '1450'
+
return facts
def format_url(use_ssl, hostname, port, path=''):
@@ -450,9 +625,11 @@ def get_current_config(facts):
# TODO: parse the /etc/sysconfig/openshift-{master,node} config to
# determine the location of files.
-
+ # TODO: I suspect this isn't working right now, but it doesn't prevent
+ # anything from working properly as far as I can tell, perhaps because
+ # we override the kubeconfig path everywhere we use it?
# Query kubeconfig settings
- kubeconfig_dir = '/var/lib/openshift/openshift.local.certificates'
+ kubeconfig_dir = '/var/lib/origin/openshift.local.certificates'
if role == 'node':
kubeconfig_dir = os.path.join(
kubeconfig_dir, "node-%s" % facts['common']['hostname']
@@ -485,7 +662,7 @@ def get_current_config(facts):
current_config['kubeconfig'] = config
# override pylint broad-except warning, since we do not want
- # to bubble up any exceptions if openshift ex config view
+ # to bubble up any exceptions if oc config view
# fails
# pylint: disable=broad-except
except Exception:
@@ -493,6 +670,21 @@ def get_current_config(facts):
return current_config
+def get_openshift_version():
+ """ Get current version of openshift on the host
+
+ Returns:
+ version: the current openshift version
+ """
+ version = None
+
+ if os.path.isfile('/usr/bin/openshift'):
+ _, output, _ = module.run_command(['/usr/bin/openshift', 'version'])
+ versions = dict(e.split(' v') for e in output.splitlines() if ' v' in e)
+ version = versions.get('openshift', '')
+
+ #TODO: acknowledge the possility of a containerized install
+ return version
def apply_provider_facts(facts, provider_facts):
""" Apply provider facts to supplied facts dict
@@ -538,7 +730,7 @@ def merge_facts(orig, new):
facts = dict()
for key, value in orig.iteritems():
if key in new:
- if isinstance(value, dict):
+ if isinstance(value, dict) and isinstance(new[key], dict):
facts[key] = merge_facts(value, new[key])
else:
facts[key] = copy.copy(new[key])
@@ -599,25 +791,25 @@ def get_local_facts_from_file(filename):
class OpenShiftFactsUnsupportedRoleError(Exception):
- """OpenShift Facts Unsupported Role Error"""
+ """Origin Facts Unsupported Role Error"""
pass
class OpenShiftFactsFileWriteError(Exception):
- """OpenShift Facts File Write Error"""
+ """Origin Facts File Write Error"""
pass
class OpenShiftFactsMetadataUnavailableError(Exception):
- """OpenShift Facts Metadata Unavailable Error"""
+ """Origin Facts Metadata Unavailable Error"""
pass
class OpenShiftFacts(object):
- """ OpenShift Facts
+ """ Origin Facts
Attributes:
- facts (dict): OpenShift facts for the host
+ facts (dict): facts for the host
Args:
role (str): role for setting local facts
@@ -659,10 +851,15 @@ class OpenShiftFacts(object):
facts = merge_facts(facts, local_facts)
facts['current_config'] = get_current_config(facts)
facts = set_url_facts_if_unset(facts)
+ facts = set_project_cfg_facts_if_unset(facts)
facts = set_fluentd_facts_if_unset(facts)
+ facts = set_node_schedulability(facts)
+ facts = set_master_selectors(facts)
+ facts = set_metrics_facts_if_unset(facts)
facts = set_identity_providers_if_unset(facts)
- facts = set_registry_url_if_unset(facts)
facts = set_sdn_facts_if_unset(facts)
+ facts = set_deployment_facts_if_unset(facts)
+ facts = set_aggregate_facts(facts)
return dict(openshift=facts)
def get_defaults(self, roles):
@@ -681,7 +878,7 @@ class OpenShiftFacts(object):
hostname_f = output.strip() if exit_code == 0 else ''
hostname_values = [hostname_f, self.system_facts['nodename'],
self.system_facts['fqdn']]
- hostname = choose_hostname(hostname_values)
+ hostname = choose_hostname(hostname_values, ip_addr)
common = dict(use_openshift_sdn=True, ip=ip_addr, public_ip=ip_addr,
deployment_type='origin', hostname=hostname,
@@ -693,7 +890,7 @@ class OpenShiftFacts(object):
if 'master' in roles:
master = dict(api_use_ssl=True, api_port='8443',
console_use_ssl=True, console_path='/console',
- console_port='8443', etcd_use_ssl=True,
+ console_port='8443', etcd_use_ssl=True, etcd_hosts='',
etcd_port='4001', portal_net='172.30.0.0/16',
embedded_etcd=True, embedded_kube=True,
embedded_dns=True, dns_port='53',
@@ -701,15 +898,11 @@ class OpenShiftFacts(object):
session_name='ssn', session_secrets_file='',
access_token_max_seconds=86400,
auth_token_max_seconds=500,
- oauth_grant_method='auto')
+ oauth_grant_method='auto', cluster_defer_ha=False)
defaults['master'] = master
if 'node' in roles:
- node = dict(pod_cidr='', labels={}, annotations={}, portal_net='172.30.0.0/16')
- node['resources_cpu'] = self.system_facts['processor_cores']
- node['resources_memory'] = int(
- int(self.system_facts['memtotal_mb']) * 1024 * 1024 * 0.75
- )
+ node = dict(labels={}, annotations={}, portal_net='172.30.0.0/16')
defaults['node'] = node
return defaults
diff --git a/roles/openshift_facts/tasks/main.yml b/roles/openshift_facts/tasks/main.yml
index d71e6d019..6301d4fc0 100644
--- a/roles/openshift_facts/tasks/main.yml
+++ b/roles/openshift_facts/tasks/main.yml
@@ -1,9 +1,10 @@
---
-- name: Verify Ansible version is greater than 1.8.0 and not 1.9.0
+- name: Verify Ansible version is greater than 1.8.0 and not 1.9.0 and not 1.9.0.1
assert:
that:
- ansible_version | version_compare('1.8.0', 'ge')
- ansible_version | version_compare('1.9.0', 'ne')
+ - ansible_version | version_compare('1.9.0.1', 'ne')
-- name: Gather OpenShift facts
+- name: Gather Cluster facts
openshift_facts:
diff --git a/roles/openshift_manage_node/tasks/main.yml b/roles/openshift_manage_node/tasks/main.yml
new file mode 100644
index 000000000..637e494ea
--- /dev/null
+++ b/roles/openshift_manage_node/tasks/main.yml
@@ -0,0 +1,21 @@
+- name: Wait for Node Registration
+ command: >
+ {{ openshift.common.client_binary }} get node {{ item | lower }}
+ register: omd_get_node
+ until: omd_get_node.rc == 0
+ retries: 20
+ delay: 5
+ with_items: openshift_nodes
+
+- name: Set node schedulability
+ command: >
+ {{ openshift.common.admin_binary }} manage-node {{ item.openshift.common.hostname | lower }} --schedulable={{ 'true' if item.openshift.node.schedulable | bool else 'false' }}
+ with_items:
+ - "{{ openshift_node_vars }}"
+
+- name: Label nodes
+ command: >
+ {{ openshift.common.client_binary }} label --overwrite node {{ item.openshift.common.hostname | lower }} {{ item.openshift.node.labels | oo_combine_dict }}
+ with_items:
+ - "{{ openshift_node_vars }}"
+ when: "'labels' in item.openshift.node and item.openshift.node.labels != {}"
diff --git a/roles/openshift_master/README.md b/roles/openshift_master/README.md
index 3178e318c..155bdb58b 100644
--- a/roles/openshift_master/README.md
+++ b/roles/openshift_master/README.md
@@ -1,13 +1,13 @@
-OpenShift Master
-================
+OpenShift/Atomic Enterprise Master
+==================================
-OpenShift Master service installation
+Master service installation
Requirements
------------
A RHEL 7.1 host pre-configured with access to the rhel-7-server-rpms,
-rhel-7-server-extras-rpms, and rhel-server-7-ose-beta-rpms repos.
+rhel-7-server-extras-rpms, and rhel-7-server-ose-3.0-rpms repos.
Role Variables
--------------
@@ -15,8 +15,8 @@ Role Variables
From this role:
| Name | Default value | |
|-------------------------------------|-----------------------|--------------------------------------------------|
-| openshift_master_debug_level | openshift_debug_level | Verbosity of the debug logs for openshift-master |
-| openshift_node_ips | [] | List of the openshift node ip addresses to pre-register when openshift-master starts up |
+| openshift_master_debug_level | openshift_debug_level | Verbosity of the debug logs for master |
+| openshift_node_ips | [] | List of the openshift node ip addresses to pre-register when master starts up |
| oreg_url | UNDEF | Default docker registry to use |
| openshift_master_api_port | UNDEF | |
| openshift_master_console_port | UNDEF | |
@@ -28,7 +28,7 @@ From this role:
From openshift_common:
| Name | Default Value | |
|-------------------------------|----------------|----------------------------------------|
-| openshift_debug_level | 0 | Global openshift debug log verbosity |
+| openshift_debug_level | 2 | Global openshift debug log verbosity |
| openshift_public_ip | UNDEF | Public IP address to use for this host |
| openshift_hostname | UNDEF | hostname to use for this instance |
diff --git a/roles/openshift_master/defaults/main.yml b/roles/openshift_master/defaults/main.yml
index 11195e83e..9766d01ae 100644
--- a/roles/openshift_master/defaults/main.yml
+++ b/roles/openshift_master/defaults/main.yml
@@ -5,20 +5,26 @@ openshift_node_ips: []
os_firewall_allow:
- service: etcd embedded
port: 4001/tcp
-- service: OpenShift api https
+- service: api server https
port: 8443/tcp
-- service: OpenShift dns tcp
+- service: dns tcp
port: 53/tcp
-- service: OpenShift dns udp
+- service: dns udp
port: 53/udp
- service: Fluentd td-agent tcp
port: 24224/tcp
- service: Fluentd td-agent udp
port: 24224/udp
+- service: pcsd
+ port: 2224/tcp
+- service: Corosync UDP
+ port: 5404/udp
+- service: Corosync UDP
+ port: 5405/udp
os_firewall_deny:
-- service: OpenShift api http
+- service: api server http
port: 8080/tcp
-- service: former OpenShift web console port
+- service: former web console port
port: 8444/tcp
- service: former etcd peer port
port: 7001/tcp
diff --git a/roles/openshift_master/handlers/main.yml b/roles/openshift_master/handlers/main.yml
index 6fd4dfb51..37028e0f6 100644
--- a/roles/openshift_master/handlers/main.yml
+++ b/roles/openshift_master/handlers/main.yml
@@ -1,3 +1,4 @@
---
-- name: restart openshift-master
- service: name=openshift-master state=restarted
+- name: restart master
+ service: name={{ openshift.common.service_type }}-master state=restarted
+ when: (not openshift_master_ha | bool) and (not master_service_status_changed | default(false))
diff --git a/roles/openshift_master/meta/main.yml b/roles/openshift_master/meta/main.yml
index 41a183c3b..c125cb5d0 100644
--- a/roles/openshift_master/meta/main.yml
+++ b/roles/openshift_master/meta/main.yml
@@ -1,7 +1,7 @@
---
galaxy_info:
author: Jhon Honce
- description: OpenShift Master
+ description: Master
company: Red Hat, Inc.
license: Apache License, Version 2.0
min_ansible_version: 1.7
diff --git a/roles/openshift_master/tasks/main.yml b/roles/openshift_master/tasks/main.yml
index 23f8b4649..94eb73346 100644
--- a/roles/openshift_master/tasks/main.yml
+++ b/roles/openshift_master/tasks/main.yml
@@ -8,10 +8,17 @@
- openshift_master_oauth_grant_method in openshift_master_valid_grant_methods
when: openshift_master_oauth_grant_method is defined
-- name: Set master OpenShift facts
+- fail:
+ msg: "openshift_master_cluster_password must be set for multi-master installations"
+ when: openshift_master_ha | bool and not openshift.master.cluster_defer_ha | bool and openshift_master_cluster_password is not defined
+
+- name: Set master facts
openshift_facts:
role: master
local_facts:
+ cluster_hostname: "{{ openshift_master_cluster_hostname | default(None) }}"
+ cluster_public_hostname: "{{ openshift_master_cluster_public_hostname | default(None) }}"
+ cluster_defer_ha: "{{ openshift_master_cluster_defer_ha | default(None) }}"
debug_level: "{{ openshift_master_debug_level | default(openshift.common.debug_level) }}"
api_port: "{{ openshift_master_api_port | default(None) }}"
api_url: "{{ openshift_master_api_url | default(None) }}"
@@ -22,6 +29,7 @@
console_url: "{{ openshift_master_console_url | default(None) }}"
console_use_ssl: "{{ openshift_master_console_use_ssl | default(None) }}"
public_console_url: "{{ openshift_master_public_console_url | default(None) }}"
+ etcd_hosts: "{{ openshift_master_etcd_hosts | default(None)}}"
etcd_port: "{{ openshift_master_etcd_port | default(None) }}"
etcd_use_ssl: "{{ openshift_master_etcd_use_ssl | default(None) }}"
etcd_urls: "{{ openshift_master_etcd_urls | default(None) }}"
@@ -41,39 +49,38 @@
oauth_grant_method: "{{ openshift_master_oauth_grant_method | default(None) }}"
sdn_cluster_network_cidr: "{{ osm_cluster_network_cidr | default(None) }}"
sdn_host_subnet_length: "{{ osm_host_subnet_length | default(None) }}"
+ default_subdomain: "{{ osm_default_subdomain | default(None) }}"
+ custom_cors_origins: "{{ osm_custom_cors_origins | default(None) }}"
+ default_node_selector: "{{ osm_default_node_selector | default(None) }}"
+ project_request_message: "{{ osm_project_request_message | default(None) }}"
+ project_request_template: "{{ osm_project_request_template | default(None) }}"
+ mcs_allocator_range: "{{ osm_mcs_allocator_range | default(None) }}"
+ mcs_labels_per_project: "{{ osm_mcs_labels_per_project | default(None) }}"
+ uid_allocator_range: "{{ osm_uid_allocator_range | default(None) }}"
+ router_selector: "{{ openshift_router_selector | default(None) }}"
+ registry_selector: "{{ openshift_registry_selector | default(None) }}"
+ api_server_args: "{{ osm_api_server_args | default(None) }}"
+ controller_args: "{{ osm_controller_args | default(None) }}"
+ infra_nodes: "{{ num_infra | default(None) }}"
+
+- name: Install Master package
+ yum: pkg={{ openshift.common.service_type }}-master{{ openshift_version }} state=present
+ register: install_result
# TODO: These values need to be configurable
-- name: Set dns OpenShift facts
+- name: Set dns facts
openshift_facts:
role: dns
local_facts:
- ip: "{{ openshift.common.ip }}"
+ ip: "{{ openshift_master_cluster_vip | default(openshift.common.ip, true) | default(None) }}"
domain: cluster.local
when: openshift.master.embedded_dns
-- name: Install OpenShift Master package
- yum: pkg=openshift-master state=present
- register: install_result
-
-- name: Reload systemd units
- command: systemctl daemon-reload
- when: install_result | changed
-
- name: Create config parent directory if it doesn't exist
file:
path: "{{ openshift_master_config_dir }}"
state: directory
-- name: Create the master certificates if they do not already exist
- command: >
- {{ openshift.common.admin_binary }} create-master-certs
- --hostnames={{ openshift.common.hostname }},{{ openshift.common.public_hostname }}
- --master={{ openshift.master.api_url }}
- --public-master={{ openshift.master.public_api_url }}
- --cert-dir={{ openshift_master_config_dir }} --overwrite=false
- args:
- creates: "{{ openshift_master_config_dir }}/master.server.key"
-
- name: Create the policy file if it does not already exist
command: >
{{ openshift.common.admin_binary }} create-bootstrap-policy-file
@@ -81,20 +88,28 @@
args:
creates: "{{ openshift_master_policy }}"
notify:
- - restart openshift-master
+ - restart master
- name: Create the scheduler config
template:
dest: "{{ openshift_master_scheduler_conf }}"
src: scheduler.json.j2
+ backup: true
notify:
- - restart openshift-master
+ - restart master
- name: Install httpd-tools if needed
yum: pkg=httpd-tools state=present
when: item.kind == 'HTPasswdPasswordIdentityProvider'
with_items: openshift.master.identity_providers
+- name: Ensure htpasswd directory exists
+ file:
+ path: "{{ item.filename | dirname }}"
+ state: directory
+ when: item.kind == 'HTPasswdPasswordIdentityProvider'
+ with_items: openshift.master.identity_providers
+
- name: Create the htpasswd file if needed
copy:
dest: "{{ item.filename }}"
@@ -109,12 +124,13 @@
template:
dest: "{{ openshift_master_config_file }}"
src: master.yaml.v1.j2
+ backup: true
notify:
- - restart openshift-master
+ - restart master
-- name: Configure OpenShift settings
+- name: Configure master settings
lineinfile:
- dest: /etc/sysconfig/openshift-master
+ dest: /etc/sysconfig/{{ openshift.common.service_type }}-master
regexp: "{{ item.regex }}"
line: "{{ item.line }}"
with_items:
@@ -123,39 +139,61 @@
- regex: '^CONFIG_FILE='
line: "CONFIG_FILE={{ openshift_master_config_file }}"
notify:
- - restart openshift-master
+ - restart master
+
+- name: Start and enable master
+ service: name={{ openshift.common.service_type }}-master enabled=yes state=started
+ when: not openshift_master_ha | bool
+ register: start_result
+
+- set_fact:
+ master_service_status_changed = start_result | changed
+
+- name: Install cluster packages
+ yum: pkg=pcs state=present
+ when: openshift_master_ha | bool and not openshift.master.cluster_defer_ha | bool
+ register: install_result
+
+- name: Start and enable cluster service
+ service: name=pcsd enabled=yes state=started
+ when: openshift_master_ha | bool and not openshift.master.cluster_defer_ha | bool
+
+- name: Set the cluster user password
+ shell: echo {{ openshift_master_cluster_password | quote }} | passwd --stdin hacluster
+ when: install_result | changed
-- name: Start and enable openshift-master
- service: name=openshift-master enabled=yes state=started
+- name: Lookup default group for ansible_ssh_user
+ command: "/usr/bin/id -g {{ ansible_ssh_user }}"
+ register: _ansible_ssh_user_gid
-- name: Create the OpenShift client config dir(s)
+- name: Create the client config dir(s)
file:
- path: "~{{ item }}/.config/openshift"
+ path: "~{{ item }}/.kube"
state: directory
mode: 0700
owner: "{{ item }}"
- group: "{{ item }}"
+ group: "{{ 'root' if item == 'root' else _ansible_ssh_user_gid.stdout }}"
with_items:
- root
- "{{ ansible_ssh_user }}"
# TODO: Update this file if the contents of the source file are not present in
# the dest file, will need to make sure to ignore things that could be added
-- name: Copy the OpenShift admin client config(s)
- command: cp {{ openshift_master_config_dir }}/admin.kubeconfig ~{{ item }}/.config/openshift/.config
+- name: Copy the admin client config(s)
+ command: cp {{ openshift_master_config_dir }}/admin.kubeconfig ~{{ item }}/.kube/config
args:
- creates: ~{{ item }}/.config/openshift/.config
+ creates: ~{{ item }}/.kube/config
with_items:
- root
- "{{ ansible_ssh_user }}"
-- name: Update the permissions on the OpenShift admin client config(s)
+- name: Update the permissions on the admin client config(s)
file:
- path: "~{{ item }}/.config/openshift/.config"
+ path: "~{{ item }}/.kube/config"
state: file
mode: 0700
owner: "{{ item }}"
- group: "{{ item }}"
+ group: "{{ 'root' if item == 'root' else _ansible_ssh_user_gid.stdout }}"
with_items:
- root
- "{{ ansible_ssh_user }}"
diff --git a/roles/openshift_master/templates/master.yaml.v1.j2 b/roles/openshift_master/templates/master.yaml.v1.j2
index 1c2d37b63..3e4f78b17 100644
--- a/roles/openshift_master/templates/master.yaml.v1.j2
+++ b/roles/openshift_master/templates/master.yaml.v1.j2
@@ -1,3 +1,6 @@
+apiLevels:
+- v1beta3
+- v1
apiVersion: v1
assetConfig:
logoutURL: ""
@@ -8,24 +11,28 @@ assetConfig:
certFile: master.server.crt
clientCA: ""
keyFile: master.server.key
+ maxRequestsInFlight: 0
+ requestTimeoutSeconds: 0
corsAllowedOrigins:
-{# TODO: add support for user specified corsAllowedOrigins #}
{% for origin in ['127.0.0.1', 'localhost', openshift.common.hostname, openshift.common.ip, openshift.common.public_hostname, openshift.common.public_ip] %}
- {{ origin }}
{% endfor %}
-{% if openshift.master.embedded_dns %}
+{% for custom_origin in openshift.master.custom_cors_origins | default("") %}
+ - {{ custom_origin }}
+{% endfor %}
+{% if openshift.master.embedded_dns | bool %}
dnsConfig:
bindAddress: {{ openshift.master.bind_addr }}:{{ openshift.master.dns_port }}
{% endif %}
etcdClientInfo:
- ca: ca.crt
+ ca: {{ "ca.crt" if (openshift.master.embedded_etcd | bool) else "master.etcd-ca.crt" }}
certFile: master.etcd-client.crt
keyFile: master.etcd-client.key
urls:
{% for etcd_url in openshift.master.etcd_urls %}
- {{ etcd_url }}
{% endfor %}
-{% if openshift.master.embedded_etcd %}
+{% if openshift.master.embedded_etcd | bool %}
etcdConfig:
address: {{ openshift.common.hostname }}:{{ openshift.master.etcd_port }}
peerAddress: {{ openshift.common.hostname }}:7001
@@ -39,13 +46,13 @@ etcdConfig:
certFile: etcd.server.crt
clientCA: ca.crt
keyFile: etcd.server.key
- storageDirectory: {{ openshift_data_dir }}/openshift.local.etcd
+ storageDirectory: {{ openshift.common.data_dir }}/openshift.local.etcd
{% endif %}
etcdStorageConfig:
kubernetesStoragePrefix: kubernetes.io
- kubernetesStorageVersion: v1beta3
- kubernetesStoragePrefix: kubernetes.io
- openShiftStorageVersion: v1beta3
+ kubernetesStorageVersion: v1
+ openShiftStoragePrefix: openshift.io
+ openShiftStorageVersion: v1
imageConfig:
format: {{ openshift.master.registry_url }}
latest: false
@@ -56,38 +63,59 @@ kubeletClientInfo:
certFile: master.kubelet-client.crt
keyFile: master.kubelet-client.key
port: 10250
-{% if openshift.master.embedded_kube %}
+{% if openshift.master.embedded_kube | bool %}
kubernetesMasterConfig:
+ apiLevels:
+ - v1beta3
+ - v1
+ apiServerArguments: {{ api_server_args if api_server_args is defined else 'null' }}
+ controllerArguments: {{ controller_args if controller_args is defined else 'null' }}
{# TODO: support overriding masterCount #}
masterCount: 1
masterIP: ""
+ podEvictionTimeout: ""
+ proxyClientInfo:
+ certFile: master.proxy-client.crt
+ keyFile: master.proxy-client.key
schedulerConfigFile: {{ openshift_master_scheduler_conf }}
+ servicesNodePortRange: ""
servicesSubnet: {{ openshift.master.portal_net }}
staticNodeNames: {{ openshift_node_ips | default([], true) }}
{% endif %}
masterClients:
{# TODO: allow user to set externalKubernetesKubeConfig #}
- deployerKubeConfig: openshift-deployer.kubeconfig
externalKubernetesKubeConfig: ""
- openshiftLoopbackKubeConfig: openshift-client.kubeconfig
+ openshiftLoopbackKubeConfig: openshift-master.kubeconfig
masterPublicURL: {{ openshift.master.public_api_url }}
networkConfig:
clusterNetworkCIDR: {{ openshift.master.sdn_cluster_network_cidr }}
hostSubnetLength: {{ openshift.master.sdn_host_subnet_length }}
+{% if openshift.common.use_openshift_sdn %}
networkPluginName: {{ openshift.common.sdn_network_plugin_name }}
+{% endif %}
+# serviceNetworkCIDR must match kubernetesMasterConfig.servicesSubnet
+ serviceNetworkCIDR: {{ openshift.master.portal_net }}
{% include 'v1_partials/oauthConfig.j2' %}
policyConfig:
bootstrapPolicyFile: {{ openshift_master_policy }}
+ openshiftInfrastructureNamespace: openshift-infra
openshiftSharedResourcesNamespace: openshift
-{# TODO: Allow users to override projectConfig items #}
projectConfig:
- defaultNodeSelector: ""
- projectRequestMessage: ""
- projectRequestTemplate: ""
+ defaultNodeSelector: "{{ openshift.master.default_node_selector }}"
+ projectRequestMessage: "{{ openshift.master.project_request_message }}"
+ projectRequestTemplate: "{{ openshift.master.project_request_template }}"
+ securityAllocator:
+ mcsAllocatorRange: "{{ openshift.master.mcs_allocator_range }}"
+ mcsLabelsPerProject: {{ openshift.master.mcs_labels_per_project }}
+ uidAllocatorRange: "{{ openshift.master.uid_allocator_range }}"
+routingConfig:
+ subdomain: "{{ openshift.master.default_subdomain | default("") }}"
serviceAccountConfig:
managedNames:
- default
- builder
+ - deployer
+ masterCA: ca.crt
privateKeyFile: serviceaccounts.private.key
publicKeyFiles:
- serviceaccounts.public.key
@@ -96,3 +124,5 @@ servingInfo:
certFile: master.server.crt
clientCA: ca.crt
keyFile: master.server.key
+ maxRequestsInFlight: 500
+ requestTimeoutSeconds: 3600
diff --git a/roles/openshift_master/templates/scheduler.json.j2 b/roles/openshift_master/templates/scheduler.json.j2
index 833e7f3e1..cb5f43bb2 100644
--- a/roles/openshift_master/templates/scheduler.json.j2
+++ b/roles/openshift_master/templates/scheduler.json.j2
@@ -1,5 +1,8 @@
{
+ "kind": "Policy",
+ "apiVersion": "v1",
"predicates": [
+ {"name": "MatchNodeSelector"},
{"name": "PodFitsResources"},
{"name": "PodFitsPorts"},
{"name": "NoDiskConflict"},
diff --git a/roles/openshift_master/templates/v1_partials/oauthConfig.j2 b/roles/openshift_master/templates/v1_partials/oauthConfig.j2
index f6fd88c65..8a4f5a746 100644
--- a/roles/openshift_master/templates/v1_partials/oauthConfig.j2
+++ b/roles/openshift_master/templates/v1_partials/oauthConfig.j2
@@ -7,9 +7,23 @@
url: {{ identity_provider.url }}
{% for key in ('ca', 'certFile', 'keyFile') %}
{% if key in identity_provider %}
- {{ key }}: {{ identity_provider[key] }}"
+ {{ key }}: "{{ identity_provider[key] }}"
{% endif %}
{% endfor %}
+{% elif identity_provider.kind == 'LDAPPasswordIdentityProvider' %}
+ attributes:
+{% for attribute_key in identity_provider.attributes %}
+ {{ attribute_key }}:
+{% for attribute_value in identity_provider.attributes[attribute_key] %}
+ - {{ attribute_value }}
+{% endfor %}
+{% endfor %}
+{% for key in ('bindDN', 'bindPassword', 'ca') %}
+ {{ key }}: "{{ identity_provider[key] }}"
+{% endfor %}
+{% for key in ('insecure', 'url') %}
+ {{ key }}: {{ identity_provider[key] }}
+{% endfor %}
{% elif identity_provider.kind == 'RequestHeaderIdentityProvider' %}
headers: {{ identity_provider.headers }}
{% if 'clientCA' in identity_provider %}
@@ -66,6 +80,7 @@ oauthConfig:
provider:
{{ identity_provider_config(identity_provider) }}
{%- endfor %}
+ masterCA: ca.crt
masterPublicURL: {{ openshift.master.public_api_url }}
masterURL: {{ openshift.master.api_url }}
sessionConfig:
diff --git a/roles/openshift_master/vars/main.yml b/roles/openshift_master/vars/main.yml
index f6f69966a..ecdb4f883 100644
--- a/roles/openshift_master/vars/main.yml
+++ b/roles/openshift_master/vars/main.yml
@@ -1,8 +1,9 @@
---
-openshift_master_config_dir: /etc/openshift/master
+openshift_master_config_dir: "{{ openshift.common.config_base }}/master"
openshift_master_config_file: "{{ openshift_master_config_dir }}/master-config.yaml"
openshift_master_scheduler_conf: "{{ openshift_master_config_dir }}/scheduler.json"
openshift_master_policy: "{{ openshift_master_config_dir }}/policy.json"
+openshift_version: "{{ openshift_pkg_version | default('') }}"
openshift_master_valid_grant_methods:
- auto
diff --git a/roles/openshift_register_nodes/README.md b/roles/openshift_master_ca/README.md
index b96faa044..5b2d3601b 100644
--- a/roles/openshift_register_nodes/README.md
+++ b/roles/openshift_master_ca/README.md
@@ -1,4 +1,4 @@
-OpenShift Register Nodes
+OpenShift Master CA
========================
TODO
diff --git a/roles/openshift_master_ca/meta/main.yml b/roles/openshift_master_ca/meta/main.yml
new file mode 100644
index 000000000..0c8881521
--- /dev/null
+++ b/roles/openshift_master_ca/meta/main.yml
@@ -0,0 +1,16 @@
+---
+galaxy_info:
+ author: Jason DeTiberus
+ description:
+ company: Red Hat, Inc.
+ license: Apache License, Version 2.0
+ min_ansible_version: 1.8
+ platforms:
+ - name: EL
+ versions:
+ - 7
+ categories:
+ - cloud
+ - system
+dependencies:
+- { role: openshift_repos }
diff --git a/roles/openshift_master_ca/tasks/main.yml b/roles/openshift_master_ca/tasks/main.yml
new file mode 100644
index 000000000..cfd1ceabf
--- /dev/null
+++ b/roles/openshift_master_ca/tasks/main.yml
@@ -0,0 +1,21 @@
+---
+- name: Install the base package for admin tooling
+ yum: pkg={{ openshift.common.service_type }}{{ openshift_version }} state=present
+ register: install_result
+
+- name: Reload generated facts
+ openshift_facts:
+
+- name: Create openshift_master_config_dir if it doesn't exist
+ file:
+ path: "{{ openshift_master_config_dir }}"
+ state: directory
+
+- name: Create the master certificates if they do not already exist
+ command: >
+ {{ openshift.common.admin_binary }} create-master-certs
+ --hostnames={{ openshift.common.all_hostnames | join(',') }}
+ --master={{ openshift.master.api_url }}
+ --public-master={{ openshift.master.public_api_url }}
+ --cert-dir={{ openshift_master_config_dir }} --overwrite=false
+ when: master_certs_missing
diff --git a/roles/openshift_register_nodes/vars/main.yml b/roles/openshift_master_ca/vars/main.yml
index 3801b8427..b35339b18 100644
--- a/roles/openshift_register_nodes/vars/main.yml
+++ b/roles/openshift_master_ca/vars/main.yml
@@ -1,8 +1,6 @@
---
-openshift_node_config_dir: /etc/openshift/node
-openshift_master_config_dir: /etc/openshift/master
-openshift_generated_configs_dir: /etc/openshift/generated-configs
+openshift_master_config_dir: "{{ openshift.common.config_base }}/master"
openshift_master_ca_cert: "{{ openshift_master_config_dir }}/ca.crt"
openshift_master_ca_key: "{{ openshift_master_config_dir }}/ca.key"
openshift_master_ca_serial: "{{ openshift_master_config_dir }}/ca.serial.txt"
-openshift_kube_api_version: v1beta3
+openshift_version: "{{ openshift_pkg_version | default('') }}"
diff --git a/roles/openshift_master_certificates/README.md b/roles/openshift_master_certificates/README.md
new file mode 100644
index 000000000..ba3d5f28c
--- /dev/null
+++ b/roles/openshift_master_certificates/README.md
@@ -0,0 +1,34 @@
+OpenShift Master Certificates
+========================
+
+TODO
+
+Requirements
+------------
+
+TODO
+
+Role Variables
+--------------
+
+TODO
+
+Dependencies
+------------
+
+TODO
+
+Example Playbook
+----------------
+
+TODO
+
+License
+-------
+
+Apache License Version 2.0
+
+Author Information
+------------------
+
+Jason DeTiberus (jdetiber@redhat.com)
diff --git a/roles/openshift_master_certificates/meta/main.yml b/roles/openshift_master_certificates/meta/main.yml
new file mode 100644
index 000000000..fd7b73b0f
--- /dev/null
+++ b/roles/openshift_master_certificates/meta/main.yml
@@ -0,0 +1,16 @@
+---
+galaxy_info:
+ author: Jason DeTiberus
+ description:
+ company: Red Hat, Inc.
+ license: Apache License, Version 2.0
+ min_ansible_version: 1.8
+ platforms:
+ - name: EL
+ versions:
+ - 7
+ categories:
+ - cloud
+ - system
+dependencies:
+- { role: openshift_master_ca }
diff --git a/roles/openshift_master_certificates/tasks/main.yml b/roles/openshift_master_certificates/tasks/main.yml
new file mode 100644
index 000000000..e4602337e
--- /dev/null
+++ b/roles/openshift_master_certificates/tasks/main.yml
@@ -0,0 +1,47 @@
+---
+- name: Ensure the generated_configs directory present
+ file:
+ path: "{{ openshift_generated_configs_dir }}/{{ item.master_cert_subdir }}"
+ state: directory
+ mode: 0700
+ with_items: masters_needing_certs
+
+- file:
+ src: "{{ openshift_master_config_dir }}/{{ item.1 }}"
+ dest: "{{ openshift_generated_configs_dir }}/{{ item.0.master_cert_subdir }}/{{ item.1 }}"
+ state: hard
+ with_nested:
+ - masters_needing_certs
+ - - ca.crt
+ - ca.key
+ - ca.serial.txt
+ - admin.crt
+ - admin.key
+ - admin.kubeconfig
+ - master.kubelet-client.crt
+ - master.kubelet-client.key
+ - "{{ 'master.proxy-client.crt' if openshift.common.version_greater_than_3_1_or_1_1 else omit }}"
+ - "{{ 'master.proxy-client.key' if openshift.common.version_greater_than_3_1_or_1_1 else omit }}"
+ - openshift-master.crt
+ - openshift-master.key
+ - openshift-master.kubeconfig
+ - openshift-registry.crt
+ - openshift-registry.key
+ - openshift-registry.kubeconfig
+ - openshift-router.crt
+ - openshift-router.key
+ - openshift-router.kubeconfig
+ - serviceaccounts.private.key
+ - serviceaccounts.public.key
+
+
+- name: Create the master certificates if they do not already exist
+ command: >
+ {{ openshift.common.admin_binary }} create-master-certs
+ --hostnames={{ item.openshift.common.all_hostnames | join(',') }}
+ --master={{ item.openshift.master.api_url }}
+ --public-master={{ item.openshift.master.public_api_url }}
+ --cert-dir={{ openshift_generated_configs_dir }}/{{ item.master_cert_subdir }}
+ --overwrite=false
+ when: master_certs_missing
+ with_items: masters_needing_certs
diff --git a/roles/openshift_master_certificates/vars/main.yml b/roles/openshift_master_certificates/vars/main.yml
new file mode 100644
index 000000000..3f18ddc79
--- /dev/null
+++ b/roles/openshift_master_certificates/vars/main.yml
@@ -0,0 +1,3 @@
+---
+openshift_generated_configs_dir: "{{ openshift.common.config_base }}/generated-configs"
+openshift_master_config_dir: "{{ openshift.common.config_base }}/master"
diff --git a/roles/openshift_master_cluster/README.md b/roles/openshift_master_cluster/README.md
new file mode 100644
index 000000000..f150981fa
--- /dev/null
+++ b/roles/openshift_master_cluster/README.md
@@ -0,0 +1,34 @@
+OpenShift Master Cluster
+========================
+
+TODO
+
+Requirements
+------------
+
+TODO
+
+Role Variables
+--------------
+
+TODO
+
+Dependencies
+------------
+
+TODO
+
+Example Playbook
+----------------
+
+TODO
+
+License
+-------
+
+Apache License Version 2.0
+
+Author Information
+------------------
+
+Jason DeTiberus (jdetiber@redhat.com)
diff --git a/roles/openshift_master_cluster/meta/main.yml b/roles/openshift_master_cluster/meta/main.yml
new file mode 100644
index 000000000..0c8881521
--- /dev/null
+++ b/roles/openshift_master_cluster/meta/main.yml
@@ -0,0 +1,16 @@
+---
+galaxy_info:
+ author: Jason DeTiberus
+ description:
+ company: Red Hat, Inc.
+ license: Apache License, Version 2.0
+ min_ansible_version: 1.8
+ platforms:
+ - name: EL
+ versions:
+ - 7
+ categories:
+ - cloud
+ - system
+dependencies:
+- { role: openshift_repos }
diff --git a/roles/openshift_master_cluster/tasks/configure.yml b/roles/openshift_master_cluster/tasks/configure.yml
new file mode 100644
index 000000000..7ab9afb51
--- /dev/null
+++ b/roles/openshift_master_cluster/tasks/configure.yml
@@ -0,0 +1,44 @@
+---
+- fail:
+ msg: This role requires that openshift_master_cluster_vip is set
+ when: openshift_master_cluster_vip is not defined or not openshift_master_cluster_vip
+- fail:
+ msg: This role requires that openshift_master_cluster_public_vip is set
+ when: openshift_master_cluster_public_vip is not defined or not openshift_master_cluster_public_vip
+
+- name: Authenticate to the cluster
+ command: pcs cluster auth -u hacluster -p {{ openshift_master_cluster_password }} {{ omc_cluster_hosts }}
+
+- name: Create the cluster
+ command: pcs cluster setup --name openshift_master {{ omc_cluster_hosts }}
+
+- name: Start the cluster
+ command: pcs cluster start --all
+
+- name: Enable the cluster on all nodes
+ command: pcs cluster enable --all
+
+- name: Set default resource stickiness
+ command: pcs resource defaults resource-stickiness=100
+
+- name: Add the cluster VIP resource
+ command: pcs resource create virtual-ip IPaddr2 ip={{ openshift_master_cluster_vip }} --group {{ openshift.common.service_type }}-master
+
+- name: Add the cluster public VIP resource
+ command: pcs resource create virtual-ip IPaddr2 ip={{ openshift_master_cluster_public_vip }} --group {{ openshift.common.service_type }}-master
+ when: openshift_master_cluster_public_vip != openshift_master_cluster_vip
+
+- name: Add the cluster master service resource
+ command: pcs resource create master systemd:{{ openshift.common.service_type }}-master op start timeout=90s stop timeout=90s --group {{ openshift.common.service_type }}-master
+
+- name: Disable stonith
+ command: pcs property set stonith-enabled=false
+
+# TODO: handle case where api port is not 8443
+- name: Wait for the clustered master service to be available
+ wait_for:
+ host: "{{ openshift_master_cluster_vip }}"
+ port: 8443
+ state: started
+ timeout: 180
+ delay: 90
diff --git a/roles/openshift_master_cluster/tasks/configure_deferred.yml b/roles/openshift_master_cluster/tasks/configure_deferred.yml
new file mode 100644
index 000000000..3b416005b
--- /dev/null
+++ b/roles/openshift_master_cluster/tasks/configure_deferred.yml
@@ -0,0 +1,8 @@
+---
+- debug: msg="Deferring config"
+
+- name: Start and enable the master
+ service:
+ name: "{{ openshift.common.service_type }}-master"
+ state: started
+ enabled: yes
diff --git a/roles/openshift_master_cluster/tasks/main.yml b/roles/openshift_master_cluster/tasks/main.yml
new file mode 100644
index 000000000..315947183
--- /dev/null
+++ b/roles/openshift_master_cluster/tasks/main.yml
@@ -0,0 +1,13 @@
+---
+- name: Test if cluster is already configured
+ command: pcs status
+ register: pcs_status
+ changed_when: false
+ failed_when: false
+ when: not openshift.master.cluster_defer_ha | bool
+
+- include: configure.yml
+ when: "pcs_status | failed and 'Error: cluster is not currently running on this node' in pcs_status.stderr"
+
+- include: configure_deferred.yml
+ when: openshift.master.cluster_defer_ha | bool
diff --git a/roles/openshift_node/README.md b/roles/openshift_node/README.md
index c3c17b848..3aff81274 100644
--- a/roles/openshift_node/README.md
+++ b/roles/openshift_node/README.md
@@ -1,28 +1,28 @@
-OpenShift Node
-==============
+OpenShift/Atomic Enterprise Node
+================================
-OpenShift Node service installation
+Node service installation
Requirements
------------
-One or more OpenShift Master servers.
+One or more Master servers.
A RHEL 7.1 host pre-configured with access to the rhel-7-server-rpms,
-rhel-7-server-extras-rpms, and rhel-server-7-ose-beta-rpms repos.
+rhel-7-server-extras-rpms, and rhel-7-server-ose-3.0-rpms repos.
Role Variables
--------------
From this role:
-| Name | Default value | |
-|------------------------------------------|-----------------------|----------------------------------------|
-| openshift_node_debug_level | openshift_debug_level | Verbosity of the debug logs for openshift-node |
-| oreg_url | UNDEF (Optional) | Default docker registry to use |
+| Name | Default value | |
+|------------------------------------------|-----------------------|--------------------------------------------------------|
+| openshift_node_debug_level | openshift_debug_level | Verbosity of the debug logs for node |
+| oreg_url | UNDEF (Optional) | Default docker registry to use |
From openshift_common:
-| Name | Default Value | |
+| Name | Default Value | |
|-------------------------------|---------------------|---------------------|
-| openshift_debug_level | 0 | Global openshift debug log verbosity |
+| openshift_debug_level | 2 | Global openshift debug log verbosity |
| openshift_public_ip | UNDEF (Required) | Public IP address to use for this host |
| openshift_hostname | UNDEF (Required) | hostname to use for this instance |
@@ -34,6 +34,18 @@ openshift_common
Example Playbook
----------------
+Notes
+-----
+
+Currently we support re-labeling nodes but we don't re-schedule running pods nor remove existing labels. That means you will have to trigger the re-schedulling manually. To re-schedule your pods, just follow the steps below:
+
+```
+oadm manage-node --schedulable=false ${NODE}
+oadm manage-node --evacuate ${NODE}
+oadm manage-node --schedulable=true ${NODE}
+````
+
+
TODO
License
diff --git a/roles/openshift_node/defaults/main.yml b/roles/openshift_node/defaults/main.yml
index be51195f2..fffbf2994 100644
--- a/roles/openshift_node/defaults/main.yml
+++ b/roles/openshift_node/defaults/main.yml
@@ -1,8 +1,15 @@
---
os_firewall_allow:
-- service: OpenShift kubelet
+- service: Kubernetes kubelet
port: 10250/tcp
- service: http
port: 80/tcp
- service: https
port: 443/tcp
+- service: Openshift kubelet ReadOnlyPort
+ port: 10255/tcp
+- service: Openshift kubelet ReadOnlyPort udp
+ port: 10255/udp
+- service: OpenShift OVS sdn
+ port: 4789/udp
+ when: openshift.node.use_openshift_sdn | bool
diff --git a/roles/openshift_node/handlers/main.yml b/roles/openshift_node/handlers/main.yml
index 953a1421b..447ca85f3 100644
--- a/roles/openshift_node/handlers/main.yml
+++ b/roles/openshift_node/handlers/main.yml
@@ -1,3 +1,7 @@
---
-- name: restart openshift-node
- service: name=openshift-node state=restarted
+- name: restart node
+ service: name={{ openshift.common.service_type }}-node state=restarted
+ when: not node_service_status_changed | default(false)
+
+- name: restart docker
+ service: name=docker state=restarted
diff --git a/roles/openshift_node/tasks/main.yml b/roles/openshift_node/tasks/main.yml
index 15d18f510..aea60b75c 100644
--- a/roles/openshift_node/tasks/main.yml
+++ b/roles/openshift_node/tasks/main.yml
@@ -1,7 +1,16 @@
---
# TODO: allow for overriding default ports where possible
+- fail:
+ msg: This role requres that osn_cluster_dns_domain is set
+ when: osn_cluster_dns_domain is not defined or not osn_cluster_dns_domain
+- fail:
+ msg: This role requres that osn_cluster_dns_ip is set
+ when: osn_cluster_dns_ip is not defined or not osn_cluster_dns_ip
+- fail:
+ msg: "SELinux is disabled, This deployment type requires that SELinux is enabled."
+ when: (not ansible_selinux or ansible_selinux.status != 'enabled') and deployment_type in ['enterprise', 'online']
-- name: Set node OpenShift facts
+- name: Set node facts
openshift_facts:
role: "{{ item.role }}"
local_facts: "{{ item.local_facts }}"
@@ -13,40 +22,41 @@
deployment_type: "{{ openshift_deployment_type }}"
- role: node
local_facts:
- resources_cpu: "{{ openshift_node_resources_cpu | default(none) }}"
- resources_memory: "{{ openshift_node_resources_memory | default(none) }}"
- pod_cidr: "{{ openshift_node_pod_cidr | default(none) }}"
- labels: "{{ openshift_node_labels | default(none) }}"
+ labels: "{{ lookup('oo_option', 'openshift_node_labels') | default( openshift_node_labels | default(none), true) }}"
annotations: "{{ openshift_node_annotations | default(none) }}"
registry_url: "{{ oreg_url | default(none) }}"
debug_level: "{{ openshift_node_debug_level | default(openshift.common.debug_level) }}"
portal_net: "{{ openshift_master_portal_net | default(None) }}"
+ kubelet_args: "{{ openshift_node_kubelet_args | default(None) }}"
+ sdn_mtu: "{{ openshift_node_sdn_mtu | default(None) }}"
+ schedulable: "{{ openshift_schedulable | default(openshift_scheduleable) | default(None) }}"
+ docker_log_driver: "{{ lookup( 'oo_option' , 'docker_log_driver' ) | default('',True) }}"
+ docker_log_options: "{{ lookup( 'oo_option' , 'docker_log_options' ) | default('',True) }}"
+ storage_plugin_deps: "{{ osn_storage_plugin_deps | default(None) }}"
-- name: Install OpenShift Node package
- yum: pkg=openshift-node state=present
+# We have to add tuned-profiles in the same transaction otherwise we run into depsolving
+# problems because the rpms don't pin the version properly.
+- name: Install Node package
+ yum: pkg={{ openshift.common.service_type }}-node{{ openshift_version }},tuned-profiles-{{ openshift.common.service_type }}-node{{ openshift_version }} state=present
register: node_install_result
-- name: Install openshift-sdn-ovs
- yum: pkg=openshift-sdn-ovs state=present
+- name: Install sdn-ovs package
+ yum: pkg={{ openshift.common.service_type }}-sdn-ovs{{ openshift_version }} state=present
register: sdn_install_result
when: openshift.common.use_openshift_sdn
-- name: Reload systemd units
- command: systemctl daemon-reload
- when: (node_install_result | changed or (openshift.common.use_openshift_sdn
- and sdn_install_result | changed))
-
# TODO: add the validate parameter when there is a validation command to run
- name: Create the Node config
template:
dest: "{{ openshift_node_config_file }}"
src: node.yaml.v1.j2
+ backup: true
notify:
- - restart openshift-node
+ - restart node
-- name: Configure OpenShift Node settings
+- name: Configure Node settings
lineinfile:
- dest: /etc/sysconfig/openshift-node
+ dest: /etc/sysconfig/{{ openshift.common.service_type }}-node
regexp: "{{ item.regex }}"
line: "{{ item.line }}"
with_items:
@@ -55,21 +65,72 @@
- regex: '^CONFIG_FILE='
line: "CONFIG_FILE={{ openshift_node_config_file }}"
notify:
- - restart openshift-node
+ - restart node
- stat: path=/etc/sysconfig/docker
register: docker_check
# TODO: Enable secure registry when code available in origin
-- name: Secure OpenShift Registry
+- name: Secure Registry and Logs Options
lineinfile:
dest: /etc/sysconfig/docker
- regexp: '^OPTIONS=.*'
- line: "OPTIONS='--insecure-registry={{ openshift.node.portal_net }} --selinux-enabled'"
+ regexp: '^OPTIONS=.*$'
+ line: "OPTIONS='--insecure-registry={{ openshift.node.portal_net }} \
+{% if ansible_selinux and ansible_selinux.status == '''enabled''' %}--selinux-enabled{% endif %} \
+{% if openshift.node.docker_log_driver is defined %} --log-driver {{ openshift.node.docker_log_driver }} {% endif %} \
+{% if openshift.node.docker_log_options is defined %} {{ openshift.node.docker_log_options | oo_split() | oo_prepend_strings_in_list('--log-opt ') | join(' ')}} {% endif %} '"
when: docker_check.stat.isreg
+ notify:
+ - restart docker
+
+- set_fact:
+ docker_additional_registries: "{{ lookup('oo_option', 'docker_additional_registries')
+ | oo_split() | union(['registry.access.redhat.com'])
+ | difference(['']) }}"
+ when: openshift.common.deployment_type == 'enterprise'
+- set_fact:
+ docker_additional_registries: "{{ lookup('oo_option', 'docker_additional_registries')
+ | oo_split() | difference(['']) }}"
+ when: openshift.common.deployment_type != 'enterprise'
+
+- name: Add personal registries
+ lineinfile:
+ dest: /etc/sysconfig/docker
+ regexp: '^ADD_REGISTRY=.*$'
+ line: "ADD_REGISTRY='{{ docker_additional_registries
+ | oo_prepend_strings_in_list('--add-registry ') | join(' ') }}'"
+ when: docker_check.stat.isreg and docker_additional_registries
+ notify:
+ - restart docker
+
+- name: Block registries
+ lineinfile:
+ dest: /etc/sysconfig/docker
+ regexp: '^BLOCK_REGISTRY=.*$'
+ line: "BLOCK_REGISTRY='{{ lookup('oo_option', 'docker_blocked_registries') | oo_split()
+ | oo_prepend_strings_in_list('--block-registry ') | join(' ') }}'"
+ when: docker_check.stat.isreg and
+ lookup('oo_option', 'docker_blocked_registries') != ''
+ notify:
+ - restart docker
+
+- name: Grant access to additional insecure registries
+ lineinfile:
+ dest: /etc/sysconfig/docker
+ regexp: '^INSECURE_REGISTRY=.*'
+ line: "INSECURE_REGISTRY='{{ lookup('oo_option', 'docker_insecure_registries') | oo_split()
+ | oo_prepend_strings_in_list('--insecure-registry ') | join(' ') }}'"
+ when: docker_check.stat.isreg and
+ lookup('oo_option', 'docker_insecure_registries') != ''
+ notify:
+ - restart docker
+
+- name: Additional storage plugin configuration
+ include: storage_plugins/main.yml
-- name: Allow NFS access for VMs
- seboolean: name=virt_use_nfs state=yes persistent=yes
+- name: Start and enable node
+ service: name={{ openshift.common.service_type }}-node enabled=yes state=started
+ register: start_result
-- name: Start and enable openshift-node
- service: name=openshift-node enabled=yes state=started
+- set_fact:
+ node_service_status_changed = start_result | changed
diff --git a/roles/openshift_node/tasks/storage_plugins/ceph.yml b/roles/openshift_node/tasks/storage_plugins/ceph.yml
new file mode 100644
index 000000000..b6936618a
--- /dev/null
+++ b/roles/openshift_node/tasks/storage_plugins/ceph.yml
@@ -0,0 +1,5 @@
+---
+- name: Install Ceph storage plugin dependencies
+ yum:
+ pkg: ceph-common
+ state: installed
diff --git a/roles/openshift_node/tasks/storage_plugins/glusterfs.yml b/roles/openshift_node/tasks/storage_plugins/glusterfs.yml
new file mode 100644
index 000000000..b812e81df
--- /dev/null
+++ b/roles/openshift_node/tasks/storage_plugins/glusterfs.yml
@@ -0,0 +1,12 @@
+---
+- name: Install GlusterFS storage plugin dependencies
+ yum:
+ pkg: glusterfs-fuse
+ state: installed
+
+- name: Set seboolean to allow gluster storage plugin access from containers
+ seboolean:
+ name: virt_use_fusefs
+ state: yes
+ persistent: yes
+ when: ansible_selinux and ansible_selinux.status == "enabled"
diff --git a/roles/openshift_node/tasks/storage_plugins/main.yml b/roles/openshift_node/tasks/storage_plugins/main.yml
new file mode 100644
index 000000000..39c7b9390
--- /dev/null
+++ b/roles/openshift_node/tasks/storage_plugins/main.yml
@@ -0,0 +1,13 @@
+---
+# The NFS storage plugin is always enabled since it doesn't require any
+# additional package dependencies
+- name: NFS storage plugin configuration
+ include: nfs.yml
+
+- name: GlusterFS storage plugin configuration
+ include: glusterfs.yml
+ when: "'glusterfs' in openshift.node.storage_plugin_deps"
+
+- name: Ceph storage plugin configuration
+ include: ceph.yml
+ when: "'ceph' in openshift.node.storage_plugin_deps"
diff --git a/roles/openshift_node/tasks/storage_plugins/nfs.yml b/roles/openshift_node/tasks/storage_plugins/nfs.yml
new file mode 100644
index 000000000..1edf21d9b
--- /dev/null
+++ b/roles/openshift_node/tasks/storage_plugins/nfs.yml
@@ -0,0 +1,7 @@
+---
+- name: Set seboolean to allow nfs storage plugin access from containers
+ seboolean:
+ name: virt_use_nfs
+ state: yes
+ persistent: yes
+ when: ansible_selinux and ansible_selinux.status == "enabled"
diff --git a/roles/openshift_node/templates/node.yaml.v1.j2 b/roles/openshift_node/templates/node.yaml.v1.j2
index cab75cd49..4931d127e 100644
--- a/roles/openshift_node/templates/node.yaml.v1.j2
+++ b/roles/openshift_node/templates/node.yaml.v1.j2
@@ -1,18 +1,33 @@
allowDisabledDocker: false
apiVersion: v1
-dnsDomain: {{ hostvars[openshift_first_master].openshift.dns.domain }}
-dnsIP: {{ hostvars[openshift_first_master].openshift.dns.ip }}
+dnsDomain: {{ osn_cluster_dns_domain }}
+dnsIP: {{ osn_cluster_dns_ip }}
+dockerConfig:
+ execHandlerName: ""
imageConfig:
format: {{ openshift.node.registry_url }}
latest: false
kind: NodeConfig
-masterKubeConfig: node.kubeconfig
+{% if openshift.node.kubelet_args is defined and openshift.node.kubelet_args %}
+kubeletArguments: {{ openshift.node.kubelet_args | to_json }}
+{% endif %}
+masterKubeConfig: system:node:{{ openshift.common.hostname }}.kubeconfig
+{% if openshift.common.use_openshift_sdn %}
networkPluginName: {{ openshift.common.sdn_network_plugin_name }}
-nodeName: {{ openshift.common.hostname }}
-podManifestConfig: null
+{% endif %}
+# networkConfig struct introduced in origin 1.0.6 and OSE 3.0.2 which
+# deprecates networkPluginName above. The two should match.
+networkConfig:
+ mtu: {{ openshift.node.sdn_mtu }}
+{% if openshift.common.use_openshift_sdn %}
+ networkPluginName: {{ openshift.common.sdn_network_plugin_name }}
+{% endif %}
+nodeName: {{ openshift.common.hostname | lower }}
+podManifestConfig:
servingInfo:
bindAddress: 0.0.0.0:10250
certFile: server.crt
clientCA: ca.crt
keyFile: server.key
-volumeDirectory: {{ openshift_data_dir }}/openshift.local.volumes
+volumeDirectory: {{ openshift.common.data_dir }}/openshift.local.volumes
+{% include 'partials/kubeletArguments.j2' %}
diff --git a/roles/openshift_node/templates/partials/kubeletArguments.j2 b/roles/openshift_node/templates/partials/kubeletArguments.j2
new file mode 100644
index 000000000..6c3bd04c5
--- /dev/null
+++ b/roles/openshift_node/templates/partials/kubeletArguments.j2
@@ -0,0 +1,5 @@
+{% if openshift.common.use_cluster_metrics | bool %}
+kubeletArguments:
+ "read-only-port":
+ - "10255"
+{% endif %} \ No newline at end of file
diff --git a/roles/openshift_node/vars/main.yml b/roles/openshift_node/vars/main.yml
index cf47f8354..43dc50ca8 100644
--- a/roles/openshift_node/vars/main.yml
+++ b/roles/openshift_node/vars/main.yml
@@ -1,3 +1,4 @@
---
-openshift_node_config_dir: /etc/openshift/node
+openshift_node_config_dir: "{{ openshift.common.config_base }}/node"
openshift_node_config_file: "{{ openshift_node_config_dir }}/node-config.yaml"
+openshift_version: "{{ openshift_pkg_version | default('') }}"
diff --git a/roles/openshift_node_certificates/README.md b/roles/openshift_node_certificates/README.md
new file mode 100644
index 000000000..6264d253a
--- /dev/null
+++ b/roles/openshift_node_certificates/README.md
@@ -0,0 +1,34 @@
+OpenShift/Atomic Enterprise Node Certificates
+=============================================
+
+TODO
+
+Requirements
+------------
+
+TODO
+
+Role Variables
+--------------
+
+TODO
+
+Dependencies
+------------
+
+TODO
+
+Example Playbook
+----------------
+
+TODO
+
+License
+-------
+
+Apache License Version 2.0
+
+Author Information
+------------------
+
+Jason DeTiberus (jdetiber@redhat.com)
diff --git a/roles/openshift_register_nodes/meta/main.yml b/roles/openshift_node_certificates/meta/main.yml
index e40a152c1..f3236e850 100644
--- a/roles/openshift_register_nodes/meta/main.yml
+++ b/roles/openshift_node_certificates/meta/main.yml
@@ -14,4 +14,3 @@ galaxy_info:
- system
dependencies:
- { role: openshift_facts }
-
diff --git a/roles/openshift_register_nodes/tasks/main.yml b/roles/openshift_node_certificates/tasks/main.yml
index 11097a7cf..57f71887b 100644
--- a/roles/openshift_register_nodes/tasks/main.yml
+++ b/roles/openshift_node_certificates/tasks/main.yml
@@ -3,6 +3,7 @@
file:
path: "{{ openshift_generated_configs_dir }}"
state: directory
+ when: nodes_needing_certs | length > 0
- name: Generate the node client config
command: >
@@ -14,18 +15,17 @@
--signer-cert={{ openshift_master_ca_cert }}
--signer-key={{ openshift_master_ca_key }}
--signer-serial={{ openshift_master_ca_serial }}
- --user=system:node-{{ item.openshift.common.hostname }}
+ --user=system:node:{{ item.openshift.common.hostname }}
args:
chdir: "{{ openshift_generated_configs_dir }}"
creates: "{{ openshift_generated_configs_dir }}/node-{{ item.openshift.common.hostname }}"
with_items: nodes_needing_certs
- name: Generate the node server certificate
- delegate_to: "{{ openshift_first_master }}"
command: >
{{ openshift.common.admin_binary }} create-server-cert
--cert=server.crt --key=server.key --overwrite=true
- --hostnames={{ [item.openshift.common.hostname, item.openshift.common.public_hostname]|unique|join(",") }}
+ --hostnames={{ item.openshift.common.all_hostnames |join(",") }}
--signer-cert={{ openshift_master_ca_cert }}
--signer-key={{ openshift_master_ca_key }}
--signer-serial={{ openshift_master_ca_serial }}
@@ -33,18 +33,3 @@
chdir: "{{ openshift_generated_configs_dir }}/node-{{ item.openshift.common.hostname }}"
creates: "{{ openshift_generated_configs_dir }}/node-{{ item.openshift.common.hostname }}/server.crt"
with_items: nodes_needing_certs
-
-- name: Register unregistered nodes
- kubernetes_register_node:
- kubectl_cmd: "{{ [openshift.common.client_binary] }}"
- default_client_config: '~/.config/openshift/.config'
- name: "{{ item.openshift.common.hostname }}"
- api_version: "{{ openshift_kube_api_version }}"
- cpu: "{{ item.openshift.node.resources_cpu | default(None) }}"
- memory: "{{ item.openshift.node.resources_memory | default(None) }}"
- pod_cidr: "{{ item.openshift.node.pod_cidr | default(None) }}"
- host_ip: "{{ item.openshift.common.ip }}"
- labels: "{{ item.openshift.node.labels | default({}) }}"
- annotations: "{{ item.openshift.node.annotations | default({}) }}"
- with_items: openshift_nodes
- register: register_result
diff --git a/roles/openshift_node_certificates/vars/main.yml b/roles/openshift_node_certificates/vars/main.yml
new file mode 100644
index 000000000..61fbb1e51
--- /dev/null
+++ b/roles/openshift_node_certificates/vars/main.yml
@@ -0,0 +1,7 @@
+---
+openshift_node_config_dir: "{{ openshift.common.config_base }}/node"
+openshift_master_config_dir: "{{ openshift.common.config_base }}/master"
+openshift_generated_configs_dir: "{{ openshift.common.config_base }}/generated-configs"
+openshift_master_ca_cert: "{{ openshift_master_config_dir }}/ca.crt"
+openshift_master_ca_key: "{{ openshift_master_config_dir }}/ca.key"
+openshift_master_ca_serial: "{{ openshift_master_config_dir }}/ca.serial.txt"
diff --git a/roles/openshift_register_nodes/library/kubernetes_register_node.py b/roles/openshift_register_nodes/library/kubernetes_register_node.py
deleted file mode 100755
index a8c38627b..000000000
--- a/roles/openshift_register_nodes/library/kubernetes_register_node.py
+++ /dev/null
@@ -1,513 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-# vim: expandtab:tabstop=4:shiftwidth=4
-#
-# disable pylint checks
-# permanently disabled unless someone wants to refactor the object model:
-# too-few-public-methods
-# no-self-use
-# too-many-arguments
-# too-many-locals
-# too-many-branches
-# pylint:disable=too-many-arguments, no-self-use
-# pylint:disable=too-many-locals, too-many-branches, too-few-public-methods
-"""Ansible module to register a kubernetes node to the cluster"""
-
-import os
-
-DOCUMENTATION = '''
----
-module: kubernetes_register_node
-short_description: Registers a kubernetes node with a master
-description:
- - Registers a kubernetes node with a master
-options:
- name:
- default: null
- description:
- - Identifier for this node (usually the node fqdn).
- required: true
- api_verison:
- choices: ['v1beta1', 'v1beta3']
- default: 'v1beta1'
- description:
- - Kubernetes API version to use
- required: true
- host_ip:
- default: null
- description:
- - IP Address to associate with the node when registering.
- Available in the following API versions: v1beta1.
- required: false
- cpu:
- default: null
- description:
- - Number of CPUs to allocate for this node. When using the v1beta1
- API, you must specify the CPU count as a floating point number
- with no more than 3 decimal places. API version v1beta3 and newer
- accepts arbitrary float values.
- required: false
- memory:
- default: null
- description:
- - Memory available for this node. When using the v1beta1 API, you
- must specify the memory size in bytes. API version v1beta3 and
- newer accepts binary SI and decimal SI values.
- required: false
-'''
-EXAMPLES = '''
-# Minimal node registration
-- openshift_register_node: name=ose3.node.example.com
-
-# Node registration using the v1beta1 API and assigning 1 CPU core and 10 GB of
-# Memory
-- openshift_register_node:
- name: ose3.node.example.com
- api_version: v1beta1
- hostIP: 192.168.1.1
- cpu: 1
- memory: 500000000
-'''
-
-
-class ClientConfigException(Exception):
- """Client Configuration Exception"""
- pass
-
-class ClientConfig(object):
- """ Representation of a client config
-
- Attributes:
- config (dict): dictionary representing the client configuration
-
- Args:
- client_opts (list of str): client options to use
- module (AnsibleModule):
-
- Raises:
- ClientConfigException:
- """
- def __init__(self, client_opts, module):
- kubectl = module.params['kubectl_cmd']
- _, output, _ = module.run_command((kubectl +
- ["config", "view", "-o", "json"] +
- client_opts), check_rc=True)
- self.config = json.loads(output)
-
- if not (bool(self.config['clusters']) or
- bool(self.config['contexts']) or
- bool(self.config['current-context']) or
- bool(self.config['users'])):
- raise ClientConfigException(
- "Client config missing required values: %s" % output
- )
-
- def current_context(self):
- """ Gets the current context for the client config
-
- Returns:
- str: The current context as set in the config
- """
- return self.config['current-context']
-
- def section_has_value(self, section_name, value):
- """ Test if specified section contains a value
-
- Args:
- section_name (str): config section to test
- value (str): value to test if present
- Returns:
- bool: True if successful, false otherwise
- """
- section = self.config[section_name]
- if isinstance(section, dict):
- return value in section
- else:
- val = next((item for item in section
- if item['name'] == value), None)
- return val is not None
-
- def has_context(self, context):
- """ Test if specified context exists in config
-
- Args:
- context (str): value to test if present
- Returns:
- bool: True if successful, false otherwise
- """
- return self.section_has_value('contexts', context)
-
- def has_user(self, user):
- """ Test if specified user exists in config
-
- Args:
- context (str): value to test if present
- Returns:
- bool: True if successful, false otherwise
- """
- return self.section_has_value('users', user)
-
- def has_cluster(self, cluster):
- """ Test if specified cluster exists in config
-
- Args:
- context (str): value to test if present
- Returns:
- bool: True if successful, false otherwise
- """
- return self.section_has_value('clusters', cluster)
-
- def get_value_for_context(self, context, attribute):
- """ Get the value of attribute in context
-
- Args:
- context (str): context to search
- attribute (str): attribute wanted
- Returns:
- str: The value for attribute in context
- """
- contexts = self.config['contexts']
- if isinstance(contexts, dict):
- return contexts[context][attribute]
- else:
- return next((c['context'][attribute] for c in contexts
- if c['name'] == context), None)
-
- def get_user_for_context(self, context):
- """ Get the user attribute in context
-
- Args:
- context (str): context to search
- Returns:
- str: The value for the attribute in context
- """
- return self.get_value_for_context(context, 'user')
-
- def get_cluster_for_context(self, context):
- """ Get the cluster attribute in context
-
- Args:
- context (str): context to search
- Returns:
- str: The value for the attribute in context
- """
- return self.get_value_for_context(context, 'cluster')
-
- def get_namespace_for_context(self, context):
- """ Get the namespace attribute in context
-
- Args:
- context (str): context to search
- Returns:
- str: The value for the attribute in context
- """
- return self.get_value_for_context(context, 'namespace')
-
-class Util(object):
- """Utility methods"""
- @staticmethod
- def remove_empty_elements(mapping):
- """ Recursively removes empty elements from a dict
-
- Args:
- mapping (dict): dict to remove empty attributes from
- Returns:
- dict: A copy of the dict with empty elements removed
- """
- if isinstance(mapping, dict):
- copy = mapping.copy()
- for key, val in mapping.iteritems():
- if not val:
- del copy[key]
- return copy
- else:
- return mapping
-
-class NodeResources(object):
- """ Kubernetes Node Resources
-
- Attributes:
- resources (dict): A dictionary representing the node resources
-
- Args:
- version (str): kubernetes api version
- cpu (str): string representation of the cpu resources for the node
- memory (str): string representation of the memory resources for the
- node
- """
- def __init__(self, version, cpu=None, memory=None):
- if version == 'v1beta1':
- self.resources = dict(capacity=dict())
- self.resources['capacity']['cpu'] = cpu
- self.resources['capacity']['memory'] = memory
-
- def get_resources(self):
- """ Get the dict representing the node resources
-
- Returns:
- dict: representation of the node resources with any empty
- elements removed
- """
- return Util.remove_empty_elements(self.resources)
-
-class NodeSpec(object):
- """ Kubernetes Node Spec
-
- Attributes:
- spec (dict): A dictionary representing the node resources
-
- Args:
- version (str): kubernetes api version
- cpu (str): string representation of the cpu resources for the node
- memory (str): string representation of the memory resources for the
- node
- cidr (str): string representation of the cidr block available for
- the node
- externalID (str): The external id of the node
- """
- def __init__(self, version, cpu=None, memory=None, cidr=None,
- externalID=None):
- if version == 'v1beta3':
- self.spec = dict(podCIDR=cidr, externalID=externalID,
- capacity=dict())
- self.spec['capacity']['cpu'] = cpu
- self.spec['capacity']['memory'] = memory
-
- def get_spec(self):
- """ Get the dict representing the node spec
-
- Returns:
- dict: representation of the node spec with any empty elements
- removed
- """
- return Util.remove_empty_elements(self.spec)
-
-class Node(object):
- """ Kubernetes Node
-
- Attributes:
- node (dict): A dictionary representing the node
-
- Args:
- module (AnsibleModule):
- client_opts (list): client connection options
- version (str, optional): kubernetes api version
- node_name (str, optional): name for node
- hostIP (str, optional): node host ip
- cpu (str, optional): cpu resources for the node
- memory (str, optional): memory resources for the node
- labels (list, optional): labels for the node
- annotations (list, optional): annotations for the node
- podCIDR (list, optional): cidr block to use for pods
- externalID (str, optional): external id of the node
- """
- def __init__(self, module, client_opts, version='v1beta1', node_name=None,
- hostIP=None, cpu=None, memory=None, labels=None,
- annotations=None, podCIDR=None, externalID=None):
- self.module = module
- self.client_opts = client_opts
- if version == 'v1beta1':
- self.node = dict(id=node_name,
- kind='Node',
- apiVersion=version,
- hostIP=hostIP,
- resources=NodeResources(version, cpu, memory),
- cidr=podCIDR,
- labels=labels,
- annotations=annotations,
- externalID=externalID)
- elif version == 'v1beta3':
- metadata = dict(name=node_name,
- labels=labels,
- annotations=annotations)
- self.node = dict(kind='Node',
- apiVersion=version,
- metadata=metadata,
- spec=NodeSpec(version, cpu, memory, podCIDR,
- externalID))
-
- def get_name(self):
- """ Get the name for the node
-
- Returns:
- str: node name
- """
- if self.node['apiVersion'] == 'v1beta1':
- return self.node['id']
- elif self.node['apiVersion'] == 'v1beta3':
- return self.node['metadata']['name']
-
- def get_node(self):
- """ Get the dict representing the node
-
- Returns:
- dict: representation of the node with any empty elements
- removed
- """
- node = self.node.copy()
- if self.node['apiVersion'] == 'v1beta1':
- node['resources'] = self.node['resources'].get_resources()
- elif self.node['apiVersion'] == 'v1beta3':
- node['spec'] = self.node['spec'].get_spec()
- return Util.remove_empty_elements(node)
-
- def exists(self):
- """ Tests if the node already exists
-
- Returns:
- bool: True if node exists, otherwise False
- """
- kubectl = self.module.params['kubectl_cmd']
- _, output, _ = self.module.run_command((kubectl + ["get", "nodes"] +
- self.client_opts),
- check_rc=True)
- if re.search(self.module.params['name'], output, re.MULTILINE):
- return True
- return False
-
- def create(self):
- """ Creates the node
-
- Returns:
- bool: True if node creation successful
- """
- kubectl = self.module.params['kubectl_cmd']
- cmd = kubectl + self.client_opts + ['create', '-f', '-']
- exit_code, output, error = self.module.run_command(
- cmd, data=self.module.jsonify(self.get_node())
- )
- if exit_code != 0:
- if re.search("minion \"%s\" already exists" % self.get_name(),
- error):
- self.module.exit_json(msg="node definition already exists",
- changed=False, node=self.get_node())
- else:
- self.module.fail_json(msg="Node creation failed.",
- exit_code=exit_code,
- output=output, error=error,
- node=self.get_node())
- else:
- return True
-
-def generate_client_opts(module):
- """ Generates the client options
-
- Args:
- module(AnsibleModule)
-
- Returns:
- str: client options
- """
- client_config = '~/.kube/.kubeconfig'
- if 'default_client_config' in module.params:
- client_config = module.params['default_client_config']
- user_has_client_config = os.path.exists(os.path.expanduser(client_config))
- if not (user_has_client_config or module.params['client_config']):
- module.fail_json(msg="Could not locate client configuration, "
- "client_config must be specified if "
- "~/.kube/.kubeconfig is not present")
-
- client_opts = []
- if module.params['client_config']:
- kubeconfig_flag = '--kubeconfig'
- if 'kubeconfig_flag' in module.params:
- kubeconfig_flag = module.params['kubeconfig_flag']
- client_opts.append(kubeconfig_flag + '=' + os.path.expanduser(module.params['client_config']))
-
- try:
- config = ClientConfig(client_opts, module)
- except ClientConfigException as ex:
- module.fail_json(msg="Failed to get client configuration",
- exception=str(ex))
-
- client_context = module.params['client_context']
- if config.has_context(client_context):
- if client_context != config.current_context():
- client_opts.append("--context=%s" % client_context)
- else:
- module.fail_json(msg="Context %s not found in client config" % client_context)
-
- client_user = module.params['client_user']
- if config.has_user(client_user):
- if client_user != config.get_user_for_context(client_context):
- client_opts.append("--user=%s" % client_user)
- else:
- module.fail_json(msg="User %s not found in client config" % client_user)
-
- client_cluster = module.params['client_cluster']
- if config.has_cluster(client_cluster):
- if client_cluster != config.get_cluster_for_context(client_context):
- client_opts.append("--cluster=%s" % client_cluster)
- else:
- module.fail_json(msg="Cluster %s not found in client config" % client_cluster)
-
- client_namespace = module.params['client_namespace']
- if client_namespace != config.get_namespace_for_context(client_context):
- client_opts.append("--namespace=%s" % client_namespace)
-
- return client_opts
-
-
-def main():
- """ main """
- module = AnsibleModule(
- argument_spec=dict(
- name=dict(required=True, type='str'),
- host_ip=dict(type='str'),
- api_version=dict(type='str', default='v1beta1',
- choices=['v1beta1', 'v1beta3']),
- cpu=dict(type='str'),
- memory=dict(type='str'),
- # TODO: needs documented
- labels=dict(type='dict', default={}),
- # TODO: needs documented
- annotations=dict(type='dict', default={}),
- # TODO: needs documented
- pod_cidr=dict(type='str'),
- # TODO: needs documented
- client_config=dict(type='str'),
- # TODO: needs documented
- client_cluster=dict(type='str', default='master'),
- # TODO: needs documented
- client_context=dict(type='str', default='default'),
- # TODO: needs documented
- client_namespace=dict(type='str', default='default'),
- # TODO: needs documented
- client_user=dict(type='str', default='system:admin'),
- # TODO: needs documented
- kubectl_cmd=dict(type='list', default=['kubectl']),
- # TODO: needs documented
- kubeconfig_flag=dict(type='str'),
- # TODO: needs documented
- default_client_config=dict(type='str')
- ),
- supports_check_mode=True
- )
-
- labels = module.params['labels']
- kube_hostname_label = 'kubernetes.io/hostname'
- if kube_hostname_label not in labels:
- labels[kube_hostname_label] = module.params['name']
-
- node = Node(module, generate_client_opts(module),
- module.params['api_version'], module.params['name'],
- module.params['host_ip'], module.params['cpu'],
- module.params['memory'], labels, module.params['annotations'],
- module.params['pod_cidr'])
-
- if node.exists():
- module.exit_json(changed=False, node=node.get_node())
- elif module.check_mode:
- module.exit_json(changed=True, node=node.get_node())
- elif node.create():
- module.exit_json(changed=True, msg="Node created successfully",
- node=node.get_node())
- else:
- module.fail_json(msg="Unknown error creating node", node=node.get_node())
-
-# ignore pylint errors related to the module_utils import
-# pylint: disable=redefined-builtin, unused-wildcard-import, wildcard-import
-# import module snippets
-from ansible.module_utils.basic import *
-if __name__ == '__main__':
- main()
diff --git a/roles/openshift_registry/README.md b/roles/openshift_registry/README.md
index 202c818b8..8e66c483b 100644
--- a/roles/openshift_registry/README.md
+++ b/roles/openshift_registry/README.md
@@ -12,14 +12,16 @@ Role Variables
--------------
From this role:
+
| Name | Default value | |
|--------------------|-------------------------------------------------------|---------------------|
| | | |
From openshift_common:
+
| Name | Default value | |
|-----------------------|---------------|--------------------------------------|
-| openshift_debug_level | 0 | Global openshift debug log verbosity |
+| openshift_debug_level | 2 | Global openshift debug log verbosity |
Dependencies
@@ -39,4 +41,3 @@ Author Information
------------------
Red Hat openshift@redhat.com
-
diff --git a/roles/openshift_registry/tasks/main.yml b/roles/openshift_registry/tasks/main.yml
index 29387d7d5..749eea5c0 100644
--- a/roles/openshift_registry/tasks/main.yml
+++ b/roles/openshift_registry/tasks/main.yml
@@ -1,11 +1,14 @@
---
-- set_fact: _oreg_images="--images={{ oreg_url|quote }}"
- when: oreg_url is defined
+# This role is unused until we add options for configuring the backend storage
+
+- set_fact: _oreg_images="--images='{{ openshift.master.registry_url }}'"
+
+- set_fact: _oreg_selector="--selector='{{ openshift.master.registry_selector }}'"
- name: Deploy OpenShift Registry
command: >
{{ openshift.common.admin_binary }} registry
- --create
- --credentials={{ openshift_master_config_dir }}/openshift-registry.kubeconfig {{ _oreg_images|default() }}
+ --create --service-account=registry {{ _oreg_selector }}
+ --credentials={{ openshift_master_config_dir }}/openshift-registry.kubeconfig {{ _oreg_images }}
register: _oreg_results
changed_when: "'service exists' not in _oreg_results.stdout"
diff --git a/roles/openshift_registry/vars/main.yml b/roles/openshift_registry/vars/main.yml
index 9fb501e85..9967e26f4 100644
--- a/roles/openshift_registry/vars/main.yml
+++ b/roles/openshift_registry/vars/main.yml
@@ -1,3 +1,2 @@
---
-openshift_master_config_dir: /etc/openshift/master
-
+openshift_master_config_dir: "{{ openshift.common.config_base }}/master"
diff --git a/roles/openshift_repos/README.md b/roles/openshift_repos/README.md
index 6bbedd839..95b155b29 100644
--- a/roles/openshift_repos/README.md
+++ b/roles/openshift_repos/README.md
@@ -7,7 +7,7 @@ Requirements
------------
A RHEL 7.1 host pre-configured with access to the rhel-7-server-rpms,
-rhel-7-server-extra-rpms, and rhel-7-server-ose-beta-rpms repos.
+rhel-7-server-extra-rpms, and rhel-7-server-ose-3.0-rpms repos.
Role Variables
--------------
diff --git a/roles/openshift_repos/files/online/repos/enterprise-v3.repo b/roles/openshift_repos/files/online/repos/enterprise-v3.repo
index 69c480f0a..92bd35834 100644
--- a/roles/openshift_repos/files/online/repos/enterprise-v3.repo
+++ b/roles/openshift_repos/files/online/repos/enterprise-v3.repo
@@ -1,7 +1,7 @@
[enterprise-v3]
-name=OpenShift Enterprise Beta4
-baseurl=https://mirror.ops.rhcloud.com/libra/libra-7-ose-beta4/
- https://gce-mirror1.ops.rhcloud.com/libra/libra-7-ose-beta4/
+name=OpenShift Enterprise
+baseurl=https://mirror.ops.rhcloud.com/libra/rhui-rhel-server-7-ose/
+ https://gce-mirror1.ops.rhcloud.com/libra/rhui-rhel-server-7-ose/
enabled=1
gpgcheck=0
failovermethod=priority
diff --git a/roles/openshift_repos/vars/main.yml b/roles/openshift_repos/vars/main.yml
index bbb4c77e7..319611a0b 100644
--- a/roles/openshift_repos/vars/main.yml
+++ b/roles/openshift_repos/vars/main.yml
@@ -1,2 +1,7 @@
---
-known_openshift_deployment_types: ['origin', 'online', 'enterprise']
+# origin uses community packages named 'origin'
+# online currently uses 'openshift' packages
+# enterprise is used for OSE 3.0 < 3.1 which uses packages named 'openshift'
+# atomic-enterprise uses Red Hat packages named 'atomic-openshift'
+# openshift-enterprise uses Red Hat packages named 'atomic-openshift' starting with OSE 3.1
+known_openshift_deployment_types: ['origin', 'online', 'enterprise','atomic-enterprise','openshift-enterprise']
diff --git a/roles/openshift_router/README.md b/roles/openshift_router/README.md
index 6d8ee25c6..836efc443 100644
--- a/roles/openshift_router/README.md
+++ b/roles/openshift_router/README.md
@@ -19,7 +19,7 @@ From this role:
From openshift_common:
| Name | Default value | |
|-----------------------|---------------|--------------------------------------|
-| openshift_debug_level | 0 | Global openshift debug log verbosity |
+| openshift_debug_level | 2 | Global openshift debug log verbosity |
Dependencies
------------
@@ -38,4 +38,3 @@ Author Information
------------------
Red Hat openshift@redhat.com
-
diff --git a/roles/openshift_router/tasks/main.yml b/roles/openshift_router/tasks/main.yml
index 929177262..498a65127 100644
--- a/roles/openshift_router/tasks/main.yml
+++ b/roles/openshift_router/tasks/main.yml
@@ -1,11 +1,14 @@
---
-- set_fact: _ortr_images="--images={{ oreg_url|quote }}"
- when: oreg_url is defined
+
+- set_fact: _ortr_images="--images='{{ openshift.master.registry_url }}'"
+
+- set_fact: _ortr_selector="--selector='{{ openshift.master.router_selector }}'"
- name: Deploy OpenShift Router
command: >
{{ openshift.common.admin_binary }} router
- --create
- --credentials={{ openshift_master_config_dir }}/openshift-router.kubeconfig {{ _ortr_images|default() }}
+ --create --replicas={{ openshift.master.infra_nodes }}
+ --service-account=router {{ _ortr_selector }}
+ --credentials={{ openshift_master_config_dir }}/openshift-router.kubeconfig {{ _ortr_images }}
register: _ortr_results
changed_when: "'service exists' not in _ortr_results.stdout"
diff --git a/roles/openshift_router/vars/main.yml b/roles/openshift_router/vars/main.yml
index 9fb501e85..9967e26f4 100644
--- a/roles/openshift_router/vars/main.yml
+++ b/roles/openshift_router/vars/main.yml
@@ -1,3 +1,2 @@
---
-openshift_master_config_dir: /etc/openshift/master
-
+openshift_master_config_dir: "{{ openshift.common.config_base }}/master"
diff --git a/roles/openshift_serviceaccounts/tasks/main.yml b/roles/openshift_serviceaccounts/tasks/main.yml
new file mode 100644
index 000000000..d93a25a21
--- /dev/null
+++ b/roles/openshift_serviceaccounts/tasks/main.yml
@@ -0,0 +1,26 @@
+- name: Create service account configs
+ template:
+ src: serviceaccount.j2
+ dest: "/tmp/{{ item }}-serviceaccount.yaml"
+ with_items: accounts
+
+- name: Create {{ item }} service account
+ command: >
+ {{ openshift.common.client_binary }} create -f "/tmp/{{ item }}-serviceaccount.yaml"
+ with_items: accounts
+ register: _sa_result
+ failed_when: "'serviceaccounts \"{{ item }}\" already exists' not in _sa_result.stderr and _sa_result.rc != 0"
+ changed_when: "'serviceaccounts \"{{ item }}\" already exists' not in _sa_result.stderr and _sa_result.rc == 0"
+
+- name: Get current security context constraints
+ shell: "{{ openshift.common.client_binary }} get scc privileged -o yaml > /tmp/scc.yaml"
+
+- name: Add security context constraint for {{ item }}
+ lineinfile:
+ dest: /tmp/scc.yaml
+ line: "- system:serviceaccount:default:{{ item }}"
+ insertafter: "^users:$"
+ with_items: accounts
+
+- name: Apply new scc rules for service accounts
+ command: "{{ openshift.common.client_binary }} update -f /tmp/scc.yaml"
diff --git a/roles/openshift_serviceaccounts/templates/serviceaccount.j2 b/roles/openshift_serviceaccounts/templates/serviceaccount.j2
new file mode 100644
index 000000000..931e249f9
--- /dev/null
+++ b/roles/openshift_serviceaccounts/templates/serviceaccount.j2
@@ -0,0 +1,4 @@
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+ name: {{ item }}
diff --git a/roles/openshift_storage_nfs_lvm/README.md b/roles/openshift_storage_nfs_lvm/README.md
new file mode 100644
index 000000000..1ee02e18a
--- /dev/null
+++ b/roles/openshift_storage_nfs_lvm/README.md
@@ -0,0 +1,108 @@
+# openshift_storage_nfs_lvm
+
+This role is useful to create and export nfs disks for openshift persistent volumes.
+It does so by creating lvm partitions on an already setup pv/vg, creating xfs
+filesystem on each partition, mounting the partitions, exporting the mounts via NFS
+and creating a json file for each mount that an openshift master can use to
+create persistent volumes.
+
+## Requirements
+
+* NFS server with NFS, iptables, and everything setup.
+
+* A lvm volume group created on the nfs server (default: openshiftvg)
+
+* The lvm volume needs to have as much free space as you are allocating
+
+## Role Variables
+
+```
+# Options of NFS exports.
+osnl_nfs_export_options: "*(rw,sync,all_squash)"
+
+# Directory, where the created partitions should be mounted. They will be
+# mounted as <osnl_mount_dir>/<lvm volume name>
+osnl_mount_dir: /exports/openshift
+
+# Volume Group to use.
+# This role always assumes that there is enough free space on the volume
+# group for all the partitions you will be making
+osnl_volume_group: openshiftvg
+
+# volume names
+# volume names are {{osnl_volume_prefix}}{{osnl_volume_size}}g{{volume number}}
+# example: stg5g0004
+
+# osnl_volume_prefix
+# Useful if you are using the nfs server for more than one cluster
+osnl_volume_prefix: "stg"
+
+# osnl_volume_size
+# Size of the volumes/partitions in Gigabytes.
+osnl_volume_size: 5
+
+# osnl_volume_num_start
+# Where to start the volume number numbering.
+osnl_volume_num_start: 3
+
+# osnl_number_of_volumes
+# How many volumes/partitions to build, with the size we stated.
+osnl_number_of_volumes: 2
+
+```
+
+## Dependencies
+
+None
+
+## Example Playbook
+
+With this playbook, 2 5Gig lvm partitions are created, named stg5g0003 and stg5g0004
+Both of them are mounted into `/exports/openshift` directory. Both directories are
+exported via NFS. json files are created in /root.
+
+ - hosts: nfsservers
+ sudo: no
+ remote_user: root
+ gather_facts: no
+ roles:
+ - role: openshift_storage_nfs_lvm
+ osnl_mount_dir: /exports/openshift
+ osnl_volume_prefix: "stg"
+ osnl_volume_size: 5
+ osnl_volume_num_start: 3
+ osnl_number_of_volumes: 2
+
+
+## Full example
+
+
+* Create an `inventory` file:
+ ```
+ [nfsservers]
+ 10.0.0.1
+ 10.0.0.2
+ ```
+
+* Create an ansible playbook, say `setupnfs.yaml`:
+ ```
+ - hosts: nfsservers
+ sudo: no
+ remote_user: root
+ gather_facts: no
+ roles:
+ - role: openshift_storage_nfs_lvm
+ osnl_mount_dir: /exports/stg
+ osnl_volume_prefix: "stg"
+ osnl_volume_size: 5
+ osnl_volume_num_start: 3
+ osnl_number_of_volumes: 2
+
+* Run the playbook:
+ ```
+ ansible-playbook -i inventory setupnfs.yml
+ ```
+
+## License
+
+Apache 2.0
diff --git a/roles/openshift_storage_nfs_lvm/defaults/main.yml b/roles/openshift_storage_nfs_lvm/defaults/main.yml
new file mode 100644
index 000000000..f81cdc724
--- /dev/null
+++ b/roles/openshift_storage_nfs_lvm/defaults/main.yml
@@ -0,0 +1,10 @@
+---
+# Options of NFS exports.
+osnl_nfs_export_options: "*(rw,sync,all_squash)"
+
+# Directory, where the created partitions should be mounted. They will be
+# mounted as <osnl_mount_dir>/test1g0001 etc.
+osnl_mount_dir: /exports/openshift
+
+# Volume Group to use.
+osnl_volume_group: openshiftvg
diff --git a/roles/openshift_storage_nfs_lvm/handlers/main.yml b/roles/openshift_storage_nfs_lvm/handlers/main.yml
new file mode 100644
index 000000000..52f3ceffe
--- /dev/null
+++ b/roles/openshift_storage_nfs_lvm/handlers/main.yml
@@ -0,0 +1,3 @@
+---
+- name: restart nfs
+ service: name=nfs-server state=restarted
diff --git a/roles/openshift_storage_nfs_lvm/meta/main.yml b/roles/openshift_storage_nfs_lvm/meta/main.yml
new file mode 100644
index 000000000..44fee47ff
--- /dev/null
+++ b/roles/openshift_storage_nfs_lvm/meta/main.yml
@@ -0,0 +1,16 @@
+---
+galaxy_info:
+ author: Jan Safranek, Troy Dawson
+ description: Create LVM volumes and use them as openshift persistent volumes.
+ company: Red Hat, Inc.
+ license: license (Apache)
+ min_ansible_version: 1.4
+ platforms:
+ - name: EL
+ versions:
+ - 7
+ - name: Fedora
+ versions:
+ - all
+ categories:
+ - openshift
diff --git a/roles/openshift_storage_nfs_lvm/tasks/main.yml b/roles/openshift_storage_nfs_lvm/tasks/main.yml
new file mode 100644
index 000000000..ead81b876
--- /dev/null
+++ b/roles/openshift_storage_nfs_lvm/tasks/main.yml
@@ -0,0 +1,24 @@
+---
+- name: Create lvm volumes
+ lvol: vg={{osnl_volume_group}} lv={{ item }} size={{osnl_volume_size}}G
+ with_sequence: start={{osnl_volume_num_start}} count={{osnl_number_of_volumes}} format={{osnl_volume_prefix}}{{osnl_volume_size}}g%04d
+
+- name: create filesystem
+ filesystem: fstype=xfs dev=/dev/{{osnl_volume_group}}/{{ item }}
+ with_sequence: start={{osnl_volume_num_start}} count={{osnl_number_of_volumes}} format={{osnl_volume_prefix}}{{osnl_volume_size}}g%04d
+
+- name: mount volumes
+ mount: name={{osnl_mount_dir}}/{{ item }} src=/dev/{{osnl_volume_group}}/{{ item }} state=mounted fstype=xfs passno=0
+ with_sequence: start={{osnl_volume_num_start}} count={{osnl_number_of_volumes}} format={{osnl_volume_prefix}}{{osnl_volume_size}}g%04d
+
+- name: Make mounts owned by nfsnobody
+ file: path={{osnl_mount_dir}}/{{ item }} owner=nfsnobody group=nfsnobody mode=0700
+ with_sequence: start={{osnl_volume_num_start}} count={{osnl_number_of_volumes}} format={{osnl_volume_prefix}}{{osnl_volume_size}}g%04d
+
+- include: nfs.yml
+
+- name: Create volume json file
+ template: src=../templates/nfs.json.j2 dest=/root/persistent-volume.{{ item }}.json
+ with_sequence: start={{osnl_volume_num_start}} count={{osnl_number_of_volumes}} format={{osnl_volume_prefix}}{{osnl_volume_size}}g%04d
+
+# TODO - Get the json files to a master, and load them.
diff --git a/roles/openshift_storage_nfs_lvm/tasks/nfs.yml b/roles/openshift_storage_nfs_lvm/tasks/nfs.yml
new file mode 100644
index 000000000..65ae069df
--- /dev/null
+++ b/roles/openshift_storage_nfs_lvm/tasks/nfs.yml
@@ -0,0 +1,16 @@
+---
+- name: Install NFS server
+ yum: name=nfs-utils state=present
+
+- name: Start rpcbind
+ service: name=rpcbind state=started enabled=yes
+
+- name: Start nfs
+ service: name=nfs-server state=started enabled=yes
+
+- name: Export the directories
+ lineinfile: dest=/etc/exports
+ regexp="^{{ osnl_mount_dir }}/{{ item }} "
+ line="{{ osnl_mount_dir }}/{{ item }} {{osnl_nfs_export_options}}"
+ with_sequence: start={{osnl_volume_num_start}} count={{osnl_number_of_volumes}} format={{osnl_volume_prefix}}{{osnl_volume_size}}g%04d
+ notify: restart nfs
diff --git a/roles/openshift_storage_nfs_lvm/templates/nfs.json.j2 b/roles/openshift_storage_nfs_lvm/templates/nfs.json.j2
new file mode 100644
index 000000000..0f3d84e75
--- /dev/null
+++ b/roles/openshift_storage_nfs_lvm/templates/nfs.json.j2
@@ -0,0 +1,21 @@
+{
+ "apiVersion": "v1",
+ "kind": "PersistentVolume",
+ "metadata": {
+ "name": "pv-{{ inventory_hostname | regex_replace("\.", "-") }}-{{ item }}",
+ "labels": {
+ "type": "nfs"
+ }
+ },
+ "spec": {
+ "capacity": {
+ "storage": "{{ osnl_volume_size }}Gi"
+ },
+ "accessModes": [ "ReadWriteMany" ],
+ "persistentVolumeReclaimPolicy": "Recycle",
+ "nfs": {
+ "Server": "{{ inventory_hostname }}",
+ "Path": "{{ osnl_mount_dir }}/{{ item }}"
+ }
+ }
+}
diff --git a/roles/os_zabbix/README.md b/roles/os_zabbix/README.md
new file mode 100644
index 000000000..ac3dc2833
--- /dev/null
+++ b/roles/os_zabbix/README.md
@@ -0,0 +1,40 @@
+os_zabbix
+=========
+
+Automate zabbix tasks.
+
+Requirements
+------------
+
+This requires the openshift_tools rpm be installed for the zbxapi.py library. It can be found here: https://github.com/openshift/openshift-tools under openshift_tools/monitoring/zbxapi.py for now.
+
+Role Variables
+--------------
+
+zab_server
+zab_username
+zab_password
+
+Dependencies
+------------
+
+This depeonds on the zbxapi.py library located here: https://github.com/openshift/openshift-tools under openshift_tools/monitoring/zbxapi.py for now.
+
+Example Playbook
+----------------
+
+ - zbx_host:
+ server: zab_server
+ user: zab_user
+ password: zab_password
+ name: 'myhost'
+
+License
+-------
+
+ASL 2.0
+
+Author Information
+------------------
+
+OpenShift operations, Red Hat, Inc
diff --git a/roles/os_zabbix/defaults/main.yml b/roles/os_zabbix/defaults/main.yml
new file mode 100644
index 000000000..ed97d539c
--- /dev/null
+++ b/roles/os_zabbix/defaults/main.yml
@@ -0,0 +1 @@
+---
diff --git a/roles/os_zabbix/handlers/main.yml b/roles/os_zabbix/handlers/main.yml
new file mode 100644
index 000000000..ed97d539c
--- /dev/null
+++ b/roles/os_zabbix/handlers/main.yml
@@ -0,0 +1 @@
+---
diff --git a/roles/os_zabbix/library/zbxapi.py b/roles/os_zabbix/library/zbxapi.py
deleted file mode 100755
index b5fa5ee2b..000000000
--- a/roles/os_zabbix/library/zbxapi.py
+++ /dev/null
@@ -1,370 +0,0 @@
-#!/usr/bin/env python
-# vim: expandtab:tabstop=4:shiftwidth=4
-'''
- ZabbixAPI ansible module
-'''
-
-# Copyright 2015 Red Hat Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-# Purpose: An ansible module to communicate with zabbix.
-#
-
-# pylint: disable=line-too-long
-# Disabling line length for readability
-
-import json
-import httplib2
-import sys
-import os
-import re
-import copy
-
-class ZabbixAPIError(Exception):
- '''
- ZabbixAPIError
- Exists to propagate errors up from the api
- '''
- pass
-
-class ZabbixAPI(object):
- '''
- ZabbixAPI class
- '''
- classes = {
- 'Action': ['create', 'delete', 'get', 'update'],
- 'Alert': ['get'],
- 'Application': ['create', 'delete', 'get', 'massadd', 'update'],
- 'Configuration': ['export', 'import'],
- 'Dcheck': ['get'],
- 'Dhost': ['get'],
- 'Drule': ['copy', 'create', 'delete', 'get', 'isreadable', 'iswritable', 'update'],
- 'Dservice': ['get'],
- 'Event': ['acknowledge', 'get'],
- 'Graph': ['create', 'delete', 'get', 'update'],
- 'Graphitem': ['get'],
- 'Graphprototype': ['create', 'delete', 'get', 'update'],
- 'History': ['get'],
- 'Hostgroup': ['create', 'delete', 'get', 'isreadable', 'iswritable', 'massadd', 'massremove', 'massupdate', 'update'],
- 'Hostinterface': ['create', 'delete', 'get', 'massadd', 'massremove', 'replacehostinterfaces', 'update'],
- 'Host': ['create', 'delete', 'get', 'isreadable', 'iswritable', 'massadd', 'massremove', 'massupdate', 'update'],
- 'Hostprototype': ['create', 'delete', 'get', 'isreadable', 'iswritable', 'update'],
- 'Httptest': ['create', 'delete', 'get', 'isreadable', 'iswritable', 'update'],
- 'Iconmap': ['create', 'delete', 'get', 'isreadable', 'iswritable', 'update'],
- 'Image': ['create', 'delete', 'get', 'update'],
- 'Item': ['create', 'delete', 'get', 'isreadable', 'iswritable', 'update'],
- 'Itemprototype': ['create', 'delete', 'get', 'isreadable', 'iswritable', 'update'],
- 'Maintenance': ['create', 'delete', 'get', 'update'],
- 'Map': ['create', 'delete', 'get', 'isreadable', 'iswritable', 'update'],
- 'Mediatype': ['create', 'delete', 'get', 'update'],
- 'Proxy': ['create', 'delete', 'get', 'isreadable', 'iswritable', 'update'],
- 'Screen': ['create', 'delete', 'get', 'update'],
- 'Screenitem': ['create', 'delete', 'get', 'isreadable', 'iswritable', 'update', 'updatebyposition'],
- 'Script': ['create', 'delete', 'execute', 'get', 'getscriptsbyhosts', 'update'],
- 'Service': ['adddependencies', 'addtimes', 'create', 'delete', 'deletedependencies', 'deletetimes', 'get', 'getsla', 'isreadable', 'iswritable', 'update'],
- 'Template': ['create', 'delete', 'get', 'isreadable', 'iswritable', 'massadd', 'massremove', 'massupdate', 'update'],
- 'Templatescreen': ['copy', 'create', 'delete', 'get', 'isreadable', 'iswritable', 'update'],
- 'Templatescreenitem': ['get'],
- 'Trigger': ['adddependencies', 'create', 'delete', 'deletedependencies', 'get', 'isreadable', 'iswritable', 'update'],
- 'Triggerprototype': ['create', 'delete', 'get', 'update'],
- 'User': ['addmedia', 'create', 'delete', 'deletemedia', 'get', 'isreadable', 'iswritable', 'login', 'logout', 'update', 'updatemedia', 'updateprofile'],
- 'Usergroup': ['create', 'delete', 'get', 'isreadable', 'iswritable', 'massadd', 'massupdate', 'update'],
- 'Usermacro': ['create', 'createglobal', 'delete', 'deleteglobal', 'get', 'update', 'updateglobal'],
- 'Usermedia': ['get'],
- }
-
- def __init__(self, data=None):
- if not data:
- data = {}
- self.server = data.get('server', None)
- self.username = data.get('user', None)
- self.password = data.get('password', None)
- if any([value == None for value in [self.server, self.username, self.password]]):
- print 'Please specify zabbix server url, username, and password.'
- sys.exit(1)
-
- self.verbose = data.get('verbose', False)
- self.use_ssl = data.has_key('use_ssl')
- self.auth = None
-
- for cname, _ in self.classes.items():
- setattr(self, cname.lower(), getattr(self, cname)(self))
-
- # pylint: disable=no-member
- # This method does not exist until the metaprogramming executed
- # This is permanently disabled.
- results = self.user.login(user=self.username, password=self.password)
-
- if results[0]['status'] == '200':
- if results[1].has_key('result'):
- self.auth = results[1]['result']
- elif results[1].has_key('error'):
- print "Unable to authenticate with zabbix server. {0} ".format(results[1]['error'])
- sys.exit(1)
- else:
- print "Error in call to zabbix. Http status: {0}.".format(results[0]['status'])
- sys.exit(1)
-
- def perform(self, method, rpc_params):
- '''
- This method calls your zabbix server.
-
- It requires the following parameters in order for a proper request to be processed:
- jsonrpc - the version of the JSON-RPC protocol used by the API;
- the Zabbix API implements JSON-RPC version 2.0;
- method - the API method being called;
- rpc_params - parameters that will be passed to the API method;
- id - an arbitrary identifier of the request;
- auth - a user authentication token; since we don't have one yet, it's set to null.
- '''
- http_method = "POST"
- jsonrpc = "2.0"
- rid = 1
-
- http = None
- if self.use_ssl:
- http = httplib2.Http()
- else:
- http = httplib2.Http(disable_ssl_certificate_validation=True,)
-
- headers = {}
- headers["Content-type"] = "application/json"
-
- body = {
- "jsonrpc": jsonrpc,
- "method": method,
- "params": rpc_params.get('params', {}),
- "id": rid,
- 'auth': self.auth,
- }
-
- if method in ['user.login', 'api.version']:
- del body['auth']
-
- body = json.dumps(body)
-
- if self.verbose:
- print body
- print method
- print headers
- httplib2.debuglevel = 1
-
- response, content = http.request(self.server, http_method, body, headers)
-
- if response['status'] not in ['200', '201']:
- raise ZabbixAPIError('Error calling zabbix. Zabbix returned %s' % response['status'])
-
- if self.verbose:
- print response
- print content
-
- try:
- content = json.loads(content)
- except ValueError as err:
- content = {"error": err.message}
-
- return response, content
-
- @staticmethod
- def meta(cname, method_names):
- '''
- This bit of metaprogramming is where the ZabbixAPI subclasses are created.
- For each of ZabbixAPI.classes we create a class from the key and methods
- from the ZabbixAPI.classes values. We pass a reference to ZabbixAPI class
- to each subclass in order for each to be able to call the perform method.
- '''
- def meta_method(_class, method_name):
- '''
- This meta method allows a class to add methods to it.
- '''
- # This template method is a stub method for each of the subclass
- # methods.
- def template_method(self, params=None, **rpc_params):
- '''
- This template method is a stub method for each of the subclass methods.
- '''
- if params:
- rpc_params['params'] = params
- else:
- rpc_params['params'] = copy.deepcopy(rpc_params)
-
- return self.parent.perform(cname.lower()+"."+method_name, rpc_params)
-
- template_method.__doc__ = \
- "https://www.zabbix.com/documentation/2.4/manual/api/reference/%s/%s" % \
- (cname.lower(), method_name)
- template_method.__name__ = method_name
- # this is where the template method is placed inside of the subclass
- # e.g. setattr(User, "create", stub_method)
- setattr(_class, template_method.__name__, template_method)
-
- # This class call instantiates a subclass. e.g. User
- _class = type(cname,
- (object,),
- {'__doc__': \
- "https://www.zabbix.com/documentation/2.4/manual/api/reference/%s" % cname.lower()})
- def __init__(self, parent):
- '''
- This init method gets placed inside of the _class
- to allow it to be instantiated. A reference to the parent class(ZabbixAPI)
- is passed in to allow each class access to the perform method.
- '''
- self.parent = parent
-
- # This attaches the init to the subclass. e.g. Create
- setattr(_class, __init__.__name__, __init__)
- # For each of our ZabbixAPI.classes dict values
- # Create a method and attach it to our subclass.
- # e.g. 'User': ['delete', 'get', 'updatemedia', 'updateprofile',
- # 'update', 'iswritable', 'logout', 'addmedia', 'create',
- # 'login', 'deletemedia', 'isreadable'],
- # User.delete
- # User.get
- for method_name in method_names:
- meta_method(_class, method_name)
- # Return our subclass with all methods attached
- return _class
-
-# Attach all ZabbixAPI.classes to ZabbixAPI class through metaprogramming
-for _class_name, _method_names in ZabbixAPI.classes.items():
- setattr(ZabbixAPI, _class_name, ZabbixAPI.meta(_class_name, _method_names))
-
-def exists(content, key='result'):
- ''' Check if key exists in content or the size of content[key] > 0
- '''
- if not content.has_key(key):
- return False
-
- if not content[key]:
- return False
-
- return True
-
-def diff_content(from_zabbix, from_user):
- ''' Compare passed in object to results returned from zabbix
- '''
- terms = ['search', 'output', 'groups', 'select', 'expand']
- regex = '(' + '|'.join(terms) + ')'
- retval = {}
- for key, value in from_user.items():
- if re.findall(regex, key):
- continue
-
- if from_zabbix[key] != str(value):
- retval[key] = str(value)
-
- return retval
-
-def main():
- '''
- This main method runs the ZabbixAPI Ansible Module
- '''
-
- module = AnsibleModule(
- argument_spec=dict(
- server=dict(default='https://localhost/zabbix/api_jsonrpc.php', type='str'),
- user=dict(default=None, type='str'),
- password=dict(default=None, type='str'),
- zbx_class=dict(choices=ZabbixAPI.classes.keys()),
- params=dict(),
- debug=dict(default=False, type='bool'),
- state=dict(default='present', type='str'),
- ),
- #supports_check_mode=True
- )
-
- user = module.params.get('user', None)
- if not user:
- user = os.environ['ZABBIX_USER']
-
- passwd = module.params.get('password', None)
- if not passwd:
- passwd = os.environ['ZABBIX_PASSWORD']
-
-
-
- api_data = {
- 'user': user,
- 'password': passwd,
- 'server': module.params['server'],
- 'verbose': module.params['debug']
- }
-
- if not user or not passwd or not module.params['server']:
- module.fail_json(msg='Please specify the user, password, and the zabbix server.')
-
- zapi = ZabbixAPI(api_data)
-
- zbx_class = module.params.get('zbx_class')
- rpc_params = module.params.get('params', {})
- state = module.params.get('state')
-
- # Get the instance we are trying to call
- zbx_class_inst = zapi.__getattribute__(zbx_class.lower())
-
- # perform get
- # Get the instance's method we are trying to call
-
- zbx_action_method = zapi.__getattribute__(zbx_class.capitalize()).__dict__['get']
- _, content = zbx_action_method(zbx_class_inst, rpc_params)
-
- if state == 'list':
- module.exit_json(changed=False, results=content['result'], state="list")
-
- if state == 'absent':
- if not exists(content):
- module.exit_json(changed=False, state="absent")
- # If we are coming from a query, we need to pass in the correct rpc_params for delete.
- # specifically the zabbix class name + 'id'
- # if rpc_params is a list then we need to pass it. (list of ids to delete)
- idname = zbx_class.lower() + "id"
- if not isinstance(rpc_params, list) and content['result'][0].has_key(idname):
- rpc_params = [content['result'][0][idname]]
-
- zbx_action_method = zapi.__getattribute__(zbx_class.capitalize()).__dict__['delete']
- _, content = zbx_action_method(zbx_class_inst, rpc_params)
- module.exit_json(changed=True, results=content['result'], state="absent")
-
- if state == 'present':
- # It's not there, create it!
- if not exists(content):
- zbx_action_method = zapi.__getattribute__(zbx_class.capitalize()).__dict__['create']
- _, content = zbx_action_method(zbx_class_inst, rpc_params)
- module.exit_json(changed=True, results=content['result'], state='present')
-
- # It's there and the same, do nothing!
- diff_params = diff_content(content['result'][0], rpc_params)
- if not diff_params:
- module.exit_json(changed=False, results=content['result'], state="present")
-
- # Add the id to update with
- idname = zbx_class.lower() + "id"
- diff_params[idname] = content['result'][0][idname]
-
-
- ## It's there and not the same, update it!
- zbx_action_method = zapi.__getattribute__(zbx_class.capitalize()).__dict__['update']
- _, content = zbx_action_method(zbx_class_inst, diff_params)
- module.exit_json(changed=True, results=content, state="present")
-
- module.exit_json(failed=True,
- changed=False,
- results='Unknown state passed. %s' % state,
- state="unknown")
-
-# pylint: disable=redefined-builtin, unused-wildcard-import, wildcard-import, locally-disabled
-# import module snippets. This are required
-from ansible.module_utils.basic import *
-
-main()
diff --git a/roles/os_zabbix/meta/main.yml b/roles/os_zabbix/meta/main.yml
new file mode 100644
index 000000000..360f5aad2
--- /dev/null
+++ b/roles/os_zabbix/meta/main.yml
@@ -0,0 +1,9 @@
+---
+galaxy_info:
+ author: OpenShift
+ description: ZabbixAPI
+ company: Red Hat, Inc
+ license: ASL 2.0
+ min_ansible_version: 1.2
+dependencies:
+- lib_zabbix
diff --git a/roles/os_zabbix/tasks/main.yml b/roles/os_zabbix/tasks/main.yml
new file mode 100644
index 000000000..a503b24d7
--- /dev/null
+++ b/roles/os_zabbix/tasks/main.yml
@@ -0,0 +1,81 @@
+---
+- name: Main List all templates
+ zbx_template:
+ zbx_server: "{{ ozb_server }}"
+ zbx_user: "{{ ozb_user }}"
+ zbx_password: "{{ ozb_password }}"
+ state: list
+ register: templates
+
+- include_vars: template_heartbeat.yml
+- include_vars: template_os_linux.yml
+- include_vars: template_docker.yml
+- include_vars: template_openshift_master.yml
+- include_vars: template_openshift_node.yml
+- include_vars: template_ops_tools.yml
+- include_vars: template_app_zabbix_server.yml
+- include_vars: template_app_zabbix_agent.yml
+
+- name: Include Template Heartbeat
+ include: ../../lib_zabbix/tasks/create_template.yml
+ vars:
+ template: "{{ g_template_heartbeat }}"
+ server: "{{ ozb_server }}"
+ user: "{{ ozb_user }}"
+ password: "{{ ozb_password }}"
+
+- name: Include Template os_linux
+ include: ../../lib_zabbix/tasks/create_template.yml
+ vars:
+ template: "{{ g_template_os_linux }}"
+ server: "{{ ozb_server }}"
+ user: "{{ ozb_user }}"
+ password: "{{ ozb_password }}"
+
+- name: Include Template docker
+ include: ../../lib_zabbix/tasks/create_template.yml
+ vars:
+ template: "{{ g_template_docker }}"
+ server: "{{ ozb_server }}"
+ user: "{{ ozb_user }}"
+ password: "{{ ozb_password }}"
+
+- name: Include Template Openshift Master
+ include: ../../lib_zabbix/tasks/create_template.yml
+ vars:
+ template: "{{ g_template_openshift_master }}"
+ server: "{{ ozb_server }}"
+ user: "{{ ozb_user }}"
+ password: "{{ ozb_password }}"
+
+- name: Include Template Openshift Node
+ include: ../../lib_zabbix/tasks/create_template.yml
+ vars:
+ template: "{{ g_template_openshift_node }}"
+ server: "{{ ozb_server }}"
+ user: "{{ ozb_user }}"
+ password: "{{ ozb_password }}"
+
+- name: Include Template Ops Tools
+ include: ../../lib_zabbix/tasks/create_template.yml
+ vars:
+ template: "{{ g_template_ops_tools }}"
+ server: "{{ ozb_server }}"
+ user: "{{ ozb_user }}"
+ password: "{{ ozb_password }}"
+
+- name: Include Template App Zabbix Server
+ include: ../../lib_zabbix/tasks/create_template.yml
+ vars:
+ template: "{{ g_template_app_zabbix_server }}"
+ server: "{{ ozb_server }}"
+ user: "{{ ozb_user }}"
+ password: "{{ ozb_password }}"
+
+- name: Include Template App Zabbix Agent
+ include: ../../lib_zabbix/tasks/create_template.yml
+ vars:
+ template: "{{ g_template_app_zabbix_agent }}"
+ server: "{{ ozb_server }}"
+ user: "{{ ozb_user }}"
+ password: "{{ ozb_password }}"
diff --git a/roles/os_zabbix/vars/main.yml b/roles/os_zabbix/vars/main.yml
new file mode 100644
index 000000000..ed97d539c
--- /dev/null
+++ b/roles/os_zabbix/vars/main.yml
@@ -0,0 +1 @@
+---
diff --git a/roles/os_zabbix/vars/template_app_zabbix_agent.yml b/roles/os_zabbix/vars/template_app_zabbix_agent.yml
new file mode 100644
index 000000000..d636d4822
--- /dev/null
+++ b/roles/os_zabbix/vars/template_app_zabbix_agent.yml
@@ -0,0 +1,23 @@
+---
+g_template_app_zabbix_agent:
+ name: Template App Zabbix Agent
+ zitems:
+ - key: agent.hostname
+ applications:
+ - Zabbix agent
+ value_type: character
+ zabbix_type: agent
+
+ - key: agent.ping
+ applications:
+ - Zabbix agent
+ description: The agent always returns 1 for this item. It could be used in combination with nodata() for availability check.
+ value_type: int
+ zabbix_type: agent
+
+ ztriggers:
+ - name: '[Reboot] Zabbix agent on {HOST.NAME} is unreachable for 15 minutes'
+ description: Zabbix agent is unreachable for 15 minutes.
+ expression: '{Template App Zabbix Agent:agent.ping.nodata(15m)}=1'
+ priority: high
+ url: https://github.com/openshift/ops-sop/blob/master/Alerts/check_ping.asciidoc
diff --git a/roles/os_zabbix/vars/template_app_zabbix_server.yml b/roles/os_zabbix/vars/template_app_zabbix_server.yml
new file mode 100644
index 000000000..43517113b
--- /dev/null
+++ b/roles/os_zabbix/vars/template_app_zabbix_server.yml
@@ -0,0 +1,412 @@
+---
+g_template_app_zabbix_server:
+ name: Template App Zabbix Server
+ zitems:
+ - key: housekeeper_creates
+ applications:
+ - Zabbix server
+ description: A simple count of the number of partition creates output by the housekeeper script.
+ units: ''
+ value_type: int
+ zabbix_type: internal
+
+ - key: housekeeper_drops
+ applications:
+ - Zabbix server
+ description: A simple count of the number of partition drops output by the housekeeper script.
+ units: ''
+ value_type: int
+ zabbix_type: internal
+
+ - key: housekeeper_errors
+ applications:
+ - Zabbix server
+ description: A simple count of the number of errors output by the housekeeper script.
+ units: ''
+ value_type: int
+ zabbix_type: internal
+
+ - key: housekeeper_total
+ applications:
+ - Zabbix server
+ description: A simple count of the total number of lines output by the housekeeper
+ script.
+ units: ''
+ value_type: int
+ zabbix_type: internal
+
+ - key: zabbix[process,alerter,avg,busy]
+ applications:
+ - Zabbix server
+ description: ''
+ units: '%'
+ value_type: float
+ zabbix_type: internal
+
+ - key: zabbix[process,configuration syncer,avg,busy]
+ applications:
+ - Zabbix server
+ description: ''
+ units: '%'
+ value_type: float
+ zabbix_type: internal
+
+ - key: zabbix[process,db watchdog,avg,busy]
+ applications:
+ - Zabbix server
+ description: ''
+ units: '%'
+ value_type: float
+ zabbix_type: internal
+
+ - key: zabbix[process,discoverer,avg,busy]
+ applications:
+ - Zabbix server
+ description: ''
+ units: '%'
+ value_type: float
+ zabbix_type: internal
+
+ - key: zabbix[process,escalator,avg,busy]
+ applications:
+ - Zabbix server
+ description: ''
+ units: '%'
+ value_type: float
+ zabbix_type: internal
+
+ - key: zabbix[process,history syncer,avg,busy]
+ applications:
+ - Zabbix server
+ description: ''
+ units: '%'
+ value_type: float
+ zabbix_type: internal
+
+ - key: zabbix[process,housekeeper,avg,busy]
+ applications:
+ - Zabbix server
+ description: ''
+ units: '%'
+ value_type: float
+ zabbix_type: internal
+
+ - key: zabbix[process,http poller,avg,busy]
+ applications:
+ - Zabbix server
+ description: ''
+ units: '%'
+ value_type: float
+ zabbix_type: internal
+
+ - key: zabbix[process,icmp pinger,avg,busy]
+ applications:
+ - Zabbix server
+ description: ''
+ units: '%'
+ value_type: float
+ zabbix_type: internal
+
+ - key: zabbix[process,ipmi poller,avg,busy]
+ applications:
+ - Zabbix server
+ description: ''
+ units: '%'
+ value_type: float
+ zabbix_type: internal
+
+ - key: zabbix[process,java poller,avg,busy]
+ applications:
+ - Zabbix server
+ description: ''
+ units: '%'
+ value_type: float
+ zabbix_type: internal
+
+ - key: zabbix[process,node watcher,avg,busy]
+ applications:
+ - Zabbix server
+ description: ''
+ units: '%'
+ value_type: float
+ zabbix_type: internal
+
+ - key: zabbix[process,poller,avg,busy]
+ applications:
+ - Zabbix server
+ description: ''
+ units: '%'
+ value_type: float
+ zabbix_type: internal
+
+ - key: zabbix[process,proxy poller,avg,busy]
+ applications:
+ - Zabbix server
+ description: ''
+ units: '%'
+ value_type: float
+ zabbix_type: internal
+
+ - key: zabbix[process,self-monitoring,avg,busy]
+ applications:
+ - Zabbix server
+ description: ''
+ units: '%'
+ value_type: float
+ zabbix_type: internal
+
+ - key: zabbix[process,snmp trapper,avg,busy]
+ applications:
+ - Zabbix server
+ description: ''
+ units: '%'
+ value_type: float
+ zabbix_type: internal
+
+ - key: zabbix[process,timer,avg,busy]
+ applications:
+ - Zabbix server
+ description: ''
+ units: '%'
+ value_type: float
+ zabbix_type: internal
+
+ - key: zabbix[process,trapper,avg,busy]
+ applications:
+ - Zabbix server
+ description: ''
+ units: '%'
+ value_type: float
+ zabbix_type: internal
+
+ - key: zabbix[process,unreachable poller,avg,busy]
+ applications:
+ - Zabbix server
+ description: ''
+ units: '%'
+ value_type: float
+ zabbix_type: internal
+
+ - key: zabbix[queue,10m]
+ applications:
+ - Zabbix server
+ description: ''
+ units: ''
+ value_type: int
+ zabbix_type: internal
+ interval: 600
+
+ - key: zabbix[queue]
+ applications:
+ - Zabbix server
+ description: ''
+ units: ''
+ value_type: int
+ zabbix_type: internal
+ interval: 600
+
+ - key: zabbix[rcache,buffer,pfree]
+ applications:
+ - Zabbix server
+ description: ''
+ units: ''
+ value_type: float
+ zabbix_type: internal
+
+ - key: zabbix[wcache,history,pfree]
+ applications:
+ - Zabbix server
+ description: ''
+ units: ''
+ value_type: float
+ zabbix_type: internal
+
+ - key: zabbix[wcache,text,pfree]
+ applications:
+ - Zabbix server
+ description: ''
+ units: ''
+ value_type: float
+ zabbix_type: internal
+
+ - key: zabbix[wcache,trend,pfree]
+ applications:
+ - Zabbix server
+ description: ''
+ units: ''
+ value_type: float
+ zabbix_type: internal
+
+ - key: zabbix[wcache,values]
+ applications:
+ - Zabbix server
+ description: ''
+ units: ''
+ value_type: float
+ zabbix_type: internal
+ delta: 1 # speed per second
+
+ ztriggers:
+ - description: "There has been unexpected output while running the housekeeping script\
+ \ on the Zabbix. There are only three kinds of lines we expect to see in the output,\
+ \ and we've gotten something enw.\r\n\r\nCheck the script's output in /var/lib/zabbix/state\
+ \ for more details."
+ expression: '{Template App Zabbix Server:housekeeper_errors.last(0)}+{Template App Zabbix Server:housekeeper_creates.last(0)}+{Template App Zabbix Server:housekeeper_drops.last(0)}<>{Template App Zabbix Server:housekeeper_total.last(0)}'
+ name: Unexpected output in Zabbix DB Housekeeping
+ priority: avg
+ url: https://github.com/openshift/ops-sop/blob/master/Alerts/Zabbix_DB_Housekeeping.asciidoc
+
+ - description: An error has occurred during running the housekeeping script on the Zabbix. Check the script's output in /var/lib/zabbix/state for more details.
+ expression: '{Template App Zabbix Server:housekeeper_errors.last(0)}>0'
+ name: Errors during Zabbix DB Housekeeping
+ priority: high
+ url: https://github.com/openshift/ops-sop/blob/master/Alerts/Zabbix_state_check.asciidoc
+
+ - description: ''
+ expression: '{Template App Zabbix Server:zabbix[process,alerter,avg,busy].min(600)}>75'
+ name: Zabbix alerter processes more than 75% busy
+ priority: avg
+ url: https://github.com/openshift/ops-sop/blob/master/Alerts/Zabbix_state_check.asciidoc
+
+ - description: ''
+ expression: '{Template App Zabbix Server:zabbix[process,configuration syncer,avg,busy].min(600)}>75'
+ name: Zabbix configuration syncer processes more than 75% busy
+ priority: avg
+ url: https://github.com/openshift/ops-sop/blob/master/Alerts/Zabbix_state_check.asciidoc
+
+ - description: ''
+ expression: '{Template App Zabbix Server:zabbix[process,db watchdog,avg,busy].min(600)}>75'
+ name: Zabbix db watchdog processes more than 75% busy
+ priority: avg
+ url: https://github.com/openshift/ops-sop/blob/master/Alerts/Zabbix_state_check.asciidoc
+
+ - description: ''
+ expression: '{Template App Zabbix Server:zabbix[process,discoverer,avg,busy].min(600)}>75'
+ name: Zabbix discoverer processes more than 75% busy
+ priority: avg
+ url: https://github.com/openshift/ops-sop/blob/master/Alerts/Zabbix_state_check.asciidoc
+
+ - description: ''
+ expression: '{Template App Zabbix Server:zabbix[process,escalator,avg,busy].min(600)}>75'
+ name: Zabbix escalator processes more than 75% busy
+ priority: avg
+ url: https://github.com/openshift/ops-sop/blob/master/Alerts/Zabbix_state_check.asciidoc
+
+ - description: ''
+ expression: '{Template App Zabbix Server:zabbix[process,history syncer,avg,busy].min(600)}>75'
+ name: Zabbix history syncer processes more than 75% busy
+ priority: avg
+ url: https://github.com/openshift/ops-sop/blob/master/Alerts/Zabbix_state_check.asciidoc
+
+ - description: ''
+ expression: '{Template App Zabbix Server:zabbix[process,housekeeper,avg,busy].min(1800)}>75'
+ name: Zabbix housekeeper processes more than 75% busy
+ priority: avg
+ url: https://github.com/openshift/ops-sop/blob/master/Alerts/Zabbix_state_check.asciidoc
+
+ - description: ''
+ expression: '{Template App Zabbix Server:zabbix[process,http poller,avg,busy].min(600)}>75'
+ name: Zabbix http poller processes more than 75% busy
+ priority: avg
+ url: https://github.com/openshift/ops-sop/blob/master/Alerts/Zabbix_state_check.asciidoc
+
+ - description: ''
+ expression: '{Template App Zabbix Server:zabbix[process,icmp pinger,avg,busy].min(600)}>75'
+ name: Zabbix icmp pinger processes more than 75% busy
+ priority: avg
+ url: https://github.com/openshift/ops-sop/blob/master/Alerts/Zabbix_state_check.asciidoc
+
+ - description: ''
+ expression: '{Template App Zabbix Server:zabbix[process,ipmi poller,avg,busy].min(600)}>75'
+ name: Zabbix ipmi poller processes more than 75% busy
+ priority: avg
+ url: https://github.com/openshift/ops-sop/blob/master/Alerts/Zabbix_state_check.asciidoc
+
+ - description: ''
+ expression: '{Template App Zabbix Server:zabbix[process,java poller,avg,busy].min(600)}>75'
+ name: Zabbix java poller processes more than 75% busy
+ priority: avg
+ url: https://github.com/openshift/ops-sop/blob/master/Alerts/Zabbix_state_check.asciidoc
+
+ - description: ''
+ expression: '{Template App Zabbix Server:zabbix[process,node watcher,avg,busy].min(600)}>75'
+ name: Zabbix node watcher processes more than 75% busy
+ priority: avg
+ url: https://github.com/openshift/ops-sop/blob/master/Alerts/Zabbix_state_check.asciidoc
+
+ - description: ''
+ expression: '{Template App Zabbix Server:zabbix[process,poller,avg,busy].min(600)}>75'
+ name: Zabbix poller processes more than 75% busy
+ priority: high
+ url: https://github.com/openshift/ops-sop/blob/master/Alerts/Zabbix_state_check.asciidoc
+
+ - description: ''
+ expression: '{Template App Zabbix Server:zabbix[process,proxy poller,avg,busy].min(600)}>75'
+ name: Zabbix proxy poller processes more than 75% busy
+ priority: avg
+ url: https://github.com/openshift/ops-sop/blob/master/Alerts/Zabbix_state_check.asciidoc
+
+ - description: ''
+ expression: '{Template App Zabbix Server:zabbix[process,self-monitoring,avg,busy].min(600)}>75'
+ name: Zabbix self-monitoring processes more than 75% busy
+ priority: avg
+ url: https://github.com/openshift/ops-sop/blob/master/Alerts/Zabbix_state_check.asciidoc
+
+ - description: ''
+ expression: '{Template App Zabbix Server:zabbix[process,snmp trapper,avg,busy].min(600)}>75'
+ name: Zabbix snmp trapper processes more than 75% busy
+ priority: avg
+ url: https://github.com/openshift/ops-sop/blob/master/Alerts/Zabbix_state_check.asciidoc
+
+ - description: Timer processes usually are busy because they have to process time
+ based trigger functions
+ expression: '{Template App Zabbix Server:zabbix[process,timer,avg,busy].min(600)}>75'
+ name: Zabbix timer processes more than 75% busy
+ priority: avg
+ url: https://github.com/openshift/ops-sop/blob/master/Alerts/Zabbix_state_check.asciidoc
+
+ - description: ''
+ expression: '{Template App Zabbix Server:zabbix[process,trapper,avg,busy].min(600)}>75'
+ name: Zabbix trapper processes more than 75% busy
+ priority: avg
+ url: https://github.com/openshift/ops-sop/blob/master/Alerts/Zabbix_state_check.asciidoc
+
+ - description: ''
+ expression: '{Template App Zabbix Server:zabbix[process,unreachable poller,avg,busy].min(600)}>75'
+ name: Zabbix unreachable poller processes more than 75% busy
+ priority: avg
+ url: https://github.com/openshift/ops-sop/blob/master/Alerts/Zabbix_state_check.asciidoc
+
+ - description: "This alert generally indicates a performance problem or a problem\
+ \ with the zabbix-server or proxy.\r\n\r\nThe first place to check for issues\
+ \ is Administration > Queue. Be sure to check the general view and the per-proxy\
+ \ view."
+ expression: '{Template App Zabbix Server:zabbix[queue,10m].min(600)}>1000'
+ name: More than 1000 items having missing data for more than 10 minutes
+ priority: high
+ url: https://github.com/openshift/ops-sop/blob/master/Alerts/data_lost_overview_plugin.asciidoc
+
+ - description: Consider increasing CacheSize in the zabbix_server.conf configuration
+ file
+ expression: '{Template App Zabbix Server:zabbix[rcache,buffer,pfree].min(600)}<5'
+ name: Less than 5% free in the configuration cache
+ priority: info
+ url: https://github.com/openshift/ops-sop/blob/master/Alerts/check_cache.asciidoc
+
+ - description: ''
+ expression: '{Template App Zabbix Server:zabbix[wcache,history,pfree].min(600)}<25'
+ name: Less than 25% free in the history cache
+ priority: avg
+ url: https://github.com/openshift/ops-sop/blob/master/Alerts/check_cache.asciidoc
+
+ - description: ''
+ expression: '{Template App Zabbix Server:zabbix[wcache,text,pfree].min(600)}<25'
+ name: Less than 25% free in the text history cache
+ priority: avg
+ url: https://github.com/openshift/ops-sop/blob/master/Alerts/check_cache.asciidoc
+
+ - description: ''
+ expression: '{Template App Zabbix Server:zabbix[wcache,trend,pfree].min(600)}<25'
+ name: Less than 25% free in the trends cache
+ priority: avg
+ url: https://github.com/openshift/ops-sop/blob/master/Alerts/check_cache.asciidoc
diff --git a/roles/os_zabbix/vars/template_docker.yml b/roles/os_zabbix/vars/template_docker.yml
new file mode 100644
index 000000000..bfabf50c5
--- /dev/null
+++ b/roles/os_zabbix/vars/template_docker.yml
@@ -0,0 +1,94 @@
+---
+g_template_docker:
+ name: Template Docker
+ zitems:
+ - key: docker.ping
+ applications:
+ - Docker Daemon
+ value_type: int
+
+ - key: docker.info_elapsed_ms
+ applications:
+ - Docker Daemon
+ value_type: int
+
+ - key: docker.storage.is_loopback
+ applications:
+ - Docker Storage
+ value_type: int
+
+ - key: docker.storage.data.space.total
+ applications:
+ - Docker Storage
+ value_type: float
+
+ - key: docker.storage.data.space.used
+ applications:
+ - Docker Storage
+ value_type: float
+
+ - key: docker.storage.data.space.available
+ applications:
+ - Docker Storage
+ value_type: float
+
+ - key: docker.storage.data.space.percent_available
+ applications:
+ - Docker Storage
+ value_type: float
+
+ - key: docker.storage.metadata.space.total
+ applications:
+ - Docker Storage
+ value_type: float
+
+ - key: docker.storage.metadata.space.used
+ applications:
+ - Docker Storage
+ value_type: float
+
+ - key: docker.storage.metadata.space.available
+ applications:
+ - Docker Storage
+ value_type: float
+
+ - key: docker.storage.metadata.space.percent_available
+ applications:
+ - Docker Storage
+ value_type: float
+ ztriggers:
+ - name: 'docker.ping failed on {HOST.NAME}'
+ expression: '{Template Docker:docker.ping.max(#3)}<1'
+ url: 'https://github.com/openshift/ops-sop/blob/master/V3/Alerts/check_docker_ping.asciidoc'
+ priority: high
+
+ - name: 'Docker storage is using LOOPBACK on {HOST.NAME}'
+ expression: '{Template Docker:docker.storage.is_loopback.last()}<>0'
+ url: 'https://github.com/openshift/ops-sop/blob/master/V3/Alerts/check_docker_loopback.asciidoc'
+ priority: high
+
+ - name: 'Critically low docker storage data space on {HOST.NAME}'
+ expression: '{Template Docker:docker.storage.data.space.percent_available.max(#3)}<5 or {Template Docker:docker.storage.data.space.available.max(#3)}<5' # < 5% or < 5GB
+ url: 'https://github.com/openshift/ops-sop/blob/master/V3/Alerts/check_docker_storage.asciidoc'
+ priority: high
+
+ - name: 'Critically low docker storage metadata space on {HOST.NAME}'
+ expression: '{Template Docker:docker.storage.metadata.space.percent_available.max(#3)}<5 or {Template Docker:docker.storage.metadata.space.available.max(#3)}<0.005' # < 5% or < 5MB
+ url: 'https://github.com/openshift/ops-sop/blob/master/V3/Alerts/check_docker_storage.asciidoc'
+ priority: high
+
+ # Put triggers that depend on other triggers here (deps must be created first)
+ - name: 'Low docker storage data space on {HOST.NAME}'
+ expression: '{Template Docker:docker.storage.data.space.percent_available.max(#3)}<10 or {Template Docker:docker.storage.data.space.available.max(#3)}<10' # < 10% or < 10GB
+ url: 'https://github.com/openshift/ops-sop/blob/master/V3/Alerts/check_docker_storage.asciidoc'
+ dependencies:
+ - 'Critically low docker storage data space on {HOST.NAME}'
+ priority: average
+
+ - name: 'Low docker storage metadata space on {HOST.NAME}'
+ expression: '{Template Docker:docker.storage.metadata.space.percent_available.max(#3)}<10 or {Template Docker:docker.storage.metadata.space.available.max(#3)}<0.01' # < 10% or < 10MB
+ url: 'https://github.com/openshift/ops-sop/blob/master/V3/Alerts/check_docker_storage.asciidoc'
+ dependencies:
+ - 'Critically low docker storage metadata space on {HOST.NAME}'
+ priority: average
+
diff --git a/roles/os_zabbix/vars/template_heartbeat.yml b/roles/os_zabbix/vars/template_heartbeat.yml
new file mode 100644
index 000000000..8dbe0d0d6
--- /dev/null
+++ b/roles/os_zabbix/vars/template_heartbeat.yml
@@ -0,0 +1,13 @@
+---
+g_template_heartbeat:
+ name: Template Heartbeat
+ zitems:
+ - name: Heartbeat Ping
+ applications:
+ - Heartbeat
+ key: heartbeat.ping
+ ztriggers:
+ - name: 'Heartbeat.ping has failed on {HOST.NAME}'
+ expression: '{Template Heartbeat:heartbeat.ping.nodata(20m)}=1'
+ priority: avg
+ url: 'https://github.com/openshift/ops-sop/blob/master/V3/Alerts/check_node_heartbeat.asciidoc'
diff --git a/roles/os_zabbix/vars/template_openshift_master.yml b/roles/os_zabbix/vars/template_openshift_master.yml
new file mode 100644
index 000000000..1de4fefbb
--- /dev/null
+++ b/roles/os_zabbix/vars/template_openshift_master.yml
@@ -0,0 +1,58 @@
+---
+g_template_openshift_master:
+ name: Template Openshift Master
+ zitems:
+ - name: create_app
+ applications:
+ - Openshift Master
+ key: create_app
+
+ - key: openshift.master.process.count
+ description: Shows number of master processes running
+ type: int
+ applications:
+ - Openshift Master
+
+ - key: openshift.master.user.count
+ description: Shows number of users in a cluster
+ type: int
+ applications:
+ - Openshift Master
+
+ - key: openshift.master.pod.running.count
+ description: Shows number of pods running
+ type: int
+ applications:
+ - Openshift Master
+
+ - key: openshift.project.counter
+ description: Shows number of projects on a cluster
+ type: int
+ applications:
+ - Openshift Master
+
+ ztriggers:
+ - name: 'Application creation has failed on {HOST.NAME}'
+ expression: '{Template Openshift Master:create_app.last(#1)}=1 and {Template Openshift Master:create_app.last(#2)}=1'
+ url: 'https://github.com/openshift/ops-sop/blob/master/V3/Alerts/check_create_app.asciidoc'
+ priority: avg
+
+ - name: 'Openshift Master process not running on {HOST.NAME}'
+ expression: '{Template Openshift Master:openshift.master.process.count.max(#3)}<1'
+ url: 'https://github.com/openshift/ops-sop/blob/master/V3/Alerts/openshift_master.asciidoc'
+ priority: high
+
+ - name: 'Too many Openshift Master processes running on {HOST.NAME}'
+ expression: '{Template Openshift Master:openshift.master.process.count.min(#3)}>1'
+ url: 'https://github.com/openshift/ops-sop/blob/master/V3/Alerts/openshift_master.asciidoc'
+ priority: high
+
+ - name: 'Number of users for Openshift Master on {HOST.NAME}'
+ expression: '{Template Openshift Master:openshift.master.user.count.last()}=0'
+ url: 'https://github.com/openshift/ops-sop/blob/master/V3/Alerts/openshift_master.asciidoc'
+ priority: info
+
+ - name: 'There are no projects running on {HOST.NAME}'
+ expression: '{Template Openshift Master:openshift.project.counter.last()}=0'
+ url: 'https://github.com/openshift/ops-sop/blob/master/V3/Alerts/openshift_master.asciidoc'
+ priority: info
diff --git a/roles/os_zabbix/vars/template_openshift_node.yml b/roles/os_zabbix/vars/template_openshift_node.yml
new file mode 100644
index 000000000..ce28b1048
--- /dev/null
+++ b/roles/os_zabbix/vars/template_openshift_node.yml
@@ -0,0 +1,44 @@
+---
+g_template_openshift_node:
+ name: Template Openshift Node
+ zitems:
+ - key: openshift.node.process.count
+ description: Shows number of OpenShift Node processes running
+ type: int
+ applications:
+ - Openshift Node
+
+ - key: openshift.node.ovs.pids.count
+ description: Shows number of ovs process ids running
+ type: int
+ applications:
+ - Openshift Node
+
+ - key: openshift.node.ovs.ports.count
+ description: Shows number of OVS ports defined
+ type: int
+ applications:
+ - Openshift Node
+
+ ztriggers:
+ - name: 'Openshift Node process not running on {HOST.NAME}'
+ expression: '{Template Openshift Node:openshift.node.process.count.max(#3)}<1'
+ url: 'https://github.com/openshift/ops-sop/blob/node/V3/Alerts/openshift_node.asciidoc'
+ priority: high
+
+ - name: 'Too many Openshift Node processes running on {HOST.NAME}'
+ expression: '{Template Openshift Node:openshift.node.process.count.min(#3)}>1'
+ url: 'https://github.com/openshift/ops-sop/blob/node/V3/Alerts/openshift_node.asciidoc'
+ priority: high
+
+ - name: 'OVS may not be running on {HOST.NAME}'
+ expression: '{Template Openshift Node:openshift.node.ovs.pids.count.last()}<>4'
+ url: 'https://github.com/openshift/ops-sop/blob/node/V3/Alerts/openshift_node.asciidoc'
+ priority: high
+
+ - name: 'Number of OVS ports is 0 on {HOST.NAME}'
+ expression: '{Template Openshift Node:openshift.node.ovs.ports.count.last()}=0'
+ url: 'https://github.com/openshift/ops-sop/blob/node/V3/Alerts/openshift_node.asciidoc'
+ priority: high
+
+
diff --git a/roles/os_zabbix/vars/template_ops_tools.yml b/roles/os_zabbix/vars/template_ops_tools.yml
new file mode 100644
index 000000000..d1b8a2514
--- /dev/null
+++ b/roles/os_zabbix/vars/template_ops_tools.yml
@@ -0,0 +1,23 @@
+---
+g_template_ops_tools:
+ name: Template Operations Tools
+ zdiscoveryrules:
+ - name: disc.ops.runner
+ key: disc.ops.runner
+ lifetime: 1
+ description: "Dynamically register operations runner items"
+
+ zitemprototypes:
+ - discoveryrule_key: disc.ops.runner
+ name: "Exit code of ops-runner[{#OSO_COMMAND}]"
+ key: "disc.ops.runner.command.exitcode[{#OSO_COMMAND}]"
+ value_type: int
+ description: "The exit code of the command run from ops-runner"
+ applications:
+ - Ops Runner
+
+ ztriggerprototypes:
+ - name: 'ops-runner[{#OSO_COMMAND}]: non-zero exit code on {HOST.NAME}'
+ expression: '{Template Operations Tools:disc.ops.runner.command.exitcode[{#OSO_COMMAND}].last()}<>0'
+ url: 'https://github.com/openshift/ops-sop/blob/master/V3/Alerts/check_ops_runner_command.asciidoc'
+ priority: average
diff --git a/roles/os_zabbix/vars/template_os_linux.yml b/roles/os_zabbix/vars/template_os_linux.yml
new file mode 100644
index 000000000..3ae1500bc
--- /dev/null
+++ b/roles/os_zabbix/vars/template_os_linux.yml
@@ -0,0 +1,260 @@
+---
+g_template_os_linux:
+ name: Template OS Linux
+ zitems:
+ - key: kernel.uname.sysname
+ applications:
+ - Kernel
+ value_type: string
+
+ - key: kernel.all.cpu.wait.total
+ applications:
+ - Kernel
+ value_type: float
+ units: '%'
+
+ - key: kernel.all.cpu.irq.hard
+ applications:
+ - Kernel
+ value_type: float
+ units: '%'
+
+ - key: kernel.all.cpu.idle
+ applications:
+ - Kernel
+ value_type: float
+ units: '%'
+
+ - key: kernel.uname.distro
+ applications:
+ - Kernel
+ value_type: string
+
+ - key: kernel.uname.nodename
+ applications:
+ - Kernel
+ value_type: string
+
+ - key: kernel.all.cpu.irq.soft
+ applications:
+ - Kernel
+ value_type: float
+ units: '%'
+
+ - key: kernel.all.load.15_minute
+ applications:
+ - Kernel
+ value_type: float
+
+ - key: kernel.all.cpu.sys
+ applications:
+ - Kernel
+ value_type: float
+ units: '%'
+
+ - key: kernel.all.load.5_minute
+ applications:
+ - Kernel
+ value_type: float
+
+ - key: kernel.all.cpu.nice
+ applications:
+ - Kernel
+ value_type: float
+ units: '%'
+
+ - key: kernel.all.load.1_minute
+ applications:
+ - Kernel
+ value_type: float
+
+ - key: kernel.uname.version
+ applications:
+ - Kernel
+ value_type: string
+
+ - key: kernel.all.uptime
+ applications:
+ - Kernel
+ value_type: int
+
+ - key: kernel.all.cpu.user
+ applications:
+ - Kernel
+ value_type: float
+ units: '%'
+
+ - key: kernel.uname.machine
+ applications:
+ - Kernel
+ value_type: string
+
+ - key: hinv.ncpu
+ applications:
+ - Kernel
+ value_type: int
+
+ - key: kernel.all.cpu.steal
+ applications:
+ - Kernel
+ value_type: float
+ units: '%'
+
+ - key: kernel.all.pswitch
+ applications:
+ - Kernel
+ value_type: int
+
+ - key: kernel.uname.release
+ applications:
+ - Kernel
+ value_type: string
+
+ - key: proc.nprocs
+ applications:
+ - Kernel
+ value_type: int
+
+ # Memory Items
+ - key: mem.freemem
+ applications:
+ - Memory
+ value_type: int
+ description: "PCP: free system memory metric from /proc/meminfo"
+ multiplier: 1024
+ units: B
+
+ - key: mem.util.bufmem
+ applications:
+ - Memory
+ value_type: int
+ description: "PCP: Memory allocated for buffer_heads.; I/O buffers metric from /proc/meminfo"
+ multiplier: 1024
+ units: B
+
+ - key: swap.used
+ applications:
+ - Memory
+ value_type: int
+ description: "PCP: swap used metric from /proc/meminfo"
+ multiplier: 1024
+ units: B
+
+ - key: swap.length
+ applications:
+ - Memory
+ value_type: int
+ description: "PCP: total swap available metric from /proc/meminfo"
+ multiplier: 1024
+ units: B
+
+ - key: mem.physmem
+ applications:
+ - Memory
+ value_type: int
+ description: "PCP: The value of this metric corresponds to the \"MemTotal\" field reported by /proc/meminfo. Note that this does not necessarily correspond to actual installed physical memory - there may be areas of the physical address space mapped as ROM in various peripheral devices and the bios may be mirroring certain ROMs in RAM."
+ multiplier: 1024
+ units: B
+
+ - key: swap.free
+ applications:
+ - Memory
+ value_type: int
+ description: "PCP: swap free metric from /proc/meminfo"
+ multiplier: 1024
+ units: B
+
+ - key: mem.util.available
+ applications:
+ - Memory
+ value_type: int
+ description: "PCP: The amount of memory that is available for a new workload, without pushing the system into swap. Estimated from MemFree, Active(file), Inactive(file), and SReclaimable, as well as the \"low\" watermarks from /proc/zoneinfo.; available memory from /proc/meminfo"
+ multiplier: 1024
+ units: B
+
+ - key: mem.util.used
+ applications:
+ - Memory
+ value_type: int
+ description: "PCP: Used memory is the difference between mem.physmem and mem.freemem; used memory metric from /proc/meminfo"
+ multiplier: 1024
+ units: B
+
+ - key: mem.util.cached
+ applications:
+ - Memory
+ value_type: int
+ description: "PCP: Memory used by the page cache, including buffered file data. This is in-memory cache for files read from the disk (the pagecache) but doesn't include SwapCached.; page cache metric from /proc/meminfo"
+ multiplier: 1024
+ units: B
+
+ zdiscoveryrules:
+ - name: disc.filesys
+ key: disc.filesys
+ lifetime: 1
+ description: "Dynamically register the filesystems"
+
+ zitemprototypes:
+ - discoveryrule_key: disc.filesys
+ name: "disc.filesys.full.{#OSO_FILESYS}"
+ key: "disc.filesys.full[{#OSO_FILESYS}]"
+ value_type: float
+ description: "PCP filesys.full option. This is the percent full returned from pcp filesys.full"
+ applications:
+ - Disk
+
+ - discoveryrule_key: disc.filesys
+ name: "Percentage of used inodes on {#OSO_FILESYS}"
+ key: "disc.filesys.inodes.pused[{#OSO_FILESYS}]"
+ value_type: float
+ description: "PCP derived value of percentage of used inodes on a filesystem."
+ applications:
+ - Disk
+
+ ztriggerprototypes:
+ - name: 'Filesystem: {#OSO_FILESYS} has less than 15% free disk space on {HOST.NAME}'
+ expression: '{Template OS Linux:disc.filesys.full[{#OSO_FILESYS}].last()}>85'
+ url: 'https://github.com/openshift/ops-sop/blob/master/V3/Alerts/check_filesys_full.asciidoc'
+ priority: warn
+
+ - name: 'Filesystem: {#OSO_FILESYS} has less than 10% free disk space on {HOST.NAME}'
+ expression: '{Template OS Linux:disc.filesys.full[{#OSO_FILESYS}].last()}>90'
+ url: 'https://github.com/openshift/ops-sop/blob/master/V3/Alerts/check_filesys_full.asciidoc'
+ priority: high
+
+ - name: 'Filesystem: {#OSO_FILESYS} has less than 10% free inodes on {HOST.NAME}'
+ expression: '{Template OS Linux:disc.filesys.inodes.pused[{#OSO_FILESYS}].last()}>90'
+ url: 'https://github.com/openshift/ops-sop/blob/master/V3/Alerts/check_filesys_full.asciidoc'
+ priority: warn
+
+ - name: 'Filesystem: {#OSO_FILESYS} has less than 5% free inodes on {HOST.NAME}'
+ expression: '{Template OS Linux:disc.filesys.inodes.pused[{#OSO_FILESYS}].last()}>95'
+ url: 'https://github.com/openshift/ops-sop/blob/master/V3/Alerts/check_filesys_full.asciidoc'
+ priority: high
+
+ ztriggers:
+ - name: 'Too many TOTAL processes on {HOST.NAME}'
+ expression: '{Template OS Linux:proc.nprocs.last()}>5000'
+ url: 'https://github.com/openshift/ops-sop/blob/master/V3/Alerts/check_proc.asciidoc'
+ priority: warn
+
+ - name: 'Lack of available memory on {HOST.NAME}'
+ expression: '{Template OS Linux:mem.freemem.last()}<30720000'
+ url: 'https://github.com/openshift/ops-sop/blob/master/V3/Alerts/check_memory.asciidoc'
+ priority: warn
+ description: 'Alert on less than 30MegaBytes. This is 30 Million Bytes. 30000 KB x 1024'
+
+ # CPU Utilization #
+ - name: 'CPU idle less than 5% on {HOST.NAME}'
+ expression: '{Template OS Linux:kernel.all.cpu.idle.last()}<5 and {Template OS Linux:kernel.all.cpu.idle.last(#2)}<5'
+ url: 'https://github.com/openshift/ops-sop/blob/master/V3/Alerts/check_cpu_idle.asciidoc'
+ priority: average
+ description: 'CPU is less than 5% idle'
+
+ - name: 'CPU idle less than 10% on {HOST.NAME}'
+ expression: '{Template OS Linux:kernel.all.cpu.idle.last()}<10 and {Template OS Linux:kernel.all.cpu.idle.last(#2)}<10'
+ url: 'https://github.com/openshift/ops-sop/blob/master/V3/Alerts/check_cpu_idle.asciidoc'
+ priority: warn
+ description: 'CPU is less than 10% idle'
+ dependencies:
+ - 'CPU idle less than 5% on {HOST.NAME}'
diff --git a/roles/rhel_subscribe/tasks/enterprise.yml b/roles/rhel_subscribe/tasks/enterprise.yml
new file mode 100644
index 000000000..e9e6e4bd4
--- /dev/null
+++ b/roles/rhel_subscribe/tasks/enterprise.yml
@@ -0,0 +1,9 @@
+---
+- name: Disable all repositories
+ command: subscription-manager repos --disable="*"
+
+- name: Enable RHEL repositories
+ command: subscription-manager repos \
+ --enable="rhel-7-server-rpms" \
+ --enable="rhel-7-server-extras-rpms" \
+ --enable="rhel-7-server-ose-3.0-rpms"
diff --git a/roles/rhel_subscribe/tasks/main.yml b/roles/rhel_subscribe/tasks/main.yml
new file mode 100644
index 000000000..8fb2fc042
--- /dev/null
+++ b/roles/rhel_subscribe/tasks/main.yml
@@ -0,0 +1,29 @@
+---
+# TODO: Enhance redhat_subscription module
+# to make it able to attach to a pool
+# to make it able to enable repositories
+
+- set_fact:
+ rhel_subscription_user: "{{ lookup('oo_option', 'rhel_subscription_user') | default(rhsub_user, True) | default(omit, True) }}"
+ rhel_subscription_pass: "{{ lookup('oo_option', 'rhel_subscription_pass') | default(rhsub_pass, True) | default(omit, True) }}"
+
+- fail:
+ msg: "This role is only supported for Red Hat hosts"
+ when: ansible_distribution != 'RedHat'
+
+- fail:
+ msg: Either rsub_user or the rhel_subscription_user env variable are required for this role.
+ when: rhel_subscription_user is not defined
+
+- fail:
+ msg: Either rsub_pass or the rhel_subscription_pass env variable are required for this role.
+ when: rhel_subscription_pass is not defined
+
+- name: RedHat subscriptions
+ redhat_subscription:
+ username: "{{ rhel_subscription_user }}"
+ password: "{{ rhel_subscription_pass }}"
+ autosubscribe: yes
+
+- include: enterprise.yml
+ when: deployment_type == 'enterprise'
diff --git a/roles/rhel_unsubscribe/tasks/main.yml b/roles/rhel_unsubscribe/tasks/main.yml
new file mode 100644
index 000000000..2aeb09d83
--- /dev/null
+++ b/roles/rhel_unsubscribe/tasks/main.yml
@@ -0,0 +1,5 @@
+---
+- name: Remove RedHat subscriptions
+ redhat_subscription:
+ state: absent
+ when: ansible_distribution == "RedHat"