From c1065413a6d499c8181a317a6a860ceff69602c2 Mon Sep 17 00:00:00 2001 From: gbolo Date: Sun, 25 Nov 2018 00:10:30 -0500 Subject: [PATCH] closes #17, closes #16, closes #9 - API redesign --- Gopkg.lock | 21 +- README.md | 38 +- aws.go | 300 ++- common.go | 14 + docs/api/config.md | 2 + docs/api/env_all_details.md | 132 ++ docs/api/env_all_summary.md | 42 + docs/api/env_details.md | 132 ++ docs/api/env_start.md | 20 + docs/api/env_stop.md | 20 + docs/api/env_summary.md | 30 + docs/api/instance_start.md | 38 + docs/api/instance_stop.md | 38 + docs/api/refresh.md | 29 + docs/api/version.md | 38 + handlers.go | 106 +- mock.go | 59 +- router.go | 50 +- testdata/mock/mock_env_cachedTable.json | 2323 +++++++++++++++++++++++ testdata/mock_env_cachedTable.json | 1087 ----------- www/static/aws-power-toggle.js | 25 +- 21 files changed, 3270 insertions(+), 1274 deletions(-) create mode 100644 common.go create mode 100644 docs/api/config.md create mode 100644 docs/api/env_all_details.md create mode 100644 docs/api/env_all_summary.md create mode 100644 docs/api/env_details.md create mode 100644 docs/api/env_start.md create mode 100644 docs/api/env_stop.md create mode 100644 docs/api/env_summary.md create mode 100644 docs/api/instance_start.md create mode 100644 docs/api/instance_stop.md create mode 100644 docs/api/refresh.md create mode 100644 docs/api/version.md create mode 100644 testdata/mock/mock_env_cachedTable.json delete mode 100644 testdata/mock_env_cachedTable.json diff --git a/Gopkg.lock b/Gopkg.lock index 1f746f8..fe7d817 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -63,6 +63,14 @@ revision = "e3702bed27f0d39777b0b37b664b6280e8ef8fbf" version = "v1.6.2" +[[projects]] + digest = "1:8c7fb7f81c06add10a17362abc1ae569ff9765a26c061c6b6e67c909f4f414db" + name = "github.com/hashicorp/go-version" + packages = ["."] + pruneopts = "" + revision = "b5a281d3160aa11950a6182bd9a9dc2cb1e02d50" + version = "v1.0.0" + [[projects]] digest = "1:d14365c51dd1d34d5c79833ec91413bfbb166be978724f15701e17080dc06dec" name = "github.com/hashicorp/hcl" @@ -89,6 +97,14 @@ pruneopts = "" revision = "0b12d6b5" +[[projects]] + digest = "1:b18132857606d5d08096e23ef1a46488ee1ac25dc7d276ca5db1cc204bb898d5" + name = "github.com/liip/sheriff" + packages = ["."] + pruneopts = "" + revision = "0ae0e1f38ffdeff014c9c7af0a1d3cc04f639b5e" + version = "0.3.0" + [[projects]] digest = "1:961dc3b1d11f969370533390fdf203813162980c858e1dabe827b60940c909a5" name = "github.com/magiconair/properties" @@ -166,11 +182,11 @@ [[projects]] branch = "master" - digest = "1:2e1aadff5bda52e267975408bf6b5e90135fc643829c9e4e964ff82c3826a1dd" + digest = "1:303c0ee48d6229a2423950f41b3ccb5a2067dc4c7b65f8863cfbd962bef05a85" name = "golang.org/x/sys" packages = ["unix"] pruneopts = "" - revision = "0cf1ed9e522b7dbb416f080a5c8003de9b702bf4" + revision = "62eef0e2fa9b2c385f7b2778e763486da6880d37" [[projects]] digest = "1:5acd3512b047305d49e8763eef7ba423901e85d5dd2fd1e71778a0ea8de10bd4" @@ -204,6 +220,7 @@ "github.com/aws/aws-sdk-go-v2/service/ec2", "github.com/gorilla/handlers", "github.com/gorilla/mux", + "github.com/liip/sheriff", "github.com/op/go-logging", "github.com/spf13/viper", ] diff --git a/README.md b/README.md index 200f0dc..4d76f7a 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ web UI and API for quickly starting and stopping AWS environments ## Getting Started -aws-power-toggle groups your instances by environments (via instance tag [described below](#Required Tags)), then allows you power toggle +aws-power-toggle groups your instances by environments (via instance tag [described below](#Required-Tags)), then allows you power toggle them with a single action. This can be very useful when you have to deal with a ton of developers who have multiple environments and need to use them sporadically. While you could leave them on all the time, it may result in your boss(es) freaking out about the bill :) Just hand this web UI and/or API to the devs and let them decide when to start/stop the environment(s). @@ -58,22 +58,34 @@ make all curl -v 127.0.0.1:8080/api/env/summary ``` -### API Examples -install `jq` to make your life easier +### API Documentation +For further details on an API endpoint (including example responses), click on the endpoint's name. -``` -### List environments and their state -curl -s -X GET 127.0.0.1:8080/api/env | jq -r '.[] | "\(.Name): \(.State)"' +* [EnvAllSummary](docs/api/env_all_summary.md): `GET /api/v1/env/summary` retrieves a summary of all known environments -### Shutdown an environment (example kube) -curl -s -X POST 127.0.0.1:8080/api/env/powerdown/kube | jq . +* [EnvSummary](docs/api/env_summary.md): `GET /api/v1/env/{env-id}/summary` retrieves a summary of a single environment -### Refresh environment cache -curl -s -X POST 127.0.0.1:8080/api/env/refresh | jq . +* [EnvAllDetails](docs/api/env_all_details.md): `GET /api/v1/env/details` retrieves full details of all known environments (including list of instances) -### Start up and environment (example kube) -curl -s -X POST 127.0.0.1:8080/api/env/startup/kube | jq . -``` +* [EnvDetails](docs/api/env_details.md): `GET /api/v1/env/{env-id}/details` retrieves full details of a single environment (including list of instances) + +* [StopEnv](docs/api/env_stop.md): `POST /api/v1/env/{env-id}/stop` triggers a shutdown of an environment + +* [StartEnv](docs/api/env_start.md): `POST /api/v1/env/{env-id}/start` triggers a startup of an environment + +* [StopInstance](docs/api/instance_stop.md): `POST /api/v1/instance/{instance-id}/stop` triggers a shutdown of a single instance + +* [StartInstance](docs/api/instance_start.md): `POST /api/v1/instance/{instance-id}/start` triggers a startup of a single instance + +* [Refresh](docs/api/refresh.md): `POST /api/v1/refresh` forces backend to refresh it's cache + +* [Version](docs/api/version.md): `GET /api/v1/version` returns backend version information + + +#### TODO: +Need to finish these... + +* [Config](docs/api/config.md): `GET /api/v1/config` returns relevant backend configuration ### Enabling AWS API mocking (web dev mode) It may be useful to mock the aws API when doing development work against the API (like for web ui development). diff --git a/aws.go b/aws.go index 2300dfe..41820ba 100644 --- a/aws.go +++ b/aws.go @@ -3,6 +3,7 @@ package main import ( "encoding/json" "fmt" + "github.com/liip/sheriff" "time" "github.com/aws/aws-sdk-go-v2/aws" @@ -14,10 +15,12 @@ const ( // defines environment states // means that ALL instances for an env are in "running" state ENV_RUNNING = "running" - // means that AT LEAST ONE instance for an env is NOT in a "running" state + // means that ALL instances for an env are in "stopped" state ENV_DOWN = "stopped" + // means that instances for an env are in EITHER "stopped" or "running" state + ENV_MIXED = "mixed" // means that AT LEAST ONE instance for an env is NOT in a "running" state or "stopped" state - ENV_CHANGING = "changing-state" + ENV_CHANGING = "changing" // enables mocking of API calls to aws for development purposes MOCK_ENABLED = false @@ -40,53 +43,100 @@ var ( envNameIgnore []string ) -type ec2Instance struct { - Id string - Type string - Name string - State string - Environment string - VCPU int - MemoryGB float32 -} +type virtualMachine struct { + // Id unique to this application + Id string `json:"id" groups:"summary,details"` + + // these values are straight from aws api + InstanceId string `json:"instance_id" groups:"summary,details"` + InstanceType string `json:"instance_type" groups:"summary,details"` + Name string `json:"name" groups:"summary,details"` + State string `json:"state" groups:"summary,details"` + Environment string `json:"environment" groups:"summary,details"` -type ec2Environment struct { - Name string - Instances []ec2Instance - TotalvCPU int - TotalMemoryGB float32 - State string + // these values are mapped from another source for aws + VCPU int `json:"vcpu" groups:"summary,details"` + MemoryGB float32 `json:"memory_gb" groups:"summary,details"` } -type ec2EnvironmentSummary struct { - Name string - RunningInstances int - TotalInstances int - TotalvCPU int - TotalMemoryGB float32 - State string +type environment struct { + // Id unique to this application + Id string `json:"id" groups:"summary,details"` + Provider string `json:"provider" groups:"summary,details"` + Region string `json:"region" groups:"summary,details"` + Name string `json:"name" groups:"summary,details"` + Instances []virtualMachine `json:"instances" groups:"details"` + + // these values are calculated based on list of Instances + RunningInstances int `json:"running_instances" groups:"summary,details"` + StoppedInstances int `json:"stopped_instances" groups:"summary,details"` + TotalInstances int `json:"total_instances" groups:"summary,details"` + TotalVCPU int `json:"total_vcpu" groups:"summary,details"` + TotalMemoryGB float32 `json:"total_memory_gb" groups:"summary,details"` + State string `json:"state" groups:"summary,details"` } // for global cached table -type envList []ec2Environment +type envList []environment // updateEnvDetails -// determines details like: State, TotalvCPU, TotalMemoryGB +// determines details like: State, TotalVCPU, TotalMemoryGB func updateEnvDetails() { for i, env := range cachedTable { - cachedTable[i].State = ENV_RUNNING - for _, instance := range env.Instances { + // these are not fully used yet (currently only for api response) + // in future we may support other providers and multiple regions + cachedTable[i].Provider = "aws" + cachedTable[i].Region = awsRegion + + // compute a unique identifier for this environment + cachedTable[i].Id = ComputeId( + cachedTable[i].Provider, + cachedTable[i].Region, + env.Name, + ) + + // vm total count + cachedTable[i].TotalInstances = len(env.Instances) + // reset counts + cachedTable[i].RunningInstances = 0 + cachedTable[i].StoppedInstances = 0 + cachedTable[i].TotalVCPU = 0 + cachedTable[i].TotalMemoryGB = 0 + + // determine counts + for c, instance := range env.Instances { + // compute a unique identifier for this instance + // InstanceId is already unique, but this will make ids consistent + // in case we add other cloud providers + cachedTable[i].Instances[c].Id = ComputeId( + cachedTable[i].Provider, + cachedTable[i].Region, + instance.InstanceId, + ) + // update cpu and memory counts - cachedTable[i].TotalvCPU += instance.VCPU + cachedTable[i].TotalVCPU += instance.VCPU cachedTable[i].TotalMemoryGB += instance.MemoryGB - // determine env state - if instance.State != "running" && instance.State != "stopped" { - cachedTable[i].State = ENV_CHANGING - break - } else if instance.State == "stopped" { - cachedTable[i].State = ENV_DOWN + // update vm states + switch instance.State { + case "running": + cachedTable[i].RunningInstances++ + case "stopped": + cachedTable[i].StoppedInstances++ } } + + // determine environment state + switch { + case cachedTable[i].TotalInstances == cachedTable[i].RunningInstances: + cachedTable[i].State = ENV_RUNNING + case cachedTable[i].TotalInstances == cachedTable[i].StoppedInstances: + cachedTable[i].State = ENV_DOWN + case cachedTable[i].TotalInstances == (cachedTable[i].RunningInstances + cachedTable[i].StoppedInstances): + cachedTable[i].State = ENV_MIXED + default: + cachedTable[i].State = ENV_CHANGING + } } } @@ -122,12 +172,12 @@ func validateEnvName(envName string) (ok bool) { } // adds and instance to cachedTable -func addInstance(instance *ec2Instance) { +func addInstance(instance *virtualMachine) { // check if we should ignore instance based on: // - configured ignored instance types // - instance state is "terminated" - if !checkInstanceType(instance.Type) || instance.State == "terminated" { - log.Debugf("instance is being ignored: name='%s' [%s](%s)\n", instance.Name, instance.Type, instance.State) + if !checkInstanceType(instance.InstanceType) || instance.State == "terminated" { + log.Debugf("instance is being ignored: name='%s' [%s](%s)\n", instance.Name, instance.InstanceType, instance.State) return } envExists := false @@ -138,9 +188,9 @@ func addInstance(instance *ec2Instance) { } } if !envExists { - ec2env := ec2Environment{ + ec2env := environment{ Name: instance.Environment, - Instances: []ec2Instance{*instance}, + Instances: []virtualMachine{*instance}, } cachedTable = append(cachedTable, ec2env) } @@ -175,7 +225,7 @@ func refreshTable() (err error) { for _, reservation := range resp.Reservations { for _, instance := range reservation.Instances { - instanceObj := ec2Instance{Id: *instance.InstanceId, State: string(instance.State.Name), Type: string(instance.InstanceType)} + instanceObj := virtualMachine{InstanceId: *instance.InstanceId, State: string(instance.State.Name), InstanceType: string(instance.InstanceType)} // populate info from tags for _, tag := range instance.Tags { if *tag.Key == environmentTagKey && *tag.Value != "" { @@ -186,7 +236,7 @@ func refreshTable() (err error) { } } // determine instance cpu and memory - if details, found := getInstanceTypeDetails(instanceObj.Type); found { + if details, found := getInstanceTypeDetails(instanceObj.InstanceType); found { instanceObj.MemoryGB = details.MemoryGB instanceObj.VCPU = details.VCPU } @@ -200,98 +250,164 @@ func refreshTable() (err error) { return } -// get instance ids for an environment -func getInstanceIds(envName string) (instanceIds []string) { +// get instance ids for an environment with a specific state +// this is used for power up/down commands against aws API +func getInstanceIds(envId, state string) (instanceIds []string) { for _, env := range cachedTable { - if env.Name == envName { + if env.Id == envId { for _, instance := range env.Instances { - instanceIds = append(instanceIds, instance.Id) + if instance.State == state { + instanceIds = append(instanceIds, instance.InstanceId) + } } } } return } -// shuts down an env -func shutdownEnv(envName string) (response []byte, err error) { - // use the mock function if enabled - if MOCK_ENABLED { - return mockShutdownEnv(envName) +// toggleInstances can start or stop a list of instances +func toggleInstances(instanceIds []string, desiredState string) (response []byte, err error) { + if len(instanceIds) < 1 { + err = fmt.Errorf("no instanceIds have been provided") + return } - instanceIds := getInstanceIds(envName) - if len(instanceIds) > maxInstancesToShutdown { - err = fmt.Errorf("SAFETY: env [%s] has too many associated instances to shutdown %d", envName, len(instanceIds)) - log.Debugf("SAFETY: instances: %v", instanceIds) - } else if len(instanceIds) > 0 { + // supported states are: start, stop + switch desiredState { + case "start": + input := &ec2.StartInstancesInput{ + InstanceIds: instanceIds, + DryRun: aws.Bool(false), + } + + req := awsClient.StartInstancesRequest(input) + awsResponse, reqErr := req.Send() + response, _ = json.MarshalIndent(awsResponse, "", " ") + err = reqErr + return + + case "stop": input := &ec2.StopInstancesInput{ InstanceIds: instanceIds, DryRun: aws.Bool(false), } req := awsClient.StopInstancesRequest(input) - resp, reqErr := req.Send() - response, _ = json.MarshalIndent(resp, "", " ") - if reqErr != nil { - log.Errorf("aws api error [%s]: %v", envName, reqErr) - err = reqErr + awsResponse, reqErr := req.Send() + response, _ = json.MarshalIndent(awsResponse, "", " ") + err = reqErr + return + + default: + err = fmt.Errorf("unsupported desiredState soecified") + return + } +} + +// shuts down an env +func shutdownEnv(envId string) (response []byte, err error) { + // use the mock function if enabled + if MOCK_ENABLED { + return mockShutdownEnv(envId) + } + + instanceIds := getInstanceIds(envId, "running") + if len(instanceIds) > maxInstancesToShutdown { + err = fmt.Errorf("SAFETY: env [%s] has too many associated instances to shutdown %d", envId, len(instanceIds)) + log.Debugf("SAFETY: instances: %v", instanceIds) + } else if len(instanceIds) > 0 { + response, err = toggleInstances(instanceIds, "stop") + if err != nil { + log.Errorf("error trying to stop env %s: %v", envId, err) } else { - log.Infof("successfully stopped env %s", envName) + log.Infof("successfully stopped env %s", envId) } } else { - err = fmt.Errorf("env [%s] has no associated instances", envName) - log.Errorf("env [%s] has no associated instances", envName) + err = fmt.Errorf("env [%s] has no associated instances", envId) + log.Errorf("env [%s] has no associated instances", envId) } return } // starts up an env -func startupEnv(envName string) (response []byte, err error) { +func startupEnv(envId string) (response []byte, err error) { // use the mock function if enabled if MOCK_ENABLED { - return mockStartupEnv(envName) + return mockStartupEnv(envId) } - instanceIds := getInstanceIds(envName) + instanceIds := getInstanceIds(envId, "stopped") if len(instanceIds) > 0 { - input := &ec2.StartInstancesInput{ - InstanceIds: instanceIds, - DryRun: aws.Bool(false), + response, err = toggleInstances(instanceIds, "start") + if err != nil { + log.Errorf("error trying to start env %s: %v", envId, err) + } else { + log.Infof("successfully started env %s", envId) } + } else { + err = fmt.Errorf("env [%s] has no associated instances", envId) + log.Errorf("env [%s] has no associated instances", envId) + } + return +} - req := awsClient.StartInstancesRequest(input) - resp, reqErr := req.Send() - response, _ = json.MarshalIndent(resp, "", " ") - if reqErr != nil { - log.Errorf("aws api error [%s]: %v", envName, reqErr) - err = reqErr +// starts up an instance based on internal id (not aws instance id) +func toggleInstance(id, desiredState string) (response []byte, err error) { + // use the mock function if enabled + if MOCK_ENABLED { + return mockToggleInstance(id, desiredState) + } + + // validate desiredState + if desiredState != "start" && desiredState != "stop" { + err = fmt.Errorf("invalid desired state: %s", desiredState) + return + } + // get the AWS instance id + awsInstanceId := getAWSInstanceId(id) + if awsInstanceId != "" { + response, err = toggleInstances([]string{awsInstanceId}, desiredState) + if err != nil { + log.Errorf("error trying to %s instance %s: %v", desiredState, id, err) } else { - log.Infof("successfully started env %s", envName) + log.Infof("successfully toggled instance state (%s): %s", desiredState, id) } } else { - err = fmt.Errorf("env [%s] has no associated instances", envName) - log.Errorf("env [%s] has no associated instances", envName) + err = fmt.Errorf("no mapping found between internal id (%s) and aws instance id", id) } return } -// returns an env Summary -func getEnvSummary() (envSummary []ec2EnvironmentSummary) { +// returns a single environment by id +func getEnvironmentById(envId string) (environment, bool) { + for _, env := range cachedTable { + if env.Id == envId { + return env, true + } + } + return environment{}, false +} + +// given an aws-power-toggle id, it will return the actual aws instance id +func getAWSInstanceId(id string) (awsInstanceId string) { for _, env := range cachedTable { - running := 0 for _, instance := range env.Instances { - if instance.State == "running" { - running++ + if instance.Id == id { + awsInstanceId = instance.InstanceId + break } } - envSummary = append(envSummary, ec2EnvironmentSummary{ - Name: env.Name, - State: env.State, - RunningInstances: running, - TotalvCPU: env.TotalvCPU, - TotalMemoryGB: env.TotalMemoryGB, - TotalInstances: len(env.Instances), - }) + } + return +} + +func getMarshalledRespone(data interface{}, groups ...string) (response []byte, err error) { + // filter out the specified group(s) + if sMarshal, sErr := sheriff.Marshal(&sheriff.Options{Groups: groups}, data); sErr != nil { + log.Errorf("error parsing json (sheriff): %v", sErr) + err = sErr + } else { + response, err = json.Marshal(sMarshal) } return } diff --git a/common.go b/common.go new file mode 100644 index 0000000..9c400be --- /dev/null +++ b/common.go @@ -0,0 +1,14 @@ +package main + +import ( + "crypto/sha1" + "fmt" + "strings" +) + +// ComputeId returns the first 12 characters from a SHA1 hash of the combined input string(s) +func ComputeId(input ...string) string { + inputString := strings.Join(input, "") + sum := fmt.Sprintf("%x", sha1.Sum([]byte(inputString))) + return sum[0:12] +} diff --git a/docs/api/config.md b/docs/api/config.md new file mode 100644 index 0000000..ce60fa9 --- /dev/null +++ b/docs/api/config.md @@ -0,0 +1,2 @@ +# PLACEHOLDER +not implemented yet diff --git a/docs/api/env_all_details.md b/docs/api/env_all_details.md new file mode 100644 index 0000000..951a51e --- /dev/null +++ b/docs/api/env_all_details.md @@ -0,0 +1,132 @@ +# Get Details of a SINGLE Environment + +Retrieves full details of a single environment which includes a list of instances + +**URL** : `/api/v1/env/{env-id}/details` + +**Method** : `GET` + +## Success Response + +**Code** : `200 OK` + +**Example Response Body** + +response of request: `/api/v1/env/931decfe6fd5/details` + +```json +{ + "id": "931decfe6fd5", + "provider": "aws", + "region": "ca-central-1", + "name": "kube", + "instances": [ + { + "id": "1aef6299109b", + "instance_id": "i-0008ad1bfd83a52eb", + "instance_type": "t3.xlarge", + "name": "kube-k8node2", + "state": "stopped", + "environment": "kube", + "vcpu": 4, + "memory_gb": 16 + }, + { + "id": "9b97d53ab004", + "instance_id": "i-04b69b4ec92d548df", + "instance_type": "t3.medium", + "name": "kube-k8master1", + "state": "stopped", + "environment": "kube", + "vcpu": 2, + "memory_gb": 4 + }, + { + "id": "be8225018847", + "instance_id": "i-0dedc66553eaecfc3", + "instance_type": "t3.medium", + "name": "kube-k8master2", + "state": "stopped", + "environment": "kube", + "vcpu": 2, + "memory_gb": 4 + }, + { + "id": "dd4c000552b2", + "instance_id": "i-0778ddf78ec72bffd", + "instance_type": "t3.small", + "name": "kube-etcd3", + "state": "stopped", + "environment": "kube", + "vcpu": 2, + "memory_gb": 2 + }, + { + "id": "63296c73e207", + "instance_id": "i-03b3782294e848647", + "instance_type": "t3.small", + "name": "kube-etcd1", + "state": "stopped", + "environment": "kube", + "vcpu": 2, + "memory_gb": 2 + }, + { + "id": "a2f4635a834b", + "instance_id": "i-0872ea25c0766d383", + "instance_type": "t3.xlarge", + "name": "kube-k8node5", + "state": "stopped", + "environment": "kube", + "vcpu": 4, + "memory_gb": 16 + }, + { + "id": "98a9867235f3", + "instance_id": "i-0e9fcaf646ce779ab", + "instance_type": "t3.xlarge", + "name": "kube-k8node3", + "state": "stopped", + "environment": "kube", + "vcpu": 4, + "memory_gb": 16 + }, + { + "id": "906d663b6ecd", + "instance_id": "i-0eba74077ac760573", + "instance_type": "t3.small", + "name": "kube-etcd2", + "state": "stopped", + "environment": "kube", + "vcpu": 2, + "memory_gb": 2 + }, + { + "id": "8a0a2a0d8725", + "instance_id": "i-0d67730effbee8b3b", + "instance_type": "t3.xlarge", + "name": "kube-k8node1", + "state": "stopped", + "environment": "kube", + "vcpu": 4, + "memory_gb": 16 + }, + { + "id": "8c65980f5b5f", + "instance_id": "i-009517923633b51f4", + "instance_type": "t3.xlarge", + "name": "kube-k8node4", + "state": "stopped", + "environment": "kube", + "vcpu": 4, + "memory_gb": 16 + } + ], + "running_instances": 0, + "stopped_instances": 10, + "total_instances": 10, + "total_vcpu": 30, + "total_memory_gb": 94, + "state": "stopped" +} +``` diff --git a/docs/api/env_all_summary.md b/docs/api/env_all_summary.md new file mode 100644 index 0000000..f0efac3 --- /dev/null +++ b/docs/api/env_all_summary.md @@ -0,0 +1,42 @@ +# Get Summary of ALL Environments + +Retrieves a list of environments that are currently available to control + +**URL** : `/api/v1/env/summary` + +**Method** : `GET` + +## Success Response + +**Code** : `200 OK` + +**Example Response Body** + +```json +[ + { + "id": "931decfe6fd5", + "name": "kube", + "provider": "aws", + "region": "ca-central-1", + "running_instances": 0, + "state": "stopped", + "stopped_instances": 10, + "total_instances": 10, + "total_memory_gb": 94, + "total_vcpu": 30 + }, + { + "id": "36436c027202", + "name": "bench6", + "provider": "aws", + "region": "ca-central-1", + "running_instances": 0, + "state": "stopped", + "stopped_instances": 53, + "total_instances": 53, + "total_memory_gb": 270, + "total_vcpu": 155 + } +] +``` diff --git a/docs/api/env_details.md b/docs/api/env_details.md new file mode 100644 index 0000000..99f8669 --- /dev/null +++ b/docs/api/env_details.md @@ -0,0 +1,132 @@ +# Get Details of ALL Environments + +retrieves full details of all known environments (including list of instances) + +**URL** : `/api/v1/env/details` + +**Method** : `GET` + +## Success Response + +**Code** : `200 OK` + +**Example Response Body** + +```json +[ + { + "id": "931decfe6fd5", + "provider": "aws", + "region": "ca-central-1", + "name": "kube", + "instances": [ + { + "id": "1aef6299109b", + "instance_id": "i-0008ad1bfd83a52eb", + "instance_type": "t3.xlarge", + "name": "kube-k8node2", + "state": "stopped", + "environment": "kube", + "vcpu": 4, + "memory_gb": 16 + }, + { + "id": "9b97d53ab004", + "instance_id": "i-04b69b4ec92d548df", + "instance_type": "t3.medium", + "name": "kube-k8master1", + "state": "stopped", + "environment": "kube", + "vcpu": 2, + "memory_gb": 4 + }, + { + "id": "be8225018847", + "instance_id": "i-0dedc66553eaecfc3", + "instance_type": "t3.medium", + "name": "kube-k8master2", + "state": "stopped", + "environment": "kube", + "vcpu": 2, + "memory_gb": 4 + }, + { + "id": "dd4c000552b2", + "instance_id": "i-0778ddf78ec72bffd", + "instance_type": "t3.small", + "name": "kube-etcd3", + "state": "stopped", + "environment": "kube", + "vcpu": 2, + "memory_gb": 2 + }, + { + "id": "63296c73e207", + "instance_id": "i-03b3782294e848647", + "instance_type": "t3.small", + "name": "kube-etcd1", + "state": "stopped", + "environment": "kube", + "vcpu": 2, + "memory_gb": 2 + }, + { + "id": "a2f4635a834b", + "instance_id": "i-0872ea25c0766d383", + "instance_type": "t3.xlarge", + "name": "kube-k8node5", + "state": "stopped", + "environment": "kube", + "vcpu": 4, + "memory_gb": 16 + }, + { + "id": "98a9867235f3", + "instance_id": "i-0e9fcaf646ce779ab", + "instance_type": "t3.xlarge", + "name": "kube-k8node3", + "state": "stopped", + "environment": "kube", + "vcpu": 4, + "memory_gb": 16 + }, + { + "id": "906d663b6ecd", + "instance_id": "i-0eba74077ac760573", + "instance_type": "t3.small", + "name": "kube-etcd2", + "state": "stopped", + "environment": "kube", + "vcpu": 2, + "memory_gb": 2 + }, + { + "id": "8a0a2a0d8725", + "instance_id": "i-0d67730effbee8b3b", + "instance_type": "t3.xlarge", + "name": "kube-k8node1", + "state": "stopped", + "environment": "kube", + "vcpu": 4, + "memory_gb": 16 + }, + { + "id": "8c65980f5b5f", + "instance_id": "i-009517923633b51f4", + "instance_type": "t3.xlarge", + "name": "kube-k8node4", + "state": "stopped", + "environment": "kube", + "vcpu": 4, + "memory_gb": 16 + } + ], + "running_instances": 0, + "stopped_instances": 10, + "total_instances": 10, + "total_vcpu": 30, + "total_memory_gb": 94, + "state": "stopped" + } +] +``` diff --git a/docs/api/env_start.md b/docs/api/env_start.md new file mode 100644 index 0000000..70fe1fa --- /dev/null +++ b/docs/api/env_start.md @@ -0,0 +1,20 @@ +# Initialize a Start-Up of an Environment + +Sends a startup request to the AWS API for all associated instances +in the specified environment + +**URL** : `/api/v1/env/{env-id}/start` + +**Method** : `POST` + +## Success Response + +**Code** : `200 OK` + +## Notes + +Responses vary depending on upstream AWS API +since we pass the exact aws response. +**This will be addressed in an upcomming release for consistency.** + +**ONLY** instances which are in a `stopped` state get included for the AWS API call. \ No newline at end of file diff --git a/docs/api/env_stop.md b/docs/api/env_stop.md new file mode 100644 index 0000000..35cd15d --- /dev/null +++ b/docs/api/env_stop.md @@ -0,0 +1,20 @@ +# Initialize a Shutdown of an Environment + +Sends a shutdown request to the AWS API for all associated instances +in the specified environment + +**URL** : `/api/v1/env/{env-id}/stop` + +**Method** : `POST` + +## Success Response + +**Code** : `200 OK` + +## Notes + +Responses vary depending on upstream AWS API +since we pass the exact aws response. +**This will be addressed in an upcomming release for consistency.** + +**ONLY** instances which are in a `running` state get included for the AWS API call. \ No newline at end of file diff --git a/docs/api/env_summary.md b/docs/api/env_summary.md new file mode 100644 index 0000000..57c4e02 --- /dev/null +++ b/docs/api/env_summary.md @@ -0,0 +1,30 @@ +# Get Summary of a SINGLE Environment + +Retrieves a summary of the specified environment + +**URL** : `/api/v1/env/{env-id}/summary` + +**Method** : `GET` + +## Success Response + +**Code** : `200 OK` + +**Example Response Body** + +response of request: `/api/v1/env/931decfe6fd5/summary` + +```json +{ + "id": "931decfe6fd5", + "name": "kube", + "provider": "aws", + "region": "ca-central-1", + "running_instances": 0, + "state": "stopped", + "stopped_instances": 10, + "total_instances": 10, + "total_memory_gb": 94, + "total_vcpu": 30 +} +``` diff --git a/docs/api/instance_start.md b/docs/api/instance_start.md new file mode 100644 index 0000000..8681039 --- /dev/null +++ b/docs/api/instance_start.md @@ -0,0 +1,38 @@ +# Initialize a Start-Up of a SINGLE Instance + +Sends a startup request to the AWS API for the specified instance id. + +`{instance-id}` is the **aws-power-toggle internal `id`, NOT the AWS `instance_id`** + +**URL** : `/api/v1/instance/{instance-id}/start` + +**Method** : `POST` + +## Success Response + +**Code** : `200 OK` + +## Example Request + +Given the following instance: +```json +{ + "id": "1aef6299109b", + "instance_id": "i-0008ad1bfd83a52eb", + "instance_type": "t3.xlarge", + "name": "kube-k8node2", + "state": "stopped", + "environment": "kube", + "vcpu": 4, + "memory_gb": 16 +} +``` + +Use the `id` field (**NOT the `instance_id` field**) to place the following request: +`/api/v1/instance/1aef6299109b/start` + +## Notes + +Responses vary depending on upstream AWS API +since we pass the exact aws response. +**This will be addressed in an upcomming release for consistency.** diff --git a/docs/api/instance_stop.md b/docs/api/instance_stop.md new file mode 100644 index 0000000..5118201 --- /dev/null +++ b/docs/api/instance_stop.md @@ -0,0 +1,38 @@ +# Initialize a Shutdown of a SINGLE Instance + +Sends a shutdown request to the AWS API for the specified instance id. + +`{instance-id}` is the **aws-power-toggle internal `id`, NOT the AWS `instance_id`** + +**URL** : `/api/v1/instance/{instance-id}/stop` + +**Method** : `POST` + +## Success Response + +**Code** : `200 OK` + +## Example Request + +Given the following instance: +```json +{ + "id": "1aef6299109b", + "instance_id": "i-0008ad1bfd83a52eb", + "instance_type": "t3.xlarge", + "name": "kube-k8node2", + "state": "running", + "environment": "kube", + "vcpu": 4, + "memory_gb": 16 +} +``` + +Use the `id` field (**NOT the `instance_id` field**) to place the following request: +`/api/v1/instance/1aef6299109b/stop` + +## Notes + +Responses vary depending on upstream AWS API +since we pass the exact aws response. +**This will be addressed in an upcomming release for consistency.** diff --git a/docs/api/refresh.md b/docs/api/refresh.md new file mode 100644 index 0000000..60da89c --- /dev/null +++ b/docs/api/refresh.md @@ -0,0 +1,29 @@ +# Refresh Environment Data + +Forces a refresh of the cached environment data. +Requests to this endpoint triggers an API call to the AWS API. + + +**URL** : `/api/v1/refresh` + +**Method** : `POST` + +## Success Response + +**Code** : `200 OK` + +**Example Response Body** + +```json +{ + "status": "OK" +} +``` + +## Notes + +The refresh is **NOT** environment specific, and affects the **entire cache.** + + +**The backend has an internal configurable timer that +also refreshes the cache periodically.** diff --git a/docs/api/version.md b/docs/api/version.md new file mode 100644 index 0000000..13d947d --- /dev/null +++ b/docs/api/version.md @@ -0,0 +1,38 @@ +# Get Version Information + +Retrieves the current running version of the backend server. +This includes release number, commit hash, and date of build. + + +**URL** : `/api/v1/version` + +**Method** : `GET` + +## Success Response + +**Code** : `200 OK` + +**Example Response Body** + +```json +{ + "version": "1.1", + "git_hash": "746c10e", + "build_date": "2018-11-24T23:21:02-0500" +} +``` + +## Notes + +The version information is passed in at compile time when using the make target: `make all` + +if the proper `ldflags` are not passed in during build, +then the following default content will be returned: + +```json +{ + "version": "devel", + "git_hash": "unknown", + "build_date": "unknown" +} +``` diff --git a/handlers.go b/handlers.go index d5c0010..73ca04a 100644 --- a/handlers.go +++ b/handlers.go @@ -1,7 +1,6 @@ package main import ( - "encoding/json" "fmt" "io/ioutil" "net/http" @@ -18,75 +17,108 @@ func handlerVersion(w http.ResponseWriter, req *http.Request) { fmt.Fprint(w, getVersionResponse()) } -// returns all envs -func handlerEnv(w http.ResponseWriter, req *http.Request) { +// handler for all environments +func handlerEnvAll(w http.ResponseWriter, req *http.Request) { + w.Header().Set("Content-Type", "application/json") - jData, err := json.Marshal(cachedTable) - if err != nil { - log.Errorf("error parsing json: %v", err) + // refresh the data + if err := refreshTable(); err != nil { + log.Errorf("refresh error: %v", err) + w.WriteHeader(http.StatusInternalServerError) + fmt.Fprintf(w, "{\"error\":\"%v\"}\n", err) + return + } + + // get vars from request to determine if environment id was specified + vars := mux.Vars(req) + group := vars["group"] + + // prepare result and return it + if response, err := getMarshalledRespone(cachedTable, group); err != nil { + w.WriteHeader(http.StatusInternalServerError) + fmt.Fprintf(w, "{\"error\":\"%v\"}\n", err) + } else { + w.Write(response) } - w.Header().Set("Content-Type", "application/json") - w.Write(jData) } -// returns summary of all envs -func handlerEnvSummary(w http.ResponseWriter, req *http.Request) { +// handler for single environment +func handlerEnvSingle(w http.ResponseWriter, req *http.Request) { + w.Header().Set("Content-Type", "application/json") // refresh the data if err := refreshTable(); err != nil { log.Errorf("refresh error: %v", err) + w.WriteHeader(http.StatusInternalServerError) fmt.Fprintf(w, "{\"error\":\"%v\"}\n", err) return } - // return result - jData, err := json.Marshal(getEnvSummary()) + // get vars from request to determine if environment id was specified + vars := mux.Vars(req) + envId := vars["env-id"] + group := vars["group"] + + // filter this environment id + envData, found := getEnvironmentById(envId) + if !found { + w.WriteHeader(http.StatusNotFound) + fmt.Fprintf(w, "{\"error\":\"environment not found\"}\n") + return + } + response, err := getMarshalledRespone(envData, group) + + // return filtered result if err != nil { - log.Errorf("error parsing json: %v", err) + w.WriteHeader(http.StatusInternalServerError) + fmt.Fprintf(w, "{\"error\":\"%v\"}\n", err) + } else { + w.Write(response) } - w.Header().Set("Content-Type", "application/json") - w.Write(jData) } -// handler to powerdown an env -func handlerEnvPowerdown(w http.ResponseWriter, req *http.Request) { - +// handler for power toggling an environment +func handlerEnvPowerToggle(w http.ResponseWriter, req *http.Request) { w.Header().Set("Content-Type", "application/json") // get vars from request to determine environment vars := mux.Vars(req) - envName := vars["env"] - - if envName != "" { - res, err := shutdownEnv(envName) - writeJsonResponse(w, err, res) - } else { + envId := vars["env-id"] + state := vars["state"] + + switch state { + case "start": + response, err := startupEnv(envId) + writeJsonResponse(w, err, response) + case "stop": + response, err := shutdownEnv(envId) + writeJsonResponse(w, err, response) + default: w.WriteHeader(http.StatusBadRequest) - fmt.Fprintf(w, "{\"error\":\"empty environment name\"}\n") + fmt.Fprintf(w, "{\"error\":\"invalid request\"}\n") } } -// handler to start up an env -func handlerEnvStartup(w http.ResponseWriter, req *http.Request) { - +// handler for power toggling an instance +func handlerInstancePowerToggle(w http.ResponseWriter, req *http.Request) { w.Header().Set("Content-Type", "application/json") // get vars from request to determine environment vars := mux.Vars(req) - envName := vars["env"] - log.Infof("starting env: %s", envName) + id := vars["instance-id"] + state := vars["state"] - if envName != "" { - res, err := startupEnv(envName) - writeJsonResponse(w, err, res) + if state == "start" || state == "stop" { + response, err := toggleInstance(id, state) + writeJsonResponse(w, err, response) } else { w.WriteHeader(http.StatusBadRequest) - fmt.Fprintf(w, "{\"error\":\"empty environment name\"}\n") + fmt.Fprintf(w, "{\"error\":\"invalid request\"}\n") } } -// handler to refresh envs -func handlerEnvRefresh(w http.ResponseWriter, req *http.Request) { +// handler to refresh cache +func handlerRefresh(w http.ResponseWriter, req *http.Request) { w.Header().Set("Content-Type", "application/json") if err := refreshTable(); err != nil { log.Errorf("refresh error: %v", err) @@ -97,6 +129,7 @@ func handlerEnvRefresh(w http.ResponseWriter, req *http.Request) { } } +// wrapper for json responses with error support func writeJsonResponse(w http.ResponseWriter, err error, response []byte) { if err == nil { w.WriteHeader(http.StatusOK) @@ -111,6 +144,7 @@ func writeJsonResponse(w http.ResponseWriter, err error, response []byte) { } } +// handler for main UI page func handlerMain(w http.ResponseWriter, req *http.Request) { // write the templated HTML w.WriteHeader(http.StatusOK) diff --git a/mock.go b/mock.go index 1104da9..9f98b82 100644 --- a/mock.go +++ b/mock.go @@ -11,7 +11,7 @@ import ( func mockRefreshTable() (err error) { // we only need to load initial test data when cachedTable is empty if len(cachedTable) == 0 { - cachedTableJsonFile, err := os.Open("testdata/mock_env_cachedTable.json") + cachedTableJsonFile, err := os.Open("testdata/mock/mock_env_cachedTable.json") if err != nil { log.Fatalf("mock API is enabled, but can't load test data: %s", err) } @@ -29,15 +29,15 @@ func mockRefreshTable() (err error) { } // mock of shutdownEnv -func mockShutdownEnv(envName string) (response []byte, err error) { - instanceIds := getInstanceIds(envName) +func mockShutdownEnv(envId string) (response []byte, err error) { + instanceIds := getInstanceIds(envId, "running") if len(instanceIds) > maxInstancesToShutdown { - err = fmt.Errorf("SAFETY: env [%s] has too many associated instances to shutdown %d", envName, len(instanceIds)) + err = fmt.Errorf("SAFETY: env [%s] has too many associated instances to shutdown %d", envId, len(instanceIds)) log.Debugf("SAFETY: instances: %v", instanceIds) } else if len(instanceIds) > 0 { // set all instances to stopped for e, env := range cachedTable { - if env.Name == envName { + if env.Id == envId { for i, _ := range cachedTable[e].Instances { cachedTable[e].Instances[i].State = "stopped" } @@ -45,21 +45,21 @@ func mockShutdownEnv(envName string) (response []byte, err error) { } } response = []byte(`{"mock": "OK"}`) - log.Infof("MOCK: successfully stopped env %s", envName) + log.Infof("MOCK: successfully stopped env %s", envId) } else { - err = fmt.Errorf("MOCK: env [%s] has no associated instances", envName) - log.Errorf("env [%s] has no associated instances", envName) + err = fmt.Errorf("MOCK: env [%s] has no associated instances", envId) + log.Errorf("env [%s] has no associated instances", envId) } return } // mock of startupEnv -func mockStartupEnv(envName string) (response []byte, err error) { - instanceIds := getInstanceIds(envName) +func mockStartupEnv(envId string) (response []byte, err error) { + instanceIds := getInstanceIds(envId, "stopped") if len(instanceIds) > 0 { // set all instances to running for e, env := range cachedTable { - if env.Name == envName { + if env.Id == envId { for i, _ := range cachedTable[e].Instances { cachedTable[e].Instances[i].State = "running" } @@ -67,10 +67,41 @@ func mockStartupEnv(envName string) (response []byte, err error) { } } response = []byte(`{"mock": "OK"}`) - log.Infof("MOCK: successfully started env %s", envName) + log.Infof("MOCK: successfully started env %s", envId) } else { - err = fmt.Errorf("MOCK: env [%s] has no associated instances", envName) - log.Errorf("MOCK: env [%s] has no associated instances", envName) + err = fmt.Errorf("MOCK: env [%s] has no associated instances", envId) + log.Errorf("MOCK: env [%s] has no associated instances", envId) + } + return +} + +// mock +func mockToggleInstance(id, desiredState string) (response []byte, err error) { + // validate desiredState + if desiredState != "start" && desiredState != "stop" { + err = fmt.Errorf("invalid desired state: %s", desiredState) + return + } + // get the AWS instance id + awsInstanceId := getAWSInstanceId(id) + if awsInstanceId != "" { + // set instance to desired state + for e, env := range cachedTable { + for i, instance := range env.Instances { + if instance.Id == id { + switch desiredState { + case "start": + cachedTable[e].Instances[i].State = "running" + case "stop": + cachedTable[e].Instances[i].State = "stopped" + } + break + } + } + } + response = []byte(`{"mock": "OK"}`) + } else { + err = fmt.Errorf("no mapping found between internal id (%s) and aws instance id", id) } return } diff --git a/router.go b/router.go index ab6e386..91b2733 100644 --- a/router.go +++ b/router.go @@ -1,12 +1,23 @@ package main import ( + "fmt" "net/http" "github.com/gorilla/mux" "github.com/spf13/viper" ) +const ( + ApiVersion = "1" + endpointFormat = "/api/v%s/%s" +) + +// getEndpoint returns a properly formatted API endpoint +func getEndpoint(suffix string) string { + return fmt.Sprintf(endpointFormat, ApiVersion, suffix) +} + type Route struct { Name string Method string @@ -16,47 +27,46 @@ type Route struct { type Routes []Route -// all defined api routes +// all defined server endpoints var routes = Routes{ // API endpoints Route{ "Version", "GET", - "/api/version", + getEndpoint("version"), handlerVersion, }, Route{ - "Environments", - "GET", - "/api/env", - handlerEnv, + "Refresh", + "POST", + getEndpoint("refresh"), + handlerRefresh, }, Route{ - "Environments", + "EnvAll", "GET", - "/api/env/summary", - handlerEnvSummary, + getEndpoint("env/{group:summary|details}"), + handlerEnvAll, }, Route{ - "Refresh", - "POST", - "/api/env/refresh", - handlerEnvRefresh, + "EnvSingle", + "GET", + getEndpoint("env/{env-id}/{group:summary|details}"), + handlerEnvSingle, }, Route{ - "StartUp", + "EnvPowerToggle", "POST", - "/api/env/startup/{env}", - handlerEnvStartup, + getEndpoint("env/{env-id}/{state:start|stop}"), + handlerEnvPowerToggle, }, Route{ - "PowerDown", + "InstancePowerToggle", "POST", - "/api/env/powerdown/{env}", - handlerEnvPowerdown, + getEndpoint("instance/{instance-id}/{state:start|stop}"), + handlerInstancePowerToggle, }, - // UI endpoints Route{ "Main", diff --git a/testdata/mock/mock_env_cachedTable.json b/testdata/mock/mock_env_cachedTable.json new file mode 100644 index 0000000..ad01cf7 --- /dev/null +++ b/testdata/mock/mock_env_cachedTable.json @@ -0,0 +1,2323 @@ +[ + { + "id": "56ae78d4805f", + "instances": [ + { + "environment": "mockenv1", + "instance_id": "i-0a5c68f08c53f5a81", + "instance_type": "c5.xlarge", + "memory_gb": 8, + "name": "mockenv1-org3peer4", + "state": "stopped", + "vcpu": 4 + }, + { + "environment": "mockenv1", + "instance_id": "i-0ab609a3c8fb70025", + "instance_type": "c5.xlarge", + "memory_gb": 8, + "name": "mockenv1-org3peer3", + "state": "stopped", + "vcpu": 4 + }, + { + "environment": "mockenv1", + "instance_id": "i-00061d4c8875b263d", + "instance_type": "c5.2xlarge", + "memory_gb": 16, + "name": "mockenv1-org2peer2", + "state": "stopped", + "vcpu": 8 + }, + { + "environment": "mockenv1", + "instance_id": "i-0d1fee52c9633fac6", + "instance_type": "c5.xlarge", + "memory_gb": 8, + "name": "mockenv1-org3peer1", + "state": "stopped", + "vcpu": 4 + }, + { + "environment": "mockenv1", + "instance_id": "i-04a4c3c42912783bf", + "instance_type": "c5.2xlarge", + "memory_gb": 16, + "name": "mockenv1-org3peer2", + "state": "stopped", + "vcpu": 8 + }, + { + "environment": "mockenv1", + "instance_id": "i-00b7f2acde2b257f4", + "instance_type": "t2.medium", + "memory_gb": 4, + "name": "mockenv1-kafka1", + "state": "stopped", + "vcpu": 2 + }, + { + "environment": "mockenv1", + "instance_id": "i-0f5dd015ec55df23d", + "instance_type": "c5.xlarge", + "memory_gb": 8, + "name": "mockenv1-org2peer3", + "state": "stopped", + "vcpu": 4 + }, + { + "environment": "mockenv1", + "instance_id": "i-01e281e66008412c5", + "instance_type": "c5.2xlarge", + "memory_gb": 16, + "name": "mockenv1-org4peer2", + "state": "stopped", + "vcpu": 8 + }, + { + "environment": "mockenv1", + "instance_id": "i-023d466a8c9802aed", + "instance_type": "t2.2xlarge", + "memory_gb": 32, + "name": "mockenv1-admin", + "state": "stopped", + "vcpu": 8 + }, + { + "environment": "mockenv1", + "instance_id": "i-0a7e0901d8a388830", + "instance_type": "c5.xlarge", + "memory_gb": 8, + "name": "mockenv1-org2peer1", + "state": "stopped", + "vcpu": 4 + }, + { + "environment": "mockenv1", + "instance_id": "i-00e9d9726ae79b57c", + "instance_type": "c5.xlarge", + "memory_gb": 8, + "name": "mockenv1-org4peer5", + "state": "stopped", + "vcpu": 4 + }, + { + "environment": "mockenv1", + "instance_id": "i-067d9e1b712c97808", + "instance_type": "t2.micro", + "memory_gb": 1, + "name": "mockenv1-orderer1", + "state": "stopped", + "vcpu": 1 + }, + { + "environment": "mockenv1", + "instance_id": "i-0607964069781218d", + "instance_type": "c5.xlarge", + "memory_gb": 8, + "name": "mockenv1-org3peer5", + "state": "stopped", + "vcpu": 4 + }, + { + "environment": "mockenv1", + "instance_id": "i-0b9dff025ebe98954", + "instance_type": "c5.xlarge", + "memory_gb": 8, + "name": "mockenv1-org2peer4", + "state": "stopped", + "vcpu": 4 + }, + { + "environment": "mockenv1", + "instance_id": "i-0db1f3649cc30252a", + "instance_type": "c5.xlarge", + "memory_gb": 8, + "name": "mockenv1-org1peer1", + "state": "stopped", + "vcpu": 4 + }, + { + "environment": "mockenv1", + "instance_id": "i-006cbdad6c27666b5", + "instance_type": "c5.xlarge", + "memory_gb": 8, + "name": "mockenv1-org1peer5", + "state": "stopped", + "vcpu": 4 + }, + { + "environment": "mockenv1", + "instance_id": "i-0b635062614f41902", + "instance_type": "c5.xlarge", + "memory_gb": 8, + "name": "mockenv1-org1peer4", + "state": "stopped", + "vcpu": 4 + }, + { + "environment": "mockenv1", + "instance_id": "i-0ce165e54c97354af", + "instance_type": "c5.2xlarge", + "memory_gb": 16, + "name": "mockenv1-org1peer2", + "state": "stopped", + "vcpu": 8 + }, + { + "environment": "mockenv1", + "instance_id": "i-092bf46daa1ba864d", + "instance_type": "t2.micro", + "memory_gb": 1, + "name": "mockenv1-orderer2", + "state": "stopped", + "vcpu": 1 + }, + { + "environment": "mockenv1", + "instance_id": "i-007fe1dee4659994d", + "instance_type": "t2.small", + "memory_gb": 2, + "name": "mockenv1-zoo2", + "state": "stopped", + "vcpu": 1 + }, + { + "environment": "mockenv1", + "instance_id": "i-02a865c984a00457b", + "instance_type": "c5.xlarge", + "memory_gb": 8, + "name": "mockenv1-org4peer3", + "state": "stopped", + "vcpu": 4 + }, + { + "environment": "mockenv1", + "instance_id": "i-0fcd4b9773bd76d98", + "instance_type": "t2.medium", + "memory_gb": 4, + "name": "mockenv1-kafka2", + "state": "stopped", + "vcpu": 2 + }, + { + "environment": "mockenv1", + "instance_id": "i-0537759a63512bbb7", + "instance_type": "c5.xlarge", + "memory_gb": 8, + "name": "mockenv1-org4peer1", + "state": "stopped", + "vcpu": 4 + }, + { + "environment": "mockenv1", + "instance_id": "i-081c2a979f70ef34e", + "instance_type": "c5.xlarge", + "memory_gb": 8, + "name": "mockenv1-org4peer4", + "state": "stopped", + "vcpu": 4 + }, + { + "environment": "mockenv1", + "instance_id": "i-03e949f0b8df6b8fa", + "instance_type": "c5.xlarge", + "memory_gb": 8, + "name": "mockenv1-org1peer3", + "state": "stopped", + "vcpu": 4 + }, + { + "environment": "mockenv1", + "instance_id": "i-06ec7f5c26d0a21ac", + "instance_type": "t2.small", + "memory_gb": 2, + "name": "mockenv1-zoo1", + "state": "stopped", + "vcpu": 1 + }, + { + "environment": "mockenv1", + "instance_id": "i-04b0e0df81ddbf819", + "instance_type": "c5.xlarge", + "memory_gb": 8, + "name": "mockenv1-org2peer5", + "state": "stopped", + "vcpu": 4 + } + ], + "name": "mockenv1", + "provider": "aws", + "region": "ca-central-1", + "running_instances": 0, + "state": "stopped", + "stopped_instances": 27, + "total_instances": 27, + "total_memory_gb": 238, + "total_vcpu": 112 + }, + { + "id": "75e4e1a93a3b", + "instances": [ + { + "environment": "mockenv2", + "instance_id": "i-0655e4242278bf53c", + "instance_type": "t2.small", + "memory_gb": 2, + "name": "mockenv2-org3admin", + "state": "stopped", + "vcpu": 1 + }, + { + "environment": "mockenv2", + "instance_id": "i-0beb81b9b12b095bd", + "instance_type": "t2.small", + "memory_gb": 2, + "name": "mockenv2-org5app2", + "state": "stopped", + "vcpu": 1 + }, + { + "environment": "mockenv2", + "instance_id": "i-047abbc75e0df27c0", + "instance_type": "t2.micro", + "memory_gb": 1, + "name": "mockenv2-org6ca1", + "state": "stopped", + "vcpu": 1 + }, + { + "environment": "mockenv2", + "instance_id": "i-011b515645ad4dc00", + "instance_type": "t2.small", + "memory_gb": 2, + "name": "mockenv2-kafka2", + "state": "stopped", + "vcpu": 1 + }, + { + "environment": "mockenv2", + "instance_id": "i-090b1a428ec4bf9eb", + "instance_type": "t2.micro", + "memory_gb": 1, + "name": "mockenv2-org4ca1", + "state": "stopped", + "vcpu": 1 + }, + { + "environment": "mockenv2", + "instance_id": "i-0e7abdd4b4081803d", + "instance_type": "t2.small", + "memory_gb": 2, + "name": "mockenv2-org6admin", + "state": "stopped", + "vcpu": 1 + }, + { + "environment": "mockenv2", + "instance_id": "i-0a89bd1a56bd3fd9f", + "instance_type": "c5.large", + "memory_gb": 4, + "name": "mockenv2-org3peer2", + "state": "stopped", + "vcpu": 2 + }, + { + "environment": "mockenv2", + "instance_id": "i-097f9c01c92880f4a", + "instance_type": "t2.small", + "memory_gb": 2, + "name": "mockenv2-org4admin", + "state": "stopped", + "vcpu": 1 + }, + { + "environment": "mockenv2", + "instance_id": "i-058935adf9d3e022d", + "instance_type": "t2.small", + "memory_gb": 2, + "name": "mockenv2-org5app1", + "state": "stopped", + "vcpu": 1 + }, + { + "environment": "mockenv2", + "instance_id": "i-0e3e419c9c5c5b033", + "instance_type": "t2.small", + "memory_gb": 2, + "name": "mockenv2-orderer2", + "state": "stopped", + "vcpu": 1 + }, + { + "environment": "mockenv2", + "instance_id": "i-0a345f92722456c2d", + "instance_type": "t2.micro", + "memory_gb": 1, + "name": "mockenv2-org4ca2", + "state": "stopped", + "vcpu": 1 + }, + { + "environment": "mockenv2", + "instance_id": "i-0963676849262ad9b", + "instance_type": "t2.small", + "memory_gb": 2, + "name": "mockenv2-org2app1", + "state": "stopped", + "vcpu": 1 + }, + { + "environment": "mockenv2", + "instance_id": "i-0a36afd331e1c8707", + "instance_type": "t2.small", + "memory_gb": 2, + "name": "mockenv2-org4app1", + "state": "stopped", + "vcpu": 1 + }, + { + "environment": "mockenv2", + "instance_id": "i-0473f26821165011b", + "instance_type": "t2.micro", + "memory_gb": 1, + "name": "mockenv2-admin", + "state": "stopped", + "vcpu": 1 + }, + { + "environment": "mockenv2", + "instance_id": "i-0275344d2e6448169", + "instance_type": "t2.small", + "memory_gb": 2, + "name": "mockenv2-zoo2", + "state": "stopped", + "vcpu": 1 + }, + { + "environment": "mockenv2", + "instance_id": "i-0fedcaac13e21f830", + "instance_type": "t2.small", + "memory_gb": 2, + "name": "mockenv2-org2app2", + "state": "stopped", + "vcpu": 1 + }, + { + "environment": "mockenv2", + "instance_id": "i-045641ef1ced05a75", + "instance_type": "t2.micro", + "memory_gb": 1, + "name": "mockenv2-org5ca1", + "state": "stopped", + "vcpu": 1 + }, + { + "environment": "mockenv2", + "instance_id": "i-03cf891551793bb19", + "instance_type": "c5.large", + "memory_gb": 4, + "name": "mockenv2-org4peer2", + "state": "stopped", + "vcpu": 2 + }, + { + "environment": "mockenv2", + "instance_id": "i-0daaed23ff0e0863c", + "instance_type": "t2.small", + "memory_gb": 2, + "name": "mockenv2-zoo1", + "state": "stopped", + "vcpu": 1 + }, + { + "environment": "mockenv2", + "instance_id": "i-020bd33c68e581b66", + "instance_type": "t2.small", + "memory_gb": 2, + "name": "mockenv2-orderer1", + "state": "stopped", + "vcpu": 1 + }, + { + "environment": "mockenv2", + "instance_id": "i-03300f1580f195ae2", + "instance_type": "t2.micro", + "memory_gb": 1, + "name": "mockenv2-org1ca1", + "state": "stopped", + "vcpu": 1 + }, + { + "environment": "mockenv2", + "instance_id": "i-0203967889caf3e6e", + "instance_type": "c5.large", + "memory_gb": 4, + "name": "mockenv2-org6peer2", + "state": "stopped", + "vcpu": 2 + }, + { + "environment": "mockenv2", + "instance_id": "i-0ec603a71d27d4f0f", + "instance_type": "c5.large", + "memory_gb": 4, + "name": "mockenv2-org5peer1", + "state": "stopped", + "vcpu": 2 + }, + { + "environment": "mockenv2", + "instance_id": "i-0416dd9eceedf6c15", + "instance_type": "c5.large", + "memory_gb": 4, + "name": "mockenv2-org6peer1", + "state": "stopped", + "vcpu": 2 + }, + { + "environment": "mockenv2", + "instance_id": "i-0e0a36c172e5b77d4", + "instance_type": "t2.small", + "memory_gb": 2, + "name": "mockenv2-org4app2", + "state": "stopped", + "vcpu": 1 + }, + { + "environment": "mockenv2", + "instance_id": "i-035852a154db41563", + "instance_type": "t2.small", + "memory_gb": 2, + "name": "mockenv2-zoo3", + "state": "stopped", + "vcpu": 1 + }, + { + "environment": "mockenv2", + "instance_id": "i-01b1e49f8934e18ea", + "instance_type": "t2.small", + "memory_gb": 2, + "name": "mockenv2-kafka1", + "state": "stopped", + "vcpu": 1 + }, + { + "environment": "mockenv2", + "instance_id": "i-020627cfcce463843", + "instance_type": "t2.small", + "memory_gb": 2, + "name": "mockenv2-org2admin", + "state": "stopped", + "vcpu": 1 + }, + { + "environment": "mockenv2", + "instance_id": "i-061d3922415a19815", + "instance_type": "t2.small", + "memory_gb": 2, + "name": "mockenv2-org5admin", + "state": "stopped", + "vcpu": 1 + }, + { + "environment": "mockenv2", + "instance_id": "i-034562753e3a38e68", + "instance_type": "t2.micro", + "memory_gb": 1, + "name": "mockenv2-org6ca2", + "state": "stopped", + "vcpu": 1 + }, + { + "environment": "mockenv2", + "instance_id": "i-0f5b5445292b07afc", + "instance_type": "c5.large", + "memory_gb": 4, + "name": "mockenv2-org2peer2", + "state": "stopped", + "vcpu": 2 + }, + { + "environment": "mockenv2", + "instance_id": "i-0cf3a247c4fabf863", + "instance_type": "t2.small", + "memory_gb": 2, + "name": "mockenv2-kafka3", + "state": "stopped", + "vcpu": 1 + }, + { + "environment": "mockenv2", + "instance_id": "i-065a19d641e34e950", + "instance_type": "t2.micro", + "memory_gb": 1, + "name": "mockenv2-org2ca1", + "state": "stopped", + "vcpu": 1 + }, + { + "environment": "mockenv2", + "instance_id": "i-0015edfc2a8cccc6d", + "instance_type": "t2.micro", + "memory_gb": 1, + "name": "mockenv2-org5ca2", + "state": "stopped", + "vcpu": 1 + }, + { + "environment": "mockenv2", + "instance_id": "i-0a94c398e3526a635", + "instance_type": "t2.small", + "memory_gb": 2, + "name": "mockenv2-kafka4", + "state": "stopped", + "vcpu": 1 + }, + { + "environment": "mockenv2", + "instance_id": "i-0d253caf816c362fb", + "instance_type": "t2.small", + "memory_gb": 2, + "name": "mockenv2-org1admin", + "state": "stopped", + "vcpu": 1 + }, + { + "environment": "mockenv2", + "instance_id": "i-09529203675e50ba4", + "instance_type": "c5.large", + "memory_gb": 4, + "name": "mockenv2-org1peer1", + "state": "stopped", + "vcpu": 2 + }, + { + "environment": "mockenv2", + "instance_id": "i-0b24846f4a1d19177", + "instance_type": "c5.large", + "memory_gb": 4, + "name": "mockenv2-org3peer1", + "state": "stopped", + "vcpu": 2 + }, + { + "environment": "mockenv2", + "instance_id": "i-0adf79a2e32e0bca8", + "instance_type": "t2.micro", + "memory_gb": 1, + "name": "mockenv2-org1ca2", + "state": "stopped", + "vcpu": 1 + }, + { + "environment": "mockenv2", + "instance_id": "i-096a5f9780c78dcfb", + "instance_type": "t2.small", + "memory_gb": 2, + "name": "mockenv2-org3app2", + "state": "stopped", + "vcpu": 1 + }, + { + "environment": "mockenv2", + "instance_id": "i-0b8b0192c8e989471", + "instance_type": "c5.large", + "memory_gb": 4, + "name": "mockenv2-org4peer1", + "state": "stopped", + "vcpu": 2 + }, + { + "environment": "mockenv2", + "instance_id": "i-07d051737f3ac0937", + "instance_type": "c5.large", + "memory_gb": 4, + "name": "mockenv2-org1peer2", + "state": "stopped", + "vcpu": 2 + }, + { + "environment": "mockenv2", + "instance_id": "i-0adee2dbd9228b2cb", + "instance_type": "t2.micro", + "memory_gb": 1, + "name": "mockenv2-org3ca1", + "state": "stopped", + "vcpu": 1 + }, + { + "environment": "mockenv2", + "instance_id": "i-0175ff2b9410c5d4e", + "instance_type": "t2.small", + "memory_gb": 2, + "name": "mockenv2-org6app1", + "state": "stopped", + "vcpu": 1 + }, + { + "environment": "mockenv2", + "instance_id": "i-06113a14aa50fc45b", + "instance_type": "t2.micro", + "memory_gb": 1, + "name": "mockenv2-org3ca2", + "state": "stopped", + "vcpu": 1 + }, + { + "environment": "mockenv2", + "instance_id": "i-0e14f1405355c4da9", + "instance_type": "t2.micro", + "memory_gb": 1, + "name": "mockenv2-org2ca2", + "state": "stopped", + "vcpu": 1 + }, + { + "environment": "mockenv2", + "instance_id": "i-042d6e25f9758773b", + "instance_type": "t2.small", + "memory_gb": 2, + "name": "mockenv2-org6app2", + "state": "stopped", + "vcpu": 1 + }, + { + "environment": "mockenv2", + "instance_id": "i-0a1a722c320915c3d", + "instance_type": "t2.small", + "memory_gb": 2, + "name": "mockenv2-org1app2", + "state": "stopped", + "vcpu": 1 + }, + { + "environment": "mockenv2", + "instance_id": "i-0f7faa94638ccef20", + "instance_type": "t2.small", + "memory_gb": 2, + "name": "mockenv2-orderer3", + "state": "stopped", + "vcpu": 1 + }, + { + "environment": "mockenv2", + "instance_id": "i-0b23ddf592991b8ee", + "instance_type": "t2.small", + "memory_gb": 2, + "name": "mockenv2-org3app1", + "state": "stopped", + "vcpu": 1 + }, + { + "environment": "mockenv2", + "instance_id": "i-0ccc10ef212856dd3", + "instance_type": "c5.large", + "memory_gb": 4, + "name": "mockenv2-org2peer1", + "state": "stopped", + "vcpu": 2 + }, + { + "environment": "mockenv2", + "instance_id": "i-0e528e724ceef797b", + "instance_type": "t2.small", + "memory_gb": 2, + "name": "mockenv2-org1app1", + "state": "stopped", + "vcpu": 1 + }, + { + "environment": "mockenv2", + "instance_id": "i-009f5086307f4e57c", + "instance_type": "c5.large", + "memory_gb": 4, + "name": "mockenv2-org5peer2", + "state": "stopped", + "vcpu": 2 + } + ], + "name": "mockenv2", + "provider": "aws", + "region": "ca-central-1", + "running_instances": 0, + "state": "stopped", + "stopped_instances": 53, + "total_instances": 53, + "total_memory_gb": 117, + "total_vcpu": 65 + }, + { + "id": "3e8ddd1274b4", + "instances": [ + { + "environment": "mockenv3", + "instance_id": "i-04a0c55913889362d", + "instance_type": "t2.medium", + "memory_gb": 4, + "name": "mockenv3-org2app1", + "state": "stopped", + "vcpu": 2 + }, + { + "environment": "mockenv3", + "instance_id": "i-0b5eb71f782dc761a", + "instance_type": "c5.2xlarge", + "memory_gb": 16, + "name": "mockenv3-org3couchdb1", + "state": "stopped", + "vcpu": 8 + }, + { + "environment": "mockenv3", + "instance_id": "i-04d62321c72da87d8", + "instance_type": "t2.medium", + "memory_gb": 4, + "name": "mockenv3-org4app1", + "state": "stopped", + "vcpu": 2 + }, + { + "environment": "mockenv3", + "instance_id": "i-0e992c1a81a293ff6", + "instance_type": "c5.2xlarge", + "memory_gb": 16, + "name": "mockenv3-org3peer3", + "state": "stopped", + "vcpu": 8 + }, + { + "environment": "mockenv3", + "instance_id": "i-041ec7c305cbb61db", + "instance_type": "t2.micro", + "memory_gb": 1, + "name": "mockenv3-org3ca1", + "state": "stopped", + "vcpu": 1 + }, + { + "environment": "mockenv3", + "instance_id": "i-0cbca67848c5c8db8", + "instance_type": "t2.medium", + "memory_gb": 4, + "name": "mockenv3-org1app2", + "state": "stopped", + "vcpu": 2 + }, + { + "environment": "mockenv3", + "instance_id": "i-077bcb143f38cbcfe", + "instance_type": "c5.xlarge", + "memory_gb": 8, + "name": "mockenv3-org2admin", + "state": "stopped", + "vcpu": 4 + }, + { + "environment": "mockenv3", + "instance_id": "i-04d04ff500e6521af", + "instance_type": "c5.2xlarge", + "memory_gb": 16, + "name": "mockenv3-org3peer4", + "state": "stopped", + "vcpu": 8 + }, + { + "environment": "mockenv3", + "instance_id": "i-0ed6ffc835322e749", + "instance_type": "c5.2xlarge", + "memory_gb": 16, + "name": "mockenv3-org3peer1", + "state": "stopped", + "vcpu": 8 + }, + { + "environment": "mockenv3", + "instance_id": "i-0f8ab29b72c5a05a5", + "instance_type": "c5.2xlarge", + "memory_gb": 16, + "name": "mockenv3-org6couchdb1", + "state": "stopped", + "vcpu": 8 + }, + { + "environment": "mockenv3", + "instance_id": "i-0b7077e7a39e2eec7", + "instance_type": "t2.medium", + "memory_gb": 4, + "name": "mockenv3-org3app2", + "state": "stopped", + "vcpu": 2 + }, + { + "environment": "mockenv3", + "instance_id": "i-03bfff149eab04a22", + "instance_type": "c5.2xlarge", + "memory_gb": 16, + "name": "mockenv3-org5peer2", + "state": "stopped", + "vcpu": 8 + }, + { + "environment": "mockenv3", + "instance_id": "i-086100c7d2aa948c3", + "instance_type": "c5.2xlarge", + "memory_gb": 16, + "name": "mockenv3-org1couchdb1", + "state": "stopped", + "vcpu": 8 + }, + { + "environment": "mockenv3", + "instance_id": "i-0b3b9ba0054811960", + "instance_type": "c5.2xlarge", + "memory_gb": 16, + "name": "mockenv3-org4peer3", + "state": "stopped", + "vcpu": 8 + }, + { + "environment": "mockenv3", + "instance_id": "i-0205dd65fafa04b52", + "instance_type": "c5.2xlarge", + "memory_gb": 16, + "name": "mockenv3-org2peer1", + "state": "stopped", + "vcpu": 8 + }, + { + "environment": "mockenv3", + "instance_id": "i-00cb37df46a3a1b9c", + "instance_type": "c5.2xlarge", + "memory_gb": 16, + "name": "mockenv3-org6couchdb3", + "state": "stopped", + "vcpu": 8 + }, + { + "environment": "mockenv3", + "instance_id": "i-04c26fe5fa5a461f6", + "instance_type": "t2.micro", + "memory_gb": 1, + "name": "mockenv3-org1ca1", + "state": "stopped", + "vcpu": 1 + }, + { + "environment": "mockenv3", + "instance_id": "i-0f457f643e5600eed", + "instance_type": "t2.medium", + "memory_gb": 4, + "name": "mockenv3-org2app2", + "state": "stopped", + "vcpu": 2 + }, + { + "environment": "mockenv3", + "instance_id": "i-0dce8b6aef982df76", + "instance_type": "c5.xlarge", + "memory_gb": 8, + "name": "mockenv3-org4admin", + "state": "stopped", + "vcpu": 4 + }, + { + "environment": "mockenv3", + "instance_id": "i-0d7e29155113217d0", + "instance_type": "c5.2xlarge", + "memory_gb": 16, + "name": "mockenv3-org3peer2", + "state": "stopped", + "vcpu": 8 + }, + { + "environment": "mockenv3", + "instance_id": "i-0ee9e80cfc74a0898", + "instance_type": "t2.micro", + "memory_gb": 1, + "name": "mockenv3-org2ca2", + "state": "stopped", + "vcpu": 1 + }, + { + "environment": "mockenv3", + "instance_id": "i-0f390537f4bb2c526", + "instance_type": "t2.medium", + "memory_gb": 4, + "name": "mockenv3-org5app2", + "state": "stopped", + "vcpu": 2 + }, + { + "environment": "mockenv3", + "instance_id": "i-0f235911b547bfe34", + "instance_type": "c5.2xlarge", + "memory_gb": 16, + "name": "mockenv3-org1couchdb3", + "state": "stopped", + "vcpu": 8 + }, + { + "environment": "mockenv3", + "instance_id": "i-0401cae45aeca3f7a", + "instance_type": "t2.micro", + "memory_gb": 1, + "name": "mockenv3-org1ca2", + "state": "stopped", + "vcpu": 1 + }, + { + "environment": "mockenv3", + "instance_id": "i-0545fcc68d9aec05d", + "instance_type": "c5.2xlarge", + "memory_gb": 16, + "name": "mockenv3-org5peer4", + "state": "stopped", + "vcpu": 8 + }, + { + "environment": "mockenv3", + "instance_id": "i-0f854d7467340384a", + "instance_type": "c5.2xlarge", + "memory_gb": 16, + "name": "mockenv3-org5couchdb2", + "state": "stopped", + "vcpu": 8 + }, + { + "environment": "mockenv3", + "instance_id": "i-09947283d689501ed", + "instance_type": "c5.xlarge", + "memory_gb": 8, + "name": "mockenv3-org5admin", + "state": "stopped", + "vcpu": 4 + }, + { + "environment": "mockenv3", + "instance_id": "i-0a91741855fd8d21b", + "instance_type": "t2.small", + "memory_gb": 2, + "name": "mockenv3-kafka2", + "state": "stopped", + "vcpu": 1 + }, + { + "environment": "mockenv3", + "instance_id": "i-0ee85ded758bbb133", + "instance_type": "t2.medium", + "memory_gb": 4, + "name": "mockenv3-org5app1", + "state": "stopped", + "vcpu": 2 + }, + { + "environment": "mockenv3", + "instance_id": "i-0d1203b346e6f3a8b", + "instance_type": "t2.micro", + "memory_gb": 1, + "name": "mockenv3-org6ca1", + "state": "stopped", + "vcpu": 1 + }, + { + "environment": "mockenv3", + "instance_id": "i-0899f1bdba6104271", + "instance_type": "c5.xlarge", + "memory_gb": 8, + "name": "mockenv3-org1admin", + "state": "stopped", + "vcpu": 4 + }, + { + "environment": "mockenv3", + "instance_id": "i-04e6cd6c653b9703f", + "instance_type": "c5.2xlarge", + "memory_gb": 16, + "name": "mockenv3-org4couchdb2", + "state": "stopped", + "vcpu": 8 + }, + { + "environment": "mockenv3", + "instance_id": "i-00717355a5b09d92d", + "instance_type": "c5.2xlarge", + "memory_gb": 16, + "name": "mockenv3-org1peer4", + "state": "stopped", + "vcpu": 8 + }, + { + "environment": "mockenv3", + "instance_id": "i-08bab54792edb3108", + "instance_type": "c5.2xlarge", + "memory_gb": 16, + "name": "mockenv3-org1peer1", + "state": "stopped", + "vcpu": 8 + }, + { + "environment": "mockenv3", + "instance_id": "i-0e5b44c3c8d46d40a", + "instance_type": "t2.micro", + "memory_gb": 1, + "name": "mockenv3-org4ca1", + "state": "stopped", + "vcpu": 1 + }, + { + "environment": "mockenv3", + "instance_id": "i-0528bfb7a1373cb75", + "instance_type": "t2.micro", + "memory_gb": 1, + "name": "mockenv3-admin", + "state": "stopped", + "vcpu": 1 + }, + { + "environment": "mockenv3", + "instance_id": "i-0ee88bbe88e410e73", + "instance_type": "t2.micro", + "memory_gb": 1, + "name": "mockenv3-org3ca2", + "state": "stopped", + "vcpu": 1 + }, + { + "environment": "mockenv3", + "instance_id": "i-00cf5cc42d686b39c", + "instance_type": "c5.2xlarge", + "memory_gb": 16, + "name": "mockenv3-org1peer3", + "state": "stopped", + "vcpu": 8 + }, + { + "environment": "mockenv3", + "instance_id": "i-018c532ea8ab6b5ef", + "instance_type": "c5.2xlarge", + "memory_gb": 16, + "name": "mockenv3-org1couchdb2", + "state": "stopped", + "vcpu": 8 + }, + { + "environment": "mockenv3", + "instance_id": "i-0cb53cad9d5c130a4", + "instance_type": "t2.small", + "memory_gb": 2, + "name": "mockenv3-kafka3", + "state": "stopped", + "vcpu": 1 + }, + { + "environment": "mockenv3", + "instance_id": "i-0dc93c407b06e3829", + "instance_type": "t2.small", + "memory_gb": 2, + "name": "mockenv3-zoo1", + "state": "stopped", + "vcpu": 1 + }, + { + "environment": "mockenv3", + "instance_id": "i-078797fa4054f26f8", + "instance_type": "c5.2xlarge", + "memory_gb": 16, + "name": "mockenv3-org4peer4", + "state": "stopped", + "vcpu": 8 + }, + { + "environment": "mockenv3", + "instance_id": "i-02db01c3e4f8af91c", + "instance_type": "t2.micro", + "memory_gb": 1, + "name": "mockenv3-org4ca2", + "state": "stopped", + "vcpu": 1 + }, + { + "environment": "mockenv3", + "instance_id": "i-03701407b8e15e994", + "instance_type": "t2.small", + "memory_gb": 2, + "name": "mockenv3-kafka1", + "state": "stopped", + "vcpu": 1 + }, + { + "environment": "mockenv3", + "instance_id": "i-0879eea460a169142", + "instance_type": "c5.2xlarge", + "memory_gb": 16, + "name": "mockenv3-org5peer1", + "state": "stopped", + "vcpu": 8 + }, + { + "environment": "mockenv3", + "instance_id": "i-07a9303107eced81a", + "instance_type": "c5.2xlarge", + "memory_gb": 16, + "name": "mockenv3-org6peer2", + "state": "stopped", + "vcpu": 8 + }, + { + "environment": "mockenv3", + "instance_id": "i-09cc94659bb0d55d1", + "instance_type": "t2.micro", + "memory_gb": 1, + "name": "mockenv3-org5ca2", + "state": "stopped", + "vcpu": 1 + }, + { + "environment": "mockenv3", + "instance_id": "i-0b200d1501d25b189", + "instance_type": "t2.micro", + "memory_gb": 1, + "name": "mockenv3-orderer2", + "state": "stopped", + "vcpu": 1 + }, + { + "environment": "mockenv3", + "instance_id": "i-006e41966ec273d5c", + "instance_type": "c5.xlarge", + "memory_gb": 8, + "name": "mockenv3-org6admin", + "state": "stopped", + "vcpu": 4 + }, + { + "environment": "mockenv3", + "instance_id": "i-07fa42e247e7e4db1", + "instance_type": "t2.micro", + "memory_gb": 1, + "name": "mockenv3-orderer1", + "state": "stopped", + "vcpu": 1 + }, + { + "environment": "mockenv3", + "instance_id": "i-02b321c4b35f6bc7b", + "instance_type": "t2.micro", + "memory_gb": 1, + "name": "mockenv3-org2ca1", + "state": "stopped", + "vcpu": 1 + }, + { + "environment": "mockenv3", + "instance_id": "i-07249f14c67c1f620", + "instance_type": "c5.2xlarge", + "memory_gb": 16, + "name": "mockenv3-org4peer1", + "state": "stopped", + "vcpu": 8 + }, + { + "environment": "mockenv3", + "instance_id": "i-0356839e916342f5f", + "instance_type": "c5.2xlarge", + "memory_gb": 16, + "name": "mockenv3-org2couchdb3", + "state": "stopped", + "vcpu": 8 + }, + { + "environment": "mockenv3", + "instance_id": "i-0b582a96eea58a0a8", + "instance_type": "c5.2xlarge", + "memory_gb": 16, + "name": "mockenv3-org4peer2", + "state": "stopped", + "vcpu": 8 + }, + { + "environment": "mockenv3", + "instance_id": "i-0161984571e97ed45", + "instance_type": "c5.2xlarge", + "memory_gb": 16, + "name": "mockenv3-org5peer3", + "state": "stopped", + "vcpu": 8 + }, + { + "environment": "mockenv3", + "instance_id": "i-08fbe3e5549c08451", + "instance_type": "c5.2xlarge", + "memory_gb": 16, + "name": "mockenv3-org2peer4", + "state": "stopped", + "vcpu": 8 + }, + { + "environment": "mockenv3", + "instance_id": "i-089c5c96127b0edc4", + "instance_type": "c5.xlarge", + "memory_gb": 8, + "name": "mockenv3-org3admin", + "state": "stopped", + "vcpu": 4 + }, + { + "environment": "mockenv3", + "instance_id": "i-0a0b3a0b84f8594d1", + "instance_type": "c5.2xlarge", + "memory_gb": 16, + "name": "mockenv3-org4couchdb1", + "state": "stopped", + "vcpu": 8 + }, + { + "environment": "mockenv3", + "instance_id": "i-0c21480388f04fffa", + "instance_type": "c5.2xlarge", + "memory_gb": 16, + "name": "mockenv3-org6couchdb2", + "state": "stopped", + "vcpu": 8 + }, + { + "environment": "mockenv3", + "instance_id": "i-020313c05c70c7661", + "instance_type": "c5.2xlarge", + "memory_gb": 16, + "name": "mockenv3-org5couchdb3", + "state": "stopped", + "vcpu": 8 + }, + { + "environment": "mockenv3", + "instance_id": "i-0d7ea2bd3066f9d24", + "instance_type": "t2.small", + "memory_gb": 2, + "name": "mockenv3-zoo2", + "state": "stopped", + "vcpu": 1 + }, + { + "environment": "mockenv3", + "instance_id": "i-0434f16f019623890", + "instance_type": "c5.2xlarge", + "memory_gb": 16, + "name": "mockenv3-org2peer2", + "state": "stopped", + "vcpu": 8 + }, + { + "environment": "mockenv3", + "instance_id": "i-09e3660555eebe3d7", + "instance_type": "t2.medium", + "memory_gb": 4, + "name": "mockenv3-org6app1", + "state": "stopped", + "vcpu": 2 + }, + { + "environment": "mockenv3", + "instance_id": "i-089f46ea175744c99", + "instance_type": "c5.2xlarge", + "memory_gb": 16, + "name": "mockenv3-org2couchdb1", + "state": "stopped", + "vcpu": 8 + }, + { + "environment": "mockenv3", + "instance_id": "i-05bc3fba82b4c798b", + "instance_type": "t2.micro", + "memory_gb": 1, + "name": "mockenv3-org6ca2", + "state": "stopped", + "vcpu": 1 + }, + { + "environment": "mockenv3", + "instance_id": "i-0525d9ec317111755", + "instance_type": "t2.medium", + "memory_gb": 4, + "name": "mockenv3-org4app2", + "state": "stopped", + "vcpu": 2 + }, + { + "environment": "mockenv3", + "instance_id": "i-09dac5f53e4d100da", + "instance_type": "t2.small", + "memory_gb": 2, + "name": "mockenv3-kafka4", + "state": "stopped", + "vcpu": 1 + }, + { + "environment": "mockenv3", + "instance_id": "i-0338c2fa2043749b3", + "instance_type": "c5.2xlarge", + "memory_gb": 16, + "name": "mockenv3-org1peer2", + "state": "stopped", + "vcpu": 8 + }, + { + "environment": "mockenv3", + "instance_id": "i-0ca6aff28e4f09ea2", + "instance_type": "t2.micro", + "memory_gb": 1, + "name": "mockenv3-org5ca1", + "state": "stopped", + "vcpu": 1 + }, + { + "environment": "mockenv3", + "instance_id": "i-030aff848e70dd91d", + "instance_type": "c5.2xlarge", + "memory_gb": 16, + "name": "mockenv3-org2couchdb2", + "state": "stopped", + "vcpu": 8 + }, + { + "environment": "mockenv3", + "instance_id": "i-0ff59189bf3e18e97", + "instance_type": "c5.2xlarge", + "memory_gb": 16, + "name": "mockenv3-org6peer4", + "state": "stopped", + "vcpu": 8 + }, + { + "environment": "mockenv3", + "instance_id": "i-058b482b1646467da", + "instance_type": "c5.2xlarge", + "memory_gb": 16, + "name": "mockenv3-org2peer3", + "state": "stopped", + "vcpu": 8 + }, + { + "environment": "mockenv3", + "instance_id": "i-05c79685437b8a258", + "instance_type": "c5.2xlarge", + "memory_gb": 16, + "name": "mockenv3-org5couchdb1", + "state": "stopped", + "vcpu": 8 + }, + { + "environment": "mockenv3", + "instance_id": "i-053fda95ac228f8c5", + "instance_type": "t2.micro", + "memory_gb": 1, + "name": "mockenv3-orderer3", + "state": "stopped", + "vcpu": 1 + }, + { + "environment": "mockenv3", + "instance_id": "i-0c42520bdd6a7a534", + "instance_type": "c5.2xlarge", + "memory_gb": 16, + "name": "mockenv3-org3couchdb3", + "state": "stopped", + "vcpu": 8 + }, + { + "environment": "mockenv3", + "instance_id": "i-00a1c56505c9b2ee4", + "instance_type": "c5.2xlarge", + "memory_gb": 16, + "name": "mockenv3-org6peer1", + "state": "stopped", + "vcpu": 8 + }, + { + "environment": "mockenv3", + "instance_id": "i-07d1c73ff4c942a3c", + "instance_type": "t2.medium", + "memory_gb": 4, + "name": "mockenv3-org6app2", + "state": "stopped", + "vcpu": 2 + }, + { + "environment": "mockenv3", + "instance_id": "i-00782b79caaa38ab5", + "instance_type": "c5.2xlarge", + "memory_gb": 16, + "name": "mockenv3-org6peer3", + "state": "stopped", + "vcpu": 8 + }, + { + "environment": "mockenv3", + "instance_id": "i-086c974df6e4a532f", + "instance_type": "t2.small", + "memory_gb": 2, + "name": "mockenv3-zoo3", + "state": "stopped", + "vcpu": 1 + }, + { + "environment": "mockenv3", + "instance_id": "i-017549e8a39609389", + "instance_type": "c5.2xlarge", + "memory_gb": 16, + "name": "mockenv3-org3couchdb2", + "state": "stopped", + "vcpu": 8 + }, + { + "environment": "mockenv3", + "instance_id": "i-08b898af6356e76ac", + "instance_type": "t2.medium", + "memory_gb": 4, + "name": "mockenv3-org3app1", + "state": "stopped", + "vcpu": 2 + }, + { + "environment": "mockenv3", + "instance_id": "i-00f3211b37f283517", + "instance_type": "t2.medium", + "memory_gb": 4, + "name": "mockenv3-org1app1", + "state": "stopped", + "vcpu": 2 + }, + { + "environment": "mockenv3", + "instance_id": "i-0ea0560a364ec6e1b", + "instance_type": "c5.2xlarge", + "memory_gb": 16, + "name": "mockenv3-org4couchdb3", + "state": "stopped", + "vcpu": 8 + } + ], + "name": "mockenv3", + "provider": "aws", + "region": "ca-central-1", + "running_instances": 0, + "state": "stopped", + "stopped_instances": 83, + "total_instances": 83, + "total_memory_gb": 798, + "total_vcpu": 407 + }, + { + "id": "36436c027202", + "instances": [ + { + "environment": "mockenv4", + "instance_id": "i-071c75646d226dc73", + "instance_type": "t3.small", + "memory_gb": 2, + "name": "mockenv4-org4app1", + "state": "stopped", + "vcpu": 2 + }, + { + "environment": "mockenv4", + "instance_id": "i-01d86244293b4d12c", + "instance_type": "t2.small", + "memory_gb": 2, + "name": "mockenv4-kafka3", + "state": "stopped", + "vcpu": 1 + }, + { + "environment": "mockenv4", + "instance_id": "i-0c6ed3dc150f3e568", + "instance_type": "t2.micro", + "memory_gb": 1, + "name": "mockenv4-org4ca1", + "state": "stopped", + "vcpu": 1 + }, + { + "environment": "mockenv4", + "instance_id": "i-02943039d40e0fbfd", + "instance_type": "t3.small", + "memory_gb": 2, + "name": "mockenv4-org5app1", + "state": "stopped", + "vcpu": 2 + }, + { + "environment": "mockenv4", + "instance_id": "i-0d368037e5b6709db", + "instance_type": "t3.small", + "memory_gb": 2, + "name": "mockenv4-org6app2", + "state": "stopped", + "vcpu": 2 + }, + { + "environment": "mockenv4", + "instance_id": "i-07bf50a4c01ed1313", + "instance_type": "c5.2xlarge", + "memory_gb": 16, + "name": "mockenv4-org3peer1", + "state": "stopped", + "vcpu": 8 + }, + { + "environment": "mockenv4", + "instance_id": "i-01c55ddb1637e2f07", + "instance_type": "t2.micro", + "memory_gb": 1, + "name": "mockenv4-org2ca2", + "state": "stopped", + "vcpu": 1 + }, + { + "environment": "mockenv4", + "instance_id": "i-09e2c3809819b2570", + "instance_type": "t3.small", + "memory_gb": 2, + "name": "mockenv4-org2app2", + "state": "stopped", + "vcpu": 2 + }, + { + "environment": "mockenv4", + "instance_id": "i-00d36b6dc2f22faad", + "instance_type": "t2.micro", + "memory_gb": 1, + "name": "mockenv4-org6ca2", + "state": "stopped", + "vcpu": 1 + }, + { + "environment": "mockenv4", + "instance_id": "i-05284abd159ef0390", + "instance_type": "t3.medium", + "memory_gb": 4, + "name": "mockenv4-org4admin", + "state": "stopped", + "vcpu": 2 + }, + { + "environment": "mockenv4", + "instance_id": "i-01839ccd34342d68c", + "instance_type": "t3.small", + "memory_gb": 2, + "name": "mockenv4-org5app2", + "state": "stopped", + "vcpu": 2 + }, + { + "environment": "mockenv4", + "instance_id": "i-02eb42e1e948cfe55", + "instance_type": "t3.medium", + "memory_gb": 4, + "name": "mockenv4-org5admin", + "state": "stopped", + "vcpu": 2 + }, + { + "environment": "mockenv4", + "instance_id": "i-076937378cb7f9d39", + "instance_type": "c5.2xlarge", + "memory_gb": 16, + "name": "mockenv4-org1peer1", + "state": "stopped", + "vcpu": 8 + }, + { + "environment": "mockenv4", + "instance_id": "i-00752d1a65895a363", + "instance_type": "t2.small", + "memory_gb": 2, + "name": "mockenv4-zoo2", + "state": "stopped", + "vcpu": 1 + }, + { + "environment": "mockenv4", + "instance_id": "i-002098f454b94a739", + "instance_type": "c5.2xlarge", + "memory_gb": 16, + "name": "mockenv4-org6peer2", + "state": "stopped", + "vcpu": 8 + }, + { + "environment": "mockenv4", + "instance_id": "i-0ad04d9e1427db1f9", + "instance_type": "c5.2xlarge", + "memory_gb": 16, + "name": "mockenv4-org5peer2", + "state": "stopped", + "vcpu": 8 + }, + { + "environment": "mockenv4", + "instance_id": "i-025a223d40dea49fa", + "instance_type": "t3.small", + "memory_gb": 2, + "name": "mockenv4-org3app1", + "state": "stopped", + "vcpu": 2 + }, + { + "environment": "mockenv4", + "instance_id": "i-0bb5e20947cd0e861", + "instance_type": "t2.micro", + "memory_gb": 1, + "name": "mockenv4-org1ca1", + "state": "stopped", + "vcpu": 1 + }, + { + "environment": "mockenv4", + "instance_id": "i-030ad523576890bdb", + "instance_type": "t2.micro", + "memory_gb": 1, + "name": "mockenv4-admin", + "state": "stopped", + "vcpu": 1 + }, + { + "environment": "mockenv4", + "instance_id": "i-01d50deae235d4715", + "instance_type": "t2.micro", + "memory_gb": 1, + "name": "mockenv4-org3ca2", + "state": "stopped", + "vcpu": 1 + }, + { + "environment": "mockenv4", + "instance_id": "i-043ddbc8cfbb8041f", + "instance_type": "t2.small", + "memory_gb": 2, + "name": "mockenv4-kafka1", + "state": "stopped", + "vcpu": 1 + }, + { + "environment": "mockenv4", + "instance_id": "i-05f8d0d8bb63b1a6b", + "instance_type": "t2.micro", + "memory_gb": 1, + "name": "mockenv4-org1ca2", + "state": "stopped", + "vcpu": 1 + }, + { + "environment": "mockenv4", + "instance_id": "i-0a30d4808fccbdcb8", + "instance_type": "t3.small", + "memory_gb": 2, + "name": "mockenv4-org1app2", + "state": "stopped", + "vcpu": 2 + }, + { + "environment": "mockenv4", + "instance_id": "i-0e71ee77d15693b4b", + "instance_type": "t2.small", + "memory_gb": 2, + "name": "mockenv4-zoo1", + "state": "stopped", + "vcpu": 1 + }, + { + "environment": "mockenv4", + "instance_id": "i-03a14738e9f555da9", + "instance_type": "t2.small", + "memory_gb": 2, + "name": "mockenv4-zoo3", + "state": "stopped", + "vcpu": 1 + }, + { + "environment": "mockenv4", + "instance_id": "i-0351e24fd1298b777", + "instance_type": "t2.micro", + "memory_gb": 1, + "name": "mockenv4-org4ca2", + "state": "stopped", + "vcpu": 1 + }, + { + "environment": "mockenv4", + "instance_id": "i-0d87b7d24b4b966c2", + "instance_type": "t3.medium", + "memory_gb": 4, + "name": "mockenv4-org1admin", + "state": "stopped", + "vcpu": 2 + }, + { + "environment": "mockenv4", + "instance_id": "i-0f12d013aeffeb095", + "instance_type": "t3.small", + "memory_gb": 2, + "name": "mockenv4-org6app1", + "state": "stopped", + "vcpu": 2 + }, + { + "environment": "mockenv4", + "instance_id": "i-0343cc018585ecddf", + "instance_type": "t3.small", + "memory_gb": 2, + "name": "mockenv4-org1app1", + "state": "stopped", + "vcpu": 2 + }, + { + "environment": "mockenv4", + "instance_id": "i-058f9365e36ff1dab", + "instance_type": "t3.medium", + "memory_gb": 4, + "name": "mockenv4-org2admin", + "state": "stopped", + "vcpu": 2 + }, + { + "environment": "mockenv4", + "instance_id": "i-04ab76023830d8087", + "instance_type": "t2.small", + "memory_gb": 2, + "name": "mockenv4-kafka2", + "state": "stopped", + "vcpu": 1 + }, + { + "environment": "mockenv4", + "instance_id": "i-0f95a04fab9d9c2e4", + "instance_type": "t3.small", + "memory_gb": 2, + "name": "mockenv4-org3app2", + "state": "stopped", + "vcpu": 2 + }, + { + "environment": "mockenv4", + "instance_id": "i-0ba3d969566a38577", + "instance_type": "c5.2xlarge", + "memory_gb": 16, + "name": "mockenv4-org3peer2", + "state": "stopped", + "vcpu": 8 + }, + { + "environment": "mockenv4", + "instance_id": "i-039d594905b6da0ff", + "instance_type": "t2.micro", + "memory_gb": 1, + "name": "mockenv4-org3ca1", + "state": "stopped", + "vcpu": 1 + }, + { + "environment": "mockenv4", + "instance_id": "i-0a81b04963eea5416", + "instance_type": "c5.2xlarge", + "memory_gb": 16, + "name": "mockenv4-org6peer1", + "state": "stopped", + "vcpu": 8 + }, + { + "environment": "mockenv4", + "instance_id": "i-05dba6198a6f8af29", + "instance_type": "t2.micro", + "memory_gb": 1, + "name": "mockenv4-orderer2", + "state": "stopped", + "vcpu": 1 + }, + { + "environment": "mockenv4", + "instance_id": "i-0a3f075db62dc422c", + "instance_type": "t2.micro", + "memory_gb": 1, + "name": "mockenv4-org6ca1", + "state": "stopped", + "vcpu": 1 + }, + { + "environment": "mockenv4", + "instance_id": "i-08b622bd87725f7fe", + "instance_type": "c5.2xlarge", + "memory_gb": 16, + "name": "mockenv4-org1peer2", + "state": "stopped", + "vcpu": 8 + }, + { + "environment": "mockenv4", + "instance_id": "i-0eee987e3c043c618", + "instance_type": "t3.medium", + "memory_gb": 4, + "name": "mockenv4-org3admin", + "state": "stopped", + "vcpu": 2 + }, + { + "environment": "mockenv4", + "instance_id": "i-0535d0aab0edb9990", + "instance_type": "t2.micro", + "memory_gb": 1, + "name": "mockenv4-org5ca1", + "state": "stopped", + "vcpu": 1 + }, + { + "environment": "mockenv4", + "instance_id": "i-07bf6fe55d4a3f552", + "instance_type": "c5.2xlarge", + "memory_gb": 16, + "name": "mockenv4-org4peer2", + "state": "stopped", + "vcpu": 8 + }, + { + "environment": "mockenv4", + "instance_id": "i-016d42a175975ffa4", + "instance_type": "t3.small", + "memory_gb": 2, + "name": "mockenv4-org4app2", + "state": "stopped", + "vcpu": 2 + }, + { + "environment": "mockenv4", + "instance_id": "i-0d24f4a1432038057", + "instance_type": "c5.2xlarge", + "memory_gb": 16, + "name": "mockenv4-org4peer1", + "state": "stopped", + "vcpu": 8 + }, + { + "environment": "mockenv4", + "instance_id": "i-0192e936f569da9e2", + "instance_type": "c5.2xlarge", + "memory_gb": 16, + "name": "mockenv4-org2peer2", + "state": "stopped", + "vcpu": 8 + }, + { + "environment": "mockenv4", + "instance_id": "i-007e3984a32f6d19b", + "instance_type": "c5.2xlarge", + "memory_gb": 16, + "name": "mockenv4-org2peer1", + "state": "stopped", + "vcpu": 8 + }, + { + "environment": "mockenv4", + "instance_id": "i-0f1785ae32fd8f301", + "instance_type": "t2.small", + "memory_gb": 2, + "name": "mockenv4-kafka4", + "state": "stopped", + "vcpu": 1 + }, + { + "environment": "mockenv4", + "instance_id": "i-00743cb11c40f7121", + "instance_type": "t3.small", + "memory_gb": 2, + "name": "mockenv4-org2app1", + "state": "stopped", + "vcpu": 2 + }, + { + "environment": "mockenv4", + "instance_id": "i-08acff738b6eefbb3", + "instance_type": "c5.2xlarge", + "memory_gb": 16, + "name": "mockenv4-org5peer1", + "state": "stopped", + "vcpu": 8 + }, + { + "environment": "mockenv4", + "instance_id": "i-0bc7b098b29c79754", + "instance_type": "t2.micro", + "memory_gb": 1, + "name": "mockenv4-org5ca2", + "state": "stopped", + "vcpu": 1 + }, + { + "environment": "mockenv4", + "instance_id": "i-0f3d2ad78d2a08c37", + "instance_type": "t2.micro", + "memory_gb": 1, + "name": "mockenv4-orderer1", + "state": "stopped", + "vcpu": 1 + }, + { + "environment": "mockenv4", + "instance_id": "i-0ddd509fd7f0d7998", + "instance_type": "t3.medium", + "memory_gb": 4, + "name": "mockenv4-org6admin", + "state": "stopped", + "vcpu": 2 + }, + { + "environment": "mockenv4", + "instance_id": "i-026a0cdf8433d74f3", + "instance_type": "t2.micro", + "memory_gb": 1, + "name": "mockenv4-orderer3", + "state": "stopped", + "vcpu": 1 + }, + { + "environment": "mockenv4", + "instance_id": "i-09e1c63fdeb70a0ea", + "instance_type": "t2.micro", + "memory_gb": 1, + "name": "mockenv4-org2ca1", + "state": "stopped", + "vcpu": 1 + } + ], + "name": "mockenv4", + "provider": "aws", + "region": "ca-central-1", + "running_instances": 0, + "state": "stopped", + "stopped_instances": 53, + "total_instances": 53, + "total_memory_gb": 270, + "total_vcpu": 155 + }, + { + "id": "7f0a86ba97d1", + "instances": [ + { + "environment": "mockenv5", + "instance_id": "i-044a7742565cd9040", + "instance_type": "t2.medium", + "memory_gb": 4, + "name": "mockenv5-org1peer2", + "state": "stopped", + "vcpu": 2 + }, + { + "environment": "mockenv5", + "instance_id": "i-08b4337605830c376", + "instance_type": "t2.medium", + "memory_gb": 4, + "name": "mockenv5-org4peer1", + "state": "stopped", + "vcpu": 2 + }, + { + "environment": "mockenv5", + "instance_id": "i-074ffb151220acb37", + "instance_type": "t2.medium", + "memory_gb": 4, + "name": "mockenv5-org4peer2", + "state": "stopped", + "vcpu": 2 + }, + { + "environment": "mockenv5", + "instance_id": "i-09c3ae7f709d026f9", + "instance_type": "t2.medium", + "memory_gb": 4, + "name": "mockenv5-kafka2", + "state": "stopped", + "vcpu": 2 + }, + { + "environment": "mockenv5", + "instance_id": "i-05e41007a825cf74f", + "instance_type": "t2.medium", + "memory_gb": 4, + "name": "mockenv5-org1peer1", + "state": "stopped", + "vcpu": 2 + }, + { + "environment": "mockenv5", + "instance_id": "i-0fdc8b231f1335e88", + "instance_type": "t2.medium", + "memory_gb": 4, + "name": "mockenv5-org2peer2", + "state": "stopped", + "vcpu": 2 + }, + { + "environment": "mockenv5", + "instance_id": "i-03fd31a538a26cd4c", + "instance_type": "t2.medium", + "memory_gb": 4, + "name": "mockenv5-org3peer1", + "state": "stopped", + "vcpu": 2 + }, + { + "environment": "mockenv5", + "instance_id": "i-0335492d5b88f5ba0", + "instance_type": "t2.micro", + "memory_gb": 1, + "name": "mockenv5-orderer1", + "state": "stopped", + "vcpu": 1 + }, + { + "environment": "mockenv5", + "instance_id": "i-09c51ed034d69d6f0", + "instance_type": "t2.small", + "memory_gb": 2, + "name": "mockenv5-zoo1", + "state": "stopped", + "vcpu": 1 + }, + { + "environment": "mockenv5", + "instance_id": "i-08041d386acfd0b2f", + "instance_type": "t2.medium", + "memory_gb": 4, + "name": "mockenv5-org3peer2", + "state": "stopped", + "vcpu": 2 + }, + { + "environment": "mockenv5", + "instance_id": "i-055df7f5477314394", + "instance_type": "t2.small", + "memory_gb": 2, + "name": "mockenv5-zoo2", + "state": "stopped", + "vcpu": 1 + }, + { + "environment": "mockenv5", + "instance_id": "i-07e831d45c42fd193", + "instance_type": "t2.medium", + "memory_gb": 4, + "name": "mockenv5-kafka1", + "state": "stopped", + "vcpu": 2 + }, + { + "environment": "mockenv5", + "instance_id": "i-0b075aeb37bc972a1", + "instance_type": "t2.micro", + "memory_gb": 1, + "name": "mockenv5-admin", + "state": "stopped", + "vcpu": 1 + }, + { + "environment": "mockenv5", + "instance_id": "i-05d597db2a6ba54e6", + "instance_type": "t2.medium", + "memory_gb": 4, + "name": "mockenv5-org2peer1", + "state": "stopped", + "vcpu": 2 + }, + { + "environment": "mockenv5", + "instance_id": "i-07a108898968f0007", + "instance_type": "t2.micro", + "memory_gb": 1, + "name": "mockenv5-orderer2", + "state": "stopped", + "vcpu": 1 + } + ], + "name": "mockenv5", + "provider": "aws", + "region": "ca-central-1", + "running_instances": 0, + "state": "stopped", + "stopped_instances": 15, + "total_instances": 15, + "total_memory_gb": 47, + "total_vcpu": 25 + }, + { + "id": "931decfe6fd5", + "instances": [ + { + "environment": "mockenv6", + "instance_id": "i-0008ad1bfd83a52eb", + "instance_type": "t3.xlarge", + "memory_gb": 16, + "name": "mockenv6-k8node2", + "state": "stopped", + "vcpu": 4 + }, + { + "environment": "mockenv6", + "instance_id": "i-04b69b4ec92d548df", + "instance_type": "t3.medium", + "memory_gb": 4, + "name": "mockenv6-k8master1", + "state": "stopped", + "vcpu": 2 + }, + { + "environment": "mockenv6", + "instance_id": "i-0dedc66553eaecfc3", + "instance_type": "t3.medium", + "memory_gb": 4, + "name": "mockenv6-k8master2", + "state": "stopped", + "vcpu": 2 + }, + { + "environment": "mockenv6", + "instance_id": "i-0778ddf78ec72bffd", + "instance_type": "t3.small", + "memory_gb": 2, + "name": "mockenv6-etcd3", + "state": "stopped", + "vcpu": 2 + }, + { + "environment": "mockenv6", + "instance_id": "i-03b3782294e848647", + "instance_type": "t3.small", + "memory_gb": 2, + "name": "mockenv6-etcd1", + "state": "stopped", + "vcpu": 2 + }, + { + "environment": "mockenv6", + "instance_id": "i-0872ea25c0766d383", + "instance_type": "t3.xlarge", + "memory_gb": 16, + "name": "mockenv6-k8node5", + "state": "stopped", + "vcpu": 4 + }, + { + "environment": "mockenv6", + "instance_id": "i-0e9fcaf646ce779ab", + "instance_type": "t3.xlarge", + "memory_gb": 16, + "name": "mockenv6-k8node3", + "state": "stopped", + "vcpu": 4 + }, + { + "environment": "mockenv6", + "instance_id": "i-0eba74077ac760573", + "instance_type": "t3.small", + "memory_gb": 2, + "name": "mockenv6-etcd2", + "state": "stopped", + "vcpu": 2 + }, + { + "environment": "mockenv6", + "instance_id": "i-0d67730effbee8b3b", + "instance_type": "t3.xlarge", + "memory_gb": 16, + "name": "mockenv6-k8node1", + "state": "stopped", + "vcpu": 4 + }, + { + "environment": "mockenv6", + "instance_id": "i-009517923633b51f4", + "instance_type": "t3.xlarge", + "memory_gb": 16, + "name": "mockenv6-k8node4", + "state": "stopped", + "vcpu": 4 + } + ], + "name": "mockenv6", + "provider": "aws", + "region": "ca-central-1", + "running_instances": 0, + "state": "stopped", + "stopped_instances": 10, + "total_instances": 10, + "total_memory_gb": 94, + "total_vcpu": 30 + }, + { + "id": "72e0ca1fc903", + "instances": [ + { + "environment": "mockenv7", + "instance_id": "i-01901f7ff1afc2365", + "instance_type": "t2.medium", + "memory_gb": 4, + "name": "mockenv7-org1-app", + "state": "stopped", + "vcpu": 2 + }, + { + "environment": "mockenv7", + "instance_id": "i-03f161f3b27709891", + "instance_type": "t2.medium", + "memory_gb": 4, + "name": "mockenv7-org5-app", + "state": "stopped", + "vcpu": 2 + }, + { + "environment": "mockenv7", + "instance_id": "i-0b1d0fcde41d75806", + "instance_type": "t2.medium", + "memory_gb": 4, + "name": "mockenv7-org2-app", + "state": "stopped", + "vcpu": 2 + }, + { + "environment": "mockenv7", + "instance_id": "i-0517e563d41f75d18", + "instance_type": "t2.medium", + "memory_gb": 4, + "name": "mockenv7-org4-app", + "state": "stopped", + "vcpu": 2 + }, + { + "environment": "mockenv7", + "instance_id": "i-0c4f22923d9f58d0a", + "instance_type": "t2.medium", + "memory_gb": 4, + "name": "mockenv7-org3-app", + "state": "stopped", + "vcpu": 2 + }, + { + "environment": "mockenv7", + "instance_id": "i-048b24df4aa79e266", + "instance_type": "t2.medium", + "memory_gb": 4, + "name": "mockenv7-org6-app", + "state": "stopped", + "vcpu": 2 + } + ], + "name": "mockenv7", + "provider": "aws", + "region": "ca-central-1", + "running_instances": 0, + "state": "stopped", + "stopped_instances": 6, + "total_instances": 6, + "total_memory_gb": 24, + "total_vcpu": 12 + } +] \ No newline at end of file diff --git a/testdata/mock_env_cachedTable.json b/testdata/mock_env_cachedTable.json deleted file mode 100644 index d1bb711..0000000 --- a/testdata/mock_env_cachedTable.json +++ /dev/null @@ -1,1087 +0,0 @@ -[ - { - "Name": "taxiapp", - "Instances": [ - { - "Id": "i-9a5c68f08c53f5a81", - "Type": "c5.xlarge", - "Name": "taxiapp-org3peer4", - "State": "running", - "Environment": "taxiapp", - "VCPU": 4, - "MemoryGB": 8 - }, - { - "Id": "i-9ab609a3c8fb70025", - "Type": "c5.xlarge", - "Name": "taxiapp-org3peer3", - "State": "running", - "Environment": "taxiapp", - "VCPU": 4, - "MemoryGB": 8 - }, - { - "Id": "i-906cbdad6c27666b5", - "Type": "c5.xlarge", - "Name": "taxiapp-org1peer5", - "State": "running", - "Environment": "taxiapp", - "VCPU": 4, - "MemoryGB": 8 - }, - { - "Id": "i-90061d4c8875b263d", - "Type": "c5.2xlarge", - "Name": "taxiapp-org2peer2", - "State": "running", - "Environment": "taxiapp", - "VCPU": 8, - "MemoryGB": 16 - }, - { - "Id": "i-9d1fee52c9633fac6", - "Type": "c5.xlarge", - "Name": "taxiapp-org3peer1", - "State": "running", - "Environment": "taxiapp", - "VCPU": 4, - "MemoryGB": 8 - }, - { - "Id": "i-94a4c3c42912783bf", - "Type": "c5.2xlarge", - "Name": "taxiapp-org3peer2", - "State": "running", - "Environment": "taxiapp", - "VCPU": 8, - "MemoryGB": 16 - }, - { - "Id": "i-9b635062614f41902", - "Type": "c5.xlarge", - "Name": "taxiapp-org1peer4", - "State": "running", - "Environment": "taxiapp", - "VCPU": 4, - "MemoryGB": 8 - }, - { - "Id": "i-90b7f2acde2b257f4", - "Type": "t2.medium", - "Name": "taxiapp-kafka1", - "State": "running", - "Environment": "taxiapp", - "VCPU": 2, - "MemoryGB": 4 - }, - { - "Id": "i-9ce165e54c97354af", - "Type": "c5.2xlarge", - "Name": "taxiapp-org1peer2", - "State": "running", - "Environment": "taxiapp", - "VCPU": 8, - "MemoryGB": 16 - }, - { - "Id": "i-992bf46daa1ba864d", - "Type": "t2.micro", - "Name": "taxiapp-orderer2", - "State": "running", - "Environment": "taxiapp", - "VCPU": 1, - "MemoryGB": 1 - }, - { - "Id": "i-9f5dd015ec55df23d", - "Type": "c5.xlarge", - "Name": "taxiapp-org2peer3", - "State": "running", - "Environment": "taxiapp", - "VCPU": 4, - "MemoryGB": 8 - }, - { - "Id": "i-91e281e66008412c5", - "Type": "c5.2xlarge", - "Name": "taxiapp-org4peer2", - "State": "running", - "Environment": "taxiapp", - "VCPU": 8, - "MemoryGB": 16 - }, - { - "Id": "i-907fe1dee4659994d", - "Type": "t2.small", - "Name": "taxiapp-zoo2", - "State": "running", - "Environment": "taxiapp", - "VCPU": 1, - "MemoryGB": 2 - }, - { - "Id": "i-92a865c984a00457b", - "Type": "c5.xlarge", - "Name": "taxiapp-org4peer3", - "State": "running", - "Environment": "taxiapp", - "VCPU": 4, - "MemoryGB": 8 - }, - { - "Id": "i-923d466a8c9802aed", - "Type": "t2.2xlarge", - "Name": "taxiapp-admin", - "State": "running", - "Environment": "taxiapp", - "VCPU": 8, - "MemoryGB": 32 - }, - { - "Id": "i-9fcd4b9773bd76d98", - "Type": "t2.medium", - "Name": "taxiapp-kafka2", - "State": "running", - "Environment": "taxiapp", - "VCPU": 2, - "MemoryGB": 4 - }, - { - "Id": "i-9a7e0901d8a388830", - "Type": "c5.xlarge", - "Name": "taxiapp-org2peer1", - "State": "running", - "Environment": "taxiapp", - "VCPU": 4, - "MemoryGB": 8 - }, - { - "Id": "i-90e9d9726ae79b57c", - "Type": "c5.xlarge", - "Name": "taxiapp-org4peer5", - "State": "running", - "Environment": "taxiapp", - "VCPU": 4, - "MemoryGB": 8 - }, - { - "Id": "i-9537759a63512bbb7", - "Type": "c5.xlarge", - "Name": "taxiapp-org4peer1", - "State": "running", - "Environment": "taxiapp", - "VCPU": 4, - "MemoryGB": 8 - }, - { - "Id": "i-967d9e1b712c97808", - "Type": "t2.micro", - "Name": "taxiapp-orderer1", - "State": "running", - "Environment": "taxiapp", - "VCPU": 1, - "MemoryGB": 1 - }, - { - "Id": "i-981c2a979f70ef34e", - "Type": "c5.xlarge", - "Name": "taxiapp-org4peer4", - "State": "running", - "Environment": "taxiapp", - "VCPU": 4, - "MemoryGB": 8 - }, - { - "Id": "i-9607964069781218d", - "Type": "c5.xlarge", - "Name": "taxiapp-org3peer5", - "State": "running", - "Environment": "taxiapp", - "VCPU": 4, - "MemoryGB": 8 - }, - { - "Id": "i-9b9dff025ebe98954", - "Type": "c5.xlarge", - "Name": "taxiapp-org2peer4", - "State": "running", - "Environment": "taxiapp", - "VCPU": 4, - "MemoryGB": 8 - }, - { - "Id": "i-9db1f3649cc30252a", - "Type": "c5.xlarge", - "Name": "taxiapp-org1peer1", - "State": "running", - "Environment": "taxiapp", - "VCPU": 4, - "MemoryGB": 8 - }, - { - "Id": "i-93e949f0b8df6b8fa", - "Type": "c5.xlarge", - "Name": "taxiapp-org1peer3", - "State": "running", - "Environment": "taxiapp", - "VCPU": 4, - "MemoryGB": 8 - }, - { - "Id": "i-96ec7f5c26d0a21ac", - "Type": "t2.small", - "Name": "taxiapp-zoo1", - "State": "running", - "Environment": "taxiapp", - "VCPU": 1, - "MemoryGB": 2 - }, - { - "Id": "i-94b0e0df81ddbf819", - "Type": "c5.xlarge", - "Name": "taxiapp-org2peer5", - "State": "running", - "Environment": "taxiapp", - "VCPU": 4, - "MemoryGB": 8 - } - ], - "TotalvCPU": 0, - "TotalMemoryGB": 0, - "State": "running" - }, - { - "Name": "identity-uat", - "Instances": [ - { - "Id": "i-9fad029fc89bd64dd", - "Type": "t2.micro", - "Name": "identity-uat-org2ca1", - "State": "running", - "Environment": "identity-uat", - "VCPU": 1, - "MemoryGB": 1 - }, - { - "Id": "i-9371c09c9854d1205", - "Type": "c5.xlarge", - "Name": "identity-uat-org5admin", - "State": "running", - "Environment": "identity-uat", - "VCPU": 4, - "MemoryGB": 8 - }, - { - "Id": "i-94178fa2661885b77", - "Type": "c5.4xlarge", - "Name": "identity-uat-org4peer3", - "State": "running", - "Environment": "identity-uat", - "VCPU": 16, - "MemoryGB": 32 - }, - { - "Id": "i-9f21574ab1e261525", - "Type": "c5.4xlarge", - "Name": "identity-uat-org1peer4", - "State": "running", - "Environment": "identity-uat", - "VCPU": 16, - "MemoryGB": 32 - }, - { - "Id": "i-9194219c82db9ecaa", - "Type": "c5.4xlarge", - "Name": "identity-uat-org6peer2", - "State": "running", - "Environment": "identity-uat", - "VCPU": 16, - "MemoryGB": 32 - }, - { - "Id": "i-982fe775f5eda619a", - "Type": "t2.small", - "Name": "identity-uat-kafka1", - "State": "running", - "Environment": "identity-uat", - "VCPU": 1, - "MemoryGB": 2 - }, - { - "Id": "i-97f63c3cf6c040735", - "Type": "t2.medium", - "Name": "identity-uat-org2app2", - "State": "running", - "Environment": "identity-uat", - "VCPU": 2, - "MemoryGB": 4 - }, - { - "Id": "i-9f72ee83329ad7f92", - "Type": "t2.medium", - "Name": "identity-uat-org1app1", - "State": "running", - "Environment": "identity-uat", - "VCPU": 2, - "MemoryGB": 4 - }, - { - "Id": "i-9062657ada57efd96", - "Type": "t2.medium", - "Name": "identity-uat-org1app2", - "State": "running", - "Environment": "identity-uat", - "VCPU": 2, - "MemoryGB": 4 - }, - { - "Id": "i-901d9e6244c24a230", - "Type": "c5.4xlarge", - "Name": "identity-uat-org2peer2", - "State": "running", - "Environment": "identity-uat", - "VCPU": 16, - "MemoryGB": 32 - }, - { - "Id": "i-9a5dc9c3faf6e2502", - "Type": "c5.xlarge", - "Name": "identity-uat-org6admin", - "State": "running", - "Environment": "identity-uat", - "VCPU": 4, - "MemoryGB": 8 - }, - { - "Id": "i-9eaa962ae0ff37eb2", - "Type": "c5.xlarge", - "Name": "identity-uat-org3admin", - "State": "running", - "Environment": "identity-uat", - "VCPU": 4, - "MemoryGB": 8 - }, - { - "Id": "i-93df21a6531d2ae0b", - "Type": "t2.medium", - "Name": "identity-uat-org4app1", - "State": "running", - "Environment": "identity-uat", - "VCPU": 2, - "MemoryGB": 4 - }, - { - "Id": "i-9d5ed0e3c6b1c2655", - "Type": "t2.micro", - "Name": "identity-uat-org2ca2", - "State": "running", - "Environment": "identity-uat", - "VCPU": 1, - "MemoryGB": 1 - }, - { - "Id": "i-95157effe761d2fb6", - "Type": "t2.micro", - "Name": "identity-uat-org6ca1", - "State": "running", - "Environment": "identity-uat", - "VCPU": 1, - "MemoryGB": 1 - }, - { - "Id": "i-9473b82a6aaad2e78", - "Type": "c5.4xlarge", - "Name": "identity-uat-org2peer4", - "State": "running", - "Environment": "identity-uat", - "VCPU": 16, - "MemoryGB": 32 - }, - { - "Id": "i-977b21f2126b7329d", - "Type": "t2.medium", - "Name": "identity-uat-org5app1", - "State": "running", - "Environment": "identity-uat", - "VCPU": 2, - "MemoryGB": 4 - }, - { - "Id": "i-9b25ee3ee03761380", - "Type": "c5.4xlarge", - "Name": "identity-uat-org5peer2", - "State": "running", - "Environment": "identity-uat", - "VCPU": 16, - "MemoryGB": 32 - }, - { - "Id": "i-915d5c6f76158fc93", - "Type": "c5.xlarge", - "Name": "identity-uat-org4admin", - "State": "running", - "Environment": "identity-uat", - "VCPU": 4, - "MemoryGB": 8 - }, - { - "Id": "i-91b75ebf25a0bea16", - "Type": "t2.medium", - "Name": "identity-uat-org5app2", - "State": "running", - "Environment": "identity-uat", - "VCPU": 2, - "MemoryGB": 4 - }, - { - "Id": "i-9ca8a5d01d2f1941b", - "Type": "c5.4xlarge", - "Name": "identity-uat-org3peer1", - "State": "running", - "Environment": "identity-uat", - "VCPU": 16, - "MemoryGB": 32 - }, - { - "Id": "i-959161886849c2186", - "Type": "c5.4xlarge", - "Name": "identity-uat-org4peer1", - "State": "running", - "Environment": "identity-uat", - "VCPU": 16, - "MemoryGB": 32 - }, - { - "Id": "i-9e63408bed2a971c9", - "Type": "t2.medium", - "Name": "identity-uat-org3app1", - "State": "running", - "Environment": "identity-uat", - "VCPU": 2, - "MemoryGB": 4 - }, - { - "Id": "i-984bff5892fb95035", - "Type": "c5.4xlarge", - "Name": "identity-uat-org1peer1", - "State": "running", - "Environment": "identity-uat", - "VCPU": 16, - "MemoryGB": 32 - }, - { - "Id": "i-937a4a720f1a179c9", - "Type": "c5.4xlarge", - "Name": "identity-uat-org6peer1", - "State": "running", - "Environment": "identity-uat", - "VCPU": 16, - "MemoryGB": 32 - }, - { - "Id": "i-939eeff3bd2da886b", - "Type": "c5.4xlarge", - "Name": "identity-uat-org5peer1", - "State": "running", - "Environment": "identity-uat", - "VCPU": 16, - "MemoryGB": 32 - }, - { - "Id": "i-96e3628f123e72fbf", - "Type": "t2.micro", - "Name": "identity-uat-org6ca2", - "State": "running", - "Environment": "identity-uat", - "VCPU": 1, - "MemoryGB": 1 - }, - { - "Id": "i-955f7ea10d22cb5c8", - "Type": "t2.micro", - "Name": "identity-uat-org4ca2", - "State": "running", - "Environment": "identity-uat", - "VCPU": 1, - "MemoryGB": 1 - }, - { - "Id": "i-932ed67930450ed32", - "Type": "t2.small", - "Name": "identity-uat-kafka4", - "State": "running", - "Environment": "identity-uat", - "VCPU": 1, - "MemoryGB": 2 - }, - { - "Id": "i-95cdbc1ef722a3b82", - "Type": "t2.medium", - "Name": "identity-uat-org4app2", - "State": "running", - "Environment": "identity-uat", - "VCPU": 2, - "MemoryGB": 4 - }, - { - "Id": "i-958c5987c5a6b8f8e", - "Type": "t2.medium", - "Name": "identity-uat-org6app1", - "State": "running", - "Environment": "identity-uat", - "VCPU": 2, - "MemoryGB": 4 - }, - { - "Id": "i-900a7bbf12e4ad7e1", - "Type": "t2.micro", - "Name": "identity-uat-org1ca1", - "State": "running", - "Environment": "identity-uat", - "VCPU": 1, - "MemoryGB": 1 - }, - { - "Id": "i-95dc21ece392e2266", - "Type": "c5.4xlarge", - "Name": "identity-uat-org2peer3", - "State": "running", - "Environment": "identity-uat", - "VCPU": 16, - "MemoryGB": 32 - }, - { - "Id": "i-9e68410d0927cd9f5", - "Type": "t2.small", - "Name": "identity-uat-zoo1", - "State": "running", - "Environment": "identity-uat", - "VCPU": 1, - "MemoryGB": 2 - }, - { - "Id": "i-97677339ee2171528", - "Type": "t2.medium", - "Name": "identity-uat-org6app2", - "State": "running", - "Environment": "identity-uat", - "VCPU": 2, - "MemoryGB": 4 - }, - { - "Id": "i-9dfcb2cb3175d9501", - "Type": "t2.micro", - "Name": "identity-uat-org3ca2", - "State": "running", - "Environment": "identity-uat", - "VCPU": 1, - "MemoryGB": 1 - }, - { - "Id": "i-96b7389832d1d60a4", - "Type": "c5.4xlarge", - "Name": "identity-uat-org4peer2", - "State": "running", - "Environment": "identity-uat", - "VCPU": 16, - "MemoryGB": 32 - }, - { - "Id": "i-9f642e2db559d8d8e", - "Type": "t2.micro", - "Name": "identity-uat-org5ca2", - "State": "running", - "Environment": "identity-uat", - "VCPU": 1, - "MemoryGB": 1 - }, - { - "Id": "i-925d6f62402fa0bfa", - "Type": "c5.4xlarge", - "Name": "identity-uat-org5peer4", - "State": "running", - "Environment": "identity-uat", - "VCPU": 16, - "MemoryGB": 32 - }, - { - "Id": "i-9990266fa87d5c7f2", - "Type": "t2.micro", - "Name": "identity-uat-org5ca1", - "State": "running", - "Environment": "identity-uat", - "VCPU": 1, - "MemoryGB": 1 - }, - { - "Id": "i-939b2ea50a4b68702", - "Type": "c5.4xlarge", - "Name": "identity-uat-org6peer3", - "State": "running", - "Environment": "identity-uat", - "VCPU": 16, - "MemoryGB": 32 - }, - { - "Id": "i-9c3a1c57c72cbc604", - "Type": "t2.small", - "Name": "identity-uat-zoo3", - "State": "running", - "Environment": "identity-uat", - "VCPU": 1, - "MemoryGB": 2 - }, - { - "Id": "i-90d9023c2bc5a5349", - "Type": "t2.small", - "Name": "identity-uat-kafka3", - "State": "running", - "Environment": "identity-uat", - "VCPU": 1, - "MemoryGB": 2 - }, - { - "Id": "i-945364c915dfb1374", - "Type": "c5.4xlarge", - "Name": "identity-uat-org6peer4", - "State": "running", - "Environment": "identity-uat", - "VCPU": 16, - "MemoryGB": 32 - }, - { - "Id": "i-9a9e068427a301954", - "Type": "c5.4xlarge", - "Name": "identity-uat-org3peer3", - "State": "running", - "Environment": "identity-uat", - "VCPU": 16, - "MemoryGB": 32 - }, - { - "Id": "i-90f987714ce8e3647", - "Type": "c5.xlarge", - "Name": "identity-uat-org2admin", - "State": "running", - "Environment": "identity-uat", - "VCPU": 4, - "MemoryGB": 8 - }, - { - "Id": "i-941a1630af0efe726", - "Type": "t2.micro", - "Name": "identity-uat-orderer3", - "State": "running", - "Environment": "identity-uat", - "VCPU": 1, - "MemoryGB": 1 - }, - { - "Id": "i-9e6acfa677c167ebd", - "Type": "t2.micro", - "Name": "identity-uat-admin", - "State": "running", - "Environment": "identity-uat", - "VCPU": 1, - "MemoryGB": 1 - }, - { - "Id": "i-9b5cbe337a28372d2", - "Type": "c5.4xlarge", - "Name": "identity-uat-org3peer4", - "State": "running", - "Environment": "identity-uat", - "VCPU": 16, - "MemoryGB": 32 - }, - { - "Id": "i-90ba51d5fa37d5dfb", - "Type": "t2.micro", - "Name": "identity-uat-org4ca1", - "State": "running", - "Environment": "identity-uat", - "VCPU": 1, - "MemoryGB": 1 - }, - { - "Id": "i-9589a649c80730984", - "Type": "t2.micro", - "Name": "identity-uat-orderer1", - "State": "running", - "Environment": "identity-uat", - "VCPU": 1, - "MemoryGB": 1 - }, - { - "Id": "i-917aba56090be677e", - "Type": "t2.micro", - "Name": "identity-uat-org1ca2", - "State": "running", - "Environment": "identity-uat", - "VCPU": 1, - "MemoryGB": 1 - }, - { - "Id": "i-928ffff6cf2fc8604", - "Type": "c5.4xlarge", - "Name": "identity-uat-org5peer3", - "State": "running", - "Environment": "identity-uat", - "VCPU": 16, - "MemoryGB": 32 - }, - { - "Id": "i-9fd5642d2925a5296", - "Type": "t2.medium", - "Name": "identity-uat-org3app2", - "State": "running", - "Environment": "identity-uat", - "VCPU": 2, - "MemoryGB": 4 - }, - { - "Id": "i-9881f1ac21cf0d624", - "Type": "t2.small", - "Name": "identity-uat-kafka2", - "State": "running", - "Environment": "identity-uat", - "VCPU": 1, - "MemoryGB": 2 - }, - { - "Id": "i-95223031edef61a29", - "Type": "t2.micro", - "Name": "identity-uat-org3ca1", - "State": "running", - "Environment": "identity-uat", - "VCPU": 1, - "MemoryGB": 1 - }, - { - "Id": "i-9b2aea71e49655b95", - "Type": "c5.xlarge", - "Name": "identity-uat-org1admin", - "State": "running", - "Environment": "identity-uat", - "VCPU": 4, - "MemoryGB": 8 - }, - { - "Id": "i-9fbbcb57d829d1226", - "Type": "c5.4xlarge", - "Name": "identity-uat-org4peer4", - "State": "running", - "Environment": "identity-uat", - "VCPU": 16, - "MemoryGB": 32 - }, - { - "Id": "i-9b6eecf14af172535", - "Type": "t2.medium", - "Name": "identity-uat-org2app1", - "State": "running", - "Environment": "identity-uat", - "VCPU": 2, - "MemoryGB": 4 - }, - { - "Id": "i-9cf828740320dc5d2", - "Type": "c5.4xlarge", - "Name": "identity-uat-org1peer3", - "State": "running", - "Environment": "identity-uat", - "VCPU": 16, - "MemoryGB": 32 - }, - { - "Id": "i-9ac67601cb448c74b", - "Type": "t2.small", - "Name": "identity-uat-zoo2", - "State": "running", - "Environment": "identity-uat", - "VCPU": 1, - "MemoryGB": 2 - }, - { - "Id": "i-98e6ae6bf8d5ab0b4", - "Type": "c5.4xlarge", - "Name": "identity-uat-org1peer2", - "State": "running", - "Environment": "identity-uat", - "VCPU": 16, - "MemoryGB": 32 - }, - { - "Id": "i-935603e4ee9e4f060", - "Type": "c5.4xlarge", - "Name": "identity-uat-org3peer2", - "State": "running", - "Environment": "identity-uat", - "VCPU": 16, - "MemoryGB": 32 - }, - { - "Id": "i-958c6f18853427d02", - "Type": "c5.4xlarge", - "Name": "identity-uat-org2peer1", - "State": "running", - "Environment": "identity-uat", - "VCPU": 16, - "MemoryGB": 32 - }, - { - "Id": "i-998877b1bc8a8787f", - "Type": "t2.micro", - "Name": "identity-uat-orderer2", - "State": "running", - "Environment": "identity-uat", - "VCPU": 1, - "MemoryGB": 1 - } - ], - "TotalvCPU": 0, - "TotalMemoryGB": 0, - "State": "running" - }, - { - "Name": "identity-dev", - "Instances": [ - { - "Id": "i-944a7742565cd9040", - "Type": "t2.medium", - "Name": "identity-dev-org1peer2", - "State": "stopped", - "Environment": "identity-dev", - "VCPU": 2, - "MemoryGB": 4 - }, - { - "Id": "i-98b4337605830c376", - "Type": "t2.medium", - "Name": "identity-dev-org4peer1", - "State": "stopped", - "Environment": "identity-dev", - "VCPU": 2, - "MemoryGB": 4 - }, - { - "Id": "i-9fdc8b231f1335e88", - "Type": "t2.medium", - "Name": "identity-dev-org2peer2", - "State": "stopped", - "Environment": "identity-dev", - "VCPU": 2, - "MemoryGB": 4 - }, - { - "Id": "i-974ffb151220acb37", - "Type": "t2.medium", - "Name": "identity-dev-org4peer2", - "State": "stopped", - "Environment": "identity-dev", - "VCPU": 2, - "MemoryGB": 4 - }, - { - "Id": "i-93fd31a538a26cd4c", - "Type": "t2.medium", - "Name": "identity-dev-org3peer1", - "State": "stopped", - "Environment": "identity-dev", - "VCPU": 2, - "MemoryGB": 4 - }, - { - "Id": "i-99c3ae7f709d026f9", - "Type": "t2.medium", - "Name": "identity-dev-kafka2", - "State": "stopped", - "Environment": "identity-dev", - "VCPU": 2, - "MemoryGB": 4 - }, - { - "Id": "i-9335492d5b88f5ba0", - "Type": "t2.micro", - "Name": "identity-dev-orderer1", - "State": "stopped", - "Environment": "identity-dev", - "VCPU": 1, - "MemoryGB": 1 - }, - { - "Id": "i-99c51ed034d69d6f0", - "Type": "t2.small", - "Name": "identity-dev-zoo1", - "State": "stopped", - "Environment": "identity-dev", - "VCPU": 1, - "MemoryGB": 2 - }, - { - "Id": "i-98041d386acfd0b2f", - "Type": "t2.medium", - "Name": "identity-dev-org3peer2", - "State": "stopped", - "Environment": "identity-dev", - "VCPU": 2, - "MemoryGB": 4 - }, - { - "Id": "i-955df7f5477314394", - "Type": "t2.small", - "Name": "identity-dev-zoo2", - "State": "stopped", - "Environment": "identity-dev", - "VCPU": 1, - "MemoryGB": 2 - }, - { - "Id": "i-95e41007a825cf74f", - "Type": "t2.medium", - "Name": "identity-dev-org1peer1", - "State": "stopped", - "Environment": "identity-dev", - "VCPU": 2, - "MemoryGB": 4 - }, - { - "Id": "i-97e831d45c42fd193", - "Type": "t2.medium", - "Name": "identity-dev-kafka1", - "State": "stopped", - "Environment": "identity-dev", - "VCPU": 2, - "MemoryGB": 4 - }, - { - "Id": "i-9b075aeb37bc972a1", - "Type": "t2.micro", - "Name": "identity-dev-admin", - "State": "stopped", - "Environment": "identity-dev", - "VCPU": 1, - "MemoryGB": 1 - }, - { - "Id": "i-95d597db2a6ba54e6", - "Type": "t2.medium", - "Name": "identity-dev-org2peer1", - "State": "stopped", - "Environment": "identity-dev", - "VCPU": 2, - "MemoryGB": 4 - }, - { - "Id": "i-97a108898968f0007", - "Type": "t2.micro", - "Name": "identity-dev-orderer2", - "State": "stopped", - "Environment": "identity-dev", - "VCPU": 1, - "MemoryGB": 1 - } - ], - "TotalvCPU": 0, - "TotalMemoryGB": 0, - "State": "stopped" - }, - { - "Name": "kube", - "Instances": [ - { - "Id": "i-9dedc66553eaecfc3", - "Type": "t3.medium", - "Name": "kube-k8master2", - "State": "stopped", - "Environment": "kube", - "VCPU": 2, - "MemoryGB": 4 - }, - { - "Id": "i-9008ad1bfd83a52eb", - "Type": "t3.xlarge", - "Name": "kube-k8node2", - "State": "stopped", - "Environment": "kube", - "VCPU": 4, - "MemoryGB": 16 - }, - { - "Id": "i-94b69b4ec92d548df", - "Type": "t3.medium", - "Name": "kube-k8master1", - "State": "stopped", - "Environment": "kube", - "VCPU": 2, - "MemoryGB": 4 - }, - { - "Id": "i-9778ddf78ec72bffd", - "Type": "t3.small", - "Name": "kube-etcd3", - "State": "stopped", - "Environment": "kube", - "VCPU": 2, - "MemoryGB": 2 - }, - { - "Id": "i-93b3782294e848647", - "Type": "t3.small", - "Name": "kube-etcd1", - "State": "stopped", - "Environment": "kube", - "VCPU": 2, - "MemoryGB": 2 - }, - { - "Id": "i-9872ea25c0766d383", - "Type": "t3.xlarge", - "Name": "kube-k8node5", - "State": "stopped", - "Environment": "kube", - "VCPU": 4, - "MemoryGB": 16 - }, - { - "Id": "i-9e9fcaf646ce779ab", - "Type": "t3.xlarge", - "Name": "kube-k8node3", - "State": "stopped", - "Environment": "kube", - "VCPU": 4, - "MemoryGB": 16 - }, - { - "Id": "i-9eba74077ac760573", - "Type": "t3.small", - "Name": "kube-etcd2", - "State": "stopped", - "Environment": "kube", - "VCPU": 2, - "MemoryGB": 2 - }, - { - "Id": "i-9d67730effbee8b3b", - "Type": "t3.xlarge", - "Name": "kube-k8node1", - "State": "stopped", - "Environment": "kube", - "VCPU": 4, - "MemoryGB": 16 - }, - { - "Id": "i-909517923633b51f4", - "Type": "t3.xlarge", - "Name": "kube-k8node4", - "State": "stopped", - "Environment": "kube", - "VCPU": 4, - "MemoryGB": 16 - } - ], - "TotalvCPU": 0, - "TotalMemoryGB": 0, - "State": "stopped" - } -] diff --git a/www/static/aws-power-toggle.js b/www/static/aws-power-toggle.js index 43e3a23..d3cc2a4 100644 --- a/www/static/aws-power-toggle.js +++ b/www/static/aws-power-toggle.js @@ -12,7 +12,7 @@ $(document).on('click','.start-button',function(){ $.ajax({ type: "POST", dataType: "json", - url: '/api/env/startup/' + $(this).data('env'), + url: '/api/v1/env/' + $(this).data('env') + '/start', beforeSend: function(){ button.innerHTML = ' sending'; @@ -35,7 +35,7 @@ $(document).on('click','.stop-button',function(){ $.ajax({ type: "POST", dataType: "json", - url: '/api/env/powerdown/' + $(this).data('env'), + url: '/api/v1/env/' + $(this).data('env') + '/stop', beforeSend: function(){ button.innerHTML = ' sending'; @@ -64,7 +64,7 @@ function drawEnvs(envDataAjax) { // loop through all envs for(var i = 0; i < envDataAjax.length; i++) { var env = envDataAjax[i]; - var running = env.RunningInstances + '/' + env.TotalInstances + var running = env.running_instances + '/' + env.total_instances iconStart = document.createElement('i'); iconStart.classList.add("fa", "fa-play"); @@ -79,6 +79,9 @@ function drawEnvs(envDataAjax) { labelChanging = document.createElement('span'); labelChanging.classList.add("badge", "badge-warning"); labelChanging.innerText = "changing"; + labelMixed = document.createElement('span'); + labelMixed.classList.add("badge", "badge-warning"); + labelMixed.innerText = "mixed"; buttonStart = document.createElement('button'); buttonStart.classList.add("btn", "btn-info", "start-button"); @@ -86,7 +89,7 @@ function drawEnvs(envDataAjax) { buttonStartText.innerText = " START"; buttonStart.appendChild(iconStart); buttonStart.appendChild(buttonStartText); - buttonStart.dataset.env = env.Name; + buttonStart.dataset.env = env.id; buttonStop = document.createElement('button'); buttonStop.classList.add("btn", "btn-secondary", "stop-button"); @@ -94,7 +97,7 @@ function drawEnvs(envDataAjax) { buttonStopText.innerText = " STOP"; buttonStop.appendChild(iconStop); buttonStop.appendChild(buttonStopText); - buttonStop.dataset.env = env.Name; + buttonStop.dataset.env = env.id; divCardBody = document.createElement('div'); divCardBody.classList.add("card-body"); @@ -104,13 +107,15 @@ function drawEnvs(envDataAjax) { divCardHeader = document.createElement('h5'); divCardHeader.classList.add("card-header"); - divCardHeader.textContent = env.Name; - if (env.State == "running") { + divCardHeader.textContent = env.name; + if (env.state == "running") { divCardHeader.appendChild(labelRunning); - } else if (env.State == "stopped") { + } else if (env.state == "stopped") { divCardHeader.appendChild(labelStopped); - } else if (env.State == "changing-state") { + } else if (env.state == "changing") { divCardHeader.appendChild(labelChanging); + } else { + divCardHeader.appendChild(labelMixed); } divCard = document.createElement('div'); @@ -137,7 +142,7 @@ async function writeEnvs() { $.ajax({ type: "GET", dataType: "json", - url: '/api/env/summary', + url: '/api/v1/env/summary', success: function(envDataResponse) { // clean loading screen