spinnaker.execution.stages.before.deployManifest

A policy targeting this object runs before executing each task in a deployManifest stage.

See Deploy Applications to Kubernetes for more information on this stage.

Example Payload

Click to expand
{
  "input": {
    "pipeline": {
      "application": "hostname",
      "authentication": {
        "allowedAccounts": [
          "spinnaker",
          "staging",
          "staging-ecs"
        ],
        "user": "myUserName"
      },
      "buildTime": 1620752502018,
      "canceled": false,
      "canceledBy": null,
      "cancellationReason": null,
      "description": "Deploy manifest",
      "endTime": null,
      "id": "01F5E61382GF88N6R7JFBA9XA2",
      "initialConfig": {},
      "keepWaitingPipelines": false,
      "limitConcurrent": false,
      "name": null,
      "notifications": [],
      "origin": "unknown",
      "partition": null,
      "paused": null,
      "pipelineConfigId": null,
      "source": null,
      "spelEvaluator": null,
      "stages": [
        "01F5E613827GH96PMBS5PJVE50"
      ],
      "startTime": 1620752502041,
      "startTimeExpiry": null,
      "status": "RUNNING",
      "systemNotifications": [],
      "templateVariables": null,
      "trigger": {
        "artifacts": [],
        "correlationId": null,
        "isDryRun": false,
        "isRebake": false,
        "isStrategy": false,
        "notifications": [],
        "other": {
          "artifacts": [],
          "dryRun": false,
          "expectedArtifacts": [],
          "notifications": [],
          "parameters": {},
          "rebake": false,
          "resolvedExpectedArtifacts": [],
          "strategy": false,
          "type": "manual",
          "user": "myUserName"
        },
        "parameters": {},
        "resolvedExpectedArtifacts": [],
        "type": "manual",
        "user": "myUserName"
      },
      "type": "ORCHESTRATION"
    },
    "stage": {
      "context": {
        "account": "spinnaker",
        "artifacts": [
          {
            "customKind": false,
            "location": "staging",
            "metadata": {
              "account": "spinnaker"
            },
            "name": "hostname",
            "reference": "hostname",
            "type": "kubernetes/deployment",
            "version": ""
          }
        ],
        "cloudProvider": "kubernetes",
        "deploy.account.name": "spinnaker",
        "deploy.server.groups": {},
        "failedManifests": [],
        "kato.last.task.id": {
          "id": "63e8305c-2251-4a83-9509-b8f5b3143cb3"
        },
        "kato.result.expected": true,
        "kato.task.firstNotFoundRetry": -1,
        "kato.task.lastStatus": "SUCCEEDED",
        "kato.task.notFoundRetryCount": 0,
        "kato.task.terminalRetryCount": 0,
        "kato.tasks": [
          {
            "history": [
              {
                "phase": "ORCHESTRATION",
                "status": "Initializing Orchestration Task"
              },
              {
                "phase": "ORCHESTRATION",
                "status": "Processing op: KubernetesDeployManifestOperation"
              },
              {
                "phase": "DEPLOY_KUBERNETES_MANIFEST",
                "status": "Beginning deployment of manifest..."
              },
              {
                "phase": "DEPLOY_KUBERNETES_MANIFEST",
                "status": "Swapping out artifacts in deployment hostname from context..."
              },
              {
                "phase": "DEPLOY_KUBERNETES_MANIFEST",
                "status": "Finding deployer for deployment..."
              },
              {
                "phase": "DEPLOY_KUBERNETES_MANIFEST",
                "status": "Checking if all requested artifacts were bound..."
              },
              {
                "phase": "DEPLOY_KUBERNETES_MANIFEST",
                "status": "Sorting manifests by priority..."
              },
              {
                "phase": "DEPLOY_KUBERNETES_MANIFEST",
                "status": "Deploy order is: deployment hostname"
              },
              {
                "phase": "DEPLOY_KUBERNETES_MANIFEST",
                "status": "Finding deployer for deployment..."
              },
              {
                "phase": "DEPLOY_KUBERNETES_MANIFEST",
                "status": "Annotating manifest deployment hostname with artifact, relationships & moniker..."
              },
              {
                "phase": "DEPLOY_KUBERNETES_MANIFEST",
                "status": "Swapping out artifacts in deployment hostname from other deployments..."
              },
              {
                "phase": "DEPLOY_KUBERNETES_MANIFEST",
                "status": "Submitting manifest deployment hostname to kubernetes master..."
              },
              {
                "phase": "DEPLOY_KUBERNETES_MANIFEST",
                "status": "Deploy manifest task completed successfully."
              },
              {
                "phase": "ORCHESTRATION",
                "status": "Orchestration completed."
              }
            ],
            "id": "63e8305c-2251-4a83-9509-b8f5b3143cb3",
            "resultObjects": [
              {
                "boundArtifacts": [],
                "createdArtifacts": [
                  {
                    "customKind": false,
                    "location": "staging",
                    "metadata": {
                      "account": "spinnaker"
                    },
                    "name": "hostname",
                    "reference": "hostname",
                    "type": "kubernetes/deployment",
                    "version": ""
                  }
                ],
                "manifestNamesByNamespace": {
                  "staging": [
                    "deployment hostname"
                  ]
                },
                "manifests": [
                  {
                    "apiVersion": "apps/v1",
                    "kind": "Deployment",
                    "metadata": {
                      "annotations": {
                        "artifact.spinnaker.io/location": "staging",
                        "artifact.spinnaker.io/name": "hostname",
                        "artifact.spinnaker.io/type": "kubernetes/deployment",
                        "artifact.spinnaker.io/version": "",
                        "deployment.kubernetes.io/revision": "4",
                        "kubectl.kubernetes.io/last-applied-configuration": "{\"apiVersion\":\"apps/v1\",\"kind\":\"Deployment\",\"metadata\":{\"annotations\":{\"artifact.spinnaker.io/location\":\"staging\",\"artifact.spinnaker.io/name\":\"hostname\",\"artifact.spinnaker.io/type\":\"kubernetes/deployment\",\"artifact.spinnaker.io/version\":\"\",\"moniker.spinnaker.io/application\":\"hostname\",\"moniker.spinnaker.io/cluster\":\"deployment hostname\"},\"labels\":{\"app.kubernetes.io/managed-by\":\"spinnaker\",\"app.kubernetes.io/name\":\"hostname\"},\"name\":\"hostname\",\"namespace\":\"staging\"},\"spec\":{\"replicas\":4,\"selector\":{\"matchLabels\":{\"app\":\"hostname\",\"version\":\"v1\"}},\"strategy\":{\"rollingUpdate\":{\"maxSurge\":1,\"maxUnavailable\":1},\"type\":\"RollingUpdate\"},\"template\":{\"metadata\":{\"annotations\":{\"artifact.spinnaker.io/location\":\"staging\",\"artifact.spinnaker.io/name\":\"hostname\",\"artifact.spinnaker.io/type\":\"kubernetes/deployment\",\"artifact.spinnaker.io/version\":\"\",\"moniker.spinnaker.io/application\":\"hostname\",\"moniker.spinnaker.io/cluster\":\"deployment hostname\",\"prometheus.io/port\":\"9113\",\"prometheus.io/scrape\":\"true\"},\"labels\":{\"app\":\"hostname\",\"app.kubernetes.io/managed-by\":\"spinnaker\",\"app.kubernetes.io/name\":\"hostname\",\"version\":\"v1\"}},\"spec\":{\"containers\":[{\"image\":\"rstarmer/hostname:v1\",\"imagePullPolicy\":\"Always\",\"name\":\"hostname\",\"resources\":{},\"volumeMounts\":[{\"mountPath\":\"/etc/nginx/conf.d/nginx-status.conf\",\"name\":\"nginx-status-conf\",\"readOnly\":true,\"subPath\":\"nginx.status.conf\"}]},{\"args\":[\"-nginx.scrape-uri=http://localhost:8090/nginx_status\"],\"image\":\"nginx/nginx-prometheus-exporter:0.3.0\",\"imagePullPolicy\":\"Always\",\"name\":\"nginx-exporter\",\"ports\":[{\"containerPort\":9113,\"name\":\"nginx-ex-port\",\"protocol\":\"TCP\"}]}],\"restartPolicy\":\"Always\",\"volumes\":[{\"configMap\":{\"defaultMode\":420,\"name\":\"nginx-status-conf-v000\"},\"name\":\"nginx-status-conf\"}]}}}}\n",
                        "moniker.spinnaker.io/application": "hostname",
                        "moniker.spinnaker.io/cluster": "deployment hostname"
                      },
                      "creationTimestamp": "2021-04-30T21:19:15Z",
                      "generation": 11,
                      "labels": {
                        "app.kubernetes.io/managed-by": "spinnaker",
                        "app.kubernetes.io/name": "hostname"
                      },
                      "managedFields": [
                        {
                          "apiVersion": "apps/v1",
                          "fieldsType": "FieldsV1",
                          "fieldsV1": {
                            "f:metadata": {
                              "f:annotations": {
                                ".": {},
                                "f:artifact.spinnaker.io/location": {},
                                "f:artifact.spinnaker.io/name": {},
                                "f:artifact.spinnaker.io/type": {},
                                "f:artifact.spinnaker.io/version": {},
                                "f:kubectl.kubernetes.io/last-applied-configuration": {},
                                "f:moniker.spinnaker.io/application": {},
                                "f:moniker.spinnaker.io/cluster": {}
                              },
                              "f:labels": {
                                ".": {},
                                "f:app.kubernetes.io/managed-by": {},
                                "f:app.kubernetes.io/name": {}
                              }
                            },
                            "f:spec": {
                              "f:progressDeadlineSeconds": {},
                              "f:replicas": {},
                              "f:revisionHistoryLimit": {},
                              "f:selector": {
                                "f:matchLabels": {
                                  ".": {},
                                  "f:app": {},
                                  "f:version": {}
                                }
                              },
                              "f:strategy": {
                                "f:rollingUpdate": {
                                  ".": {},
                                  "f:maxSurge": {},
                                  "f:maxUnavailable": {}
                                },
                                "f:type": {}
                              },
                              "f:template": {
                                "f:metadata": {
                                  "f:annotations": {
                                    ".": {},
                                    "f:artifact.spinnaker.io/location": {},
                                    "f:artifact.spinnaker.io/name": {},
                                    "f:artifact.spinnaker.io/type": {},
                                    "f:artifact.spinnaker.io/version": {},
                                    "f:moniker.spinnaker.io/application": {},
                                    "f:moniker.spinnaker.io/cluster": {},
                                    "f:prometheus.io/port": {},
                                    "f:prometheus.io/scrape": {}
                                  },
                                  "f:labels": {
                                    ".": {},
                                    "f:app": {},
                                    "f:app.kubernetes.io/managed-by": {},
                                    "f:app.kubernetes.io/name": {},
                                    "f:version": {}
                                  }
                                },
                                "f:spec": {
                                  "f:containers": {
                                    "k:{\"name\":\"hostname\"}": {
                                      ".": {},
                                      "f:image": {},
                                      "f:imagePullPolicy": {},
                                      "f:name": {},
                                      "f:resources": {},
                                      "f:terminationMessagePath": {},
                                      "f:terminationMessagePolicy": {},
                                      "f:volumeMounts": {
                                        ".": {},
                                        "k:{\"mountPath\":\"/etc/nginx/conf.d/nginx-status.conf\"}": {
                                          ".": {},
                                          "f:mountPath": {},
                                          "f:name": {},
                                          "f:readOnly": {},
                                          "f:subPath": {}
                                        }
                                      }
                                    },
                                    "k:{\"name\":\"nginx-exporter\"}": {
                                      ".": {},
                                      "f:args": {},
                                      "f:image": {},
                                      "f:imagePullPolicy": {},
                                      "f:name": {},
                                      "f:ports": {
                                        ".": {},
                                        "k:{\"containerPort\":9113,\"protocol\":\"TCP\"}": {
                                          ".": {},
                                          "f:containerPort": {},
                                          "f:name": {},
                                          "f:protocol": {}
                                        }
                                      },
                                      "f:resources": {},
                                      "f:terminationMessagePath": {},
                                      "f:terminationMessagePolicy": {}
                                    }
                                  },
                                  "f:dnsPolicy": {},
                                  "f:restartPolicy": {},
                                  "f:schedulerName": {},
                                  "f:securityContext": {},
                                  "f:terminationGracePeriodSeconds": {},
                                  "f:volumes": {
                                    ".": {},
                                    "k:{\"name\":\"nginx-status-conf\"}": {
                                      ".": {},
                                      "f:configMap": {
                                        ".": {},
                                        "f:defaultMode": {},
                                        "f:name": {}
                                      },
                                      "f:name": {}
                                    }
                                  }
                                }
                              }
                            }
                          },
                          "manager": "kubectl",
                          "operation": "Update",
                          "time": "2021-04-30T21:19:15Z"
                        },
                        {
                          "apiVersion": "apps/v1",
                          "fieldsType": "FieldsV1",
                          "fieldsV1": {
                            "f:metadata": {
                              "f:annotations": {
                                "f:deployment.kubernetes.io/revision": {}
                              }
                            },
                            "f:status": {
                              "f:availableReplicas": {},
                              "f:conditions": {
                                ".": {},
                                "k:{\"type\":\"Available\"}": {
                                  ".": {},
                                  "f:lastTransitionTime": {},
                                  "f:lastUpdateTime": {},
                                  "f:message": {},
                                  "f:reason": {},
                                  "f:status": {},
                                  "f:type": {}
                                },
                                "k:{\"type\":\"Progressing\"}": {
                                  ".": {},
                                  "f:lastTransitionTime": {},
                                  "f:lastUpdateTime": {},
                                  "f:message": {},
                                  "f:reason": {},
                                  "f:status": {},
                                  "f:type": {}
                                }
                              },
                              "f:observedGeneration": {},
                              "f:readyReplicas": {},
                              "f:replicas": {},
                              "f:updatedReplicas": {}
                            }
                          },
                          "manager": "kube-controller-manager",
                          "operation": "Update",
                          "time": "2021-05-07T22:39:40Z"
                        }
                      ],
                      "name": "hostname",
                      "namespace": "staging",
                      "resourceVersion": "25266763",
                      "selfLink": "/apis/apps/v1/namespaces/staging/deployments/hostname",
                      "uid": "e1d20734-60ea-44a0-a830-168f001b482f"
                    },
                    "spec": {
                      "progressDeadlineSeconds": 600,
                      "replicas": 4,
                      "revisionHistoryLimit": 10,
                      "selector": {
                        "matchLabels": {
                          "app": "hostname",
                          "version": "v1"
                        }
                      },
                      "strategy": {
                        "rollingUpdate": {
                          "maxSurge": 1,
                          "maxUnavailable": 1
                        },
                        "type": "RollingUpdate"
                      },
                      "template": {
                        "metadata": {
                          "annotations": {
                            "artifact.spinnaker.io/location": "staging",
                            "artifact.spinnaker.io/name": "hostname",
                            "artifact.spinnaker.io/type": "kubernetes/deployment",
                            "artifact.spinnaker.io/version": "",
                            "moniker.spinnaker.io/application": "hostname",
                            "moniker.spinnaker.io/cluster": "deployment hostname",
                            "prometheus.io/port": "9113",
                            "prometheus.io/scrape": "true"
                          },
                          "labels": {
                            "app": "hostname",
                            "app.kubernetes.io/managed-by": "spinnaker",
                            "app.kubernetes.io/name": "hostname",
                            "version": "v1"
                          }
                        },
                        "spec": {
                          "containers": [
                            {
                              "image": "rstarmer/hostname:v1",
                              "imagePullPolicy": "Always",
                              "name": "hostname",
                              "resources": {},
                              "terminationMessagePath": "/dev/termination-log",
                              "terminationMessagePolicy": "File",
                              "volumeMounts": [
                                {
                                  "mountPath": "/etc/nginx/conf.d/nginx-status.conf",
                                  "name": "nginx-status-conf",
                                  "readOnly": true,
                                  "subPath": "nginx.status.conf"
                                }
                              ]
                            },
                            {
                              "args": [
                                "-nginx.scrape-uri=http://localhost:8090/nginx_status"
                              ],
                              "image": "nginx/nginx-prometheus-exporter:0.3.0",
                              "imagePullPolicy": "Always",
                              "name": "nginx-exporter",
                              "ports": [
                                {
                                  "containerPort": 9113,
                                  "name": "nginx-ex-port",
                                  "protocol": "TCP"
                                }
                              ],
                              "resources": {},
                              "terminationMessagePath": "/dev/termination-log",
                              "terminationMessagePolicy": "File"
                            }
                          ],
                          "dnsPolicy": "ClusterFirst",
                          "restartPolicy": "Always",
                          "schedulerName": "default-scheduler",
                          "securityContext": {},
                          "terminationGracePeriodSeconds": 30,
                          "volumes": [
                            {
                              "configMap": {
                                "defaultMode": 420,
                                "name": "nginx-status-conf-v000"
                              },
                              "name": "nginx-status-conf"
                            }
                          ]
                        }
                      }
                    },
                    "status": {
                      "availableReplicas": 10,
                      "conditions": [
                        {
                          "lastTransitionTime": "2021-04-30T21:19:15Z",
                          "lastUpdateTime": "2021-05-07T20:39:03Z",
                          "message": "ReplicaSet \"hostname-f5b957cc\" has successfully progressed.",
                          "reason": "NewReplicaSetAvailable",
                          "status": "True",
                          "type": "Progressing"
                        },
                        {
                          "lastTransitionTime": "2021-05-07T22:39:40Z",
                          "lastUpdateTime": "2021-05-07T22:39:40Z",
                          "message": "Deployment has minimum availability.",
                          "reason": "MinimumReplicasAvailable",
                          "status": "True",
                          "type": "Available"
                        }
                      ],
                      "observedGeneration": 10,
                      "readyReplicas": 10,
                      "replicas": 10,
                      "updatedReplicas": 10
                    }
                  }
                ]
              }
            ],
            "status": {
              "completed": true,
              "failed": false,
              "retryable": false
            }
          }
        ],
        "manifestArtifactAccount": "embedded-artifact",
        "manifests": [
          {
            "apiVersion": "apps/v1",
            "kind": "Deployment",
            "metadata": {
              "annotations": {
                "artifact.spinnaker.io/location": "staging",
                "artifact.spinnaker.io/name": "hostname",
                "artifact.spinnaker.io/type": "kubernetes/deployment",
                "artifact.spinnaker.io/version": "",
                "moniker.spinnaker.io/application": "hostname",
                "moniker.spinnaker.io/cluster": "deployment hostname"
              },
              "labels": {
                "app.kubernetes.io/managed-by": "spinnaker",
                "app.kubernetes.io/name": "hostname"
              },
              "name": "hostname",
              "namespace": "staging"
            },
            "spec": {
              "replicas": 4,
              "selector": {
                "matchLabels": {
                  "app": "hostname",
                  "version": "v1"
                }
              },
              "strategy": {
                "rollingUpdate": {
                  "maxSurge": 1,
                  "maxUnavailable": 1
                },
                "type": "RollingUpdate"
              },
              "template": {
                "metadata": {
                  "annotations": {
                    "artifact.spinnaker.io/location": "staging",
                    "artifact.spinnaker.io/name": "hostname",
                    "artifact.spinnaker.io/type": "kubernetes/deployment",
                    "artifact.spinnaker.io/version": "",
                    "moniker.spinnaker.io/application": "hostname",
                    "moniker.spinnaker.io/cluster": "deployment hostname",
                    "prometheus.io/port": "9113",
                    "prometheus.io/scrape": "true"
                  },
                  "labels": {
                    "app": "hostname",
                    "app.kubernetes.io/managed-by": "spinnaker",
                    "app.kubernetes.io/name": "hostname",
                    "version": "v1"
                  }
                },
                "spec": {
                  "containers": [
                    {
                      "image": "rstarmer/hostname:v1",
                      "imagePullPolicy": "Always",
                      "name": "hostname",
                      "resources": {},
                      "volumeMounts": [
                        {
                          "mountPath": "/etc/nginx/conf.d/nginx-status.conf",
                          "name": "nginx-status-conf",
                          "readOnly": true,
                          "subPath": "nginx.status.conf"
                        }
                      ]
                    },
                    {
                      "args": [
                        "-nginx.scrape-uri=http://localhost:8090/nginx_status"
                      ],
                      "image": "nginx/nginx-prometheus-exporter:0.3.0",
                      "imagePullPolicy": "Always",
                      "name": "nginx-exporter",
                      "ports": [
                        {
                          "containerPort": 9113,
                          "name": "nginx-ex-port",
                          "protocol": "TCP"
                        }
                      ]
                    }
                  ],
                  "restartPolicy": "Always",
                  "volumes": [
                    {
                      "configMap": {
                        "defaultMode": 420,
                        "name": "nginx-status-conf-v000"
                      },
                      "name": "nginx-status-conf"
                    }
                  ]
                }
              }
            }
          }
        ],
        "messages": [],
        "moniker": {
          "app": "hostname",
          "cluster": "deployment hostname"
        },
        "optionalArtifacts": [],
        "outputs.boundArtifacts": [],
        "outputs.createdArtifacts": [
          {
            "customKind": false,
            "location": "staging",
            "metadata": {
              "account": "spinnaker"
            },
            "name": "hostname",
            "reference": "hostname",
            "type": "kubernetes/deployment",
            "version": ""
          }
        ],
        "outputs.manifestNamesByNamespace": {
          "staging": [
            "deployment hostname"
          ]
        },
        "outputs.manifests": [
          {
            "apiVersion": "apps/v1",
            "kind": "Deployment",
            "metadata": {
              "annotations": {
                "artifact.spinnaker.io/location": "staging",
                "artifact.spinnaker.io/name": "hostname",
                "artifact.spinnaker.io/type": "kubernetes/deployment",
                "artifact.spinnaker.io/version": "",
                "deployment.kubernetes.io/revision": "4",
                "kubectl.kubernetes.io/last-applied-configuration": "{\"apiVersion\":\"apps/v1\",\"kind\":\"Deployment\",\"metadata\":{\"annotations\":{\"artifact.spinnaker.io/location\":\"staging\",\"artifact.spinnaker.io/name\":\"hostname\",\"artifact.spinnaker.io/type\":\"kubernetes/deployment\",\"artifact.spinnaker.io/version\":\"\",\"moniker.spinnaker.io/application\":\"hostname\",\"moniker.spinnaker.io/cluster\":\"deployment hostname\"},\"labels\":{\"app.kubernetes.io/managed-by\":\"spinnaker\",\"app.kubernetes.io/name\":\"hostname\"},\"name\":\"hostname\",\"namespace\":\"staging\"},\"spec\":{\"replicas\":4,\"selector\":{\"matchLabels\":{\"app\":\"hostname\",\"version\":\"v1\"}},\"strategy\":{\"rollingUpdate\":{\"maxSurge\":1,\"maxUnavailable\":1},\"type\":\"RollingUpdate\"},\"template\":{\"metadata\":{\"annotations\":{\"artifact.spinnaker.io/location\":\"staging\",\"artifact.spinnaker.io/name\":\"hostname\",\"artifact.spinnaker.io/type\":\"kubernetes/deployment\",\"artifact.spinnaker.io/version\":\"\",\"moniker.spinnaker.io/application\":\"hostname\",\"moniker.spinnaker.io/cluster\":\"deployment hostname\",\"prometheus.io/port\":\"9113\",\"prometheus.io/scrape\":\"true\"},\"labels\":{\"app\":\"hostname\",\"app.kubernetes.io/managed-by\":\"spinnaker\",\"app.kubernetes.io/name\":\"hostname\",\"version\":\"v1\"}},\"spec\":{\"containers\":[{\"image\":\"rstarmer/hostname:v1\",\"imagePullPolicy\":\"Always\",\"name\":\"hostname\",\"resources\":{},\"volumeMounts\":[{\"mountPath\":\"/etc/nginx/conf.d/nginx-status.conf\",\"name\":\"nginx-status-conf\",\"readOnly\":true,\"subPath\":\"nginx.status.conf\"}]},{\"args\":[\"-nginx.scrape-uri=http://localhost:8090/nginx_status\"],\"image\":\"nginx/nginx-prometheus-exporter:0.3.0\",\"imagePullPolicy\":\"Always\",\"name\":\"nginx-exporter\",\"ports\":[{\"containerPort\":9113,\"name\":\"nginx-ex-port\",\"protocol\":\"TCP\"}]}],\"restartPolicy\":\"Always\",\"volumes\":[{\"configMap\":{\"defaultMode\":420,\"name\":\"nginx-status-conf-v000\"},\"name\":\"nginx-status-conf\"}]}}}}\n",
                "moniker.spinnaker.io/application": "hostname",
                "moniker.spinnaker.io/cluster": "deployment hostname"
              },
              "creationTimestamp": "2021-04-30T21:19:15Z",
              "generation": 11,
              "labels": {
                "app.kubernetes.io/managed-by": "spinnaker",
                "app.kubernetes.io/name": "hostname"
              },
              "managedFields": [
                {
                  "apiVersion": "apps/v1",
                  "fieldsType": "FieldsV1",
                  "fieldsV1": {
                    "f:metadata": {
                      "f:annotations": {
                        ".": {},
                        "f:artifact.spinnaker.io/location": {},
                        "f:artifact.spinnaker.io/name": {},
                        "f:artifact.spinnaker.io/type": {},
                        "f:artifact.spinnaker.io/version": {},
                        "f:kubectl.kubernetes.io/last-applied-configuration": {},
                        "f:moniker.spinnaker.io/application": {},
                        "f:moniker.spinnaker.io/cluster": {}
                      },
                      "f:labels": {
                        ".": {},
                        "f:app.kubernetes.io/managed-by": {},
                        "f:app.kubernetes.io/name": {}
                      }
                    },
                    "f:spec": {
                      "f:progressDeadlineSeconds": {},
                      "f:replicas": {},
                      "f:revisionHistoryLimit": {},
                      "f:selector": {
                        "f:matchLabels": {
                          ".": {},
                          "f:app": {},
                          "f:version": {}
                        }
                      },
                      "f:strategy": {
                        "f:rollingUpdate": {
                          ".": {},
                          "f:maxSurge": {},
                          "f:maxUnavailable": {}
                        },
                        "f:type": {}
                      },
                      "f:template": {
                        "f:metadata": {
                          "f:annotations": {
                            ".": {},
                            "f:artifact.spinnaker.io/location": {},
                            "f:artifact.spinnaker.io/name": {},
                            "f:artifact.spinnaker.io/type": {},
                            "f:artifact.spinnaker.io/version": {},
                            "f:moniker.spinnaker.io/application": {},
                            "f:moniker.spinnaker.io/cluster": {},
                            "f:prometheus.io/port": {},
                            "f:prometheus.io/scrape": {}
                          },
                          "f:labels": {
                            ".": {},
                            "f:app": {},
                            "f:app.kubernetes.io/managed-by": {},
                            "f:app.kubernetes.io/name": {},
                            "f:version": {}
                          }
                        },
                        "f:spec": {
                          "f:containers": {
                            "k:{\"name\":\"hostname\"}": {
                              ".": {},
                              "f:image": {},
                              "f:imagePullPolicy": {},
                              "f:name": {},
                              "f:resources": {},
                              "f:terminationMessagePath": {},
                              "f:terminationMessagePolicy": {},
                              "f:volumeMounts": {
                                ".": {},
                                "k:{\"mountPath\":\"/etc/nginx/conf.d/nginx-status.conf\"}": {
                                  ".": {},
                                  "f:mountPath": {},
                                  "f:name": {},
                                  "f:readOnly": {},
                                  "f:subPath": {}
                                }
                              }
                            },
                            "k:{\"name\":\"nginx-exporter\"}": {
                              ".": {},
                              "f:args": {},
                              "f:image": {},
                              "f:imagePullPolicy": {},
                              "f:name": {},
                              "f:ports": {
                                ".": {},
                                "k:{\"containerPort\":9113,\"protocol\":\"TCP\"}": {
                                  ".": {},
                                  "f:containerPort": {},
                                  "f:name": {},
                                  "f:protocol": {}
                                }
                              },
                              "f:resources": {},
                              "f:terminationMessagePath": {},
                              "f:terminationMessagePolicy": {}
                            }
                          },
                          "f:dnsPolicy": {},
                          "f:restartPolicy": {},
                          "f:schedulerName": {},
                          "f:securityContext": {},
                          "f:terminationGracePeriodSeconds": {},
                          "f:volumes": {
                            ".": {},
                            "k:{\"name\":\"nginx-status-conf\"}": {
                              ".": {},
                              "f:configMap": {
                                ".": {},
                                "f:defaultMode": {},
                                "f:name": {}
                              },
                              "f:name": {}
                            }
                          }
                        }
                      }
                    }
                  },
                  "manager": "kubectl",
                  "operation": "Update",
                  "time": "2021-04-30T21:19:15Z"
                },
                {
                  "apiVersion": "apps/v1",
                  "fieldsType": "FieldsV1",
                  "fieldsV1": {
                    "f:metadata": {
                      "f:annotations": {
                        "f:deployment.kubernetes.io/revision": {}
                      }
                    },
                    "f:status": {
                      "f:availableReplicas": {},
                      "f:conditions": {
                        ".": {},
                        "k:{\"type\":\"Available\"}": {
                          ".": {},
                          "f:lastTransitionTime": {},
                          "f:lastUpdateTime": {},
                          "f:message": {},
                          "f:reason": {},
                          "f:status": {},
                          "f:type": {}
                        },
                        "k:{\"type\":\"Progressing\"}": {
                          ".": {},
                          "f:lastTransitionTime": {},
                          "f:lastUpdateTime": {},
                          "f:message": {},
                          "f:reason": {},
                          "f:status": {},
                          "f:type": {}
                        }
                      },
                      "f:observedGeneration": {},
                      "f:readyReplicas": {},
                      "f:replicas": {},
                      "f:updatedReplicas": {}
                    }
                  },
                  "manager": "kube-controller-manager",
                  "operation": "Update",
                  "time": "2021-05-07T22:39:40Z"
                }
              ],
              "name": "hostname",
              "namespace": "staging",
              "resourceVersion": "25266763",
              "selfLink": "/apis/apps/v1/namespaces/staging/deployments/hostname",
              "uid": "e1d20734-60ea-44a0-a830-168f001b482f"
            },
            "spec": {
              "progressDeadlineSeconds": 600,
              "replicas": 4,
              "revisionHistoryLimit": 10,
              "selector": {
                "matchLabels": {
                  "app": "hostname",
                  "version": "v1"
                }
              },
              "strategy": {
                "rollingUpdate": {
                  "maxSurge": 1,
                  "maxUnavailable": 1
                },
                "type": "RollingUpdate"
              },
              "template": {
                "metadata": {
                  "annotations": {
                    "artifact.spinnaker.io/location": "staging",
                    "artifact.spinnaker.io/name": "hostname",
                    "artifact.spinnaker.io/type": "kubernetes/deployment",
                    "artifact.spinnaker.io/version": "",
                    "moniker.spinnaker.io/application": "hostname",
                    "moniker.spinnaker.io/cluster": "deployment hostname",
                    "prometheus.io/port": "9113",
                    "prometheus.io/scrape": "true"
                  },
                  "labels": {
                    "app": "hostname",
                    "app.kubernetes.io/managed-by": "spinnaker",
                    "app.kubernetes.io/name": "hostname",
                    "version": "v1"
                  }
                },
                "spec": {
                  "containers": [
                    {
                      "image": "rstarmer/hostname:v1",
                      "imagePullPolicy": "Always",
                      "name": "hostname",
                      "resources": {},
                      "terminationMessagePath": "/dev/termination-log",
                      "terminationMessagePolicy": "File",
                      "volumeMounts": [
                        {
                          "mountPath": "/etc/nginx/conf.d/nginx-status.conf",
                          "name": "nginx-status-conf",
                          "readOnly": true,
                          "subPath": "nginx.status.conf"
                        }
                      ]
                    },
                    {
                      "args": [
                        "-nginx.scrape-uri=http://localhost:8090/nginx_status"
                      ],
                      "image": "nginx/nginx-prometheus-exporter:0.3.0",
                      "imagePullPolicy": "Always",
                      "name": "nginx-exporter",
                      "ports": [
                        {
                          "containerPort": 9113,
                          "name": "nginx-ex-port",
                          "protocol": "TCP"
                        }
                      ],
                      "resources": {},
                      "terminationMessagePath": "/dev/termination-log",
                      "terminationMessagePolicy": "File"
                    }
                  ],
                  "dnsPolicy": "ClusterFirst",
                  "restartPolicy": "Always",
                  "schedulerName": "default-scheduler",
                  "securityContext": {},
                  "terminationGracePeriodSeconds": 30,
                  "volumes": [
                    {
                      "configMap": {
                        "defaultMode": 420,
                        "name": "nginx-status-conf-v000"
                      },
                      "name": "nginx-status-conf"
                    }
                  ]
                }
              }
            },
            "status": {
              "availableReplicas": 10,
              "conditions": [
                {
                  "lastTransitionTime": "2021-04-30T21:19:15Z",
                  "lastUpdateTime": "2021-05-07T20:39:03Z",
                  "message": "ReplicaSet \"hostname-f5b957cc\" has successfully progressed.",
                  "reason": "NewReplicaSetAvailable",
                  "status": "True",
                  "type": "Progressing"
                },
                {
                  "lastTransitionTime": "2021-05-07T22:39:40Z",
                  "lastUpdateTime": "2021-05-07T22:39:40Z",
                  "message": "Deployment has minimum availability.",
                  "reason": "MinimumReplicasAvailable",
                  "status": "True",
                  "type": "Available"
                }
              ],
              "observedGeneration": 10,
              "readyReplicas": 10,
              "replicas": 10,
              "updatedReplicas": 10
            }
          }
        ],
        "relationships": {
          "loadBalancers": [],
          "securityGroups": []
        },
        "requiredArtifacts": [],
        "source": "text",
        "stableManifests": [
          {
            "location": "staging",
            "manifestName": "deployment hostname"
          }
        ],
        "user": "myUserName"
      },
      "endTime": null,
      "id": "01F5E613827GH96PMBS5PJVE50",
      "lastModified": null,
      "name": "deployManifest",
      "outputs": {
        "artifacts": [
          {
            "customKind": false,
            "location": "staging",
            "metadata": {
              "account": "spinnaker"
            },
            "name": "hostname",
            "reference": "hostname",
            "type": "kubernetes/deployment",
            "version": ""
          }
        ],
        "manifests": [
          {
            "apiVersion": "apps/v1",
            "kind": "Deployment",
            "metadata": {
              "annotations": {
                "artifact.spinnaker.io/location": "staging",
                "artifact.spinnaker.io/name": "hostname",
                "artifact.spinnaker.io/type": "kubernetes/deployment",
                "artifact.spinnaker.io/version": "",
                "moniker.spinnaker.io/application": "hostname",
                "moniker.spinnaker.io/cluster": "deployment hostname"
              },
              "labels": {
                "app.kubernetes.io/managed-by": "spinnaker",
                "app.kubernetes.io/name": "hostname"
              },
              "name": "hostname",
              "namespace": "staging"
            },
            "spec": {
              "replicas": 4,
              "selector": {
                "matchLabels": {
                  "app": "hostname",
                  "version": "v1"
                }
              },
              "strategy": {
                "rollingUpdate": {
                  "maxSurge": 1,
                  "maxUnavailable": 1
                },
                "type": "RollingUpdate"
              },
              "template": {
                "metadata": {
                  "annotations": {
                    "artifact.spinnaker.io/location": "staging",
                    "artifact.spinnaker.io/name": "hostname",
                    "artifact.spinnaker.io/type": "kubernetes/deployment",
                    "artifact.spinnaker.io/version": "",
                    "moniker.spinnaker.io/application": "hostname",
                    "moniker.spinnaker.io/cluster": "deployment hostname",
                    "prometheus.io/port": "9113",
                    "prometheus.io/scrape": "true"
                  },
                  "labels": {
                    "app": "hostname",
                    "app.kubernetes.io/managed-by": "spinnaker",
                    "app.kubernetes.io/name": "hostname",
                    "version": "v1"
                  }
                },
                "spec": {
                  "containers": [
                    {
                      "image": "rstarmer/hostname:v1",
                      "imagePullPolicy": "Always",
                      "name": "hostname",
                      "resources": {},
                      "volumeMounts": [
                        {
                          "mountPath": "/etc/nginx/conf.d/nginx-status.conf",
                          "name": "nginx-status-conf",
                          "readOnly": true,
                          "subPath": "nginx.status.conf"
                        }
                      ]
                    },
                    {
                      "args": [
                        "-nginx.scrape-uri=http://localhost:8090/nginx_status"
                      ],
                      "image": "nginx/nginx-prometheus-exporter:0.3.0",
                      "imagePullPolicy": "Always",
                      "name": "nginx-exporter",
                      "ports": [
                        {
                          "containerPort": 9113,
                          "name": "nginx-ex-port",
                          "protocol": "TCP"
                        }
                      ]
                    }
                  ],
                  "restartPolicy": "Always",
                  "volumes": [
                    {
                      "configMap": {
                        "defaultMode": 420,
                        "name": "nginx-status-conf-v000"
                      },
                      "name": "nginx-status-conf"
                    }
                  ]
                }
              }
            }
          }
        ],
        "optionalArtifacts": [],
        "outputs.boundArtifacts": [],
        "outputs.createdArtifacts": [
          {
            "customKind": false,
            "location": "staging",
            "metadata": {
              "account": "spinnaker"
            },
            "name": "hostname",
            "reference": "hostname",
            "type": "kubernetes/deployment",
            "version": ""
          }
        ],
        "outputs.manifestNamesByNamespace": {
          "staging": [
            "deployment hostname"
          ]
        },
        "outputs.manifests": [
          {
            "apiVersion": "apps/v1",
            "kind": "Deployment",
            "metadata": {
              "annotations": {
                "artifact.spinnaker.io/location": "staging",
                "artifact.spinnaker.io/name": "hostname",
                "artifact.spinnaker.io/type": "kubernetes/deployment",
                "artifact.spinnaker.io/version": "",
                "deployment.kubernetes.io/revision": "4",
                "kubectl.kubernetes.io/last-applied-configuration": "{\"apiVersion\":\"apps/v1\",\"kind\":\"Deployment\",\"metadata\":{\"annotations\":{\"artifact.spinnaker.io/location\":\"staging\",\"artifact.spinnaker.io/name\":\"hostname\",\"artifact.spinnaker.io/type\":\"kubernetes/deployment\",\"artifact.spinnaker.io/version\":\"\",\"moniker.spinnaker.io/application\":\"hostname\",\"moniker.spinnaker.io/cluster\":\"deployment hostname\"},\"labels\":{\"app.kubernetes.io/managed-by\":\"spinnaker\",\"app.kubernetes.io/name\":\"hostname\"},\"name\":\"hostname\",\"namespace\":\"staging\"},\"spec\":{\"replicas\":4,\"selector\":{\"matchLabels\":{\"app\":\"hostname\",\"version\":\"v1\"}},\"strategy\":{\"rollingUpdate\":{\"maxSurge\":1,\"maxUnavailable\":1},\"type\":\"RollingUpdate\"},\"template\":{\"metadata\":{\"annotations\":{\"artifact.spinnaker.io/location\":\"staging\",\"artifact.spinnaker.io/name\":\"hostname\",\"artifact.spinnaker.io/type\":\"kubernetes/deployment\",\"artifact.spinnaker.io/version\":\"\",\"moniker.spinnaker.io/application\":\"hostname\",\"moniker.spinnaker.io/cluster\":\"deployment hostname\",\"prometheus.io/port\":\"9113\",\"prometheus.io/scrape\":\"true\"},\"labels\":{\"app\":\"hostname\",\"app.kubernetes.io/managed-by\":\"spinnaker\",\"app.kubernetes.io/name\":\"hostname\",\"version\":\"v1\"}},\"spec\":{\"containers\":[{\"image\":\"rstarmer/hostname:v1\",\"imagePullPolicy\":\"Always\",\"name\":\"hostname\",\"resources\":{},\"volumeMounts\":[{\"mountPath\":\"/etc/nginx/conf.d/nginx-status.conf\",\"name\":\"nginx-status-conf\",\"readOnly\":true,\"subPath\":\"nginx.status.conf\"}]},{\"args\":[\"-nginx.scrape-uri=http://localhost:8090/nginx_status\"],\"image\":\"nginx/nginx-prometheus-exporter:0.3.0\",\"imagePullPolicy\":\"Always\",\"name\":\"nginx-exporter\",\"ports\":[{\"containerPort\":9113,\"name\":\"nginx-ex-port\",\"protocol\":\"TCP\"}]}],\"restartPolicy\":\"Always\",\"volumes\":[{\"configMap\":{\"defaultMode\":420,\"name\":\"nginx-status-conf-v000\"},\"name\":\"nginx-status-conf\"}]}}}}\n",
                "moniker.spinnaker.io/application": "hostname",
                "moniker.spinnaker.io/cluster": "deployment hostname"
              },
              "creationTimestamp": "2021-04-30T21:19:15Z",
              "generation": 11,
              "labels": {
                "app.kubernetes.io/managed-by": "spinnaker",
                "app.kubernetes.io/name": "hostname"
              },
              "managedFields": [
                {
                  "apiVersion": "apps/v1",
                  "fieldsType": "FieldsV1",
                  "fieldsV1": {
                    "f:metadata": {
                      "f:annotations": {
                        ".": {},
                        "f:artifact.spinnaker.io/location": {},
                        "f:artifact.spinnaker.io/name": {},
                        "f:artifact.spinnaker.io/type": {},
                        "f:artifact.spinnaker.io/version": {},
                        "f:kubectl.kubernetes.io/last-applied-configuration": {},
                        "f:moniker.spinnaker.io/application": {},
                        "f:moniker.spinnaker.io/cluster": {}
                      },
                      "f:labels": {
                        ".": {},
                        "f:app.kubernetes.io/managed-by": {},
                        "f:app.kubernetes.io/name": {}
                      }
                    },
                    "f:spec": {
                      "f:progressDeadlineSeconds": {},
                      "f:replicas": {},
                      "f:revisionHistoryLimit": {},
                      "f:selector": {
                        "f:matchLabels": {
                          ".": {},
                          "f:app": {},
                          "f:version": {}
                        }
                      },
                      "f:strategy": {
                        "f:rollingUpdate": {
                          ".": {},
                          "f:maxSurge": {},
                          "f:maxUnavailable": {}
                        },
                        "f:type": {}
                      },
                      "f:template": {
                        "f:metadata": {
                          "f:annotations": {
                            ".": {},
                            "f:artifact.spinnaker.io/location": {},
                            "f:artifact.spinnaker.io/name": {},
                            "f:artifact.spinnaker.io/type": {},
                            "f:artifact.spinnaker.io/version": {},
                            "f:moniker.spinnaker.io/application": {},
                            "f:moniker.spinnaker.io/cluster": {},
                            "f:prometheus.io/port": {},
                            "f:prometheus.io/scrape": {}
                          },
                          "f:labels": {
                            ".": {},
                            "f:app": {},
                            "f:app.kubernetes.io/managed-by": {},
                            "f:app.kubernetes.io/name": {},
                            "f:version": {}
                          }
                        },
                        "f:spec": {
                          "f:containers": {
                            "k:{\"name\":\"hostname\"}": {
                              ".": {},
                              "f:image": {},
                              "f:imagePullPolicy": {},
                              "f:name": {},
                              "f:resources": {},
                              "f:terminationMessagePath": {},
                              "f:terminationMessagePolicy": {},
                              "f:volumeMounts": {
                                ".": {},
                                "k:{\"mountPath\":\"/etc/nginx/conf.d/nginx-status.conf\"}": {
                                  ".": {},
                                  "f:mountPath": {},
                                  "f:name": {},
                                  "f:readOnly": {},
                                  "f:subPath": {}
                                }
                              }
                            },
                            "k:{\"name\":\"nginx-exporter\"}": {
                              ".": {},
                              "f:args": {},
                              "f:image": {},
                              "f:imagePullPolicy": {},
                              "f:name": {},
                              "f:ports": {
                                ".": {},
                                "k:{\"containerPort\":9113,\"protocol\":\"TCP\"}": {
                                  ".": {},
                                  "f:containerPort": {},
                                  "f:name": {},
                                  "f:protocol": {}
                                }
                              },
                              "f:resources": {},
                              "f:terminationMessagePath": {},
                              "f:terminationMessagePolicy": {}
                            }
                          },
                          "f:dnsPolicy": {},
                          "f:restartPolicy": {},
                          "f:schedulerName": {},
                          "f:securityContext": {},
                          "f:terminationGracePeriodSeconds": {},
                          "f:volumes": {
                            ".": {},
                            "k:{\"name\":\"nginx-status-conf\"}": {
                              ".": {},
                              "f:configMap": {
                                ".": {},
                                "f:defaultMode": {},
                                "f:name": {}
                              },
                              "f:name": {}
                            }
                          }
                        }
                      }
                    }
                  },
                  "manager": "kubectl",
                  "operation": "Update",
                  "time": "2021-04-30T21:19:15Z"
                },
                {
                  "apiVersion": "apps/v1",
                  "fieldsType": "FieldsV1",
                  "fieldsV1": {
                    "f:metadata": {
                      "f:annotations": {
                        "f:deployment.kubernetes.io/revision": {}
                      }
                    },
                    "f:status": {
                      "f:availableReplicas": {},
                      "f:conditions": {
                        ".": {},
                        "k:{\"type\":\"Available\"}": {
                          ".": {},
                          "f:lastTransitionTime": {},
                          "f:lastUpdateTime": {},
                          "f:message": {},
                          "f:reason": {},
                          "f:status": {},
                          "f:type": {}
                        },
                        "k:{\"type\":\"Progressing\"}": {
                          ".": {},
                          "f:lastTransitionTime": {},
                          "f:lastUpdateTime": {},
                          "f:message": {},
                          "f:reason": {},
                          "f:status": {},
                          "f:type": {}
                        }
                      },
                      "f:observedGeneration": {},
                      "f:readyReplicas": {},
                      "f:replicas": {},
                      "f:updatedReplicas": {}
                    }
                  },
                  "manager": "kube-controller-manager",
                  "operation": "Update",
                  "time": "2021-05-07T22:39:40Z"
                }
              ],
              "name": "hostname",
              "namespace": "staging",
              "resourceVersion": "25266763",
              "selfLink": "/apis/apps/v1/namespaces/staging/deployments/hostname",
              "uid": "e1d20734-60ea-44a0-a830-168f001b482f"
            },
            "spec": {
              "progressDeadlineSeconds": 600,
              "replicas": 4,
              "revisionHistoryLimit": 10,
              "selector": {
                "matchLabels": {
                  "app": "hostname",
                  "version": "v1"
                }
              },
              "strategy": {
                "rollingUpdate": {
                  "maxSurge": 1,
                  "maxUnavailable": 1
                },
                "type": "RollingUpdate"
              },
              "template": {
                "metadata": {
                  "annotations": {
                    "artifact.spinnaker.io/location": "staging",
                    "artifact.spinnaker.io/name": "hostname",
                    "artifact.spinnaker.io/type": "kubernetes/deployment",
                    "artifact.spinnaker.io/version": "",
                    "moniker.spinnaker.io/application": "hostname",
                    "moniker.spinnaker.io/cluster": "deployment hostname",
                    "prometheus.io/port": "9113",
                    "prometheus.io/scrape": "true"
                  },
                  "labels": {
                    "app": "hostname",
                    "app.kubernetes.io/managed-by": "spinnaker",
                    "app.kubernetes.io/name": "hostname",
                    "version": "v1"
                  }
                },
                "spec": {
                  "containers": [
                    {
                      "image": "rstarmer/hostname:v1",
                      "imagePullPolicy": "Always",
                      "name": "hostname",
                      "resources": {},
                      "terminationMessagePath": "/dev/termination-log",
                      "terminationMessagePolicy": "File",
                      "volumeMounts": [
                        {
                          "mountPath": "/etc/nginx/conf.d/nginx-status.conf",
                          "name": "nginx-status-conf",
                          "readOnly": true,
                          "subPath": "nginx.status.conf"
                        }
                      ]
                    },
                    {
                      "args": [
                        "-nginx.scrape-uri=http://localhost:8090/nginx_status"
                      ],
                      "image": "nginx/nginx-prometheus-exporter:0.3.0",
                      "imagePullPolicy": "Always",
                      "name": "nginx-exporter",
                      "ports": [
                        {
                          "containerPort": 9113,
                          "name": "nginx-ex-port",
                          "protocol": "TCP"
                        }
                      ],
                      "resources": {},
                      "terminationMessagePath": "/dev/termination-log",
                      "terminationMessagePolicy": "File"
                    }
                  ],
                  "dnsPolicy": "ClusterFirst",
                  "restartPolicy": "Always",
                  "schedulerName": "default-scheduler",
                  "securityContext": {},
                  "terminationGracePeriodSeconds": 30,
                  "volumes": [
                    {
                      "configMap": {
                        "defaultMode": 420,
                        "name": "nginx-status-conf-v000"
                      },
                      "name": "nginx-status-conf"
                    }
                  ]
                }
              }
            },
            "status": {
              "availableReplicas": 10,
              "conditions": [
                {
                  "lastTransitionTime": "2021-04-30T21:19:15Z",
                  "lastUpdateTime": "2021-05-07T20:39:03Z",
                  "message": "ReplicaSet \"hostname-f5b957cc\" has successfully progressed.",
                  "reason": "NewReplicaSetAvailable",
                  "status": "True",
                  "type": "Progressing"
                },
                {
                  "lastTransitionTime": "2021-05-07T22:39:40Z",
                  "lastUpdateTime": "2021-05-07T22:39:40Z",
                  "message": "Deployment has minimum availability.",
                  "reason": "MinimumReplicasAvailable",
                  "status": "True",
                  "type": "Available"
                }
              ],
              "observedGeneration": 10,
              "readyReplicas": 10,
              "replicas": 10,
              "updatedReplicas": 10
            }
          }
        ],
        "requiredArtifacts": []
      },
      "parentStageId": null,
      "refId": "0",
      "requisiteStageRefIds": [],
      "scheduledTime": null,
      "startTime": 1620752502094,
      "startTimeExpiry": null,
      "status": "RUNNING",
      "syntheticStageOwner": null,
      "tasks": [
        {
          "endTime": 1620752502246,
          "id": "1",
          "implementingClass": "com.netflix.spinnaker.orca.clouddriver.tasks.manifest.ResolveDeploySourceManifestTask",
          "loopEnd": false,
          "loopStart": false,
          "name": "resolveDeploySourceManifest",
          "stageEnd": false,
          "stageStart": true,
          "startTime": 1620752502114,
          "status": "SUCCEEDED"
        },
        {
          "endTime": 1620752502738,
          "id": "2",
          "implementingClass": "com.netflix.spinnaker.orca.clouddriver.tasks.manifest.DeployManifestTask",
          "loopEnd": false,
          "loopStart": false,
          "name": "deployManifest",
          "stageEnd": false,
          "stageStart": false,
          "startTime": 1620752502265,
          "status": "SUCCEEDED"
        },
        {
          "endTime": 1620752508133,
          "id": "3",
          "implementingClass": "com.netflix.spinnaker.orca.clouddriver.tasks.MonitorKatoTask",
          "loopEnd": false,
          "loopStart": false,
          "name": "monitorDeploy",
          "stageEnd": false,
          "stageStart": false,
          "startTime": 1620752502764,
          "status": "SUCCEEDED"
        },
        {
          "endTime": 1620752508319,
          "id": "4",
          "implementingClass": "com.netflix.spinnaker.orca.clouddriver.tasks.manifest.PromoteManifestKatoOutputsTask",
          "loopEnd": false,
          "loopStart": false,
          "name": "promoteOutputs",
          "stageEnd": false,
          "stageStart": false,
          "startTime": 1620752508168,
          "status": "SUCCEEDED"
        },
        {
          "endTime": 1620752508606,
          "id": "5",
          "implementingClass": "com.netflix.spinnaker.orca.clouddriver.tasks.manifest.WaitForManifestStableTask",
          "loopEnd": false,
          "loopStart": false,
          "name": "waitForManifestToStabilize",
          "stageEnd": false,
          "stageStart": false,
          "startTime": 1620752508388,
          "status": "SUCCEEDED"
        },
        {
          "endTime": null,
          "id": "6",
          "implementingClass": "com.netflix.spinnaker.orca.clouddriver.tasks.artifacts.CleanupArtifactsTask",
          "loopEnd": false,
          "loopStart": false,
          "name": "cleanupArtifacts",
          "stageEnd": false,
          "stageStart": false,
          "startTime": 1620752508624,
          "status": "RUNNING"
        },
        {
          "endTime": null,
          "id": "7",
          "implementingClass": "com.netflix.spinnaker.orca.clouddriver.tasks.MonitorKatoTask",
          "loopEnd": false,
          "loopStart": false,
          "name": "monitorCleanup",
          "stageEnd": false,
          "stageStart": false,
          "startTime": null,
          "status": "NOT_STARTED"
        },
        {
          "endTime": null,
          "id": "8",
          "implementingClass": "com.netflix.spinnaker.orca.clouddriver.tasks.manifest.PromoteManifestKatoOutputsTask",
          "loopEnd": false,
          "loopStart": false,
          "name": "promoteOutputs",
          "stageEnd": false,
          "stageStart": false,
          "startTime": null,
          "status": "NOT_STARTED"
        },
        {
          "endTime": null,
          "id": "9",
          "implementingClass": "com.netflix.spinnaker.orca.pipeline.tasks.artifacts.BindProducedArtifactsTask",
          "loopEnd": false,
          "loopStart": false,
          "name": "bindProducedArtifacts",
          "stageEnd": true,
          "stageStart": false,
          "startTime": null,
          "status": "NOT_STARTED"
        }
      ],
      "type": "deployManifest"
    },
    "user": {
      "isAdmin": false,
      "roles": [],
      "username": "myUserName"
    }
  }
}

Example Policy

  • This policy requires that a set of annotations have been applied to any manifests that are being deployed. Specifically the annotations ‘app’ and ‘owner’ must have been applied.

      package spinnaker.execution.stages.before.deployManifest
      required_annotations:=["app","owner"]
      deny["Manifest is missing a required annotation"] {
          metadata :=input.stage.context.manifests[_].metadata
          annotations := object.get(metadata,"annotations",{})
          # Use object.get to check if data exists
          object.get(annotations,required_annotations[_],null)==null
      }{
          metadata :=input.stage.context.manifests[_].spec.template.metadata
          annotations := object.get(metadata,"annotations",{})
          # Use object.get to check if data exists
          object.get(annotations,required_annotations[_],null)==null
      }
    

  • This policy requires prevents exposing a set of ports that are unencrypted buy have encrypted alternatives. Specifically this policy prevents exposing HTTP, FTP, TELNET, POP3, NNTP, IMAP, LDAP, and SMTP from a pod, deployment, or replicaset.

    package spinnaker.execution.stages.before.deployManifest
    
    blockedPorts := [20,21,23,80,110,119,143,389,587,8080,8088,8888]
    
    deny["A port typically used by an unencrypted protocol was detected."] {
        #Check for service
        ports := input.stage.context.manifests[_].spec.ports[_]
        any([object.get(ports,"port",null) == blockedPorts[_], 
              object.get(ports,"targetPort",null) == blockedPorts[_]])
    }{ 
        #Check for pod
        input.stage.context.manifests[_].spec.containers[_].ports[_].containerPort=blockedPorts[_]
    } { 
        #Check for pod template
        input.stage.context.manifests[_].spec.template.spec.containers[_].ports[_].containerPort=blockedPorts[_]
        }
    

  • This policy checks whether or not the image being approved is on a list of imaged that are approved for deployment. The list of what images are approved must seperately be uploaded to the OPA data document

    package spinnaker.execution.stages.before.deployManifest
    
    deny["Manifest creates a pod from an image that is not approved by the security scanning process."] {
    #Check pod templates
        isImageUnApproved(input.stage.context.manifests[_].spec.template.spec.containers[_].image)
    } {#check pods
        isImageUnApproved(input.stage.context.manifests[_].spec.containers[_].image)
    }
    {#check pod template initContainers
        isImageUnApproved(input.stage.context.manifests[_].spec.template.spec.initContainers[_].image)
    }
    {#check pod initContainers
        isImageUnApproved(input.stage.context.manifests[_].spec.initContainers[_].image)
    }
    
    isImageUnApproved(image){    not isImageApproved(image) }
    isImageApproved(image){    image==data.approvedImages[_]}
    

  • This policy prevents applications from deploying to namespaces that they are not whitelisted for.

    package spinnaker.execution.stages.before.deployManifest
    
    allowedNamespaces:=[{"app":"app1","ns": ["ns1","ns2"]},
                        {"app":"app2", "ns":["ns3"]}]
    
    deny["stage deploys to a namespace to which this application lacks access"]{
        ns :=object.get(input.stage.context.manifests[_].metadata,"namespace","default")
        application := input.pipeline.application
        not canDeploy(ns, application)
    }
    
    canDeploy(namespace, application){
        some i
        allowedNamespaces[i].app==application
        allowedNamespaces[i].ns[_]==namespace
    }
    

Keys

Parameters related to the stage against which the policy is executing can be found in the input.stage.context object.

input.pipeline

KeyTypeDescription
input.pipeline.applicationstringThe name of the application to which this pipeline belongs.
input.pipeline.authentication.allowedAccounts[]stringThe list of accounts to which the user this stage runs as has access.
input.pipeline.authentication.userstringThe Spinnaker user initiating the change.
input.pipeline.buildTimenumber
input.pipeline.descriptionstringDescription of the pipeline defined in the UI.
input.pipeline.idstringThe unique ID of the pipeline.
input.pipeline.keepWaitingPipelinesbooleanIf concurrent pipeline execution is disabled, then the pipelines that are in the waiting queue will get canceled when the next execution starts unless this is true.
input.pipeline.limitConcurrentbooleanTrue if only 1 concurrent execution of this pipeline is allowed.
input.pipeline.namestringThe name of this pipeline.
input.pipeline.originstring
input.pipeline.partition
input.pipeline.paused
input.pipeline.pipelineConfigId
input.pipeline.source
input.pipeline.spelEvaluatorstringWhich version of spring expression language is being used to evaluate SpEL.
input.pipeline.stages[]stringAn array of the stages in the pipeline. Typically if you are writing a policy that examines multiple pipeline stages, it is better to write that policy against either the opa.pipelines package, or the spinnaker.execution.pipelines.before package.
input.pipeline.startTimenumberTimestamp from when the pipeline was started.
input.pipeline.startTimeExpirydateUnix epoch date at which the pipeline expires.
input.pipeline.statusstringThe status of the pipeline, typically ‘RUNNING’.
input.pipeline.templateVariables
input.pipeline.typestring

input.pipeline.trigger

See input.pipeline.trigger for more information.

input.stage

See input.stage for more information.

input.stage.context

KeyTypeDescription
input.stage.context.accountstringWhat account is this stage deploying to. This is often used, for example, to check whether or not a policy applies to the given account.
input.stage.context.artifacts[]arraySee artifacts for more information.
input.stage.context.cloudProviderstringThe cloud provider for the account this is deploying to. Typically ‘kubernetes’
input.stage.context.deploy.account.namestringThe name of the account to which the stage is deploying.
input.stage.context.kato.last.task.id.idstring
input.stage.context.kato.result.expectedboolean
input.stage.context.kato.task.firstNotFoundRetrynumber
input.stage.context.kato.task.lastStatusstring
input.stage.context.kato.task.notFoundRetryCountnumber
input.stage.context.kato.task.terminalRetryCountnumber
input.stage.context.kato.tasks[]stringThis array contains the tasks that are executed during this stage. when each task finishes execution, the policy is rechecked with the status of each execution task updated.
input.stage.context.kato.tasks[].history[].phasestringThe history of task phase changes.
input.stage.context.kato.tasks[].history[].statusstringThe history of task status changes.
input.stage.context.kato.tasks[].idstringThe unique id of the task.
input.stage.context.kato.tasks[].resultObjects[]{object}DO NOT USE. This contains numerous manifests/artifacts created by the execution of the stage. Typically policies should be written against the inputs to the stage, not its outputs.
input.stage.context.kato.tasks[].status.completedbooleanTrue when the task has finished executing.
input.stage.context.kato.tasks[].status.failedbooleanDid the task attempt to execute and fail.
input.stage.context.kato.tasks[].status.retryablebooleanCan the task retry if execution fails.
input.stage.context.manifestArtifactAccountstringWhat artifact account are artifacts stored in.
input.stage.context.manifests[]objectThe raw kubernetes manifest being deployed. This is the element you should write policies against that involve the manifest.
input.stage.context.moniker.appstringThe name of the application to which this pipeline belongs.
input.stage.context.moniker.clusterstringThe name of the cluster to which this stage is deploying.
input.stage.context.outputsobjectDO NOT USE. This contains numerous manifests/artifacts created by the execution of the stage. Typically policies should be written against the inputs to the stage, not its outputs.
input.stage.context.sourcestringSpecifies whether the manifest is coming from an artifact or was directly specified in the pipeline as text.
input.stage.context.stableManifests[].locationstringThe namespace of the stable manifest.
input.stage.context.stableManifests[].manifestNamestringThe manifests name.
input.stage.context.userstringthe ID of the user that the stage runs as.

input.user

This object provides information about the user performing the action. This can be used to restrict actions by role. See input.user for more information.


Last modified August 18, 2023: (02b163b7)