From 37d997d9cfe54655ab91ae4ba738c7a405481e83 Mon Sep 17 00:00:00 2001
From: Jiří Locker <jiri.locker@gmail.com>
Date: Mon, 06 Jan 2020 22:55:15 +0100
Subject: [PATCH] Add OptaWeb Employee Rostering Demo (#963)

---
 ansible/roles/ocp-workload-optaweb-employee-rostering/tasks/post_workload.yml   |    9 +
 ansible/roles/ocp-workload-optaweb-employee-rostering/tasks/wait_for_deploy.yml |   30 +++++
 ansible/roles/ocp-workload-optaweb-employee-rostering/tasks/pre_workload.yml    |   36 ++++++
 ansible/roles/ocp-workload-optaweb-employee-rostering/tasks/wait_for_build.yml  |   23 +++
 ansible/roles/ocp-workload-optaweb-employee-rostering/readme.adoc               |  131 +++++++++++++++++++++
 ansible/roles/ocp-workload-optaweb-employee-rostering/defaults/main.yml         |   28 ++++
 ansible/roles/ocp-workload-optaweb-employee-rostering/tasks/workload.yml        |   55 +++++++++
 ansible/roles/ocp-workload-optaweb-employee-rostering/tasks/main.yml            |   20 +++
 ansible/roles/ocp-workload-optaweb-employee-rostering/tasks/remove_workload.yml |   20 +++
 9 files changed, 352 insertions(+), 0 deletions(-)

diff --git a/ansible/roles/ocp-workload-optaweb-employee-rostering/defaults/main.yml b/ansible/roles/ocp-workload-optaweb-employee-rostering/defaults/main.yml
new file mode 100644
index 0000000..2676664
--- /dev/null
+++ b/ansible/roles/ocp-workload-optaweb-employee-rostering/defaults/main.yml
@@ -0,0 +1,28 @@
+---
+ocp_username: jlocker-redhat.com
+ocp_user_needs_quota: True
+
+ocp_user_groups:
+  - OPENTLC-PROJECT-PROVISIONERS
+
+quota_requests_cpu: 4
+quota_limits_cpu: 4
+
+quota_requests_memory: '4Gi'
+quota_limits_memory: '8Gi'
+
+quota_configmaps: 4
+quota_pods: 6
+quota_persistentvolumeclaims: 1
+quota_services: 3
+quota_secrets: 1
+quota_requests_storage: 1Gi
+
+build_status_retries: 45
+build_status_delay: 30
+
+deploy_status_retries: 15
+deploy_status_delay: 20
+
+optaweb_git_repository: https://github.com/kiegroup/optaweb-employee-rostering
+optaweb_git_branch: RHPDS
diff --git a/ansible/roles/ocp-workload-optaweb-employee-rostering/readme.adoc b/ansible/roles/ocp-workload-optaweb-employee-rostering/readme.adoc
new file mode 100644
index 0000000..06942ea
--- /dev/null
+++ b/ansible/roles/ocp-workload-optaweb-employee-rostering/readme.adoc
@@ -0,0 +1,131 @@
+= ocp-workload-developer-environment - Sample Config
+
+== Role overview
+
+* This is a simple role that does the following:
+** Playbook: link:./tasks/pre_workload.yml[pre_workload.yml] - Sets up an
+ environment for the workload deployment
+*** Adds a user to a list of groups defined in the
+ link:./defaults/main.yml[defaults file].
+*** Sets a cluster resource quota for the user based on the variables in the
+ link:./defaults/main.yml[defaults file] .
+*** Debug task will print out: `pre_workload Tasks Complete`
+
+** Playbook: link:./tasks/workload.yml[workload.yml] - Used to deploy the actual
+ workload, i.e, 3scale, Mobile or some Demo
+*** This role doesn't do anything here
+*** Debug task will print out: `workload Tasks Complete`
+
+** Playbook: link:./tasks/post_workload.yml[post_workload.yml] - Used to
+ configure the workload after deployment
+*** This role doesn't do anything here
+*** Debug task will print out: `post_workload Tasks Complete`
+
+== Review the defaults variable file
+
+* This file link:./defaults/main.yml[./defaults/main.yml] contains all the variables you
+ need to define to control the deployment of your workload.
+
+* You can modify any of these default values by adding
+`-e"variable_name=variable_value"` to the command line
+
+=== Deploy Workload on OpenShift Cluster from an existing playbook:
+
+[source,yaml]
+----
+- name: Deploy a workload role on a master host
+  hosts: all
+  become: true
+  gather_facts: False
+  tags:
+    - step007
+  roles:
+    - { role: "{{ocp_workload}}", when: 'ocp_workload is defined' }
+
+----
+NOTE: You might want to change `hosts: all` to fit your requirements
+
+
+=== Common configuration to run these playbooks
+You should have these environment variables defined/exported in your system in order
+to run these playbooks.
+
+----
+HOST_GUID=dev37
+TARGET_HOST="bastion.$HOST_GUID.openshift.opentlc.com"
+OCP_USERNAME="ddoyle-redhat.com"
+SSH_USER="opentlc-mgr"
+SSH_PRIVATE_KEY="id_rsa"
+GUID=duncandoyle
+----
+
+=== Deploy a Workload with the `ocp-workload` playbook [Mostly for testing]
+----
+WORKLOAD="ocp-workload-optaweb-employee-rostering"
+
+# a TARGET_HOST is specified in the command line, without using an inventory file
+ansible-playbook -i ${TARGET_HOST}, ./configs/ocp-workloads/ocp-workload.yml \
+                 -e"ansible_ssh_private_key_file=~/.ssh/${SSH_PRIVATE_KEY}" \
+                 -e"ansible_user=${SSH_USER}" \
+                 -e"ocp_username=${OCP_USERNAME}" \
+                 -e"ocp_workload=${WORKLOAD}" \
+                 -e"guid=${GUID}" \
+                 -e"ocp_user_needs_quota=true" \
+                 -e"ocp_master=master.${HOST_GUID}.openshift.opentlc.com" \
+                 -e"ocp_apps_domain=apps.${HOST_GUID}.openshift.opentlc.com" \
+                 -e"ACTION=create"
+----
+
+=== To Delete an environment
+Use the common configuration first. Then run this.
+
+----
+WORKLOAD="ocp-workload-optaweb-employee-rostering"
+
+# a TARGET_HOST is specified in the command line, without using an inventory file
+ansible-playbook -i ${TARGET_HOST}, ./configs/ocp-workloads/ocp-workload.yml \
+                    -e"ansible_ssh_private_key_file=~/.ssh/${SSH_PRIVATE_KEY}" \
+                    -e"ansible_user=${SSH_USER}" \
+                    -e"ocp_username=${OCP_USERNAME}" \
+                    -e"ocp_workload=${WORKLOAD}" \
+                    -e"guid=${GUID}" \
+                    -e"ACTION=remove"
+----
+
+== Set up your Ansible inventory file
+
+* You can create an Ansible inventory file to define your connection
+ method to your host (Master/Bastion with OC command)
+
+* You can also use the command line to define the hosts directly if your `ssh`
+ configuration is set to connect to the host correctly
+
+* You can also use the command line to use localhost or if your cluster is
+ already authenticated and configured in your `oc` configuration
+[source, ini]
+
+.example inventory file
+----
+[gptehosts:vars]
+ansible_ssh_private_key_file=~/.ssh/keytoyourhost.pem
+ansible_user=ec2-user
+
+[gptehosts:children]
+openshift
+
+[openshift]
+bastion.cluster1.openshift.opentlc.com
+bastion.cluster2.openshift.opentlc.com
+bastion.cluster3.openshift.opentlc.com ansible_ssh_host=ec2-11-111-111-11.us-west-2.compute.amazonaws.com
+bastion.cluster4.openshift.opentlc.com
+
+
+[dev]
+bastion.cluster1.openshift.opentlc.com
+bastion.cluster2.openshift.opentlc.com
+
+
+[prod]
+bastion.cluster3.openshift.opentlc.com
+bastion.cluster4.openshift.opentlc.com
+----
diff --git a/ansible/roles/ocp-workload-optaweb-employee-rostering/tasks/main.yml b/ansible/roles/ocp-workload-optaweb-employee-rostering/tasks/main.yml
new file mode 100644
index 0000000..c2bea43
--- /dev/null
+++ b/ansible/roles/ocp-workload-optaweb-employee-rostering/tasks/main.yml
@@ -0,0 +1,20 @@
+---
+- name: Running Pre Workload Tasks
+  import_tasks: ./pre_workload.yml
+  become: false
+  when: ACTION == "create" or ACTION == "provision"
+
+- name: Running Workload Tasks
+  import_tasks: ./workload.yml
+  become: false
+  when: ACTION == "create" or ACTION == "provision"
+
+- name: Running Post Workload Tasks
+  import_tasks: ./post_workload.yml
+  become: false
+  when: ACTION == "create" or ACTION == "provision"
+
+- name: Running Workload removal Tasks
+  import_tasks: ./remove_workload.yml
+  become: false
+  when: ACTION == "destroy" or ACTION == "remove"
diff --git a/ansible/roles/ocp-workload-optaweb-employee-rostering/tasks/post_workload.yml b/ansible/roles/ocp-workload-optaweb-employee-rostering/tasks/post_workload.yml
new file mode 100644
index 0000000..a6af045
--- /dev/null
+++ b/ansible/roles/ocp-workload-optaweb-employee-rostering/tasks/post_workload.yml
@@ -0,0 +1,9 @@
+---
+- name: Delete the remote files used in this role
+  file:
+    path: /tmp/{{guid}}
+    state: absent
+
+- name: post_workload Tasks Complete
+  debug:
+    msg: "Post-Software checks completed successfully"
diff --git a/ansible/roles/ocp-workload-optaweb-employee-rostering/tasks/pre_workload.yml b/ansible/roles/ocp-workload-optaweb-employee-rostering/tasks/pre_workload.yml
new file mode 100644
index 0000000..7796fa3
--- /dev/null
+++ b/ansible/roles/ocp-workload-optaweb-employee-rostering/tasks/pre_workload.yml
@@ -0,0 +1,36 @@
+---
+
+# - name: Add user to developer group (allowed to create projects)
+#   shell: "oadm groups add-users {{item}} {{ocp_username}}"
+#   register: groupadd_register
+#   with_items: "{{ocp_user_groups}}"
+#   when: ocp_username is defined and ocp_user_groups is defined
+#
+# - name: test that command worked
+#   debug:
+#     var: groupadd_register
+#     verbosity: 2
+
+- name: Show path
+  shell: "echo $PATH"
+
+
+- name: Create user Quota - clusterresourcequota
+  shell: |
+        oc create clusterquota clusterquota-"{{ocp_username}}-{{guid}}" \
+        --project-annotation-selector=openshift.io/requester="{{ocp_username}}" \
+        --hard requests.cpu="{{quota_requests_cpu}}" \
+        --hard limits.cpu="{{quota_limits_cpu}}"  \
+        --hard requests.memory="{{quota_requests_memory}}" \
+        --hard limits.memory="{{quota_limits_memory}}" \
+        --hard configmaps="{{quota_configmaps}}" \
+        --hard pods="{{quota_pods}}" \
+        --hard persistentvolumeclaims="{{quota_persistentvolumeclaims}}"  \
+        --hard services="{{quota_services}}" \
+        --hard secrets="{{quota_secrets}}" \
+        --hard requests.storage="{{quota_requests_storage}}"
+  ignore_errors: true
+
+- name: pre_workload Tasks Complete
+  debug:
+    msg: "Pre-Software checks completed successfully"
diff --git a/ansible/roles/ocp-workload-optaweb-employee-rostering/tasks/remove_workload.yml b/ansible/roles/ocp-workload-optaweb-employee-rostering/tasks/remove_workload.yml
new file mode 100644
index 0000000..16fde37
--- /dev/null
+++ b/ansible/roles/ocp-workload-optaweb-employee-rostering/tasks/remove_workload.yml
@@ -0,0 +1,20 @@
+---
+- name: post_workload Tasks Complete
+  debug:
+    msg: "Pre-Software checks completed successfully - Removed"
+
+- name: define ocp_project
+  set_fact:
+    ocp_project: "optaweb-employee-rostering-{{guid}}"
+
+- name: Remove user Project
+  shell: "oc delete project {{ocp_project}}"
+  ignore_errors: true
+
+- name: Remove user Quota - oc delete clusterresourcequota  "clusterquota-{{ocp_username}}-{{guid}}"
+  shell: oc delete clusterresourcequota clusterquota-{{ocp_username}}-{{guid}}
+  ignore_errors: true
+
+- name: post_workload Tasks Complete
+  debug:
+    msg: "Post-Software checks completed successfully - Removed"
diff --git a/ansible/roles/ocp-workload-optaweb-employee-rostering/tasks/wait_for_build.yml b/ansible/roles/ocp-workload-optaweb-employee-rostering/tasks/wait_for_build.yml
new file mode 100644
index 0000000..7975fb2
--- /dev/null
+++ b/ansible/roles/ocp-workload-optaweb-employee-rostering/tasks/wait_for_build.yml
@@ -0,0 +1,23 @@
+---
+
+# Purpose:
+#   This script queries OCP for builds that exist but are not yet ready.
+#   So long as there are unready builds, this script continues to loop
+#
+# Manual Test to determine list of unready builds :
+#  1) install jp :  https://github.com/jmespath/jp
+#  2) oc get builds -o json | jp "items[?  (status.phase != 'Complete') ].metadata.annotations.\"openshift.io/build-config.name\""
+#
+#  Documentation pertaining to jq syntax:
+#    - http://jmespath.org/tutorial.html
+#    - https://stackoverflow.com/questions/41261680/ansible-json-query-path-to-select-item-by-content
+#
+- name: "Wait for following builds to become ready: {{build_to_wait}}"
+  command: 'oc get build -o json -n "{{ ocp_project }}"'
+  register: build_state
+  changed_when: false
+  retries: "{{ build_status_retries }}"
+  delay: "{{ build_status_delay }}"
+  vars:
+    query: "items[?  (status.phase != 'Complete') ].metadata.annotations.\"openshift.io/build-config.name\""
+  until: "build_state.stdout |from_json |json_query(query) |intersect(build_to_wait) |length == 0"
diff --git a/ansible/roles/ocp-workload-optaweb-employee-rostering/tasks/wait_for_deploy.yml b/ansible/roles/ocp-workload-optaweb-employee-rostering/tasks/wait_for_deploy.yml
new file mode 100644
index 0000000..c2f878d
--- /dev/null
+++ b/ansible/roles/ocp-workload-optaweb-employee-rostering/tasks/wait_for_deploy.yml
@@ -0,0 +1,30 @@
+---
+
+# Purpose:
+#   This script queries OCP for replication controllers that exist but are not yet ready.
+#   So long as there are unready replication controllers, this script continues to loop
+#
+# Manual Test to determine list of unready replication controllers :
+#  1) install jp :  https://github.com/jmespath/jp
+#  2) oc get rc -o json | jp 'items[?  (status.readyReplicas == ""|| status.readyReplicas == `0`) ].metadata.annotations."openshift.io/deployment-config.name"'
+#
+
+- name: "Wait for following replication controllers to be created: {{ item }}"
+  command: 'oc get rc -o json -n "{{ ocp_project }}"'
+  register: rc_state
+  changed_when: false
+  retries: "{{ deploy_status_retries }}"
+  delay: "{{ deploy_status_delay }}"
+  until: 'rc_state.stdout |from_json | json_query("items[? (kind == ''ReplicationController'')].metadata.annotations.\"openshift.io/deployment-config.name\"") |intersect(item) |length >= 1'
+  loop: "{{pod_to_wait}}"
+
+- name: "Wait for following deployments to become ready: {{pod_to_wait}}"
+  command: 'oc get rc -o json -n "{{ ocp_project }}"'
+  register: rc_state
+  changed_when: false
+  retries: "{{ deploy_status_retries }}"
+  delay: "{{ deploy_status_delay }}"
+  until: 'rc_state.stdout |from_json |json_query("items[? ((status.readyReplicas == \"\" || status.readyReplicas == ''`0`'') && (metadata.annotations.\"openshift.io/deployment.cancelled\" != ''true''))].metadata.annotations.\"openshift.io/deployment-config.name\"") |intersect(pod_to_wait) |length == 0'
+
+#  Documentation pertaining to jq syntax:
+#    - http://jmespath.org/tutorial.html
diff --git a/ansible/roles/ocp-workload-optaweb-employee-rostering/tasks/workload.yml b/ansible/roles/ocp-workload-optaweb-employee-rostering/tasks/workload.yml
new file mode 100644
index 0000000..39f913f
--- /dev/null
+++ b/ansible/roles/ocp-workload-optaweb-employee-rostering/tasks/workload.yml
@@ -0,0 +1,55 @@
+---
+- name: define ocp_project
+  set_fact:
+    ocp_project: "optaweb-employee-rostering-{{guid}}"
+
+- name: Create project for OptaPlanner Employee Rostering Demo
+  shell: |
+    oc new-project {{ocp_project}} \
+    --display-name="OptaPlanner Employee Rostering Demo" \
+    --description="OptaPlanner Employee Rostering Demo"
+  ignore_errors: true
+
+- name: "Label namespace"
+  command: "oc label namespace {{ocp_project}} AAD='{{guid}}'"
+
+- name: "Create PostgreSQL database"
+  shell: "oc new-app postgresql-persistent -n {{ocp_project}}"
+
+- name: "Create OptaWeb app"
+  shell: "oc new-app --name employee-rostering \
+      --strategy=docker \
+      java:8~{{optaweb_git_repository}}#{{optaweb_git_branch}} \
+      -n {{ocp_project}}"
+
+- name: "Share PostgreSQL secret with OptaWeb app"
+  shell: "oc set env dc/employee-rostering --from=secret/postgresql -n {{ocp_project}}"
+
+- name: "Expose the service"
+  shell: "oc expose svc/employee-rostering -n {{ocp_project}}"
+
+- name: Wait 10 seconds for the builds to be defined
+  pause:
+    seconds: 10
+
+#### Wait for the build to complete before slapping on the quota ....
+- include_tasks: ./wait_for_build.yml
+  vars:
+    build_to_wait:
+      - employee-rostering
+
+#### Wait for the deployment to complete before slapping on the quota ...
+- include_tasks: ./wait_for_deploy.yml
+  vars:
+    pod_to_wait:
+      - employee-rostering
+
+- name: Annotate the completed project as requested by user
+  shell: "oc annotate namespace {{ocp_project}} openshift.io/requester={{ocp_username}} --overwrite"
+
+- name: Give user access to the completed project
+  shell: "oc policy add-role-to-user admin {{ocp_username}} -n {{ocp_project}}"
+
+- name: workload Tasks Complete
+  debug:
+    msg: workload Tasks Complete

--
Gitblit v1.9.3