Fix 1127 bug: Use config instead of resources for SSL certificates 43/9343/15
authorDavid Garcia <david.garcia@canonical.com>
Tue, 7 Jul 2020 09:14:19 +0000 (11:14 +0200)
committerDavid Garcia <david.garcia@canonical.com>
Fri, 10 Jul 2020 11:46:50 +0000 (13:46 +0200)
Change-Id: I66246049e3ca48cdaa03bbc58e123a519f696acc
Signed-off-by: David Garcia <david.garcia@canonical.com>
installers/charm/bundles/osm-ha/bundle.yaml
installers/charm/bundles/osm/bundle.yaml
installers/charm/ng-ui/README.md
installers/charm/ng-ui/config.yaml
installers/charm/ng-ui/files/default
installers/charm/ng-ui/metadata.yaml
installers/charm/ng-ui/src/charm.py
installers/charmed_install.sh

index f395830..c6f0249 100644 (file)
@@ -118,6 +118,19 @@ applications:
     annotations:
       gui-x: 250
       gui-y: -200
+  ng-ui:
+    charm: "%(prefix)s/ng-ui%(suffix)s"
+    channel: "%(channel)s"
+    scale: 1
+    series: kubernetes
+    options:
+      port: 80
+      https_port: 443
+      server_name: localhost
+      client_max_body_size: 15M
+    annotations:
+      gui-x: 500
+      gui-y: 100
   lcm-k8s:
     charm: "cs:~charmed-osm/lcm-k8s"
     channel: "%(channel)s"
@@ -242,3 +255,5 @@ relations:
     - "mongodb-k8s:mongo"
   - - "pla:mysql"
     - "mariadb-k8s:mysql"
+  - - 'ng-ui:nbi'
+    - 'nbi-k8s:nbi'
index 71465f6..7f712e2 100644 (file)
@@ -125,8 +125,12 @@ applications:
     series: kubernetes
     options:
       port: 80
+      https_port: 443
       server_name: localhost
       client_max_body_size: 15M
+    annotations:
+      gui-x: 500
+      gui-y: 100
   lcm-k8s:
     charm: "%(prefix)s/lcm-k8s%(suffix)s"
     channel: "%(channel)s"
@@ -251,3 +255,5 @@ relations:
     - "mongodb-k8s:mongo"
   - - "pla:mysql"
     - "mariadb-k8s:mysql"
+  - - 'ng-ui:nbi'
+    - 'nbi-k8s:nbi'
index 19d8227..e6a3d58 100644 (file)
@@ -21,6 +21,15 @@ juju deploy . # cs:~charmed-osm/ng-ui --channel edge
 juju relate ng-ui nbi-k8s
 ```
 
+## How to expose the NG-UI through ingress
+
+```bash
+juju config ng-ui juju-external-hostname=ng.<k8s_worker_ip>.xip.io
+juju expose ng-ui
+```
+
+> Note: The <k8s_worker_ip> is the IP of the K8s worker node. With microk8s, you can see the IP with `microk8s.config`. It is usually the IP of your host machine.
+
 ## How to scale
 
 ```bash
@@ -34,9 +43,8 @@ Generate your own certificate if you don't have one already:
 ```bash
 sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ssl_certificate.key -out ssl_certificate.crt
 sudo chown $USER:$USER ssl_certificate.key
-juju attach-resource ng-ui ssl_certificate=ssl_certificate.crt
-juju attach-resource ng-ui ssl_certificate_key=ssl_certificate.key
-juju config ng-ui port 443
+juju config ng-ui ssl_certificate=`cat ssl_certificate.crt | base64 -w 0`
+juju config ng-ui ssl_certificate_key=`cat ssl_certificate.key | base64 -w 0`
 ```
 
 ## Config Examples
index 7dd6d60..3d538fe 100644 (file)
@@ -24,6 +24,10 @@ options:
     description: Port number
     type: int
     default: 80
+  https_port:
+    description: Port number
+    type: int
+    default: 443
   server_name:
     description: Server name
     type: string
@@ -31,4 +35,10 @@ options:
   client_max_body_size:
     description: Client maximum body size
     type: string
-    default: 15M
\ No newline at end of file
+    default: 15M
+  ssl_certificate:
+    description: Base64 encoded ssl certificate
+    type: string
+  ssl_certificate_key:
+    description: Base64 encoded ssl certificate key
+    type: string
index 321435c..e014715 100644 (file)
 #   limitations under the License.
 
 
+
 server {
-    listen       $port;
+    listen $http_port;
+    listen $https_port default ssl;
     server_name  $server_name;
     root   /usr/share/nginx/html;
     index  index.html index.htm;
@@ -22,7 +24,7 @@ server {
     $ssl_crt
     $ssl_crt_key
     ssl_protocols       TLSv1 TLSv1.1 TLSv1.2;
-    ssl_ciphers         HIGH:!aNULL:!MD5;
+    ssl_ciphers EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH;
     location /osm {
         proxy_pass https://$nbi_host:$nbi_port;
         proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
index b096635..a0a5921 100644 (file)
@@ -25,10 +25,3 @@ deployment:
 requires:
   nbi:
     interface: osm-nbi
-resources:
-  ssl_certificate:
-    type: file
-    filename: ssl_certificate.crt
-  ssl_certificate_key:
-    type: file
-    filename: ssl_certificate.key
\ No newline at end of file
index 7d46130..33d9ade 100755 (executable)
@@ -15,6 +15,7 @@
 
 import sys
 import logging
+import base64
 
 sys.path.append("lib")
 
@@ -26,6 +27,7 @@ from ops.model import (
     MaintenanceStatus,
     BlockedStatus,
     ModelError,
+    WaitingStatus,
 )
 
 from glob import glob
@@ -54,8 +56,8 @@ class NGUICharm(CharmBase):
 
         # SSL Certificate path
         self.ssl_folder = "/certs"
-        self.ssl_crt = "{}/ssl_certificate.crt".format(self.ssl_folder)
-        self.ssl_key = "{}/ssl_certificate.key".format(self.ssl_folder)
+        self.ssl_crt_name = "ssl_certificate.crt"
+        self.ssl_key_name = "ssl_certificate.key"
 
     def _apply_spec(self):
         # Only apply the spec if this unit is a leader.
@@ -64,7 +66,7 @@ class NGUICharm(CharmBase):
             unit.status = ActiveStatus("Ready")
             return
         if not self.state.nbi_host or not self.state.nbi_port:
-            unit.status = MaintenanceStatus("Waiting for NBI")
+            unit.status = WaitingStatus("Waiting for NBI")
             return
         unit.status = MaintenanceStatus("Applying new pod spec")
 
@@ -79,34 +81,9 @@ class NGUICharm(CharmBase):
     def make_pod_spec(self):
         config = self.framework.model.config
 
-        ports = [
-            {"name": "port", "containerPort": config["port"], "protocol": "TCP",},
-        ]
-
-        kubernetes = {
-            "readinessProbe": {
-                "tcpSocket": {"port": config["port"]},
-                "timeoutSeconds": 5,
-                "periodSeconds": 5,
-                "initialDelaySeconds": 10,
-            },
-            "livenessProbe": {
-                "tcpSocket": {"port": config["port"]},
-                "timeoutSeconds": 5,
-                "initialDelaySeconds": 45,
-            },
-        }
-
-        ssl_certificate = None
-        ssl_certificate_key = None
-        try:
-            ssl_certificate = self.model.resources.fetch("ssl_certificate")
-            ssl_certificate_key = self.model.resources.fetch("ssl_certificate_key")
-        except ModelError as e:
-            logger.info(e)
-
         config_spec = {
-            "port": config["port"],
+            "http_port": config["port"],
+            "https_port": config["https_port"],
             "server_name": config["server_name"],
             "client_max_body_size": config["client_max_body_size"],
             "nbi_host": self.state.nbi_host or config["nbi_host"],
@@ -115,10 +92,28 @@ class NGUICharm(CharmBase):
             "ssl_crt_key": "",
         }
 
-        if ssl_certificate and ssl_certificate_key:
-            config_spec["ssl_crt"] = "ssl_certificate {};".format(self.ssl_crt)
-            config_spec["ssl_crt_key"] = "ssl_certificate_key {};".format(self.ssl_key)
-            config_spec["port"] = "{} ssl".format(config_spec["port"])
+        ssl_certificate = None
+        ssl_certificate_key = None
+        ssl_enabled = False
+
+        if "ssl_certificate" in config and "ssl_certificate_key" in config:
+            # Get bytes of cert and key
+            cert_b = base64.b64decode(config["ssl_certificate"])
+            key_b = base64.b64decode(config["ssl_certificate_key"])
+            # Decode key and cert
+            ssl_certificate = cert_b.decode("utf-8")
+            ssl_certificate_key = key_b.decode("utf-8")
+            # Get paths
+            cert_path = "{}/{}".format(self.ssl_folder, self.ssl_crt_name)
+            key_path = "{}/{}".format(self.ssl_folder, self.ssl_key_name)
+
+            config_spec["port"] = "{} ssl".format(config["https_port"])
+            config_spec["ssl_crt"] = "ssl_certificate {};".format(cert_path)
+            config_spec["ssl_crt_key"] = "ssl_certificate_key {};".format(key_path)
+            ssl_enabled = True
+        else:
+            config_spec["ssl_crt"] = ""
+            config_spec["ssl_crt_key"] = ""
 
         files = [
             {
@@ -132,6 +127,24 @@ class NGUICharm(CharmBase):
                 },
             }
         ]
+        port = config["https_port"] if ssl_enabled else config["port"]
+        ports = [
+            {"name": "port", "containerPort": port, "protocol": "TCP",},
+        ]
+
+        kubernetes = {
+            "readinessProbe": {
+                "tcpSocket": {"port": port},
+                "timeoutSeconds": 5,
+                "periodSeconds": 5,
+                "initialDelaySeconds": 10,
+            },
+            "livenessProbe": {
+                "tcpSocket": {"port": port},
+                "timeoutSeconds": 5,
+                "initialDelaySeconds": 45,
+            },
+        }
 
         if ssl_certificate and ssl_certificate_key:
             files.append(
@@ -139,10 +152,8 @@ class NGUICharm(CharmBase):
                     "name": "ssl",
                     "mountPath": self.ssl_folder,
                     "files": {
-                        Path(filename)
-                        .name: Template(Path(filename).read_text())
-                        .substitute(config_spec)
-                        for filename in [ssl_certificate, ssl_certificate_key]
+                        self.ssl_crt_name: ssl_certificate,
+                        self.ssl_key_name: ssl_certificate_key,
                     },
                 }
             )
@@ -184,13 +195,6 @@ class NGUICharm(CharmBase):
         self.state.nbi_port = event.relation.data[event.unit].get("port")
         self._apply_spec()
 
-    def resource_get(self, resource_name: str) -> Path:
-        from pathlib import Path
-        from subprocess import run
-
-        result = run(["resource-get", resource_name], output=True, text=True)
-        return Path(result.stdout.strip())
-
 
 if __name__ == "__main__":
     main(NGUICharm)
index cb840fa..ed0d58a 100755 (executable)
@@ -234,6 +234,9 @@ applications:
   pla:
     options:
       image: opensourcemano/pla:$TAG
+  ng-ui:
+    options:
+      image: opensourcemano/ng-ui:$TAG
 
 EOF
     mv /tmp/images-overlay.yaml $IMAGES_OVERLAY_FILE