mex-docs

The MobiledgeX Web Console is designed to enable a developer to perform all of the necessary steps to deploy an application to the Edge. However, there are use cases where a web based console is not the best solution. For example, adding deployment logic to a make/build process, setting up a CI/CD pipeline, or enforcing change management policies for application updates.

To provide for these use cases, MobiledgeX exposes a RESTful API that provides the functionality of the Web Console. Although it is possible to access the API directly (via tools such as cUrl, resty, or postmate), MobiledgeX provides the mcctl utility program for interaction with the API.

The mcctl utility provides the following:

The mcctl utility is available for Linux x86_64 and MacOS, and can be downloaded from the MobiledgeX Artifactory repository. Need to add in steps to download here

Once downloaded, you will need to add execute permission to the file in order to execute it. This can be done by using the terminal to run chmod 755 ./mcctl.

Users of MacOS Catalina will need to take an additional step to authorize the application with Gatekeeper. This involves the following steps:

  1. Open finder in the directory (folder) where you have downloaded the mcctl program. This can be done by running open . in the terminal.
  2. Launch the app you’re trying to run and acknowledge the Gatekeeper warning that prevents the app from running.
  3. Head to System Preferences > Security and Privacy > General and look for a note at the bottom of the screen about an app launch being denied.
  4. Click on “Open Anyway” to bypass Gatekeeper and launch the app.

Exercise Parameters

The following parameters are used throughout this exercise.

Logging In

In order to use mcctl, you must first log into the api to retrieve an authorization token.

$ mcctl login --addr  https://console-stage.mobiledgex.net  name=jschmidt                   
password:
login successful
token saved to /home/jschmidt/.mctoken
$

Clone the Source Repository

$ git clone https://github.com/skydvr01/Docker_NodeJS_Hello_World.git

Cloning into 'Docker_NodeJS_Hello_World'...
remote: Enumerating objects: 22, done.
remote: Counting objects: 100% (22/22), done.
remote: Compressing objects: 100% (21/21), done.
remote: Total 22 (delta 8), reused 8 (delta 0), pack-reused 0
Unpacking objects: 100% (22/22), 6.30 KiB | 379.00 KiB/s, done.
$

Build and Upload the Docker Image

Build the Docker Image

$ cd Docker_NodeJS_Hello_World
$ docker build -t helloworld:2.0 .
Sending build context to Docker daemon  106.5kB
Step 1/4 : FROM node:7-onbuild
7-onbuild: Pulling from library/node
ad74af05f5a2: Pull complete
2b032b8bbe8b: Pull complete
a9a5b35f6ead: Pull complete
3245b5a1c52c: Pull complete
afa075743392: Pull complete
9fb9f21641cd: Pull complete
3f40ad2666bc: Pull complete
49c0ed396b49: Pull complete
7af304825012: Pull complete
Digest: sha256:e506d4de7f21fc0cf51e2d2f922eb0349bd2c07f39dd6335e4338f92c9408994
Status: Downloaded newer image for node:7-onbuild
# Executing 5 build triggers
 ---> Running in 9607e4ba380f
Removing intermediate container 9607e4ba380f
 ---> Running in 8a411e89d05e
Removing intermediate container 8a411e89d05e
 ---> Running in 677a952c4669
npm info it worked if it ends with ok
npm info ok
Removing intermediate container 677a952c4669
 ---> 43f574a297b2
Step 2/4 : LABEL maintainer "alexander.donn@mobiledgex.com"
 ---> Running in 7326130e2b9b
Removing intermediate container 7326130e2b9b
 ---> eca3888c059a
Step 3/4 : HEALTHCHECK --interval=5s             --timeout=5s             CMD curl -f http://127.0.0.1:8000 || exit 1
 ---> Running in c23ac72b1395
Removing intermediate container c23ac72b1395
 ---> 078d3d91e71b
Step 4/4 : EXPOSE 8000
 ---> Running in 68df598f66ca
Removing intermediate container 68df598f66ca
 ---> 3c320a9cd114
Successfully built 3c320a9cd114
Successfully tagged helloworld:2.0
$

Log into the MobiledgeX Repository

$ docker login -u demo docker.mobiledgex.net
Password:
WARNING! Your password will be stored unencrypted in /home/jschmidt/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store

Login Succeeded
$

Tag the Docker Image

$ docker tag helloworld:2.0 docker.mobiledgex.net/demoorg/images/helloworld:2.0
$

Push the Docker Image to the Registry

$ docker push docker.mobiledgex.net/demoorg/images/helloworld:2.0               
The push refers to repository [docker.mobiledgex.net/demoorg/images/helloworld]
7dc5eba82ecd: Pushed
0bb28eb62de6: Pushed
6647b5cd7702: Pushed
2895be281ac1: Pushed
ab90d83fa34a: Pushed
8ee318e54723: Pushed
e6695624484e: Pushed
da59b99bbd3b: Pushed
5616a6292c16: Pushed
f3ed6cb59ab0: Pushed
654f45ecb7e3: Pushed
2c40c66f7667: Pushed
2.0: digest: sha256:99c172c4225ffde587c88bc8898dbf7ab963bf14ce9089c8acc8fd7343f8a273 size: 2841
$

Logout From the MobiledgeX Registry

$ docker logout docker.mobiledgex.net
Removing login credentials for docker.mobiledgex.net
$

Creating an Application

Use the mcctl utility with the correct parameters for your application.

$ mcctl --addr https://console.mobiledgex.net region CreateApp \
region=EU app-org=demoorg appname=helloworld appvers=2.0 \
imagetype=ImageTypeDocker \
imagepath=docker.mobiledgex.net/demoorg/images/helloworld:2.0 \
defaultflavor=m4.small accesstype=AccessTypeDefaultForDeployment \
accessports=tcp:8000 deployment=docker
$

Check the application using mcctl.

$ mcctl --addr https://console.mobiledgex.net --output-format json \
 region ShowApp region=EU app-org=demoorg appname=helloworld appvers=2.0

[
  {
    "key": {
      "organization": "demoorg",
      "name": "helloworld",
      "version": "2.0"
    },
    "image_path": "docker.mobiledgex.net/demoorg/images/helloworld:2.0",
    "image_type": 1,
    "access_ports": "tcp:8000",
    "default_flavor": {
      "name": "m4.small"
    },
    "deployment": "docker",
    "access_type": 2
  }
]
$

Creating a Cluster

Use mcctl to create a cluster instance; this will be used to run the application instance spawned from the application definition we just added.

Note: The MobiledgeX API will automatically create a cluster (autocluster) for you if you pass through a cluster name beginning with autocluster to the AppInst creation payload.

$ mcctl --addr https://console.mobiledgex.net region CreateClusterInst \
  region=EU cluster=hellocluster cloudlet-org=TDG cloudlet=hamburg-main \
  cluster-org=demoorg flavor=m4.small ipaccess=IpAccessDedicated \
  deployment=docker
message: Creating
message: Creating Dedicated VM for Docker
message: Creating Heat Stack for hamburg-main-hellocluster-demoorg
message: 'Creating Heat Stack for hamburg-main-hellocluster-demoorg, Heat Stack Status:
  CREATE_IN_PROGRESS'
message: 'Creating Heat Stack for hamburg-main-hellocluster-demoorg, Heat Stack Status:
  CREATE_COMPLETE'

message: Ready
message: Created ClusterInst successfully
$

Check the status of the cluster:

$ mcctl --addr https://console.mobiledgex.net --output-format json region \
  ShowClusterInst region=EU cluster=hellocluster cloudlet-org=TDG \
  cloudlet=hamburg-main cluster-org=demoorg
[
  {
    "key": {
      "cluster_key": {
        "name": "hellocluster"
      },
      "cloudlet_key": {
        "organization": "TDG",
        "name": "hamburg-main"
      },
      "organization": "demoorg"
    },
    "flavor": {
      "name": "m4.small"
    },
    "liveness": 1,
    "state": 5,
    "ip_access": 1,
    "allocated_ip": "dynamic",
    "node_flavor": "m4.small",
    "deployment": "docker",
    "status": {}
  }
$

Creating an Application Instance

Use mcctl to create an application instance; this will run an instance of the application that we defined on the cluster we just created (alternatively, the autocluster logic can be used here).

Note: The MobiledgeX API will automatically create a cluster (autocluster) for you if you pass through a cluster name beginning with autocluster to the AppInst creation payload.

$ mcctl --addr https://console.mobiledgex.net region CreateAppInst region=EU \
 app-org=demoorg appname=helloworld appvers=2.0 cloudlet-org=TDG \
 cloudlet=hamburg-main cluster=hellocluster cluster-org=demoorg
message: Seeding docker secret
message: Deploying Docker App
message: Configuring Firewall Rules and DNS
message: Creating
message: Ready
message: Created AppInst successfully
$

Check the application instance:

$ mcctl --addr https://console.mobiledgex.net --output-format json region \
  ShowAppInst  region=EU app-org=demoorg appname=helloworld appvers=2.0
[
  {
    "key": {
      "app_key": {
        "organization": "demoorg",
        "name": "helloworld",
        "version": "2.0"
      },
      "cluster_inst_key": {
        "cluster_key": {
          "name": "hellocluster"
        },
        "cloudlet_key": {
          "organization": "TDG",
          "name": "hamburg-main"
        },
        "organization": "demoorg"
      }
    },
    "cloudlet_loc": {
      "latitude": 53.5511,
      "longitude": 9.9937
    },
    "uri": "hellocluster.hamburg-main.tdg.mobiledgex.net",
    "liveness": 1,
    "mapped_ports": [
      {
        "proto": 1,
        "internal_port": 8000,
        "public_port": 8000
      }
    ],
    "flavor": {
      "name": "m4.small"
    },
    "state": 5,
    "runtime_info": {
      "container_ids": [
        "envoyhelloworld20",
        "helloworld20"
      ]
    },
    "created_at": {
      "seconds": 1592493852,
      "nanos": 519023900
    },
    "status": {},
    "power_state": 3,
    "vm_flavor": "m4.small"
  }
]
$

Test the Application Instance

Get the URI for the application; this example uses the json tool to parse the output:

$ mcctl --addr https://console.mobiledgex.net --output-format json region ShowAppInst
  region=EU app-org=demoorg appname=helloworld appvers=2.0  |  json -ag uri

hellocluster.hamburg-main.tdg.mobiledgex.net
$

Use cUrl to test the application instance:

$ curl http://hellocluster.hamburg-main.tdg.mobiledgex.net:8000
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link href="https://fonts.googleapis.com/css?family=Lobster|Saira+Condensed&display=swap" rel="stylesheet">
    <title>Hello World!</title>
    <style>
      body {
        margin: 0;
      }

      .center-me {
        display: flex;
        justify-content: center;
        align-items: center;
        /*font-family: 'Saira Condensed', sans-serif;*/
        font-family: 'Lobster', cursive;
        font-size: 100px;
        height: 100vh;
      }
    </style>
  </head>
  <body>

    <div class="center-me">
      <p>Hello World! 🥳</p>
    </div>

  </body>
</html>
$

Viewing Metrics

It is possible to retrieve metrics on running clusters, applications, and (for operators) cloudlets from the MobiledgeX API. To do this, it is recommended that you use the mcctl utility. Examples are shown below for both Cluster Instances and Applications.

Application Metrics

$ mcctl --addr https://console.mobiledgex.net --output-format json metrics \
  app region=EU app-org=demoorg appname=helloworld appvers=2.0 \
  selector=cpu,mem,disk,network

{
  "data": [
    {
      "Series": [
        {
          "columns": [
            "time",
            "app",
            "ver",
            "cluster",
            "clusterorg",
            "cloudlet",
            "cloudletorg",
            "apporg",
            "pod",
            "cpu",
            "mem",
            "disk",
            "sendBytes",
            "recvBytes"
          ],
          "name": "appinst-network",
          "values": [
            [
              "2020-06-18T15:50:09.271640054Z",
              "helloworld",
              "20",
              "hellocluster",
              "demoorg",
              "hamburg-main",
              "TDG",
              "demoorg",
              "helloworld",
              null,
              null,
              null,
              130047,
              133836
            ],
            [
              "2020-06-18T15:50:02.230659657Z",
              "helloworld",
              "20",
              "hellocluster",
              "demoorg",
              "hamburg-main",
              "TDG",
              "demoorg",
              "helloworld",
              null,
              null,
              null,
              129228,
              133017
            ],
            [
              "2020-06-18T15:49:55.188034584Z",
              "helloworld",
              "20",
              "hellocluster",
              "demoorg",
              "hamburg-main",
              "TDG",
              "demoorg",
              "helloworld",
              null,
              null,
              null,
              128716,
              132608
            ],
            [
              "2020-06-18T15:49:48.143705282Z",
              "helloworld",
              "20",
              "hellocluster",
              "demoorg",
              "hamburg-main",
              "TDG",
              "demoorg",
              "helloworld",
              null,
              null,
              null,
              128306,
              132095
            ]
          ]
        }
      ]
    }
  ]
}
$

Cluster Metrics

$ mcctl --addr https://console.mobiledgex.net --output-format json metrics \
  cluster  region=EU cluster-org=demoorg cluster=hellocluster \
  selector=cpu,mem,disk,network last=1
{
  "data": [
    {
      "Series": [
        {
          "columns": [
            "time",
            "cluster",
            "clusterorg",
            "cloudlet",
            "cloudletorg",
            "cpu",
            "mem",
            "disk",
            "sendBytes",
            "recvBytes"
          ],
          "name": "cluster-network",
          "values": [
            [
              "2020-06-18T15:48:35.941672094Z",
              "hellocluster",
              "demoorg",
              "hamburg-main",
              "TDG",
              null,
              null,
              null,
              4087394,
              407099742
            ]
          ]
        },
        {
          "columns": [
            "time",
            "cluster",
            "clusterorg",
            "cloudlet",
            "cloudletorg",
            "cpu",
            "mem",
            "disk",
            "sendBytes",
            "recvBytes"
          ],
          "name": "cluster-mem",
          "values": [
            [
              "2020-06-18T15:48:35.941672094Z",
              "hellocluster",
              "demoorg",
              "hamburg-main",
              "TDG",
              null,
              10.46972236220657,
              null,
              null,
              null
            ]
          ]
        },
        {
          "columns": [
            "time",
            "cluster",
            "clusterorg",
            "cloudlet",
            "cloudletorg",
            "cpu",
            "mem",
            "disk",
            "sendBytes",
            "recvBytes"
          ],
          "name": "cluster-disk",
          "values": [
            [
              "2020-06-18T15:48:35.941672094Z",
              "hellocluster",
              "demoorg",
              "hamburg-main",
              "TDG",
              null,
              null,
              20.06319508568715,
              null,
              null
            ]
          ]
        },
        {
          "columns": [
            "time",
            "cluster",
            "clusterorg",
            "cloudlet",
            "cloudletorg",
            "cpu",
            "mem",
            "disk",
            "sendBytes",
            "recvBytes"
          ],
          "name": "cluster-cpu",
          "values": [
            [
              "2020-06-18T15:48:35.941672094Z",
              "hellocluster",
              "demoorg",
              "hamburg-main",
              "TDG",
              0,
              null,
              null,
              null,
              null
            ]
          ]
        }
      ]
    }
  ]
}
$

Viewing Events

Application Events

$ mcctl --addr https://console.mobiledgex.net --output-format json \
  events  app region=EU apporg=demoorg appname=helloworld appvers=2.0  
{
  "data": [
    {
      "Series": [
        {
          "columns": [
            "time",
            "app",
            "ver",
            "cluster",
            "clusterorg",
            "cloudlet",
            "cloudletorg",
            "apporg",
            "event",
            "status"
          ],
          "name": "appinst",
          "values": [
            [
              "2020-06-18T15:24:48.160858343Z",
              "helloworld",
              "2.0",
              "hellocluster",
              "demoorg",
              "hamburg-main",
              "TDG",
              "demoorg",
              "CREATED",
              "UP"
            ]
          ]
        }
      ]
    }
  ]
}
$

Cluster Events

$ mcctl --addr https://console.mobiledgex.net --output-format json \
  events cluster  region=EU clusterorg=demoorg cluster=hellocluster        
{
  "data": [
    {
      "Series": [
        {
          "columns": [
            "time",
            "cluster",
            "clusterorg",
            "cloudlet",
            "cloudletorg",
            "flavor",
            "vcpu",
            "ram",
            "disk",
            "other",
            "event",
            "status"
          ],
          "name": "clusterinst",
          "values": [
            [
              "2020-06-18T15:16:34.947555381Z",
              "hellocluster",
              "demoorg",
              "hamburg-main",
              "TDG",
              "m4.small",
              2,
              2048,
              20,
              "map[]",
              "CREATED",
              "UP"
            ]
          ]
        }
      ]
    }
  ]
}
$

Reviewing the Audit Log

$ mcctl --addr https://console.mobiledgex.net --output-format json \
  audit showorg org=demoorg
[
  {
    "operationname": "/api/v1/auth/ctrl/CreateAppInst",
    "username": "demo",
    "clientip": "172.17.0.1",
    "status": 200,
    "starttime": 1592493850935462,
    "duration": 37294028,
    "request": "{\"appinst\":{\"key\":{\"app_key\":{\"name\":\"helloworld\",\"organization\":\"demoorg\",\"version\":\"2.0\"},\"cluster_inst_key\":{\"cloudlet_key\":{\"name\":\"hamburg-main\",\"organization\":\"TDG\"},\"cluster_key\":{\"name\":\"hellocluster\"},\"organization\":\"demoorg\"}}},\"region\":\"EU\"}",
    "response": "{\"data\":{\"message\":\"Seeding docker secret\"}}\n{\"data\":{\"message\":\"Deploying Docker App\"}}\n{\"data\":{\"message\":\"Configuring Firewall Rules and DNS\"}}\n{\"data\":{\"message\":\"Creating\"}}\n{\"data\":{\"message\":\"Ready\"}}\n{\"data\":{\"message\":\"Created AppInst successfully\"}}\n",
    "error": "",
    "traceid": "5034d1ced12bb5cf"
  },
  {
    "operationname": "/api/v1/auth/ctrl/CreateApp",
    "username": "demo",
    "clientip": "172.17.0.1",
    "status": 200,
    "starttime": 1592493739016000,
    "duration": 3922894,
    "request": "{\"app\":{\"access_ports\":\"tcp:8000\",\"access_type\":0,\"default_flavor\":{\"name\":\"m4.small\"},\"deployment\":\"docker\",\"image_path\":\"docker.mobiledgex.net/demoorg/images/helloworld:2.0\",\"image_type\":1,\"key\":{\"name\":\"helloworld\",\"organization\":\"demoorg\",\"version\":\"2.0\"}},\"region\":\"EU\"}",
    "response": "{}",
    "error": "",
    "traceid": "34a8ce6da7bac7b8"
  },
  {
    "operationname": "/api/v1/auth/ctrl/DeleteApp",
    "username": "demo",
    "clientip": "172.17.0.1",
    "status": 200,
    "starttime": 1592493647899812,
    "duration": 796033,
    "request": "{\"region\":\"EU\",\"app\":{\"key\":{\"organization\":\"demoorg\",\"name\":\"helloworld\",\"version\":\"2.0\"}}}",
    "response": "{}",
    "error": "",
    "traceid": "5604e0f62e32400f"
  },
  {
    "operationname": "/api/v1/auth/ctrl/CreateAppInst",
    "username": "demo",
    "clientip": "172.17.0.1",
    "status": 400,
    "starttime": 1592493592155579,
    "duration": 1604621,
    "request": "{\"appinst\":{\"key\":{\"app_key\":{\"name\":\"helloworld\",\"organization\":\"demoorg\",\"version\":\"2.0\"},\"cluster_inst_key\":{\"cloudlet_key\":{\"name\":\"hamburg-main\",\"organization\":\"TDG\"},\"cluster_key\":{\"name\":\"hellocluster\"},\"organization\":\"demoorg\"}}},\"region\":\"EU\"}",
    "response": "{\"message\":\"Cannot deploy kubernetes App into docker ClusterInst\"}",
    "error": "",
    "traceid": "066ff271f942e895"
  },
  {
    "operationname": "/api/v1/auth/ctrl/CreateClusterInst",
    "username": "demo",
    "clientip": "172.17.0.1",
    "status": 200,
    "starttime": 1592493298925277,
    "duration": 96092555,
    "request": "{\"clusterinst\":{\"deployment\":\"docker\",\"flavor\":{\"name\":\"m4.small\"},\"ip_access\":1,\"key\":{\"cloudlet_key\":{\"name\":\"hamburg-main\",\"organization\":\"TDG\"},\"cluster_key\":{\"name\":\"hellocluster\"},\"organization\":\"demoorg\"}},\"region\":\"EU\"}",
    "response": "{\"data\":{\"message\":\"Creating\"}}\n{\"data\":{\"message\":\"Creating Dedicated VM for Docker\"}}\n{\"data\":{\"message\":\"Creating Heat Stack for hamburg-main-hellocluster-demoorg\"}}\n{\"data\":{\"message\":\"Creating Heat Stack for hamburg-main-hellocluster-demoorg, Heat Stack Status: CREATE_IN_PROGRESS\"}}\n{\"data\":{\"message\":\"Creating Heat Stack for hamburg-main-hellocluster-demoorg, Heat Stack Status: CREATE_COMPLETE\"}}\n{\"data\":{\"message\":\"Setting Up Root LB\"}}\n{\"data\":{\"message\":\"Ready\"}}\n{\"data\":{\"message\":\"Created ClusterInst successfully\"}}\n",
    "error": "",
    "traceid": "4b13b6bb61928581"
  },
  {
    "operationname": "/api/v1/auth/ctrl/CreateAppInst",
    "username": "demo",
    "clientip": "172.17.0.1",
    "status": 400,
    "starttime": 1592493129120337,
    "duration": 1535173,
    "request": "{\"appinst\":{\"key\":{\"app_key\":{\"name\":\"helloworld\",\"organization\":\"demoorg\",\"version\":\"2.0\"},\"cluster_inst_key\":{\"cloudlet_key\":{\"name\":\"hamburg-main\",\"organization\":\"TDG\"},\"cluster_key\":{\"name\":\"hellocluster\"},\"organization\":\"demoorg\"}}},\"region\":\"EU\"}",
    "response": "{\"message\":\"Specified ClusterInst not found\"}",
    "error": "",
    "traceid": "7f07a2e9f29d5a64"
  },
  {
    "operationname": "/api/v1/auth/ctrl/CreateAppInst",
    "username": "demo",
    "clientip": "172.17.0.1",
    "status": 200,
    "starttime": 1592493022343860,
    "duration": 1531702,
    "request": "{\"appinst\":{\"key\":{\"app_key\":{\"name\":\"helloworld\",\"organization\":\"demoorg\",\"version\":\"2.0\"},\"cluster_inst_key\":{\"cloudlet_key\":{\"name\":\"hamburg-main\",\"organization\":\"TDG\"}}}},\"region\":\"EU\"}",
    "response": "{\"data\":{\"message\":\"Setting ClusterInst developer to match App developer\"}}\n{\"result\":{\"message\":\"Invalid cluster name\",\"code\":400}}\n",
    "error": "",
    "traceid": "076ea2b797cf3fd8"
  },
  {
    "operationname": "/api/v1/auth/ctrl/CreateApp",
    "username": "demo",
    "clientip": "172.17.0.1",
    "status": 400,
    "starttime": 1592492110389860,
    "duration": 3912500,
    "request": "{\"app\":{\"access_ports\":\"tcp:8000\",\"access_type\":0,\"default_flavor\":{\"name\":\"m4.small\"},\"image_path\":\"docker.mobiledgex.net/demoorg/images/helloworld:2.0\",\"image_type\":1,\"key\":{\"name\":\"helloworld\",\"organization\":\"demoorg\",\"version\":\"2.0\"}},\"region\":\"EU\"}",
    "response": "{\"message\":\"App key {\\\"organization\\\":\\\"demoorg\\\",\\\"name\\\":\\\"helloworld\\\",\\\"version\\\":\\\"2.0\\\"} already exists\"}",
    "error": "",
    "traceid": "40190a8d5f99c6e6"
  },
  {
    "operationname": "/api/v1/auth/ctrl/CreateApp",
    "username": "demo",
    "clientip": "172.17.0.1",
    "status": 200,
    "starttime": 1592492083400526,
    "duration": 3590830,
    "request": "{\"app\":{\"access_ports\":\"tcp:8000\",\"access_type\":0,\"default_flavor\":{\"name\":\"m4.small\"},\"image_path\":\"docker.mobiledgex.net/demoorg/images/helloworld:2.0\",\"image_type\":1,\"key\":{\"name\":\"helloworld\",\"organization\":\"demoorg\",\"version\":\"2.0\"}},\"region\":\"EU\"}",
    "response": "{}",
    "error": "",
    "traceid": "60b78153f95413e9"
  },
  {
    "operationname": "/api/v1/auth/ctrl/CreateApp",
    "username": "demo",
    "clientip": "172.17.0.1",
    "status": 400,
    "starttime": 1592492017266333,
    "duration": 3840846,
    "request": "{\"app\":{\"access_ports\":\"tcp:8000\",\"access_type\":0,\"default_flavor\":{\"name\":\"m4.small\"},\"image_path\":\"docker.mobiledgex.net/demoorg/helloworld:2.0\",\"image_type\":1,\"key\":{\"name\":\"helloworld\",\"organization\":\"demoorg\",\"version\":\"2.0\"}},\"region\":\"EU\"}",
    "response": "{\"message\":\"failed to validate docker registry image, path docker.mobiledgex.net/demoorg/helloworld:2.0, Access denied to registry path\"}",
    "error": "",
    "traceid": "77d8f3c0fd0d69f8"
  },
  {
    "operationname": "/api/v1/auth/ctrl/CreateApp",
    "username": "demo",
    "clientip": "172.17.0.1",
    "status": 400,
    "starttime": 1592491977561889,
    "duration": 869118,
    "request": "{\"app\":{\"access_ports\":\"tcp:8000\",\"access_type\":1,\"default_flavor\":{\"name\":\"m4.small\"},\"image_path\":\"docker.mobiledgex.net/demoorg/helloworld:2.0\",\"image_type\":1,\"key\":{\"name\":\"helloworld\",\"organization\":\"demoorg\",\"version\":\"2.0\"}},\"region\":\"EU\"}",
    "response": "{\"message\":\"Invalid access type for deployment\"}",
    "error": "",
    "traceid": "327bc1c726a7a822"
  }
]
$

Deleting an Application Instance

Use mcctl to delete an application instance.

$ mcctl --addr https://console.mobiledgex.net --output-format json region \
  DeleteAppInst  region=EU app-org=demoorg appname=helloworld appvers=2.0 \
  cluster=hellocluster cloudlet-org=TDG cloudlet=hamburg-main
{
  "message": "Setting ClusterInst developer to match App developer"
}
{
  "message": "Deleting"
}
{
  "message": "NotPresent"
}
{
  "message": "Deleted AppInst successfully"
}
$

Check that the application instance has been deleted:

$ mcctl --addr https://console.mobiledgex.net --output-format json region \
  ShowAppInst  region=EU app-org=demoorg appname=helloworld appvers=2.0 \
  cluster=hellocluster
$

Deleting a Cluster Instance

Use mcctl to delete a cluster instance.

$ mcctl --addr https://console.mobiledgex.net --output-format json region DeleteClusterInst \
  region=EU cluster=hellocluster cloudlet-org=TDG cloudlet=hamburg-main cluster-org=demoorg

{
  "message": "Deleting"
}
{
  "message": "NotPresent"
}
{
  "message": "Deleted ClusterInst successfully"
}
$

Check that the cluster has been deleted.

$ mcctl --addr https://console.mobiledgex.net --output-format json region ShowClusterInst \
  region=EU cluster=hellocluster cloudlet-org=TDG cloudlet=hamburg-main cluster-org=demoorg
$

Deleting an Application

Use mcctl to delete an application.

$ mcctl --addr https://console.mobiledgex.net --output-format json \
  region DeleteApp region=EU app-org=demoorg appname=helloworld appvers=2.0

{}
$

Check that the application has been deleted.

$ mcctl --addr https://console.mobiledgex.net --output-format json \
  region ShowApp region=EU app-org=demoorg appname=helloworld appvers=2.0
$