Moodle Platform Stack
----------------------

Moodle is an open source e-learning platform (https://moodle.org/). 

This example demonstrates deploying multiple Moodle Platform stacks on Kubernetes. 
A Moodle platform stack is created from Custom Resources for Moodle and Mysqlcluster. 
We will use Moodle Operator from CloudARK and MySQL Operator from PressLabs
(https://github.com/presslabs/mysql-operator) to create Moodle Platform stacks. 

Moodle supports various plugins.  Moodle Operator takes the list of plugins to be installed 
as declarative input in the Moodle Custom Resource Spec.  The Operator installs the plugins at appropriate
location within the Moodle installation.  Check namespace1/moodle1.yaml to see an example of how
plugins are specified in the Custom Resource Spec. 

For database, Moodle instance uses the MysqlCluster instance.  The database connection endpoints
are specified in Moodle Custom Resource Spec.  The endpoints consist of name of the MysqlCluster Custom
Resource instance's service and name of the Secret storing the password. 


Steps:
-------

1) Create Kubernetes Cluster
   - Minikube
     - Download Minikube (latest), download Helm (latest)
     - minikube start --memory 4096
  - GKE
     - Create a GKE cluster with 4vCPUs and 15.00 GB memory minimum

2) Install KubePlus
   - git clone https://github.com/cloud-ark/kubeplus.git
   - cd kubeplus
   - kubectl apply -f deploy

3) Setup Helm
   - kubectl create -f scripts/helm-rbac-config.yaml
   - helm init --service-account tiller

4) Wait till Tiller Pod is running
   - kubectl get pods -n kube-system

5) Once Helm Pod is ready, deploy Moodle and MySQL Operators.  If using GKE, also install Nginx Ingress Controller
   - helm install https://github.com/cloud-ark/operatorcharts/blob/master/mysql-operator-0.2.5-4.tgz?raw=true
   - Minikube
     - helm install https://github.com/cloud-ark/operatorcharts/blob/master/moodle-operator-chart-0.4.4.tgz?raw=true
   - GKE
     - helm install https://github.com/cloud-ark/operatorcharts/blob/master/moodle-operator-chart-0.5.0.tgz?raw=true
     - Install Nginx Ingress Controller
       - helm install stable/nginx-ingress --name nginx

6) Wait till all Operator Pods are ready
   - kubectl get pods

7) Find available Custom Resources
   - kubectl get customresourcedefinitions

8) Find the Custom Resource Kind names
   - kubectl describe customresourcedefinitions mysqlclusters.mysql.presslabs.org
   - kubectl describe customresourcedefinitions moodles.moodlecontroller.kubeplus

9) Find more information like how-to use, Spec properties, etc.  for each Kind
   - kubectl man MysqlCluster
   - kubectl man Moodle

10) Deploy Moodle Platform Stack in namespace1
   - cd namespace1
   - kubectl create ns namespace1
   
   - Create MysqlCluster Custom Resource instance
     - kubectl create -f cluster1-secret.yaml
     - kubectl create -f cluster1.yaml

   - Wait till MysqlCluster pods are ready
     - kubectl get pods -n namespace1

   - Once MysqlCluster pods are ready, deploy Moodle
     - Minikube:
       - Nothing special to do

     - GKE:
       - Register a DomainName with some DNS provider like AWS Route53. 
         Update moodle1-gke.yaml to include 'domainName' attribute, e.g.: 'domainName: www.moodle1.net'. 

     - Find the name of the MysqlCluster 'master' Service corresponding to the cluster1 MysqlCluster. 
       - kubectl composition MysqlCluster cluster1 namespace1

     - Add that name in moodle1.yaml / moodle1-gke.yaml in Spec.mySQLServiceName field

     - Create Moodle instance
       - Minikube
         - kubectl create -f moodle1.yaml
       - GKE
         - kubectl create -f moodle1-gke.yaml
  
   - Wail till Moodle Pod is ready (It will take about 5/6 minutes for Moodle Pod to become ready)
     - kubectl get pods -n namespace1

   - Login to Moodle Instance
     - Minikube
       - Update /etc/hosts with <minikube ip or cluster node ip> moodle1.  Example:
         - 192.168.99.100 moodle1
         - You can find minikube ip using: "minikube ip" command

     - GKE
       - Get the IP address of the Nginx Ingress controller and add it to the DNS as a 'A record' set
         - kubectl get svc
           - Get EXTERNAL-IP of the nginx-ingress-controller and add it as 'A record' to the DNS. 
       - Navigate to the domain name url.  Note that this will be a 'http' url.  If your browser auto-changes
         the url to 'https', delete browser cookies so that you will be able to navigate to 'http' url. 

     - Get Moodle instance admin password
  	   - kubectl describe moodles moodle1 -n namespace1
         - Note down the secret name and Moodle instance URL
       - kubectl get secret moodle1 -n namespace1 -o jsonpath="{.data.adminPassword}" | base64 --decode
         - Navigate to the URL of moodle1 instance (available in the output of 'describe' command)
           - Login using 'admin' as username and password retrieved earlier from 'kubectl get secret' command
     - Check installed plugins
      - As part of creating moodle instance, we install the 'profilecohort' plugin. 
        Check the custom resource specification moodle1.yaml to see this definition. 
        - Once logged in to the Moodle instance, hit 'Site Administration'.  
          This will show a message to update Moodle database for 'profilecohort' plugin. 
        - Select that option to complete Plugin installation.  
          You should see a 'success' message when the plugin is installed. 
        - Hit the 'contine' button.  This will take you to the main screen.  
          Fill out the profile and then hit 'update profile'. 
        - Then 
          - Navigate to -> Administration -> Plugins -> Plugins Overview
          - You should see 'profilecohort' plugin in the 'Additional plugins' list

11) Check the composition of Moodle instance
    - kubectl composition Moodle moodle1 namespace1

12) Deploy Moodle2 instance in namespace2
    - cd ../namespace2
    - Repeat steps from 10 for namespace2


Troubleshooting
----------------

1) Get Moodle Operator logs
   - kubectl logs <moodle-operator-pod>

2) Check Helm Deployments
   - helm list
