diff --git a/public/app.json b/public/app.json new file mode 100644 index 0000000..b90ddf6 --- /dev/null +++ b/public/app.json @@ -0,0 +1,1146 @@ +{ + "kind": "List", + "apiVersion": "v1", + "metadata": {}, + "items": [ + { + "kind": "DeploymentConfig", + "apiVersion": "v1", + "metadata": { + "name": "amq-test-php", + "generation": 1, + "creationTimestamp": null, + "labels": { + "app": "amq-test-php" + }, + "annotations": { + "openshift.io/generated-by": "OpenShiftWebConsole" + } + }, + "spec": { + "strategy": { + "type": "Rolling", + "rollingParams": { + "updatePeriodSeconds": 1, + "intervalSeconds": 1, + "timeoutSeconds": 600, + "maxUnavailable": "25%", + "maxSurge": "25%" + }, + "resources": {}, + "activeDeadlineSeconds": 21600 + }, + "triggers": [ + { + "type": "ImageChange", + "imageChangeParams": { + "automatic": true, + "containerNames": [ + "amq-test-php" + ], + "from": { + "kind": "ImageStreamTag", + "namespace": "amq-test", + "name": "amq-test-php:latest" + } + } + }, + { + "type": "ConfigChange" + } + ], + "replicas": 1, + "test": false, + "selector": { + "deploymentconfig": "amq-test-php" + }, + "template": { + "metadata": { + "creationTimestamp": null, + "labels": { + "app": "amq-test-php", + "deploymentconfig": "amq-test-php" + } + }, + "spec": { + "containers": [ + { + "name": "amq-test-php", + "image": "172.30.1.1:5000/amq-test/amq-test-php@sha256:165c5c4184fb88c1b7f0cd62b19c53dac44834a27bdd43540a20fea91c53cb0e", + "ports": [ + { + "containerPort": 8080, + "protocol": "TCP" + }, + { + "containerPort": 8443, + "protocol": "TCP" + } + ], + "resources": {}, + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "File", + "imagePullPolicy": "Always" + } + ], + "restartPolicy": "Always", + "terminationGracePeriodSeconds": 30, + "dnsPolicy": "ClusterFirst", + "securityContext": {}, + "schedulerName": "default-scheduler" + } + } + }, + "status": { + "latestVersion": 0, + "observedGeneration": 0, + "replicas": 0, + "updatedReplicas": 0, + "availableReplicas": 0, + "unavailableReplicas": 0 + } + }, + { + "kind": "DeploymentConfig", + "apiVersion": "v1", + "metadata": { + "name": "broker-amq", + "generation": 1, + "creationTimestamp": null, + "labels": { + "app": "amq63-persistent", + "application": "broker", + "template": "amq63-persistent", + "xpaas": "1.4.12" + } + }, + "spec": { + "strategy": { + "type": "Rolling", + "rollingParams": { + "updatePeriodSeconds": 1, + "intervalSeconds": 1, + "timeoutSeconds": 600, + "maxUnavailable": "25%", + "maxSurge": 0 + }, + "resources": {}, + "activeDeadlineSeconds": 21600 + }, + "triggers": [ + { + "type": "ImageChange", + "imageChangeParams": { + "automatic": true, + "containerNames": [ + "broker-amq" + ], + "from": { + "kind": "ImageStreamTag", + "namespace": "openshift", + "name": "jboss-amq-63:1.3" + } + } + }, + { + "type": "ConfigChange" + } + ], + "replicas": 0, + "test": false, + "selector": { + "deploymentConfig": "broker-amq" + }, + "template": { + "metadata": { + "name": "broker-amq", + "creationTimestamp": null, + "labels": { + "application": "broker", + "deploymentConfig": "broker-amq" + } + }, + "spec": { + "volumes": [ + { + "name": "broker-amq-pvol", + "persistentVolumeClaim": { + "claimName": "broker-amq-claim" + } + } + ], + "containers": [ + { + "name": "broker-amq", + "image": "registry.access.redhat.com/jboss-amq-6/amq63-openshift@sha256:3981a66428347bd3874d1146390db35278ffab56d8eb736ceedf3971950d2631", + "ports": [ + { + "name": "jolokia", + "containerPort": 8778, + "protocol": "TCP" + }, + { + "name": "amqp", + "containerPort": 5672, + "protocol": "TCP" + }, + { + "name": "mqtt", + "containerPort": 1883, + "protocol": "TCP" + }, + { + "name": "stomp", + "containerPort": 61613, + "protocol": "TCP" + }, + { + "name": "tcp", + "containerPort": 61616, + "protocol": "TCP" + } + ], + "env": [ + { + "name": "AMQ_TRANSPORTS", + "value": "openwire" + }, + { + "name": "AMQ_QUEUES", + "value": "test" + }, + { + "name": "AMQ_TOPICS", + "value": "test" + }, + { + "name": "MQ_SERIALIZABLE_PACKAGES" + }, + { + "name": "AMQ_SPLIT", + "value": "true" + }, + { + "name": "AMQ_MESH_DISCOVERY_TYPE", + "value": "dns" + }, + { + "name": "AMQ_MESH_SERVICE_NAME", + "value": "broker-amq-mesh" + }, + { + "name": "AMQ_MESH_SERVICE_NAMESPACE", + "valueFrom": { + "fieldRef": { + "apiVersion": "v1", + "fieldPath": "metadata.namespace" + } + } + }, + { + "name": "AMQ_STORAGE_USAGE_LIMIT", + "value": "100 gb" + }, + { + "name": "AMQ_QUEUE_MEMORY_LIMIT" + }, + { + "name": "AMQ_USER", + "valueFrom": { + "configMapKeyRef": { + "name": "amq-auth", + "key": "amq.user" + } + } + }, + { + "name": "AMQ_PASSWORD", + "valueFrom": { + "configMapKeyRef": { + "name": "amq-auth", + "key": "amq.password" + } + } + } + ], + "resources": {}, + "volumeMounts": [ + { + "name": "broker-amq-pvol", + "mountPath": "/opt/amq/data" + } + ], + "readinessProbe": { + "exec": { + "command": [ + "/bin/bash", + "-c", + "/opt/amq/bin/readinessProbe.sh" + ] + }, + "timeoutSeconds": 1, + "periodSeconds": 10, + "successThreshold": 1, + "failureThreshold": 3 + }, + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "File", + "imagePullPolicy": "Always" + } + ], + "restartPolicy": "Always", + "terminationGracePeriodSeconds": 60, + "dnsPolicy": "ClusterFirst", + "securityContext": {}, + "schedulerName": "default-scheduler" + } + } + }, + "status": { + "latestVersion": 0, + "observedGeneration": 0, + "replicas": 0, + "updatedReplicas": 0, + "availableReplicas": 0, + "unavailableReplicas": 0 + } + }, + { + "kind": "DeploymentConfig", + "apiVersion": "v1", + "metadata": { + "name": "broker-drainer", + "generation": 1, + "creationTimestamp": null, + "labels": { + "app": "amq63-persistent", + "application": "broker", + "template": "amq63-persistent", + "xpaas": "1.4.12" + } + }, + "spec": { + "strategy": { + "type": "Recreate", + "recreateParams": { + "timeoutSeconds": 600 + }, + "resources": {}, + "activeDeadlineSeconds": 21600 + }, + "triggers": [ + { + "type": "ImageChange", + "imageChangeParams": { + "automatic": true, + "containerNames": [ + "broker-drainer" + ], + "from": { + "kind": "ImageStreamTag", + "namespace": "openshift", + "name": "jboss-amq-63:1.3" + } + } + }, + { + "type": "ConfigChange" + } + ], + "replicas": 0, + "test": false, + "selector": { + "deploymentConfig": "broker-drainer" + }, + "template": { + "metadata": { + "name": "broker-drainer", + "creationTimestamp": null, + "labels": { + "application": "broker", + "deploymentConfig": "broker-drainer" + } + }, + "spec": { + "volumes": [ + { + "name": "broker-amq-pvol", + "persistentVolumeClaim": { + "claimName": "broker-amq-claim" + } + } + ], + "containers": [ + { + "name": "broker-drainer", + "image": "registry.access.redhat.com/jboss-amq-6/amq63-openshift@sha256:3981a66428347bd3874d1146390db35278ffab56d8eb736ceedf3971950d2631", + "command": [ + "/opt/amq/bin/drain.sh" + ], + "ports": [ + { + "name": "jolokia", + "containerPort": 8778, + "protocol": "TCP" + }, + { + "name": "tcp", + "containerPort": 61616, + "protocol": "TCP" + } + ], + "env": [ + { + "name": "AMQ_USER", + "value": "userkav" + }, + { + "name": "AMQ_PASSWORD", + "value": "wYXWewvt" + }, + { + "name": "AMQ_MESH_SERVICE_NAME", + "value": "broker-amq-mesh" + }, + { + "name": "AMQ_MESH_SERVICE_NAMESPACE", + "valueFrom": { + "fieldRef": { + "apiVersion": "v1", + "fieldPath": "metadata.namespace" + } + } + } + ], + "resources": {}, + "volumeMounts": [ + { + "name": "broker-amq-pvol", + "mountPath": "/opt/amq/data" + } + ], + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "File", + "imagePullPolicy": "Always" + } + ], + "restartPolicy": "Always", + "terminationGracePeriodSeconds": 60, + "dnsPolicy": "ClusterFirst", + "securityContext": {}, + "schedulerName": "default-scheduler" + } + } + }, + "status": { + "latestVersion": 0, + "observedGeneration": 0, + "replicas": 0, + "updatedReplicas": 0, + "availableReplicas": 0, + "unavailableReplicas": 0 + } + }, + { + "kind": "DeploymentConfig", + "apiVersion": "v1", + "metadata": { + "name": "s2i-spring-boot-camel-amq", + "generation": 1, + "creationTimestamp": null, + "labels": { + "app": "s2i-spring-boot-camel-amq", + "component": "s2i-spring-boot-camel-amq", + "group": "quickstarts", + "project": "s2i-spring-boot-camel-amq", + "provider": "s2i", + "template": "s2i-spring-boot-camel-amq", + "version": "1.0.0.redhat-000067" + } + }, + "spec": { + "strategy": { + "type": "Rolling", + "rollingParams": { + "updatePeriodSeconds": 1, + "intervalSeconds": 1, + "timeoutSeconds": 600, + "maxUnavailable": "25%", + "maxSurge": "25%" + }, + "resources": {}, + "activeDeadlineSeconds": 21600 + }, + "triggers": [ + { + "type": "ConfigChange" + }, + { + "type": "ImageChange", + "imageChangeParams": { + "automatic": true, + "containerNames": [ + "s2i-spring-boot-camel-amq" + ], + "from": { + "kind": "ImageStreamTag", + "namespace": "amq-test", + "name": "s2i-spring-boot-camel-amq:latest" + } + } + } + ], + "replicas": 0, + "test": false, + "selector": { + "component": "s2i-spring-boot-camel-amq", + "deploymentconfig": "s2i-spring-boot-camel-amq", + "group": "quickstarts", + "project": "s2i-spring-boot-camel-amq", + "provider": "s2i", + "version": "1.0.0.redhat-000067" + }, + "template": { + "metadata": { + "creationTimestamp": null, + "labels": { + "component": "s2i-spring-boot-camel-amq", + "deploymentconfig": "s2i-spring-boot-camel-amq", + "group": "quickstarts", + "project": "s2i-spring-boot-camel-amq", + "provider": "s2i", + "version": "1.0.0.redhat-000067" + } + }, + "spec": { + "containers": [ + { + "name": "s2i-spring-boot-camel-amq", + "image": "172.30.1.1:5000/amq-test/s2i-spring-boot-camel-amq@sha256:7e031a538c1a4ff3110c708f9361eb62e4d7c27ad562046baccab093d77848bd", + "ports": [ + { + "name": "jolokia", + "containerPort": 8778, + "protocol": "TCP" + } + ], + "env": [ + { + "name": "KUBERNETES_NAMESPACE", + "valueFrom": { + "fieldRef": { + "apiVersion": "v1", + "fieldPath": "metadata.namespace" + } + } + }, + { + "name": "ACTIVEMQ_BROKER_USERNAME", + "valueFrom": { + "configMapKeyRef": { + "name": "amq-auth", + "key": "amq.user" + } + } + }, + { + "name": "ACTIVEMQ_BROKER_PASSWORD", + "valueFrom": { + "configMapKeyRef": { + "name": "amq-auth", + "key": "amq.password" + } + } + }, + { + "name": "ACTIVEMQ_SERVICE_NAME", + "valueFrom": { + "configMapKeyRef": { + "name": "amq-auth", + "key": "amq.service" + } + } + } + ], + "resources": { + "limits": { + "cpu": "1" + }, + "requests": { + "cpu": "200m" + } + }, + "livenessProbe": { + "httpGet": { + "path": "/health", + "port": 8081, + "scheme": "HTTP" + }, + "initialDelaySeconds": 180, + "timeoutSeconds": 1, + "periodSeconds": 10, + "successThreshold": 1, + "failureThreshold": 3 + }, + "readinessProbe": { + "httpGet": { + "path": "/health", + "port": 8081, + "scheme": "HTTP" + }, + "initialDelaySeconds": 10, + "timeoutSeconds": 1, + "periodSeconds": 10, + "successThreshold": 1, + "failureThreshold": 3 + }, + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "File", + "imagePullPolicy": "Always" + } + ], + "restartPolicy": "Always", + "terminationGracePeriodSeconds": 30, + "dnsPolicy": "ClusterFirst", + "securityContext": {}, + "schedulerName": "default-scheduler" + } + } + }, + "status": { + "latestVersion": 0, + "observedGeneration": 0, + "replicas": 0, + "updatedReplicas": 0, + "availableReplicas": 0, + "unavailableReplicas": 0 + } + }, + { + "kind": "BuildConfig", + "apiVersion": "v1", + "metadata": { + "name": "amq-test-php", + "creationTimestamp": null, + "labels": { + "app": "amq-test-php" + }, + "annotations": { + "openshift.io/generated-by": "OpenShiftWebConsole" + } + }, + "spec": { + "triggers": [ + { + "type": "ImageChange", + "imageChange": {} + }, + { + "type": "ConfigChange" + }, + { + "type": "Generic", + "generic": { + "secret": "bd39cea3805f1d71" + } + }, + { + "type": "GitHub", + "github": { + "secret": "d273402c08f8a7d5" + } + } + ], + "runPolicy": "Serial", + "source": { + "type": "Git", + "git": { + "uri": "https://github.com/openshift/cakephp-ex.git", + "ref": "master" + } + }, + "strategy": { + "type": "Source", + "sourceStrategy": { + "from": { + "kind": "ImageStreamTag", + "namespace": "openshift", + "name": "php:7.1" + } + } + }, + "output": { + "to": { + "kind": "ImageStreamTag", + "name": "amq-test-php:latest" + } + }, + "resources": {}, + "postCommit": {}, + "nodeSelector": null + }, + "status": { + "lastVersion": 0 + } + }, + { + "kind": "BuildConfig", + "apiVersion": "v1", + "metadata": { + "name": "s2i-spring-boot-camel-amq", + "creationTimestamp": null, + "labels": { + "app": "s2i-spring-boot-camel-amq", + "component": "s2i-spring-boot-camel-amq", + "group": "quickstarts", + "project": "s2i-spring-boot-camel-amq", + "provider": "s2i", + "template": "s2i-spring-boot-camel-amq", + "version": "1.0.0.redhat-000067" + } + }, + "spec": { + "triggers": [ + { + "type": "GitHub", + "github": { + "secret": "Rtityt2rfjl4HhRRP6JwKCXCOrAlIfftjVHwwdyb" + } + }, + { + "type": "Generic", + "generic": { + "secret": "Rtityt2rfjl4HhRRP6JwKCXCOrAlIfftjVHwwdyb" + } + }, + { + "type": "ConfigChange" + }, + { + "type": "ImageChange", + "imageChange": {} + } + ], + "runPolicy": "Serial", + "source": { + "type": "Git", + "git": { + "uri": "https://github.com/fabric8-quickstarts/spring-boot-camel-amq.git", + "ref": "spring-boot-camel-amq-1.0.0.redhat-000067" + } + }, + "strategy": { + "type": "Source", + "sourceStrategy": { + "from": { + "kind": "ImageStreamTag", + "namespace": "openshift", + "name": "fis-java-openshift:2.0" + }, + "env": [ + { + "name": "BUILD_LOGLEVEL", + "value": "5" + }, + { + "name": "ARTIFACT_DIR" + }, + { + "name": "MAVEN_ARGS", + "value": "package -DskipTests -Dfabric8.skip -e -B" + }, + { + "name": "MAVEN_ARGS_APPEND" + } + ], + "incremental": true, + "forcePull": true + } + }, + "output": { + "to": { + "kind": "ImageStreamTag", + "name": "s2i-spring-boot-camel-amq:latest" + } + }, + "resources": {}, + "postCommit": {}, + "nodeSelector": null + }, + "status": { + "lastVersion": 0 + } + }, + { + "kind": "ImageStream", + "apiVersion": "v1", + "metadata": { + "name": "amq-test-php", + "generation": 1, + "creationTimestamp": null, + "labels": { + "app": "amq-test-php" + }, + "annotations": { + "openshift.io/generated-by": "OpenShiftWebConsole" + } + }, + "spec": { + "lookupPolicy": { + "local": false + }, + "tags": [ + { + "name": "latest", + "annotations": null, + "from": { + "kind": "DockerImage", + "name": "172.30.1.1:5000/amq-test/amq-test-php:latest" + }, + "generation": null, + "importPolicy": {}, + "referencePolicy": { + "type": "" + } + } + ] + }, + "status": { + "dockerImageRepository": "" + } + }, + { + "kind": "ImageStream", + "apiVersion": "v1", + "metadata": { + "name": "s2i-spring-boot-camel-amq", + "generation": 1, + "creationTimestamp": null, + "labels": { + "app": "s2i-spring-boot-camel-amq", + "component": "s2i-spring-boot-camel-amq", + "group": "quickstarts", + "project": "s2i-spring-boot-camel-amq", + "provider": "s2i", + "template": "s2i-spring-boot-camel-amq", + "version": "1.0.0.redhat-000067" + } + }, + "spec": { + "lookupPolicy": { + "local": false + }, + "tags": [ + { + "name": "latest", + "annotations": null, + "from": { + "kind": "DockerImage", + "name": "172.30.1.1:5000/amq-test/s2i-spring-boot-camel-amq:latest" + }, + "generation": null, + "importPolicy": {}, + "referencePolicy": { + "type": "" + } + } + ] + }, + "status": { + "dockerImageRepository": "" + } + }, + { + "kind": "Service", + "apiVersion": "v1", + "metadata": { + "name": "amq-test-php", + "creationTimestamp": null, + "labels": { + "app": "amq-test-php" + }, + "annotations": { + "openshift.io/generated-by": "OpenShiftWebConsole" + } + }, + "spec": { + "ports": [ + { + "name": "8080-tcp", + "protocol": "TCP", + "port": 8080, + "targetPort": 8080 + } + ], + "selector": { + "deploymentconfig": "amq-test-php" + }, + "type": "ClusterIP", + "sessionAffinity": "None" + }, + "status": { + "loadBalancer": {} + } + }, + { + "kind": "Service", + "apiVersion": "v1", + "metadata": { + "name": "broker-amq-amqp", + "creationTimestamp": null, + "labels": { + "app": "amq63-persistent", + "application": "broker", + "template": "amq63-persistent", + "xpaas": "1.4.12" + }, + "annotations": { + "description": "The broker's AMQP port." + } + }, + "spec": { + "ports": [ + { + "protocol": "TCP", + "port": 5672, + "targetPort": 5672 + } + ], + "selector": { + "deploymentConfig": "broker-amq" + }, + "type": "ClusterIP", + "sessionAffinity": "None" + }, + "status": { + "loadBalancer": {} + } + }, + { + "kind": "Service", + "apiVersion": "v1", + "metadata": { + "name": "broker-amq-mesh", + "creationTimestamp": null, + "labels": { + "app": "amq63-persistent", + "application": "broker", + "template": "amq63-persistent", + "xpaas": "1.4.12" + }, + "annotations": { + "description": "Supports node discovery for mesh formation.", + "service.alpha.kubernetes.io/tolerate-unready-endpoints": "true" + } + }, + "spec": { + "ports": [ + { + "name": "mesh", + "protocol": "TCP", + "port": 61616, + "targetPort": 61616 + } + ], + "selector": { + "deploymentConfig": "broker-amq" + }, + "clusterIP": "None", + "type": "ClusterIP", + "sessionAffinity": "None" + }, + "status": { + "loadBalancer": {} + } + }, + { + "kind": "Service", + "apiVersion": "v1", + "metadata": { + "name": "broker-amq-mqtt", + "creationTimestamp": null, + "labels": { + "app": "amq63-persistent", + "application": "broker", + "template": "amq63-persistent", + "xpaas": "1.4.12" + }, + "annotations": { + "description": "The broker's MQTT port." + } + }, + "spec": { + "ports": [ + { + "protocol": "TCP", + "port": 1883, + "targetPort": 1883 + } + ], + "selector": { + "deploymentConfig": "broker-amq" + }, + "type": "ClusterIP", + "sessionAffinity": "None" + }, + "status": { + "loadBalancer": {} + } + }, + { + "kind": "Service", + "apiVersion": "v1", + "metadata": { + "name": "broker-amq-stomp", + "creationTimestamp": null, + "labels": { + "app": "amq63-persistent", + "application": "broker", + "template": "amq63-persistent", + "xpaas": "1.4.12" + }, + "annotations": { + "description": "The broker's STOMP port." + } + }, + "spec": { + "ports": [ + { + "protocol": "TCP", + "port": 61613, + "targetPort": 61613 + } + ], + "selector": { + "deploymentConfig": "broker-amq" + }, + "type": "ClusterIP", + "sessionAffinity": "None" + }, + "status": { + "loadBalancer": {} + } + }, + { + "kind": "Service", + "apiVersion": "v1", + "metadata": { + "name": "broker-amq-tcp", + "creationTimestamp": null, + "labels": { + "app": "amq63-persistent", + "application": "broker", + "template": "amq63-persistent", + "xpaas": "1.4.12" + }, + "annotations": { + "description": "The broker's OpenWire port.", + "service.alpha.openshift.io/dependencies": "[{\"name\": \"broker-amq-amqp\", \"kind\": \"Service\"},{\"name\": \"broker-amq-mqtt\", \"kind\": \"Service\"},{\"name\": \"broker-amq-stomp\", \"kind\": \"Service\"}]" + } + }, + "spec": { + "ports": [ + { + "protocol": "TCP", + "port": 61616, + "targetPort": 61616 + } + ], + "selector": { + "deploymentConfig": "broker-amq" + }, + "type": "ClusterIP", + "sessionAffinity": "None" + }, + "status": { + "loadBalancer": {} + } + }, + { + "kind": "Route", + "apiVersion": "v1", + "metadata": { + "name": "amq-test-php", + "creationTimestamp": null, + "labels": { + "app": "amq-test-php" + }, + "annotations": { + "openshift.io/generated-by": "OpenShiftWebConsole", + "openshift.io/host.generated": "true" + } + }, + "spec": { + "host": "amq-test-php-amq-test.192.168.42.179.nip.io", + "to": { + "kind": "Service", + "name": "amq-test-php", + "weight": 100 + }, + "port": { + "targetPort": "8080-tcp" + }, + "wildcardPolicy": "None" + }, + "status": { + "ingress": [ + { + "host": "amq-test-php-amq-test.192.168.42.179.nip.io", + "routerName": "router", + "conditions": [ + { + "type": "Admitted", + "status": "True", + "lastTransitionTime": "2018-07-22T16:33:30Z" + } + ], + "wildcardPolicy": "None" + } + ] + } + }, + { + "kind": "ConfigMap", + "apiVersion": "v1", + "metadata": { + "name": "amq-auth", + "creationTimestamp": null + }, + "data": { + "amq.password": "wYXWewvt", + "amq.service": "broker-amq-tcp", + "amq.user": "userkav" + } + }, + { + "kind": "PersistentVolumeClaim", + "apiVersion": "v1", + "metadata": { + "name": "broker-amq-claim", + "creationTimestamp": null, + "labels": { + "app": "amq63-persistent", + "application": "broker", + "template": "amq63-persistent", + "xpaas": "1.4.12" + }, + "annotations": { + "pv.kubernetes.io/bind-completed": "yes", + "pv.kubernetes.io/bound-by-controller": "yes" + } + }, + "spec": { + "accessModes": [ + "ReadWriteMany" + ], + "resources": { + "requests": { + "storage": "1Gi" + } + }, + "volumeName": "pv0042" + }, + "status": {} + } + ] +} diff --git a/src/App.js b/src/App.js index c6a8ae1..50d42ae 100644 --- a/src/App.js +++ b/src/App.js @@ -4,7 +4,7 @@ import 'semantic-ui-css/semantic.min.css'; import { Dimmer, Loader } from 'semantic-ui-react'; import './App.css'; import TMainPage from './t-design/MainPage'; -import T2MainPage from './t2-design/MainPage'; +import DiagramWithTemplate from './t2-design/DiagramWithTemplate'; import GMainPage from './g-design/MainPage'; import Home from './pages/Home'; import BoosterMatrix from './pages/BoosterMatrix'; @@ -31,7 +31,7 @@ class App extends Component { - + diff --git a/src/t2-design/DiagramWithTemplate.css b/src/t2-design/DiagramWithTemplate.css new file mode 100644 index 0000000..2a0c070 --- /dev/null +++ b/src/t2-design/DiagramWithTemplate.css @@ -0,0 +1,34 @@ +.t2-design-withtemplate { + display: flex; + width: 100%; + height: 100%; +} + +.t2-design-withtemplate table { + width: 100%; + height: 100%; +} + +.t2-design-withtemplate td { + padding: 0px; + margin: 0px; +} + +.templatecell { + width: 40%; +} + +.templatecontainer { + width: 100%; + height: 100%; +} + +.templatebox { + width: 100%; + height: 100%; +} + +.templatebox textarea { + width: 100%; + height: 400px; +} \ No newline at end of file diff --git a/src/t2-design/DiagramWithTemplate.js b/src/t2-design/DiagramWithTemplate.js new file mode 100644 index 0000000..acd985e --- /dev/null +++ b/src/t2-design/DiagramWithTemplate.js @@ -0,0 +1,166 @@ +import React from 'react'; +import classNames from 'classnames'; +import _ from "lodash"; + +import { Form } from 'semantic-ui-react' + +import Topology from "./components/Topology"; + +import './DiagramWithTemplate.css'; + +class DiagramWithTemplate extends React.Component { + + constructor(props) { + super(props); + this.state = { + selectedItemId: null, + templateJson: null, + layout: { + nodes: { + r1: {type: 'route', belongsTo: 's1'}, + s1: {type: 'service', name: 'Placeholder'}, + d1: {type: 'storage', belongsTo: 's1'}, + }, + edges: { + l1: {from: 'r1', to: 's1'}, + l2: {from: 's1', to: 'd1'}, + } + } + }; + } + + componentDidMount() { + fetch("/app.json") + .then(response => response.text()) + .then(text => this.updateLayoutFromText(text)); + } + + updateLayoutFromText = (text) => { + let json = JSON.parse(text); + this.setState({templateText: text, templateJson: json, layout: this.templateToLayout(json)}) + } + + templateToLayout = (template) => { + let layout = { nodes: {}, edges: {} }; + + // First find and transform our "services" + this.itemsByKind(template, "DeploymentConfig").forEach(item => this.transformDeploymentConfig(layout, template, item)); + + // Find and transform Routes + this.itemsByKind(template, "Route").forEach(item => this.transformRoute(layout, template, item)); + + // Find and transform ConfigMaps + this.itemsByKind(template, "ConfigMap").forEach(item => this.transformConfigMap(layout, template, item)); + + // Find and transform PersistentVolumeClaims + this.itemsByKind(template, "PersistentVolumeClaim").forEach(item => this.transformPersistentVolumeClaim(layout, template, item)); + + return layout; + } + + // DeploymentConfigs, BuildConfigs and Services + + transformDeploymentConfig = (layout, template, item) => { + let hasBC = this.itemsByKind(template, "BuildConfig").filter(i => i.metadata.name === item.metadata.name).length > 0; + let services = this.itemsByKind(template, "Service").filter(i => this.deploymentConfigSelector(i) === item.metadata.name).map(i => i.metadata.name); + layout.nodes[this.serviceId(item)] = ({ type: 'service', name: item.metadata.name, hasBuildConfig: hasBC, services: services }); + } + + serviceId = (item) => this.serviceIdFromName(item.metadata.name); + + serviceIdFromName = (name) => 'srv-' + name; + + // Routes + + transformRoute = (layout, template, item) => { + let id = this.routeId(item); + let to = this.routeBelongsTo(layout, template, item); + layout.nodes[id] = ({ type: 'route', name: item.metadata.name, belongsTo: to }); + layout.edges[id+"-"+to] = ({ type: 'line', from: id, to: to }); + } + + routeBelongsTo = (layout, template, item) => { + let srvKind = item.spec.to.kind; + let srvName = item.spec.to.name; + let items = this.itemsByKind(template, srvKind).filter(i => i.metadata.name === srvName); + return this.serviceIdFromName(this.deploymentConfigSelector(items[0])); + } + + routeId = (item) => 'r-' + item.metadata.name; + + // ConfigMaps + + transformConfigMap = (layout, template, item) => { + let id = this.configMapId(item); + layout.nodes[id] = ({ type: 'configmap', name: item.metadata.name }); + + // Try making connections + this.itemsByKind(template, "DeploymentConfig") + .filter(i => _.get(i, 'spec.template.spec.containers', []) + .filter(v => _.get(v, 'env', []) + .filter(e => _.get(e, 'valueFrom.configMapKeyRef.name') === item.metadata.name).length > 0).length > 0) + .forEach(s => { + let to = this.serviceId(s); + layout.edges[id+"-"+to] = ({ type: 'line', from: id, to: to }); + }); + } + + configMapId = (item) => 'cm-' + item.metadata.name; + + // PersistentVolumeClaims + + transformPersistentVolumeClaim = (layout, template, item) => { + let id = this.persistentVolumeClaimId(item); + layout.nodes[id] = ({ type: 'storage', name: item.metadata.name }); + + // Try making connections + this.itemsByKind(template, "DeploymentConfig") + .filter(i => _.get(i, 'spec.template.spec.volumes', []) + .filter(v => _.get(v, 'persistentVolumeClaim.claimName') === item.metadata.name).length > 0) + .forEach(s => { + let to = this.serviceId(s); + layout.edges[id+"-"+to] = ({ type: 'line', from: id, to: to }); + }); + } + + persistentVolumeClaimId = (item) => 'pvc-' + item.metadata.name; + + deploymentConfigSelector = (item) => _.get(item, 'spec.selector.deploymentconfig', _.get(item, 'spec.selector.deploymentConfig')); + + itemsByKind = (template, kind) => + template.items.filter(i => kind.toLowerCase() === i.kind.toLowerCase()); + + onSelectItem = (id, item) => { + this.setState({selectedItemId: id}); + } + + render() { + return ( +
+ + + + + + + +
+ + +
+
+ this.setState({templateText: t.value})} + wrap="off" /> + this.updateLayoutFromText(this.state.templateText)}>Apply + +
+
+
+ ); + } +} + +export default DiagramWithTemplate; diff --git a/src/t2-design/MainPage.css b/src/t2-design/MainPage.css deleted file mode 100644 index 1d53d58..0000000 --- a/src/t2-design/MainPage.css +++ /dev/null @@ -1,2 +0,0 @@ -.t2-design-mainpage { -} diff --git a/src/t2-design/MainPage.js b/src/t2-design/MainPage.js deleted file mode 100644 index f6d6fa0..0000000 --- a/src/t2-design/MainPage.js +++ /dev/null @@ -1,46 +0,0 @@ -import React from 'react'; -import PropTypes from "prop-types"; - -import Topology from "./components/Topology"; - -import './MainPage.css'; - -class MainPage extends React.Component { - - constructor(props) { - super(props); - this.state = { - selectedItemId: null, - }; - } - - onSelectItem = (item) => { - this.setState({selectedItemId: item.id}); - } - - render() { - let topo = { - nodes: { - r1: {type: 'route', belongsTo: 's1'}, - s1: {type: 'service', name: 'Vert.x'}, - s2: {type: 'service', name: 'PostgreSQL', icon: 'database'}, - s3: {type: 'service', name: 'AMQ Broker', icon: 'envelope outline'}, - cm1: {type: 'configmap', belongsTo: 's2'}, - d1: {type: 'storage', belongsTo: 's2'}, - }, - edges: { - l1: {from: 'r1', to: 's1'}, - l2: {from: 's1', to: 'cm1'}, - l3: {from: 's2', to: 'cm1'}, - l4: {from: 's2', to: 'd1'}, - } - }; - return ( -
- -
- ); - } -} - -export default MainPage; diff --git a/src/t2-design/components/ConfigMap.js b/src/t2-design/components/ConfigMap.js index 762bf7a..909107f 100644 --- a/src/t2-design/components/ConfigMap.js +++ b/src/t2-design/components/ConfigMap.js @@ -1,6 +1,4 @@ import React from 'react'; -import PropTypes from 'prop-types'; -import classNames from 'classnames'; import IconItem from "./IconItem"; diff --git a/src/t2-design/components/DOMRef.js b/src/t2-design/components/DOMRef.js index 9615df4..c3ff547 100644 --- a/src/t2-design/components/DOMRef.js +++ b/src/t2-design/components/DOMRef.js @@ -4,10 +4,6 @@ import PropTypes from 'prop-types'; class DOMRef extends React.Component { - constructor(props) { - super(props); - } - componentDidMount() { let node = ReactDOM.findDOMNode(this); this.props.domRef(this.props, node); diff --git a/src/t2-design/components/IconItem.js b/src/t2-design/components/IconItem.js index c5097a8..8d61981 100644 --- a/src/t2-design/components/IconItem.js +++ b/src/t2-design/components/IconItem.js @@ -1,8 +1,6 @@ import React from 'react'; -import ReactDOM from "react-dom"; import PropTypes from 'prop-types'; import classNames from 'classnames'; -import _ from "lodash"; import { Icon } from 'semantic-ui-react' diff --git a/src/t2-design/components/Item.js b/src/t2-design/components/Item.js index bc92572..45b2c8a 100644 --- a/src/t2-design/components/Item.js +++ b/src/t2-design/components/Item.js @@ -1,5 +1,4 @@ import React from 'react'; -import ReactDOM from "react-dom"; import PropTypes from 'prop-types'; import DOMRef from './DOMRef' diff --git a/src/t2-design/components/Route.js b/src/t2-design/components/Route.js index 8e56888..824f10c 100644 --- a/src/t2-design/components/Route.js +++ b/src/t2-design/components/Route.js @@ -1,6 +1,4 @@ import React from 'react'; -import PropTypes from 'prop-types'; -import classNames from 'classnames'; import IconItem from "./IconItem"; diff --git a/src/t2-design/components/Service.js b/src/t2-design/components/Service.js index 0778480..eed729f 100644 --- a/src/t2-design/components/Service.js +++ b/src/t2-design/components/Service.js @@ -1,8 +1,6 @@ import React from 'react'; -import ReactDOM from 'react-dom'; import PropTypes from 'prop-types'; import classNames from 'classnames'; -import _ from 'lodash'; import { Card, Icon } from 'semantic-ui-react' @@ -19,11 +17,27 @@ const Service = (props) => ( {props.name} - Service / Deployment / Build + {serviceType(props)} ); +const serviceType = (props) => { + var type; + if (props.hasBuildConfig || (props.services && props.services.length > 0)) { + type = [DC]; + if (props.hasBuildConfig) { + type = [...type, " / ", BC]; + } + if (props.services && props.services.length > 0) { + type = ["Services / ", type]; + } + } else { + type = "DeploymentConfig" + } + return type; +}; + Service.propTypes = { name: PropTypes.string.isRequired, icon: PropTypes.string.isRequired, diff --git a/src/t2-design/components/Storage.js b/src/t2-design/components/Storage.js index 0321f41..ff44e90 100644 --- a/src/t2-design/components/Storage.js +++ b/src/t2-design/components/Storage.js @@ -1,6 +1,4 @@ import React from 'react'; -import PropTypes from 'prop-types'; -import classNames from 'classnames'; import IconItem from "./IconItem"; diff --git a/src/t2-design/components/Topology.css b/src/t2-design/components/Topology.css index 4d4edfd..3478587 100644 --- a/src/t2-design/components/Topology.css +++ b/src/t2-design/components/Topology.css @@ -1,6 +1,7 @@ .topo { display: flex; - height: 500px; /* TEMP please change */ + height: 100%; + overflow: auto; } .topo-service-stack { @@ -16,7 +17,7 @@ } .topo .topo-service-stack .internals { - height: 120px !important; + height: 160px !important; } .topo .topo-svg { diff --git a/src/t2-design/components/Topology.js b/src/t2-design/components/Topology.js index 44edfee..ca1ba86 100644 --- a/src/t2-design/components/Topology.js +++ b/src/t2-design/components/Topology.js @@ -50,13 +50,17 @@ class Topology extends React.Component { } onDOMRef = (item, node) => { - elementResizeEvent(node, this.onResize) + if (node != null) { + elementResizeEvent(node, this.onResize); + } } onItemDOMRef= (item, node) => { - elementResizeEvent(node, this.onResize) + if (node != null) { + elementResizeEvent(node, this.onResize); + } this.setState((prevState, props) => { - return ({ nodeDOMRefs: { ...prevState.nodeDOMRefs, [item.id]: node } }); + return ({nodeDOMRefs: {...prevState.nodeDOMRefs, [item.id]: node}}); }); } @@ -68,27 +72,57 @@ class Topology extends React.Component { onSelectItem = (item) => { this.setState({ selectedItemId: item.id }); - this.props.onSelect(this.props.layout.nodes[item.id]); + this.props.onSelect(item.id, this.props.layout.nodes[item.id]); } - rowForService = (elems, klass, className, serviceId) => { - let columns = this.columnsForService(elems, klass, serviceId); + rowForService = (elems, className, serviceId) => { + let columns = this.columnsForService(elems, serviceId); return ( {columns} ); } - columnsForService = (elems, klass, serviceId) => { + columnsForService = (elems, serviceId) => { let result = elems - .filter(e => e.props.klass === klass && e.props.belongsTo === serviceId) + .filter(e => e.props.belongsTo === serviceId) .map(e => ({e})); return (result.length > 0) ? result : []; } + determineBelongsToFromEdges = (layout) => { + Object.entries(layout.nodes) + .filter(([nid, node]) => node.type !== 'service' && !node.belongsTo) + .forEach(([nid, node]) => { + let connected = Object.entries(layout.edges).filter(([eid, edge]) => edge.from === nid || edge.to === nid); + if (connected.length > 0) { + let edge = connected[0][1]; + node.belongsTo = (edge.from === nid) ? edge.to : edge.from; + } + }); + } + + distributeOrphans = (layout) => { + let services = Object.entries(layout.nodes).filter(([nid, node]) => node.type === 'service'); + let orphans = Object.entries(layout.nodes).filter(([nid, node]) => node.type !== 'service' && !node.belongsTo).map(([nid, node]) => node); + while (orphans.length > 0) { + let orphan = orphans.pop(); + services.sort(([aid, a], [bid, b]) => this.countServiceBelong(layout, aid) - this.countServiceBelong(layout, bid)); + orphan.belongsTo = services[0][0]; + } + } + + countServiceBelong = (layout, sid) => + Object.entries(layout.nodes).filter(([nid, node]) => node.type !== 'service' && node.belongsTo === sid).length; + render() { - let nodeElems = this.createNodeElements(this.props.layout.nodes); + var layout = _.cloneDeep(this.props.layout); + this.determineBelongsToFromEdges(layout); + this.distributeOrphans(layout); + let nodeElems = this.createNodeElements(layout.nodes); let serviceElems = nodeElems.filter(e => e.props.klass === 'service'); - let edgeElems = this.createEdgeElements(this.props.layout.edges); + let externalElems = nodeElems.filter(e => e.props.klass === 'external'); + let internalElems = nodeElems.filter(e => e.props.klass === 'internal'); + let edgeElems = this.createEdgeElements(layout.edges); return (
@@ -98,12 +132,13 @@ class Topology extends React.Component { className={classNames('topo-service-stack')} textAlign="center" verticalAlign="middle" + stackable={false} > - {this.rowForService(nodeElems, "external", "externals", se.props.id)} + {this.rowForService(externalElems, "externals", se.props.id)} {se} - {this.rowForService(nodeElems, "internal", "internals", se.props.id)} + {this.rowForService(internalElems, "internals", se.props.id)} ); })}