diff --git a/charts/oes/Chart.yaml b/charts/oes/Chart.yaml index acd3e4a4..cdb7b45a 100644 --- a/charts/oes/Chart.yaml +++ b/charts/oes/Chart.yaml @@ -1,8 +1,8 @@ apiVersion: v2 name: oes -version: 3.12.6 -appVersion: 3.12.4 -description: "ISD-3.12.4 - Improvements in loading Application dashboard in ISD UI" +version: 3.12.7 +appVersion: 3.12.5 +description: "ISD-3.12.5 - Enhanced the connection authentication messages fotr Integrators in ISD UI" icon: https://raw.githubusercontent.com/OpsMx/enterprise-spinnaker/master/img/opsmx.png maintainers: - email: srinivas@opsmx.io @@ -37,6 +37,9 @@ dependencies: - name: prometheus version: 11.16.2 condition: global.enableCentralMonitoring + - name: grafana + version: 6.31.0 + condition: global.enableCentralMonitoring - name: gitea version: 5.0.1 condition: global.gitea.enabled diff --git a/charts/oes/charts/grafana/.helmignore b/charts/oes/charts/grafana/.helmignore new file mode 100644 index 00000000..8cade131 --- /dev/null +++ b/charts/oes/charts/grafana/.helmignore @@ -0,0 +1,23 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*~ +# Various IDEs +.vscode +.project +.idea/ +*.tmproj +OWNERS diff --git a/charts/oes/charts/grafana/Chart.yaml b/charts/oes/charts/grafana/Chart.yaml new file mode 100644 index 00000000..f6b988b3 --- /dev/null +++ b/charts/oes/charts/grafana/Chart.yaml @@ -0,0 +1,22 @@ +apiVersion: v2 +appVersion: 9.0.1 +description: The leading tool for querying and visualizing time series and metrics. +home: https://grafana.net +icon: https://raw.githubusercontent.com/grafana/grafana/master/public/img/logo_transparent_400x.png +kubeVersion: ^1.8.0-0 +maintainers: +- email: zanhsieh@gmail.com + name: zanhsieh +- email: rluckie@cisco.com + name: rtluckie +- email: maor.friedman@redhat.com + name: maorfr +- email: miroslav.hadzhiev@gmail.com + name: Xtigyro +- email: mail@torstenwalter.de + name: torstenwalter +name: grafana +sources: +- https://github.com/grafana/grafana +type: application +version: 6.31.0 diff --git a/charts/oes/charts/grafana/README.md b/charts/oes/charts/grafana/README.md new file mode 100644 index 00000000..5b545d19 --- /dev/null +++ b/charts/oes/charts/grafana/README.md @@ -0,0 +1,570 @@ +# Grafana Helm Chart + +* Installs the web dashboarding system [Grafana](http://grafana.org/) + +## Get Repo Info + +```console +helm repo add grafana https://grafana.github.io/helm-charts +helm repo update +``` + +_See [helm repo](https://helm.sh/docs/helm/helm_repo/) for command documentation._ + +## Installing the Chart + +To install the chart with the release name `my-release`: + +```console +helm install my-release grafana/grafana +``` + +## Uninstalling the Chart + +To uninstall/delete the my-release deployment: + +```console +helm delete my-release +``` + +The command removes all the Kubernetes components associated with the chart and deletes the release. + +## Upgrading an existing Release to a new major version + +A major chart version change (like v1.2.3 -> v2.0.0) indicates that there is an +incompatible breaking change needing manual actions. + +### To 4.0.0 (And 3.12.1) + +This version requires Helm >= 2.12.0. + +### To 5.0.0 + +You have to add --force to your helm upgrade command as the labels of the chart have changed. + +### To 6.0.0 + +This version requires Helm >= 3.1.0. + +## Configuration + +| Parameter | Description | Default | +|-------------------------------------------|-----------------------------------------------|---------------------------------------------------------| +| `replicas` | Number of nodes | `1` | +| `podDisruptionBudget.minAvailable` | Pod disruption minimum available | `nil` | +| `podDisruptionBudget.maxUnavailable` | Pod disruption maximum unavailable | `nil` | +| `deploymentStrategy` | Deployment strategy | `{ "type": "RollingUpdate" }` | +| `livenessProbe` | Liveness Probe settings | `{ "httpGet": { "path": "/api/health", "port": 3000 } "initialDelaySeconds": 60, "timeoutSeconds": 30, "failureThreshold": 10 }` | +| `readinessProbe` | Readiness Probe settings | `{ "httpGet": { "path": "/api/health", "port": 3000 } }`| +| `securityContext` | Deployment securityContext | `{"runAsUser": 472, "runAsGroup": 472, "fsGroup": 472}` | +| `priorityClassName` | Name of Priority Class to assign pods | `nil` | +| `image.repository` | Image repository | `grafana/grafana` | +| `image.tag` | Overrides the Grafana image tag whose default is the chart appVersion (`Must be >= 5.0.0`) | `` | +| `image.sha` | Image sha (optional) | `` | +| `image.pullPolicy` | Image pull policy | `IfNotPresent` | +| `image.pullSecrets` | Image pull secrets (can be templated) | `[]` | +| `service.enabled` | Enable grafana service | `true` | +| `service.type` | Kubernetes service type | `ClusterIP` | +| `service.port` | Kubernetes port where service is exposed | `80` | +| `service.portName` | Name of the port on the service | `service` | +| `service.targetPort` | Internal service is port | `3000` | +| `service.nodePort` | Kubernetes service nodePort | `nil` | +| `service.annotations` | Service annotations (can be templated) | `{}` | +| `service.labels` | Custom labels | `{}` | +| `service.clusterIP` | internal cluster service IP | `nil` | +| `service.loadBalancerIP` | IP address to assign to load balancer (if supported) | `nil` | +| `service.loadBalancerSourceRanges` | list of IP CIDRs allowed access to lb (if supported) | `[]` | +| `service.externalIPs` | service external IP addresses | `[]` | +| `headlessService` | Create a headless service | `false` | +| `extraExposePorts` | Additional service ports for sidecar containers| `[]` | +| `hostAliases` | adds rules to the pod's /etc/hosts | `[]` | +| `ingress.enabled` | Enables Ingress | `false` | +| `ingress.annotations` | Ingress annotations (values are templated) | `{}` | +| `ingress.labels` | Custom labels | `{}` | +| `ingress.path` | Ingress accepted path | `/` | +| `ingress.pathType` | Ingress type of path | `Prefix` | +| `ingress.hosts` | Ingress accepted hostnames | `["chart-example.local"]` | +| `ingress.extraPaths` | Ingress extra paths to prepend to every host configuration. Useful when configuring [custom actions with AWS ALB Ingress Controller](https://kubernetes-sigs.github.io/aws-alb-ingress-controller/guide/ingress/annotation/#actions). Requires `ingress.hosts` to have one or more host entries. | `[]` | +| `ingress.tls` | Ingress TLS configuration | `[]` | +| `resources` | CPU/Memory resource requests/limits | `{}` | +| `nodeSelector` | Node labels for pod assignment | `{}` | +| `tolerations` | Toleration labels for pod assignment | `[]` | +| `affinity` | Affinity settings for pod assignment | `{}` | +| `extraInitContainers` | Init containers to add to the grafana pod | `{}` | +| `extraContainers` | Sidecar containers to add to the grafana pod | `""` | +| `extraContainerVolumes` | Volumes that can be mounted in sidecar containers | `[]` | +| `extraLabels` | Custom labels for all manifests | `{}` | +| `schedulerName` | Name of the k8s scheduler (other than default) | `nil` | +| `persistence.enabled` | Use persistent volume to store data | `false` | +| `persistence.type` | Type of persistence (`pvc` or `statefulset`) | `pvc` | +| `persistence.size` | Size of persistent volume claim | `10Gi` | +| `persistence.existingClaim` | Use an existing PVC to persist data (can be templated) | `nil` | +| `persistence.storageClassName` | Type of persistent volume claim | `nil` | +| `persistence.accessModes` | Persistence access modes | `[ReadWriteOnce]` | +| `persistence.annotations` | PersistentVolumeClaim annotations | `{}` | +| `persistence.finalizers` | PersistentVolumeClaim finalizers | `[ "kubernetes.io/pvc-protection" ]` | +| `persistence.subPath` | Mount a sub dir of the persistent volume (can be templated) | `nil` | +| `persistence.inMemory.enabled` | If persistence is not enabled, whether to mount the local storage in-memory to improve performance | `false` | +| `persistence.inMemory.sizeLimit` | SizeLimit for the in-memory local storage | `nil` | +| `initChownData.enabled` | If false, don't reset data ownership at startup | true | +| `initChownData.image.repository` | init-chown-data container image repository | `busybox` | +| `initChownData.image.tag` | init-chown-data container image tag | `1.31.1` | +| `initChownData.image.sha` | init-chown-data container image sha (optional)| `""` | +| `initChownData.image.pullPolicy` | init-chown-data container image pull policy | `IfNotPresent` | +| `initChownData.resources` | init-chown-data pod resource requests & limits | `{}` | +| `schedulerName` | Alternate scheduler name | `nil` | +| `env` | Extra environment variables passed to pods | `{}` | +| `envValueFrom` | Environment variables from alternate sources. See the API docs on [EnvVarSource](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.17/#envvarsource-v1-core) for format details. Can be templated | `{}` | +| `envFromSecret` | Name of a Kubernetes secret (must be manually created in the same namespace) containing values to be added to the environment. Can be templated | `""` | +| `envFromSecrets` | List of Kubernetes secrets (must be manually created in the same namespace) containing values to be added to the environment. Can be templated | `[]` | +| `envFromConfigMaps` | List of Kubernetes ConfigMaps (must be manually created in the same namespace) containing values to be added to the environment. Can be templated | `[]` | +| `envRenderSecret` | Sensible environment variables passed to pods and stored as secret | `{}` | +| `enableServiceLinks` | Inject Kubernetes services as environment variables. | `true` | +| `extraSecretMounts` | Additional grafana server secret mounts | `[]` | +| `extraVolumeMounts` | Additional grafana server volume mounts | `[]` | +| `extraConfigmapMounts` | Additional grafana server configMap volume mounts (values are templated) | `[]` | +| `extraEmptyDirMounts` | Additional grafana server emptyDir volume mounts | `[]` | +| `plugins` | Plugins to be loaded along with Grafana | `[]` | +| `datasources` | Configure grafana datasources (passed through tpl) | `{}` | +| `notifiers` | Configure grafana notifiers | `{}` | +| `dashboardProviders` | Configure grafana dashboard providers | `{}` | +| `dashboards` | Dashboards to import | `{}` | +| `dashboardsConfigMaps` | ConfigMaps reference that contains dashboards | `{}` | +| `grafana.ini` | Grafana's primary configuration | `{}` | +| `ldap.enabled` | Enable LDAP authentication | `false` | +| `ldap.existingSecret` | The name of an existing secret containing the `ldap.toml` file, this must have the key `ldap-toml`. | `""` | +| `ldap.config` | Grafana's LDAP configuration | `""` | +| `annotations` | Deployment annotations | `{}` | +| `labels` | Deployment labels | `{}` | +| `podAnnotations` | Pod annotations | `{}` | +| `podLabels` | Pod labels | `{}` | +| `podPortName` | Name of the grafana port on the pod | `grafana` | +| `lifecycleHooks` | Lifecycle hooks for podStart and preStop [Example](https://kubernetes.io/docs/tasks/configure-pod-container/attach-handler-lifecycle-event/#define-poststart-and-prestop-handlers) | `{}` | +| `sidecar.image.repository` | Sidecar image repository | `quay.io/kiwigrid/k8s-sidecar` | +| `sidecar.image.tag` | Sidecar image tag | `1.19.2` | +| `sidecar.image.sha` | Sidecar image sha (optional) | `""` | +| `sidecar.imagePullPolicy` | Sidecar image pull policy | `IfNotPresent` | +| `sidecar.resources` | Sidecar resources | `{}` | +| `sidecar.securityContext` | Sidecar securityContext | `{}` | +| `sidecar.enableUniqueFilenames` | Sets the kiwigrid/k8s-sidecar UNIQUE_FILENAMES environment variable. If set to `true` the sidecar will create unique filenames where duplicate data keys exist between ConfigMaps and/or Secrets within the same or multiple Namespaces. | `false` | +| `sidecar.dashboards.enabled` | Enables the cluster wide search for dashboards and adds/updates/deletes them in grafana | `false` | +| `sidecar.dashboards.SCProvider` | Enables creation of sidecar provider | `true` | +| `sidecar.dashboards.provider.name` | Unique name of the grafana provider | `sidecarProvider` | +| `sidecar.dashboards.provider.orgid` | Id of the organisation, to which the dashboards should be added | `1` | +| `sidecar.dashboards.provider.folder` | Logical folder in which grafana groups dashboards | `""` | +| `sidecar.dashboards.provider.disableDelete` | Activate to avoid the deletion of imported dashboards | `false` | +| `sidecar.dashboards.provider.allowUiUpdates` | Allow updating provisioned dashboards from the UI | `false` | +| `sidecar.dashboards.provider.type` | Provider type | `file` | +| `sidecar.dashboards.provider.foldersFromFilesStructure` | Allow Grafana to replicate dashboard structure from filesystem. | `false` | +| `sidecar.dashboards.watchMethod` | Method to use to detect ConfigMap changes. With WATCH the sidecar will do a WATCH requests, with SLEEP it will list all ConfigMaps, then sleep for 60 seconds. | `WATCH` | +| `sidecar.skipTlsVerify` | Set to true to skip tls verification for kube api calls | `nil` | +| `sidecar.dashboards.label` | Label that config maps with dashboards should have to be added | `grafana_dashboard` | +| `sidecar.dashboards.labelValue` | Label value that config maps with dashboards should have to be added | `nil` | +| `sidecar.dashboards.folder` | Folder in the pod that should hold the collected dashboards (unless `sidecar.dashboards.defaultFolderName` is set). This path will be mounted. | `/tmp/dashboards` | +| `sidecar.dashboards.folderAnnotation` | The annotation the sidecar will look for in configmaps to override the destination folder for files | `nil` | +| `sidecar.dashboards.defaultFolderName` | The default folder name, it will create a subfolder under the `sidecar.dashboards.folder` and put dashboards in there instead | `nil` | +| `sidecar.dashboards.searchNamespace` | Namespaces list. If specified, the sidecar will search for dashboards config-maps inside these namespaces.Otherwise the namespace in which the sidecar is running will be used.It's also possible to specify ALL to search in all namespaces. | `nil` | +| `sidecar.dashboards.script` | Absolute path to shell script to execute after a configmap got reloaded. | `nil` | +| `sidecar.dashboards.resource` | Should the sidecar looks into secrets, configmaps or both. | `both` | +| `sidecar.dashboards.extraMounts` | Additional dashboard sidecar volume mounts. | `[]` | +| `sidecar.datasources.enabled` | Enables the cluster wide search for datasources and adds/updates/deletes them in grafana |`false` | +| `sidecar.datasources.label` | Label that config maps with datasources should have to be added | `grafana_datasource` | +| `sidecar.datasources.labelValue` | Label value that config maps with datasources should have to be added | `nil` | +| `sidecar.datasources.searchNamespace` | Namespaces list. If specified, the sidecar will search for datasources config-maps inside these namespaces.Otherwise the namespace in which the sidecar is running will be used.It's also possible to specify ALL to search in all namespaces. | `nil` | +| `sidecar.datasources.resource` | Should the sidecar looks into secrets, configmaps or both. | `both` | +| `sidecar.datasources.reloadURL` | Full url of datasource configuration reload API endpoint, to invoke after a config-map change | `"http://localhost:3000/api/admin/provisioning/datasources/reload"` | +| `sidecar.datasources.skipReload` | Enabling this omits defining the REQ_URL and REQ_METHOD environment variables | `false` | +| `sidecar.notifiers.enabled` | Enables the cluster wide search for notifiers and adds/updates/deletes them in grafana | `false` | +| `sidecar.notifiers.label` | Label that config maps with notifiers should have to be added | `grafana_notifier` | +| `sidecar.notifiers.searchNamespace` | Namespaces list. If specified, the sidecar will search for notifiers config-maps (or secrets) inside these namespaces.Otherwise the namespace in which the sidecar is running will be used.It's also possible to specify ALL to search in all namespaces. | `nil` | +| `sidecar.notifiers.resource` | Should the sidecar looks into secrets, configmaps or both. | `both` | +| `smtp.existingSecret` | The name of an existing secret containing the SMTP credentials. | `""` | +| `smtp.userKey` | The key in the existing SMTP secret containing the username. | `"user"` | +| `smtp.passwordKey` | The key in the existing SMTP secret containing the password. | `"password"` | +| `admin.existingSecret` | The name of an existing secret containing the admin credentials (can be templated). | `""` | +| `admin.userKey` | The key in the existing admin secret containing the username. | `"admin-user"` | +| `admin.passwordKey` | The key in the existing admin secret containing the password. | `"admin-password"` | +| `serviceAccount.autoMount` | Automount the service account token in the pod| `true` | +| `serviceAccount.annotations` | ServiceAccount annotations | | +| `serviceAccount.create` | Create service account | `true` | +| `serviceAccount.name` | Service account name to use, when empty will be set to created account if `serviceAccount.create` is set else to `default` | `` | +| `serviceAccount.nameTest` | Service account name to use for test, when empty will be set to created account if `serviceAccount.create` is set else to `default` | `nil` | +| `rbac.create` | Create and use RBAC resources | `true` | +| `rbac.namespaced` | Creates Role and Rolebinding instead of the default ClusterRole and ClusteRoleBindings for the grafana instance | `false` | +| `rbac.useExistingRole` | Set to a rolename to use existing role - skipping role creating - but still doing serviceaccount and rolebinding to the rolename set here. | `nil` | +| `rbac.pspEnabled` | Create PodSecurityPolicy (with `rbac.create`, grant roles permissions as well) | `true` | +| `rbac.pspUseAppArmor` | Enforce AppArmor in created PodSecurityPolicy (requires `rbac.pspEnabled`) | `true` | +| `rbac.extraRoleRules` | Additional rules to add to the Role | [] | +| `rbac.extraClusterRoleRules` | Additional rules to add to the ClusterRole | [] | +| `command` | Define command to be executed by grafana container at startup | `nil` | +| `testFramework.enabled` | Whether to create test-related resources | `true` | +| `testFramework.image` | `test-framework` image repository. | `bats/bats` | +| `testFramework.tag` | `test-framework` image tag. | `v1.4.1` | +| `testFramework.imagePullPolicy` | `test-framework` image pull policy. | `IfNotPresent` | +| `testFramework.securityContext` | `test-framework` securityContext | `{}` | +| `downloadDashboards.env` | Environment variables to be passed to the `download-dashboards` container | `{}` | +| `downloadDashboards.envFromSecret` | Name of a Kubernetes secret (must be manually created in the same namespace) containing values to be added to the environment. Can be templated | `""` | +| `downloadDashboards.resources` | Resources of `download-dashboards` container | `{}` | +| `downloadDashboardsImage.repository` | Curl docker image repo | `curlimages/curl` | +| `downloadDashboardsImage.tag` | Curl docker image tag | `7.73.0` | +| `downloadDashboardsImage.sha` | Curl docker image sha (optional) | `""` | +| `downloadDashboardsImage.pullPolicy` | Curl docker image pull policy | `IfNotPresent` | +| `namespaceOverride` | Override the deployment namespace | `""` (`Release.Namespace`) | +| `serviceMonitor.enabled` | Use servicemonitor from prometheus operator | `false` | +| `serviceMonitor.namespace` | Namespace this servicemonitor is installed in | | +| `serviceMonitor.interval` | How frequently Prometheus should scrape | `1m` | +| `serviceMonitor.path` | Path to scrape | `/metrics` | +| `serviceMonitor.scheme` | Scheme to use for metrics scraping | `http` | +| `serviceMonitor.tlsConfig` | TLS configuration block for the endpoint | `{}` | +| `serviceMonitor.labels` | Labels for the servicemonitor passed to Prometheus Operator | `{}` | +| `serviceMonitor.scrapeTimeout` | Timeout after which the scrape is ended | `30s` | +| `serviceMonitor.relabelings` | MetricRelabelConfigs to apply to samples before ingestion. | `[]` | +| `revisionHistoryLimit` | Number of old ReplicaSets to retain | `10` | +| `imageRenderer.enabled` | Enable the image-renderer deployment & service | `false` | +| `imageRenderer.image.repository` | image-renderer Image repository | `grafana/grafana-image-renderer` | +| `imageRenderer.image.tag` | image-renderer Image tag | `latest` | +| `imageRenderer.image.sha` | image-renderer Image sha (optional) | `""` | +| `imageRenderer.image.pullPolicy` | image-renderer ImagePullPolicy | `Always` | +| `imageRenderer.env` | extra env-vars for image-renderer | `{}` | +| `imageRenderer.serviceAccountName` | image-renderer deployment serviceAccountName | `""` | +| `imageRenderer.securityContext` | image-renderer deployment securityContext | `{}` | +| `imageRenderer.hostAliases` | image-renderer deployment Host Aliases | `[]` | +| `imageRenderer.priorityClassName` | image-renderer deployment priority class | `''` | +| `imageRenderer.service.enabled` | Enable the image-renderer service | `true` | +| `imageRenderer.service.portName` | image-renderer service port name | `http` | +| `imageRenderer.service.port` | image-renderer service port used by both service and deployment | `8081` | +| `imageRenderer.grafanaProtocol` | Protocol to use for image renderer callback url | `http` | +| `imageRenderer.grafanaSubPath` | Grafana sub path to use for image renderer callback url | `''` | +| `imageRenderer.podPortName` | name of the image-renderer port on the pod | `http` | +| `imageRenderer.revisionHistoryLimit` | number of image-renderer replica sets to keep | `10` | +| `imageRenderer.networkPolicy.limitIngress` | Enable a NetworkPolicy to limit inbound traffic from only the created grafana pods | `true` | +| `imageRenderer.networkPolicy.limitEgress` | Enable a NetworkPolicy to limit outbound traffic to only the created grafana pods | `false` | +| `imageRenderer.resources` | Set resource limits for image-renderer pdos | `{}` | +| `imageRenderer.nodeSelector` | Node labels for pod assignment | `{}` | +| `imageRenderer.tolerations` | Toleration labels for pod assignment | `[]` | +| `imageRenderer.affinity` | Affinity settings for pod assignment | `{}` | +| `networkPolicy.enabled` | Enable creation of NetworkPolicy resources. | `false` | +| `networkPolicy.allowExternal` | Don't require client label for connections | `true` | +| `networkPolicy.explicitNamespacesSelector` | A Kubernetes LabelSelector to explicitly select namespaces from which traffic could be allowed | `{}` | +| `networkPolicy.ingress` | Enable the creation of an ingress network policy | `true` | +| `networkPolicy.egress.enabled` | Enable the creation of an egress network policy | `false` | +| `networkPolicy.egress.ports` | An array of ports to allow for the egress | `[]` | +| `enableKubeBackwardCompatibility` | Enable backward compatibility of kubernetes where pod's defintion version below 1.13 doesn't have the enableServiceLinks option | `false` | + + + +### Example ingress with path + +With grafana 6.3 and above +```yaml +grafana.ini: + server: + domain: monitoring.example.com + root_url: "%(protocol)s://%(domain)s/grafana" + serve_from_sub_path: true +ingress: + enabled: true + hosts: + - "monitoring.example.com" + path: "/grafana" +``` + +### Example of extraVolumeMounts + +Volume can be type persistentVolumeClaim or hostPath but not both at same time. +If none existingClaim or hostPath argument is givent then type is emptyDir. + +```yaml +- extraVolumeMounts: + - name: plugins + mountPath: /var/lib/grafana/plugins + subPath: configs/grafana/plugins + existingClaim: existing-grafana-claim + readOnly: false + - name: dashboards + mountPath: /var/lib/grafana/dashboards + hostPath: /usr/shared/grafana/dashboards + readOnly: false +``` + +## Import dashboards + +There are a few methods to import dashboards to Grafana. Below are some examples and explanations as to how to use each method: + +```yaml +dashboards: + default: + some-dashboard: + json: | + { + "annotations": + + ... + # Complete json file here + ... + + "title": "Some Dashboard", + "uid": "abcd1234", + "version": 1 + } + custom-dashboard: + # This is a path to a file inside the dashboards directory inside the chart directory + file: dashboards/custom-dashboard.json + prometheus-stats: + # Ref: https://grafana.com/dashboards/2 + gnetId: 2 + revision: 2 + datasource: Prometheus + local-dashboard: + url: https://raw.githubusercontent.com/user/repository/master/dashboards/dashboard.json +``` + +## BASE64 dashboards + +Dashboards could be stored on a server that does not return JSON directly and instead of it returns a Base64 encoded file (e.g. Gerrit) +A new parameter has been added to the url use case so if you specify a b64content value equals to true after the url entry a Base64 decoding is applied before save the file to disk. +If this entry is not set or is equals to false not decoding is applied to the file before saving it to disk. + +### Gerrit use case + +Gerrit API for download files has the following schema: where {project-name} and +{file-id} usually has '/' in their values and so they MUST be replaced by %2F so if project-name is user/repo, branch-id is master and file-id is equals to dir1/dir2/dashboard +the url value is + +## Sidecar for dashboards + +If the parameter `sidecar.dashboards.enabled` is set, a sidecar container is deployed in the grafana +pod. This container watches all configmaps (or secrets) in the cluster and filters out the ones with +a label as defined in `sidecar.dashboards.label`. The files defined in those configmaps are written +to a folder and accessed by grafana. Changes to the configmaps are monitored and the imported +dashboards are deleted/updated. + +A recommendation is to use one configmap per dashboard, as a reduction of multiple dashboards inside +one configmap is currently not properly mirrored in grafana. + +Example dashboard config: + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: sample-grafana-dashboard + labels: + grafana_dashboard: "1" +data: + k8s-dashboard.json: |- + [...] +``` + +## Sidecar for datasources + +If the parameter `sidecar.datasources.enabled` is set, an init container is deployed in the grafana +pod. This container lists all secrets (or configmaps, though not recommended) in the cluster and +filters out the ones with a label as defined in `sidecar.datasources.label`. The files defined in +those secrets are written to a folder and accessed by grafana on startup. Using these yaml files, +the data sources in grafana can be imported. + +Secrets are recommended over configmaps for this usecase because datasources usually contain private +data like usernames and passwords. Secrets are the more appropriate cluster resource to manage those. + +Example values to add a datasource adapted from [Grafana](http://docs.grafana.org/administration/provisioning/#example-datasource-config-file): + +```yaml +datasources: + datasources.yaml: + apiVersion: 1 + datasources: + # name of the datasource. Required + - name: Graphite + # datasource type. Required + type: graphite + # access mode. proxy or direct (Server or Browser in the UI). Required + access: proxy + # org id. will default to orgId 1 if not specified + orgId: 1 + # url + url: http://localhost:8080 + # database password, if used + password: + # database user, if used + user: + # database name, if used + database: + # enable/disable basic auth + basicAuth: + # basic auth username + basicAuthUser: + # basic auth password + basicAuthPassword: + # enable/disable with credentials headers + withCredentials: + # mark as default datasource. Max one per org + isDefault: + # fields that will be converted to json and stored in json_data + jsonData: + graphiteVersion: "1.1" + tlsAuth: true + tlsAuthWithCACert: true + # json object of data that will be encrypted. + secureJsonData: + tlsCACert: "..." + tlsClientCert: "..." + tlsClientKey: "..." + version: 1 + # allow users to edit datasources from the UI. + editable: false +``` + +## Sidecar for notifiers + +If the parameter `sidecar.notifiers.enabled` is set, an init container is deployed in the grafana +pod. This container lists all secrets (or configmaps, though not recommended) in the cluster and +filters out the ones with a label as defined in `sidecar.notifiers.label`. The files defined in +those secrets are written to a folder and accessed by grafana on startup. Using these yaml files, +the notification channels in grafana can be imported. The secrets must be created before +`helm install` so that the notifiers init container can list the secrets. + +Secrets are recommended over configmaps for this usecase because alert notification channels usually contain +private data like SMTP usernames and passwords. Secrets are the more appropriate cluster resource to manage those. + +Example datasource config adapted from [Grafana](https://grafana.com/docs/grafana/latest/administration/provisioning/#alert-notification-channels): + +```yaml +notifiers: + - name: notification-channel-1 + type: slack + uid: notifier1 + # either + org_id: 2 + # or + org_name: Main Org. + is_default: true + send_reminder: true + frequency: 1h + disable_resolve_message: false + # See `Supported Settings` section for settings supporter for each + # alert notification type. + settings: + recipient: 'XXX' + token: 'xoxb' + uploadImage: true + url: https://slack.com + +delete_notifiers: + - name: notification-channel-1 + uid: notifier1 + org_id: 2 + - name: notification-channel-2 + # default org_id: 1 +``` + +## How to serve Grafana with a path prefix (/grafana) + +In order to serve Grafana with a prefix (e.g., ), add the following to your values.yaml. + +```yaml +ingress: + enabled: true + annotations: + kubernetes.io/ingress.class: "nginx" + nginx.ingress.kubernetes.io/rewrite-target: /$1 + nginx.ingress.kubernetes.io/use-regex: "true" + + path: /grafana/?(.*) + hosts: + - k8s.example.dev + +grafana.ini: + server: + root_url: http://localhost:3000/grafana # this host can be localhost +``` + +## How to securely reference secrets in grafana.ini + +This example uses Grafana uses [file providers](https://grafana.com/docs/grafana/latest/administration/configuration/#file-provider) for secret values and the `extraSecretMounts` configuration flag (Additional grafana server secret mounts) to mount the secrets. + +In grafana.ini: + +```yaml +grafana.ini: + [auth.generic_oauth] + enabled = true + client_id = $__file{/etc/secrets/auth_generic_oauth/client_id} + client_secret = $__file{/etc/secrets/auth_generic_oauth/client_secret} +``` + +Existing secret, or created along with helm: + +```yaml +--- +apiVersion: v1 +kind: Secret +metadata: + name: auth-generic-oauth-secret +type: Opaque +stringData: + client_id: + client_secret: +``` + +Include in the `extraSecretMounts` configuration flag: + +```yaml +- extraSecretMounts: + - name: auth-generic-oauth-secret-mount + secretName: auth-generic-oauth-secret + defaultMode: 0440 + mountPath: /etc/secrets/auth_generic_oauth + readOnly: true +``` + +### extraSecretMounts using a Container Storage Interface (CSI) provider + +This example uses a CSI driver e.g. retrieving secrets using [Azure Key Vault Provider](https://github.com/Azure/secrets-store-csi-driver-provider-azure) + +```yaml +- extraSecretMounts: + - name: secrets-store-inline + mountPath: /run/secrets + readOnly: true + csi: + driver: secrets-store.csi.k8s.io + readOnly: true + volumeAttributes: + secretProviderClass: "my-provider" + nodePublishSecretRef: + name: akv-creds +``` + +## Image Renderer Plug-In + +This chart supports enabling [remote image rendering](https://github.com/grafana/grafana-image-renderer/blob/master/README.md#run-in-docker) + +```yaml +imageRenderer: + enabled: true +``` + +### Image Renderer NetworkPolicy + +By default the image-renderer pods will have a network policy which only allows ingress traffic from the created grafana instance + +### High Availability for unified alerting + +If you want to run Grafana in a high availability cluster you need to enable +the headless service by setting `headlessService: true` in your `values.yaml` +file. + +As next step you have to setup the `grafana.ini` in your `values.yaml` in a way +that it will make use of the headless service to obtain all the IPs of the +cluster. You should replace ``{{ Name }}`` with the name of your helm deployment. + +```yaml +grafana.ini: + ... + unified_alerting: + enabled: true + ha_peers: {{ Name }}-headless:9094 + alerting: + enabled: false +``` diff --git a/charts/oes/charts/grafana/ci/default-values.yaml b/charts/oes/charts/grafana/ci/default-values.yaml new file mode 100644 index 00000000..fc2ba605 --- /dev/null +++ b/charts/oes/charts/grafana/ci/default-values.yaml @@ -0,0 +1 @@ +# Leave this file empty to ensure that CI runs builds against the default configuration in values.yaml. diff --git a/charts/oes/charts/grafana/ci/with-affinity-values.yaml b/charts/oes/charts/grafana/ci/with-affinity-values.yaml new file mode 100644 index 00000000..f5b9b53e --- /dev/null +++ b/charts/oes/charts/grafana/ci/with-affinity-values.yaml @@ -0,0 +1,16 @@ +affinity: + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchLabels: + app.kubernetes.io/instance: grafana-test + app.kubernetes.io/name: grafana + topologyKey: failure-domain.beta.kubernetes.io/zone + weight: 100 + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchLabels: + app.kubernetes.io/instance: grafana-test + app.kubernetes.io/name: grafana + topologyKey: kubernetes.io/hostname diff --git a/charts/oes/charts/grafana/ci/with-dashboard-json-values.yaml b/charts/oes/charts/grafana/ci/with-dashboard-json-values.yaml new file mode 100644 index 00000000..e0c4e416 --- /dev/null +++ b/charts/oes/charts/grafana/ci/with-dashboard-json-values.yaml @@ -0,0 +1,53 @@ +dashboards: + my-provider: + my-awesome-dashboard: + # An empty but valid dashboard + json: | + { + "__inputs": [], + "__requires": [ + { + "type": "grafana", + "id": "grafana", + "name": "Grafana", + "version": "6.3.5" + } + ], + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": "-- Grafana --", + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "editable": true, + "gnetId": null, + "graphTooltip": 0, + "id": null, + "links": [], + "panels": [], + "schemaVersion": 19, + "style": "dark", + "tags": [], + "templating": { + "list": [] + }, + "time": { + "from": "now-6h", + "to": "now" + }, + "timepicker": { + "refresh_intervals": ["5s"] + }, + "timezone": "", + "title": "Dummy Dashboard", + "uid": "IdcYQooWk", + "version": 1 + } + datasource: Prometheus diff --git a/charts/oes/charts/grafana/ci/with-dashboard-values.yaml b/charts/oes/charts/grafana/ci/with-dashboard-values.yaml new file mode 100644 index 00000000..7b662c5f --- /dev/null +++ b/charts/oes/charts/grafana/ci/with-dashboard-values.yaml @@ -0,0 +1,19 @@ +dashboards: + my-provider: + my-awesome-dashboard: + gnetId: 10000 + revision: 1 + datasource: Prometheus +dashboardProviders: + dashboardproviders.yaml: + apiVersion: 1 + providers: + - name: 'my-provider' + orgId: 1 + folder: '' + type: file + updateIntervalSeconds: 10 + disableDeletion: true + editable: true + options: + path: /var/lib/grafana/dashboards/my-provider diff --git a/charts/oes/charts/grafana/ci/with-extraconfigmapmounts-values.yaml b/charts/oes/charts/grafana/ci/with-extraconfigmapmounts-values.yaml new file mode 100644 index 00000000..f2d55a83 --- /dev/null +++ b/charts/oes/charts/grafana/ci/with-extraconfigmapmounts-values.yaml @@ -0,0 +1,7 @@ +extraConfigmapMounts: + - name: '{{ template "grafana.fullname" . }}' + configMap: '{{ template "grafana.fullname" . }}' + mountPath: /var/lib/grafana/dashboards/test-dashboard.json + # This is not a realistic test, but for this we only care about extraConfigmapMounts not being empty and pointing to an existing ConfigMap + subPath: grafana.ini + readOnly: true diff --git a/charts/oes/charts/grafana/ci/with-image-renderer-values.yaml b/charts/oes/charts/grafana/ci/with-image-renderer-values.yaml new file mode 100644 index 00000000..32f30743 --- /dev/null +++ b/charts/oes/charts/grafana/ci/with-image-renderer-values.yaml @@ -0,0 +1,19 @@ +podLabels: + customLableA: Aaaaa +imageRenderer: + enabled: true + env: + RENDERING_ARGS: --disable-gpu,--window-size=1280x758 + RENDERING_MODE: clustered + podLabels: + customLableB: Bbbbb + networkPolicy: + limitIngress: true + limitEgress: true + resources: + limits: + cpu: 1000m + memory: 1000Mi + requests: + cpu: 500m + memory: 50Mi diff --git a/charts/oes/charts/grafana/ci/with-persistence.yaml b/charts/oes/charts/grafana/ci/with-persistence.yaml new file mode 100644 index 00000000..b92ca02c --- /dev/null +++ b/charts/oes/charts/grafana/ci/with-persistence.yaml @@ -0,0 +1,3 @@ +persistence: + type: pvc + enabled: true diff --git a/charts/oes/charts/grafana/dashboards/custom-dashboard.json b/charts/oes/charts/grafana/dashboards/custom-dashboard.json new file mode 100644 index 00000000..9e26dfee --- /dev/null +++ b/charts/oes/charts/grafana/dashboards/custom-dashboard.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/charts/oes/charts/grafana/templates/NOTES.txt b/charts/oes/charts/grafana/templates/NOTES.txt new file mode 100644 index 00000000..1fc8436d --- /dev/null +++ b/charts/oes/charts/grafana/templates/NOTES.txt @@ -0,0 +1,54 @@ +1. Get your '{{ .Values.adminUser }}' user password by running: + + kubectl get secret --namespace {{ template "grafana.namespace" . }} {{ template "grafana.fullname" . }} -o jsonpath="{.data.admin-password}" | base64 --decode ; echo + +2. The Grafana server can be accessed via port {{ .Values.service.port }} on the following DNS name from within your cluster: + + {{ template "grafana.fullname" . }}.{{ template "grafana.namespace" . }}.svc.cluster.local +{{ if .Values.ingress.enabled }} + If you bind grafana to 80, please update values in values.yaml and reinstall: + ``` + securityContext: + runAsUser: 0 + runAsGroup: 0 + fsGroup: 0 + + command: + - "setcap" + - "'cap_net_bind_service=+ep'" + - "/usr/sbin/grafana-server &&" + - "sh" + - "/run.sh" + ``` + Details refer to https://grafana.com/docs/installation/configuration/#http-port. + Or grafana would always crash. + + From outside the cluster, the server URL(s) are: +{{- range .Values.ingress.hosts }} + http://{{ . }} +{{- end }} +{{ else }} + Get the Grafana URL to visit by running these commands in the same shell: +{{ if contains "NodePort" .Values.service.type -}} + export NODE_PORT=$(kubectl get --namespace {{ template "grafana.namespace" . }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ template "grafana.fullname" . }}) + export NODE_IP=$(kubectl get nodes --namespace {{ template "grafana.namespace" . }} -o jsonpath="{.items[0].status.addresses[0].address}") + echo http://$NODE_IP:$NODE_PORT +{{ else if contains "LoadBalancer" .Values.service.type -}} + NOTE: It may take a few minutes for the LoadBalancer IP to be available. + You can watch the status of by running 'kubectl get svc --namespace {{ template "grafana.namespace" . }} -w {{ template "grafana.fullname" . }}' + export SERVICE_IP=$(kubectl get svc --namespace {{ template "grafana.namespace" . }} {{ template "grafana.fullname" . }} -o jsonpath='{.status.loadBalancer.ingress[0].ip}') + http://$SERVICE_IP:{{ .Values.service.port -}} +{{ else if contains "ClusterIP" .Values.service.type }} + export POD_NAME=$(kubectl get pods --namespace {{ template "grafana.namespace" . }} -l "app.kubernetes.io/name={{ template "grafana.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}") + kubectl --namespace {{ template "grafana.namespace" . }} port-forward $POD_NAME 3000 +{{- end }} +{{- end }} + +3. Login with the password from step 1 and the username: {{ .Values.adminUser }} + +{{- if not .Values.persistence.enabled }} +################################################################################# +###### WARNING: Persistence is disabled!!! You will lose your data when ##### +###### the Grafana pod is terminated. ##### +################################################################################# +{{- end }} diff --git a/charts/oes/charts/grafana/templates/_helpers.tpl b/charts/oes/charts/grafana/templates/_helpers.tpl new file mode 100644 index 00000000..41ec751a --- /dev/null +++ b/charts/oes/charts/grafana/templates/_helpers.tpl @@ -0,0 +1,185 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +*/}} +{{- define "grafana.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "grafana.fullname" -}} +{{- if .Values.fullnameOverride -}} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- $name := default .Chart.Name .Values.nameOverride -}} +{{- if contains $name .Release.Name -}} +{{- .Release.Name | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} +{{- end -}} +{{- end -}} +{{- end -}} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "grafana.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Create the name of the service account +*/}} +{{- define "grafana.serviceAccountName" -}} +{{- if .Values.serviceAccount.create -}} + {{ default (include "grafana.fullname" .) .Values.serviceAccount.name }} +{{- else -}} + {{ default "default" .Values.serviceAccount.name }} +{{- end -}} +{{- end -}} + +{{- define "grafana.serviceAccountNameTest" -}} +{{- if .Values.serviceAccount.create -}} + {{ default (print (include "grafana.fullname" .) "-test") .Values.serviceAccount.nameTest }} +{{- else -}} + {{ default "default" .Values.serviceAccount.nameTest }} +{{- end -}} +{{- end -}} + +{{/* +Allow the release namespace to be overridden for multi-namespace deployments in combined charts +*/}} +{{- define "grafana.namespace" -}} + {{- if .Values.namespaceOverride -}} + {{- .Values.namespaceOverride -}} + {{- else -}} + {{- .Release.Namespace -}} + {{- end -}} +{{- end -}} + +{{/* +Common labels +*/}} +{{- define "grafana.labels" -}} +helm.sh/chart: {{ include "grafana.chart" . }} +{{ include "grafana.selectorLabels" . }} +{{- if or .Chart.AppVersion .Values.image.tag }} +app.kubernetes.io/version: {{ .Values.image.tag | default .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- if .Values.extraLabels }} +{{ toYaml .Values.extraLabels }} +{{- end }} +{{- end -}} + +{{/* +Selector labels +*/}} +{{- define "grafana.selectorLabels" -}} +app.kubernetes.io/name: {{ include "grafana.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end -}} + +{{/* +Common labels +*/}} +{{- define "grafana.imageRenderer.labels" -}} +helm.sh/chart: {{ include "grafana.chart" . }} +{{ include "grafana.imageRenderer.selectorLabels" . }} +{{- if or .Chart.AppVersion .Values.image.tag }} +app.kubernetes.io/version: {{ .Values.image.tag | default .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end -}} + +{{/* +Selector labels ImageRenderer +*/}} +{{- define "grafana.imageRenderer.selectorLabels" -}} +app.kubernetes.io/name: {{ include "grafana.name" . }}-image-renderer +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end -}} + +{{/* +Looks if there's an existing secret and reuse its password. If not it generates +new password and use it. +*/}} +{{- define "grafana.password" -}} +{{- $secret := (lookup "v1" "Secret" (include "grafana.namespace" .) (include "grafana.fullname" .) ) -}} + {{- if $secret -}} + {{- index $secret "data" "admin-password" -}} + {{- else -}} + {{- (randAlphaNum 40) | b64enc | quote -}} + {{- end -}} +{{- end -}} + +{{/* +Return the appropriate apiVersion for rbac. +*/}} +{{- define "grafana.rbac.apiVersion" -}} + {{- if .Capabilities.APIVersions.Has "rbac.authorization.k8s.io/v1" }} + {{- print "rbac.authorization.k8s.io/v1" -}} + {{- else -}} + {{- print "rbac.authorization.k8s.io/v1beta1" -}} + {{- end -}} +{{- end -}} + +{{/* +Return the appropriate apiVersion for ingress. +*/}} +{{- define "grafana.ingress.apiVersion" -}} + {{- if and (.Capabilities.APIVersions.Has "networking.k8s.io/v1") (semverCompare ">= 1.19-0" .Capabilities.KubeVersion.Version) -}} + {{- print "networking.k8s.io/v1" -}} + {{- else if .Capabilities.APIVersions.Has "networking.k8s.io/v1beta1" -}} + {{- print "networking.k8s.io/v1beta1" -}} + {{- else -}} + {{- print "extensions/v1beta1" -}} + {{- end -}} +{{- end -}} + +{{/* +Return the appropriate apiVersion for podSecurityPolicy. +*/}} +{{- define "grafana.podSecurityPolicy.apiVersion" -}} + {{- if and (.Capabilities.APIVersions.Has "policy/v1") (semverCompare ">= 1.16-0" .Capabilities.KubeVersion.Version) -}} + {{- print "policy/v1beta1" -}} + {{- else -}} + {{- print "extensions/v1beta1" -}} + {{- end -}} +{{- end -}} + +{{/* +Return the appropriate apiVersion for podDisruptionBudget. +*/}} +{{- define "grafana.podDisruptionBudget.apiVersion" -}} + {{- if and (.Capabilities.APIVersions.Has "policy/v1") (semverCompare ">= 1.21-0" .Capabilities.KubeVersion.Version) -}} + {{- print "policy/v1" -}} + {{- else -}} + {{- print "policy/v1beta1" -}} + {{- end -}} +{{- end -}} + +{{/* +Return if ingress is stable. +*/}} +{{- define "grafana.ingress.isStable" -}} + {{- eq (include "grafana.ingress.apiVersion" .) "networking.k8s.io/v1" -}} +{{- end -}} + +{{/* +Return if ingress supports ingressClassName. +*/}} +{{- define "grafana.ingress.supportsIngressClassName" -}} + {{- or (eq (include "grafana.ingress.isStable" .) "true") (and (eq (include "grafana.ingress.apiVersion" .) "networking.k8s.io/v1beta1") (semverCompare ">= 1.18-0" .Capabilities.KubeVersion.Version)) -}} +{{- end -}} + +{{/* +Return if ingress supports pathType. +*/}} +{{- define "grafana.ingress.supportsPathType" -}} + {{- or (eq (include "grafana.ingress.isStable" .) "true") (and (eq (include "grafana.ingress.apiVersion" .) "networking.k8s.io/v1beta1") (semverCompare ">= 1.18-0" .Capabilities.KubeVersion.Version)) -}} +{{- end -}} diff --git a/charts/oes/charts/grafana/templates/_pod.tpl b/charts/oes/charts/grafana/templates/_pod.tpl new file mode 100644 index 00000000..9ca039f8 --- /dev/null +++ b/charts/oes/charts/grafana/templates/_pod.tpl @@ -0,0 +1,748 @@ + +{{- define "grafana.pod" -}} +{{- if .Values.schedulerName }} +schedulerName: "{{ .Values.schedulerName }}" +{{- end }} +serviceAccountName: {{ template "grafana.serviceAccountName" . }} +automountServiceAccountToken: {{ .Values.serviceAccount.autoMount }} +{{- if .Values.securityContext }} +securityContext: +{{ toYaml .Values.securityContext | indent 2 }} +{{- end }} +{{- if .Values.hostAliases }} +hostAliases: +{{ toYaml .Values.hostAliases | indent 2 }} +{{- end }} +{{- if .Values.priorityClassName }} +priorityClassName: {{ .Values.priorityClassName }} +{{- end }} +{{- if ( or .Values.persistence.enabled .Values.dashboards .Values.sidecar.notifiers.enabled .Values.extraInitContainers (and .Values.sidecar.datasources.enabled .Values.sidecar.datasources.initDatasources)) }} +initContainers: +{{- end }} +{{- if ( and .Values.persistence.enabled .Values.initChownData.enabled ) }} + - name: init-chown-data + {{- if .Values.initChownData.image.sha }} + image: "{{ .Values.initChownData.image.repository }}:{{ .Values.initChownData.image.tag }}@sha256:{{ .Values.initChownData.image.sha }}" + {{- else }} + image: "{{ .Values.initChownData.image.repository }}:{{ .Values.initChownData.image.tag }}" + {{- end }} + imagePullPolicy: {{ .Values.initChownData.image.pullPolicy }} + securityContext: + runAsNonRoot: false + runAsUser: 0 + command: ["chown", "-R", "{{ .Values.securityContext.runAsUser }}:{{ .Values.securityContext.runAsGroup }}", "/var/lib/grafana"] + resources: +{{ toYaml .Values.initChownData.resources | indent 6 }} + volumeMounts: + - name: storage + mountPath: "/var/lib/grafana" +{{- if .Values.persistence.subPath }} + subPath: {{ tpl .Values.persistence.subPath . }} +{{- end }} +{{- end }} +{{- if .Values.dashboards }} + - name: download-dashboards + {{- if .Values.downloadDashboardsImage.sha }} + image: "{{ .Values.downloadDashboardsImage.repository }}:{{ .Values.downloadDashboardsImage.tag }}@sha256:{{ .Values.downloadDashboardsImage.sha }}" + {{- else }} + image: "{{ .Values.downloadDashboardsImage.repository }}:{{ .Values.downloadDashboardsImage.tag }}" + {{- end }} + imagePullPolicy: {{ .Values.downloadDashboardsImage.pullPolicy }} + command: ["/bin/sh"] + args: [ "-c", "mkdir -p /var/lib/grafana/dashboards/default && /bin/sh -x /etc/grafana/download_dashboards.sh" ] + resources: +{{ toYaml .Values.downloadDashboards.resources | indent 6 }} + env: +{{- range $key, $value := .Values.downloadDashboards.env }} + - name: "{{ $key }}" + value: "{{ $value }}" +{{- end }} +{{- if .Values.downloadDashboards.envFromSecret }} + envFrom: + - secretRef: + name: {{ tpl .Values.downloadDashboards.envFromSecret . }} +{{- end }} + volumeMounts: + - name: config + mountPath: "/etc/grafana/download_dashboards.sh" + subPath: download_dashboards.sh + - name: storage + mountPath: "/var/lib/grafana" +{{- if .Values.persistence.subPath }} + subPath: {{ tpl .Values.persistence.subPath . }} +{{- end }} + {{- range .Values.extraSecretMounts }} + - name: {{ .name }} + mountPath: {{ .mountPath }} + readOnly: {{ .readOnly }} + {{- end }} +{{- end }} +{{- if and .Values.sidecar.datasources.enabled .Values.sidecar.datasources.initDatasources }} + - name: {{ template "grafana.name" . }}-init-sc-datasources + {{- if .Values.sidecar.image.sha }} + image: "{{ .Values.sidecar.image.repository }}:{{ .Values.sidecar.image.tag }}@sha256:{{ .Values.sidecar.image.sha }}" + {{- else }} + image: "{{ .Values.sidecar.image.repository }}:{{ .Values.sidecar.image.tag }}" + {{- end }} + imagePullPolicy: {{ .Values.sidecar.imagePullPolicy }} + env: + - name: METHOD + value: "LIST" + - name: LABEL + value: "{{ .Values.sidecar.datasources.label }}" + {{- if .Values.sidecar.datasources.labelValue }} + - name: LABEL_VALUE + value: {{ quote .Values.sidecar.datasources.labelValue }} + {{- end }} + - name: FOLDER + value: "/etc/grafana/provisioning/datasources" + - name: RESOURCE + value: {{ quote .Values.sidecar.datasources.resource }} + {{- if .Values.sidecar.enableUniqueFilenames }} + - name: UNIQUE_FILENAMES + value: "{{ .Values.sidecar.enableUniqueFilenames }}" + {{- end }} + {{- if .Values.sidecar.datasources.searchNamespace }} + - name: NAMESPACE + value: "{{ .Values.sidecar.datasources.searchNamespace | join "," }}" + {{- end }} + {{- if .Values.sidecar.skipTlsVerify }} + - name: SKIP_TLS_VERIFY + value: "{{ .Values.sidecar.skipTlsVerify }}" + {{- end }} + resources: +{{ toYaml .Values.sidecar.resources | indent 6 }} +{{- if .Values.sidecar.securityContext }} + securityContext: +{{- toYaml .Values.sidecar.securityContext | nindent 6 }} +{{- end }} + volumeMounts: + - name: sc-datasources-volume + mountPath: "/etc/grafana/provisioning/datasources" +{{- end }} +{{- if .Values.sidecar.notifiers.enabled }} + - name: {{ template "grafana.name" . }}-sc-notifiers + {{- if .Values.sidecar.image.sha }} + image: "{{ .Values.sidecar.image.repository }}:{{ .Values.sidecar.image.tag }}@sha256:{{ .Values.sidecar.image.sha }}" + {{- else }} + image: "{{ .Values.sidecar.image.repository }}:{{ .Values.sidecar.image.tag }}" + {{- end }} + imagePullPolicy: {{ .Values.sidecar.imagePullPolicy }} + env: + - name: METHOD + value: LIST + - name: LABEL + value: "{{ .Values.sidecar.notifiers.label }}" + - name: FOLDER + value: "/etc/grafana/provisioning/notifiers" + - name: RESOURCE + value: {{ quote .Values.sidecar.notifiers.resource }} + {{- if .Values.sidecar.enableUniqueFilenames }} + - name: UNIQUE_FILENAMES + value: "{{ .Values.sidecar.enableUniqueFilenames }}" + {{- end }} + {{- if .Values.sidecar.notifiers.searchNamespace }} + - name: NAMESPACE + value: "{{ .Values.sidecar.notifiers.searchNamespace | join "," }}" + {{- end }} + {{- if .Values.sidecar.skipTlsVerify }} + - name: SKIP_TLS_VERIFY + value: "{{ .Values.sidecar.skipTlsVerify }}" + {{- end }} +{{- if .Values.sidecar.livenessProbe }} + livenessProbe: +{{ toYaml .Values.livenessProbe | indent 6 }} +{{- end }} +{{- if .Values.sidecar.readinessProbe }} + readinessProbe: +{{ toYaml .Values.readinessProbe | indent 6 }} +{{- end }} + resources: +{{ toYaml .Values.sidecar.resources | indent 6 }} +{{- if .Values.sidecar.securityContext }} + securityContext: +{{- toYaml .Values.sidecar.securityContext | nindent 6 }} +{{- end }} + volumeMounts: + - name: sc-notifiers-volume + mountPath: "/etc/grafana/provisioning/notifiers" +{{- end}} +{{- if .Values.extraInitContainers }} +{{ tpl (toYaml .Values.extraInitContainers) . | indent 2 }} +{{- end }} +{{- if .Values.image.pullSecrets }} +imagePullSecrets: +{{- $root := . }} +{{- range .Values.image.pullSecrets }} + - name: {{ tpl . $root }} +{{- end}} +{{- end }} +{{- if not .Values.enableKubeBackwardCompatibility }} +enableServiceLinks: {{ .Values.enableServiceLinks }} +{{- end }} +containers: +{{- if .Values.sidecar.dashboards.enabled }} + - name: {{ template "grafana.name" . }}-sc-dashboard + {{- if .Values.sidecar.image.sha }} + image: "{{ .Values.sidecar.image.repository }}:{{ .Values.sidecar.image.tag }}@sha256:{{ .Values.sidecar.image.sha }}" + {{- else }} + image: "{{ .Values.sidecar.image.repository }}:{{ .Values.sidecar.image.tag }}" + {{- end }} + imagePullPolicy: {{ .Values.sidecar.imagePullPolicy }} + env: + - name: METHOD + value: {{ .Values.sidecar.dashboards.watchMethod }} + - name: LABEL + value: "{{ .Values.sidecar.dashboards.label }}" + {{- if .Values.sidecar.dashboards.labelValue }} + - name: LABEL_VALUE + value: {{ quote .Values.sidecar.dashboards.labelValue }} + {{- end }} + - name: FOLDER + value: "{{ .Values.sidecar.dashboards.folder }}{{- with .Values.sidecar.dashboards.defaultFolderName }}/{{ . }}{{- end }}" + - name: RESOURCE + value: {{ quote .Values.sidecar.dashboards.resource }} + {{- if .Values.sidecar.enableUniqueFilenames }} + - name: UNIQUE_FILENAMES + value: "{{ .Values.sidecar.enableUniqueFilenames }}" + {{- end }} + {{- if .Values.sidecar.dashboards.searchNamespace }} + - name: NAMESPACE + value: "{{ .Values.sidecar.dashboards.searchNamespace | join "," }}" + {{- end }} + {{- if .Values.sidecar.skipTlsVerify }} + - name: SKIP_TLS_VERIFY + value: "{{ .Values.sidecar.skipTlsVerify }}" + {{- end }} + {{- if .Values.sidecar.dashboards.folderAnnotation }} + - name: FOLDER_ANNOTATION + value: "{{ .Values.sidecar.dashboards.folderAnnotation }}" + {{- end }} + {{- if .Values.sidecar.dashboards.script }} + - name: SCRIPT + value: "{{ .Values.sidecar.dashboards.script }}" + {{- end }} + {{- if .Values.sidecar.dashboards.watchServerTimeout }} + - name: WATCH_SERVER_TIMEOUT + value: "{{ .Values.sidecar.dashboards.watchServerTimeout }}" + {{- end }} + {{- if .Values.sidecar.dashboards.watchClientTimeout }} + - name: WATCH_CLIENT_TIMEOUT + value: "{{ .Values.sidecar.dashboards.watchClientTimeout }}" + {{- end }} +{{- if .Values.sidecar.livenessProbe }} + livenessProbe: +{{ toYaml .Values.livenessProbe | indent 6 }} +{{- end }} +{{- if .Values.sidecar.readinessProbe }} + readinessProbe: +{{ toYaml .Values.readinessProbe | indent 6 }} +{{- end }} + resources: +{{ toYaml .Values.sidecar.resources | indent 6 }} +{{- if .Values.sidecar.securityContext }} + securityContext: +{{- toYaml .Values.sidecar.securityContext | nindent 6 }} +{{- end }} + volumeMounts: + - name: sc-dashboard-volume + mountPath: {{ .Values.sidecar.dashboards.folder | quote }} + {{- if .Values.sidecar.dashboards.extraMounts }} + {{- toYaml .Values.sidecar.dashboards.extraMounts | trim | nindent 6}} + {{- end }} +{{- end}} +{{- if .Values.sidecar.datasources.enabled }} + - name: {{ template "grafana.name" . }}-sc-datasources + {{- if .Values.sidecar.image.sha }} + image: "{{ .Values.sidecar.image.repository }}:{{ .Values.sidecar.image.tag }}@sha256:{{ .Values.sidecar.image.sha }}" + {{- else }} + image: "{{ .Values.sidecar.image.repository }}:{{ .Values.sidecar.image.tag }}" + {{- end }} + imagePullPolicy: {{ .Values.sidecar.imagePullPolicy }} + env: + - name: METHOD + value: {{ .Values.sidecar.datasources.watchMethod }} + - name: LABEL + value: "{{ .Values.sidecar.datasources.label }}" + {{- if .Values.sidecar.datasources.labelValue }} + - name: LABEL_VALUE + value: {{ quote .Values.sidecar.datasources.labelValue }} + {{- end }} + - name: FOLDER + value: "/etc/grafana/provisioning/datasources" + - name: RESOURCE + value: {{ quote .Values.sidecar.datasources.resource }} + {{- if .Values.sidecar.enableUniqueFilenames }} + - name: UNIQUE_FILENAMES + value: "{{ .Values.sidecar.enableUniqueFilenames }}" + {{- end }} + {{- if .Values.sidecar.datasources.searchNamespace }} + - name: NAMESPACE + value: "{{ .Values.sidecar.datasources.searchNamespace | join "," }}" + {{- end }} + {{- if .Values.sidecar.skipTlsVerify }} + - name: SKIP_TLS_VERIFY + value: "{{ .Values.sidecar.skipTlsVerify }}" + {{- end }} + {{- if and (not .Values.env.GF_SECURITY_ADMIN_USER) (not .Values.env.GF_SECURITY_DISABLE_INITIAL_ADMIN_CREATION) }} + - name: REQ_USERNAME + valueFrom: + secretKeyRef: + name: {{ (tpl .Values.admin.existingSecret .) | default (include "grafana.fullname" .) }} + key: {{ .Values.admin.userKey | default "admin-user" }} + {{- end }} + {{- if and (not .Values.env.GF_SECURITY_ADMIN_PASSWORD) (not .Values.env.GF_SECURITY_ADMIN_PASSWORD__FILE) (not .Values.env.GF_SECURITY_DISABLE_INITIAL_ADMIN_CREATION) }} + - name: REQ_PASSWORD + valueFrom: + secretKeyRef: + name: {{ (tpl .Values.admin.existingSecret .) | default (include "grafana.fullname" .) }} + key: {{ .Values.admin.passwordKey | default "admin-password" }} + {{- end }} + {{- if not .Values.sidecar.datasources.skipReload }} + - name: REQ_URL + value: {{ .Values.sidecar.datasources.reloadURL }} + - name: REQ_METHOD + value: POST + {{- end }} +{{- if .Values.sidecar.livenessProbe }} + livenessProbe: +{{ toYaml .Values.livenessProbe | indent 6 }} +{{- end }} +{{- if .Values.sidecar.readinessProbe }} + readinessProbe: +{{ toYaml .Values.readinessProbe | indent 6 }} +{{- end }} + resources: +{{ toYaml .Values.sidecar.resources | indent 6 }} +{{- if .Values.sidecar.securityContext }} + securityContext: +{{- toYaml .Values.sidecar.securityContext | nindent 6 }} +{{- end }} + volumeMounts: + - name: sc-datasources-volume + mountPath: "/etc/grafana/provisioning/datasources" +{{- end}} +{{- if .Values.sidecar.plugins.enabled }} + - name: {{ template "grafana.name" . }}-sc-plugins + {{- if .Values.sidecar.image.sha }} + image: "{{ .Values.sidecar.image.repository }}:{{ .Values.sidecar.image.tag }}@sha256:{{ .Values.sidecar.image.sha }}" + {{- else }} + image: "{{ .Values.sidecar.image.repository }}:{{ .Values.sidecar.image.tag }}" + {{- end }} + imagePullPolicy: {{ .Values.sidecar.imagePullPolicy }} + env: + - name: METHOD + value: {{ .Values.sidecar.plugins.watchMethod }} + - name: LABEL + value: "{{ .Values.sidecar.plugins.label }}" + {{- if .Values.sidecar.plugins.labelValue }} + - name: LABEL_VALUE + value: {{ quote .Values.sidecar.plugins.labelValue }} + {{- end }} + - name: FOLDER + value: "/etc/grafana/provisioning/plugins" + - name: RESOURCE + value: {{ quote .Values.sidecar.plugins.resource }} + {{- if .Values.sidecar.enableUniqueFilenames }} + - name: UNIQUE_FILENAMES + value: "{{ .Values.sidecar.enableUniqueFilenames }}" + {{- end }} + {{- if .Values.sidecar.plugins.searchNamespace }} + - name: NAMESPACE + value: "{{ .Values.sidecar.plugins.searchNamespace | join "," }}" + {{- end }} + {{- if .Values.sidecar.skipTlsVerify }} + - name: SKIP_TLS_VERIFY + value: "{{ .Values.sidecar.skipTlsVerify }}" + {{- end }} + {{- if and (not .Values.env.GF_SECURITY_ADMIN_USER) (not .Values.env.GF_SECURITY_DISABLE_INITIAL_ADMIN_CREATION) }} + - name: REQ_USERNAME + valueFrom: + secretKeyRef: + name: {{ (tpl .Values.admin.existingSecret .) | default (include "grafana.fullname" .) }} + key: {{ .Values.admin.userKey | default "admin-user" }} + {{- end }} + {{- if and (not .Values.env.GF_SECURITY_ADMIN_PASSWORD) (not .Values.env.GF_SECURITY_ADMIN_PASSWORD__FILE) (not .Values.env.GF_SECURITY_DISABLE_INITIAL_ADMIN_CREATION) }} + - name: REQ_PASSWORD + valueFrom: + secretKeyRef: + name: {{ (tpl .Values.admin.existingSecret .) | default (include "grafana.fullname" .) }} + key: {{ .Values.admin.passwordKey | default "admin-password" }} + {{- end }} + {{- if not .Values.sidecar.plugins.skipReload }} + - name: REQ_URL + value: {{ .Values.sidecar.plugins.reloadURL }} + - name: REQ_METHOD + value: POST + {{- end }} +{{- if .Values.sidecar.livenessProbe }} + livenessProbe: +{{ toYaml .Values.livenessProbe | indent 6 }} +{{- end }} +{{- if .Values.sidecar.readinessProbe }} + readinessProbe: +{{ toYaml .Values.readinessProbe | indent 6 }} +{{- end }} + resources: +{{ toYaml .Values.sidecar.resources | indent 6 }} +{{- if .Values.sidecar.securityContext }} + securityContext: +{{- toYaml .Values.sidecar.securityContext | nindent 6 }} +{{- end }} + volumeMounts: + - name: sc-plugins-volume + mountPath: "/etc/grafana/provisioning/plugins" +{{- end}} + - name: {{ .Chart.Name }} + {{- if .Values.image.sha }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}@sha256:{{ .Values.image.sha }}" + {{- else }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" + {{- end }} + imagePullPolicy: {{ .Values.image.pullPolicy }} + {{- if .Values.command }} + command: + {{- range .Values.command }} + - {{ . }} + {{- end }} + {{- end}} +{{- if .Values.containerSecurityContext }} + securityContext: +{{- toYaml .Values.containerSecurityContext | nindent 6 }} +{{- end }} + volumeMounts: + - name: config + mountPath: "/etc/grafana/grafana.ini" + subPath: grafana.ini + {{- if .Values.ldap.enabled }} + - name: ldap + mountPath: "/etc/grafana/ldap.toml" + subPath: ldap.toml + {{- end }} + {{- $root := . }} + {{- range .Values.extraConfigmapMounts }} + - name: {{ tpl .name $root }} + mountPath: {{ tpl .mountPath $root }} + subPath: {{ (tpl .subPath $root) | default "" }} + readOnly: {{ .readOnly }} + {{- end }} + - name: storage + mountPath: "/var/lib/grafana" +{{- if .Values.persistence.subPath }} + subPath: {{ tpl .Values.persistence.subPath . }} +{{- end }} +{{- if .Values.dashboards }} +{{- range $provider, $dashboards := .Values.dashboards }} +{{- range $key, $value := $dashboards }} +{{- if (or (hasKey $value "json") (hasKey $value "file")) }} + - name: dashboards-{{ $provider }} + mountPath: "/var/lib/grafana/dashboards/{{ $provider }}/{{ $key }}.json" + subPath: "{{ $key }}.json" +{{- end }} +{{- end }} +{{- end }} +{{- end -}} +{{- if .Values.dashboardsConfigMaps }} +{{- range (keys .Values.dashboardsConfigMaps | sortAlpha) }} + - name: dashboards-{{ . }} + mountPath: "/var/lib/grafana/dashboards/{{ . }}" +{{- end }} +{{- end }} +{{- if .Values.datasources }} +{{- range (keys .Values.datasources | sortAlpha) }} + - name: config + mountPath: "/etc/grafana/provisioning/datasources/{{ . }}" + subPath: {{ . | quote }} +{{- end }} +{{- end }} +{{- if .Values.notifiers }} +{{- range (keys .Values.notifiers | sortAlpha) }} + - name: config + mountPath: "/etc/grafana/provisioning/notifiers/{{ . }}" + subPath: {{ . | quote }} +{{- end }} +{{- end }} +{{- if .Values.dashboardProviders }} +{{- range (keys .Values.dashboardProviders | sortAlpha) }} + - name: config + mountPath: "/etc/grafana/provisioning/dashboards/{{ . }}" + subPath: {{ . | quote }} +{{- end }} +{{- end }} +{{- if .Values.sidecar.dashboards.enabled }} + - name: sc-dashboard-volume + mountPath: {{ .Values.sidecar.dashboards.folder | quote }} +{{ if .Values.sidecar.dashboards.SCProvider }} + - name: sc-dashboard-provider + mountPath: "/etc/grafana/provisioning/dashboards/sc-dashboardproviders.yaml" + subPath: provider.yaml +{{- end}} +{{- end}} +{{- if .Values.sidecar.datasources.enabled }} + - name: sc-datasources-volume + mountPath: "/etc/grafana/provisioning/datasources" +{{- end}} +{{- if .Values.sidecar.plugins.enabled }} + - name: sc-plugins-volume + mountPath: "/etc/grafana/provisioning/plugins" +{{- end}} +{{- if .Values.sidecar.notifiers.enabled }} + - name: sc-notifiers-volume + mountPath: "/etc/grafana/provisioning/notifiers" +{{- end}} + {{- range .Values.extraSecretMounts }} + - name: {{ .name }} + mountPath: {{ .mountPath }} + readOnly: {{ .readOnly }} + subPath: {{ .subPath | default "" }} + {{- end }} + {{- range .Values.extraVolumeMounts }} + - name: {{ .name }} + mountPath: {{ .mountPath }} + subPath: {{ .subPath | default "" }} + readOnly: {{ .readOnly }} + {{- end }} + {{- range .Values.extraEmptyDirMounts }} + - name: {{ .name }} + mountPath: {{ .mountPath }} + {{- end }} + ports: + - name: {{ .Values.service.portName }} + containerPort: {{ .Values.service.port }} + protocol: TCP + - name: {{ .Values.podPortName }} + containerPort: 3000 + protocol: TCP + env: + {{- if and (not .Values.env.GF_SECURITY_ADMIN_USER) (not .Values.env.GF_SECURITY_DISABLE_INITIAL_ADMIN_CREATION) }} + - name: GF_SECURITY_ADMIN_USER + valueFrom: + secretKeyRef: + name: {{ (tpl .Values.admin.existingSecret .) | default (include "grafana.fullname" .) }} + key: {{ .Values.admin.userKey | default "admin-user" }} + {{- end }} + {{- if and (not .Values.env.GF_SECURITY_ADMIN_PASSWORD) (not .Values.env.GF_SECURITY_ADMIN_PASSWORD__FILE) (not .Values.env.GF_SECURITY_DISABLE_INITIAL_ADMIN_CREATION) }} + - name: GF_SECURITY_ADMIN_PASSWORD + valueFrom: + secretKeyRef: + name: {{ (tpl .Values.admin.existingSecret .) | default (include "grafana.fullname" .) }} + key: {{ .Values.admin.passwordKey | default "admin-password" }} + {{- end }} + {{- if .Values.plugins }} + - name: GF_INSTALL_PLUGINS + valueFrom: + configMapKeyRef: + name: {{ template "grafana.fullname" . }} + key: plugins + {{- end }} + {{- if .Values.smtp.existingSecret }} + - name: GF_SMTP_USER + valueFrom: + secretKeyRef: + name: {{ .Values.smtp.existingSecret }} + key: {{ .Values.smtp.userKey | default "user" }} + - name: GF_SMTP_PASSWORD + valueFrom: + secretKeyRef: + name: {{ .Values.smtp.existingSecret }} + key: {{ .Values.smtp.passwordKey | default "password" }} + {{- end }} + {{- if .Values.imageRenderer.enabled }} + - name: GF_RENDERING_SERVER_URL + value: http://{{ template "grafana.fullname" . }}-image-renderer.{{ template "grafana.namespace" . }}:{{ .Values.imageRenderer.service.port }}/render + - name: GF_RENDERING_CALLBACK_URL + value: {{ .Values.imageRenderer.grafanaProtocol }}://{{ template "grafana.fullname" . }}.{{ template "grafana.namespace" . }}:{{ .Values.service.port }}/{{ .Values.imageRenderer.grafanaSubPath }} + {{- end }} + - name: GF_PATHS_DATA + value: {{ (get .Values "grafana.ini").paths.data }} + - name: GF_PATHS_LOGS + value: {{ (get .Values "grafana.ini").paths.logs }} + - name: GF_PATHS_PLUGINS + value: {{ (get .Values "grafana.ini").paths.plugins }} + - name: GF_PATHS_PROVISIONING + value: {{ (get .Values "grafana.ini").paths.provisioning }} + {{- range $key, $value := .Values.envValueFrom }} + - name: {{ $key | quote }} + valueFrom: +{{ tpl (toYaml $value) $ | indent 10 }} + {{- end }} +{{- range $key, $value := .Values.env }} + - name: "{{ tpl $key $ }}" + value: "{{ tpl (print $value) $ }}" +{{- end }} + {{- if or .Values.envFromSecret (or .Values.envRenderSecret .Values.envFromSecrets) .Values.envFromConfigMaps }} + envFrom: + {{- if .Values.envFromSecret }} + - secretRef: + name: {{ tpl .Values.envFromSecret . }} + {{- end }} + {{- if .Values.envRenderSecret }} + - secretRef: + name: {{ template "grafana.fullname" . }}-env + {{- end }} + {{- range .Values.envFromSecrets }} + - secretRef: + name: {{ tpl .name $ }} + optional: {{ .optional | default false }} + {{- end }} + {{- range .Values.envFromConfigMaps }} + - configMapRef: + name: {{ tpl .name $ }} + optional: {{ .optional | default false }} + {{- end }} + {{- end }} + livenessProbe: +{{ toYaml .Values.livenessProbe | indent 6 }} + readinessProbe: +{{ toYaml .Values.readinessProbe | indent 6 }} +{{- if .Values.lifecycleHooks }} + lifecycle: {{ tpl (.Values.lifecycleHooks | toYaml) . | nindent 6 }} +{{- end }} + resources: +{{ toYaml .Values.resources | indent 6 }} +{{- with .Values.extraContainers }} +{{ tpl . $ | indent 2 }} +{{- end }} +{{- with .Values.nodeSelector }} +nodeSelector: +{{ toYaml . | indent 2 }} +{{- end }} +{{- $root := . }} +{{- with .Values.affinity }} +affinity: +{{ tpl (toYaml .) $root | indent 2 }} +{{- end }} +{{- with .Values.tolerations }} +tolerations: +{{ toYaml . | indent 2 }} +{{- end }} +volumes: + - name: config + configMap: + name: {{ template "grafana.fullname" . }} +{{- $root := . }} +{{- range .Values.extraConfigmapMounts }} + - name: {{ tpl .name $root }} + configMap: + name: {{ tpl .configMap $root }} +{{- end }} + {{- if .Values.dashboards }} + {{- range (keys .Values.dashboards | sortAlpha) }} + - name: dashboards-{{ . }} + configMap: + name: {{ template "grafana.fullname" $ }}-dashboards-{{ . }} + {{- end }} + {{- end }} + {{- if .Values.dashboardsConfigMaps }} + {{ $root := . }} + {{- range $provider, $name := .Values.dashboardsConfigMaps }} + - name: dashboards-{{ $provider }} + configMap: + name: {{ tpl $name $root }} + {{- end }} + {{- end }} + {{- if .Values.ldap.enabled }} + - name: ldap + secret: + {{- if .Values.ldap.existingSecret }} + secretName: {{ .Values.ldap.existingSecret }} + {{- else }} + secretName: {{ template "grafana.fullname" . }} + {{- end }} + items: + - key: ldap-toml + path: ldap.toml + {{- end }} +{{- if and .Values.persistence.enabled (eq .Values.persistence.type "pvc") }} + - name: storage + persistentVolumeClaim: + claimName: {{ tpl (.Values.persistence.existingClaim | default (include "grafana.fullname" .)) . }} +{{- else if and .Values.persistence.enabled (eq .Values.persistence.type "statefulset") }} +# nothing +{{- else }} + - name: storage +{{- if .Values.persistence.inMemory.enabled }} + emptyDir: + medium: Memory +{{- if .Values.persistence.inMemory.sizeLimit }} + sizeLimit: {{ .Values.persistence.inMemory.sizeLimit }} +{{- end -}} +{{- else }} + emptyDir: {} +{{- end -}} +{{- end -}} +{{- if .Values.sidecar.dashboards.enabled }} + - name: sc-dashboard-volume +{{- if .Values.sidecar.dashboards.sizeLimit }} + emptyDir: + sizeLimit: {{ .Values.sidecar.dashboards.sizeLimit }} +{{- else }} + emptyDir: {} +{{- end -}} +{{- if .Values.sidecar.dashboards.SCProvider }} + - name: sc-dashboard-provider + configMap: + name: {{ template "grafana.fullname" . }}-config-dashboards +{{- end }} +{{- end }} +{{- if .Values.sidecar.datasources.enabled }} + - name: sc-datasources-volume +{{- if .Values.sidecar.datasources.sizeLimit }} + emptyDir: + sizeLimit: {{ .Values.sidecar.datasources.sizeLimit }} +{{- else }} + emptyDir: {} +{{- end -}} +{{- end -}} +{{- if .Values.sidecar.plugins.enabled }} + - name: sc-plugins-volume +{{- if .Values.sidecar.plugins.sizeLimit }} + emptyDir: + sizeLimit: {{ .Values.sidecar.plugins.sizeLimit }} +{{- else }} + emptyDir: {} +{{- end -}} +{{- end -}} +{{- if .Values.sidecar.notifiers.enabled }} + - name: sc-notifiers-volume +{{- if .Values.sidecar.notifiers.sizeLimit }} + emptyDir: + sizeLimit: {{ .Values.sidecar.notifiers.sizeLimit }} +{{- else }} + emptyDir: {} +{{- end -}} +{{- end -}} +{{- range .Values.extraSecretMounts }} +{{- if .secretName }} + - name: {{ .name }} + secret: + secretName: {{ .secretName }} + defaultMode: {{ .defaultMode }} +{{- else if .projected }} + - name: {{ .name }} + projected: {{- toYaml .projected | nindent 6 }} +{{- else if .csi }} + - name: {{ .name }} + csi: {{- toYaml .csi | nindent 6 }} +{{- end }} +{{- end }} +{{- range .Values.extraVolumeMounts }} + - name: {{ .name }} + {{- if .existingClaim }} + persistentVolumeClaim: + claimName: {{ .existingClaim }} + {{- else if .hostPath }} + hostPath: + path: {{ .hostPath }} + {{- else }} + emptyDir: {} + {{- end }} +{{- end }} +{{- range .Values.extraEmptyDirMounts }} + - name: {{ .name }} + emptyDir: {} +{{- end -}} +{{- if .Values.extraContainerVolumes }} +{{ toYaml .Values.extraContainerVolumes | indent 2 }} +{{- end }} +{{- end }} diff --git a/charts/oes/charts/grafana/templates/clusterrole.yaml b/charts/oes/charts/grafana/templates/clusterrole.yaml new file mode 100644 index 00000000..154658b5 --- /dev/null +++ b/charts/oes/charts/grafana/templates/clusterrole.yaml @@ -0,0 +1,25 @@ +{{- if and .Values.rbac.create (not .Values.rbac.namespaced) (not .Values.rbac.useExistingRole) }} +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + labels: + {{- include "grafana.labels" . | nindent 4 }} +{{- with .Values.annotations }} + annotations: +{{ toYaml . | indent 4 }} +{{- end }} + name: {{ template "grafana.fullname" . }}-clusterrole +{{- if or .Values.sidecar.dashboards.enabled (or .Values.rbac.extraClusterRoleRules (or .Values.sidecar.datasources.enabled .Values.sidecar.plugins.enabled)) }} +rules: +{{- if or .Values.sidecar.dashboards.enabled (or .Values.sidecar.datasources.enabled .Values.sidecar.plugins.enabled) }} +- apiGroups: [""] # "" indicates the core API group + resources: ["configmaps", "secrets"] + verbs: ["get", "watch", "list"] +{{- end}} +{{- with .Values.rbac.extraClusterRoleRules }} +{{ toYaml . | indent 0 }} +{{- end}} +{{- else }} +rules: [] +{{- end}} +{{- end}} diff --git a/charts/oes/charts/grafana/templates/clusterrolebinding.yaml b/charts/oes/charts/grafana/templates/clusterrolebinding.yaml new file mode 100644 index 00000000..4accbfac --- /dev/null +++ b/charts/oes/charts/grafana/templates/clusterrolebinding.yaml @@ -0,0 +1,24 @@ +{{- if and .Values.rbac.create (not .Values.rbac.namespaced) }} +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ template "grafana.fullname" . }}-clusterrolebinding + labels: + {{- include "grafana.labels" . | nindent 4 }} +{{- with .Values.annotations }} + annotations: +{{ toYaml . | indent 4 }} +{{- end }} +subjects: + - kind: ServiceAccount + name: {{ template "grafana.serviceAccountName" . }} + namespace: {{ template "grafana.namespace" . }} +roleRef: + kind: ClusterRole +{{- if (not .Values.rbac.useExistingRole) }} + name: {{ template "grafana.fullname" . }}-clusterrole +{{- else }} + name: {{ .Values.rbac.useExistingRole }} +{{- end }} + apiGroup: rbac.authorization.k8s.io +{{- end -}} diff --git a/charts/oes/charts/grafana/templates/configmap-dashboard-provider.yaml b/charts/oes/charts/grafana/templates/configmap-dashboard-provider.yaml new file mode 100644 index 00000000..d3e577f5 --- /dev/null +++ b/charts/oes/charts/grafana/templates/configmap-dashboard-provider.yaml @@ -0,0 +1,30 @@ +{{- if .Values.sidecar.dashboards.enabled }} +apiVersion: v1 +kind: ConfigMap +metadata: + labels: + {{- include "grafana.labels" . | nindent 4 }} +{{- with .Values.annotations }} + annotations: +{{ toYaml . | indent 4 }} +{{- end }} + name: {{ template "grafana.fullname" . }}-config-dashboards + namespace: {{ template "grafana.namespace" . }} +data: + allow-snippet-annotations: "false" + provider.yaml: |- + apiVersion: 1 + providers: + - name: '{{ .Values.sidecar.dashboards.provider.name }}' + orgId: {{ .Values.sidecar.dashboards.provider.orgid }} + {{- if not .Values.sidecar.dashboards.provider.foldersFromFilesStructure }} + folder: '{{ .Values.sidecar.dashboards.provider.folder }}' + {{- end}} + type: {{ .Values.sidecar.dashboards.provider.type }} + disableDeletion: {{ .Values.sidecar.dashboards.provider.disableDelete }} + allowUiUpdates: {{ .Values.sidecar.dashboards.provider.allowUiUpdates }} + updateIntervalSeconds: {{ .Values.sidecar.dashboards.provider.updateIntervalSeconds | default 30 }} + options: + foldersFromFilesStructure: {{ .Values.sidecar.dashboards.provider.foldersFromFilesStructure }} + path: {{ .Values.sidecar.dashboards.folder }}{{- with .Values.sidecar.dashboards.defaultFolderName }}/{{ . }}{{- end }} +{{- end}} diff --git a/charts/oes/charts/grafana/templates/configmap.yaml b/charts/oes/charts/grafana/templates/configmap.yaml new file mode 100644 index 00000000..2c1757d0 --- /dev/null +++ b/charts/oes/charts/grafana/templates/configmap.yaml @@ -0,0 +1,102 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "grafana.fullname" . }} + namespace: {{ template "grafana.namespace" . }} + labels: + {{- include "grafana.labels" . | nindent 4 }} +{{- with .Values.annotations }} + annotations: +{{ toYaml . | indent 4 }} +{{- end }} +data: + allow-snippet-annotations: "false" +{{- if .Values.plugins }} + plugins: {{ join "," .Values.plugins }} +{{- end }} + grafana.ini: | +{{- range $elem, $elemVal := index .Values "grafana.ini" }} + {{- if not (kindIs "map" $elemVal) }} + {{- if kindIs "invalid" $elemVal }} + {{ $elem }} = + {{- else if kindIs "string" $elemVal }} + {{ $elem }} = {{ tpl $elemVal $ }} + {{- else }} + {{ $elem }} = {{ $elemVal }} + {{- end }} + {{- end }} +{{- end }} +{{- range $key, $value := index .Values "grafana.ini" }} + {{- if kindIs "map" $value }} + [{{ $key }}] + {{- range $elem, $elemVal := $value }} + {{- if kindIs "invalid" $elemVal }} + {{ $elem }} = + {{- else if kindIs "string" $elemVal }} + {{ $elem }} = {{ tpl $elemVal $ }} + {{- else }} + {{ $elem }} = {{ $elemVal }} + {{- end }} + {{- end }} + {{- end }} +{{- end }} + +{{- if .Values.datasources }} +{{ $root := . }} + {{- range $key, $value := .Values.datasources }} + {{ $key }}: | +{{ tpl (toYaml $value | indent 4) $root }} + {{- end -}} +{{- end -}} + +{{- if .Values.notifiers }} + {{- range $key, $value := .Values.notifiers }} + {{ $key }}: | +{{ toYaml $value | indent 4 }} + {{- end -}} +{{- end -}} + +{{- if .Values.dashboardProviders }} + {{- range $key, $value := .Values.dashboardProviders }} + {{ $key }}: | +{{ toYaml $value | indent 4 }} + {{- end -}} +{{- end -}} + +{{- if .Values.dashboards }} + download_dashboards.sh: | + #!/usr/bin/env sh + set -euf + {{- if .Values.dashboardProviders }} + {{- range $key, $value := .Values.dashboardProviders }} + {{- range $value.providers }} + mkdir -p {{ .options.path }} + {{- end }} + {{- end }} + {{- end }} + {{ $dashboardProviders := .Values.dashboardProviders }} + {{- range $provider, $dashboards := .Values.dashboards }} + {{- range $key, $value := $dashboards }} + {{- if (or (hasKey $value "gnetId") (hasKey $value "url")) }} + curl -skf \ + --connect-timeout 60 \ + --max-time 60 \ + {{- if not $value.b64content }} + -H "Accept: application/json" \ + {{- if $value.token }} + -H "Authorization: token {{ $value.token }}" \ + {{- end }} + -H "Content-Type: application/json;charset=UTF-8" \ + {{ end }} + {{- $dpPath := "" -}} + {{- range $kd := (index $dashboardProviders "dashboardproviders.yaml").providers -}} + {{- if eq $kd.name $provider -}} + {{- $dpPath = $kd.options.path -}} + {{- end -}} + {{- end -}} + {{- if $value.url -}}"{{ $value.url }}"{{- else -}}"https://grafana.com/api/dashboards/{{ $value.gnetId }}/revisions/{{- if $value.revision -}}{{ $value.revision }}{{- else -}}1{{- end -}}/download"{{- end -}}{{ if $value.datasource }} | sed '/-- .* --/! s/"datasource":.*,/"datasource": "{{ $value.datasource }}",/g'{{ end }}{{- if $value.b64content -}} | base64 -d {{- end -}} \ + > "{{- if $dpPath -}}{{ $dpPath }}{{- else -}}/var/lib/grafana/dashboards/{{ $provider }}{{- end -}}/{{ $key }}.json" + {{- end }} + {{- end -}} + {{- end }} +{{- end }} diff --git a/charts/oes/charts/grafana/templates/dashboards-json-configmap.yaml b/charts/oes/charts/grafana/templates/dashboards-json-configmap.yaml new file mode 100644 index 00000000..59e0be64 --- /dev/null +++ b/charts/oes/charts/grafana/templates/dashboards-json-configmap.yaml @@ -0,0 +1,35 @@ +{{- if .Values.dashboards }} +{{ $files := .Files }} +{{- range $provider, $dashboards := .Values.dashboards }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "grafana.fullname" $ }}-dashboards-{{ $provider }} + namespace: {{ template "grafana.namespace" $ }} + labels: + {{- include "grafana.labels" $ | nindent 4 }} + dashboard-provider: {{ $provider }} +{{- if $dashboards }} +data: +{{- $dashboardFound := false }} +{{- range $key, $value := $dashboards }} +{{- if (or (hasKey $value "json") (hasKey $value "file")) }} +{{- $dashboardFound = true }} +{{ print $key | indent 2 }}.json: +{{- if hasKey $value "json" }} + |- +{{ $value.json | indent 6 }} +{{- end }} +{{- if hasKey $value "file" }} +{{ toYaml ( $files.Get $value.file ) | indent 4}} +{{- end }} +{{- end }} +{{- end }} +{{- if not $dashboardFound }} + {} +{{- end }} +{{- end }} +--- +{{- end }} + +{{- end }} diff --git a/charts/oes/charts/grafana/templates/deployment.yaml b/charts/oes/charts/grafana/templates/deployment.yaml new file mode 100644 index 00000000..d0465b1e --- /dev/null +++ b/charts/oes/charts/grafana/templates/deployment.yaml @@ -0,0 +1,50 @@ +{{ if (and (not .Values.useStatefulSet) (or (not .Values.persistence.enabled) (eq .Values.persistence.type "pvc"))) }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ template "grafana.fullname" . }} + namespace: {{ template "grafana.namespace" . }} + labels: + {{- include "grafana.labels" . | nindent 4 }} +{{- if .Values.labels }} +{{ toYaml .Values.labels | indent 4 }} +{{- end }} +{{- with .Values.annotations }} + annotations: +{{ toYaml . | indent 4 }} +{{- end }} +spec: + {{- if and (not .Values.autoscaling.enabled) (.Values.replicas) }} + replicas: {{ .Values.replicas }} + {{- end }} + revisionHistoryLimit: {{ .Values.revisionHistoryLimit }} + selector: + matchLabels: + {{- include "grafana.selectorLabels" . | nindent 6 }} +{{- with .Values.deploymentStrategy }} + strategy: +{{ toYaml . | trim | indent 4 }} +{{- end }} + template: + metadata: + labels: + {{- include "grafana.selectorLabels" . | nindent 8 }} +{{- with .Values.podLabels }} +{{ toYaml . | indent 8 }} +{{- end }} + annotations: + checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }} + checksum/dashboards-json-config: {{ include (print $.Template.BasePath "/dashboards-json-configmap.yaml") . | sha256sum }} + checksum/sc-dashboard-provider-config: {{ include (print $.Template.BasePath "/configmap-dashboard-provider.yaml") . | sha256sum }} +{{- if and (or (and (not .Values.admin.existingSecret) (not .Values.env.GF_SECURITY_ADMIN_PASSWORD__FILE) (not .Values.env.GF_SECURITY_ADMIN_PASSWORD)) (and .Values.ldap.enabled (not .Values.ldap.existingSecret))) (not .Values.env.GF_SECURITY_DISABLE_INITIAL_ADMIN_CREATION) }} + checksum/secret: {{ include (print $.Template.BasePath "/secret.yaml") . | sha256sum }} +{{- end }} +{{- if .Values.envRenderSecret }} + checksum/secret-env: {{ include (print $.Template.BasePath "/secret-env.yaml") . | sha256sum }} +{{- end }} +{{- with .Values.podAnnotations }} +{{ toYaml . | indent 8 }} +{{- end }} + spec: + {{- include "grafana.pod" . | nindent 6 }} +{{- end }} diff --git a/charts/oes/charts/grafana/templates/extra-manifests.yaml b/charts/oes/charts/grafana/templates/extra-manifests.yaml new file mode 100644 index 00000000..a9bb3b6b --- /dev/null +++ b/charts/oes/charts/grafana/templates/extra-manifests.yaml @@ -0,0 +1,4 @@ +{{ range .Values.extraObjects }} +--- +{{ tpl (toYaml .) $ }} +{{ end }} diff --git a/charts/oes/charts/grafana/templates/headless-service.yaml b/charts/oes/charts/grafana/templates/headless-service.yaml new file mode 100644 index 00000000..1df42e96 --- /dev/null +++ b/charts/oes/charts/grafana/templates/headless-service.yaml @@ -0,0 +1,22 @@ +{{- if or .Values.headlessService (and .Values.persistence.enabled (not .Values.persistence.existingClaim) (eq .Values.persistence.type "statefulset"))}} +apiVersion: v1 +kind: Service +metadata: + name: {{ template "grafana.fullname" . }}-headless + namespace: {{ template "grafana.namespace" . }} + labels: + {{- include "grafana.labels" . | nindent 4 }} +{{- with .Values.annotations }} + annotations: +{{ toYaml . | indent 4 }} +{{- end }} +spec: + clusterIP: None + selector: + {{- include "grafana.selectorLabels" . | nindent 4 }} + type: ClusterIP + ports: + - protocol: TCP + port: 3000 + targetPort: 3000 +{{- end }} diff --git a/charts/oes/charts/grafana/templates/hpa.yaml b/charts/oes/charts/grafana/templates/hpa.yaml new file mode 100644 index 00000000..9c186d74 --- /dev/null +++ b/charts/oes/charts/grafana/templates/hpa.yaml @@ -0,0 +1,20 @@ +{{- if .Values.autoscaling.enabled }} +apiVersion: autoscaling/v2beta1 +kind: HorizontalPodAutoscaler +metadata: + name: {{ template "grafana.fullname" . }} + labels: + app.kubernetes.io/name: {{ template "grafana.name" . }} + helm.sh/chart: {{ template "grafana.chart" . }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/instance: {{ .Release.Name }} +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: {{ template "grafana.fullname" . }} + minReplicas: {{ .Values.autoscaling.minReplicas }} + maxReplicas: {{ .Values.autoscaling.maxReplicas }} + metrics: +{{ toYaml .Values.autoscaling.metrics | indent 4 }} +{{- end }} diff --git a/charts/oes/charts/grafana/templates/image-renderer-deployment.yaml b/charts/oes/charts/grafana/templates/image-renderer-deployment.yaml new file mode 100644 index 00000000..1a9d4c58 --- /dev/null +++ b/charts/oes/charts/grafana/templates/image-renderer-deployment.yaml @@ -0,0 +1,121 @@ +{{ if .Values.imageRenderer.enabled }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ template "grafana.fullname" . }}-image-renderer + namespace: {{ template "grafana.namespace" . }} + labels: + {{- include "grafana.imageRenderer.labels" . | nindent 4 }} +{{- if .Values.imageRenderer.labels }} +{{ toYaml .Values.imageRenderer.labels | indent 4 }} +{{- end }} +{{- with .Values.imageRenderer.annotations }} + annotations: +{{ toYaml . | indent 4 }} +{{- end }} +spec: + replicas: {{ .Values.imageRenderer.replicas }} + revisionHistoryLimit: {{ .Values.imageRenderer.revisionHistoryLimit }} + selector: + matchLabels: + {{- include "grafana.imageRenderer.selectorLabels" . | nindent 6 }} +{{- with .Values.imageRenderer.deploymentStrategy }} + strategy: +{{ toYaml . | trim | indent 4 }} +{{- end }} + template: + metadata: + labels: + {{- include "grafana.imageRenderer.selectorLabels" . | nindent 8 }} +{{- with .Values.imageRenderer.podLabels }} +{{ toYaml . | indent 8 }} +{{- end }} + annotations: + checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }} +{{- with .Values.imageRenderer.podAnnotations }} +{{ toYaml . | indent 8 }} +{{- end }} + spec: + + {{- if .Values.imageRenderer.schedulerName }} + schedulerName: "{{ .Values.imageRenderer.schedulerName }}" + {{- end }} + {{- if .Values.imageRenderer.serviceAccountName }} + serviceAccountName: "{{ .Values.imageRenderer.serviceAccountName }}" + {{- end }} + {{- if .Values.imageRenderer.securityContext }} + securityContext: + {{- toYaml .Values.imageRenderer.securityContext | nindent 8 }} + {{- end }} + {{- if .Values.imageRenderer.hostAliases }} + hostAliases: + {{- toYaml .Values.imageRenderer.hostAliases | nindent 8 }} + {{- end }} + {{- if .Values.imageRenderer.priorityClassName }} + priorityClassName: {{ .Values.imageRenderer.priorityClassName }} + {{- end }} + {{- if .Values.imageRenderer.image.pullSecrets }} + imagePullSecrets: + {{- $root := . }} + {{- range .Values.imageRenderer.image.pullSecrets }} + - name: {{ tpl . $root }} + {{- end}} + {{- end }} + containers: + - name: {{ .Chart.Name }}-image-renderer + {{- if .Values.imageRenderer.image.sha }} + image: "{{ .Values.imageRenderer.image.repository }}:{{ .Values.imageRenderer.image.tag }}@sha256:{{ .Values.imageRenderer.image.sha }}" + {{- else }} + image: "{{ .Values.imageRenderer.image.repository }}:{{ .Values.imageRenderer.image.tag }}" + {{- end }} + imagePullPolicy: {{ .Values.imageRenderer.image.pullPolicy }} + {{- if .Values.imageRenderer.command }} + command: + {{- range .Values.imageRenderer.command }} + - {{ . }} + {{- end }} + {{- end}} + ports: + - name: {{ .Values.imageRenderer.service.portName }} + containerPort: {{ .Values.imageRenderer.service.port }} + protocol: TCP + livenessProbe: + httpGet: + path: / + port: {{ .Values.imageRenderer.service.portName }} + env: + - name: HTTP_PORT + value: {{ .Values.imageRenderer.service.port | quote }} + {{- range $key, $value := .Values.imageRenderer.env }} + - name: {{ $key | quote }} + value: {{ $value | quote }} + {{- end }} + securityContext: + capabilities: + drop: ['all'] + allowPrivilegeEscalation: false + readOnlyRootFilesystem: true + volumeMounts: + - mountPath: /tmp + name: image-renderer-tmpfs + {{- with .Values.imageRenderer.resources }} + resources: +{{ toYaml . | indent 12 }} + {{- end }} + {{- with .Values.imageRenderer.nodeSelector }} + nodeSelector: +{{ toYaml . | indent 8 }} + {{- end }} + {{- $root := . }} + {{- with .Values.imageRenderer.affinity }} + affinity: +{{ tpl (toYaml .) $root | indent 8 }} + {{- end }} + {{- with .Values.imageRenderer.tolerations }} + tolerations: +{{ toYaml . | indent 8 }} + {{- end }} + volumes: + - name: image-renderer-tmpfs + emptyDir: {} +{{- end }} diff --git a/charts/oes/charts/grafana/templates/image-renderer-network-policy.yaml b/charts/oes/charts/grafana/templates/image-renderer-network-policy.yaml new file mode 100644 index 00000000..f8ca73aa --- /dev/null +++ b/charts/oes/charts/grafana/templates/image-renderer-network-policy.yaml @@ -0,0 +1,76 @@ +{{- if and (.Values.imageRenderer.enabled) (.Values.imageRenderer.networkPolicy.limitIngress) }} +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: {{ template "grafana.fullname" . }}-image-renderer-ingress + namespace: {{ template "grafana.namespace" . }} + annotations: + comment: Limit image-renderer ingress traffic from grafana +spec: + podSelector: + matchLabels: + {{- include "grafana.imageRenderer.selectorLabels" . | nindent 6 }} + {{- if .Values.imageRenderer.podLabels }} + {{ toYaml .Values.imageRenderer.podLabels | nindent 6 }} + {{- end }} + + policyTypes: + - Ingress + ingress: + - ports: + - port: {{ .Values.imageRenderer.service.port }} + protocol: TCP + from: + - namespaceSelector: + matchLabels: + name: {{ template "grafana.namespace" . }} + podSelector: + matchLabels: + {{- include "grafana.selectorLabels" . | nindent 14 }} + {{- if .Values.podLabels }} + {{ toYaml .Values.podLabels | nindent 14 }} + {{- end }} +{{ end }} + +{{- if and (.Values.imageRenderer.enabled) (.Values.imageRenderer.networkPolicy.limitEgress) }} +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: {{ template "grafana.fullname" . }}-image-renderer-egress + namespace: {{ template "grafana.namespace" . }} + annotations: + comment: Limit image-renderer egress traffic to grafana +spec: + podSelector: + matchLabels: + {{- include "grafana.imageRenderer.selectorLabels" . | nindent 6 }} + {{- if .Values.imageRenderer.podLabels }} + {{ toYaml .Values.imageRenderer.podLabels | nindent 6 }} + {{- end }} + + policyTypes: + - Egress + egress: + # allow dns resolution + - ports: + - port: 53 + protocol: UDP + - port: 53 + protocol: TCP + # talk only to grafana + - ports: + - port: {{ .Values.service.port }} + protocol: TCP + to: + - namespaceSelector: + matchLabels: + name: {{ template "grafana.namespace" . }} + podSelector: + matchLabels: + {{- include "grafana.selectorLabels" . | nindent 14 }} + {{- if .Values.podLabels }} + {{ toYaml .Values.podLabels | nindent 14 }} + {{- end }} +{{ end }} diff --git a/charts/oes/charts/grafana/templates/image-renderer-service.yaml b/charts/oes/charts/grafana/templates/image-renderer-service.yaml new file mode 100644 index 00000000..f29586c3 --- /dev/null +++ b/charts/oes/charts/grafana/templates/image-renderer-service.yaml @@ -0,0 +1,30 @@ +{{ if .Values.imageRenderer.enabled }} +{{ if .Values.imageRenderer.service.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ template "grafana.fullname" . }}-image-renderer + namespace: {{ template "grafana.namespace" . }} + labels: + {{- include "grafana.imageRenderer.labels" . | nindent 4 }} +{{- if .Values.imageRenderer.service.labels }} +{{ toYaml .Values.imageRenderer.service.labels | indent 4 }} +{{- end }} +{{- with .Values.imageRenderer.service.annotations }} + annotations: +{{ toYaml . | indent 4 }} +{{- end }} +spec: + type: ClusterIP + {{- if .Values.imageRenderer.service.clusterIP }} + clusterIP: {{ .Values.imageRenderer.service.clusterIP }} + {{end}} + ports: + - name: {{ .Values.imageRenderer.service.portName }} + port: {{ .Values.imageRenderer.service.port }} + protocol: TCP + targetPort: {{ .Values.imageRenderer.service.targetPort }} + selector: + {{- include "grafana.imageRenderer.selectorLabels" . | nindent 4 }} +{{ end }} +{{ end }} diff --git a/charts/oes/charts/grafana/templates/ingress.yaml b/charts/oes/charts/grafana/templates/ingress.yaml new file mode 100644 index 00000000..7699ceca --- /dev/null +++ b/charts/oes/charts/grafana/templates/ingress.yaml @@ -0,0 +1,78 @@ +{{- if .Values.ingress.enabled -}} +{{- $ingressApiIsStable := eq (include "grafana.ingress.isStable" .) "true" -}} +{{- $ingressSupportsIngressClassName := eq (include "grafana.ingress.supportsIngressClassName" .) "true" -}} +{{- $ingressSupportsPathType := eq (include "grafana.ingress.supportsPathType" .) "true" -}} +{{- $fullName := include "grafana.fullname" . -}} +{{- $servicePort := .Values.service.port -}} +{{- $ingressPath := .Values.ingress.path -}} +{{- $ingressPathType := .Values.ingress.pathType -}} +{{- $extraPaths := .Values.ingress.extraPaths -}} +apiVersion: {{ include "grafana.ingress.apiVersion" . }} +kind: Ingress +metadata: + name: {{ $fullName }} + namespace: {{ template "grafana.namespace" . }} + labels: + {{- include "grafana.labels" . | nindent 4 }} +{{- if .Values.ingress.labels }} +{{ toYaml .Values.ingress.labels | indent 4 }} +{{- end }} + {{- if .Values.ingress.annotations }} + annotations: + {{- range $key, $value := .Values.ingress.annotations }} + {{ $key }}: {{ tpl $value $ | quote }} + {{- end }} + {{- end }} +spec: + {{- if and $ingressSupportsIngressClassName .Values.ingress.ingressClassName }} + ingressClassName: {{ .Values.ingress.ingressClassName }} + {{- end -}} +{{- if .Values.ingress.tls }} + tls: +{{ tpl (toYaml .Values.ingress.tls) $ | indent 4 }} +{{- end }} + rules: + {{- if .Values.ingress.hosts }} + {{- range .Values.ingress.hosts }} + - host: {{ tpl . $}} + http: + paths: +{{- if $extraPaths }} +{{ toYaml $extraPaths | indent 10 }} +{{- end }} + - path: {{ $ingressPath }} + {{- if $ingressSupportsPathType }} + pathType: {{ $ingressPathType }} + {{- end }} + backend: + {{- if $ingressApiIsStable }} + service: + name: {{ $fullName }} + port: + number: {{ $servicePort }} + {{- else }} + serviceName: {{ $fullName }} + servicePort: {{ $servicePort }} + {{- end }} + {{- end }} + {{- else }} + - http: + paths: + - backend: + {{- if $ingressApiIsStable }} + service: + name: {{ $fullName }} + port: + number: {{ $servicePort }} + {{- else }} + serviceName: {{ $fullName }} + servicePort: {{ $servicePort }} + {{- end }} + {{- if $ingressPath }} + path: {{ $ingressPath }} + {{- end }} + {{- if $ingressSupportsPathType }} + pathType: {{ $ingressPathType }} + {{- end }} + {{- end -}} +{{- end }} diff --git a/charts/oes/charts/grafana/templates/networkpolicy.yaml b/charts/oes/charts/grafana/templates/networkpolicy.yaml new file mode 100644 index 00000000..d277a9d3 --- /dev/null +++ b/charts/oes/charts/grafana/templates/networkpolicy.yaml @@ -0,0 +1,52 @@ +{{- if .Values.networkPolicy.enabled }} +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: {{ template "grafana.fullname" . }} + namespace: {{ template "grafana.namespace" . }} + labels: + {{- include "grafana.labels" . | nindent 4 }} +{{- if .Values.labels }} +{{ toYaml .Values.labels | indent 4 }} +{{- end }} +{{- with .Values.annotations }} + annotations: +{{ toYaml . | indent 4 }} +{{- end }} +spec: + policyTypes: + {{- if .Values.networkPolicy.ingress }} + - Ingress + {{- end }} + {{- if .Values.networkPolicy.egress.enabled }} + - Egress + {{- end }} + podSelector: + matchLabels: + {{- include "grafana.selectorLabels" . | nindent 6 }} + + {{- if .Values.networkPolicy.egress.enabled }} + egress: + - ports: + {{ .Values.networkPolicy.egress.ports | toJson }} + {{- end }} + {{- if .Values.networkPolicy.ingress }} + ingress: + - ports: + - port: {{ .Values.service.targetPort }} + {{- if not .Values.networkPolicy.allowExternal }} + from: + - podSelector: + matchLabels: + {{ template "grafana.fullname" . }}-client: "true" + {{- if .Values.networkPolicy.explicitNamespacesSelector }} + namespaceSelector: + {{ toYaml .Values.networkPolicy.explicitNamespacesSelector | indent 12 }} + {{- end }} + - podSelector: + matchLabels: + {{- include "grafana.labels" . | nindent 14 }} + role: read + {{- end }} + {{- end }} +{{- end }} diff --git a/charts/oes/charts/grafana/templates/poddisruptionbudget.yaml b/charts/oes/charts/grafana/templates/poddisruptionbudget.yaml new file mode 100644 index 00000000..70901b70 --- /dev/null +++ b/charts/oes/charts/grafana/templates/poddisruptionbudget.yaml @@ -0,0 +1,22 @@ +{{- if .Values.podDisruptionBudget }} +apiVersion: {{ include "grafana.podDisruptionBudget.apiVersion" . }} +kind: PodDisruptionBudget +metadata: + name: {{ template "grafana.fullname" . }} + namespace: {{ template "grafana.namespace" . }} + labels: + {{- include "grafana.labels" . | nindent 4 }} +{{- if .Values.labels }} +{{ toYaml .Values.labels | indent 4 }} +{{- end }} +spec: +{{- if .Values.podDisruptionBudget.minAvailable }} + minAvailable: {{ .Values.podDisruptionBudget.minAvailable }} +{{- end }} +{{- if .Values.podDisruptionBudget.maxUnavailable }} + maxUnavailable: {{ .Values.podDisruptionBudget.maxUnavailable }} +{{- end }} + selector: + matchLabels: + {{- include "grafana.selectorLabels" . | nindent 6 }} +{{- end }} diff --git a/charts/oes/charts/grafana/templates/podsecuritypolicy.yaml b/charts/oes/charts/grafana/templates/podsecuritypolicy.yaml new file mode 100644 index 00000000..881df6f6 --- /dev/null +++ b/charts/oes/charts/grafana/templates/podsecuritypolicy.yaml @@ -0,0 +1,49 @@ +{{- if .Values.rbac.pspEnabled }} +apiVersion: {{ include "grafana.podSecurityPolicy.apiVersion" . }} +kind: PodSecurityPolicy +metadata: + name: {{ template "grafana.fullname" . }} + labels: + {{- include "grafana.labels" . | nindent 4 }} + annotations: + seccomp.security.alpha.kubernetes.io/allowedProfileNames: 'docker/default,runtime/default' + seccomp.security.alpha.kubernetes.io/defaultProfileName: 'docker/default' + {{- if .Values.rbac.pspUseAppArmor }} + apparmor.security.beta.kubernetes.io/allowedProfileNames: 'runtime/default' + apparmor.security.beta.kubernetes.io/defaultProfileName: 'runtime/default' + {{- end }} +spec: + privileged: false + allowPrivilegeEscalation: false + requiredDropCapabilities: + # Default set from Docker, with DAC_OVERRIDE and CHOWN + - ALL + volumes: + - 'configMap' + - 'emptyDir' + - 'projected' + - 'csi' + - 'secret' + - 'downwardAPI' + - 'persistentVolumeClaim' + hostNetwork: false + hostIPC: false + hostPID: false + runAsUser: + rule: 'RunAsAny' + seLinux: + rule: 'RunAsAny' + supplementalGroups: + rule: 'MustRunAs' + ranges: + # Forbid adding the root group. + - min: 1 + max: 65535 + fsGroup: + rule: 'MustRunAs' + ranges: + # Forbid adding the root group. + - min: 1 + max: 65535 + readOnlyRootFilesystem: false +{{- end }} diff --git a/charts/oes/charts/grafana/templates/pvc.yaml b/charts/oes/charts/grafana/templates/pvc.yaml new file mode 100644 index 00000000..8d93f5c2 --- /dev/null +++ b/charts/oes/charts/grafana/templates/pvc.yaml @@ -0,0 +1,33 @@ +{{- if and .Values.persistence.enabled (not .Values.persistence.existingClaim) (eq .Values.persistence.type "pvc")}} +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: {{ template "grafana.fullname" . }} + namespace: {{ template "grafana.namespace" . }} + labels: + {{- include "grafana.labels" . | nindent 4 }} + {{- with .Values.persistence.annotations }} + annotations: +{{ toYaml . | indent 4 }} + {{- end }} + {{- with .Values.persistence.finalizers }} + finalizers: +{{ toYaml . | indent 4 }} + {{- end }} +spec: + accessModes: + {{- range .Values.persistence.accessModes }} + - {{ . | quote }} + {{- end }} + resources: + requests: + storage: {{ .Values.persistence.size | quote }} + {{- if .Values.persistence.storageClassName }} + storageClassName: {{ .Values.persistence.storageClassName }} + {{- end -}} + {{- with .Values.persistence.selectorLabels }} + selector: + matchLabels: +{{ toYaml . | indent 6 }} + {{- end }} +{{- end -}} diff --git a/charts/oes/charts/grafana/templates/role.yaml b/charts/oes/charts/grafana/templates/role.yaml new file mode 100644 index 00000000..ff2160f4 --- /dev/null +++ b/charts/oes/charts/grafana/templates/role.yaml @@ -0,0 +1,32 @@ +{{- if and .Values.rbac.create (not .Values.rbac.useExistingRole) -}} +apiVersion: {{ template "grafana.rbac.apiVersion" . }} +kind: Role +metadata: + name: {{ template "grafana.fullname" . }} + namespace: {{ template "grafana.namespace" . }} + labels: + {{- include "grafana.labels" . | nindent 4 }} +{{- with .Values.annotations }} + annotations: +{{ toYaml . | indent 4 }} +{{- end }} +{{- if or .Values.rbac.pspEnabled (and .Values.rbac.namespaced (or .Values.sidecar.dashboards.enabled (or .Values.sidecar.datasources.enabled (or .Values.sidecar.plugins.enabled .Values.rbac.extraRoleRules)))) }} +rules: +{{- if .Values.rbac.pspEnabled }} +- apiGroups: ['extensions'] + resources: ['podsecuritypolicies'] + verbs: ['use'] + resourceNames: [{{ template "grafana.fullname" . }}] +{{- end }} +{{- if and .Values.rbac.namespaced (or .Values.sidecar.dashboards.enabled (or .Values.sidecar.datasources.enabled .Values.sidecar.plugins.enabled)) }} +- apiGroups: [""] # "" indicates the core API group + resources: ["configmaps", "secrets"] + verbs: ["get", "watch", "list"] +{{- end }} +{{- with .Values.rbac.extraRoleRules }} +{{ toYaml . | indent 0 }} +{{- end}} +{{- else }} +rules: [] +{{- end }} +{{- end }} diff --git a/charts/oes/charts/grafana/templates/rolebinding.yaml b/charts/oes/charts/grafana/templates/rolebinding.yaml new file mode 100644 index 00000000..e0107255 --- /dev/null +++ b/charts/oes/charts/grafana/templates/rolebinding.yaml @@ -0,0 +1,25 @@ +{{- if .Values.rbac.create -}} +apiVersion: {{ template "grafana.rbac.apiVersion" . }} +kind: RoleBinding +metadata: + name: {{ template "grafana.fullname" . }} + namespace: {{ template "grafana.namespace" . }} + labels: + {{- include "grafana.labels" . | nindent 4 }} +{{- with .Values.annotations }} + annotations: +{{ toYaml . | indent 4 }} +{{- end }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role +{{- if (not .Values.rbac.useExistingRole) }} + name: {{ template "grafana.fullname" . }} +{{- else }} + name: {{ .Values.rbac.useExistingRole }} +{{- end }} +subjects: +- kind: ServiceAccount + name: {{ template "grafana.serviceAccountName" . }} + namespace: {{ template "grafana.namespace" . }} +{{- end -}} diff --git a/charts/oes/charts/grafana/templates/secret-env.yaml b/charts/oes/charts/grafana/templates/secret-env.yaml new file mode 100644 index 00000000..5c09313e --- /dev/null +++ b/charts/oes/charts/grafana/templates/secret-env.yaml @@ -0,0 +1,14 @@ +{{- if .Values.envRenderSecret }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ template "grafana.fullname" . }}-env + namespace: {{ template "grafana.namespace" . }} + labels: + {{- include "grafana.labels" . | nindent 4 }} +type: Opaque +data: +{{- range $key, $val := .Values.envRenderSecret }} + {{ $key }}: {{ $val | b64enc | quote }} +{{- end -}} +{{- end }} diff --git a/charts/oes/charts/grafana/templates/secret.yaml b/charts/oes/charts/grafana/templates/secret.yaml new file mode 100644 index 00000000..c8aa750a --- /dev/null +++ b/charts/oes/charts/grafana/templates/secret.yaml @@ -0,0 +1,26 @@ +{{- if or (and (not .Values.admin.existingSecret) (not .Values.env.GF_SECURITY_ADMIN_PASSWORD__FILE) (not .Values.env.GF_SECURITY_ADMIN_PASSWORD) (not .Values.env.GF_SECURITY_DISABLE_INITIAL_ADMIN_CREATION)) (and .Values.ldap.enabled (not .Values.ldap.existingSecret)) }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ template "grafana.fullname" . }} + namespace: {{ template "grafana.namespace" . }} + labels: + {{- include "grafana.labels" . | nindent 4 }} +{{- with .Values.annotations }} + annotations: +{{ toYaml . | indent 4 }} +{{- end }} +type: Opaque +data: + {{- if and (not .Values.env.GF_SECURITY_DISABLE_INITIAL_ADMIN_CREATION) (not .Values.admin.existingSecret) (not .Values.env.GF_SECURITY_ADMIN_PASSWORD__FILE) (not .Values.env.GF_SECURITY_ADMIN_PASSWORD) }} + admin-user: {{ .Values.adminUser | b64enc | quote }} + {{- if .Values.adminPassword }} + admin-password: {{ .Values.adminPassword | b64enc | quote }} + {{- else }} + admin-password: {{ template "grafana.password" . }} + {{- end }} + {{- end }} + {{- if not .Values.ldap.existingSecret }} + ldap-toml: {{ tpl .Values.ldap.config $ | b64enc | quote }} + {{- end }} +{{- end }} diff --git a/charts/oes/charts/grafana/templates/service.yaml b/charts/oes/charts/grafana/templates/service.yaml new file mode 100644 index 00000000..ba84ef97 --- /dev/null +++ b/charts/oes/charts/grafana/templates/service.yaml @@ -0,0 +1,51 @@ +{{ if .Values.service.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ template "grafana.fullname" . }} + namespace: {{ template "grafana.namespace" . }} + labels: + {{- include "grafana.labels" . | nindent 4 }} +{{- if .Values.service.labels }} +{{ toYaml .Values.service.labels | indent 4 }} +{{- end }} +{{- with .Values.service.annotations }} + annotations: +{{ toYaml . | indent 4 }} +{{- end }} +spec: +{{- if (or (eq .Values.service.type "ClusterIP") (empty .Values.service.type)) }} + type: ClusterIP + {{- if .Values.service.clusterIP }} + clusterIP: {{ .Values.service.clusterIP }} + {{end}} +{{- else if eq .Values.service.type "LoadBalancer" }} + type: {{ .Values.service.type }} + {{- if .Values.service.loadBalancerIP }} + loadBalancerIP: {{ .Values.service.loadBalancerIP }} + {{- end }} + {{- if .Values.service.loadBalancerSourceRanges }} + loadBalancerSourceRanges: +{{ toYaml .Values.service.loadBalancerSourceRanges | indent 4 }} + {{- end -}} +{{- else }} + type: {{ .Values.service.type }} +{{- end }} +{{- if .Values.service.externalIPs }} + externalIPs: +{{ toYaml .Values.service.externalIPs | indent 4 }} +{{- end }} + ports: + - name: {{ .Values.service.portName }} + port: {{ .Values.service.port }} + protocol: TCP + targetPort: {{ .Values.service.targetPort }} +{{ if (and (eq .Values.service.type "NodePort") (not (empty .Values.service.nodePort))) }} + nodePort: {{.Values.service.nodePort}} +{{ end }} + {{- if .Values.extraExposePorts }} + {{- tpl (toYaml .Values.extraExposePorts) . | indent 4 }} + {{- end }} + selector: + {{- include "grafana.selectorLabels" . | nindent 4 }} +{{ end }} diff --git a/charts/oes/charts/grafana/templates/serviceaccount.yaml b/charts/oes/charts/grafana/templates/serviceaccount.yaml new file mode 100644 index 00000000..4ccee15e --- /dev/null +++ b/charts/oes/charts/grafana/templates/serviceaccount.yaml @@ -0,0 +1,14 @@ +{{- if .Values.serviceAccount.create }} +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + {{- include "grafana.labels" . | nindent 4 }} +{{- $root := . }} +{{- with .Values.serviceAccount.annotations }} + annotations: +{{ tpl (toYaml . | indent 4) $root }} +{{- end }} + name: {{ template "grafana.serviceAccountName" . }} + namespace: {{ template "grafana.namespace" . }} +{{- end }} diff --git a/charts/oes/charts/grafana/templates/servicemonitor.yaml b/charts/oes/charts/grafana/templates/servicemonitor.yaml new file mode 100644 index 00000000..56bc68ed --- /dev/null +++ b/charts/oes/charts/grafana/templates/servicemonitor.yaml @@ -0,0 +1,44 @@ +{{- if .Values.serviceMonitor.enabled }} +--- +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ template "grafana.fullname" . }} + {{- if .Values.serviceMonitor.namespace }} + namespace: {{ .Values.serviceMonitor.namespace }} + {{- else }} + namespace: {{ template "grafana.namespace" . }} + {{- end }} + labels: + {{- include "grafana.labels" . | nindent 4 }} + {{- if .Values.serviceMonitor.labels }} + {{- toYaml .Values.serviceMonitor.labels | nindent 4 }} + {{- end }} +spec: + endpoints: + - port: {{ .Values.service.portName }} + {{- with .Values.serviceMonitor.interval }} + interval: {{ . }} + {{- end }} + {{- with .Values.serviceMonitor.scrapeTimeout }} + scrapeTimeout: {{ . }} + {{- end }} + honorLabels: true + path: {{ .Values.serviceMonitor.path }} + scheme: {{ .Values.serviceMonitor.scheme }} + {{- if .Values.serviceMonitor.tlsConfig }} + tlsConfig: + {{- toYaml .Values.serviceMonitor.tlsConfig | nindent 6 }} + {{- end }} + {{- if .Values.serviceMonitor.relabelings }} + relabelings: + {{- toYaml .Values.serviceMonitor.relabelings | nindent 4 }} + {{- end }} + jobLabel: "{{ .Release.Name }}" + selector: + matchLabels: + {{- include "grafana.selectorLabels" . | nindent 8 }} + namespaceSelector: + matchNames: + - {{ template "grafana.namespace" . }} +{{- end }} diff --git a/charts/oes/charts/grafana/templates/statefulset.yaml b/charts/oes/charts/grafana/templates/statefulset.yaml new file mode 100644 index 00000000..b308dec4 --- /dev/null +++ b/charts/oes/charts/grafana/templates/statefulset.yaml @@ -0,0 +1,54 @@ +{{- if (or (.Values.useStatefulSet) (and .Values.persistence.enabled (not .Values.persistence.existingClaim) (eq .Values.persistence.type "statefulset")))}} +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: {{ template "grafana.fullname" . }} + namespace: {{ template "grafana.namespace" . }} + labels: + {{- include "grafana.labels" . | nindent 4 }} +{{- with .Values.annotations }} + annotations: +{{ toYaml . | indent 4 }} +{{- end }} +spec: + replicas: {{ .Values.replicas }} + selector: + matchLabels: + {{- include "grafana.selectorLabels" . | nindent 6 }} + serviceName: {{ template "grafana.fullname" . }}-headless + template: + metadata: + labels: + {{- include "grafana.selectorLabels" . | nindent 8 }} +{{- with .Values.podLabels }} +{{ toYaml . | indent 8 }} +{{- end }} + annotations: + checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }} + checksum/dashboards-json-config: {{ include (print $.Template.BasePath "/dashboards-json-configmap.yaml") . | sha256sum }} + checksum/sc-dashboard-provider-config: {{ include (print $.Template.BasePath "/configmap-dashboard-provider.yaml") . | sha256sum }} + {{- if and (or (and (not .Values.admin.existingSecret) (not .Values.env.GF_SECURITY_ADMIN_PASSWORD__FILE) (not .Values.env.GF_SECURITY_ADMIN_PASSWORD)) (and .Values.ldap.enabled (not .Values.ldap.existingSecret))) (not .Values.env.GF_SECURITY_DISABLE_INITIAL_ADMIN_CREATION) }} + checksum/secret: {{ include (print $.Template.BasePath "/secret.yaml") . | sha256sum }} +{{- end }} +{{- with .Values.podAnnotations }} +{{ toYaml . | indent 8 }} +{{- end }} + spec: + {{- include "grafana.pod" . | nindent 6 }} + {{- if .Values.persistence.enabled}} + volumeClaimTemplates: + - metadata: + name: storage + spec: + accessModes: {{ .Values.persistence.accessModes }} + storageClassName: {{ .Values.persistence.storageClassName }} + resources: + requests: + storage: {{ .Values.persistence.size }} + {{- with .Values.persistence.selectorLabels }} + selector: + matchLabels: +{{ toYaml . | indent 10 }} + {{- end }} + {{- end }} +{{- end }} diff --git a/charts/oes/charts/grafana/templates/tests/test-configmap.yaml b/charts/oes/charts/grafana/templates/tests/test-configmap.yaml new file mode 100644 index 00000000..ff53aaf1 --- /dev/null +++ b/charts/oes/charts/grafana/templates/tests/test-configmap.yaml @@ -0,0 +1,17 @@ +{{- if .Values.testFramework.enabled }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "grafana.fullname" . }}-test + namespace: {{ template "grafana.namespace" . }} + labels: + {{- include "grafana.labels" . | nindent 4 }} +data: + run.sh: |- + @test "Test Health" { + url="http://{{ template "grafana.fullname" . }}/api/health" + + code=$(wget --server-response --spider --timeout 10 --tries 1 ${url} 2>&1 | awk '/^ HTTP/{print $2}') + [ "$code" == "200" ] + } +{{- end }} diff --git a/charts/oes/charts/grafana/templates/tests/test-podsecuritypolicy.yaml b/charts/oes/charts/grafana/templates/tests/test-podsecuritypolicy.yaml new file mode 100644 index 00000000..58b46498 --- /dev/null +++ b/charts/oes/charts/grafana/templates/tests/test-podsecuritypolicy.yaml @@ -0,0 +1,29 @@ +{{- if and .Values.testFramework.enabled .Values.rbac.pspEnabled }} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ template "grafana.fullname" . }}-test + labels: + {{- include "grafana.labels" . | nindent 4 }} +spec: + allowPrivilegeEscalation: true + privileged: false + hostNetwork: false + hostIPC: false + hostPID: false + fsGroup: + rule: RunAsAny + seLinux: + rule: RunAsAny + supplementalGroups: + rule: RunAsAny + runAsUser: + rule: RunAsAny + volumes: + - configMap + - downwardAPI + - emptyDir + - projected + - csi + - secret +{{- end }} diff --git a/charts/oes/charts/grafana/templates/tests/test-role.yaml b/charts/oes/charts/grafana/templates/tests/test-role.yaml new file mode 100644 index 00000000..6b10677a --- /dev/null +++ b/charts/oes/charts/grafana/templates/tests/test-role.yaml @@ -0,0 +1,14 @@ +{{- if and .Values.testFramework.enabled .Values.rbac.pspEnabled -}} +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: {{ template "grafana.fullname" . }}-test + namespace: {{ template "grafana.namespace" . }} + labels: + {{- include "grafana.labels" . | nindent 4 }} +rules: +- apiGroups: ['policy'] + resources: ['podsecuritypolicies'] + verbs: ['use'] + resourceNames: [{{ template "grafana.fullname" . }}-test] +{{- end }} diff --git a/charts/oes/charts/grafana/templates/tests/test-rolebinding.yaml b/charts/oes/charts/grafana/templates/tests/test-rolebinding.yaml new file mode 100644 index 00000000..58fa5e78 --- /dev/null +++ b/charts/oes/charts/grafana/templates/tests/test-rolebinding.yaml @@ -0,0 +1,17 @@ +{{- if and .Values.testFramework.enabled .Values.rbac.pspEnabled -}} +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: {{ template "grafana.fullname" . }}-test + namespace: {{ template "grafana.namespace" . }} + labels: + {{- include "grafana.labels" . | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: {{ template "grafana.fullname" . }}-test +subjects: +- kind: ServiceAccount + name: {{ template "grafana.serviceAccountNameTest" . }} + namespace: {{ template "grafana.namespace" . }} +{{- end }} diff --git a/charts/oes/charts/grafana/templates/tests/test-serviceaccount.yaml b/charts/oes/charts/grafana/templates/tests/test-serviceaccount.yaml new file mode 100644 index 00000000..5c335073 --- /dev/null +++ b/charts/oes/charts/grafana/templates/tests/test-serviceaccount.yaml @@ -0,0 +1,9 @@ +{{- if and .Values.testFramework.enabled .Values.serviceAccount.create }} +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + {{- include "grafana.labels" . | nindent 4 }} + name: {{ template "grafana.serviceAccountNameTest" . }} + namespace: {{ template "grafana.namespace" . }} +{{- end }} diff --git a/charts/oes/charts/grafana/templates/tests/test.yaml b/charts/oes/charts/grafana/templates/tests/test.yaml new file mode 100644 index 00000000..ef43d80d --- /dev/null +++ b/charts/oes/charts/grafana/templates/tests/test.yaml @@ -0,0 +1,51 @@ +{{- if .Values.testFramework.enabled }} +apiVersion: v1 +kind: Pod +metadata: + name: {{ template "grafana.fullname" . }}-test + labels: + {{- include "grafana.labels" . | nindent 4 }} + annotations: + "helm.sh/hook": test-success + "helm.sh/hook-delete-policy": "before-hook-creation,hook-succeeded" + namespace: {{ template "grafana.namespace" . }} +spec: + serviceAccountName: {{ template "grafana.serviceAccountNameTest" . }} + {{- if .Values.testFramework.securityContext }} + securityContext: {{ toYaml .Values.testFramework.securityContext | nindent 4 }} + {{- end }} + {{- $root := . }} + {{- if .Values.image.pullSecrets }} + imagePullSecrets: + {{- range .Values.image.pullSecrets }} + - name: {{ tpl . $root }} + {{- end}} + {{- end }} + {{- with .Values.nodeSelector }} + nodeSelector: +{{ toYaml . | indent 4 }} + {{- end }} + {{- $root := . }} + {{- with .Values.affinity }} + affinity: +{{ tpl (toYaml .) $root | indent 4 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: +{{ toYaml . | indent 4 }} + {{- end }} + containers: + - name: {{ .Release.Name }}-test + image: "{{ .Values.testFramework.image}}:{{ .Values.testFramework.tag }}" + imagePullPolicy: "{{ .Values.testFramework.imagePullPolicy}}" + command: ["/opt/bats/bin/bats", "-t", "/tests/run.sh"] + volumeMounts: + - mountPath: /tests + name: tests + readOnly: true + volumes: + - name: tests + configMap: + name: {{ template "grafana.fullname" . }}-test + restartPolicy: Never +{{- end }} diff --git a/charts/oes/charts/grafana/values.yaml b/charts/oes/charts/grafana/values.yaml new file mode 100644 index 00000000..12b80e83 --- /dev/null +++ b/charts/oes/charts/grafana/values.yaml @@ -0,0 +1,924 @@ +rbac: + create: true + ## Use an existing ClusterRole/Role (depending on rbac.namespaced false/true) + # useExistingRole: name-of-some-(cluster)role + pspEnabled: true + pspUseAppArmor: true + namespaced: false + extraRoleRules: [] + # - apiGroups: [] + # resources: [] + # verbs: [] + extraClusterRoleRules: [] + # - apiGroups: [] + # resources: [] + # verbs: [] +serviceAccount: + create: true + name: + nameTest: +## Service account annotations. Can be templated. +# annotations: +# eks.amazonaws.com/role-arn: arn:aws:iam::123456789000:role/iam-role-name-here + autoMount: true + +replicas: 1 + +## Create a headless service for the deployment +headlessService: false + +## Create HorizontalPodAutoscaler object for deployment type +# +autoscaling: + enabled: false +# minReplicas: 1 +# maxReplicas: 10 +# metrics: +# - type: Resource +# resource: +# name: cpu +# targetAverageUtilization: 60 +# - type: Resource +# resource: +# name: memory +# targetAverageUtilization: 60 + +## See `kubectl explain poddisruptionbudget.spec` for more +## ref: https://kubernetes.io/docs/tasks/run-application/configure-pdb/ +podDisruptionBudget: {} +# minAvailable: 1 +# maxUnavailable: 1 + +## See `kubectl explain deployment.spec.strategy` for more +## ref: https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#strategy +deploymentStrategy: + type: RollingUpdate + +readinessProbe: + httpGet: + path: /api/health + port: 3000 + +livenessProbe: + httpGet: + path: /api/health + port: 3000 + initialDelaySeconds: 60 + timeoutSeconds: 30 + failureThreshold: 10 + +## Use an alternate scheduler, e.g. "stork". +## ref: https://kubernetes.io/docs/tasks/administer-cluster/configure-multiple-schedulers/ +## +# schedulerName: "default-scheduler" + +image: + repository: grafana/grafana + # Overrides the Grafana image tag whose default is the chart appVersion + tag: "" + sha: "" + pullPolicy: IfNotPresent + + ## Optionally specify an array of imagePullSecrets. + ## Secrets must be manually created in the namespace. + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/ + ## Can be templated. + ## + # pullSecrets: + # - myRegistrKeySecretName + +testFramework: + enabled: true + image: "bats/bats" + tag: "v1.4.1" + imagePullPolicy: IfNotPresent + securityContext: {} + +securityContext: + runAsUser: 472 + runAsGroup: 472 + fsGroup: 472 + +containerSecurityContext: + {} + +# Extra configmaps to mount in grafana pods +# Values are templated. +extraConfigmapMounts: [] + # - name: certs-configmap + # mountPath: /etc/grafana/ssl/ + # subPath: certificates.crt # (optional) + # configMap: certs-configmap + # readOnly: true + + +extraEmptyDirMounts: [] + # - name: provisioning-notifiers + # mountPath: /etc/grafana/provisioning/notifiers + + +# Apply extra labels to common labels. +extraLabels: {} + +## Assign a PriorityClassName to pods if set +# priorityClassName: + +downloadDashboardsImage: + repository: curlimages/curl + tag: 7.73.0 + sha: "" + pullPolicy: IfNotPresent + +downloadDashboards: + env: {} + envFromSecret: "" + resources: {} + +## Pod Annotations +# podAnnotations: {} + +## Pod Labels +# podLabels: {} + +podPortName: grafana + +## Deployment annotations +# annotations: {} + +## Expose the grafana service to be accessed from outside the cluster (LoadBalancer service). +## or access it from within the cluster (ClusterIP service). Set the service type and the port to serve it. +## ref: http://kubernetes.io/docs/user-guide/services/ +## +service: + enabled: true + type: ClusterIP + port: 80 + targetPort: 3000 + # targetPort: 4181 To be used with a proxy extraContainer + annotations: {} + labels: {} + portName: service + +serviceMonitor: + ## If true, a ServiceMonitor CRD is created for a prometheus operator + ## https://github.com/coreos/prometheus-operator + ## + enabled: false + path: /metrics + # namespace: monitoring (defaults to use the namespace this chart is deployed to) + labels: {} + interval: 1m + scheme: http + tlsConfig: {} + scrapeTimeout: 30s + relabelings: [] + +extraExposePorts: [] + # - name: keycloak + # port: 8080 + # targetPort: 8080 + # type: ClusterIP + +# overrides pod.spec.hostAliases in the grafana deployment's pods +hostAliases: [] + # - ip: "1.2.3.4" + # hostnames: + # - "my.host.com" + +ingress: + enabled: false + # For Kubernetes >= 1.18 you should specify the ingress-controller via the field ingressClassName + # See https://kubernetes.io/blog/2020/04/02/improvements-to-the-ingress-api-in-kubernetes-1.18/#specifying-the-class-of-an-ingress + # ingressClassName: nginx + # Values can be templated + annotations: {} + # kubernetes.io/ingress.class: nginx + # kubernetes.io/tls-acme: "true" + labels: {} + path: / + + # pathType is only for k8s >= 1.1= + pathType: Prefix + + hosts: + - chart-example.local + ## Extra paths to prepend to every host configuration. This is useful when working with annotation based services. + extraPaths: [] + # - path: /* + # backend: + # serviceName: ssl-redirect + # servicePort: use-annotation + ## Or for k8s > 1.19 + # - path: /* + # pathType: Prefix + # backend: + # service: + # name: ssl-redirect + # port: + # name: use-annotation + + + tls: [] + # - secretName: chart-example-tls + # hosts: + # - chart-example.local + +resources: {} +# limits: +# cpu: 100m +# memory: 128Mi +# requests: +# cpu: 100m +# memory: 128Mi + +## Node labels for pod assignment +## ref: https://kubernetes.io/docs/user-guide/node-selection/ +# +nodeSelector: {} + +## Tolerations for pod assignment +## ref: https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/ +## +tolerations: [] + +## Affinity for pod assignment (evaluated as template) +## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity +## +affinity: {} + +## Additional init containers (evaluated as template) +## ref: https://kubernetes.io/docs/concepts/workloads/pods/init-containers/ +## +extraInitContainers: [] + +## Enable an Specify container in extraContainers. This is meant to allow adding an authentication proxy to a grafana pod +extraContainers: "" +# extraContainers: | +# - name: proxy +# image: quay.io/gambol99/keycloak-proxy:latest +# args: +# - -provider=github +# - -client-id= +# - -client-secret= +# - -github-org= +# - -email-domain=* +# - -cookie-secret= +# - -http-address=http://0.0.0.0:4181 +# - -upstream-url=http://127.0.0.1:3000 +# ports: +# - name: proxy-web +# containerPort: 4181 + +## Volumes that can be used in init containers that will not be mounted to deployment pods +extraContainerVolumes: [] +# - name: volume-from-secret +# secret: +# secretName: secret-to-mount +# - name: empty-dir-volume +# emptyDir: {} + +## Enable persistence using Persistent Volume Claims +## ref: http://kubernetes.io/docs/user-guide/persistent-volumes/ +## +persistence: + type: pvc + enabled: false + # storageClassName: default + accessModes: + - ReadWriteOnce + size: 10Gi + # annotations: {} + finalizers: + - kubernetes.io/pvc-protection + # selectorLabels: {} + ## Sub-directory of the PV to mount. Can be templated. + # subPath: "" + ## Name of an existing PVC. Can be templated. + # existingClaim: + + ## If persistence is not enabled, this allows to mount the + ## local storage in-memory to improve performance + ## + inMemory: + enabled: false + ## The maximum usage on memory medium EmptyDir would be + ## the minimum value between the SizeLimit specified + ## here and the sum of memory limits of all containers in a pod + ## + # sizeLimit: 300Mi + +initChownData: + ## If false, data ownership will not be reset at startup + ## This allows the prometheus-server to be run with an arbitrary user + ## + enabled: true + + ## initChownData container image + ## + image: + repository: busybox + tag: "1.31.1" + sha: "" + pullPolicy: IfNotPresent + + ## initChownData resource requests and limits + ## Ref: http://kubernetes.io/docs/user-guide/compute-resources/ + ## + resources: {} + # limits: + # cpu: 100m + # memory: 128Mi + # requests: + # cpu: 100m + # memory: 128Mi + + +# Administrator credentials when not using an existing secret (see below) +adminUser: admin +# adminPassword: strongpassword + +# Use an existing secret for the admin user. +admin: + ## Name of the secret. Can be templated. + existingSecret: "" + userKey: admin-user + passwordKey: admin-password + +## Define command to be executed at startup by grafana container +## Needed if using `vault-env` to manage secrets (ref: https://banzaicloud.com/blog/inject-secrets-into-pods-vault/) +## Default is "run.sh" as defined in grafana's Dockerfile +# command: +# - "sh" +# - "/run.sh" + +## Use an alternate scheduler, e.g. "stork". +## ref: https://kubernetes.io/docs/tasks/administer-cluster/configure-multiple-schedulers/ +## +# schedulerName: + +## Extra environment variables that will be pass onto deployment pods +## +## to provide grafana with access to CloudWatch on AWS EKS: +## 1. create an iam role of type "Web identity" with provider oidc.eks.* (note the provider for later) +## 2. edit the "Trust relationships" of the role, add a line inside the StringEquals clause using the +## same oidc eks provider as noted before (same as the existing line) +## also, replace NAMESPACE and prometheus-operator-grafana with the service account namespace and name +## +## "oidc.eks.us-east-1.amazonaws.com/id/XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:sub": "system:serviceaccount:NAMESPACE:prometheus-operator-grafana", +## +## 3. attach a policy to the role, you can use a built in policy called CloudWatchReadOnlyAccess +## 4. use the following env: (replace 123456789000 and iam-role-name-here with your aws account number and role name) +## +## env: +## AWS_ROLE_ARN: arn:aws:iam::123456789000:role/iam-role-name-here +## AWS_WEB_IDENTITY_TOKEN_FILE: /var/run/secrets/eks.amazonaws.com/serviceaccount/token +## AWS_REGION: us-east-1 +## +## 5. uncomment the EKS section in extraSecretMounts: below +## 6. uncomment the annotation section in the serviceAccount: above +## make sure to replace arn:aws:iam::123456789000:role/iam-role-name-here with your role arn + +env: {} + +## "valueFrom" environment variable references that will be added to deployment pods. Name is templated. +## ref: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.19/#envvarsource-v1-core +## Renders in container spec as: +## env: +## ... +## - name: +## valueFrom: +## +envValueFrom: {} + # ENV_NAME: + # configMapKeyRef: + # name: configmap-name + # key: value_key + +## The name of a secret in the same kubernetes namespace which contain values to be added to the environment +## This can be useful for auth tokens, etc. Value is templated. +envFromSecret: "" + +## Sensible environment variables that will be rendered as new secret object +## This can be useful for auth tokens, etc +envRenderSecret: {} + +## The names of secrets in the same kubernetes namespace which contain values to be added to the environment +## Each entry should contain a name key, and can optionally specify whether the secret must be defined with an optional key. +## Name is templated. +envFromSecrets: [] +## - name: secret-name +## optional: true + +## The names of conifgmaps in the same kubernetes namespace which contain values to be added to the environment +## Each entry should contain a name key, and can optionally specify whether the configmap must be defined with an optional key. +## Name is templated. +## ref: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#configmapenvsource-v1-core +envFromConfigMaps: [] +## - name: configmap-name +## optional: true + +# Inject Kubernetes services as environment variables. +# See https://kubernetes.io/docs/concepts/services-networking/connect-applications-service/#environment-variables +enableServiceLinks: true + +## Additional grafana server secret mounts +# Defines additional mounts with secrets. Secrets must be manually created in the namespace. +extraSecretMounts: [] + # - name: secret-files + # mountPath: /etc/secrets + # secretName: grafana-secret-files + # readOnly: true + # subPath: "" + # + # for AWS EKS (cloudwatch) use the following (see also instruction in env: above) + # - name: aws-iam-token + # mountPath: /var/run/secrets/eks.amazonaws.com/serviceaccount + # readOnly: true + # projected: + # defaultMode: 420 + # sources: + # - serviceAccountToken: + # audience: sts.amazonaws.com + # expirationSeconds: 86400 + # path: token + # + # for CSI e.g. Azure Key Vault use the following + # - name: secrets-store-inline + # mountPath: /run/secrets + # readOnly: true + # csi: + # driver: secrets-store.csi.k8s.io + # readOnly: true + # volumeAttributes: + # secretProviderClass: "akv-grafana-spc" + # nodePublishSecretRef: # Only required when using service principal mode + # name: grafana-akv-creds # Only required when using service principal mode + +## Additional grafana server volume mounts +# Defines additional volume mounts. +extraVolumeMounts: [] + # - name: extra-volume-0 + # mountPath: /mnt/volume0 + # readOnly: true + # existingClaim: volume-claim + # - name: extra-volume-1 + # mountPath: /mnt/volume1 + # readOnly: true + # hostPath: /usr/shared/ + +## Container Lifecycle Hooks. Execute a specific bash command or make an HTTP request +lifecycleHooks: {} + # postStart: + # exec: + # command: [] + +## Pass the plugins you want installed as a list. +## +plugins: [] + # - digrich-bubblechart-panel + # - grafana-clock-panel + +## Configure grafana datasources +## ref: http://docs.grafana.org/administration/provisioning/#datasources +## +datasources: {} +# datasources.yaml: +# apiVersion: 1 +# datasources: +# - name: Prometheus +# type: prometheus +# url: http://prometheus-prometheus-server +# access: proxy +# isDefault: true +# - name: CloudWatch +# type: cloudwatch +# access: proxy +# uid: cloudwatch +# editable: false +# jsonData: +# authType: default +# defaultRegion: us-east-1 + +## Configure notifiers +## ref: http://docs.grafana.org/administration/provisioning/#alert-notification-channels +## +notifiers: {} +# notifiers.yaml: +# notifiers: +# - name: email-notifier +# type: email +# uid: email1 +# # either: +# org_id: 1 +# # or +# org_name: Main Org. +# is_default: true +# settings: +# addresses: an_email_address@example.com +# delete_notifiers: + +## Configure grafana dashboard providers +## ref: http://docs.grafana.org/administration/provisioning/#dashboards +## +## `path` must be /var/lib/grafana/dashboards/ +## +dashboardProviders: {} +# dashboardproviders.yaml: +# apiVersion: 1 +# providers: +# - name: 'default' +# orgId: 1 +# folder: '' +# type: file +# disableDeletion: false +# editable: true +# options: +# path: /var/lib/grafana/dashboards/default + +## Configure grafana dashboard to import +## NOTE: To use dashboards you must also enable/configure dashboardProviders +## ref: https://grafana.com/dashboards +## +## dashboards per provider, use provider name as key. +## +dashboards: {} + # default: + # some-dashboard: + # json: | + # $RAW_JSON + # custom-dashboard: + # file: dashboards/custom-dashboard.json + # prometheus-stats: + # gnetId: 2 + # revision: 2 + # datasource: Prometheus + # local-dashboard: + # url: https://example.com/repository/test.json + # token: '' + # local-dashboard-base64: + # url: https://example.com/repository/test-b64.json + # token: '' + # b64content: true + +## Reference to external ConfigMap per provider. Use provider name as key and ConfigMap name as value. +## A provider dashboards must be defined either by external ConfigMaps or in values.yaml, not in both. +## ConfigMap data example: +## +## data: +## example-dashboard.json: | +## RAW_JSON +## +dashboardsConfigMaps: {} +# default: "" + +## Grafana's primary configuration +## NOTE: values in map will be converted to ini format +## ref: http://docs.grafana.org/installation/configuration/ +## +grafana.ini: + paths: + data: /var/lib/grafana/ + logs: /var/log/grafana + plugins: /var/lib/grafana/plugins + provisioning: /etc/grafana/provisioning + analytics: + check_for_updates: true + log: + mode: console + grafana_net: + url: https://grafana.net +## grafana Authentication can be enabled with the following values on grafana.ini + # server: + # The full public facing url you use in browser, used for redirects and emails + # root_url: + # https://grafana.com/docs/grafana/latest/auth/github/#enable-github-in-grafana + # auth.github: + # enabled: false + # allow_sign_up: false + # scopes: user:email,read:org + # auth_url: https://github.com/login/oauth/authorize + # token_url: https://github.com/login/oauth/access_token + # api_url: https://api.github.com/user + # team_ids: + # allowed_organizations: + # client_id: + # client_secret: +## LDAP Authentication can be enabled with the following values on grafana.ini +## NOTE: Grafana will fail to start if the value for ldap.toml is invalid + # auth.ldap: + # enabled: true + # allow_sign_up: true + # config_file: /etc/grafana/ldap.toml + +## Grafana's LDAP configuration +## Templated by the template in _helpers.tpl +## NOTE: To enable the grafana.ini must be configured with auth.ldap.enabled +## ref: http://docs.grafana.org/installation/configuration/#auth-ldap +## ref: http://docs.grafana.org/installation/ldap/#configuration +ldap: + enabled: false + # `existingSecret` is a reference to an existing secret containing the ldap configuration + # for Grafana in a key `ldap-toml`. + existingSecret: "" + # `config` is the content of `ldap.toml` that will be stored in the created secret + config: "" + # config: |- + # verbose_logging = true + + # [[servers]] + # host = "my-ldap-server" + # port = 636 + # use_ssl = true + # start_tls = false + # ssl_skip_verify = false + # bind_dn = "uid=%s,ou=users,dc=myorg,dc=com" + +## Grafana's SMTP configuration +## NOTE: To enable, grafana.ini must be configured with smtp.enabled +## ref: http://docs.grafana.org/installation/configuration/#smtp +smtp: + # `existingSecret` is a reference to an existing secret containing the smtp configuration + # for Grafana. + existingSecret: "" + userKey: "user" + passwordKey: "password" + +## Sidecars that collect the configmaps with specified label and stores the included files them into the respective folders +## Requires at least Grafana 5 to work and can't be used together with parameters dashboardProviders, datasources and dashboards +sidecar: + image: + repository: quay.io/kiwigrid/k8s-sidecar + tag: 1.19.2 + sha: "" + imagePullPolicy: IfNotPresent + resources: {} +# limits: +# cpu: 100m +# memory: 100Mi +# requests: +# cpu: 50m +# memory: 50Mi + securityContext: {} + # skipTlsVerify Set to true to skip tls verification for kube api calls + # skipTlsVerify: true + enableUniqueFilenames: false + readinessProbe: {} + livenessProbe: {} + dashboards: + enabled: false + SCProvider: true + # label that the configmaps with dashboards are marked with + label: grafana_dashboard + # value of label that the configmaps with dashboards are set to + labelValue: null + # folder in the pod that should hold the collected dashboards (unless `defaultFolderName` is set) + folder: /tmp/dashboards + # The default folder name, it will create a subfolder under the `folder` and put dashboards in there instead + defaultFolderName: null + # Namespaces list. If specified, the sidecar will search for config-maps/secrets inside these namespaces. + # Otherwise the namespace in which the sidecar is running will be used. + # It's also possible to specify ALL to search in all namespaces. + searchNamespace: null + # Method to use to detect ConfigMap changes. With WATCH the sidecar will do a WATCH requests, with SLEEP it will list all ConfigMaps, then sleep for 60 seconds. + watchMethod: WATCH + # search in configmap, secret or both + resource: both + # If specified, the sidecar will look for annotation with this name to create folder and put graph here. + # You can use this parameter together with `provider.foldersFromFilesStructure`to annotate configmaps and create folder structure. + folderAnnotation: null + # Absolute path to shell script to execute after a configmap got reloaded + script: null + # watchServerTimeout: request to the server, asking it to cleanly close the connection after that. + # defaults to 60sec; much higher values like 3600 seconds (1h) are feasible for non-Azure K8S + # watchServerTimeout: 3600 + # + # watchClientTimeout: is a client-side timeout, configuring your local socket. + # If you have a network outage dropping all packets with no RST/FIN, + # this is how long your client waits before realizing & dropping the connection. + # defaults to 66sec (sic!) + # watchClientTimeout: 60 + # + # provider configuration that lets grafana manage the dashboards + provider: + # name of the provider, should be unique + name: sidecarProvider + # orgid as configured in grafana + orgid: 1 + # folder in which the dashboards should be imported in grafana + folder: '' + # type of the provider + type: file + # disableDelete to activate a import-only behaviour + disableDelete: false + # allow updating provisioned dashboards from the UI + allowUiUpdates: false + # allow Grafana to replicate dashboard structure from filesystem + foldersFromFilesStructure: false + # Additional dashboard sidecar volume mounts + extraMounts: [] + # Sets the size limit of the dashboard sidecar emptyDir volume + sizeLimit: {} + datasources: + enabled: false + # label that the configmaps with datasources are marked with + label: grafana_datasource + # value of label that the configmaps with datasources are set to + labelValue: null + # If specified, the sidecar will search for datasource config-maps inside this namespace. + # Otherwise the namespace in which the sidecar is running will be used. + # It's also possible to specify ALL to search in all namespaces + searchNamespace: null + # Method to use to detect ConfigMap changes. With WATCH the sidecar will do a WATCH requests, with SLEEP it will list all ConfigMaps, then sleep for 60 seconds. + watchMethod: WATCH + # search in configmap, secret or both + resource: both + # Endpoint to send request to reload datasources + reloadURL: "http://localhost:3000/api/admin/provisioning/datasources/reload" + skipReload: false + # Deploy the datasource sidecar as an initContainer in addition to a container. + # This is needed if skipReload is true, to load any datasources defined at startup time. + initDatasources: false + # Sets the size limit of the datasource sidecar emptyDir volume + sizeLimit: {} + plugins: + enabled: false + # label that the configmaps with plugins are marked with + label: grafana_plugin + # value of label that the configmaps with plugins are set to + labelValue: null + # If specified, the sidecar will search for plugin config-maps inside this namespace. + # Otherwise the namespace in which the sidecar is running will be used. + # It's also possible to specify ALL to search in all namespaces + searchNamespace: null + # Method to use to detect ConfigMap changes. With WATCH the sidecar will do a WATCH requests, with SLEEP it will list all ConfigMaps, then sleep for 60 seconds. + watchMethod: WATCH + # search in configmap, secret or both + resource: both + # Endpoint to send request to reload plugins + reloadURL: "http://localhost:3000/api/admin/provisioning/plugins/reload" + skipReload: false + # Deploy the datasource sidecar as an initContainer in addition to a container. + # This is needed if skipReload is true, to load any plugins defined at startup time. + initPlugins: false + # Sets the size limit of the plugin sidecar emptyDir volume + sizeLimit: {} + notifiers: + enabled: false + # label that the configmaps with notifiers are marked with + label: grafana_notifier + # If specified, the sidecar will search for notifier config-maps inside this namespace. + # Otherwise the namespace in which the sidecar is running will be used. + # It's also possible to specify ALL to search in all namespaces + searchNamespace: null + # search in configmap, secret or both + resource: both + # Sets the size limit of the notifier sidecar emptyDir volume + sizeLimit: {} + +## Override the deployment namespace +## +namespaceOverride: "" + +## Number of old ReplicaSets to retain +## +revisionHistoryLimit: 10 + +## Add a seperate remote image renderer deployment/service +imageRenderer: + # Enable the image-renderer deployment & service + enabled: false + replicas: 1 + image: + # image-renderer Image repository + repository: grafana/grafana-image-renderer + # image-renderer Image tag + tag: latest + # image-renderer Image sha (optional) + sha: "" + # image-renderer ImagePullPolicy + pullPolicy: Always + # extra environment variables + env: + HTTP_HOST: "0.0.0.0" + # RENDERING_ARGS: --no-sandbox,--disable-gpu,--window-size=1280x758 + # RENDERING_MODE: clustered + # IGNORE_HTTPS_ERRORS: true + # image-renderer deployment serviceAccount + serviceAccountName: "" + # image-renderer deployment securityContext + securityContext: {} + # image-renderer deployment Host Aliases + hostAliases: [] + # image-renderer deployment priority class + priorityClassName: '' + service: + # Enable the image-renderer service + enabled: true + # image-renderer service port name + portName: 'http' + # image-renderer service port used by both service and deployment + port: 8081 + targetPort: 8081 + # If https is enabled in Grafana, this needs to be set as 'https' to correctly configure the callback used in Grafana + grafanaProtocol: http + # In case a sub_path is used this needs to be added to the image renderer callback + grafanaSubPath: "" + # name of the image-renderer port on the pod + podPortName: http + # number of image-renderer replica sets to keep + revisionHistoryLimit: 10 + networkPolicy: + # Enable a NetworkPolicy to limit inbound traffic to only the created grafana pods + limitIngress: true + # Enable a NetworkPolicy to limit outbound traffic to only the created grafana pods + limitEgress: false + resources: {} +# limits: +# cpu: 100m +# memory: 100Mi +# requests: +# cpu: 50m +# memory: 50Mi + ## Node labels for pod assignment + ## ref: https://kubernetes.io/docs/user-guide/node-selection/ + # + nodeSelector: {} + + ## Tolerations for pod assignment + ## ref: https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/ + ## + tolerations: [] + + ## Affinity for pod assignment (evaluated as template) + ## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity + ## + affinity: {} + +networkPolicy: + ## @param networkPolicy.enabled Enable creation of NetworkPolicy resources. Only Ingress traffic is filtered for now. + ## + enabled: false + ## @param networkPolicy.allowExternal Don't require client label for connections + ## The Policy model to apply. When set to false, only pods with the correct + ## client label will have network access to grafana port defined. + ## When true, grafana will accept connections from any source + ## (with the correct destination port). + ## + ingress: true + ## @param networkPolicy.ingress When true enables the creation + ## an ingress network policy + ## + allowExternal: true + ## @param networkPolicy.explicitNamespacesSelector A Kubernetes LabelSelector to explicitly select namespaces from which traffic could be allowed + ## If explicitNamespacesSelector is missing or set to {}, only client Pods that are in the networkPolicy's namespace + ## and that match other criteria, the ones that have the good label, can reach the grafana. + ## But sometimes, we want the grafana to be accessible to clients from other namespaces, in this case, we can use this + ## LabelSelector to select these namespaces, note that the networkPolicy's namespace should also be explicitly added. + ## + ## Example: + ## explicitNamespacesSelector: + ## matchLabels: + ## role: frontend + ## matchExpressions: + ## - {key: role, operator: In, values: [frontend]} + ## + explicitNamespacesSelector: {} + ## + ## + ## + ## + ## + ## + egress: + ## @param networkPolicy.egress.enabled When enabled, an egress network policy will be + ## created allowing grafana to connect to external data sources from kubernetes cluster. + enabled: false + ## + ## @param networkPolicy.egress.ports Add individual ports to be allowed by the egress + ports: [] + ## Add ports to the egress by specifying - port: + ## E.X. + ## ports: + ## - port: 80 + ## - port: 443 + ## + ## + ## + ## + ## + ## + +# Enable backward compatibility of kubernetes where version below 1.13 doesn't have the enableServiceLinks option +enableKubeBackwardCompatibility: false +useStatefulSet: false +# Create a dynamic manifests via values: +extraObjects: [] + # - apiVersion: "kubernetes-client.io/v1" + # kind: ExternalSecret + # metadata: + # name: grafana-secrets + # spec: + # backendType: gcpSecretsManager + # data: + # - key: grafana-admin-password + # name: adminPassword diff --git a/charts/oes/charts/openldap/templates/deployment.yaml b/charts/oes/charts/openldap/templates/deployment.yaml index 6f15e92a..5ce67f5f 100644 --- a/charts/oes/charts/openldap/templates/deployment.yaml +++ b/charts/oes/charts/openldap/templates/deployment.yaml @@ -86,8 +86,7 @@ spec: command: - /bin/sh - -c - - until service slapd status; do sleep 10 ;done;ldapadd -x -D 'cn=admin,dc=example,dc=org' - -w opsmxadmin123 -f /container/service/slapd/assets/config/bootstrap/ldif/custom/10-users.ldif + - until service slapd status; do sleep 10 ;done imagePullPolicy: {{ .Values.image.pullPolicy }} {{- if .Values.customLdifFiles }} args: [--copy-service] diff --git a/charts/oes/charts/prometheus/config/node_alerting_rules.yml b/charts/oes/charts/prometheus/config/node_alerting_rules.yml index a9f41719..22f7d514 100644 --- a/charts/oes/charts/prometheus/config/node_alerting_rules.yml +++ b/charts/oes/charts/prometheus/config/node_alerting_rules.yml @@ -2,13 +2,13 @@ groups: - name: container_cpu_usage_is_high rules: - alert: POD_CPU_IS_HIGH - expr: sum(rate(container_cpu_usage_seconds_total{container!=""}[3m])) BY (container, pod, namespace) * 100 > 80 + expr: sum(rate(container_cpu_usage_seconds_total{container!=""}[5m])) BY (container, pod, namespace) * 100 > 90 for: 1m labels: severity: critical annotations: - description: 'Container {{ $labels.container}} inside POD {{ $labels.pod }} cpu is high in {{$labels.namespace}}' - summary: 'pod cpu is high' + description: 'Container {{ $labels.container }} CPU usage inside POD {{ $labels.pod}} is high in {{ $labels.namespace}}' + summary: 'POD {{ $labels.pod}} CPU Usage is high in {{ $labels.namespace}}' - name: container_memory_usage_is_high rules: - alert: POD_MEMORY_USAGE_IS_HIGH @@ -22,7 +22,7 @@ groups: - name: node_cpu_greater_than_80 rules: - alert: NODE_CPU_IS_HIGH - expr: 100 - (avg by(instance) (rate(node_cpu_seconds_total{mode="idle"}[2m])) * 100) > 80 + expr: 100 - (avg by(instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100) > 90 for: 1m labels: severity: critical @@ -38,4 +38,24 @@ groups: severity: critical annotations: description: 'node {{ $labels.kubernetes_node }} memory left is low' - summary: 'node memory left is lesser than 10 precent' + summary: 'node memory left is lesser than 10 precent' +- name: node_disk_space_too_low + rules: + - alert: NODE_DISK_SPACE_IS_LOW + expr: (100 * ((node_filesystem_avail_bytes{mountpoint="/",fstype!="rootfs"} ) / (node_filesystem_size_bytes{mountpoint="/",fstype!="rootfs"}))) < 10 + for: 1m + labels: + severity: critical + annotations: + description: node {{ $labels.node }} disk space is only {{ printf "%0.2f" $value }}% free. + summary: 'node disk space remaining is less than 10 percent' +- name: node_down + rules: + - alert: NODE_DOWN + expr: up{component="node-exporter"} == 0 + for: 3m + labels: + severity: warning + annotations: + summary: 'Node {{ $labels.kubernetes_node }} is down' + description: '{{ $labels.job }} job failed to scrape instance {{ $labels.instance }} for more than 3 minutes. Node Seems to be down' diff --git a/charts/oes/charts/prometheus/config/spin_alerting_rules.yml b/charts/oes/charts/prometheus/config/spin_alerting_rules.yml index 53297f7d..542c0c98 100644 --- a/charts/oes/charts/prometheus/config/spin_alerting_rules.yml +++ b/charts/oes/charts/prometheus/config/spin_alerting_rules.yml @@ -3,150 +3,198 @@ groups: rules: - alert: clouddriver-rw-is-down annotations: - description: Service {{$labels.service}} in namespace {{$labels.namespace}} - is not responding + description: 'Service {{$labels.service}} with pod name {{$labels.pod}} in namespace {{$labels.namespace}} + is not responding' summary: Clouddriver-rw Spinnaker service is down - expr: absent(up{service="spin-clouddriver-rw"}) == 1 + expr: up{job="opsmx_spinnaker_metrics", service="spin-clouddriver-rw"} == 0 labels: severity: critical - alert: clouddriver-ro-is-down annotations: - description: Service {{$labels.service}} in namespace {{$labels.namespace}} - is not responding + description: 'Service {{$labels.service}} with pod name {{$labels.pod}} in namespace {{$labels.namespace}} + is not responding' summary: Clouddriver-ro Spinnaker service is down - expr: absent(up{service="spin-clouddriver-ro"}) == 1 + expr: up{job="opsmx_spinnaker_metrics", service="spin-clouddriver-ro"} == 0 labels: severity: critical - alert: clouddriver-caching-is-down annotations: - description: Service {{$labels.service}} in namespace {{$labels.namespace}} - is not responding + description: 'Service {{$labels.service}} with pod name {{$labels.pod}} in namespace {{$labels.namespace}} + is not responding' summary: Clouddriver-caching Spinnaker service is down - expr: absent(up{service="spin-clouddriver-caching"}) == 1 + expr: up{job="opsmx_spinnaker_metrics", service="spin-clouddriver-caching"} == 0 labels: severity: critical + - alert: clouddriver-ro-deck-is-down + annotations: + description: 'Service {{$labels.service}} with pod name {{$labels.pod}} in namespace {{$labels.namespace}} + is not responding' + summary: Clouddriver-ro-deck Spinnaker service is down + expr: up{job="opsmx_spinnaker_metrics", service="spin-clouddriver-ro-deck"} == 0 + labels: + severity: critical - alert: gate-is-down annotations: - description: Service {{$labels.service}} in namespace {{$labels.namespace}} - is not responding + description: 'Service {{$labels.service}} with pod name {{$labels.pod}} in namespace {{$labels.namespace}} + is not responding' summary: Gate Spinnaker services is down - expr: absent(up{service="spin-gate"}) == 1 + expr: up{job="opsmx_spinnaker_metrics", service="spin-gate"} == 0 labels: severity: critical - alert: orca-is-down annotations: - description: Service {{$labels.service}} in namespace {{$labels.namespace}} - is not responding + description: 'Service {{$labels.service}} with pod name {{$labels.pod}} in namespace {{$labels.namespace}} + is not responding' summary: Orca Spinnaker service is down - expr: absent(up{job="opsmx_spinnaker_metrics", service="spin-orca"}) == 1 + expr: up{job="opsmx_spinnaker_metrics", service="spin-orca"} == 0 labels: severity: critical - alert: igor-is-down annotations: - description: Service {{$labels.service}} in namespace {{$labels.namespace}} - is not responding + description: 'Service {{$labels.service}} with pod name {{$labels.pod}} in namespace {{$labels.namespace}} + is not responding' summary: Igor Spinnaker service is down - expr: absent(up{service="spin-igor"}) == 1 + expr: up{job="opsmx_spinnaker_metrics", service="spin-igor"} == 0 labels: severity: critical - alert: echo-scheduler-is-down annotations: - description: Service {{$labels.service}} in namespace {{$labels.namespace}} - is not responding + description: 'Service {{$labels.service}} with pod name {{$labels.pod}} in namespace {{$labels.namespace}} + is not responding' summary: Echo-Scheduler Spinnaker service is down - expr: absent(up{service="spin-echo-scheduler" }) == 1 + expr: up{job="opsmx_spinnaker_metrics", service="spin-echo-scheduler"} == 0 labels: severity: critical - alert: echo-worker-is-down annotations: - description: Service {{$labels.service}} in namespace {{$labels.namespace}} - is not responding + description: 'Service {{$labels.service}} with pod name {{$labels.pod}} in namespace {{$labels.namespace}} + is not responding' summary: Echo-worker Spinnaker service is down - expr: absent(up{service="spin-echo-worker" }) == 1 + expr: up{job="opsmx_spinnaker_metrics", service="spin-echo-worker"} == 0 labels: severity: critical - alert: front50-is-down annotations: - description: Service {{$labels.service}} in namespace {{$labels.namespace}} - is not responding + description: 'Service {{$labels.service}} with pod name {{$labels.pod}} in namespace {{$labels.namespace}} + is not responding' summary: Front50 Spinnaker service is down - expr: absent(up{service="spin-front50" }) == 1 + expr: up{job="opsmx_spinnaker_metrics", service="spin-front50"} == 0 labels: severity: critical + - alert: fiat-is-down + annotations: + description: 'Service {{$labels.service}} with pod name {{$labels.pod}} in namespace {{$labels.namespace}} + is not responding' + summary: Fiat Spinnaker service is down + expr: up{job="opsmx_spinnaker_metrics", service="spin-fiat"} == 0 + labels: + severity: critical + - alert: rosco-is-down + annotations: + description: 'Service {{$labels.service}} with pod name {{$labels.pod}} in namespace {{$labels.namespace}} + is not responding' + summary: Rosco Spinnaker service is down + expr: up{job="opsmx_spinnaker_metrics", service="spin-rosco"} == 0 + labels: + severity: critical - name: latency-too-high rules: - alert: clouddriver-ro-latency-too-high - expr: sum(rate(clouddriver_ro:controller:invocations__count_total{service="spin-clouddriver-ro",statusCode="200"}[2m])) by (instance, method)/ sum(rate(clouddriver_ro:controller:invocations__total{service="spin-clouddriver-ro",statusCode="200"}[2m])) by (instance, method) > 200 - for: 5m + expr: sum(rate(clouddriver_ro:controller:invocations__total{service="spin-clouddriver-ro"}[5m])) by (controller, instance, method, success, statusCode, service, namespace)/ sum(rate(clouddriver_ro:controller:invocations__count_total{service="spin-clouddriver-ro"}[5m])) by (controller, instance, method, success, statusCode, service, namespace) > 1 + for: 15m labels: severity: warning annotations: - description: "Service {{$labels.service}} is slow ({{$value}} per minute)" - summary: latency of clouddriver-ro is too high + description: "Latency of the Service {{$labels.service}} is {{$value}} seconds for {{ $labels }}" + summary: Latency of the service {{ $labels.service }} in namespace {{$labels.namespace}} is high - alert: clouddriver-rw-latency-too-high - expr: sum(rate(clouddriver_rw:controller:invocations__count_total{service="spin-clouddriver-rw",statusCode="200"}[2m])) by (instance, method)/ sum(rate(clouddriver_rw:controller:invocations__total{service="spin-clouddriver-rw",statusCode="200"}[2m])) by (instance, method) > 200 - for: 5m + expr: sum(rate(clouddriver_rw:controller:invocations__total{service="spin-clouddriver-rw"}[5m])) by (controller, instance, method, success, statusCode, service, namespace)/ sum(rate(clouddriver_rw:controller:invocations__count_total{service="spin-clouddriver-rw"}[5m])) by (controller, instance, method, success, statusCode, service, namespace) > 0.5 + for: 15m labels: severity: warning annotations: - description: "Service {{$labels.service}} is slow ({{$value}} per minute)" - summary: latency of clouddriver-rw is too high + description: "Latency of the Service {{$labels.service}} is ({{$value}} seconds for {{ $labels }}" + summary: Latency of the service {{ $labels.service }} in namespace {{$labels.namespace}} is high - alert: clouddriver-caching-latency-too-high - expr: sum(rate(clouddriver_caching:controller:invocations__count_total{service="spin-clouddriver-caching",statusCode="200"}[2m])) by (instance, method)/ sum(rate(clouddriver_caching:controller:invocations__total{service="spin-clouddriver-caching",statusCode="200"}[2m])) by (instance, method) > 300 - for: 5m + expr: sum(rate(clouddriver_caching:controller:invocations__total{service="spin-clouddriver-caching"}[5m])) by (controller, instance, method, success, statusCode, service, namespace)/ sum(rate(clouddriver_caching:controller:invocations__count_total{service="spin-clouddriver-caching"}[5m])) by (controller, instance, method, success, statusCode, service, namespace) > 5 + for: 15m + labels: + severity: warning + annotations: + description: "Latency of the Service {{$labels.service}} is {{$value}} seconds for {{ $labels }}" + summary: Latency of the service {{ $labels.service }} in namespace {{$labels.namespace}} is high + - alert: clouddriver_ro_deck-latency-too-high + expr: sum(rate(clouddriver_ro_deck:controller:invocations__total{service="spin-clouddriver-ro-deck"}[5m])) by (controller, instance, method, success, statusCode, service, namespace)/ sum(rate(clouddriver_ro_deck:controller:invocations__total{service="spin-clouddriver-ro-deck"}[5m])) by (controller, instance, method, success, statusCode, service, namespace) > 5 + for: 15m labels: severity: warning annotations: - description: "Service {{$labels.service}} is slow ({{$value}} per minute)" - summary: latency clouddriver-caching is too high + description: "Latency of the Service {{$labels.service}} is {{$value}} seconds for {{ $labels }}" + summary: Latency of the service {{ $labels.service }} in namespace {{$labels.namespace}} is high - alert: gate-latency-too-high - expr: sum(rate(gate:controller:invocations__count_total{service="spin-gate",statusCode="200"}[2m])) by (instance, method)/ sum(rate(gate:controller:invocations__total{service="spin-gate",statusCode="200"}[2m])) by (instance, method) > 200 - for: 5m + expr: sum(rate(gate:controller:invocations__total{service="spin-gate"}[5m])) by (controller, instance, method, success, statusCode, service, namespace)/ sum(rate(gate:controller:invocations__count_total{service="spin-gate"}[5m])) by (controller, instance, method, success, statusCode, service, namespace) > 0.5 + for: 15m labels: severity: warning annotations: - description: "Service {{$labels.service}} is slow ({{$value}} per minute)" - summary: latency of gate is too high + description: "Latency of the Service {{$labels.service}} is {{$value}} seconds for {{ $labels }}" + summary: Latency of the service {{ $labels.service }} in namespace {{$labels.namespace}} is high - alert: orca-latency-too-high - expr: sum(rate(orca:controller:invocations__count_total{service="spin-orca",statusCode="200"}[2m])) by (instance, method)/ sum(rate(orca:controller:invocations__total{service="spin-orca",statusCode="200"}[2m])) by (instance, method) > 2000 - for: 5m + expr: sum(rate(orca:controller:invocations__total{service="spin-orca"}[5m])) by (controller, instance, method, success, statusCode, service, namespace)/ sum(rate(orca:controller:invocations__count_total{service="spin-orca"}[5m])) by (controller, instance, method, success, statusCode, service, namespace) > 0.5 + for: 15m labels: severity: warning annotations: - description: "Service {{$labels.service}} is slow ({{$value}} per minute)" - summary: latency of orca is too high + description: "Latency of the Service {{$labels.service}} is {{$value}} seconds for {{ $labels }}" + summary: Latency of the service {{ $labels.service }} in namespace {{$labels.namespace}} is high - alert: igor-latency-too-high - expr: sum(rate(igor:controller:invocations__count_total{service="spin-igor",statusCode="200"}[2m])) by (instance, method)/ sum(rate(igor:controller:invocations__total{service="spin-igor",statusCode="200"}[2m])) by (instance, method) > 10000 - for: 5m + expr: sum(rate(igor:controller:invocations__total{service="spin-igor"}[5m])) by (controller, instance, method, success, statusCode, service, namespace)/ sum(rate(igor:controller:invocations__count_total{service="spin-igor"}[5m])) by (controller, instance, method, success, statusCode, service, namespace) > 0.5 + for: 15m labels: severity: warning annotations: - description: "Service {{$labels.service}} is slow ({{$value}} per minute)" - summary: latency of igor is too high + description: "Latency of the Service {{$labels.service}} is {{$value}} seconds for {{ $labels }}" + summary: Latency of the service {{ $labels.service }} in namespace {{$labels.namespace}} is high - alert: echo_scheduler-latency-too-high - expr: sum(rate(echo_scheduler:controller:invocations__count_total{service="spin-echo-scheduler",statusCode="200"}[2m])) by (instance, method)/ sum(rate(echo_scheduler:controller:invocations__total{service="spin-echo-scheduler",statusCode="200"}[2m])) by (instance, method) > 300 - for: 5m + expr: sum(rate(echo_scheduler:controller:invocations__total{service="spin-echo-scheduler"}[5m])) by (controller, instance, method, success, statusCode, service, namespace)/ sum(rate(echo_scheduler:controller:invocations__count_total{service="spin-echo-scheduler"}[5m])) by (controller, instance, method, success, statusCode, service, namespace) > 0.5 + for: 15m labels: severity: warning annotations: - description: "Service {{$labels.service}} is slow ({{$value}} per minute)" - summary: latency of echo-scheduler is too high + description: "Latency of the Service {{$labels.service}} is {{$value}} seconds for {{ $labels }}" + summary: Latency of the service {{ $labels.service }} in namespace {{$labels.namespace}} is high - alert: echo_worker-latency-too-high - expr: sum(rate(echo_worker:controller:invocations__count_total{service="spin-echo-worker",statusCode="200"}[2m])) by (instance, method)/ sum(rate(echo_worker:controller:invocations__total{service="spin-echo-worker",statusCode="200"}[2m])) by (instance, method) > 2000 - for: 5m + expr: sum(rate(echo_worker:controller:invocations__total{service="spin-echo-worker"}[5m])) by (controller, instance, method, success, statusCode, service, namespace)/ sum(rate(echo_worker:controller:invocations__count_total{service="spin-echo-worker"}[5m])) by (controller, instance, method, success, statusCode, service, namespace) > 0.5 + for: 15m labels: severity: warning annotations: - description: "Service {{$labels.service}} is slow ({{$value}} per minute)" - summary: latency of echo-worker is too high + description: "Latency of the Service {{$labels.service}} is {{$value}} seconds for {{ $labels }}" + summary: Latency of the service {{ $labels.service }} in namespace {{$labels.namespace}} is high - alert: front50-latency-too-high - expr: sum(rate(front50:controller:invocations__count_total{service="spin-front50",statusCode="200"}[2m])) by (instance, method)/ sum(rate(front50:controller:invocations__total{service="spin-front50",statusCode="200"}[2m])) by (instance, method) > 600 - for: 5m + expr: sum(rate(front50:controller:invocations__total{service="spin-front50"}[5m])) by (controller, instance, method, success, statusCode, service, namespace)/ sum(rate(front50:controller:invocations__count_total{service="spin-front50"}[5m])) by (controller, instance, method, success, statusCode, service, namespace) > 0.5 + for: 15m labels: severity: warning annotations: - description: "Service {{$labels.service}} is slow ({{$value}} per minute)" - summary: latency of front50 is too high + description: "Latency of the Service {{$labels.service}} is {{$value}} seconds for {{ $labels }}" + summary: Latency of the service {{ $labels.service }} in namespace {{$labels.namespace}} is high + - alert: fiat-latency-too-high + expr: sum(rate(fiat:controller:invocations__total{service="spin-fiat"}[5m])) by (controller, instance, method, success, statusCode, service, namespace)/ sum(rate(fiat:controller:invocations__count_total{service="spin-fiat"}[5m])) by (controller, instance, method, success, statusCode, service, namespace) > 0.5 + for: 15m + labels: + severity: warning + annotations: + description: "Latency of the Service {{$labels.service}} is {{$value}} seconds for {{ $labels }}" + summary: Latency of the service {{ $labels.service }} in namespace {{$labels.namespace}} is high + - alert: rosco-latency-too-high + expr: sum(rate(rosco:controller:invocations__total{service="spin-rosco"}[5m])) by (controller, instance, method, success, statusCode, service, namespace)/ sum(rate(rosco:controller:invocations__count_total{service="spin-rosco"}[5m])) by (controller, instance, method, success, statusCode, service, namespace) > 0.5 + for: 15m + labels: + severity: warning + annotations: + description: "Latency of the Service {{$labels.service}} is {{$value}} seconds for {{ $labels }}" + summary: Latency of the service {{ $labels.service }} in namespace {{$labels.namespace}} is high - name: jvm-too-high rules: - alert: clouddriver-rw-pod-may-be-evicted-soon @@ -220,6 +268,16 @@ groups: expr: (sum(front50:jvm:memory:used__value) by (instance, area) / sum(front50:jvm:memory:max__value) by (instance, area)) > .9 labels: severity: warning +- name: Front50-cache + rules: + - alert: "front50:storageServiceSupport:cacheAge__value" + annotations: + description: front50 cacheAge for {{$labels.pod}} in namespace {{$labels.namespace}} has value = {{$value}} + summary: "front50 cacheAge too high" + expr: front50:storageServiceSupport:cacheAge__value > 300000 + for: 2m + labels: + severity: warning - name: orca-queue-issue rules: - alert: orca-queue-depth-high @@ -227,14 +285,14 @@ groups: description: Service {{$labels.service}} in namespace {{$labels.namespace}} may be evicted soon summary: Orca queue depth is high - expr: (sum(orca:queue:ready:depth{namespace="oes"}) by (instance) ) > 10 + expr: (sum(orca:queue:ready:depth__value{namespace!=""}) by (instance)) > 10 labels: severity: warning - alert: orca-queue-lag-high annotations: - description: Lag = {{$value}} + description: Service {{$labels.service}} in namespace {{$labels.namespace}} has Lag value of {{$value}} summary: Orca queue lag is high - expr: sum(rate (orca:controller:invocations__totalTime_total[2m])) by (instance) / sum(rate(orca:controller:invocations__count_total[2m])) by (instance) > 0.5 + expr: sum(rate (orca:controller:invocations__total[2m])) by (instance, service, namespace) / sum(rate(orca:controller:invocations__count_total[2m])) by (instance, service, namespace) > 0.5 labels: severity: warning - name: igor-needs-attention @@ -243,7 +301,7 @@ groups: annotations: description: Igor in namespace {{$labels.namespace}} needs human help summary: Igor needs attention - expr: igor:pollingMonitor:itemsOverThreshold > 0 + expr: igor:pollingMonitor:itemsOverThreshold__value > 0 labels: severity: crtical - name: autopilot-scrape-target-is-down @@ -290,9 +348,9 @@ groups: expr: up{component="visibility"}==0 labels: severity: critical -- name: Default Prometheus Job is Down +- name: prometheus-job-down rules: - - alert: PROMETHEUS_JOB_IS_DOWN + - alert: prometheus-job-is-down expr: up{job="prometheus"} == 0 for: 5m labels: @@ -300,9 +358,9 @@ groups: annotations: summary: The Default Prometheus Job is Down (job {{ $labels.job}}) description: "Default Prometheus Job is Down LABELS = {{ $labels }}" -- name: Volume is almost full (< 10% left) +- name: volume-is-almost-full (< 10% left) rules: - - alert: PVC_STORAGE_FULL + - alert: pvc-storage-full expr: kubelet_volume_stats_available_bytes / kubelet_volume_stats_capacity_bytes * 100 < 10 for: 2m labels: @@ -310,9 +368,9 @@ groups: annotations: summary: Kubernetes Volume running out of disk space for (persistentvolumeclaim {{ $labels.persistentvolumeclaim }} in namespace {{$labels.namespace}}) description: "Volume is almost full (< 10% left)\n VALUE = {{ $value }}\n LABELS = {{ $labels }}" -- name: Kubernetes API server is experiencing high error rate +- name: kubernetes-api-server-experiencing-high-error-rate rules: - - alert: KUBE_API_SERVER_ERRORS + - alert: kube-api-server-errors expr: sum(rate(apiserver_request_total{job="kubernetes-apiservers",code=~"^(?:5..)$"}[2m])) / sum(rate(apiserver_request_total{job="kubernetes-apiservers"}[2m])) * 100 > 3 for: 2m labels: @@ -320,19 +378,59 @@ groups: annotations: summary: Kubernetes API server errors (instance {{ $labels.instance }}) description: "Kubernetes API server is experiencing high error rate\n VALUE = {{ $value }}\n LABELS = {{ $labels }}" -- name: Latency too high +- name: autopilot-component-latency-too-high rules: - - alert: TOO_HIGH_LATENCY - expr: sum(rate(http_server_requests_seconds_sum{component!=""}[2m])) by (kubernetes_pod_name, method, component)/sum(rate(http_server_requests_seconds_count{component!=""}[2m])) by (kubernetes_pod_name, method, component) > 0.1 + - alert: oes-audit-client-latency-too-high + expr: sum(rate(http_server_requests_seconds_sum{component="auditclient"}[2m])) by (kubernetes_pod_name, method, outcome, status, component, kubernetes_namespace, uri)/sum(rate(http_server_requests_seconds_count{component="auditclient"}[2m])) by (kubernetes_pod_name, method, outcome, status, component, kubernetes_namespace, uri) > 0.5 + for: 2m + labels: + severity: warning + annotations: + summary: Latency of the component {{ $labels.component }} in namespace {{$labels.kubernetes_namespace}} is high + description: "Latency of the component {{ $labels.component }} is {{ $value }} seconds for {{ $labels }}" + - alert: oes-autopilot-latency-too-high + expr: sum(rate(http_server_requests_seconds_sum{component="autopilot"}[2m])) by (kubernetes_pod_name, method, outcome, status, component, kubernetes_namespace, uri)/sum(rate(http_server_requests_seconds_count{component="autopilot"}[2m])) by (kubernetes_pod_name, method, outcome, status, component, kubernetes_namespace, uri) > 0.5 + for: 2m + labels: + severity: warning + annotations: + summary: Latency of the component {{ $labels.component }} in namespace {{$labels.kubernetes_namespace}} is high + description: "Latency of the component {{ $labels.component }} is {{ $value }} seconds for {{ $labels }}" + - alert: oes-dashboard-latency-too-high + expr: sum(rate(http_server_requests_seconds_sum{component="dashboard"}[2m])) by (kubernetes_pod_name, method, outcome, status, component, kubernetes_namespace, uri)/sum(rate(http_server_requests_seconds_count{component="dashboard"}[2m])) by (kubernetes_pod_name, method, outcome, status, component, kubernetes_namespace, uri) > 0.5 for: 2m labels: severity: warning annotations: - summary: Latency of the component (component {{ $labels.component }} in namespace {{$labels.namespace}} is high) - description: "Latency of the component\n VALUE = {{ $value }}\n LABELS = {{ $labels }}" -- name: Kube-API Server is down + summary: Latency of the component {{ $labels.component }} in namespace {{$labels.kubernetes_namespace}} is high + description: "Latency of the component {{ $labels.component }} is {{ $value }} seconds for {{ $labels }}" + - alert: oes-platform-latency-too-high + expr: sum(rate(http_server_requests_seconds_sum{component="platform"}[2m])) by (kubernetes_pod_name, method, outcome, status, component, kubernetes_namespace, uri)/sum(rate(http_server_requests_seconds_count{component="platform"}[2m])) by (kubernetes_pod_name, method, outcome, status, component, kubernetes_namespace, uri) > 0.5 + for: 2m + labels: + severity: warning + annotations: + summary: Latency of the component {{ $labels.component }} in namespace {{$labels.kubernetes_namespace}} is high + description: "Latency of the component {{ $labels.component }} is {{ $value }} seconds for {{ $labels }}" + - alert: oes-sapor-latency-too-high + expr: sum(rate(http_server_requests_seconds_sum{component="sapor"}[2m])) by (kubernetes_pod_name, method, outcome, status, component, kubernetes_namespace, uri)/sum(rate(http_server_requests_seconds_count{component="sapor"}[2m])) by (kubernetes_pod_name, method, outcome, status, component, kubernetes_namespace, uri) > 0.5 + for: 2m + labels: + severity: warning + annotations: + summary: Latency of the component {{ $labels.component }} in namespace {{$labels.kubernetes_namespace}} is high + description: "Latency of the component {{ $labels.component }} is {{ $value }} seconds for {{ $labels }}" + - alert: oes-visibility-latency-too-high + expr: sum(rate(http_server_requests_seconds_sum{component="visibility"}[2m])) by (kubernetes_pod_name, method, outcome, status, component, kubernetes_namespace, uri)/sum(rate(http_server_requests_seconds_count{component="visibility"}[2m])) by (kubernetes_pod_name, method, outcome, status, component, kubernetes_namespace, uri) > 0.5 + for: 2m + labels: + severity: warning + annotations: + summary: Latency of the component {{ $labels.component }} in namespace {{$labels.kubernetes_namespace}} is high + description: "Latency of the component {{ $labels.component }} is {{ $value }} seconds for {{ $labels }}" +- name: kube-api-server-is-down rules: - - alert: KUBE_API_SERVER_DOWN + - alert: kube-api-server-down expr: up{job="kubernetes-apiservers"} == 0 for: 2m labels: @@ -340,3 +438,53 @@ groups: annotations: summary: Kube API Server job {{ $labels.job }} is down description: "Kubernetes API Server service went down LABELS = {{ $labels }}" +- name: autopilot-component-jvm-errors + rules: + - alert: jvm-memory-filling-up-for-oes-audit-client + expr: (sum by (instance, kubernetes_pod_name, component, kubernetes_namespace)(jvm_memory_used_bytes{app="oes", area="heap", component="auditclient"}) / sum by (instance, kubernetes_pod_name, component, kubernetes_namespace)(jvm_memory_max_bytes{app="oes", area="heap", component="auditclient"})) * 100 > 90 + for: 5m + labels: + severity: warning + annotations: + summary: JVM memory filling up for {{ $labels.component }} for pod {{ $labels.kubernetes_pod_name }} in namespace {{ $labels.kubernetes_namespace }}) + description: "JVM memory is filling up for {{ $labels.kubernetes_pod_name }} in namespace {{ $labels.kubernetes_namespace }} (> 80%)\n VALUE = {{ $value }}" + - alert: jvm-memory-filling-up-for-oes-autopilot + expr: (sum by (instance, kubernetes_pod_name, component, kubernetes_namespace)(jvm_memory_used_bytes{app="oes", area="heap", component="autopilot"}) / sum by (instance, kubernetes_pod_name, component, kubernetes_namespace)(jvm_memory_max_bytes{app="oes", area="heap", component="autopilot"})) * 100 > 90 + for: 5m + labels: + severity: warning + annotations: + summary: JVM memory filling up for {{ $labels.component }} for pod {{ $labels.kubernetes_pod_name }} in namespace {{ $labels.kubernetes_namespace }}) + description: "JVM memory is filling up for {{ $labels.kubernetes_pod_name }} in namespace {{ $labels.kubernetes_namespace }} (> 80%)\n VALUE = {{ $value }}" + - alert: jvm-memory-filling-up-for-oes-dashboard + expr: (sum by (instance, kubernetes_pod_name, component, kubernetes_namespace)(jvm_memory_used_bytes{app="oes", area="heap", component="dashboard"}) / sum by (instance, kubernetes_pod_name, component, kubernetes_namespace)(jvm_memory_max_bytes{app="oes", area="heap", component="autopilot"})) * 100 > 90 + for: 5m + labels: + severity: warning + annotations: + summary: JVM memory filling up for {{ $labels.component }} for pod {{ $labels.kubernetes_pod_name }} in namespace {{ $labels.kubernetes_namespace }}) + description: "JVM memory is filling up for {{ $labels.kubernetes_pod_name }} in namespace {{ $labels.kubernetes_namespace }} (> 80%)\n VALUE = {{ $value }}" + - alert: jvm-memory-filling-up-for-oes-platform + expr: (sum by (instance, kubernetes_pod_name, component, kubernetes_namespace)(jvm_memory_used_bytes{app="oes", area="heap", component="platform"}) / sum by (instance, kubernetes_pod_name, component, kubernetes_namespace)(jvm_memory_max_bytes{app="oes", area="heap", component="platform"})) * 100 > 90 + for: 5m + labels: + severity: warning + annotations: + summary: JVM memory filling up for {{ $labels.component }} for pod {{ $labels.kubernetes_pod_name }} in namespace {{ $labels.kubernetes_namespace }}) + description: "JVM memory is filling up for {{ $labels.kubernetes_pod_name }} in namespace {{ $labels.kubernetes_namespace }} (> 80%)\n VALUE = {{ $value }}" + - alert: jvm-memory-filling-up-for-oes-sapor + expr: (sum by (instance, kubernetes_pod_name, component, kubernetes_namespace)(jvm_memory_used_bytes{app="oes", area="heap", component="sapor"}) / sum by (instance, kubernetes_pod_name, component, kubernetes_namespace)(jvm_memory_max_bytes{app="oes", area="heap", component="sapor"})) * 100 > 90 + for: 5m + labels: + severity: warning + annotations: + summary: JVM memory filling up for {{ $labels.component }} for pod {{ $labels.kubernetes_pod_name }} in namespace {{ $labels.kubernetes_namespace }}) + description: "JVM memory is filling up for {{ $labels.kubernetes_pod_name }} in namespace {{ $labels.kubernetes_namespace }} (> 80%)\n VALUE = {{ $value }}" + - alert: jvm-memory-filling-up-for-oes-visibility + expr: (sum by (instance, kubernetes_pod_name, component, kubernetes_namespace)(jvm_memory_used_bytes{app="oes", area="heap", component="visibility"}) / sum by (instance, kubernetes_pod_name, component, kubernetes_namespace)(jvm_memory_max_bytes{app="oes", area="heap", component="visibility"})) * 100 > 90 + for: 5m + labels: + severity: warning + annotations: + summary: JVM memory filling up for {{ $labels.component }} for pod {{ $labels.kubernetes_pod_name }} in namespace {{ $labels.kubernetes_namespace }}) + description: "JVM memory is filling up for {{ $labels.kubernetes_pod_name }} in namespace {{ $labels.kubernetes_namespace }} (> 80%)\n VALUE = {{ $value }}" diff --git a/charts/oes/charts/spinnaker/templates/configmap/halyard-init-script.yaml b/charts/oes/charts/spinnaker/templates/configmap/halyard-init-script.yaml index 2c7de9e7..65ca3ceb 100755 --- a/charts/oes/charts/spinnaker/templates/configmap/halyard-init-script.yaml +++ b/charts/oes/charts/spinnaker/templates/configmap/halyard-init-script.yaml @@ -191,6 +191,38 @@ data: if [ -f /tmp/spinnaker/.hal/halyard.yaml ]; then cp /tmp/spinnaker/.hal/halyard.yaml /tmp/config fi + {{- if and (.Values.global.auth.saml) (.Values.global.commonGate.enabled) }} + kubectl get secret oes-gate-config -o jsonpath='{.data.*}' -n ${SPINNAKER_NAMESPACE} | base64 -d > /tmp/gate1.yml + oesuihost=$(yq e '.saml.redirectHostname' /tmp/gate1.yml) + oesuiurl={{ .Values.global.oesUI.protocol }}://$oesuihost + echo $oesuiurl + #yq e '.services.gate.baseUrl = "'$oesuiurl'"' /tmp/gate1.yml > /tmp/gate2.yml + #yq e '.services.gate.baseUrl = {{ .Values.global.oesUI.protocol }}:"'$oesuiurl'"' /tmp/gate1.yml > /tmp/gate2.yml + yq e '.services.gate.baseUrl = "'$oesuiurl'"' /tmp/gate1.yml > /tmp/gate2.yml + mv /tmp/gate2.yml /tmp/gate.yml + yq e '.deploymentConfigurations.[].security.apiSecurity.overrideBaseUrl = "'$oesuiurl'"' /tmp/spinnaker/.hal/config > /tmp/spinnaker/.hal/config1 + mv /tmp/spinnaker/.hal/config1 /tmp/spinnaker/.hal/config + yq e -j '.' /tmp/gate.yml > /tmp/saml.yml + jq '.saml |= . + {"metadataLocal": "encryptedFile:oesmetadataxml:oesmetadata.xml"} + {"serviceAddress": "'$oesuiurl'"} + {"keyStore": "encryptedFile:oessamljks:oessaml.jks"} + {"keyStorePassword":"encrypted:samljks-password:password"}' /tmp/saml.yml > /tmp/finalsaml.yml + #yq eval -P /tmp/saml1.yml > /tmp/saml2.yml + #yq e '.saml.serviceAddress = {{ .Values.global.oesUI.protocol }}:"'$oesuiurl'"' /tmp/saml2.yml > /tmp/finalsaml.yml + yq e -j '.saml' /tmp/finalsaml.yml > /tmp/delete.yml + yq eval -j 'del(.enabled) | del(.userSource) | del(.jksSecretName) | del(.metadataSecretName) | del(.metadataUrl) | del(.redirectBasePath)| del(.redirectHostname) | del(.redirectProtocol) | del(.redirectBasePath)' /tmp/delete.yml > /tmp/delete1.yml + replace=$(cat /tmp/delete1.yml) + yq e -j '.' /tmp/spinnaker/.hal/config > /tmp/spinnaker/.hal/config.json + jq --argjson toolConnectorParameteres ''"$replace"'' '.deploymentConfigurations[].security.authn.saml += $toolConnectorParameteres' /tmp/spinnaker/.hal/config.json > /tmp/spinnaker/.hal/config1.json + yq eval -P /tmp/spinnaker/.hal/config1.json > /tmp/spinnaker/.hal/finalconfig.json + mv /tmp/spinnaker/.hal/finalconfig.json /tmp/spinnaker/.hal/config + yq e '.deploymentConfigurations.[].security.authn.saml.enabled = "true"' /tmp/spinnaker/.hal/config > /tmp/spinnaker/.hal/config1 + mv /tmp/spinnaker/.hal/config1 /tmp/spinnaker/.hal/config + sleep 30s + kubectl delete secret oes-gate-config -n ${SPINNAKER_NAMESPACE} + kubectl create secret generic oes-gate-config --from-file=/tmp/gate.yml -n ${SPINNAKER_NAMESPACE} + kubectl delete pod -l component=gate -n ${SPINNAKER_NAMESPACE} + {{- else }} + yq e '.deploymentConfigurations.[].security.authn.saml.enabled = "false"' /tmp/spinnaker/.hal/config > /tmp/spinnaker/.hal/config1 + mv /tmp/spinnaker/.hal/config1 /tmp/spinnaker/.hal/config + {{- end }} {{- end }} # git or stash {{- end }} # Enabled diff --git a/charts/oes/config/oes-audit/audit-client-local.yaml b/charts/oes/config/oes-audit/audit-client-local.yaml index 4328886b..3ba5d15c 100644 --- a/charts/oes/config/oes-audit/audit-client-local.yaml +++ b/charts/oes/config/oes-audit/audit-client-local.yaml @@ -19,3 +19,12 @@ feign: visibilityservice: name: visibilityservice url: http://oes-visibility:8096 + +fixedDelay: + in: + milliseconds: 120000 +initialDelay: + in: + milliseconds: 300000 +scheduler: + threads: 16 diff --git a/charts/oes/config/oes-audit/audit-local.yaml b/charts/oes/config/oes-audit/audit-local.yaml index b00c48c9..0325ef2a 100644 --- a/charts/oes/config/oes-audit/audit-local.yaml +++ b/charts/oes/config/oes-audit/audit-local.yaml @@ -6,6 +6,14 @@ spring: logging: level: com.opsmx.auditservice: INFO +message-broker: + enabled: true + username: '{{ .Values.rabbitmq.username }}' + password: '{{ .Values.rabbitmq.password }}' + host: rabbitmq-service + port: {{ .Values.rabbitmq.port }} + endpoint: + name: rabbitmq standardErrorCodes: filePath: /opsmx/conf/standard-error-code.csv feign: diff --git a/charts/oes/config/oes-gate/gate.yml b/charts/oes/config/oes-gate/gate.yml index 245a80ed..2c34228c 100644 --- a/charts/oes/config/oes-gate/gate.yml +++ b/charts/oes/config/oes-gate/gate.yml @@ -35,7 +35,7 @@ services: clouddriver: host: 0.0.0.0 port: 7002 - baseUrl: http://spin-clouddriver-rw.spinnaker:7002 + baseUrl: http://spin-clouddriver-rw:7002 enabled: true clouddriverCaching: host: 0.0.0.0 diff --git a/charts/oes/config/oes-platform/platform-local.yml b/charts/oes/config/oes-platform/platform-local.yml index 5f566602..77be5bce 100644 --- a/charts/oes/config/oes-platform/platform-local.yml +++ b/charts/oes/config/oes-platform/platform-local.yml @@ -20,15 +20,14 @@ supportedFeatures: {{ toYaml .Values.platform.config.supportedFeatures | indent 2 }} userGroup: superAdminGroups: {{ .Values.platform.config.adminGroups }} -app: - dashboard: - adminuser: {{ .Values.platform.config.app.dashboard.adminuser }} # mandatory to provide admin user name to run admin jobs that compute dashboard counts fixedDelay: - in: - milliseconds: 120000 + in: + milliseconds: 120000 initialDelay: - in: - milliseconds: 600000 + in: + Milliseconds: 300000 +scheduler: + workerThreads: 50 user: {{- if .Values.gate.config.saml.enabled }} source: {{ .Values.gate.config.saml.userSource }} @@ -55,6 +54,12 @@ oes: url: http://oes-visibility:8096 auditclient: url: http://oes-audit-client:8098 + policyGate: + url: "{{ .Values.global.oesUI.protocol }}://{{ .Values.global.oesUI.host }}/gate" + path: /v1/data/ + ui: + # Ex: "https://oes-poc.dev.opsmx.org/" + url: "{{ .Values.global.oesUI.protocol }}://{{ .Values.global.oesUI.host }}/ui" gate: url: http://oes-gate:8084 approvalGate: diff --git a/charts/oes/config/oes-sapor/application.yml b/charts/oes/config/oes-sapor/application.yml index 96b0d49f..f212b837 100644 --- a/charts/oes/config/oes-sapor/application.yml +++ b/charts/oes/config/oes-sapor/application.yml @@ -6,6 +6,15 @@ spring: password: '{{ .Values.db.password }}' {{- end }} +message-broker: + enabled: true + username: '{{ .Values.rabbitmq.username }}' + password: '{{ .Values.rabbitmq.password }}' + host: rabbitmq-service + port: {{ .Values.rabbitmq.port }} + endpoint: + name: rabbitmq + standardErrorCodes: filePath: /opsmx/conf/standard-error-code.csv diff --git a/charts/oes/config/oes-ui/help-text.json b/charts/oes/config/oes-ui/help-text.json index 6d023b07..ab1c59c6 100644 --- a/charts/oes/config/oes-ui/help-text.json +++ b/charts/oes/config/oes-ui/help-text.json @@ -1,2938 +1,3035 @@ { - "POLICY_LISTING": { - "HEADER": "Policies not found!", - "BODY": "
The Policy Management feature allows you to create policies to set stringent guidelines for safe and fine grained controls in a CI/CD pipeline. This feature gives you to set guard rails by declaring specific policy rules or guidelines. For e.g., Automated Testing should be completed before deployment is a rule which must be met when creating a CI/CD pipeline.

Static Policy lets users validate the conditions while creating the pipelines, whereas Runtime Policy enables users for automated decision making during pipeline execution.

A policy defines a set of conditions that needs to be checked. As an example, a policy could be created to define a blackout window period (or a moratorium period) for performing production deployments. A moratorium period defines the time period within which no production deployments should be performed. Any deployment to the production environment during this period will automatically be rejected/stopped, if that deployment is triggered during the moratorium period.

Autopilot uses Open Policy Engine(OPA) for policy definition & execution. OPA is a open source, general-purpose policy engine that unifies policy enforcement across the stack. It uses a high-level declarative language called Rego that lets you specify policy as code and simple APIs to offload policy decision-making from your software.

Click on New Policy button to create a new policy.
" - }, - "AGENT_LISTING": { - "HEADER": "No Agents found!", - "BODY": "

The Agent allows Spinnaker installations to reach through firewalls in a secure manner,allowing access to private Kubernetes clusters as well as reach internal services such as Jenkins and Artifactory. The agent is typically used with OpsMx's SaaS Spinnaker offering, where OpsMx hosts the Spinnaker installation, but services used by Spinnaker are within a secure area owned by the customer.One of the core advantages of using an agent is that the credentials do not need to be provided to anyone i.e.credentials remain with - in the cluster where deployment is done.

The Agent is a two part system: a Controller runs near Spinnaker, and the Agent runs in the target secure cluster.The Agent is configured to communicate with specific services(Kubernetes, Jenkins etc) within a customer 's security domain, while the Controller is in Spinnaker's domain.

The Agent is deployed with a manifest provided by OpsMx.This manifest has per - installation credentials to authenticate to the controller,controller address etc.Services are configured in the Agent by the customer.URL endpoints.Spinnaker account names and credentials are specified to the agent configuration using a service configuration.The credentials never leave the agent.

New Agent button is enabled when Spinnaker is configured in Setup->Spinnaker. Click on New Agent to create the Agent for your environment.

" - }, - "AGENT_CREATION": { - "HEADER": "Agent", - "BODY": "

Adding an agent involves the following steps:

  • Enter the details (Agent Name, Cluster Name and Description) and click save
  • Click Download Manifest which appears after save
  • In the remote Kubernetes cluster, create service configmap in the default namespace. Examples are available here
  • Apply the downloaded manifest in the default namespace using kubectl apply -f <downloaded file> Note that the agent should be able to reach the LB configured with agent-grpc service
  • Check the Setup->Agent screen for the agent connection status
", - "AGENT_NAME": { - "TOOLTIP": "Name of the agent with which it will referred to", - "VALIDATION_MESSAGE": { - "required": "Agent Name cannot be empty", - "cannotContainSpace": "Agent Name cannot contain space", - "noSpecialCharacters": "Allowed special character is '-'", - "startingFromNumber": "Agent Name should not start with number", - "agentNameExist": "Agent Name already exists" - } - }, + "POLICY_LISTING": { + "HEADER": "Policies not found!", + "BODY": "
The Policy Management feature allows you to create policies to set stringent guidelines for safe and fine grained controls in a CI/CD pipeline. This feature gives you to set guard rails by declaring specific policy rules or guidelines. For e.g., Automated Testing should be completed before deployment is a rule which must be met when creating a CI/CD pipeline.

Static Policy lets users validate the conditions while creating the pipelines, whereas Runtime Policy enables users for automated decision making during pipeline execution.

A policy defines a set of conditions that needs to be checked. As an example, a policy could be created to define a blackout window period (or a moratorium period) for performing production deployments. A moratorium period defines the time period within which no production deployments should be performed. Any deployment to the production environment during this period will automatically be rejected/stopped, if that deployment is triggered during the moratorium period.

Autopilot uses Open Policy Engine(OPA) for policy definition & execution. OPA is a open source, general-purpose policy engine that unifies policy enforcement across the stack. It uses a high-level declarative language called Rego that lets you specify policy as code and simple APIs to offload policy decision-making from your software.

Click on New Policy button to create a new policy.
" + }, + "AGENT_LISTING": { + "HEADER": "No Agents found!", + "BODY": "

The Agent allows Spinnaker installations to reach through firewalls in a secure manner,allowing access to private Kubernetes clusters as well as reach internal services such as Jenkins and Artifactory. The agent is typically used with OpsMx's SaaS Spinnaker offering, where OpsMx hosts the Spinnaker installation, but services used by Spinnaker are within a secure area owned by the customer.One of the core advantages of using an agent is that the credentials do not need to be provided to anyone i.e.credentials remain with - in the cluster where deployment is done.

The Agent is a two part system: a Controller runs near Spinnaker, and the Agent runs in the target secure cluster.The Agent is configured to communicate with specific services(Kubernetes, Jenkins etc) within a customer 's security domain, while the Controller is in Spinnaker's domain.

The Agent is deployed with a manifest provided by OpsMx.This manifest has per - installation credentials to authenticate to the controller,controller address etc.Services are configured in the Agent by the customer.URL endpoints.Spinnaker account names and credentials are specified to the agent configuration using a service configuration.The credentials never leave the agent.

New Agent button is enabled when Spinnaker is configured in Setup->Spinnaker. Click on New Agent to create the Agent for your environment.

" + }, + "AGENT_CREATION": { + "HEADER": "Agent", "BODY": "

The Agent allows Spinnaker installations to reach through firewalls in a secure manner,allowing access to private Kubernetes clusters as well as reach internal services such as Jenkins and Artifactory.

Adding an agent involves the following steps:

  • Enter the details (Agent Name, Cluster Name and Description) and click save
  • Click Download Manifest which appears after save
  • In the remote Kubernetes cluster, create service configmap in the default namespace. Examples are available here
  • Apply the downloaded manifest in the default namespace using kubectl apply -f <downloaded file> Note that the agent should be able to reach the LB configured with agent-grpc service
  • Check the Setup->Agent screen for the agent connection status
", + "AGENT_NAME": { + "TOOLTIP": "Name of the agent with which it will referred to", + "VALIDATION_MESSAGE": { + "required": "Agent Name cannot be empty", + "cannotContainSpace": "Agent Name cannot contain space", + "noSpecialCharacters": "Allowed special character is '-'", + "startingFromNumber": "Agent Name should not start with number", + "agentNameExist": "Agent Name already exists" + } + }, "CLUSTER_NAME": { - "TOOLTIP": "Name of the remote cluster on which agent will be installed on", - "VALIDATION_MESSAGE": { - "required": "Cluster Name cannot be empty", - "cannotContainSpace": "Cluster Name cannot contain space", - "noSpecialCharacters": "Allowed special character is '-'", - "startingFromNumber": "Cluster Name should not start with number" - } - }, - "DESCRIPTION": { - "TOOLTIP": "Short description about the agent", - "VALIDATION_MESSAGE": {} - }, - "CONNECT_TO_SPINNAKER": { - "TOOLTIP": "The spinnaker instance you want to associate this account to", - "VALIDATION_MESSAGE": { - "required": "Please select Spinnaker" - } - } - }, - "CLOUDPROVIDER_LISTING": { - "HEADER": "No Cloud Providers found!", - "BODY": "

Providers are integrations to Cloud platforms you deploy your applications to.

In this section, you’ll register credentials for your Cloud platforms. Those credentials are known as Accounts. Autopilot allows you to create & manage Accounts for different Spinnaker Cloud Providers such as AWS, GCP, Kubernetes, etc.

When Spinnaker is configured for Direct Sync, New Accounts button will not be visible.

New Accounts button will be enabled when Spinnaker is configured to use External Accounts in Setup->Spinnaker. Click on New Accounts button to create an account for your cloud provider. You can create multiple accounts for the same provider.

Click on Sync Spinnaker Accounts button to sync Cloud Provider accounts with Spinnaker.

" - }, - "CLOUDPROVIDER_CREATION": { - "HEADER": "Cloud Provider", - "BODY": "

In this page, you can create & manage Accounts for different Spinnaker Cloud Providers.

", - "AGENT_NAME": { - "TOOLTIP": "", - "VALIDATION_MESSAGE": { - "required": "Agent name cannot be empty", - "cannotContainSpace": "Agent name cannot contain space", - "noSpecialCharacters": "Allowed special character are ',-'" - } - }, - "CLOUD_PROVIDER": { - "TOOLTIP": "The cloud provider type for which you want to add the account", - "VALIDATION_MESSAGE": { - "required": "Please select Cloud Provider" - } - }, - "SPINNAKER": { - "TOOLTIP": "The Spinnaker instance with which this account would be tied to", - "VALIDATION_MESSAGE": { - "required": "Please select Spinnaker" - } - }, - "ENVIRONMENT": { - "TOOLTIP": "The environment name for the account. Many accounts can share the same environment (e.g. dev, test, prod)", - "VALIDATION_MESSAGE": { - "required": "Please select Environment" - } - }, - "CUSTOM_ENVIRONMENT": { - "TOOLTIP": "", - "VALIDATION_MESSAGE": { - "noSpecialCharacters": "Environment Name cannot contain special characters", - "cannotContainSpace":"Environment Name cannot contain space", - "required":"Environment Name cannot be empty", - "startingFromNumber": "Environment Name cannot start with number", - "maxlength": "Environment name should not have more than 63 characters!", - "exists": "Environment name already exists" - } - }, - "ACCOUNT_NAME": { - "TOOLTIP": "Name of the account to operate on", - "VALIDATION_MESSAGE": { - "required": "Account name cannot be empty", - "cannotContainSpace": "Account name cannot contain space", - "noSpecialCharacters": "Allowed special character is '-'" - } - }, - "NAMESPACE": { - "TOOLTIP": "A list of namespaces this Spinnaker account can deploy to and will cache (namespaces should be 'coma' separated ex: default,dev", - "VALIDATION_MESSAGE": { - "required": "Namespace cannot be empty", - "cannotContainSpace": "Namespace cannot contain space", - "noSpecialCharacters": "Special characters not allowed except ',-'" - } - }, - "UPLOAD_KUBECONFIG_FILE": { - "TOOLTIP": "The path to your kubeconfig file. By default, it will be under the Spinnaker user’s home directory in the typical .kube/config location.", - "VALIDATION_MESSAGE": { - "required": "File cannot be empty" - } - }, - "READ": { - "TOOLTIP": "A user must have at least one of these roles in order to view this account’s cloud resources.", - "VALIDATION_MESSAGE": { - "cannotContainSpace": "Read Permissions cannot contain space" - } - }, - "WRITE": { - "TOOLTIP": "A user must have at least one of these roles in order to make changes to this account’s cloud resources", - "VALIDATION_MESSAGE": { - "cannotContainSpace": "Write Permissions cannot contain space" - } - }, - "EXECUTE": { - "TOOLTIP": "", - "VALIDATION_MESSAGE": { - "cannotContainSpace": "Execute Permissions cannot contain space" - } - }, - "ACCOUNT_ID": { - "TOOLTIP": "Your AWS account ID to manage. Refer http://docs.aws.amazon.com/IAM/latest/UserGuide/console_account-alias.html for more information", - "VALIDATION_MESSAGE": { - "required": "Account Id cannot be empty", - "cannotContainSpace": "Account Id cannot contain space" - } - }, - "ROLE": { - "TOOLTIP": "If set, Halyard will configure a credentials provider that uses AWS Security Token Service to assume the specified role", - "VALIDATION_MESSAGE": { - "required": "Role cannot be empty", - "cannotContainSpace": "Role cannot contain space" - } - }, - "REGIONS": { - "TOOLTIP": "The AWS regions this Spinnaker account will manage", - "VALIDATION_MESSAGE": { - "required": "Region cannot be empty", - "cannotContainSpace": "Region cannot contain space" - } - }, - "PRIMARY_ACCOUNT": { - "TOOLTIP": "Whether this account is the primary account? If yes then provide the access & secret key details.", - "VALIDATION_MESSAGE": {} - }, - "ACCESS_KEY": { - "TOOLTIP": "The default access key used to communicate with AWS", - "VALIDATION_MESSAGE": { - "required": "Access key cannot be empty" - } - }, - "ACCESS_KEY_BAKERY": { - "TOOLTIP": "The default access key used for AWS bakery configuration", - "VALIDATION_MESSAGE": { - "required": "Access Key (Bakery) cannot be empty" - } + "TOOLTIP": "Name of the remote cluster on which agent will be installed on", + "VALIDATION_MESSAGE": { + "required": "Cluster Name cannot be empty", + "cannotContainSpace": "Cluster Name cannot contain space", + "noSpecialCharacters": "Allowed special character is '-'", + "startingFromNumber": "Cluster Name should not start with number" + } + }, + "DESCRIPTION": { + "TOOLTIP": "Short description about the agent", + "VALIDATION_MESSAGE": {} + }, + "CONNECT_TO_SPINNAKER": { + "TOOLTIP": "The spinnaker instance you want to associate this account to", + "VALIDATION_MESSAGE": { + "required": "Please select Spinnaker" + } + } + }, + "CLOUDPROVIDER_LISTING": { + "HEADER": "No Cloud Targets found!", + "BODY": "

Providers are integrations to Cloud platforms you deploy your applications to.

In this section, you’ll register credentials for your Cloud platforms. Those credentials are known as Accounts. Autopilot allows you to create & manage Accounts for different Spinnaker Cloud Targets such as AWS, GCP, Kubernetes, etc.

When Spinnaker is configured for Direct Sync, New Accounts button will not be visible.

New Accounts button will be enabled when Spinnaker is configured to use External Accounts in Setup->Spinnaker. Click on New Accounts button to create an account for your cloud provider. You can create multiple accounts for the same provider.

Click on Sync Spinnaker Accounts button to sync Cloud Target accounts with Spinnaker.

" + }, + "CLOUDPROVIDER_CREATION": { + "HEADER": "Cloud Target", + "BODY": "

In this page, you can create & manage Accounts for different Spinnaker Cloud Targets.

", + "AGENT_NAME": { + "TOOLTIP": "", + "VALIDATION_MESSAGE": { + "required": "Agent name cannot be empty", + "cannotContainSpace": "Agent name cannot contain space", + "noSpecialCharacters": "Allowed special character are ',-'" + } + }, + "CLOUD_PROVIDER": { + "TOOLTIP": "The cloud provider type for which you want to add the account", + "VALIDATION_MESSAGE": { + "required": "Please select Cloud Target" + } + }, + "SPINNAKER": { + "TOOLTIP": "The Spinnaker instance with which this account would be tied to", + "VALIDATION_MESSAGE": { + "required": "Please select Spinnaker" + } + }, + "ENVIRONMENT": { + "TOOLTIP": "The environment name for the account. Many accounts can share the same environment (e.g. dev, test, prod)", + "VALIDATION_MESSAGE": { + "required": "Please select Environment" + } + }, + "CUSTOM_ENVIRONMENT": { + "TOOLTIP": "", + "VALIDATION_MESSAGE": { + "noSpecialCharacters": "Environment Name cannot contain special characters", + "cannotContainSpace": "Environment Name cannot contain space", + "required": "Environment Name cannot be empty", + "startingFromNumber": "Environment Name cannot start with number", + "maxlength": "Environment name should not have more than 63 characters!", + "exists": "Environment name already exists" + } + }, + "ACCOUNT_NAME": { + "TOOLTIP": "Name of the account to operate on", + "VALIDATION_MESSAGE": { + "required": "Account name cannot be empty", + "cannotContainSpace": "Account name cannot contain space", + "noSpecialCharacters": "Allowed special character is '-'" + } + }, + "NAMESPACE": { + "TOOLTIP": "A list of namespaces this Spinnaker account can deploy to and will cache (namespaces should be 'coma' separated ex: default,dev", + "VALIDATION_MESSAGE": { + "required": "Namespace cannot be empty", + "cannotContainSpace": "Namespace cannot contain space", + "noSpecialCharacters": "Special characters not allowed except ',-'" + } + }, + "UPLOAD_KUBECONFIG_FILE": { + "TOOLTIP": "The path to your kubeconfig file. By default, it will be under the Spinnaker user’s home directory in the typical .kube/config location.", + "VALIDATION_MESSAGE": { + "required": "File cannot be empty" + } + }, + "READ": { + "TOOLTIP": "A user must have at least one of these roles in order to view this account’s cloud resources.", + "VALIDATION_MESSAGE": { + "cannotContainSpace": "Read Permissions cannot contain space" + } + }, + "WRITE": { + "TOOLTIP": "A user must have at least one of these roles in order to make changes to this account’s cloud resources", + "VALIDATION_MESSAGE": { + "cannotContainSpace": "Write Permissions cannot contain space" + } + }, + "EXECUTE": { + "TOOLTIP": "", + "VALIDATION_MESSAGE": { + "cannotContainSpace": "Execute Permissions cannot contain space" + } + }, + "ACCOUNT_ID": { + "TOOLTIP": "Your AWS account ID to manage. Refer http://docs.aws.amazon.com/IAM/latest/UserGuide/console_account-alias.html for more information", + "VALIDATION_MESSAGE": { + "required": "Account Id cannot be empty", + "cannotContainSpace": "Account Id cannot contain space" + } + }, + "ROLE": { + "TOOLTIP": "If set, Halyard will configure a credentials provider that uses AWS Security Token Service to assume the specified role", + "VALIDATION_MESSAGE": { + "required": "Role cannot be empty", + "cannotContainSpace": "Role cannot contain space" + } + }, + "REGIONS": { + "TOOLTIP": "The AWS regions this Spinnaker account will manage", + "VALIDATION_MESSAGE": { + "required": "Region cannot be empty", + "cannotContainSpace": "Region cannot contain space" + } + }, + "PRIMARY_ACCOUNT": { + "TOOLTIP": "Whether this account is the primary account? If yes then provide the access & secret key details.", + "VALIDATION_MESSAGE": {} + }, + "ACCESS_KEY": { + "TOOLTIP": "The default access key used to communicate with AWS", + "VALIDATION_MESSAGE": { + "required": "Access key cannot be empty" + } + }, + "ACCESS_KEY_BAKERY": { + "TOOLTIP": "The default access key used for AWS bakery configuration", + "VALIDATION_MESSAGE": { + "required": "Access Key (Bakery) cannot be empty" + } + }, + "SECRET_KEY": { + "TOOLTIP": "The secret key used to communicate with AWS", + "VALIDATION_MESSAGE": { + "required": "Secret key cannot be empty" + } + }, + "SECRET_KEY_BAKERY": { + "TOOLTIP": "The default secret key used for AWS baskery configuration", + "VALIDATION_MESSAGE": { + "required": "Secret Key (Bakery) cannot be empty" + } + }, + "APP_KEY": { + "TOOLTIP": "The appKey (password) of your service principal", + "VALIDATION_MESSAGE": { + "required": "App key cannot be empty", + "cannotContainSpace": "App key cannot contain space" + } + }, + "CLIENT_ID": { + "TOOLTIP": "The clientId (also called appId) of your service principal", + "VALIDATION_MESSAGE": { + "required": "Client Id cannot be empty", + "cannotContainSpace": "Client Id cannot contain space" + } + }, + "DEFAULT_KEYVALUT": { + "TOOLTIP": "The name of a KeyVault that contains the user name, password, and ssh public key used to create VMs", + "VALIDATION_MESSAGE": { + "required": "Default Keyvault cannot be empty", + "cannotContainSpace": "Default Keyvault cannot contain space" + } + }, + "SUBSCRIPTION_ID": { + "TOOLTIP": "The subscriptionId that your service principal is assigned to", + "VALIDATION_MESSAGE": { + "required": "Subscription Id cannot be empty", + "cannotContainSpace": "Subscription Id cannot contain space" + } + }, + "TENANT_ID": { + "TOOLTIP": "The tenantId that your service principal is assigned to", + "VALIDATION_MESSAGE": { + "required": "Tenant Id cannot be empty", + "cannotContainSpace": "Tenant Id cannot contain space" + } + }, + "GCP_FILE": { + "TOOLTIP": "The path to a JSON service account that Spinnaker will use as credentials. This is only needed if Spinnaker is not deployed on a Google Compute Engine VM, or needs permissions not afforded to the VM it is running on. Refer https://cloud.google.com/compute/docs/access/service-accounts for more information", + "VALIDATION_MESSAGE": { + "required": "File cannot be empty" + } + }, + "AWS_ACCOUNT_NAME": { + "TOOLTIP": "", + "VALIDATION_MESSAGE": { + "required": "Please Select AWS Account" + } + } + }, + "SPINNAKER_LISTING": { + "HEADER": "No Spinnaker Configured!", + "BODY": "

The Spinnaker Setup tab allows you to setup a Spinnaker instance with which you can connect Autopilot and sync all the applications from Spinnaker.

GitOps style Spinnaker is suported where in all configuration is maintained in a repository such as git. These optional sections help configure gitOps style Spinnaker:

Source Control for Accounts: In this section, you can specify the repository for External configuration in CD Integration

Source Control for Pipeline:In this section, you can specify the repository for pipeline gitOps in Spinnaker that allows you to save and restore pipelines from a git repository.

Click on the Add CD Integration button to add Spinnaker instance

" + }, + "SPINNAKER_SETUP": { + "HEADER": "Spinnaker", + "BODY": "

In this page you can add / update your Spinnaker instance.

Fields:

  • Spinnaker Name: User defined name for Spinnaker instance.
    Example: opsmx-spinnaker
  • Spinnaker Gate URL: Gate URL of the Spinnaker instance.
    Example: https://spinnaker-gate.xyz.com or http://oes-gate:8084
  • Authentication Type:: Can be LDAP or X509
  • Token: This is used when Authentication Type is LDAP; username & password to LDAP server separated by ':' in base64 format; Output of 'echo -ne 'username:password' | base64 -w0'
  • Password: This is used when Authentication Type is LDAP; Password for P12 File
  • P12 File: This is used when Authentication Type is X509; P12 File needed for X509/AD Authentication
  • Source Control for Accounts: In this section, you can specify the repository for External configuration in Spinnaker
  • Source Control for Pipeline: In this section, you can specify the repository for pipeline gitOps in Spinnaker that allows you to save and restore pipelines from a git repository
", + "SPINNAKER_NAME": { + "TOOLTIP": "Name of the Spinnaker instance", + "VALIDATION_MESSAGE": { + "required": "Spinnaker Name cannot be empty", + "cannotContainSpace": "Spinnaker Name cannot contain space", + "noSpecialCharacters": "Allowed special character is '-'", + "startingFromNumber": "Spinnaker Name should not start with number" + } + }, + "SPINNAKER_GATE_URL": { + "TOOLTIP": "Gate Url of the Spinnaker instance", + "VALIDATION_MESSAGE": { + "required": "Spinnaker Gate URL cannot be empty", + "cannotContainSpace": "Spinnaker Gate URL cannot contain space", + "invalidUrl": "Spinnaker Gate URL is invalid" + } + }, + "AUTHENTICATION_TYPE": { + "TOOLTIP": "Select the type of authentication for the spinnaker being added", + "VALIDATION_MESSAGE": { + "required": "Please select Authentication Type" + } + }, + "LDAP_USERNAME": { + "TOOLTIP": "User Name", + "VALIDATION_MESSAGE": { + "required": "User Name cannot be empty", + "minlength": "User Name should be more than 4 characters" + } + }, + "LDAP_PASSWORD": { + "TOOLTIP": "Password", + "VALIDATION_MESSAGE": { + "required": "Password cannot be empty", + "minlength": "Password should be more than 8 characters" + } + }, + "TOKEN": { + "TOOLTIP": "Token for Spinnaker authentication", + "VALIDATION_MESSAGE": { + "required": "Token cannot be empty", + "minlength": "Token should be more than 8 characters" + } + }, + "PASSWORD": { + "TOOLTIP": "Password", + "VALIDATION_MESSAGE": { + "required": "Password cannot be empty", + "minlength": "Password should be more than 8 characters" + } + }, + "P12_FILE": { + "TOOLTIP": "P12 File", + "VALIDATION_MESSAGE": { + "required": "P12 File cannot be empty" + } + }, + "SYNC_ACCOUNTS": { + "TOOLTIP": "Select Mode of synchronisation of Cloud Targets between Autopilot & Spinnaker", + "VALIDATION_MESSAGE": { + "required": "Please select Sync Accounts type" + } + }, + "ACCOUNTS_PROVIDER": { + "TOOLTIP": "Source Control for Halyard Configuration and / or External Account Configuration", + "VALIDATION_MESSAGE": { + "required": "Please select provider" + } + }, + "ACCOUNTS_ACCOUNT_NAME": { + "TOOLTIP": "Account name of the Source Control", + "VALIDATION_MESSAGE": { + "required": "Please select Account Name" + } + }, + "ACCOUNTS_REPOSITORY": { + "TOOLTIP": "Repository name with full path in the selected Source Control Eg., https://github.com/OpsMx/Opsmx-Saas.git", + "VALIDATION_MESSAGE": { + "required": "Repository cannot be empty", + "cannotContainSpace": "Repository cannot contain space", + "invalidUrl": "Repository is invalid" + } + }, + "ACCOUNTS_SOURCE_PATH": { + "TOOLTIP": "Existing path in the repository", + "VALIDATION_MESSAGE": {} + }, + "ACCOUNTS_REGION": { + "TOOLTIP": "The AWS regions this Spinnaker account will manage", + "VALIDATION_MESSAGE": { + "required": "Region cannot be empty", + "cannotContainSpace": "Region cannot contain space", + "startingFromNumber": "Region should not start with number" + } + }, + "ACCOUNTS_BUCKET_NAME": { + "TOOLTIP": "Bucket Name", + "VALIDATION_MESSAGE": { + "required": "Bucket Name cannot be empty", + "cannotContainSpace": "Bucket Name cannot contain space", + "startingFromNumber": "Bucket Name should not start with number" + } + }, + "PIPELINE_PROVIDER": { + "TOOLTIP": "Use this Spinnaker for pipeline promotion.", + "VALIDATION_MESSAGE": { + "required": "Please select provider" + } + }, + "PIPELINE_ACCOUNT_NAME": { + "TOOLTIP": "", + "VALIDATION_MESSAGE": { + "required": "Please select Account Name" + } + }, + "PIPELINE_REPOSITORY": { + "TOOLTIP": "", + "VALIDATION_MESSAGE": { + "required": "Repository cannot be empty", + "cannotContainSpace": "Repository cannot contain space", + "invalidUrl": "Repository is invalid" + } + }, + "PIPELINE_SOURCE_PATH": { + "TOOLTIP": "Existing path in the repository", + "VALIDATION_MESSAGE": {} + }, + "PIPELINE_REGION": { + "TOOLTIP": "", + "VALIDATION_MESSAGE": { + "required": "Region cannot be empty", + "cannotContainSpace": "Region cannot contain space", + "startingFromNumber": "Region should not start with number" + } + }, + "PIPELINE_BUCKET_NAME": { + "TOOLTIP": "Bucket Name", + "VALIDATION_MESSAGE": { + "required": "Bucket Name cannot be empty", + "cannotContainSpace": "Bucket Name cannot contain space", + "startingFromNumber": "Bucket Name should not start with number" + } + } + }, + "INTEGRATOR_LISTING": { + "HEADER": "No Integrator found!", + "BODY": "

Autopilot offers integration with many CI/CD Tools. Integrations are grouped under the following categories - Artifact, CI, Governance, Monitoring Tools, Notifications, Policy and SAST/DAST.

Integrations are used to

  • pull logs & metrics for Continuous Verification
  • pull meta data from CI/CD Tools for Informed Approvals
  • enforce organizational policies at the time of creating or executing a pipeline.
  • configure integrations in Spinnaker for Artifacts, Notifications. etc

Click on the New Integration button to add accounts for your CI/CD tools

", + "SYNC_SPINNAKER_ACCOUNTS": { + "TOOLTIP": "Push Integration changes to Spinnaker", + "VALIDATION_MESSAGE": "" + } + }, + "PIPELINE_EXECUTION_AUDIT_LISTING": { + "HEADER": "Pipeline executions not found!", + "BODY": "
This page shows pipeline executions coming from a CD Tool such as Spinnaker in a list view. It also contains the summary view showing the total number of Pipeline Runs, Successful Runs, Failed Runs, Cancelled Runs.

Only important fields including Application, Service, Pipeline, Status, Start Time and End Time are shown by default. Additional fields can be enabled using the Hamburger menu towars the right corner.

Ensure that the Spinnaker is already connected under Setup -> CD Integration. Pipeline executions will start appearing in this page after establishing connection to Spinnaker.
", + "TOOLTIP": { + "EXECUTION_DATA": "Pipeline is in Running State", + "CONNECTOR_DATA": "Pipeline is in Running State", + "STAGE_DURATION": "Pipeline is in Running State" + }, + "VALIDATION_MESSAGE": { + "STAGE_DURATION": "No Data available to view Stage Duration", + "PIPELINE_NOT_EXISTS" : "Execution details not found. Pipeline associated with this execution is deleted" + } + }, + "PIPELINE_AUDIT_LISTING": { + "HEADER": "Pipeline updates not found!", + "BODY": "
This page shows pipeline updates coming from a CD Tool such as Spinnaker in a list view.
Ensure that the Spinnaker is already connected under Setup -> CD Integration. Pipeline updates will start appearing in this page after establishing connection to Spinnaker.
" + }, + "POLICY_AUDIT_LISTING": { + "HEADER": "Policy updates / executions not found!", + "BODY": "
This page shows policy updates and policy executions, along with allowed/denied information, in a list view. Possible uses, apart from audit and compliance, includes helping users understand the policies that they might be inadvertently trying to break.

For policy updates, ensure that a policy is created/updated under Setup -> Policies. For policy execution events, please add a policy in a pipeline and execute it.
" + }, + "POLICY_CREATION": { + "BODY": "

In this page, you can define & manage policies.

Fields:

  • Name: User defined name for the policy
  • Policy Type: Static or Runtime Policy
  • Policy Engine: Policy Engine to be used; currently, only OPA is supported
  • Policy Engine Account: Policy Engine Account for the Credentials
  • Policy File: File containing the Policy You can upload the file by clicking on Choose File button. This is optional. If not present, you can enter the policy directly in the Policy Details field
  • Policy Details: Policy definition
  • Policy Permissions: Enable/disable access to the policy in Autopilot to specific usergroup
", + "HEADER": "Policy", + "NAME": { + "TOOLTIP": "Policy Name", + "VALIDATION_MESSAGE": { + "required": "Name cannot be empty", + "cannotContainSpace": "Name cannot contain space", + "exists": "Name already exists" + } + }, + "POLICY_DETAILS": { + "TOOLTIP": "Policy Details", + "VALIDATION_MESSAGE": { + "required": "Policy Details cannot be empty" + } + }, + "POLICY_ENGINE": { + "TOOLTIP": "Supported Policy Account Types", + "VALIDATION_MESSAGE": { + "required": "Please select Policy Account Type" + } + }, + "POLICY_ENGINE_ACCOUNT": { + "TOOLTIP": "Policy Account Names", + "VALIDATION_MESSAGE": { + "required": "Please select Policy Engine Account" + } + }, + "POLICY_TYPE": { + "TOOLTIP": "A static policy lets users validate conditions before the start of execution, whereas a Runtime policy enables users for automated decision making during execution.", + "VALIDATION_MESSAGE": { + "required": "Please select Policy Engine Type" + } + }, + "POLICY_DESCRIPTION": { + "TOOLTIP": "Policy Description" + }, + "POLICY_FILE": { + "TOOLTIP": "Policy File" + } + }, + "VERIFICATION": { + "HEADER": "Verfication Gate executions not found!", + "BODY": "

The Continuous Verification performs automated log and metrics analysis for new releases with built-in unsupervised and supervised machine learning algorithms for risk analysis and canary deployments.

Continuous Verification is a release verification process that provides Dev and Ops engineers an intelligent automated real-time actionable risk assessment of a new release deployed. The Continuous Verification verifies the latest version of the service comparing to the baseline or prior release after production rollout. The baseline can be a deployment done prior or the current deployment during rollout using canary or blue/green or rolling update strategies.

It leverages unsupervised and supervised machine learning techniques to analyze 100s of metrics and logs data to perform in-depth analysis of architectural regressions, performance, scalability and security violations of new releases in a scalable way for enterprises.

Autopilot provides a Verification Gate to analyse logs from your Target Application and this can be inserted as a Stage in your CI/CD Pipeline.Note that one must configure the metric and log datasources, such as Prometheus and Elastic before using this functionality.

This page shows Verification Gate executions in a list view.

Insert Verification Gate to a pipeline in your application using Setup -> Applications. When the pipeline is run, the Gate executions will start appearing in this page.

", + "LOG_ANALYSIS": { + "BODY": "", + "SENSITIVITY": { + "TOOLTIP": "Impact of Unexpected Issues on the log scoring", + "VALIDATION_MESSAGE": {} }, - "SECRET_KEY": { - "TOOLTIP": "The secret key used to communicate with AWS", - "VALIDATION_MESSAGE": { - "required": "Secret key cannot be empty" - } - }, - "SECRET_KEY_BAKERY": { - "TOOLTIP": "The default secret key used for AWS baskery configuration", - "VALIDATION_MESSAGE": { - "required": "Secret Key (Bakery) cannot be empty" - } - }, - "APP_KEY": { - "TOOLTIP": "The appKey (password) of your service principal", - "VALIDATION_MESSAGE": { - "required": "App key cannot be empty", - "cannotContainSpace": "App key cannot contain space" - } - }, - "CLIENT_ID": { - "TOOLTIP": "The clientId (also called appId) of your service principal", - "VALIDATION_MESSAGE": { - "required": "Client Id cannot be empty", - "cannotContainSpace": "Client Id cannot contain space" - } - }, - "DEFAULT_KEYVALUT": { - "TOOLTIP": "The name of a KeyVault that contains the user name, password, and ssh public key used to create VMs", - "VALIDATION_MESSAGE": { - "required": "Default Keyvault cannot be empty", - "cannotContainSpace": "Default Keyvault cannot contain space" - } - }, - "SUBSCRIPTION_ID": { - "TOOLTIP": "The subscriptionId that your service principal is assigned to", - "VALIDATION_MESSAGE": { - "required": "Subscription Id cannot be empty", - "cannotContainSpace": "Subscription Id cannot contain space" - } - }, - "TENANT_ID": { - "TOOLTIP": "The tenantId that your service principal is assigned to", - "VALIDATION_MESSAGE": { - "required": "Tenant Id cannot be empty", - "cannotContainSpace": "Tenant Id cannot contain space" - } - }, - "GCP_FILE": { - "TOOLTIP": "The path to a JSON service account that Spinnaker will use as credentials. This is only needed if Spinnaker is not deployed on a Google Compute Engine VM, or needs permissions not afforded to the VM it is running on. Refer https://cloud.google.com/compute/docs/access/service-accounts for more information", - "VALIDATION_MESSAGE": { - "required": "File cannot be empty" - } - }, - "AWS_ACCOUNT_NAME": { - "TOOLTIP": "", - "VALIDATION_MESSAGE": { - "required": "Please Select AWS Account" - } - } - }, - "SPINNAKER_LISTING": { - "HEADER": "No Spinnaker Configured!", - "BODY": "

The Spinnaker Setup tab allows you to setup a Spinnaker instance with which you can connect Autopilot and sync all the applications from Spinnaker.

GitOps style Spinnaker is suported where in all configuration is maintained in a repository such as git. These optional sections help configure gitOps style Spinnaker:

Source Control for Accounts: In this section, you can specify the repository for External configuration in Spinnaker

Source Control for Pipeline:In this section, you can specify the repository for pipeline gitOps in Spinnaker that allows you to save and restore pipelines from a git repository.

Click on the Add Spinnaker button to add Spinnaker instance

" - }, - "SPINNAKER_SETUP": { - "HEADER": "Spinnaker", - "BODY": "

In this page you can add / update your Spinnaker instance.

Fields:

  • Spinnaker Name: User defined name for Spinnaker instance.
    Example: opsmx-spinnaker
  • Spinnaker Gate URL: Gate URL of the Spinnaker instance.
    Example: https://spinnaker-gate.xyz.com or http://oes-gate:8084
  • Authentication Type:: Can be LDAP or X509
  • Token: This is used when Authentication Type is LDAP; username & password to LDAP server separated by ':' in base64 format; Output of 'echo -ne 'username:password' | base64 -w0'
  • Password: This is used when Authentication Type is LDAP; Password for P12 File
  • P12 File: This is used when Authentication Type is X509; P12 File needed for X509/AD Authentication
  • Source Control for Accounts: In this section, you can specify the repository for External configuration in Spinnaker
  • Source Control for Pipeline: In this section, you can specify the repository for pipeline gitOps in Spinnaker that allows you to save and restore pipelines from a git repository
", - "SPINNAKER_NAME": { - "TOOLTIP": "Name of the Spinnaker instance", - "VALIDATION_MESSAGE": { - "required": "Spinnaker Name cannot be empty", - "cannotContainSpace": "Spinnaker Name cannot contain space", - "noSpecialCharacters": "Allowed special character is '-'", - "startingFromNumber": "Spinnaker Name should not start with number" - } - }, - "SPINNAKER_GATE_URL": { - "TOOLTIP": "Gate Url of the Spinnaker instance", - "VALIDATION_MESSAGE": { - "required": "Spinnaker Gate URL cannot be empty", - "cannotContainSpace": "Spinnaker Gate URL cannot contain space", - "invalidUrl": "Spinnaker Gate URL is invalid" - } - }, - "AUTHENTICATION_TYPE": { - "TOOLTIP": "Select the type of authentication for the spinnaker being added", - "VALIDATION_MESSAGE": { - "required": "Please select Authentication Type" - } - }, - "LDAP_USERNAME" : { - "TOOLTIP": "User Name", - "VALIDATION_MESSAGE": { - "required":"User Name cannot be empty", - "minlength":"User Name should be more than 4 characters" - } + "PERCEIVED_RISK": { + "TOOLTIP": "The overall risk associated with the changes in this verification run", + "VALIDATION_MESSAGE": {} + } + }, + "ANALYSIS_SUMMARY": { + "LOG_TEMPLATE": { + "TOOLTIP": "Log Template", + "VALIDATION_MESSAGE": {} }, - "LDAP_PASSWORD" : { - "TOOLTIP": "Password", - "VALIDATION_MESSAGE": { - "required":"Password cannot be empty", - "minlength":"Password should be more than 8 characters" - } + "METRIC_TEMPLATE": { + "TOOLTIP": "Metric Template", + "VALIDATION_MESSAGE": {} }, - "TOKEN": { - "TOOLTIP": "Token for Spinnaker authentication", - "VALIDATION_MESSAGE": { - "required": "Token cannot be empty", - "minlength": "Token should be more than 8 characters" - } + "LOG_BASELINE_START_TIME": { + "TOOLTIP": "Baseline Start Time", + "VALIDATION_MESSAGE": {} }, - "PASSWORD": { - "TOOLTIP": "Password", - "VALIDATION_MESSAGE": { - "required": "Password cannot be empty", - "minlength": "Password should be more than 8 characters" - } - }, - "P12_FILE": { - "TOOLTIP": "P12 File", - "VALIDATION_MESSAGE": { - "required": "P12 File cannot be empty" - } - }, - "SYNC_ACCOUNTS": { - "TOOLTIP": "Select Mode of synchronisation of Cloud Providers between Autopilot & Spinnaker", - "VALIDATION_MESSAGE": { - "required": "Please select Sync Accounts type" - } - }, - "ACCOUNTS_PROVIDER": { - "TOOLTIP": "Source Control for Halyard Configuration and / or External Account Configuration", - "VALIDATION_MESSAGE": { - "required": "Please select provider" - } - }, - "ACCOUNTS_ACCOUNT_NAME": { - "TOOLTIP": "Account name of the Source Control", - "VALIDATION_MESSAGE": { - "required": "Please select Account Name" - } - }, - "ACCOUNTS_REPOSITORY": { - "TOOLTIP": "Repository name with full path in the selected Source Control Eg., https://github.com/OpsMx/Opsmx-Saas.git", - "VALIDATION_MESSAGE": { - "required": "Repository cannot be empty", - "cannotContainSpace": "Repository cannot contain space", - "invalidUrl": "Repository is invalid" - } - }, - "ACCOUNTS_SOURCE_PATH": { - "TOOLTIP": "Existing path in the repository", - "VALIDATION_MESSAGE": {} - }, - "ACCOUNTS_REGION": { - "TOOLTIP": "The AWS regions this Spinnaker account will manage", - "VALIDATION_MESSAGE": { - "required": "Region cannot be empty", - "cannotContainSpace": "Region cannot contain space", - "startingFromNumber": "Region should not start with number" - } - }, - "ACCOUNTS_BUCKET_NAME": { - "TOOLTIP": "Bucket Name", - "VALIDATION_MESSAGE": { - "required": "Bucket Name cannot be empty", - "cannotContainSpace": "Bucket Name cannot contain space", - "startingFromNumber": "Bucket Name should not start with number" - } - }, - "PIPELINE_PROVIDER": { - "TOOLTIP": "Use this Spinnaker for pipeline promotion.", - "VALIDATION_MESSAGE": { - "required": "Please select provider" - } - }, - "PIPELINE_ACCOUNT_NAME": { - "TOOLTIP": "", - "VALIDATION_MESSAGE": { - "required": "Please select Account Name" - } - }, - "PIPELINE_REPOSITORY": { - "TOOLTIP": "", - "VALIDATION_MESSAGE": { - "required": "Repository cannot be empty", - "cannotContainSpace": "Repository cannot contain space", - "invalidUrl": "Repository is invalid" - } - }, - "PIPELINE_SOURCE_PATH": { - "TOOLTIP": "Existing path in the repository", - "VALIDATION_MESSAGE": {} - }, - "PIPELINE_REGION": { - "TOOLTIP": "", - "VALIDATION_MESSAGE": { - "required": "Region cannot be empty", - "cannotContainSpace": "Region cannot contain space", - "startingFromNumber": "Region should not start with number" - } - }, - "PIPELINE_BUCKET_NAME": { - "TOOLTIP": "Bucket Name", - "VALIDATION_MESSAGE": { - "required": "Bucket Name cannot be empty", - "cannotContainSpace": "Bucket Name cannot contain space", - "startingFromNumber": "Bucket Name should not start with number" - } - } - }, - "INTEGRATOR_LISTING": { - "HEADER": "No Integrator found!", - "BODY": "

Autopilot offers integration with many CI/CD Tools. Integrations are grouped under the following categories - Artifact, CI, Governance, Monitoring Tools, Notifications, Policy and SAST/DAST.

Integrations are used to

  • pull logs & metrics for Continuous Verification
  • pull meta data from CI/CD Tools for Informed Approvals
  • enforce organizational policies at the time of creating or executing a pipeline.
  • configure integrations in Spinnaker for Artifacts, Notifications. etc

Click on the New Integration button to add accounts for your CI/CD tools

", - - "SYNC_SPINNAKER_ACCOUNTS" : { - "TOOLTIP": "Push Integration changes to Spinnaker", - "VALIDATION_MESSAGE": "" - } - }, - "PIPELINE_EXECUTION_AUDIT_LISTING": { - "HEADER": "Pipeline executions not found!", - "BODY": "
This page shows pipeline executions coming from a CD Tool such as Spinnaker in a list view. It also contains the summary view showing the total number of Pipeline Runs, Successful Runs, Failed Runs, Cancelled Runs.

Only important fields including Application, Service, Pipeline, Status, Start Time and End Time are shown by default. Additional fields can be enabled using the Hamburger menu towars the right corner.

Ensure that the Spinnaker is already connected under Setup -> Spinnaker. Pipeline executions will start appearing in this page after establishing connection to Spinnaker.
", - "TOOLTIP": { - "EXECUTION_DATA": "Pipeline is in Running State", - "CONNECTOR_DATA": "Pipeline is in Running State", - "STAGE_DURATION": "Pipeline is in Running State" - }, - "VALIDATION_MESSAGE": { - "STAGE_DURATION": "No Data available to view Stage Duration" - } - }, - "PIPELINE_AUDIT_LISTING": { - "HEADER": "Pipeline updates not found!", - "BODY": "
This page shows pipeline updates coming from a CD Tool such as Spinnaker in a list view.
Ensure that the Spinnaker is already connected under Setup -> Spinnaker. Pipeline updates will start appearing in this page after establishing connection to Spinnaker.
" - }, - "POLICY_AUDIT_LISTING": { - "HEADER": "Policy updates / executions not found!", - "BODY": "
This page shows policy updates and policy executions, along with allowed/denied information, in a list view. Possible uses, apart from audit and compliance, includes helping users understand the policies that they might be inadvertently trying to break.

For policy updates, ensure that a policy is created/updated under Compliance -> Policy Management. For policy execution events, please add a policy in a pipeline and execute it.
" - }, - "POLICY_CREATION": { - "BODY": "

In this page, you can define & manage policies.

Fields:

  • Name: User defined name for the policy
  • Policy Type: Static or Runtime Policy
  • Policy Engine: Policy Engine to be used; currently, only OPA is supported
  • Policy Engine Account: Policy Engine Account for the Credentials
  • Policy File: File containing the Policy You can upload the file by clicking on Choose File button. This is optional. If not present, you can enter the policy directly in the Policy Details field
  • Policy Details: Policy definition
  • Policy Permissions: Enable/disable access to the policy in Autopilot to specific usergroup
", - "HEADER": "Policy", - "NAME": { - "TOOLTIP": "Policy Name", - "VALIDATION_MESSAGE": { - "required": "Name cannot be empty", - "cannotContainSpace": "Name cannot contain space", - "exists": "Name already exists" - } - }, - "POLICY_DETAILS": { - "TOOLTIP": "Policy Details", - "VALIDATION_MESSAGE": { - "required": "Policy Details cannot be empty" - } - }, - "POLICY_ENGINE": { - "TOOLTIP": "Supported Policy Account Types", - "VALIDATION_MESSAGE": { - "required": "Please select Policy Account Type" - } - }, - "POLICY_ENGINE_ACCOUNT": { - "TOOLTIP": "Policy Account Names", - "VALIDATION_MESSAGE": { - "required": "Please select Policy Engine Account" - } - }, - "POLICY_TYPE": { - "TOOLTIP": "A static policy lets users validate conditions before the start of execution, whereas a Runtime policy enables users for automated decision making during execution.", - "VALIDATION_MESSAGE": { - "required": "Please select Policy Engine Type" - } - }, - "POLICY_DESCRIPTION": { - "TOOLTIP": "Policy Description" - }, - "POLICY_FILE": { - "TOOLTIP": "Policy File" - } - }, - "VERIFICATION": { - "HEADER": "Verfication Gate executions not found!", - "BODY": "

The Continuous Verification performs automated log and metrics analysis for new releases with built-in unsupervised and supervised machine learning algorithms for risk analysis and canary deployments.

Continuous Verification is a release verification process that provides Dev and Ops engineers an intelligent automated real-time actionable risk assessment of a new release deployed. The Continuous Verification verifies the latest version of the service comparing to the baseline or prior release after production rollout. The baseline can be a deployment done prior or the current deployment during rollout using canary or blue/green or rolling update strategies.

It leverages unsupervised and supervised machine learning techniques to analyze 100s of metrics and logs data to perform in-depth analysis of architectural regressions, performance, scalability and security violations of new releases in a scalable way for enterprises.

Autopilot provides a Verification Gate to analyse logs from your Target Application and this can be inserted as a Stage in your CI/CD Pipeline.Note that one must configure the metric and log datasources, such as Prometheus and Elastic before using this functionality.

This page shows Verification Gate executions in a list view.

Insert Verification Gate to a pipeline in your application using Setup -> Applications. When the pipeline is run, the Gate executions will start appearing in this page.

", - "LOG_ANALYSIS": { - "BODY": "", - "SENSITIVITY": { - "TOOLTIP": "Impact of Unexpected Issues on the log scoring", - "VALIDATION_MESSAGE": {} - }, - "PERCEIVED_RISK": { - "TOOLTIP": "The overall risk associated with the changes in this verification run", - "VALIDATION_MESSAGE": {} - } - }, - "ANALYSIS_SUMMARY": { - "LOG_TEMPLATE": { - "TOOLTIP": "Log Template", - "VALIDATION_MESSAGE": {} - }, - "METRIC_TEMPLATE": { - "TOOLTIP": "Metric Template", - "VALIDATION_MESSAGE": {} - }, - "LOG_BASELINE_START_TIME": { - "TOOLTIP": "Baseline Start Time", - "VALIDATION_MESSAGE": {} - }, - "LOG_BASELINE_END_TIME": { - "TOOLTIP": "Baseline End Time", - "VALIDATION_MESSAGE": {} - }, - "LOG_NEW_RELEASE_START_TIME": { - "TOOLTIP": "New Release Start Time", - "VALIDATION_MESSAGE": {} - }, - "LOG_NEW_RELEASE_END_TIME": { - "TOOLTIP": "New Release End Time", - "VALIDATION_MESSAGE": {} - }, - "ANALYSIS_TYPE": { - "TOOLTIP": "Analysis Type", - "VALIDATION_MESSAGE": {} - }, - "LOG_STATUS": { - "TOOLTIP": "Log Status", - "VALIDATION_MESSAGE": {} - }, - "LOG_SCORE": { - "TOOLTIP": "Log Score", - "VALIDATION_MESSAGE": {} - }, - "METRIC_STATUS": { - "TOOLTIP": "Metric Status", - "VALIDATION_MESSAGE": {} - }, - "METRIC_SCORE": { - "TOOLTIP": "Metric Score", - "VALIDATION_MESSAGE": {} - }, - "BASELINE_SIZE": { - "TOOLTIP": "Baseline Size", - "VALIDATION_MESSAGE": {} - }, - "NEW_RELEASE_SIZE": { - "TOOLTIP": "New Release Size", - "VALIDATION_MESSAGE": {} - }, - "BASELINE_LINES": { - "TOOLTIP": "Baseline Lines", - "VALIDATION_MESSAGE": {} - }, - "NEW_RELEASE_LINES": { - "TOOLTIP": "New Release Lines", - "VALIDATION_MESSAGE": {} - }, - "ANALYSIS_DURATION": { - "TOOLTIP": "Analysis Duration", - "VALIDATION_MESSAGE": {} - }, - "LIFETIME_HOURS": { - "TOOLTIP": "Lifetime Hours", - "VALIDATION_MESSAGE": {} - }, - "RECLASSIFICATION_DURATION": { - "TOOLTIP": "Reclassification Duration", - "VALIDATION_MESSAGE": {} - }, - "INTERVAL_MINUTES": { - "TOOLTIP": "Interval Minutes", - "VALIDATION_MESSAGE": {} - }, - "REGULAR_EXPRESSION": { - "TOOLTIP": "Regular Expression", - "VALIDATION_MESSAGE": {} - }, - "RESPONSE_KEY": { - "TOOLTIP": "Response Key", - "VALIDATION_MESSAGE": {} - }, - "SCORING_ALGORITHM": { - "TOOLTIP": "Scoring Algorithm", - "VALIDATION_MESSAGE": {} - }, - "BASELINE_LOGS": { - "TOOLTIP": "Baseline Logs", - "VALIDATION_MESSAGE": {} - }, - "NEW_RELEASE_LOGS": { - "TOOLTIP": "New Release Logs", - "VALIDATION_MESSAGE": {} - } - }, - "METRIC_ANALYSIS": { - "BODY": "" - }, - "CORRELATION": { - "BODY": "" - } - }, - "MANUAL_TRIGGER": { - "BODY": "

Continuous Verification is a REST service that can be deployed on premise or use managed cloud service for analysis. Continuous Verification interfaces with monitoring systems for logs and metrics and uses the metadata provided in start analysis phase to retrieve the logs and metrics for deployment verification. Continuous Verification does not interface with the services deployed directly for its analysis. Deployment Pipeline can be based on Spinnaker or Jenkins for Enterprise Continuous Delivery. Verification can also be triggered manually by providing the required parameters in this dialog box.

", - "APPLICATION": { - "TOOLTIP": "Name of the application", - "VALIDATION_MESSAGE": "" - }, - "BASELINE_START_TIME": { - "TOOLTIP": "Time to enable warming up of the container", - "VALIDATION_MESSAGE": "" - }, - "NEW_RELEASE_START_TIME": { - "TOOLTIP": "Intervals in which metric-data is fetched and analysed", - "VALIDATION_MESSAGE": "" - }, - "SUCCESSFUL_SCORE": { - "TOOLTIP": "The score under which the Analysis should fail", - "VALIDATION_MESSAGE": "" - }, - "UNHEALTHY_SCORE": { - "TOOLTIP": "The score above which the Analysis should be a pass", - "VALIDATION_MESSAGE": "" - }, - "ANALYSIS_LIFETIME": { - "TOOLTIP": "The time in hours for which the Canary Analysis should be run", - "VALIDATION_MESSAGE": "" - }, - "RUN_INFO": { - "TOOLTIP": { - "Build Info": "http://jenkins.opsmx.net:8181/jenkins/job/Dev-visibilityservice-build-branch/770/", - "Code Repository": "https://github.com/OpsMx/visibility-service", - "Version": "v1.09" - }, - "VALIDATION_MESSAGE": "" - }, - "SERVICE": { - "TOOLTIP": "Service", - "VALIDATION_MESSAGE": "" + "LOG_BASELINE_END_TIME": { + "TOOLTIP": "Baseline End Time", + "VALIDATION_MESSAGE": {} }, - "TEMPLATE_NAME": { - "TOOLTIP": "Template Name", - "VALIDATION_MESSAGE": "" + "LOG_NEW_RELEASE_START_TIME": { + "TOOLTIP": "New Release Start Time", + "VALIDATION_MESSAGE": {} }, - "GATE": { - "TOOLTIP": "Gate", - "VALIDATION_MESSAGE": "" + "LOG_NEW_RELEASE_END_TIME": { + "TOOLTIP": "New Release End Time", + "VALIDATION_MESSAGE": {} }, - "FILTER_KEY": { - "TOOLTIP": "Filter Key", - "VALIDATION_MESSAGE": "" + "ANALYSIS_TYPE": { + "TOOLTIP": "Analysis Type", + "VALIDATION_MESSAGE": {} }, - "BASELINE": { - "TOOLTIP": "Baseline", - "VALIDATION_MESSAGE": "" + "LOG_STATUS": { + "TOOLTIP": "Log Status", + "VALIDATION_MESSAGE": {} }, - "NEW_RELEASE": { - "TOOLTIP": "New Release", - "VALIDATION_MESSAGE": "" - } - }, - "TEST_VERIFICATON": { - "HEADER": "Test Verfication Gate executions not found!", - "BODY": "

The Continuous Verification performs automated log and metric analysis for new releases with built-in unsupervised and supervised machine learning algorithms for risk analysis. Autopilot provides a Test Verification Gate to analyse logs from your Test Harness and this can be inserted as a Stage in your CI/CD Pipeline.

This page shows Test Verification Gate executions in a list view.

Insert Test Verification Gate to a pipeline in your application using Setup -> Applications.When the pipeline is run, the Gate executions will start appearing in this page.

" - }, - "TEST_CASE": { - "HEADER": "Test Cases not found!", - "BODY": "

The Continuous Verification performs automated log and metric analysis for new releases with built-in unsupervised and supervised machine learning algorithms for risk analysis. Autopilot provides a Test Verification Gate to analyse logs from your Test Harness and this can be inserted as a Stage in your CI/CD Pipeline.

This page shows Test Cases in a list view.

Insert Test Verification Gate to a pipeline in your application using Setup -> Applications.When the pipeline is run, the Gate executions will start appearing in this page.

" - }, - "VISIBILITY_LISTING": { - "HEADER": "
Approval Gate executions not found!
", - "BODY": "

Autopilot provides approval mechanism for deployments. To make an informed decision regarding pipeline execution, an approver may need to check the data from multiple data sources, such as CI Systems, Repositories, SAST/DAST Tools etc. Autopilot provides Approval Gate feature which fetches relevant information from multiple CI/CD Tools, presents the data in one place, to enable the user to make an quick and informed decision on pipeline execution. This Gate can be inserted as a Stage in your CI/CD Pipeline.

Note that appropriate data sources must be configured in the Integration view before Approval stage can be used.

This page shows Approval Gate executions in a list view.

Insert Approval Gate to a pipeline in your application using Setup -> Applications. When the pipeline is run, the Gate executions will start appearing in this page.

" - }, - "VISIBILITY_DETAILS": { - "APPLICATION_NAME": { - "TOOLTIP": "", - "VALIDATION_MESSAGE": "" - }, - "SERVICE_NAME": { - "TOOLTIP": "", - "VALIDATION_MESSAGE": "" - }, - "APPROVAL_BTN_TITLE": { - "TOOLTIP": "Insufficient Permission to execute", - "VALIDATION_MESSAGE": "" - }, - "GATE_NAME": { - "TOOLTIP": "", - "VALIDATION_MESSAGE": "" - }, - "STATUS": { - "TOOLTIP": "", - "VALIDATION_MESSAGE": "" - }, - "COMMENT": { - "TOOLTIP": "", - "VALIDATION_MESSAGE": "" - }, - "TRIGGER_URL": { - "TOOLTIP": "", - "VALIDATION_MESSAGE": "" - }, - "APPROVAL_GROUP": { - "TOOLTIP": "", - "VALIDATION_MESSAGE": "" - }, - "CONNECTORS": { - "TOOLTIP": "", - "VALIDATION_MESSAGE": "" - }, - "ACTIVATED_TIME": { - "TOOLTIP": "", - "VALIDATION_MESSAGE": "" - }, - "REVIEWED_AT": { - "TOOLTIP": "", - "VALIDATION_MESSAGE": "" - }, - "REVIEWER": { - "TOOLTIP": "", - "VALIDATION_MESSAGE": "" - }, - "COMMENTS": { - "TOOLTIP": "", - "VALIDATION_MESSAGE": "" - } - }, - "FORM_GRID": { - "ADD_NEW_ROW": { - "TOOLTIP": "Add New Row", - "VALIDATION_MESSAGE": "" - }, - "DELETE_ROW": { - "TOOLTIP": "Delete row", - "VALIDATION_MESSAGE": "" - } - }, - "APPLICATION_DASHBOARD": { - "VERIFICATION_FAILURES":{ - "TOOLTIP": "Total number of Verification Failures including Test Verification Failures", - "VALIDATION_MESSAGE": "" - } - }, - "APPLICATION_LISTING": { - "HEADER": "No Applications found!", - "BODY": "

You will be able to view the applications you have created or imported from a CD Tool such as Spinnaker in this page. There could be just one or multiple services in an application. Each service can have multiple pipelines and each pipeline can have multiple stages needed in order to successfully deploy the application.

You can create native Autopilot applications or import the applications created in Spinnaker.

Spinnaker Application: To import applications from Spinnaker, click on the Sync Spinnaker Applications button; before doing this, ensure that the Spinnaker is already connected under Setup -> Spinnaker

Autopilot Application: To create a native Autopilot Application, click on the New Application button

" , - "PLACEHOLDER": "You don't have access to this Page. Please contact your Administrator", - "SYNC_SPINNAKER":{ - "TOOLTIP": "To be able to work on applications created in Spinnaker, you need to import them here", - "VALIDATION_MESSAGE": "" - } - }, - "START_DEPLOYMENT": { - "APPLICATION_NAME": { - "TOOLTIP": "", - "VALIDATION_MESSAGE": { - "required": "Application Name is required", - "empty": "Please create Spinnaker Application to continue" - } - }, - "SERVICE_NAME": { - "TOOLTIP": "", - "VALIDATION_MESSAGE": { - "required": "Service Name is required", - "empty": "Pipelines are not present for this Application" - } - }, - "START_DEPLOYMENT_BTN": { - "TOOLTIP": "Please create Spinnaker Application to 'Start New Deployment'", - "VALIDATION_MESSAGE": { - "required": "Service Name is required" - } - } - }, - "APPLICATION_DETAILS": { - "HEADER": "Application Details", - "BODY": "
  • Application Name: User defined name of the application
  • Description: Application description
  • Email ID: Your email id
", - "APPLICATION_NAME": { - "TOOLTIP": "", - "VALIDATION_MESSAGE": { - "exists": "Application already exists", - "noSpecialCharacters": "Application Name cannot contain special characters", - "cannotContainSpace": "Application Name cannot contain space", - "required": "Application Name cannot be empty", - "startingFromNumber": "Application Name cannot start with numbers", - "maxlength": "Application name should not have more than 63 characters!" - } - }, - "APPLICATION_DESCRIPTION": { - "TOOLTIP": "", - "VALIDATION_MESSAGE": "" - }, - "EMAIL_ID": { - "TOOLTIP": "", - "VALIDATION_MESSAGE": { - "email": "Email Id is invalid", - "required": "Email Id cannot be empty" - } - } - }, - "SERVICE_DETAILS": { - "HEADER": "Services", - "BODY": "

An Application can contain multiple services. A service can contain multiple pipelines. When a Service is created, a Pipeline with the same name is created automatically. You can add more pipelines by clicking on '+' symbol in Service Pipeline

", - "SERVICE_NAME": { - "TOOLTIP": "", - "VALIDATION_MESSAGE": { - "exists": "Service already exists", - "noSpecialCharacters": "Service Name cannot contain special characters", - "cannotContainSpace": "Service Name cannot contain space", - "required": "Service Name cannot be empty", - "startingFromNumber": "Service Name cannot start with number", - "maxlength": "Service name should not have more than 63 characters!" - } - }, - "SERVICE_PIPELINE": { - "TOOLTIP": "", - "VALIDATION_MESSAGE": "" - }, - "ADD_NEW_SERVICE": { - "TOOLTIP": "Add a new Service", - "VALIDATION_MESSAGE": "" - }, - "SHOW_OR_HIDE_SERVICE": { - "TOOLTIP": "Show / Hide this Service in the Application Dashboard", - "VALIDATION_MESSAGE": "" - }, - "DELETE_PIPELINE_ICON": { - "TOOLTIP": "Delete Pipeline from Service", - "VALIDATION_MESSAGE": "" - }, - "DELETE_PERMISSION": { - "TOOLTIP": "Insufficient Permission to Delete this Service", - "VALIDATION_MESSAGE": "" - }, - "DELETE_SERVICE": { - "TOOLTIP": "Service can be deleted on deleting pipelines", - "VALIDATION_MESSAGE": "" - } - }, - "GROUP_PERMISSION": { - "APP_PERMISSIONS": { - "TOOLTIP": "Authorization definition for this Application", - "VALIDATION_MESSAGE": { - "groupValid": "Groups cannot be empty", - "permissionsValid": "Atleast 1 permission should be assigned to the groups", - "allPermissionForOneGroup": "Atleast 1 group should have all permissions" - } - }, - "INTEGRATORS_PERMISSIONS": { - "TOOLTIP": "Authorization definition for this Integration", - "VALIDATION_MESSAGE": "" - }, - "CLOUD_PROVIDER_PERMISSIONS": { - "TOOLTIP": "Authorization definition for this Cloud Provider", - "VALIDATION_MESSAGE": "" - }, - "AGENT_PERMISSIONS": { - "TOOLTIP": "Authorization definition for this Agent", - "VALIDATION_MESSAGE": "" - }, - "POLICY_PERMISSIONS": { - "TOOLTIP": "Authorization definition for this Policy", - "VALIDATION_MESSAGE": "" - }, - "ADD_GROUP": { - "TOOLTIP": "Add New Group", - "VALIDATION_MESSAGE": "" - }, - "DELETE": { - "TOOLTIP": "Delete", - "VALIDATION_MESSAGE": "" - } - }, - "GATE_DETAILS": { - "HEADER": "Gate Configuration", - "BODY": "

Select Gates from Existing Gates dropdown to load Gate Configuration and to add new Gate Configuration click the Add New Gate button

Autopilot has the following Gate Types

  • Approval: Fetches relevant information from multiple CI/CD Tools, presents the data in one place, to enable the user to make quick and informed decision on pipeline execution
  • Verification: Analyze logs & metrics from your target application to evaluate the risk in software delivery
  • Test Verification: Analyze logs from your Test Harness to evaluate the risk in software delivery
  • Policy: Defines a set of conditions that need to be verified while creating or executing a CI/CD pipeline
", - "PIPELINE": { - "TOOLTIP": "Shows the structure of how the Gates are stacked in the Pipeline", - "VALIDATION_MESSAGE": "" - }, - "TYPE": { - "TOOLTIP": "", - "VALIDATION_MESSAGE": "" - }, - "EXISITING_GATE": { - "TOOLTIP": "", - "VALIDATION_MESSAGE": "" - }, - "ENVIRONMENT": { - "TOOLTIP": "Specify Environment for this Gate", - "VALIDATION_MESSAGE": { - "required": "Environment Name is Invalid" - } - }, - "CUSTOM_ENVIRONMENT_NAME": { - "TOOLTIP": "", - "VALIDATION_MESSAGE": { - "noSpecialCharacters": "Environment Name cannot contain special characters", - "cannotContainSpace": "Environment Name cannot contain space", - "required": "Environment Name cannot be empty", - "startingFromNumber": "Environment Name cannot start with number", - "maxlength": "Environment name should not have more than 63 characters!" - } - }, - "GATE_NAME": { - "TOOLTIP": "", - "VALIDATION_MESSAGE": { - "exists": "Gate already exists", - "noSpecialCharacters": "Gate Name cannot contain special characters", - "cannotContainSpace": "Gate Name cannot contain space", - "required": "Gate Name cannot be empty", - "startingFromNumber": "Gate Name cannot start with number", - "maxlength": "Gate name should not have more than 63 characters!" - } - }, - "DEPENDS_ON": { - "TOOLTIP": "This field determines the placement of the current Gate in the Pipeline. This field is not required if there are no Stages in the Pipeline", - "VALIDATION_MESSAGE": { - "required": "Depends On cannot be empty" - } - }, - "CONNECTOR": { - "TOOLTIP": "Tool to gather information for informed Approvals", - "VALIDATION_MESSAGE": { - "required": "Please select Connector" - } + "LOG_SCORE": { + "TOOLTIP": "Log Score", + "VALIDATION_MESSAGE": {} }, - "ACCOUNT": { - "TOOLTIP": "Account name of the connector", - "VALIDATION_MESSAGE": { - "required": "Please select Account" - } + "METRIC_STATUS": { + "TOOLTIP": "Metric Status", + "VALIDATION_MESSAGE": {} }, - "TEMPLATE": { - "TOOLTIP": "Define the specific fields of interest from connector", - "VALIDATION_MESSAGE": { - "required": "Please select Template" - } + "METRIC_SCORE": { + "TOOLTIP": "Metric Score", + "VALIDATION_MESSAGE": {} }, - "ADD_NEW_TEMPLATE": { - "TOOLTIP": "Add New Connector", - "VALIDATION_MESSAGE": "" + "BASELINE_SIZE": { + "TOOLTIP": "Baseline Size", + "VALIDATION_MESSAGE": {} }, - "EDIT_TEMPLATE": { - "TOOLTIP": "Edit Template", - "VALIDATION_MESSAGE": "" + "NEW_RELEASE_SIZE": { + "TOOLTIP": "New Release Size", + "VALIDATION_MESSAGE": {} }, - "VIEW_TEMPLATE": { - "TOOLTIP": "View Template", - "VALIDATION_MESSAGE": "" + "BASELINE_LINES": { + "TOOLTIP": "Baseline Lines", + "VALIDATION_MESSAGE": {} }, - "DELETE_TEMPLATE": { - "TOOLTIP": "Delete Template", - "VALIDATION_MESSAGE": "" + "NEW_RELEASE_LINES": { + "TOOLTIP": "New Release Lines", + "VALIDATION_MESSAGE": {} }, - "TEMPLATE_TOOL_TYPE": { - "TOOLTIP": "", - "VALIDATION_MESSAGE": "" + "ANALYSIS_DURATION": { + "TOOLTIP": "Analysis Duration", + "VALIDATION_MESSAGE": {} }, - "TEMPLATE_NAME": { - "TOOLTIP": "", - "VALIDATION_MESSAGE": { - "noSpecialCharacters": "Template Name cannot contain special characters", - "required": "Template Name cannot be empty", - "startingFromNumber": "Template Name cannot start with number", - "maxlength": "Template Name should not have more than 63 characters!" - } - }, - "TEMPLATE_DESCRIPTION": { - "TOOLTIP": "", - "VALIDATION_MESSAGE": "" - }, - "AUTOMATED_APPROVAL": { - "TOOLTIP": "Use predefined conditions to Approve or Reject a request. You can configure conditions using Policies.", - "VALIDATION_MESSAGE": { - "required": "Please select Approval Condition" - } - }, - "APPROVAL_GROUPS": { - "TOOLTIP": "Selected groups will be able to review this Approval Gate", - "VALIDATION_MESSAGE": { - "required": "Please select Approval Groups to continue" - } - }, - "APPROVAL_GROUP_MSG": { - "TOOLTIP": "Selected groups should have atleast view access to the application", - "VALIDATION_MESSAGE": "" - }, - "GATE_SECURITY_SOURCE_URL": { - "TOOLTIP": "Source Url", - "VALIDATION_MESSAGE": "" - }, - "GATE_SECURITY_SOURCE_URL_COPY": { - "TOOLTIP": "Copy Source Url", - "VALIDATION_MESSAGE": "" - }, - "PAYLOAD_CONSTRAINTS": { - "TOOLTIP": "Payload Constraints for Gate Security", - "VALIDATION_MESSAGE": "" - }, - "PAYLOAD_CONSTRAINTS_KEY": { - "TOOLTIP": "", - "VALIDATION_MESSAGE": { - "cannotContainSpace": "Key cannot contain space", - "required": "Invalid Key" - } + "LIFETIME_HOURS": { + "TOOLTIP": "Lifetime Hours", + "VALIDATION_MESSAGE": {} }, - "LOG_TEMPLATE": { - "TOOLTIP": "A collection of all the information needed to run the log analysis", - "VALIDATION_MESSAGE": "" + "RECLASSIFICATION_DURATION": { + "TOOLTIP": "Reclassification Duration", + "VALIDATION_MESSAGE": {} }, - "CREATE_GATE_CONFIG_TEMPLATE": { - "TOOLTIP": "Create New Template", - "VALIDATION_MESSAGE": "" + "INTERVAL_MINUTES": { + "TOOLTIP": "Interval Minutes", + "VALIDATION_MESSAGE": {} + }, + "REGULAR_EXPRESSION": { + "TOOLTIP": "Regular Expression", + "VALIDATION_MESSAGE": {} }, - "EDIT_GATE_CONFIG_TEMPLATE": { - "TOOLTIP": "Edit Template", - "VALIDATION_MESSAGE": "" + "RESPONSE_KEY": { + "TOOLTIP": "Response Key", + "VALIDATION_MESSAGE": {} }, - "VIEW_GATE_CONFIG_TEMPLATE": { - "TOOLTIP": "View Template", - "VALIDATION_MESSAGE": "" + "SCORING_ALGORITHM": { + "TOOLTIP": "Scoring Algorithm", + "VALIDATION_MESSAGE": {} }, - "DELETE_GATE_CONFIG_TEMPLATE": { - "TOOLTIP": "Delete Template", - "VALIDATION_MESSAGE": "" + "BASELINE_LOGS": { + "TOOLTIP": "Baseline Logs", + "VALIDATION_MESSAGE": {} }, - "METRIC_TEMPLATE": { - "TOOLTIP": "Information needed to run the metric analysis", - "VALIDATION_MESSAGE": "" - }, - "POLICY": { - "TOOLTIP": "", - "VALIDATION_MESSAGE": "" - }, - "DELETE_PERMISSION":{ - "TOOLTIP": "Insufficient Permission to Delete this Gate", - "VALIDATION_MESSAGE": "" - } - }, - "LOGGED_INUSER_DETAILS": { - "HEADER": "No Users found", + "NEW_RELEASE_LOGS": { + "TOOLTIP": "New Release Logs", + "VALIDATION_MESSAGE": {} + } + }, + "METRIC_ANALYSIS": { + "BODY": "" + }, + "CORRELATION": { "BODY": "" - }, - "INTEGRATION": { - "AMAZONS3": { - "HEADER": "Amazon S3", - "BODY": "

Amazon S3 integration can be used to configure Spinnaker for Amazon S3.

Fields:

  • Account Name: User defined name for the Amazon S3 Account (Example: opsmx-s3)
  • Access Key Id: AWS Access Key Id
  • Secret Access Key: AWS Secret Access Key
  • Connect to Spinnaker: Toggle to configure Spinnaker for Amazon S3
  • Permissions: Enable/disable access to the Amazon S3 account in Autopilot to specific usergroups
", - "ACCOUNTNAME": { - "TOOLTIP": "User defined name for the Amazon S3 account", - "VALIDATION_MESSAGE": { - "noSpecialCharacters": "Account Name cannot contain special characters other than -", - "cannotContainSpace": "Account Name cannot contain space", - "required": "Account Name cannot be empty", - "startingFromNumber": "Account Name cannot start with numbers" - } - }, - "ACCESS_ID": { - "TOOLTIP": "AWS Access Key Id", - "VALIDATION_MESSAGE": { - "required": "Access Key Id cannot be empty" - } - }, - "SECRET_KEY": { - "TOOLTIP": "AWS Secret Access Key", - "VALIDATION_MESSAGE": { - "required": "Secret Access Key cannot be empty" - } - }, - "SPINNAKERTOGGLE": { - "TOOLTIP": "", - "VALIDATION_MESSAGE": {} - } - }, - "ARTIFACTORY": { - "HEADER": "Artifactory", - "BODY": "

Artifactory integration can be used as a datasource for Approval Gate as well as to configure Spinnaker for Artifactory.

Fields:

  • Account Name: User defined name for the Artifactory Account (Example: opsmx-artifactory)
  • Endpoint: Artifactory URL (Example: https://xyz.myjfrog.com)
  • Token: Artifactory personal access token. You can find here how to generate personal access tokens. (Example: ZlQDAwMFwvdXNlcnNcL21hZGh1a2FyIiwic2NwIjoiYXBwbGllZC1wZXJtaXNzaW9uc1wvYWRtaW4gYXBpOioiLCJhdWQiOlsiamZydEAqIiwiamZhY0AqIiwiamZldnmbWRAKiJdLCJpc3MiOiJqZmZlQDAAzNzY3MiwiaWF0IjoxNjI5ODY0ODcyLCJqdGkiOiI1ZWFiNjlhYi1hZDY0LTRjOGItOTMyZC0wMDAxMWZiZWU5YWIifQ.tzBgL3fQgZ1dwlLLS2UAT7G)
  • Connect to Spinnaker: Toggle to configure Spinnaker for Artifactory
  • Permissions: Enable/disable access to the Artifactory account in Autopilot to specific usergroups
", - "ACCOUNTNAME": { - "TOOLTIP": "User defined name for the Artifactory account", - "VALIDATION_MESSAGE": { - "noSpecialCharacters": "Account Name cannot contain special characters other than -", - "cannotContainSpace": "Account Name cannot contain space", - "required": "Account Name cannot be empty", - "startingFromNumber": "Account Name cannot start with numbers" - } - }, - "ENDPOINT": { - "TOOLTIP": "Artifactory URL", - "VALIDATION_MESSAGE": { - "required": "Endpoint cannot be empty", - "invalidUrl": "URL is invalid" - } - }, - "TOKEN": { - "TOOLTIP": "Artifactory Personal Access Token", - "VALIDATION_MESSAGE": { - "required": "Token cannot be empty" - } - }, - "SPINNAKERTOGGLE": { - "TOOLTIP": "", - "VALIDATION_MESSAGE": {} - } - }, - "BITBUCKET": { - "HEADER": "Bitbucket Cloud", - "BODY": "

BitBucket Cloud integration can be used as a datasource for Approval Gate as well as to configure Spinnaker for BitBucket Cloud.

Fields:

  • Name: User defined name for the Bitbucket Cloud Account (Example: opsmx-bitbucket)
  • Host URL: BitBucket Cloud URL (Example: https://bitbucket.org)
  • API URL: This is needed by Autopilot to access Bitbucket Cloud resources such as accounts & repositories through API calls (Example: https://api.bitbucket.org/2.0/repositories)
  • Authentication Type: can be Token or User Name/Password
  • User Name: Bitbucket Cloud User Name
  • Token: BitBucket personal access token (Example: xCPkVZfxaE9iULmfYYkK)
  • Password: Bitbucket Cloud Password
  • Connect to Spinnaker: Toggle to configure Spinnaker for Bitbucket Cloud
  • Permissions: Enable/disable access to the Bitbucket Account in Autopilot to specific usergroups
", - "ACCOUNTNAME": { - "TOOLTIP": "User defined name for the BitBucket Cloud account", - "VALIDATION_MESSAGE": { - "noSpecialCharacters": "Account Name cannot contain special characters other than -", - "cannotContainSpace": "Account Name cannot contain space", - "required": "Account Name cannot be empty", - "startingFromNumber": "Account Name cannot start with numbers" - } - }, - "HOSTURL": { - "TOOLTIP": "BitBucket Cloud URL", - "VALIDATION_MESSAGE": { - "required": "Host URL cannot be empty", - "invalidUrl": "URL is invalid" - } - }, - "APIURL": { - "TOOLTIP": "BitBucket Cloud Api URL. This is needed by Autopilot to access Bitbucket Cloud resources such as accounts & repositories through API calls", - "VALIDATION_MESSAGE": { - "required": "API URL cannot be empty", - "invalidUrl": "URL is invalid" - } - }, - "AUTHENTICATIONTYPE": { - "TOOLTIP": "can be Token or User Name/Password", - "VALIDATION_MESSAGE": {} - }, - "TOKEN": { - "TOOLTIP": "BitBucket Cloud personal access token", - "VALIDATION_MESSAGE": { - "required": "Token cannot be empty" - } - }, - "USERNAME": { - "TOOLTIP": "BitBucket Cloud User Name", - "VALIDATION_MESSAGE": { - "noSpecialCharacters": "User Name cannot contain special characters other than - and _", - "cannotContainSpace": "User Name cannot contain space", - "required": "User Name cannot be empty", - "startingFromNumber": "User Name cannot start with numbers" - } - }, - "PASSWORD": { - "TOOLTIP": "BitBucket Cloud Password", - "VALIDATION_MESSAGE": { - "required": "Password cannot be empty" - } - }, - "SPINNAKERTOGGLE": { - "TOOLTIP": "", - "VALIDATION_MESSAGE": {} - } - }, - "BITBUCKET_SERVER": { - "HEADER": "Bitbucket Server", - "BODY": "

BitBucket Server integration can be used as a datasource for Approval Gate as well as to configure Spinnaker for BitBucket Server.

Fields:

  • Account Name: User defined name for the Bitbucket Server Account (Example: opsmx-bitbucket)
  • Host URL: BitBucket Server URL (Example: https://xyz.mybitbucket.com)
  • Authentication Type: can be Token or User Name/Password
  • User Name: Bitbucket Server User Name
  • Token: BitBucket Server personal access token. You can find here how to generate personal access tokens. (Example: DjpMgHmwqUnIvvmljFgqGQ)
  • Password: Bitbucket Server Password
  • Connect to Spinnaker: Toggle to configure Spinnaker for Bitbucket Server
  • Permissions: Enable/disable access to the Bitbucket Server account in Autopilot to specific usergroups
", - "ACCOUNTNAME": { - "TOOLTIP": "User defined name for the Bitbucket Server account", - "VALIDATION_MESSAGE": { - "noSpecialCharacters": "Account Name cannot contain special characters other than -", - "cannotContainSpace": "Account Name cannot contain space", - "required": "Account Name cannot be empty", - "startingFromNumber": "Account Name cannot start with numbers" - } - }, - "HOSTURL": { - "TOOLTIP": "BitBucket Server URL", - "VALIDATION_MESSAGE": { - "required": "Host URL cannot be empty", - "invalidUrl": "URL is invalid" - } - }, - "AUTHENTICATIONTYPE": { - "TOOLTIP": "can be Token or User Name/Password", - "VALIDATION_MESSAGE": {} - }, - "TOKEN": { - "TOOLTIP": "Bitbucket Server personal access token", - "VALIDATION_MESSAGE": { - "required": "Token cannot be empty" - } - }, - "USERNAME": { - "TOOLTIP": "Bitbucket Server User Name", - "VALIDATION_MESSAGE": { - "noSpecialCharacters": "User Name cannot contain special characters other than - and _", - "cannotContainSpace": "User Name cannot contain space", - "required": "User Name cannot be empty", - "startingFromNumber": "User Name cannot start with numbers" - } - }, - "PASSWORD": { - "TOOLTIP": "Bitbucket Server Password", - "VALIDATION_MESSAGE": { - "required": "Password cannot be empty" - } - }, - "SPINNAKERTOGGLE": { - "TOOLTIP": "", - "VALIDATION_MESSAGE": {} - } - }, - "DOCKERHUB": { - "HEADER": "Docker Registry", - "BODY": "", - "ACCOUNTNAME": { - "TOOLTIP": "User defined name for the Docker Registry account", - "VALIDATION_MESSAGE": { - "noSpecialCharacters": "Account Name cannot contain special characters other than -", - "cannotContainSpace": "Account Name cannot contain space", - "required": "Account Name cannot be empty", - "startingFromNumber": "Account Name cannot start with numbers" - } - }, - "TOKEN": { - "TOOLTIP": "Docker Registry Personal Access Token", - "VALIDATION_MESSAGE": { - "required": "Token cannot be empty" - } - }, - "USERNAME": { - "TOOLTIP": "Docker Registry User Name", - "VALIDATION_MESSAGE": { - "noSpecialCharacters": "User Name cannot contain special characters other than - and _", - "cannotContainSpace": "User Name cannot contain space", - "required": "User Name cannot be empty", - "startingFromNumber": "User Name cannot start with numbers" - } - }, - "HOSTURL": { - "TOOLTIP": "Docker Registry Host URL", - "VALIDATION_MESSAGE": { - "required": "Host URL cannot be empty", - "invalidUrl": "URL is invalid" - } - } - }, - "GITHUB": { - "HEADER": "GitHub", - "BODY": "

GIT HUB integration can be used as a datasource for Approval Gate as well as to configure Spinnaker for GitHub.

Fields:

  • Account Name: User defined name for the GitHub Account(Example: opsmx-github)
  • Token: GitHub personal access token. You can find here how to generate personal access tokens. (Example: ghp_ln1eJK4yuomnY6JREp72IDJC4Hq6Sm)
  • User Name: GitHub User Name
  • Connect to Spinnaker: Toggle to configure Spinnaker for GitHub
  • Permissions: Enable/disable access to the GIT HUB account in Autopilot to specific usergroups
", - "ACCOUNTNAME": { - "TOOLTIP": "User defined name for the GitHub account", - "VALIDATION_MESSAGE": { - "noSpecialCharacters": "Account Name cannot contain special characters other than -", - "cannotContainSpace": "Account Name cannot contain space", - "required": "Account Name cannot be empty", - "startingFromNumber": "Account Name cannot start with numbers" - } - }, - "HOSTURL": { - "TOOLTIP": "GitHub Host URL", - "VALIDATION_MESSAGE": { - "required": "Host URL cannot be empty", - "invalidUrl": "URL is invalid" - } - }, - "URL": { - "TOOLTIP": "GitHub Api URL to access resources such as accounts & repositories through API calls.", - "VALIDATION_MESSAGE": { - "required": "API URL cannot be empty", - "invalidUrl": "URL is invalid" - } - }, - "TOKEN": { - "TOOLTIP": "GitHub Personal Access Token. You can generate token (settings -> Developer Settings -> Personal access tokens -> generate new Token)", - "VALIDATION_MESSAGE": { - "required": "Token cannot be empty" - } - }, - "USERNAME": { - "TOOLTIP": "GitHub User Name", - "VALIDATION_MESSAGE": { - "noSpecialCharacters": "User Name cannot contain special characters other than - and _", - "cannotContainSpace": "User Name cannot contain space", - "required": "User Name cannot be empty", - "startingFromNumber": "User Name cannot start with numbers" - } - }, - "SPINNAKERTOGGLE": { - "TOOLTIP": "", - "VALIDATION_MESSAGE": {} - } - }, - "GITREPO":{ - "HEADER": "Git Repo", - "BODY": "", - "ACCOUNTNAME":{ - "TOOLTIP":"The name of the account to operate on", - "VALIDATION_MESSAGE":{ - "noSpecialCharacters": "Account Name cannot contain special characters other than -", - "cannotContainSpace":"Account Name cannot contain space", - "required":"Account Name cannot be empty", - "startingFromNumber": "Account Name cannot start with numbers" - } - }, - "DEPLOYMENT":{ - "TOOLTIP":"This Halyard deployment will be used for Account creation / update", - "VALIDATION_MESSAGE":{ - "required":"URL cannot be empty", - "invalidUrl": "URL is invalid" } }, - "AUTHENTICATIONTYPE":{ - "TOOLTIP":"Select how the external resource confirms the user credentials", - "VALIDATION_MESSAGE":{} - }, - "URL":{ - "TOOLTIP":"", - "VALIDATION_MESSAGE":{ - "required":"API URL cannot be empty", - "invalidUrl": "URL is invalid" + "MANUAL_TRIGGER": { + "BODY": "

Continuous Verification is a REST service that can be deployed on premise or use managed cloud service for analysis. Continuous Verification interfaces with monitoring systems for logs and metrics and uses the metadata provided in start analysis phase to retrieve the logs and metrics for deployment verification. Continuous Verification does not interface with the services deployed directly for its analysis. Deployment Pipeline can be based on Spinnaker or Jenkins for Enterprise Continuous Delivery. Verification can also be triggered manually by providing the required parameters in this dialog box.

", + "APPLICATION": { + "TOOLTIP": "Name of the application", + "VALIDATION_MESSAGE": "" + }, + "BASELINE_START_TIME": { + "TOOLTIP": "Time to enable warming up of the container", + "VALIDATION_MESSAGE": "" + }, + "NEW_RELEASE_START_TIME": { + "TOOLTIP": "Intervals in which metric-data is fetched and analysed", + "VALIDATION_MESSAGE": "" + }, + "SUCCESSFUL_SCORE": { + "TOOLTIP": "The score under which the Analysis should fail", + "VALIDATION_MESSAGE": "" + }, + "UNHEALTHY_SCORE": { + "TOOLTIP": "The score above which the Analysis should be a pass", + "VALIDATION_MESSAGE": "" + }, + "ANALYSIS_LIFETIME": { + "TOOLTIP": "The time in hours for which the Canary Analysis should be run", + "VALIDATION_MESSAGE": "" + }, + "RUN_INFO": { + "TOOLTIP": { + "Build Info": "http://jenkins.opsmx.net:8181/jenkins/job/Dev-visibilityservice-build-branch/770/", + "Code Repository": "https://github.com/OpsMx/visibility-service", + "Version": "v1.09" + }, + "VALIDATION_MESSAGE": "" + }, + "SERVICE": { + "TOOLTIP": "Service", + "VALIDATION_MESSAGE": "" + }, + "TEMPLATE_NAME": { + "TOOLTIP": "Template Name", + "VALIDATION_MESSAGE": "" + }, + "GATE": { + "TOOLTIP": "Gate", + "VALIDATION_MESSAGE": "" + }, + "FILTER_KEY": { + "TOOLTIP": "Filter Key", + "VALIDATION_MESSAGE": "" + }, + "BASELINE": { + "TOOLTIP": "Baseline", + "VALIDATION_MESSAGE": "" + }, + "NEW_RELEASE": { + "TOOLTIP": "New Release", + "VALIDATION_MESSAGE": "" } }, - "TOKEN":{ - "TOOLTIP":"Git token", - "VALIDATION_MESSAGE":{ - "required":"Token cannot be empty" - } + "TEST_VERIFICATON": { + "HEADER": "Test Verfication Gate executions not found!", + "BODY": "

The Continuous Verification performs automated log and metric analysis for new releases with built-in unsupervised and supervised machine learning algorithms for risk analysis. Autopilot provides a Test Verification Gate to analyse logs from your Test Harness and this can be inserted as a Stage in your CI/CD Pipeline.

This page shows Test Verification Gate executions in a list view.

Insert Test Verification Gate to a pipeline in your application using Setup -> Applications.When the pipeline is run, the Gate executions will start appearing in this page.

" }, - "PASSWORD":{ - "TOOLTIP":"Git password", - "VALIDATION_MESSAGE":{ - "required":"Password cannot be empty" - } + "TEST_CASE": { + "HEADER": "Test Cases not found!", + "BODY": "

The Continuous Verification performs automated log and metric analysis for new releases with built-in unsupervised and supervised machine learning algorithms for risk analysis. Autopilot provides a Test Verification Gate to analyse logs from your Test Harness and this can be inserted as a Stage in your CI/CD Pipeline.

This page shows Test Cases in a list view.

Insert Test Verification Gate to a pipeline in your application using Setup -> Applications.When the pipeline is run, the Gate executions will start appearing in this page.

" }, - "USERNAME":{ - "TOOLTIP":"Git username", - "VALIDATION_MESSAGE":{ - "noSpecialCharacters": "User Name cannot contain special characters other than - and _", - "cannotContainSpace":"User Name cannot contain space", - "required":"User Name cannot be empty", - "startingFromNumber": "User Name cannot start with numbers" - } + "VISIBILITY_LISTING": { + "HEADER": "
Approval Gate executions not found!
", + "BODY": "

Autopilot provides approval mechanism for deployments. To make an informed decision regarding pipeline execution, an approver may need to check the data from multiple data sources, such as CI Systems, Repositories, SAST/DAST Tools etc. Autopilot provides Approval Gate feature which fetches relevant information from multiple CI/CD Tools, presents the data in one place, to enable the user to make an quick and informed decision on pipeline execution. This Gate can be inserted as a Stage in your CI/CD Pipeline.

Note that appropriate data sources must be configured in the Integration view before Approval stage can be used.

This page shows Approval Gate executions in a list view.

Insert Approval Gate to a pipeline in your application using Setup -> Applications. When the pipeline is run, the Gate executions will start appearing in this page.

" }, - "SPINNAKERTOGGLE":{ - "TOOLTIP":"Switch On this toggle to configure the resource in a gitops enabled Spinnaker instance", - "VALIDATION_MESSAGE":{} - } -}, -"HELM":{ - "HEADER": "Helm", - "BODY": "", - "ACCOUNTNAME":{ - "TOOLTIP":"The name of the account to operate on", - "VALIDATION_MESSAGE":{ - "noSpecialCharacters": "Account Name cannot contain special characters other than -", - "cannotContainSpace":"Account Name cannot contain space", - "required":"Account Name cannot be empty", - "startingFromNumber": "Account Name cannot start with numbers" + "VISIBILITY_DETAILS": { + "APPLICATION_NAME": { + "TOOLTIP": "", + "VALIDATION_MESSAGE": "" + }, + "SERVICE_NAME": { + "TOOLTIP": "", + "VALIDATION_MESSAGE": "" + }, + "APPROVAL_BTN_TITLE": { + "TOOLTIP": "Insufficient Permission to execute", + "VALIDATION_MESSAGE": "" + }, + "GATE_NAME": { + "TOOLTIP": "", + "VALIDATION_MESSAGE": "" + }, + "STATUS": { + "TOOLTIP": "", + "VALIDATION_MESSAGE": "" + }, + "COMMENT": { + "TOOLTIP": "", + "VALIDATION_MESSAGE": "" + }, + "TRIGGER_URL": { + "TOOLTIP": "", + "VALIDATION_MESSAGE": "" + }, + "APPROVAL_GROUP": { + "TOOLTIP": "", + "VALIDATION_MESSAGE": "" + }, + "CONNECTORS": { + "TOOLTIP": "", + "VALIDATION_MESSAGE": "" + }, + "ACTIVATED_TIME": { + "TOOLTIP": "", + "VALIDATION_MESSAGE": "" + }, + "REVIEWED_AT": { + "TOOLTIP": "", + "VALIDATION_MESSAGE": "" + }, + "REVIEWER": { + "TOOLTIP": "", + "VALIDATION_MESSAGE": "" + }, + "COMMENTS": { + "TOOLTIP": "", + "VALIDATION_MESSAGE": "" } }, - "REPOSITORY":{ - "TOOLTIP":"URL of the Helm Chart Repository", - "VALIDATION_MESSAGE":{ - "required":"URL cannot be empty", - "invalidUrl": "URL is invalid" + "FORM_GRID": { + "ADD_NEW_ROW": { + "TOOLTIP": "Add New Row", + "VALIDATION_MESSAGE": "" + }, + "DELETE_ROW": { + "TOOLTIP": "Delete row", + "VALIDATION_MESSAGE": "" } }, - "DEPLOYMENT":{ - "TOOLTIP":"This Halyard deployment will be used for Account creation / update", - "VALIDATION_MESSAGE":{ - + "APPLICATION_DASHBOARD": { + "VERIFICATION_FAILURES": { + "TOOLTIP": "Total number of Verification Failures including Test Verification Failures", + "VALIDATION_MESSAGE": "" } }, - "AUTHENTICATIONTYPE":{ - "TOOLTIP":"Select how the external resource confirms the user credentials", - "VALIDATION_MESSAGE":{} - }, - "TOKEN":{ - "TOOLTIP":"", - "VALIDATION_MESSAGE":{ - "required":"Token cannot be empty" + "APPLICATION_LISTING": { + "HEADER": "No Applications found!", + "BODY": "

You will be able to view the applications you have created or imported from a CD Tool such as Spinnaker in this page. There could be just one or multiple services in an application. Each service can have multiple pipelines and each pipeline can have multiple stages needed in order to successfully deploy the application.

You can create native Autopilot applications or import the applications created in Spinnaker.

Spinnaker Application: To import applications from Spinnaker, click on the Sync Spinnaker Applications button; before doing this, ensure that the Spinnaker is already connected under Setup -> Spinnaker

Autopilot Application: To create a native Autopilot Application, click on the New Application button

", + "PLACEHOLDER": "You don't have access to this Page. Please contact your Administrator", + "SYNC_SPINNAKER": { + "TOOLTIP": "To be able to work on applications created in Spinnaker, you need to import them here", + "VALIDATION_MESSAGE": "" + }, + "SYNC_SPINNAKER_NOT_CONFIGURED": { + "TOOLTIP": "Configure Spinnaker to Sync Spinnaker Applications from here", + "VALIDATION_MESSAGE": "" + }, + "SYNC_SPINNAKER_ERROR": { + "TOOLTIP": "Could not fetch Spinnaker Details. Please contact Administrator", + "VALIDATION_MESSAGE": "" + }, + "DISABLE_CREATE_APPLICATION_BTN": { + "TOOLTIP": "You do not have permission to create Application", + "VALIDATION_MESSAGE": "" } }, - "USERNAME":{ - "TOOLTIP":"User Name", - "VALIDATION_MESSAGE":{ - "noSpecialCharacters": "User Name cannot contain special characters other than - and _", - "cannotContainSpace":"User Name cannot contain space", - "required":"User Name cannot be empty", - "startingFromNumber": "User Name cannot start with numbers" - } - }, - "PASSWORD": { - "TOOLTIP": "Password", - "VALIDATION_MESSAGE":{ - } - }, - "PASSWORDCOMMAND": { - "TOOLTIP": "Command to retrieve docker token/password, commands must be available in environment", - "VALIDATION_MESSAGE":{ - } - }, - "FILE": { - "TOOLTIP": "The path to a file containing your docker password in plaintext (not a docker/config.json file)", - "VALIDATION_MESSAGE": { - } - }, - "SPINNAKERTOGGLE":{ - "TOOLTIP":"Switch On this toggle to configure the resource in a gitops enabled Spinnaker instance", - "VALIDATION_MESSAGE":{} - } -}, -"HTTP":{ - "HEADER": "Http", - "BODY": "", - "ACCOUNTNAME":{ - "TOOLTIP":"The name of the account to operate on", - "VALIDATION_MESSAGE":{ - "noSpecialCharacters": "Account Name cannot contain special characters other than -", - "cannotContainSpace":"Account Name cannot contain space", - "required":"Account Name cannot be empty", - "startingFromNumber": "Account Name cannot start with numbers" - } - }, - - "AUTHENTICATIONTYPE":{ - "TOOLTIP":"Select how the external resource confirms the user credentials", - "VALIDATION_MESSAGE":{} - }, - "TOKEN":{ - "TOOLTIP":"", - "VALIDATION_MESSAGE":{ - "required":"Token cannot be empty" - } - }, - "USERNAME":{ - "TOOLTIP":"User Name", - "VALIDATION_MESSAGE":{ - "noSpecialCharacters": "User Name cannot contain special characters other than - and _", - "cannotContainSpace":"User Name cannot contain space", - "required":"User Name cannot be empty", - "startingFromNumber": "User Name cannot start with numbers" - } - }, - "PASSWORD": { - "TOOLTIP": "Password", - "VALIDATION_MESSAGE":{ - } - }, - "PASSWORDCOMMAND": { - "TOOLTIP": "Command to retrieve docker token/password, commands must be available in environment", - "VALIDATION_MESSAGE":{ - } - }, - "FILE": { - "TOOLTIP": "The path to a file containing your docker password in plaintext (not a docker/config.json file)", - "VALIDATION_MESSAGE": { - } - }, - "SPINNAKERTOGGLE":{ - "TOOLTIP":"Switch On this toggle to configure the resource in a gitops enabled Spinnaker instance", - "VALIDATION_MESSAGE":{} - } -}, -"GCS":{ - "HEADER": "GCS", - "BODY": "", - "ACCOUNTNAME":{ - "TOOLTIP":"The name of the account to operate on", - "VALIDATION_MESSAGE":{ - "noSpecialCharacters": "Account Name cannot contain special characters other than -", - "cannotContainSpace":"Account Name cannot contain space", - "required":"Account Name cannot be empty", - "startingFromNumber": "Account Name cannot start with numbers" - } - }, - "AUTHENTICATIONTYPE":{ - "TOOLTIP":"Select how the external resource confirms the user credentials", - "VALIDATION_MESSAGE":{} - }, - "FILE": { - "TOOLTIP": "JSON service account that Spinnaker will use as credentials", - "VALIDATION_MESSAGE": { - } - }, - "SPINNAKERTOGGLE":{ - "TOOLTIP":"Switch On this toggle to configure the resource in a gitops enabled Spinnaker instance", - "VALIDATION_MESSAGE":{} - } -}, -"ECR":{ - "HEADER": "ECR", - "BODY": "", - "ACCOUNTNAME":{ - "TOOLTIP":"The name of the account to operate on", - "VALIDATION_MESSAGE":{ - "noSpecialCharacters": "Account Name cannot contain special characters other than -", - "cannotContainSpace":"Account Name cannot contain space", - "required":"Account Name cannot be empty", - "startingFromNumber": "Account Name cannot start with numbers" - } - }, - "REPOSITORIES":{ - "TOOLTIP":"An optional list of repositories to cache images from", - "VALIDATION_MESSAGE":{ - "cannotContainSpace":"Repository cannot contain space", - "startingFromNumber": "Repository cannot start with numbers" - } - }, - "REGISTRYURL":{ - "TOOLTIP":"The registry address you want to pull and deploy images from. For example: gcr.io", - "VALIDATION_MESSAGE":{ - } - }, - "GROUPMEMBERSHIP":{ - "TOOLTIP":"A user must be a member of at least one specified group in order to make changes to this account’s cloud resources", - "VALIDATION_MESSAGE":{ - "cannotContainSpace":"Repository cannot contain space" - } - }, - "REGION": { - "TOOLTIP": "AWS region" - }, - "EMAIL":{ - "TOOLTIP":"Your docker registry email", - "VALIDATION_MESSAGE":{ - "email":"Email Id is invalid", - "required":"Email Id cannot be empty" - } - }, - "AUTHENTICATIONTYPE":{ - "TOOLTIP":"Select how the external resource confirms the user credentials", - "VALIDATION_MESSAGE":{} - }, - "TOKEN":{ - "TOOLTIP":"", - "VALIDATION_MESSAGE":{ - "required":"Token cannot be empty" - } - }, - "USERNAME":{ - "TOOLTIP":"GCR User Name", - "VALIDATION_MESSAGE":{ - "noSpecialCharacters": "User Name cannot contain special characters other than - and _", - "cannotContainSpace":"User Name cannot contain space", - "required":"User Name cannot be empty", - "startingFromNumber": "User Name cannot start with numbers" - } - }, - "PASSWORD": { - "TOOLTIP": "Your docker registry password", - "VALIDATION_MESSAGE":{ - } - }, - "PASSWORDCOMMAND": { - "TOOLTIP": "Command to retrieve docker token/password, commands must be available in environment", - "VALIDATION_MESSAGE":{ - } - }, - "FILE": { - "TOOLTIP": "The path to a file containing your docker password in plaintext (not a docker/config.json file)", - "VALIDATION_MESSAGE": { - } - }, - "SPINNAKERTOGGLE":{ - "TOOLTIP":"Switch On this toggle to configure the resource in a gitops enabled Spinnaker instance", - "VALIDATION_MESSAGE":{} - } -}, -"PUBSUB":{ - "HEADER": "PUBSUB", - "BODY": "", - "ACCOUNTNAME":{ - "TOOLTIP":"The name of the account to operate on", - "VALIDATION_MESSAGE":{ - "noSpecialCharacters": "Account Name cannot contain special characters other than -", - "cannotContainSpace":"Account Name cannot contain space", - "required":"Account Name cannot be empty", - "startingFromNumber": "Account Name cannot start with numbers" - } - }, - "PROJECTNAME": { - "TOOLTIP": "The name of the GCP project your subscription lives in", - "VALIDATION_MESSAGE":{ - "cannotContainSpace":"Project Name cannot contain space", - "required":"Project Name cannot be empty" - } - }, - "SUBSCRIPTIONNAME": { - "TOOLTIP": "The name of the subscription to listen to. This identifier does not include the name of the project, and must already be configured for Spinnaker to work.", - "VALIDATION_MESSAGE":{ - "cannotContainSpace":"Subscription Name cannot contain space", - "required":"Subscription Name cannot be empty" - } - }, - "MESSAGEFORMAT": { - "TOOLTIP":"Supporting Message Formats: GCB,GCS,GCR,CUSTOM", - "VALIDATION_MESSAGE": {} - }, - "TEMPLATEFILE": { - "TOOLTIP":"Applicable only for CUSTOM message format", - "VALIDATION_MESSAGE": {} - }, - "AUTHENTICATIONTYPE":{ - "TOOLTIP":"Select how the external resource confirms the user credentials", - "VALIDATION_MESSAGE":{} - }, - "FILE": { - "TOOLTIP": "JSON service account that Spinnaker will use as credentials", - "VALIDATION_MESSAGE": { - } - }, - "SPINNAKERTOGGLE":{ - "TOOLTIP":"Switch On this toggle to configure the resource in a gitops enabled Spinnaker instance", - "VALIDATION_MESSAGE":{} - } -}, -"GCB":{ - "HEADER": "GCB", - "BODY": "", - "ACCOUNTNAME":{ - "TOOLTIP":"The name of the account to operate on", - "VALIDATION_MESSAGE":{ - "noSpecialCharacters": "Account Name cannot contain special characters other than -", - "cannotContainSpace":"Account Name cannot contain space", - "required":"Account Name cannot be empty", - "startingFromNumber": "Account Name cannot start with numbers" - } - }, - "PROJECTNAME": { - "TOOLTIP": "The name of the GCP project in which to trigger and monitor builds", - "VALIDATION_MESSAGE":{ - "cannotContainSpace":"Project Name cannot contain space", - "required":"Project Name cannot be empty" - } - }, - "SUBSCRIPTIONNAME": { - "TOOLTIP": "The name of the PubSub subscription on which to listen for build changes", - "VALIDATION_MESSAGE":{ - "cannotContainSpace":"Subscription Name cannot contain space", - "required":"Subscription Name cannot be empty" - } - }, - "AUTHENTICATIONTYPE":{ - "TOOLTIP":"Select how the external resource confirms the user credentials", - "VALIDATION_MESSAGE":{} - }, - "FILE": { - "TOOLTIP": "JSON service account that Spinnaker will use as credentials", - "VALIDATION_MESSAGE": { - } - }, - "USERNAME":{ - "TOOLTIP":"GCB User Name", - "VALIDATION_MESSAGE":{ - "noSpecialCharacters": "User Name cannot contain special characters other than - and _", - "cannotContainSpace":"User Name cannot contain space", - "required":"User Name cannot be empty", - "startingFromNumber": "User Name cannot start with numbers" - } - }, - "PASSWORD": { - "TOOLTIP": "Password", - "VALIDATION_MESSAGE":{ - } - }, - "SPINNAKERTOGGLE":{ - "TOOLTIP":"Switch On this toggle to configure the resource in a gitops enabled Spinnaker instance", - "VALIDATION_MESSAGE":{} - } -}, -"GCR":{ - "HEADER": "GCR", - "BODY": "", - "ACCOUNTNAME":{ - "TOOLTIP":"The name of the account to operate on", - "VALIDATION_MESSAGE":{ - "noSpecialCharacters": "Account Name cannot contain special characters other than -", - "cannotContainSpace":"Account Name cannot contain space", - "required":"Account Name cannot be empty", - "startingFromNumber": "Account Name cannot start with numbers" - } - }, - "AUTHENTICATIONTYPE":{ - "TOOLTIP":"Select how the external resource confirms the user credentials", - "VALIDATION_MESSAGE":{} - }, - "REPOSITORIES":{ - "TOOLTIP":"An optional list of repositories to cache images from", - "VALIDATION_MESSAGE":{ - "cannotContainSpace":"Repository cannot contain space", - "startingFromNumber": "Repository cannot start with numbers" - } - }, - "REGISTRYURL":{ - "TOOLTIP":"The registry address you want to pull and deploy images from. For example: gcr.io", - "VALIDATION_MESSAGE":{ - } - }, - "REQUIREDGROUPMEMBERSHIP":{ - "TOOLTIP":"A user must be a member of at least one specified group in order to make changes to this account’s cloud resources", - "VALIDATION_MESSAGE":{ - "cannotContainSpace":"Repository cannot contain space" - } - }, - "EMAIL":{ - "TOOLTIP":"Your docker registry email", - "VALIDATION_MESSAGE":{ - "email":"Email Id is invalid", - "required":"Email Id cannot be empty" - } - }, - "URL":{ - "TOOLTIP":"", - "VALIDATION_MESSAGE":{ - "required":"API URL cannot be empty", - "invalidUrl": "URL is invalid" + "START_DEPLOYMENT": { + "APPLICATION_NAME": { + "TOOLTIP": "", + "VALIDATION_MESSAGE": { + "required": "Application Name is required", + "empty": "Please create Spinnaker Application to continue" + } + }, + "SERVICE_NAME": { + "TOOLTIP": "", + "VALIDATION_MESSAGE": { + "required": "Service Name is required", + "empty": "Pipelines are not present for this Application" + } + }, + "START_DEPLOYMENT_BTN": { + "TOOLTIP": "Please create Spinnaker Application to 'Start New Deployment'", + "VALIDATION_MESSAGE": { + "required": "Service Name is required" + } } }, - "TOKEN":{ - "TOOLTIP":"", - "VALIDATION_MESSAGE":{ - "required":"Token cannot be empty" + "APPLICATION_DETAILS": { + "HEADER": "Application Details", + "BODY": "
  • Application Name: User defined name of the application
  • Description: Application description
  • Email ID: Your email id
", + "APPLICATION_NAME": { + "TOOLTIP": "", + "VALIDATION_MESSAGE": { + "exists": "Application already exists", + "noSpecialCharacters": "Application Name cannot contain special characters", + "cannotContainSpace": "Application Name cannot contain space", + "required": "Application Name cannot be empty", + "startingFromNumber": "Application Name cannot start with numbers", + "maxlength": "Application name should not have more than 63 characters!" + } + }, + "APPLICATION_DESCRIPTION": { + "TOOLTIP": "", + "VALIDATION_MESSAGE": "" + }, + "EMAIL_ID": { + "TOOLTIP": "", + "VALIDATION_MESSAGE": { + "email": "Email Id is invalid", + "required": "Email Id cannot be empty" + } } }, - "USERNAME":{ - "TOOLTIP":"GCR User Name", - "VALIDATION_MESSAGE":{ - "noSpecialCharacters": "User Name cannot contain special characters other than - and _", - "cannotContainSpace":"User Name cannot contain space", - "required":"User Name cannot be empty", - "startingFromNumber": "User Name cannot start with numbers" + "SERVICE_DETAILS": { + "HEADER": "Services", + "BODY": "

An Application can contain multiple services. A service can contain multiple pipelines. When a Service is created, a Pipeline with the same name is created automatically. You can add more pipelines by clicking on '+' symbol in Service Pipeline

", + "SERVICE_NAME": { + "TOOLTIP": "", + "VALIDATION_MESSAGE": { + "exists": "Service already exists", + "noSpecialCharacters": "Service Name cannot contain special characters", + "cannotContainSpace": "Service Name cannot contain space", + "required": "Service Name cannot be empty", + "startingFromNumber": "Service Name cannot start with number", + "maxlength": "Service name should not have more than 63 characters!" + } + }, + "SERVICE_PIPELINE": { + "TOOLTIP": "", + "VALIDATION_MESSAGE": "" + }, + "ADD_NEW_SERVICE": { + "TOOLTIP": "Add a new Service", + "VALIDATION_MESSAGE": "" + }, + "SHOW_OR_HIDE_SERVICE": { + "TOOLTIP": "Show / Hide this Service in the Application Dashboard", + "VALIDATION_MESSAGE": "" + }, + "DELETE_PIPELINE_ICON": { + "TOOLTIP": "Delete Pipeline from Service", + "VALIDATION_MESSAGE": "" + }, + "DELETE_PERMISSION": { + "TOOLTIP": "Insufficient Permission to Delete this Service", + "VALIDATION_MESSAGE": "" + }, + "DELETE_SERVICE": { + "TOOLTIP": "Service can be deleted on deleting pipelines", + "VALIDATION_MESSAGE": "" } }, - "PASSWORD": { - "TOOLTIP": "Your docker registry password", - "VALIDATION_MESSAGE":{ + "GROUP_PERMISSION": { + "APP_PERMISSIONS": { + "TOOLTIP": "Authorization definition for this Application", + "VALIDATION_MESSAGE": { + "groupValid": "Groups cannot be empty", + "permissionsValid": "Atleast 1 permission should be assigned to the groups", + "allPermissionForOneGroup": "Atleast 1 group should have all permissions" + } + }, + "INTEGRATORS_PERMISSIONS": { + "TOOLTIP": "Authorization definition for this Integration", + "VALIDATION_MESSAGE": "" + }, + "CLOUD_PROVIDER_PERMISSIONS": { + "TOOLTIP": "Authorization definition for this Cloud Target", + "VALIDATION_MESSAGE": "" + }, + "AGENT_PERMISSIONS": { + "TOOLTIP": "Authorization definition for this Agent", + "VALIDATION_MESSAGE": "" + }, + "POLICY_PERMISSIONS": { + "TOOLTIP": "Authorization definition for this Policy", + "VALIDATION_MESSAGE": "" + }, + "ADD_GROUP": { + "TOOLTIP": "Add New Group", + "VALIDATION_MESSAGE": "" + }, + "DELETE": { + "TOOLTIP": "Delete", + "VALIDATION_MESSAGE": "" } }, - "PASSWORDCOMMAND": { - "TOOLTIP": "Command to retrieve docker token/password, commands must be available in environment", - "VALIDATION_MESSAGE":{ + "GATE_DETAILS": { + "HEADER": "Gate Configuration", + "BODY": "

Select Gates from Existing Gates dropdown to load Gate Configuration and to add new Gate Configuration click the Add New Gate button

Autopilot has the following Gate Types

  • Approval: Fetches relevant information from multiple CI/CD Tools, presents the data in one place, to enable the user to make quick and informed decision on pipeline execution
  • Verification: Analyze logs & metrics from your target application to evaluate the risk in software delivery
  • Test Verification: Analyze logs from your Test Harness to evaluate the risk in software delivery
  • Policy: Defines a set of conditions that need to be verified while creating or executing a CI/CD pipeline
", + "PIPELINE": { + "TOOLTIP": "Shows the structure of how the Gates are stacked in the Pipeline", + "VALIDATION_MESSAGE": "" + }, + "TYPE": { + "TOOLTIP": "", + "VALIDATION_MESSAGE": "" + }, + "EXISITING_GATE": { + "TOOLTIP": "", + "VALIDATION_MESSAGE": "" + }, + "ENVIRONMENT": { + "TOOLTIP": "Specify Environment for this Gate", + "VALIDATION_MESSAGE": { + "required": "Environment Name is Invalid" + } + }, + "CUSTOM_ENVIRONMENT_NAME": { + "TOOLTIP": "", + "VALIDATION_MESSAGE": { + "noSpecialCharacters": "Environment Name cannot contain special characters", + "cannotContainSpace": "Environment Name cannot contain space", + "required": "Environment Name cannot be empty", + "startingFromNumber": "Environment Name cannot start with number", + "maxlength": "Environment name should not have more than 63 characters!", + "exists": "Environment name already exists" + } + }, + "GATE_NAME": { + "TOOLTIP": "", + "VALIDATION_MESSAGE": { + "exists": "Gate already exists", + "noSpecialCharacters": "Gate Name cannot contain special characters", + "cannotContainSpace": "Gate Name cannot contain space", + "required": "Gate Name cannot be empty", + "startingFromNumber": "Gate Name cannot start with number", + "maxlength": "Gate name should not have more than 63 characters!" + } + }, + "DEPENDS_ON": { + "TOOLTIP": "This field determines the placement of the current Gate in the Pipeline. This field is not required if there are no Stages in the Pipeline", + "VALIDATION_MESSAGE": { + "required": "Depends On cannot be empty" + } + }, + "CONNECTOR": { + "TOOLTIP": "Tool to gather information for informed Approvals", + "VALIDATION_MESSAGE": { + "required": "Please select Connector" + } + }, + "ACCOUNT": { + "TOOLTIP": "Account name of the connector", + "VALIDATION_MESSAGE": { + "required": "Please select Account" + } + }, + "TEMPLATE": { + "TOOLTIP": "Define the specific fields of interest from connector", + "VALIDATION_MESSAGE": { + "required": "Please select Template" + } + }, + "ADD_NEW_TEMPLATE": { + "TOOLTIP": "Add New Connector", + "VALIDATION_MESSAGE": "" + }, + "EDIT_TEMPLATE": { + "TOOLTIP": "Edit Template", + "VALIDATION_MESSAGE": "" + }, + "VIEW_TEMPLATE": { + "TOOLTIP": "View Template", + "VALIDATION_MESSAGE": "" + }, + "DELETE_TEMPLATE": { + "TOOLTIP": "Delete Template", + "VALIDATION_MESSAGE": "" + }, + "TEMPLATE_TOOL_TYPE": { + "TOOLTIP": "", + "VALIDATION_MESSAGE": "" + }, + "TEMPLATE_NAME": { + "TOOLTIP": "", + "VALIDATION_MESSAGE": { + "noSpecialCharacters": "Template Name cannot contain special characters", + "required": "Template Name cannot be empty", + "startingFromNumber": "Template Name cannot start with number", + "maxlength": "Template Name should not have more than 63 characters!" + } + }, + "TEMPLATE_DESCRIPTION": { + "TOOLTIP": "", + "VALIDATION_MESSAGE": "" + }, + "AUTOMATED_APPROVAL": { + "TOOLTIP": "Use predefined conditions to Approve or Reject a request. You can configure conditions using Policies.", + "VALIDATION_MESSAGE": { + "required": "Please select Approval Condition" + } + }, + "APPROVAL_GROUPS": { + "TOOLTIP": "Selected groups will be able to review this Approval Gate", + "VALIDATION_MESSAGE": { + "required": "Please select Approval Groups to continue" + } + }, + "APPROVAL_GROUP_MSG": { + "TOOLTIP": "Selected groups should have atleast view access to the application", + "VALIDATION_MESSAGE": "" + }, + "GATE_SECURITY_SOURCE_URL": { + "TOOLTIP": "Source Url", + "VALIDATION_MESSAGE": "" + }, + "GATE_SECURITY_SOURCE_URL_COPY": { + "TOOLTIP": "Copy Source Url", + "VALIDATION_MESSAGE": "" + }, + "PAYLOAD_CONSTRAINTS": { + "TOOLTIP": "Payload Constraints for Gate Security", + "VALIDATION_MESSAGE": "" + }, + "PAYLOAD_CONSTRAINTS_KEY": { + "TOOLTIP": "", + "VALIDATION_MESSAGE": { + "cannotContainSpace": "Key cannot contain space", + "required": "Invalid Key" + } + }, + "LOG_TEMPLATE": { + "TOOLTIP": "A collection of all the information needed to run the log analysis", + "VALIDATION_MESSAGE": "" + }, + "CREATE_GATE_CONFIG_TEMPLATE": { + "TOOLTIP": "Create New Template", + "VALIDATION_MESSAGE": "" + }, + "EDIT_GATE_CONFIG_TEMPLATE": { + "TOOLTIP": "Edit Template", + "VALIDATION_MESSAGE": "" + }, + "VIEW_GATE_CONFIG_TEMPLATE": { + "TOOLTIP": "View Template", + "VALIDATION_MESSAGE": "" + }, + "DELETE_GATE_CONFIG_TEMPLATE": { + "TOOLTIP": "Delete Template", + "VALIDATION_MESSAGE": "" + }, + "METRIC_TEMPLATE": { + "TOOLTIP": "Information needed to run the metric analysis", + "VALIDATION_MESSAGE": "" + }, + "POLICY": { + "TOOLTIP": "", + "VALIDATION_MESSAGE": "" + }, + "DELETE_PERMISSION": { + "TOOLTIP": "Insufficient Permission to Delete this Gate", + "VALIDATION_MESSAGE": "" } }, - "FILE": { - "TOOLTIP": "The path to a file containing your docker password in plaintext (not a docker/config.json file)", - "VALIDATION_MESSAGE": { - } + "LOGGED_INUSER_DETAILS": { + "HEADER": "No Users found", + "BODY": "" }, - "SPINNAKERTOGGLE":{ - "TOOLTIP":"Switch On this toggle to configure the resource in a gitops enabled Spinnaker instance", - "VALIDATION_MESSAGE":{} - } -}, - "BAMBOO": { - "HEADER": "Bamboo CI", - "BODY": "

Bamboo CI integration can be used as a datasource for Approval Gate.

Fields:

  • Name: User defined name for the Bamboo CI Account (Example: opsmx-bamboo)
  • Endpoint: Bamboo CI URL (Example: https://xyz.mybamboo.com)
  • Token: Bamboo CI personal access token. You can find here how to generate personal access tokens. (Example: YmFrwqw0w9r90skfsOk9wcdd014p98kklw==)
  • User Name: Bamboo CI User Name
  • Password: Bamboo CI Password
  • Permissions: Enable/disable access to the Bamboo CI account in Autopilot to specific usergroups
", - "ACCOUNTNAME": { - "TOOLTIP": "User defined name for the Bamboo CI account", - "VALIDATION_MESSAGE": { - "noSpecialCharacters": "Account Name cannot contain special characters other than -", - "cannotContainSpace": "Account Name cannot contain space", - "required": "Account Name cannot be empty", - "startingFromNumber": "Account Name cannot start with numbers" - } - }, - "ENDPOINT": { - "TOOLTIP": "Bamboo CI URL", - "VALIDATION_MESSAGE": { - "required": "Bamboo End Point cannot be empty", - "invalidUrl": "URL is invalid" - } - }, - "AUTHENTICATIONTYPE": { - "TOOLTIP": "can be Token or User Name/Password", - "VALIDATION_MESSAGE": {} - }, - "TOKEN": { - "TOOLTIP": "Bamboo CI personal access token", - "VALIDATION_MESSAGE": { - "required": "Token cannot be empty" - } - }, - "USERNAME": { - "TOOLTIP": "Bamboo CI User Name", - "VALIDATION_MESSAGE": { - "noSpecialCharacters": "User Name cannot contain special characters other than - and _", - "cannotContainSpace": "User Name cannot contain space", - "required": "User Name cannot be empty", - "startingFromNumber": "User Name cannot start with numbers" - } - }, - "PASSWORD": { - "TOOLTIP": "Bamboo CI Password", - "VALIDATION_MESSAGE": { - "required": "Password cannot be empty" - } - } - }, - "JENKINS": { - "HEADER": "Jenkins", - "BODY": "

Jenkins integration can be used as a datasource for Approval Gate as well as to configure Spinnaker for Jenkins.

Fields:

  • Account Name: User defined name for the Jenkins Account (Example: opsmx-jenkins)
  • Host URL: Jenkins URL (Example: https://xyz.my-jenkins.com/jenkins)
  • Authentication Type: can be Token or User Name/Password
  • Token: Jenkins personal access token. You can find here how to generate personal access tokens. (Example: 77d67609a841b1811a114b7fbfa109b3c2)
  • User Name: Jenkins User Name
  • Password: Jenkins Password
  • Connect to Spinnaker: Toggle to configure Spinnaker for Jenkins
  • Permissions: Enable/disable access to the Jenkins account in Autopilot to specific usergroups
", - "ACCOUNTNAME": { - "TOOLTIP": "User defined name for the Jenkins account", - "VALIDATION_MESSAGE": { - "noSpecialCharacters": "Account Name cannot contain special characters other than -", - "cannotContainSpace": "Account Name cannot contain space", - "required": "Account Name cannot be empty", - "startingFromNumber": "Account Name cannot start with numbers" - } - }, - "HOSTURL": { - "TOOLTIP": "Jenkins URL", - "VALIDATION_MESSAGE": { - "required": "Host URL cannot be empty", - "invalidUrl": "URL is invalid" - } - }, - "AUTHENTICATIONTYPE": { - "TOOLTIP": "can be Token or User Name/Password", - "VALIDATION_MESSAGE": {} - }, - "TOKEN": { - "TOOLTIP": "Jenkins personal access token", - "VALIDATION_MESSAGE": { - "required": "Token cannot be empty" - } - }, - "USERNAME": { - "TOOLTIP": "Jenkins User Name", - "VALIDATION_MESSAGE": { - "noSpecialCharacters": "User Name cannot contain special characters other than - and _", - "cannotContainSpace": "User Name cannot contain space", - "required": "User Name cannot be empty", - "startingFromNumber": "User Name cannot start with numbers" - } - }, - "PASSWORD": { - "TOOLTIP": "Jenkins Password", - "VALIDATION_MESSAGE": { - "required": "Password cannot be empty" - } - }, - "SPINNAKERTOGGLE": { - "TOOLTIP": "", - "VALIDATION_MESSAGE": {} - } - }, - "JIRA": { - "HEADER": "Jira", - "BODY": "", - "ACCOUNTNAME": { - "TOOLTIP": "User defined name for the Jira account", - "VALIDATION_MESSAGE": { - "noSpecialCharacters": "Account Name cannot contain special characters other than -", - "cannotContainSpace": "Account Name cannot contain space", - "required": "Account Name cannot be empty", - "startingFromNumber": "Account Name cannot start with numbers" - } - }, - "EMAIL": { - "TOOLTIP": "Jira Email Id", - "VALIDATION_MESSAGE": { - "email": "Email Id is invalid", - "required": "Email Id cannot be empty" - } - }, - "TOKEN": { - "TOOLTIP": "Jira Personal Access Token", - "VALIDATION_MESSAGE": { - "required": "Token cannot be empty" - } - }, - "HOSTURL": { - "TOOLTIP": "Jira Host URL", - "VALIDATION_MESSAGE": { - "required": "Host URL cannot be empty", - "invalidUrl": "URL is invalid" - } - }, - "SPINNAKERTOGGLE": { - "TOOLTIP": "", - "VALIDATION_MESSAGE": {} - } - }, - "SERVICENOW": { - "HEADER": "Service Now", - "BODY": "", - "ACCOUNTNAME": { - "TOOLTIP": "User defined name for the Service Now account", - "VALIDATION_MESSAGE": { - "noSpecialCharacters": "Account Name cannot contain special characters other than -", - "cannotContainSpace": "Account Name cannot contain space", - "required": "Account Name cannot be empty", - "startingFromNumber": "Account Name cannot start with numbers" - } - }, - "USERNAME": { - "TOOLTIP": "Service Now User Name", - "VALIDATION_MESSAGE": { - "noSpecialCharacters": "User Name cannot contain special characters other than - and _", - "cannotContainSpace": "User Name cannot contain space", - "required": "User Name cannot be empty", - "startingFromNumber": "User Name cannot start with numbers" - } - }, - "PASSWORD": { - "TOOLTIP": "Service Now Password", - "VALIDATION_MESSAGE": { - "required": "Password cannot be empty" - } - }, - "HOSTURL": { - "TOOLTIP": "Service Now Host URL", - "VALIDATION_MESSAGE": { - "required": "Host URL cannot be empty", - "invalidUrl": "URL is invalid" - } - } - }, - "APPDYNAMICS": { - "HEADER": "APPDYNAMICS", - "BODY": "", - "ACCOUNTNAME": { - "TOOLTIP": "User defined name for the APPDYNAMICS account", - "VALIDATION_MESSAGE": { - "noSpecialCharacters": "Account Name cannot contain special characters other than -", - "cannotContainSpace": "Account Name cannot contain space", - "required": "Account Name cannot be empty", - "startingFromNumber": "Account Name cannot start with numbers" - } - }, - "CONTROLLERHOST": { - "TOOLTIP": "APPDYNAMICS Controller Host", - "VALIDATION_MESSAGE": { - "required": "Controller Host cannot be empty", - "invalidUrl": "URL is invalid" - } - }, - "TEMPORARYACCESSTOKEN": { - "TOOLTIP": "APPDYNAMICS Personal Temporary Access Token", - "VALIDATION_MESSAGE": { - "required": "Temporary Access Token cannot be empty" - } - } - }, - "CLOUDWATCH": { - "HEADER": "AWS-CLOUDWATCH", - "BODY": "", - "ACCOUNTNAME": { - "TOOLTIP": "User defined name for the AWS-CLOUDWATCH account", - "VALIDATION_MESSAGE": { - "noSpecialCharacters": "Account Name cannot contain special characters other than -", - "cannotContainSpace": "Account Name cannot contain space", - "required": "Account Name cannot be empty", - "startingFromNumber": "Account Name cannot start with numbers" - } - }, - "ACCESS_ID": { - "TOOLTIP": "AWS-CLOUDWATCH Access Key Id", - "VALIDATION_MESSAGE": { - "required": "Access Key Id cannot be empty" - } - }, - "SECRET_KEY": { - "TOOLTIP": "AWS-CLOUDWATCH Secret Access Key", - "VALIDATION_MESSAGE": { - "required": "Secret Access Key cannot be empty" - } - } - }, - "DATADOG": { - "HEADER": "DATADOG", - "BODY": "", - "ACCOUNTNAME": { - "TOOLTIP": "User defined name for the DATADOG account", - "VALIDATION_MESSAGE": { - "noSpecialCharacters": "Account Name cannot contain special characters other than -", - "cannotContainSpace": "Account Name cannot contain space", - "required": "Account Name cannot be empty", - "startingFromNumber": "Account Name cannot start with numbers" - } - }, - "API_KEY": { - "TOOLTIP": "DATADOG Api Key", - "VALIDATION_MESSAGE": { - "required": "Application Key cannot be empty" - } - }, - "APPLICATION_KEY": { - "TOOLTIP": "DATADOG Application Key", - "VALIDATION_MESSAGE": { - "required": "Application Key cannot be empty" - } - } - }, - "DYNATRACE": { - "HEADER": "Dynatrace", - "BODY": "", - "ACCOUNTNAME": { - "TOOLTIP": "User defined name for the Dynatrace account", - "VALIDATION_MESSAGE": { - "noSpecialCharacters": "Account Name cannot contain special characters other than -", - "cannotContainSpace": "Account Name cannot contain space", - "required": "Account Name cannot be empty", - "startingFromNumber": "Account Name cannot start with numbers" - } - }, - "END_POINT": { - "TOOLTIP": "Dynatrace URL", - "VALIDATION_MESSAGE": { - "required": "Url cannot be empty", - "invalidUrl": "URL is invalid" - } - }, - "API_TOKEN": { - "TOOLTIP": "Dynatrace Personal Access Token", - "VALIDATION_MESSAGE": { - "required": "Api Token cannot be empty" - } - } - }, - "ELASTICSEARCH": { - "HEADER": "Elasticsearch", - "BODY": "", - "ACCOUNTNAME": { - "TOOLTIP": "User defined name for the Elasticsearch account", - "VALIDATION_MESSAGE": { - "noSpecialCharacters": "Account Name cannot contain special characters other than -", - "cannotContainSpace": "Account Name cannot contain space", - "required": "Account Name cannot be empty", - "startingFromNumber": "Account Name cannot start with numbers" - } - }, - "ENDPOINT": { - "TOOLTIP": "ElasticSearch End Point", - "VALIDATION_MESSAGE": { - "required": "Elastic End Point cannot be empty", - "invalidUrl": "URL is invalid" - } - }, - "USERNAME": { - "TOOLTIP": "ElasticSearch User Name", - "VALIDATION_MESSAGE": { - "noSpecialCharacters": "User Name cannot contain special characters other than - and _", - "cannotContainSpace": "User Name cannot contain space", - "startingFromNumber": "User Name cannot start with numbers" - } - }, - "PASSWORD": { - "TOOLTIP": "ElasticSearch Password", - "VALIDATION_MESSAGE": { - "required": "Password cannot be empty" - } - }, - "KIBANAENDPOINT": { - "TOOLTIP": "ElasticSearch Kibana End Point", - "VALIDATION_MESSAGE": { - "required": "Kibana End Point cannot be empty", - "invalidUrl": "URL is invalid" - } - }, - "KIBANAUSERNAME": { - "TOOLTIP": "ElasticSearch Kibana User Name", - "VALIDATION_MESSAGE": { - "noSpecialCharacters": "Kibana User Name cannot contain special characters other than - and _", - "cannotContainSpace": "Kibana User Name cannot contain space", - "required": "Kibana User Name cannot be empty", - "startingFromNumber": "Kibana User Name cannot start with numbers" - } - }, - "KIBANAPASSWORD": { - "TOOLTIP": "ElasticSearch Kibana Password", - "VALIDATION_MESSAGE": { - "required": "Kibana Password cannot be empty" - } - } - }, - "GRAPHITE": { - "HEADER": "Graphite", - "BODY": "", - "ACCOUNTNAME": { - "TOOLTIP": "User defined name for the Graphite account", - "VALIDATION_MESSAGE": { - "noSpecialCharacters": "Account Name cannot contain special characters other than -", - "cannotContainSpace": "Account Name cannot contain space", - "required": "Account Name cannot be empty", - "startingFromNumber": "Account Name cannot start with numbers" - } - }, - "URL": { - "TOOLTIP": "Graphite End Point", - "VALIDATION_MESSAGE": { - "required": "End Point cannot be empty", - "invalidUrl": "URL is invalid" - } - } - }, - "GRAYLOG": { - "HEADER": "GRAYLOG", - "BODY": "", - "ACCOUNTNAME": { - "TOOLTIP": "User defined name for the GRAYLOG account", - "VALIDATION_MESSAGE": { - "noSpecialCharacters": "Account Name cannot contain special characters other than -", - "cannotContainSpace": "Account Name cannot contain space", - "required": "Account Name cannot be empty", - "startingFromNumber": "Account Name cannot start with numbers" - } - }, - "ENDPOINT": { - "TOOLTIP": "GrayLog End Point", - "VALIDATION_MESSAGE": { - "required": "End Point cannot be empty", - "invalidUrl": "URL is invalid" - } - }, - "TOKEN": { - "TOOLTIP": "GrayLog Personal Access Token", - "VALIDATION_MESSAGE": { - "required": "Token cannot be empty" - } - } - }, - "NEWRELIC": { - "HEADER": "New Relic", - "BODY": "", - "ACCOUNTNAME": { - "TOOLTIP": "User defined name for the New Relic account", - "VALIDATION_MESSAGE": { - "noSpecialCharacters": "Account Name cannot contain special characters other than -", - "cannotContainSpace": "Account Name cannot contain space", - "required": "Account Name cannot be empty", - "startingFromNumber": "Account Name cannot start with numbers" - } - }, - "APIKEY": { - "TOOLTIP": "NewRelic Api Key", - "VALIDATION_MESSAGE": { - "required": "Token cannot be empty" - } - }, - "APPLICATIONKEY": { - "TOOLTIP": "NewRelic Application Key", - "VALIDATION_MESSAGE": { - "required": "Token cannot be empty" - } - }, - "ACCOUNTID": { - "TOOLTIP": "NewRelic Account Id", - "VALIDATION_MESSAGE": { - "required": "Token cannot be empty" - } - }, - "QUERYKEY": { - "TOOLTIP": "NewRelic Query Key", - "VALIDATION_MESSAGE": { - "required": "Token cannot be empty" - } - } - }, - "PROMETHEUS": { - "HEADER": "Prometheus", - "BODY": "", - "ACCOUNTNAME": { - "TOOLTIP": "User defined name for the Prometheus account", - "VALIDATION_MESSAGE": { - "noSpecialCharacters": "Account Name cannot contain special characters other than -", - "cannotContainSpace": "Account Name cannot contain space", - "required": "Account Name cannot be empty", - "startingFromNumber": "Account Name cannot start with numbers" - } - }, - "ENDPOINT": { - "TOOLTIP": "Prometheus End Point", - "VALIDATION_MESSAGE": { - "required": "End Point cannot be empty", - "invalidUrl": "URL is invalid" - } - }, - "USERNAME": { - "TOOLTIP": "Prometheus User Name", - "VALIDATION_MESSAGE": { - "noSpecialCharacters": "User Name cannot contain special characters other than - and _", - "cannotContainSpace": "User Name cannot contain space", - "required": "User Name cannot be empty", - "startingFromNumber": "User Name cannot start with numbers" - } - }, - "PASSWORD": { - "TOOLTIP": "Prometheus Password", - "VALIDATION_MESSAGE": { - "required": "Password cannot be empty" - } - } - }, - "SPLUNK": { - "HEADER": "Splunk", - "BODY": "", - "ACCOUNTNAME": { - "TOOLTIP": "User defined name for the Splunk account", - "VALIDATION_MESSAGE": { - "noSpecialCharacters": "Account Name cannot contain special characters other than -", - "cannotContainSpace": "Account Name cannot contain space", - "required": "Account Name cannot be empty", - "startingFromNumber": "Account Name cannot start with numbers" - } - }, - "END_POINT": { - "TOOLTIP": "Splunk Splunk URL", - "VALIDATION_MESSAGE": { - "required": "Splunk Url cannot be empty", - "invalidUrl": "URL is invalid" - } - }, - "PASSWORD": { - "TOOLTIP": "Splunk Password", - "VALIDATION_MESSAGE": { - "required": "Password cannot be empty" - } - }, - "USER_NAME": { - "TOOLTIP": "Splunk User Name", - "VALIDATION_MESSAGE": { - "noSpecialCharacters": "Account Name cannot contain special characters other than -", - "cannotContainSpace": "Account Name cannot contain space", - "required": "Account Name cannot be empty", - "startingFromNumber": "Account Name cannot start with numbers" - } - }, - "DASHBOARD_ENDPOINT": { - "TOOLTIP": "Splunk DashBoard URL", - "VALIDATION_MESSAGE": { - "required": "Splunk DashBoard Url cannot be empty", - "invalidUrl": "URL is invalid" - } - } - }, - "STACKDRIVER": { - "HEADER": "Stackdriver", - "BODY": "", - "ACCOUNTNAME": { - "TOOLTIP": "User defined name for the Stackdriver account", - "VALIDATION_MESSAGE": { - "noSpecialCharacters": "Account Name cannot contain special characters other than -", - "cannotContainSpace": "Account Name cannot contain space", - "required": "Account Name cannot be empty", - "startingFromNumber": "Account Name cannot start with numbers" - } - }, - "KEY_FILE": { - "TOOLTIP": "Stackdriver Encrypted Key file", - "VALIDATION_MESSAGE": { - "required": "Encrypted Key File cannot be empty" - } - } - }, - "SUMOLOGIC": { - "HEADER": "Sumo Logic", - "BODY": "", - "ACCOUNTNAME": { - "TOOLTIP": "User defined name for the Sumologic account", - "VALIDATION_MESSAGE": { - "noSpecialCharacters": "Account Name cannot contain special characters other than -", - "cannotContainSpace": "Account Name cannot contain space", - "required": "Account Name cannot be empty", - "startingFromNumber": "Account Name cannot start with numbers" - } - }, - "ACCESSID": { - "TOOLTIP": "sumologic Access Id. You can generate Access Id (Administration > Security > Access Keys)", - "VALIDATION_MESSAGE": { - "required": "Access Id cannot be empty" - } - }, - "ACCESSKEY": { - "TOOLTIP": "sumologic Access Key. You can generate Access Id (Administration > Security > Access Keys)", - "VALIDATION_MEeSSAGE": { - "required": "Access Key cannot be empty" - } - }, - "ZONE": { - "TOOLTIP": "sumologic Zone", - "VALIDATION_MESSAGE": { - "noSpecialCharacters": "Zone cannot contain special characters other than -", - "cannotContainSpace": "Zone cannot contain space", - "required": "Zone cannot be empty", - "startingFromNumber": "Zone cannot start with numbers" - } - } - }, - "VMWARETANZU":{ - "HEADER": "VMWare Tanzu Observability", - "BODY":"", - "ACCOUNTNAME":{ - "TOOLTIP":"User defined name for the VMWare Tanzu Observability account", - "VALIDATION_MESSAGE":{ - "noSpecialCharacters": "Account Name cannot contain special characters other than -", - "cannotContainSpace":"Account Name cannot contain space", - "required":"Account Name cannot be empty", - "startingFromNumber": "Account Name cannot start with numbers" - } + "INTEGRATION": { + "AMAZONS3": { + "HEADER": "Amazon S3", + "BODY": "

Amazon S3 integration can be used to configure Spinnaker for Amazon S3.

Fields:

  • Account Name: User defined name for the Amazon S3 Account (Example: opsmx-s3)
  • Access Key Id: AWS Access Key Id
  • Secret Access Key: AWS Secret Access Key
  • Connect to Spinnaker: Toggle to configure Spinnaker for Amazon S3
  • Permissions: Enable/disable access to the Amazon S3 account in Autopilot to specific usergroups
", + "ACCOUNTNAME": { + "TOOLTIP": "User defined name for the Amazon S3 account", + "VALIDATION_MESSAGE": { + "noSpecialCharacters": "Account Name cannot contain special characters other than -", + "cannotContainSpace": "Account Name cannot contain space", + "required": "Account Name cannot be empty", + "startingFromNumber": "Account Name cannot start with numbers" + } + }, + "ACCESS_ID": { + "TOOLTIP": "AWS Access Key Id", + "VALIDATION_MESSAGE": { + "required": "Access Key Id cannot be empty" + } + }, + "SECRET_KEY": { + "TOOLTIP": "AWS Secret Access Key", + "VALIDATION_MESSAGE": { + "required": "Secret Access Key cannot be empty" + } }, - "END_POINT":{ - "TOOLTIP":"VMWare Tanzu Observability URL", - "VALIDATION_MESSAGE":{ - "required":"Url cannot be empty", + "SPINNAKERTOGGLE": { + "TOOLTIP": "Switch On this toggle to configure the resource in a gitops enabled Spinnaker instance", + "VALIDATION_MESSAGE": {} + } + }, + "ARTIFACTORY": { + "HEADER": "Artifactory", + "BODY": "

Artifactory integration can be used as a datasource for Approval Gate as well as to configure Spinnaker for Artifactory.

Fields:

  • Account Name: User defined name for the Artifactory Account (Example: opsmx-artifactory)
  • Endpoint: Artifactory URL (Example: https://xyz.myjfrog.com)
  • Token: Artifactory personal access token. You can find here how to generate personal access tokens. (Example: ZlQDAwMFwvdXNlcnNcL21hZGh1a2FyIiwic2NwIjoiYXBwbGllZC1wZXJtaXNzaW9uc1wvYWRtaW4gYXBpOioiLCJhdWQiOlsiamZydEAqIiwiamZhY0AqIiwiamZldnmbWRAKiJdLCJpc3MiOiJqZmZlQDAAzNzY3MiwiaWF0IjoxNjI5ODY0ODcyLCJqdGkiOiI1ZWFiNjlhYi1hZDY0LTRjOGItOTMyZC0wMDAxMWZiZWU5YWIifQ.tzBgL3fQgZ1dwlLLS2UAT7G)
  • Connect to Spinnaker: Toggle to configure Spinnaker for Artifactory
  • Permissions: Enable/disable access to the Artifactory account in Autopilot to specific usergroups
", + "ACCOUNTNAME": { + "TOOLTIP": "User defined name for the Artifactory account", + "VALIDATION_MESSAGE": { + "noSpecialCharacters": "Account Name cannot contain special characters other than -", + "cannotContainSpace": "Account Name cannot contain space", + "required": "Account Name cannot be empty", + "startingFromNumber": "Account Name cannot start with numbers" + } + }, + "ENDPOINT": { + "TOOLTIP": "Artifactory URL", + "VALIDATION_MESSAGE": { + "required": "Endpoint cannot be empty", "invalidUrl": "URL is invalid" } }, - "EMAIL":{ - "TOOLTIP":"VMWare Tanzu Observability Email Id", - "VALIDATION_MESSAGE":{ - "email":"Email Id is invalid", - "required":"Email Id cannot be empty" - } - }, - "API_TOKEN":{ - "TOOLTIP":"VMWare Tanzu Observability Personal Access Token", - "VALIDATION_MESSAGE":{ - "required":"Api Token cannot be empty" - } - } - }, - "MSTEAMS": { - "HEADER": "Microsoft Teams", - "BODY": "" - }, - "SLACK": { - "HEADER": "Slack", - "BODY": "", - "ACCOUNTNAME": { - "TOOLTIP": "User defined name for the Slack account", - "VALIDATION_MESSAGE": { - "noSpecialCharacters": "Account Name cannot contain special characters other than -", - "cannotContainSpace": "Account Name cannot contain space", - "required": "Account Name cannot be empty", - "startingFromNumber": "Account Name cannot start with numbers" - } - }, - "BOTNAME": { - "TOOLTIP": "Slack Bot Name", - "VALIDATION_MESSAGE": { - "noSpecialCharacters": "Bot Name cannot contain special characters other than -", - "cannotContainSpace": "Bot Name cannot contain space", - "required": "Bot Name cannot be empty", - "startingFromNumber": "Bot Name cannot start with numbers" - } - }, - "TOKEN": { - "TOOLTIP": "Slack Personal Access Token", - "VALIDATION_MESSAGE": { - "required": "Token cannot be empty" - } - }, - "SPINNAKERTOGGLE": { - "TOOLTIP": "", - "VALIDATION_MESSAGE": {} - } - }, - "OPA": { - "HEADER": "OPA", - "BODY": "", - "ACCOUNTNAME": { - "TOOLTIP": "User defined name for the OPA account", - "VALIDATION_MESSAGE": { - "noSpecialCharacters": "Account Name cannot contain special characters other than -", - "cannotContainSpace": "Account Name cannot contain space", - "required": "Account Name cannot be empty", - "startingFromNumber": "Account Name cannot start with numbers" - } - }, - "ENDPOINT": { - "TOOLTIP": "OPA End Point", - "VALIDATION_MESSAGE": { - "required": "End Point cannot be empty", - "invalidUrl": "URL is invalid" - } - } - }, - "AQUAWAVE": { - "HEADER": "Aqua Wave", - "BODY": "", - "ACCOUNTNAME": { - "TOOLTIP": "User defined name for the Aqua Wave account", - "VALIDATION_MESSAGE": { - "noSpecialCharacters": "Account Name cannot contain special characters other than -", - "cannotContainSpace": "Account Name cannot contain space", - "required": "Account Name cannot be empty", - "startingFromNumber": "Account Name cannot start with numbers" - } - }, - "USERNAME": { - "TOOLTIP": "Aqua Wave User Name", - "VALIDATION_MESSAGE": { - "noSpecialCharacters": "User Name cannot contain special characters other than - and _", - "cannotContainSpace": "User Name cannot contain space", - "required": "User Name cannot be empty", - "startingFromNumber": "User Name cannot start with numbers" - } - }, - "TOKEN": { - "TOOLTIP": "Aqua Wave Personal Access Token", - "VALIDATION_MESSAGE": { - "required": "Token cannot be empty" - } - } - }, - "APPSCAN": { - "HEADER": "HCL AppScan", - "BODY": "", - "ACCOUNTNAME": { - "TOOLTIP": "User defined name for the HCL AppScan account", - "VALIDATION_MESSAGE": { - "noSpecialCharacters": "Account Name cannot contain special characters other than -", - "cannotContainSpace": "Account Name cannot contain space", - "required": "Account Name cannot be empty", - "startingFromNumber": "Account Name cannot start with numbers" - } - }, - "TOKEN": { - "TOOLTIP": "Appscan Personal Access Token", - "VALIDATION_MESSAGE": { - "required": "Token cannot be empty" - } - } - }, - "JFROG": { - "HEADER": "JFrog XRay Scanning", - "BODY": "", - "ACCOUNTNAME": { - "TOOLTIP": "User defined name for the JFrog XRay Scanning account", - "VALIDATION_MESSAGE": { - "noSpecialCharacters": "Account Name cannot contain special characters other than -", - "cannotContainSpace": "Account Name cannot contain space", - "required": "Account Name cannot be empty", - "startingFromNumber": "Account Name cannot start with numbers" - } - }, - "ENDPOINT": { - "TOOLTIP": "JFrog URL", - "VALIDATION_MESSAGE": { - "required": "Endpoint cannot be empty", - "invalidUrl": "URL is invalid" - } - }, - "TOKEN": { - "TOOLTIP": "JFrog Personal Access Token", - "VALIDATION_MESSAGE": { - "required": "Token cannot be empty" - } - } - }, - "PRISMACLOUD": { - "HEADER": "Prisma Cloud", - "BODY": "", - "ACCOUNTNAME": { - "TOOLTIP": "User defined name for the Prisma Cloud account", - "VALIDATION_MESSAGE": { - "noSpecialCharacters": "Account Name cannot contain special characters other than -", - "cannotContainSpace": "Account Name cannot contain space", - "required": "Account Name cannot be empty", - "startingFromNumber": "Account Name cannot start with numbers" - } - }, - "HOSTURL": { - "TOOLTIP": "Prisma Cloud Host URL", - "VALIDATION_MESSAGE": { - "required": "Host URL cannot be empty", - "invalidUrl": "URL is invalid" - } - }, - "APPLICATIONURL": { - "TOOLTIP": "Prisma Cloud Application URL", - "VALIDATION_MESSAGE": { - "required": "Application URL cannot be empty", - "invalidUrl": "URL is invalid" - } - }, - "ACCESSKEYID": { - "TOOLTIP": "Prisma Cloud Access Key Id", - "VALIDATION_MESSAGE": { - "required": "Access Key Id cannot be empty" - } - }, - "SECRETKEY": { - "TOOLTIP": "Prisma Cloud Secret Key", - "VALIDATION_MESSAGE": { - "required": "Secret Key cannot be empty" - } - } - }, - "SONARQUBE": { - "HEADER": "SonarQube", - "BODY": "", - "ACCOUNTNAME": { - "TOOLTIP": "User defined name for the SonarQube account", - "VALIDATION_MESSAGE": { - "noSpecialCharacters": "Account Name cannot contain special characters other than -", - "cannotContainSpace": "Account Name cannot contain space", - "required": "Account Name cannot be empty", - "startingFromNumber": "Account Name cannot start with numbers" - } - }, - "HOSTURL": { - "TOOLTIP": "Sonarqube Host URL", - "VALIDATION_MESSAGE": { - "required": "Host URL cannot be empty", - "invalidUrl": "URL is invalid" - } - }, - "TOKEN": { - "TOOLTIP": "Sonarqube Personal Access Token", - "VALIDATION_MESSAGE": { - "required": "Token cannot be empty" - } - } - }, - "AUTOPILOT": { - "HEADER": "Autopilot", - "BODY": "", - "ACCOUNTNAME": { - "TOOLTIP": "User defined name for the Autopilot account", - "VALIDATION_MESSAGE": { - "noSpecialCharacters": "Account Name cannot contain special characters other than -", - "cannotContainSpace": "Account Name cannot contain space", - "required": "Account Name cannot be empty", - "startingFromNumber": "Account Name cannot start with numbers" - } - }, - "USERNAME": { - "TOOLTIP": " Autopilot User Name", - "VALIDATION_MESSAGE": { - "noSpecialCharacters": "User Name cannot contain special characters other than - and _", - "cannotContainSpace": "User Name cannot contain space", - "required": "User Name cannot be empty", - "startingFromNumber": "User Name cannot start with numbers" - } - } - } - }, - "UNCHANGED_FORM": "Form is unchanged. Please make modifications in the form to enable the button.", - "INVALID_FORM": "Few fields are mandatory or invalid. Please fill the form to enable the button.", - "NO_WRITE_ACCESS": "You have only read permission. Please check with your administrator for updating permissions.", - "METRIC_TEMPLATE" : { - "APM_INFRA" : { - "TEMPLATE_NAME" : { - "TOOLTIP":"Metric Template Name", - "VALIDATION_MESSAGE": { - "required":"Template Name cannot be empty", - "noSpecialCharacters": "Template Name cannot contain special characters", - "cannotContainSpace":"Template Name cannot contain space", - "startingFromNumber": "Template Name cannot start with number", - "maxlength": "Template name should not have more than 63 characters!", - "exists": "Template already exists" - } - }, - "APM_MONITORING_PROVIDER": { - "TOOLTIP" :"Data source for Risk Analysis", - "VALIDATION_MESSAGE" : {} - }, - "APM_ACCOUNT": { - "TOOLTIP" :"APM Account", - "VALIDATION_MESSAGE" : {} - }, - "APM_APPLICATION": { - "TOOLTIP" :"APM Application", - "VALIDATION_MESSAGE" : {} - }, - "APM_API_SELECTION": { - "TOOLTIP" :"APM API Selection", - "VALIDATION_MESSAGE" : {} - }, - "INFRA_MONITORING_PROVIDER": { - "TOOLTIP" :"Data source for Risk Analysis", - "VALIDATION_MESSAGE" : {} - }, - "INFRA_ACCOUNT": { - "TOOLTIP" :"Infrastructure Account", - "VALIDATION_MESSAGE" : {} - }, - "INFRA_METRIC_GROUPS": { - "TOOLTIP" :"Infrastructure Metric Groups", - "VALIDATION_MESSAGE" : {} - }, - "FILTER_KEY": { - "TOOLTIP" :"Metric Scope Placeholder will be replaced by Baseline & New Release values in the Metric Query. For example, Scope Placeholder “pod_name” will be replaced by Baseline & New Release values in the metric query avg(container_memory_usage_bytes{pod=~'pod_name',container!=''}) for getting baseline & New Release metrics data respectively from the monitoring provider", - "VALIDATION_MESSAGE" : { - "required":"Filter Key cannot be empty", - "cannotContainSpace":"Filter Key cannot contain space" - } - }, - "BASELINE": { - "TOOLTIP" :"Baseline", - "VALIDATION_MESSAGE" : { - "required":"Baseline cannot be empty", - "cannotContainSpace":"Baseline cannot contain space" - } - }, - "NEW_RELEASE": { - "TOOLTIP" :"New Release", - "VALIDATION_MESSAGE" : { - "required":"New Release cannot be empty", - "cannotContainSpace":"New Release cannot contain space" - } - }, - "NORMALIZATION": { - "TOOLTIP" :"Apply load based normalization", - "VALIDATION_MESSAGE" : {} - }, - "THRESHOLD": { - "TOOLTIP" :"Threshold for Metric failure", - "VALIDATION_MESSAGE" : {} - }, - "SPECIFY_CRITICAL_WATCHLIST": { - "TOOLTIP" :"Specify critical/watchlist for metrics", - "VALIDATION_MESSAGE" : {} - } - }, - "CUSTOM" : { - "TEMPLATE_NAME" : { - "TOOLTIP":"Template Name", - "VALIDATION_MESSAGE": { - "required":"Template Name cannot be empty", - "noSpecialCharacters": "Template Name cannot contain special characters", - "cannotContainSpace":"Template Name cannot contain space", - "startingFromNumber": "Template Name cannot start with number", - "maxlength": "Template name should not have more than 63 characters!", - "exists": "Template already exists" - } - }, - "DATA_SOURCE": { - "TOOLTIP" :"Data source for Risk Analysis", - "VALIDATION_MESSAGE" : { - "required":"Data source cannot be empty" - } - }, - "ACCOUNT": { - "TOOLTIP": "Account", - "VALIDATION_MESSAGE": { - "required":"Account cannot be empty" - } - }, - "FILTER_KEY" :{ - "TOOLTIP":"Metric Scope Placeholder will be replaced by Baseline & New Release values in the Metric Query. For example, Scope Placeholder “pod_name” will be replaced by Baseline & New Release values in the metric query avg(container_memory_usage_bytes{pod=~'pod_name',container!=''}) for getting baseline & New Release metrics data respectively from the monitoring provider", - "VALIDATION_MESSAGE": { - "required":"Filter Key cannot be empty", - "cannotContainSpace":"Filter Key cannot contain space" - } - }, - "BASELINE" :{ - "TOOLTIP":"Baseline", - "VALIDATION_MESSAGE": { - "required":"Baseline cannot be empty", - "cannotContainSpace":"Baseline cannot contain space" - } - }, - "NEW_RELEASE" :{ - "TOOLTIP":"New Release", - "VALIDATION_MESSAGE": { - "required":"New Release cannot be empty", - "cannotContainSpace":"New Release cannot contain space" - } - }, - "ADD_NEW_QUERY": { - "TOOLTIP": "Add New Query", - "VALIDATION_MESSAGE": {} - }, - "QUERY_SELECTION" :{ - "TOOLTIP":"Query Selection", - "VALIDATION_MESSAGE": {} - }, - "QUERY_NAME": { - "TOOLTIP" :"Query Name", - "VALIDATION_MESSAGE" : { - "required":"Query Name cannot be empty" - } - }, - "QUERY_STRING": { - "TOOLTIP" :"Query String", - "VALIDATION_MESSAGE" : { - "required":"Query String cannot be empty" - } - }, - "RISK_DIRECTION": { - "TOOLTIP" :"Risk Direction", - "VALIDATION_MESSAGE" : {} - }, - "THRESHOLD": { - "TOOLTIP" :"Threshold", - "VALIDATION_MESSAGE" : {} - }, - "CRITICAL": { - "TOOLTIP" :"Critical", - "VALIDATION_MESSAGE" : {} - }, - "WATCHLIST": { - "TOOLTIP" :"Watchlist", - "VALIDATION_MESSAGE" : {} - }, - "WEIGHT": { - "TOOLTIP" :"Weight", - "VALIDATION_MESSAGE" : {} - } - } - }, - "USAGE_INSIGHTS": { - "APPLICATIONS": { - "TOOLTIP": "Application" - }, - "PIPELINES": { - "TOOLTIP": "Pipelines" - }, - "PIPELINES_WITH_INTELLIGENT_GATES": { - "TOOLTIP": "Pipelines with Intelligent Gates" - }, - "INTELLIGENT_GATES_BREAKDOWN": { - "TOOLTIP": "Intelligent Gates Breakdown" - }, - "GATES_USED": { - "TOOLTIP": "Gates Used" - }, - "USERS": { - "TOOLTIP": "Users" - } - }, - "DELIVERY_INSIGHTS": { - "PIPELINES": { - "TOOLTIP": "Pipelines" - }, - "MOST_ACTIVE_PIPELINES": { - "TOOLTIP": "Most Active Pipelines" - }, - "MOST_SUCCESSFUL_PIPELINES": { - "TOOLTIP": "Most Successful Pipelines" - }, - "MOST_FAILED_PIPELINES": { - "TOOLTIP": "Most Failed Pipelines" - }, - "FASTEST_PIPELINES": { - "TOOLTIP": "Fastest Pipelines " - }, - "SLOWEST_PIPELINES": { - "TOOLTIP": "Slowest Pipelines " - }, - "MANUAL_JUDGEMENT": { - "TOOLTIP": "Manual Judgement" - } - }, - "ACCESS_MANAGEMENT": { - "ADMINISTRATOR": { - "INFO":"Super Administrator Groups will not appear in the dropdown since their Access Permissions cannot be modified.
Administrators will have full Access to all Resources.", - "TOOLTIP": "Groups with Administration Permissions" - }, - "USER_ROLE_LISTING": { - "HEADER": "ROLE MANAGEMENT", - "BODY": "Users should be assigned user roles only if they need global access to one or more resources." - }, - "USER_ROLE_CREATION": { - "ROLENAME": { - "TOOLTIP": "", - "VALIDATION_MESSAGE": { - "required": "Role Name cannot be empty" - } - }, - "USER_GROUPS": { - "TOOLTIP": "", - "VALIDATION_MESSAGE": { - "required": "Groups cannot be empty" - } - }, - "PERMISSIONS": { - "VALIDATION_MESSAGE": { - "required": "Atleast one feature has to be enabled with permissions" - } - } - }, - "FEATURE_VISIBILTY_LISTING":{ - "HEADER": "FEATURE FLAG MANAGEMENT", - "BODY":"Feature Visibility is used for scenarios where one or more user groups need exclusive access to a specific feature. For example, the 'Compliance Team' should only access the Policy Management feature. Administrators can enable the feature flag for the compliance team user group. The feature visibility function will ensure that the policy management feature is not visible for all other user groups." - }, - "FEATURE_VISIBILTY_CREATION": { - "ROLENAME":{ - "TOOLTIP": "", - "VALIDATION_MESSAGE": { - "required":"Role Name cannot be empty" - } - }, - "USER_GROUPS":{ - "TOOLTIP": "", - "VALIDATION_MESSAGE": { - "required":"Groups cannot be empty" - } - }, - "PERMISSIONS":{ - "VALIDATION_MESSAGE":{ - "required":"Atleast one feature has to be enabled" - } - } - } - }, - "LOG_TEMPLATE": { - "STRING_PATTERN": { - "TOOLTIP": "String Pattern", - "VALIDATION_MESSAGE": { - "required": "String Pattern cannot be empty" - } - }, - "LOG_TOPICS":{ - "TOOLTIP" :"Strings that appear in logs with their characterization" - }, - "LOG_TAGS":{ - "TOOLTIP" :"Create custom tags based on business logic." - }, - "CHARACTERIZATION_TOPIC": { - "TOOLTIP": "Characterization Topic", - "VALIDATION_MESSAGE": { - "required": "Characterization Topic cannot be empty" - } - }, - "TYPE": { - "TOOLTIP": "Type", - "VALIDATION_MESSAGE": {} - }, - "ENABLE_CLUSTER_TAG": { - "TOOLTIP": "Create custom tags based on business logic.", - "VALIDATION_MESSAGE": {} - }, - "CLUSTER_TAG_STRING": { - "TOOLTIP": "The string pattern that appears in logs", - "VALIDATION_MESSAGE": { - "required": "Cluster Tag String cannot be empty" - } - }, - "CLUSTER_TAG": { - "TOOLTIP": "Cluster Tag", - "VALIDATION_MESSAGE": { - "required": "Cluster Tag cannot be empty" - } - }, - "LOG_TEMPLATE_NAME": { - "TOOLTIP": "Log Template Name", - "VALIDATION_MESSAGE": { - "required": "Template Name cannot be empty" - } - }, - "PROVIDER": { - "TOOLTIP": "Data source for Risk Analysis", - "VALIDATION_MESSAGE": { - "required": "Provider cannot be empty" - } - }, - "LOG_ACCOUNT": { - "TOOLTIP": "Account of the Log provider; Refer Integrations tab under Setup", - "VALIDATION_MESSAGE": { - "required": "Log Account cannot be empty" - } - }, - "QUERY_FILTER_KEY": { - "TOOLTIP": "Unique Key which identify logs to be processed in the Index", - "VALIDATION_MESSAGE": { - "required": "Query Filter Key cannot be empty" - } + "TOKEN": { + "TOOLTIP": "Artifactory Personal Access Token", + "VALIDATION_MESSAGE": { + "required": "Token cannot be empty" + } }, - "BASELINE": { - "TOOLTIP": "Unique value which identify baseline logs in the Index", - "VALIDATION_MESSAGE": { - "required": "Baseline cannot be empty" - } + "SPINNAKERTOGGLE": { + "TOOLTIP": "Switch On this toggle to configure the resource in a gitops enabled Spinnaker instance", + "VALIDATION_MESSAGE": {} + } + }, + "BITBUCKET": { + "HEADER": "Bitbucket Cloud", + "BODY": "

BitBucket Cloud integration can be used as a datasource for Approval Gate as well as to configure Spinnaker for BitBucket Cloud.

Fields:

  • Name: User defined name for the Bitbucket Cloud Account (Example: opsmx-bitbucket)
  • Host URL: BitBucket Cloud URL (Example: https://bitbucket.org)
  • API URL: This is needed by Autopilot to access Bitbucket Cloud resources such as accounts & repositories through API calls (Example: https://api.bitbucket.org/2.0/repositories)
  • Authentication Type: can be Token or User Name/Password
  • User Name: Bitbucket Cloud User Name
  • Token: BitBucket personal access token (Example: xCPkVZfxaE9iULmfYYkK)
  • Password: Bitbucket Cloud Password
  • Connect to Spinnaker: Toggle to configure Spinnaker for Bitbucket Cloud
  • Permissions: Enable/disable access to the Bitbucket Account in Autopilot to specific usergroups
", + "ACCOUNTNAME": { + "TOOLTIP": "User defined name for the BitBucket Cloud account", + "VALIDATION_MESSAGE": { + "noSpecialCharacters": "Account Name cannot contain special characters other than -", + "cannotContainSpace": "Account Name cannot contain space", + "required": "Account Name cannot be empty", + "startingFromNumber": "Account Name cannot start with numbers" + } }, - "NEW_RELEASE": { - "TOOLTIP": "Unique value which identify New Release logs in the Index", - "VALIDATION_MESSAGE": { - "required": "New Release cannot be empty" - } - }, - "RESPONSE_KEYWORDS": { - "TOOLTIP": "Field name in the Index containing logs to be processed", - "VALIDATION_MESSAGE": { - "required": "Response Keywords cannot be empty" - } - }, - "TIMESTAMP_KEY": { - "TOOLTIP": "Unique Key which identify the timestamp for log; this field is optional; by default, it is @timestamp for elasticsearch and timestamp for graylog", - "VALIDATION_MESSAGE": {} - }, - "AUTOBASELINE": { - "TOOLTIP": "ML based learning of the baseline from historic analysis", - "VALIDATION_MESSAGE": {} - }, - "CONTEXTUAL_CLUSTER": { - "TOOLTIP": "Enable/disable cluster of unexpected events in similar context", - "VALIDATION_MESSAGE": {} - }, - "CONTEXTUAL_WINDOW_SIZE": { - "TOOLTIP": "Number of Log events to be seen in a Context. Allowed size in between 25 and 50", - "VALIDATION_MESSAGE": { - "max": "Allowed size is in between 25 to 50", - "min": "Allowed size is in between 25 to 50" - } - }, - "INFO_CLUSTER_SCORING": { - "TOOLTIP": "Enabling this option will include INFO clusters in scoring", - "VALIDATION_MESSAGE": {} + "HOSTURL": { + "TOOLTIP": "BitBucket Cloud URL", + "VALIDATION_MESSAGE": { + "required": "Host URL cannot be empty", + "invalidUrl": "URL is invalid" + } }, - "SENSITIVITY": { - "TOOLTIP": "Impact of Unexpected Issues on the log scoring", - "VALIDATION_MESSAGE": { - "required": "Sensitivity cannot be empty" - } + "APIURL": { + "TOOLTIP": "BitBucket Cloud Api URL. This is needed by Autopilot to access Bitbucket Cloud resources such as accounts & repositories through API calls", + "VALIDATION_MESSAGE": { + "required": "API URL cannot be empty", + "invalidUrl": "URL is invalid" + } }, - "SCORING_ALGORITHM": { - "TOOLTIP": "Scoring Algorithm for Risk Analysis", - "VALIDATION_MESSAGE": {} + "AUTHENTICATIONTYPE": { + "TOOLTIP": "can be Token or User Name/Password", + "VALIDATION_MESSAGE": {} }, - "LOG_GROUP": { - "TOOLTIP": "Group of log streams that share the same retention, monitoring, and access control settings", - "VALIDATION_MESSAGE": { - "required": "Log Group cannot be empty" - } + "TOKEN": { + "TOOLTIP": "BitBucket Cloud personal access token", + "VALIDATION_MESSAGE": { + "required": "Token cannot be empty" + } }, - "LOG_STREAM": { - "TOOLTIP": "Sequence of log events that share the same source", - "VALIDATION_MESSAGE": { - "required": "Log Stream cannot be empty" - } + "USERNAME": { + "TOOLTIP": "BitBucket Cloud User Name", + "VALIDATION_MESSAGE": { + "noSpecialCharacters": "User Name cannot contain special characters other than - and _", + "cannotContainSpace": "User Name cannot contain space", + "required": "User Name cannot be empty", + "startingFromNumber": "User Name cannot start with numbers" + } }, - "REGION": { - "TOOLTIP": "Geographic area where AWS data center", - "VALIDATION_MESSAGE": { - "required": "Region cannot be empty" - } + "PASSWORD": { + "TOOLTIP": "BitBucket Cloud Password", + "VALIDATION_MESSAGE": { + "required": "Password cannot be empty" + } }, - "INDEX_PATTERN": { - "TOOLTIP": "Index containing logs for processing", - "VALIDATION_MESSAGE": { - "required": "Intex Pattern cannot be empty" - } + "SPINNAKERTOGGLE": { + "TOOLTIP": "Switch On this toggle to configure the resource in a gitops enabled Spinnaker instance", + "VALIDATION_MESSAGE": {} + } + }, + "BITBUCKET_SERVER": { + "HEADER": "Bitbucket Server", + "BODY": "

BitBucket Server integration can be used as a datasource for Approval Gate as well as to configure Spinnaker for BitBucket Server.

Fields:

  • Account Name: User defined name for the Bitbucket Server Account (Example: opsmx-bitbucket)
  • Host URL: BitBucket Server URL (Example: https://xyz.mybitbucket.com)
  • Authentication Type: can be Token or User Name/Password
  • User Name: Bitbucket Server User Name
  • Token: BitBucket Server personal access token. You can find here how to generate personal access tokens. (Example: DjpMgHmwqUnIvvmljFgqGQ)
  • Password: Bitbucket Server Password
  • Connect to Spinnaker: Toggle to configure Spinnaker for Bitbucket Server
  • Permissions: Enable/disable access to the Bitbucket Server account in Autopilot to specific usergroups
", + "ACCOUNTNAME": { + "TOOLTIP": "User defined name for the Bitbucket Server account", + "VALIDATION_MESSAGE": { + "noSpecialCharacters": "Account Name cannot contain special characters other than -", + "cannotContainSpace": "Account Name cannot contain space", + "required": "Account Name cannot be empty", + "startingFromNumber": "Account Name cannot start with numbers" + } }, - "CUSTOM_REGEX": { - "TOOLTIP": "Custom Regular Expression to filter the logs", - "VALIDATION_MESSAGE": {} + "HOSTURL": { + "TOOLTIP": "BitBucket Server URL", + "VALIDATION_MESSAGE": { + "required": "Host URL cannot be empty", + "invalidUrl": "URL is invalid" + } }, - "REGULAR_EXPRESSION": { - "TOOLTIP": "Sequence of characters that specifies a search pattern", - "VALIDATION_MESSAGE": {} + "AUTHENTICATIONTYPE": { + "TOOLTIP": "can be Token or User Name/Password", + "VALIDATION_MESSAGE": {} }, - "RESPONSE_KEY": { - "TOOLTIP": "Field name in the Index where regex to be searched", - "VALIDATION_MESSAGE": {} - }, - "STREAM_ID": { - "TOOLTIP": "The streams are a mechanism to route messages into categories in realtime while they are processed", - "VALIDATION_MESSAGE": { - "required": "Stream ID cannot be empty" - } - }, - "NAMESPACE": { - "TOOLTIP": "Namespace", - "VALIDATION_MESSAGE": { - "required": "Namespace cannot be empty" - } - }, - "TEST_CASE_KEY": { - "TOOLTIP": "Field in the log index which holds the test case names", - "VALIDATION_MESSAGE": { - "required": "Test Case Key cannot be empty" - } - }, - "TEST_SUITE_KEY": { - "TOOLTIP": "Field in the log index which holds the test suite names", - "VALIDATION_MESSAGE": { - "required": "Test Suite Key cannot be empty" - } - } - } + "TOKEN": { + "TOOLTIP": "Bitbucket Server personal access token", + "VALIDATION_MESSAGE": { + "required": "Token cannot be empty" + } + }, + "USERNAME": { + "TOOLTIP": "Bitbucket Server User Name", + "VALIDATION_MESSAGE": { + "noSpecialCharacters": "User Name cannot contain special characters other than - and _", + "cannotContainSpace": "User Name cannot contain space", + "required": "User Name cannot be empty", + "startingFromNumber": "User Name cannot start with numbers" + } + }, + "PASSWORD": { + "TOOLTIP": "Bitbucket Server Password", + "VALIDATION_MESSAGE": { + "required": "Password cannot be empty" + } + }, + "SPINNAKERTOGGLE": { + "TOOLTIP": "Switch On this toggle to configure the resource in a gitops enabled Spinnaker instance", + "VALIDATION_MESSAGE": {} + } + }, + "DOCKERHUB": { + "HEADER": "Docker Registry", + "BODY": "", + "ACCOUNTNAME": { + "TOOLTIP": "User defined name for the Docker Registry account", + "VALIDATION_MESSAGE": { + "noSpecialCharacters": "Account Name cannot contain special characters other than -", + "cannotContainSpace": "Account Name cannot contain space", + "required": "Account Name cannot be empty", + "startingFromNumber": "Account Name cannot start with numbers" + } + }, + "TOKEN": { + "TOOLTIP": "Docker Registry Personal Access Token", + "VALIDATION_MESSAGE": { + "required": "Token cannot be empty" + } + }, + "USERNAME": { + "TOOLTIP": "Docker Registry User Name", + "VALIDATION_MESSAGE": { + "noSpecialCharacters": "User Name cannot contain special characters other than - and _", + "cannotContainSpace": "User Name cannot contain space", + "required": "User Name cannot be empty", + "startingFromNumber": "User Name cannot start with numbers" + } + }, + "HOSTURL": { + "TOOLTIP": "Docker Registry Host URL", + "VALIDATION_MESSAGE": { + "required": "Host URL cannot be empty", + "invalidUrl": "URL is invalid" + } + } + }, + "OCR": { + "HEADER": "Other Container Registry", + "BODY": "", + "ACCOUNTNAME": { + "TOOLTIP": "User defined name for the Other Container Registry account", + "VALIDATION_MESSAGE": { + "noSpecialCharacters": "Account Name cannot contain special characters other than -", + "cannotContainSpace": "Account Name cannot contain space", + "required": "Account Name cannot be empty", + "startingFromNumber": "Account Name cannot start with numbers" + } + }, + "TOKEN": { + "TOOLTIP": "Container Registry Personal Access Token", + "VALIDATION_MESSAGE": { + "required": "Token cannot be empty" + } + }, + "USERNAME": { + "TOOLTIP": "Container Registry User Name", + "VALIDATION_MESSAGE": { + "noSpecialCharacters": "User Name cannot contain special characters other than - and _", + "cannotContainSpace": "User Name cannot contain space", + "required": "User Name cannot be empty", + "startingFromNumber": "User Name cannot start with numbers" + } + }, + "HOSTURL": { + "TOOLTIP": "Container Registry Host URL", + "VALIDATION_MESSAGE": { + "required": "Host URL cannot be empty", + "invalidUrl": "URL is invalid" + } + } + }, + "GITHUB": { + "HEADER": "GitHub", + "BODY": "

GIT HUB integration can be used as a datasource for Approval Gate as well as to configure Spinnaker for GitHub.

Fields:

  • Account Name: User defined name for the GitHub Account(Example: opsmx-github)
  • Token: GitHub personal access token. You can find here how to generate personal access tokens. (Example: ghp_ln1eJK4yuomnY6JREp72IDJC4Hq6Sm)
  • User Name: GitHub User Name
  • Connect to Spinnaker: Toggle to configure Spinnaker for GitHub
  • Permissions: Enable/disable access to the GIT HUB account in Autopilot to specific usergroups
", + "ACCOUNTNAME": { + "TOOLTIP": "User defined name for the GitHub account", + "VALIDATION_MESSAGE": { + "noSpecialCharacters": "Account Name cannot contain special characters other than -", + "cannotContainSpace": "Account Name cannot contain space", + "required": "Account Name cannot be empty", + "startingFromNumber": "Account Name cannot start with numbers" + } + }, + "HOSTURL": { + "TOOLTIP": "GitHub Host URL", + "VALIDATION_MESSAGE": { + "required": "Host URL cannot be empty", + "invalidUrl": "URL is invalid" + } + }, + "URL": { + "TOOLTIP": "GitHub Api URL to access resources such as accounts & repositories through API calls.", + "VALIDATION_MESSAGE": { + "required": "API URL cannot be empty", + "invalidUrl": "URL is invalid" + } + }, + "TOKEN": { + "TOOLTIP": "GitHub Personal Access Token. You can generate token (settings -> Developer Settings -> Personal access tokens -> generate new Token)", + "VALIDATION_MESSAGE": { + "required": "Token cannot be empty" + } + }, + "USERNAME": { + "TOOLTIP": "GitHub User Name", + "VALIDATION_MESSAGE": { + "noSpecialCharacters": "User Name cannot contain special characters other than - and _", + "cannotContainSpace": "User Name cannot contain space", + "required": "User Name cannot be empty", + "startingFromNumber": "User Name cannot start with numbers" + } + }, + "SPINNAKERTOGGLE": { + "TOOLTIP": "Switch On this toggle to configure the resource in a gitops enabled Spinnaker instance", + "VALIDATION_MESSAGE": {} + } + }, + "GITLAB": { + "HEADER": "GitLab", + "BODY": "", + "ACCOUNTNAME": { + "TOOLTIP": "User defined name for the GitLab account", + "VALIDATION_MESSAGE": { + "noSpecialCharacters": "Account Name cannot contain special characters other than -", + "cannotContainSpace": "Account Name cannot contain space", + "required": "Account Name cannot be empty", + "startingFromNumber": "Account Name cannot start with numbers" + } + }, + "HOSTURL": { + "TOOLTIP": "GitLab Host URL", + "VALIDATION_MESSAGE": { + "required": "Host URL cannot be empty", + "invalidUrl": "URL is invalid" + } + }, + "APIBASEURL": { + "TOOLTIP": "", + "VALIDATION_MESSAGE": { + "required": "API URL cannot be empty", + "invalidUrl": "URL is invalid" + } + }, + "TOKEN": { + "TOOLTIP": "", + "VALIDATION_MESSAGE": { + "required": "Token cannot be empty" + } + }, + "SPINNAKERTOGGLE": { + "TOOLTIP": "Switch On this toggle to configure the resource in a gitops enabled Spinnaker instance", + "VALIDATION_MESSAGE": {} + } + }, + "GITREPO": { + "HEADER": "Git Repo", + "BODY": "", + "ACCOUNTNAME": { + "TOOLTIP": "The name of the account to operate on", + "VALIDATION_MESSAGE": { + "noSpecialCharacters": "Account Name cannot contain special characters other than -", + "cannotContainSpace": "Account Name cannot contain space", + "required": "Account Name cannot be empty", + "startingFromNumber": "Account Name cannot start with numbers" + } + }, + "DEPLOYMENT": { + "TOOLTIP": "This Halyard deployment will be used for Account creation / update", + "VALIDATION_MESSAGE": { + "required": "URL cannot be empty", + "invalidUrl": "URL is invalid" + } + }, + "AUTHENTICATIONTYPE": { + "TOOLTIP": "Select how the external resource confirms the user credentials", + "VALIDATION_MESSAGE": {} + }, + "URL": { + "TOOLTIP": "", + "VALIDATION_MESSAGE": { + "required": "API URL cannot be empty", + "invalidUrl": "URL is invalid" + } + }, + "TOKEN": { + "TOOLTIP": "Git token", + "VALIDATION_MESSAGE": { + "required": "Token cannot be empty" + } + }, + "PASSWORD": { + "TOOLTIP": "Git password", + "VALIDATION_MESSAGE": { + "required": "Password cannot be empty" + } + }, + "USERNAME": { + "TOOLTIP": "Git username", + "VALIDATION_MESSAGE": { + "noSpecialCharacters": "User Name cannot contain special characters other than - and _", + "cannotContainSpace": "User Name cannot contain space", + "required": "User Name cannot be empty", + "startingFromNumber": "User Name cannot start with numbers" + } + }, + "SPINNAKERTOGGLE": { + "TOOLTIP": "Switch On this toggle to configure the resource in a gitops enabled Spinnaker instance", + "VALIDATION_MESSAGE": {} + } + }, + "HELM": { + "HEADER": "Helm", + "BODY": "", + "ACCOUNTNAME": { + "TOOLTIP": "The name of the account to operate on", + "VALIDATION_MESSAGE": { + "noSpecialCharacters": "Account Name cannot contain special characters other than -", + "cannotContainSpace": "Account Name cannot contain space", + "required": "Account Name cannot be empty", + "startingFromNumber": "Account Name cannot start with numbers" + } + }, + "REPOSITORY": { + "TOOLTIP": "URL of the Helm Chart Repository", + "VALIDATION_MESSAGE": { + "required": "URL cannot be empty", + "invalidUrl": "URL is invalid" + } + }, + "DEPLOYMENT": { + "TOOLTIP": "This Halyard deployment will be used for Account creation / update", + "VALIDATION_MESSAGE": {} + }, + "AUTHENTICATIONTYPE": { + "TOOLTIP": "Select how the external resource confirms the user credentials", + "VALIDATION_MESSAGE": {} + }, + "TOKEN": { + "TOOLTIP": "", + "VALIDATION_MESSAGE": { + "required": "Token cannot be empty" + } + }, + "USERNAME": { + "TOOLTIP": "User Name", + "VALIDATION_MESSAGE": { + "noSpecialCharacters": "User Name cannot contain special characters other than - and _", + "cannotContainSpace": "User Name cannot contain space", + "required": "User Name cannot be empty", + "startingFromNumber": "User Name cannot start with numbers" + } + }, + "PASSWORD": { + "TOOLTIP": "Password", + "VALIDATION_MESSAGE": {} + }, + "PASSWORDCOMMAND": { + "TOOLTIP": "Command to retrieve docker token/password, commands must be available in environment", + "VALIDATION_MESSAGE": {} + }, + "FILE": { + "TOOLTIP": "The path to a file containing your docker password in plaintext (not a docker/config.json file)", + "VALIDATION_MESSAGE": {} + }, + "SPINNAKERTOGGLE": { + "TOOLTIP": "Switch On this toggle to configure the resource in a gitops enabled Spinnaker instance", + "VALIDATION_MESSAGE": {} + } + }, + "HTTP": { + "HEADER": "Http", + "BODY": "", + "ACCOUNTNAME": { + "TOOLTIP": "The name of the account to operate on", + "VALIDATION_MESSAGE": { + "noSpecialCharacters": "Account Name cannot contain special characters other than -", + "cannotContainSpace": "Account Name cannot contain space", + "required": "Account Name cannot be empty", + "startingFromNumber": "Account Name cannot start with numbers" + } + }, + "AUTHENTICATIONTYPE": { + "TOOLTIP": "Select how the external resource confirms the user credentials", + "VALIDATION_MESSAGE": {} + }, + "TOKEN": { + "TOOLTIP": "", + "VALIDATION_MESSAGE": { + "required": "Token cannot be empty" + } + }, + "USERNAME": { + "TOOLTIP": "User Name", + "VALIDATION_MESSAGE": { + "noSpecialCharacters": "User Name cannot contain special characters other than - and _", + "cannotContainSpace": "User Name cannot contain space", + "required": "User Name cannot be empty", + "startingFromNumber": "User Name cannot start with numbers" + } + }, + "PASSWORD": { + "TOOLTIP": "Password", + "VALIDATION_MESSAGE": {} + }, + "PASSWORDCOMMAND": { + "TOOLTIP": "Command to retrieve docker token/password, commands must be available in environment", + "VALIDATION_MESSAGE": {} + }, + "FILE": { + "TOOLTIP": "The path to a file containing your docker password in plaintext (not a docker/config.json file)", + "VALIDATION_MESSAGE": {} + }, + "SPINNAKERTOGGLE": { + "TOOLTIP": "Switch On this toggle to configure the resource in a gitops enabled Spinnaker instance", + "VALIDATION_MESSAGE": {} + } + }, + "GCS": { + "HEADER": "GCS", + "BODY": "", + "ACCOUNTNAME": { + "TOOLTIP": "The name of the account to operate on", + "VALIDATION_MESSAGE": { + "noSpecialCharacters": "Account Name cannot contain special characters other than -", + "cannotContainSpace": "Account Name cannot contain space", + "required": "Account Name cannot be empty", + "startingFromNumber": "Account Name cannot start with numbers" + } + }, + "AUTHENTICATIONTYPE": { + "TOOLTIP": "Select how the external resource confirms the user credentials", + "VALIDATION_MESSAGE": {} + }, + "FILE": { + "TOOLTIP": "JSON service account that Spinnaker will use as credentials", + "VALIDATION_MESSAGE": {} + }, + "SPINNAKERTOGGLE": { + "TOOLTIP": "Switch On this toggle to configure the resource in a gitops enabled Spinnaker instance", + "VALIDATION_MESSAGE": {} + } + }, + "ECR": { + "HEADER": "ECR", + "BODY": "", + "ACCOUNTNAME": { + "TOOLTIP": "The name of the account to operate on", + "VALIDATION_MESSAGE": { + "noSpecialCharacters": "Account Name cannot contain special characters other than -", + "cannotContainSpace": "Account Name cannot contain space", + "required": "Account Name cannot be empty", + "startingFromNumber": "Account Name cannot start with numbers" + } + }, + "REPOSITORIES": { + "TOOLTIP": "An optional list of repositories to cache images from", + "VALIDATION_MESSAGE": { + "cannotContainSpace": "Repository cannot contain space", + "startingFromNumber": "Repository cannot start with numbers" + } + }, + "REGISTRYURL": { + "TOOLTIP": "The registry address you want to pull and deploy images from. For example: gcr.io", + "VALIDATION_MESSAGE": {} + }, + "GROUPMEMBERSHIP": { + "TOOLTIP": "A user must be a member of at least one specified group in order to make changes to this account’s cloud resources", + "VALIDATION_MESSAGE": { + "cannotContainSpace": "Repository cannot contain space" + } + }, + "REGION": { + "TOOLTIP": "AWS region" + }, + "EMAIL": { + "TOOLTIP": "Your docker registry email", + "VALIDATION_MESSAGE": { + "email": "Email Id is invalid", + "required": "Email Id cannot be empty" + } + }, + "AUTHENTICATIONTYPE": { + "TOOLTIP": "Select how the external resource confirms the user credentials", + "VALIDATION_MESSAGE": {} + }, + "TOKEN": { + "TOOLTIP": "", + "VALIDATION_MESSAGE": { + "required": "Token cannot be empty" + } + }, + "USERNAME": { + "TOOLTIP": "GCR User Name", + "VALIDATION_MESSAGE": { + "noSpecialCharacters": "User Name cannot contain special characters other than - and _", + "cannotContainSpace": "User Name cannot contain space", + "required": "User Name cannot be empty", + "startingFromNumber": "User Name cannot start with numbers" + } + }, + "PASSWORD": { + "TOOLTIP": "Your docker registry password", + "VALIDATION_MESSAGE": {} + }, + "PASSWORDCOMMAND": { + "TOOLTIP": "Command to retrieve docker token/password, commands must be available in environment", + "VALIDATION_MESSAGE": {} + }, + "FILE": { + "TOOLTIP": "The path to a file containing your docker password in plaintext (not a docker/config.json file)", + "VALIDATION_MESSAGE": {} + }, + "SPINNAKERTOGGLE": { + "TOOLTIP": "Switch On this toggle to configure the resource in a gitops enabled Spinnaker instance", + "VALIDATION_MESSAGE": {} + } + }, + "PUBSUB": { + "HEADER": "PUBSUB", + "BODY": "", + "ACCOUNTNAME": { + "TOOLTIP": "The name of the account to operate on", + "VALIDATION_MESSAGE": { + "noSpecialCharacters": "Account Name cannot contain special characters other than -", + "cannotContainSpace": "Account Name cannot contain space", + "required": "Account Name cannot be empty", + "startingFromNumber": "Account Name cannot start with numbers" + } + }, + "PROJECTNAME": { + "TOOLTIP": "The name of the GCP project your subscription lives in", + "VALIDATION_MESSAGE": { + "cannotContainSpace": "Project Name cannot contain space", + "required": "Project Name cannot be empty" + } + }, + "SUBSCRIPTIONNAME": { + "TOOLTIP": "The name of the subscription to listen to. This identifier does not include the name of the project, and must already be configured for Spinnaker to work.", + "VALIDATION_MESSAGE": { + "cannotContainSpace": "Subscription Name cannot contain space", + "required": "Subscription Name cannot be empty" + } + }, + "MESSAGEFORMAT": { + "TOOLTIP": "Supporting Message Formats: GCB,GCS,GCR,CUSTOM", + "VALIDATION_MESSAGE": {} + }, + "TEMPLATEFILE": { + "TOOLTIP": "Applicable only for CUSTOM message format", + "VALIDATION_MESSAGE": {} + }, + "AUTHENTICATIONTYPE": { + "TOOLTIP": "Select how the external resource confirms the user credentials", + "VALIDATION_MESSAGE": {} + }, + "FILE": { + "TOOLTIP": "JSON service account that Spinnaker will use as credentials", + "VALIDATION_MESSAGE": {} + }, + "SPINNAKERTOGGLE": { + "TOOLTIP": "Switch On this toggle to configure the resource in a gitops enabled Spinnaker instance", + "VALIDATION_MESSAGE": {} + } + }, + "GCB": { + "HEADER": "GCB", + "BODY": "", + "ACCOUNTNAME": { + "TOOLTIP": "The name of the account to operate on", + "VALIDATION_MESSAGE": { + "noSpecialCharacters": "Account Name cannot contain special characters other than -", + "cannotContainSpace": "Account Name cannot contain space", + "required": "Account Name cannot be empty", + "startingFromNumber": "Account Name cannot start with numbers" + } + }, + "PROJECTNAME": { + "TOOLTIP": "The name of the GCP project in which to trigger and monitor builds", + "VALIDATION_MESSAGE": { + "cannotContainSpace": "Project Name cannot contain space", + "required": "Project Name cannot be empty" + } + }, + "SUBSCRIPTIONNAME": { + "TOOLTIP": "The name of the PubSub subscription on which to listen for build changes", + "VALIDATION_MESSAGE": { + "cannotContainSpace": "Subscription Name cannot contain space", + "required": "Subscription Name cannot be empty" + } + }, + "AUTHENTICATIONTYPE": { + "TOOLTIP": "Select how the external resource confirms the user credentials", + "VALIDATION_MESSAGE": {} + }, + "FILE": { + "TOOLTIP": "JSON service account that Spinnaker will use as credentials", + "VALIDATION_MESSAGE": {} + }, + "USERNAME": { + "TOOLTIP": "GCB User Name", + "VALIDATION_MESSAGE": { + "noSpecialCharacters": "User Name cannot contain special characters other than - and _", + "cannotContainSpace": "User Name cannot contain space", + "required": "User Name cannot be empty", + "startingFromNumber": "User Name cannot start with numbers" + } + }, + "PASSWORD": { + "TOOLTIP": "Password", + "VALIDATION_MESSAGE": {} + }, + "SPINNAKERTOGGLE": { + "TOOLTIP": "Switch On this toggle to configure the resource in a gitops enabled Spinnaker instance", + "VALIDATION_MESSAGE": {} + } + }, + "GCR": { + "HEADER": "GCR", + "BODY": "", + "ACCOUNTNAME": { + "TOOLTIP": "The name of the account to operate on", + "VALIDATION_MESSAGE": { + "noSpecialCharacters": "Account Name cannot contain special characters other than -", + "cannotContainSpace": "Account Name cannot contain space", + "required": "Account Name cannot be empty", + "startingFromNumber": "Account Name cannot start with numbers" + } + }, + "AUTHENTICATIONTYPE": { + "TOOLTIP": "Select how the external resource confirms the user credentials", + "VALIDATION_MESSAGE": {} + }, + "REPOSITORIES": { + "TOOLTIP": "An optional list of repositories to cache images from", + "VALIDATION_MESSAGE": { + "cannotContainSpace": "Repository cannot contain space", + "startingFromNumber": "Repository cannot start with numbers" + } + }, + "REGISTRYURL": { + "TOOLTIP": "The registry address you want to pull and deploy images from. For example: gcr.io", + "VALIDATION_MESSAGE": {} + }, + "REQUIREDGROUPMEMBERSHIP": { + "TOOLTIP": "A user must be a member of at least one specified group in order to make changes to this account’s cloud resources", + "VALIDATION_MESSAGE": { + "cannotContainSpace": "Repository cannot contain space" + } + }, + "EMAIL": { + "TOOLTIP": "Your docker registry email", + "VALIDATION_MESSAGE": { + "email": "Email Id is invalid", + "required": "Email Id cannot be empty" + } + }, + "URL": { + "TOOLTIP": "", + "VALIDATION_MESSAGE": { + "required": "API URL cannot be empty", + "invalidUrl": "URL is invalid" + } + }, + "TOKEN": { + "TOOLTIP": "", + "VALIDATION_MESSAGE": { + "required": "Token cannot be empty" + } + }, + "USERNAME": { + "TOOLTIP": "GCR User Name", + "VALIDATION_MESSAGE": { + "noSpecialCharacters": "User Name cannot contain special characters other than - and _", + "cannotContainSpace": "User Name cannot contain space", + "required": "User Name cannot be empty", + "startingFromNumber": "User Name cannot start with numbers" + } + }, + "PASSWORD": { + "TOOLTIP": "Your docker registry password", + "VALIDATION_MESSAGE": {} + }, + "PASSWORDCOMMAND": { + "TOOLTIP": "Command to retrieve docker token/password, commands must be available in environment", + "VALIDATION_MESSAGE": {} + }, + "FILE": { + "TOOLTIP": "The path to a file containing your docker password in plaintext (not a docker/config.json file)", + "VALIDATION_MESSAGE": {} + }, + "SPINNAKERTOGGLE": { + "TOOLTIP": "Switch On this toggle to configure the resource in a gitops enabled Spinnaker instance", + "VALIDATION_MESSAGE": {} + } + }, + "BAMBOO": { + "HEADER": "Bamboo CI", + "BODY": "

Bamboo CI integration can be used as a datasource for Approval Gate.

Fields:

  • Name: User defined name for the Bamboo CI Account (Example: opsmx-bamboo)
  • Endpoint: Bamboo CI URL (Example: https://xyz.mybamboo.com)
  • Token: Bamboo CI personal access token. You can find here how to generate personal access tokens. (Example: YmFrwqw0w9r90skfsOk9wcdd014p98kklw==)
  • User Name: Bamboo CI User Name
  • Password: Bamboo CI Password
  • Permissions: Enable/disable access to the Bamboo CI account in Autopilot to specific usergroups
", + "ACCOUNTNAME": { + "TOOLTIP": "User defined name for the Bamboo CI account", + "VALIDATION_MESSAGE": { + "noSpecialCharacters": "Account Name cannot contain special characters other than -", + "cannotContainSpace": "Account Name cannot contain space", + "required": "Account Name cannot be empty", + "startingFromNumber": "Account Name cannot start with numbers" + } + }, + "ENDPOINT": { + "TOOLTIP": "Bamboo CI URL", + "VALIDATION_MESSAGE": { + "required": "Bamboo End Point cannot be empty", + "invalidUrl": "URL is invalid" + } + }, + "AUTHENTICATIONTYPE": { + "TOOLTIP": "can be Token or User Name/Password", + "VALIDATION_MESSAGE": {} + }, + "TOKEN": { + "TOOLTIP": "Bamboo CI personal access token", + "VALIDATION_MESSAGE": { + "required": "Token cannot be empty" + } + }, + "USERNAME": { + "TOOLTIP": "Bamboo CI User Name", + "VALIDATION_MESSAGE": { + "noSpecialCharacters": "User Name cannot contain special characters other than - and _", + "cannotContainSpace": "User Name cannot contain space", + "required": "User Name cannot be empty", + "startingFromNumber": "User Name cannot start with numbers" + } + }, + "PASSWORD": { + "TOOLTIP": "Bamboo CI Password", + "VALIDATION_MESSAGE": { + "required": "Password cannot be empty" + } + } + }, + "JENKINS": { + "HEADER": "Jenkins", + "BODY": "

Jenkins integration can be used as a datasource for Approval Gate as well as to configure Spinnaker for Jenkins.

Fields:

  • Account Name: User defined name for the Jenkins Account (Example: opsmx-jenkins)
  • Host URL: Jenkins URL (Example: https://xyz.my-jenkins.com/jenkins)
  • Authentication Type: can be Token or User Name/Password
  • Token: Jenkins personal access token. You can find here how to generate personal access tokens. (Example: 77d67609a841b1811a114b7fbfa109b3c2)
  • User Name: Jenkins User Name
  • Password: Jenkins Password
  • Connect to Spinnaker: Toggle to configure Spinnaker for Jenkins
  • Permissions: Enable/disable access to the Jenkins account in Autopilot to specific usergroups
", + "ACCOUNTNAME": { + "TOOLTIP": "User defined name for the Jenkins account", + "VALIDATION_MESSAGE": { + "noSpecialCharacters": "Account Name cannot contain special characters other than -", + "cannotContainSpace": "Account Name cannot contain space", + "required": "Account Name cannot be empty", + "startingFromNumber": "Account Name cannot start with numbers" + } + }, + "HOSTURL": { + "TOOLTIP": "Jenkins URL", + "VALIDATION_MESSAGE": { + "required": "Host URL cannot be empty", + "invalidUrl": "URL is invalid" + } + }, + "AUTHENTICATIONTYPE": { + "TOOLTIP": "can be Token or User Name/Password", + "VALIDATION_MESSAGE": {} + }, + "TOKEN": { + "TOOLTIP": "Jenkins personal access token", + "VALIDATION_MESSAGE": { + "required": "Token cannot be empty" + } + }, + "USERNAME": { + "TOOLTIP": "Jenkins User Name", + "VALIDATION_MESSAGE": { + "noSpecialCharacters": "User Name cannot contain special characters other than - and _", + "cannotContainSpace": "User Name cannot contain space", + "required": "User Name cannot be empty", + "startingFromNumber": "User Name cannot start with numbers" + } + }, + "PASSWORD": { + "TOOLTIP": "Jenkins Password", + "VALIDATION_MESSAGE": { + "required": "Password cannot be empty" + } + }, + "SPINNAKERTOGGLE": { + "TOOLTIP": "Switch On this toggle to configure the resource in a gitops enabled Spinnaker instance", + "VALIDATION_MESSAGE": {} + } + }, + "JIRA": { + "HEADER": "Jira", + "BODY": "", + "ACCOUNTNAME": { + "TOOLTIP": "User defined name for the Jira account", + "VALIDATION_MESSAGE": { + "noSpecialCharacters": "Account Name cannot contain special characters other than -", + "cannotContainSpace": "Account Name cannot contain space", + "required": "Account Name cannot be empty", + "startingFromNumber": "Account Name cannot start with numbers" + } + }, + "EMAIL": { + "TOOLTIP": "Jira Email Id", + "VALIDATION_MESSAGE": { + "email": "Email Id is invalid", + "required": "Email Id cannot be empty" + } + }, + "TOKEN": { + "TOOLTIP": "Jira Personal Access Token", + "VALIDATION_MESSAGE": { + "required": "Token cannot be empty" + } + }, + "HOSTURL": { + "TOOLTIP": "Jira Host URL", + "VALIDATION_MESSAGE": { + "required": "Host URL cannot be empty", + "invalidUrl": "URL is invalid" + } + }, + "SPINNAKERTOGGLE": { + "TOOLTIP": "Switch On this toggle to configure the resource in a gitops enabled Spinnaker instance", + "VALIDATION_MESSAGE": {} + } + }, + "SERVICENOW": { + "HEADER": "Service Now", + "BODY": "", + "ACCOUNTNAME": { + "TOOLTIP": "User defined name for the Service Now account", + "VALIDATION_MESSAGE": { + "noSpecialCharacters": "Account Name cannot contain special characters other than -", + "cannotContainSpace": "Account Name cannot contain space", + "required": "Account Name cannot be empty", + "startingFromNumber": "Account Name cannot start with numbers" + } + }, + "USERNAME": { + "TOOLTIP": "Service Now User Name", + "VALIDATION_MESSAGE": { + "noSpecialCharacters": "User Name cannot contain special characters other than - and _", + "cannotContainSpace": "User Name cannot contain space", + "required": "User Name cannot be empty", + "startingFromNumber": "User Name cannot start with numbers" + } + }, + "PASSWORD": { + "TOOLTIP": "Service Now Password", + "VALIDATION_MESSAGE": { + "required": "Password cannot be empty" + } + }, + "HOSTURL": { + "TOOLTIP": "Service Now Host URL", + "VALIDATION_MESSAGE": { + "required": "Host URL cannot be empty", + "invalidUrl": "URL is invalid" + } + } + }, + "APPDYNAMICS": { + "HEADER": "APPDYNAMICS", + "BODY": "", + "ACCOUNTNAME": { + "TOOLTIP": "User defined name for the APPDYNAMICS account", + "VALIDATION_MESSAGE": { + "noSpecialCharacters": "Account Name cannot contain special characters other than -", + "cannotContainSpace": "Account Name cannot contain space", + "required": "Account Name cannot be empty", + "startingFromNumber": "Account Name cannot start with numbers" + } + }, + "CONTROLLERHOST": { + "TOOLTIP": "APPDYNAMICS Controller Host", + "VALIDATION_MESSAGE": { + "required": "Controller Host cannot be empty", + "invalidUrl": "URL is invalid" + } + }, + "TEMPORARYACCESSTOKEN": { + "TOOLTIP": "APPDYNAMICS Personal Temporary Access Token", + "VALIDATION_MESSAGE": { + "required": "Temporary Access Token cannot be empty" + } + } + }, + "CLOUDWATCH": { + "HEADER": "AWS-CLOUDWATCH", + "BODY": "", + "ACCOUNTNAME": { + "TOOLTIP": "User defined name for the AWS-CLOUDWATCH account", + "VALIDATION_MESSAGE": { + "noSpecialCharacters": "Account Name cannot contain special characters other than -", + "cannotContainSpace": "Account Name cannot contain space", + "required": "Account Name cannot be empty", + "startingFromNumber": "Account Name cannot start with numbers" + } + }, + "ACCESS_ID": { + "TOOLTIP": "AWS-CLOUDWATCH Access Key Id", + "VALIDATION_MESSAGE": { + "required": "Access Key Id cannot be empty" + } + }, + "SECRET_KEY": { + "TOOLTIP": "AWS-CLOUDWATCH Secret Access Key", + "VALIDATION_MESSAGE": { + "required": "Secret Access Key cannot be empty" + } + } + }, + "DATADOG": { + "HEADER": "DATADOG", + "BODY": "", + "ACCOUNTNAME": { + "TOOLTIP": "User defined name for the DATADOG account", + "VALIDATION_MESSAGE": { + "noSpecialCharacters": "Account Name cannot contain special characters other than -", + "cannotContainSpace": "Account Name cannot contain space", + "required": "Account Name cannot be empty", + "startingFromNumber": "Account Name cannot start with numbers" + } + }, + "API_KEY": { + "TOOLTIP": "DATADOG Api Key", + "VALIDATION_MESSAGE": { + "required": "Application Key cannot be empty" + } + }, + "APPLICATION_KEY": { + "TOOLTIP": "DATADOG Application Key", + "VALIDATION_MESSAGE": { + "required": "Application Key cannot be empty" + } + } + }, + "DYNATRACE": { + "HEADER": "Dynatrace", + "BODY": "", + "ACCOUNTNAME": { + "TOOLTIP": "User defined name for the Dynatrace account", + "VALIDATION_MESSAGE": { + "noSpecialCharacters": "Account Name cannot contain special characters other than -", + "cannotContainSpace": "Account Name cannot contain space", + "required": "Account Name cannot be empty", + "startingFromNumber": "Account Name cannot start with numbers" + } + }, + "END_POINT": { + "TOOLTIP": "Dynatrace URL", + "VALIDATION_MESSAGE": { + "required": "Url cannot be empty", + "invalidUrl": "URL is invalid" + } + }, + "API_TOKEN": { + "TOOLTIP": "Dynatrace Personal Access Token", + "VALIDATION_MESSAGE": { + "required": "Api Token cannot be empty" + } + } + }, + "ELASTICSEARCH": { + "HEADER": "Elasticsearch", + "BODY": "", + "ACCOUNTNAME": { + "TOOLTIP": "User defined name for the Elasticsearch account", + "VALIDATION_MESSAGE": { + "noSpecialCharacters": "Account Name cannot contain special characters other than -", + "cannotContainSpace": "Account Name cannot contain space", + "required": "Account Name cannot be empty", + "startingFromNumber": "Account Name cannot start with numbers" + } + }, + "ENDPOINT": { + "TOOLTIP": "ElasticSearch End Point", + "VALIDATION_MESSAGE": { + "required": "Elastic End Point cannot be empty", + "invalidUrl": "URL is invalid" + } + }, + "USERNAME": { + "TOOLTIP": "ElasticSearch User Name", + "VALIDATION_MESSAGE": { + "noSpecialCharacters": "User Name cannot contain special characters other than - and _", + "cannotContainSpace": "User Name cannot contain space", + "startingFromNumber": "User Name cannot start with numbers" + } + }, + "PASSWORD": { + "TOOLTIP": "ElasticSearch Password", + "VALIDATION_MESSAGE": { + "required": "Password cannot be empty" + } + }, + "KIBANAENDPOINT": { + "TOOLTIP": "ElasticSearch Kibana End Point", + "VALIDATION_MESSAGE": { + "required": "Kibana End Point cannot be empty", + "invalidUrl": "URL is invalid" + } + }, + "KIBANAUSERNAME": { + "TOOLTIP": "ElasticSearch Kibana User Name", + "VALIDATION_MESSAGE": { + "noSpecialCharacters": "Kibana User Name cannot contain special characters other than - and _", + "cannotContainSpace": "Kibana User Name cannot contain space", + "required": "Kibana User Name cannot be empty", + "startingFromNumber": "Kibana User Name cannot start with numbers" + } + }, + "KIBANAPASSWORD": { + "TOOLTIP": "ElasticSearch Kibana Password", + "VALIDATION_MESSAGE": { + "required": "Kibana Password cannot be empty" + } + } + }, + "GRAPHITE": { + "HEADER": "Graphite", + "BODY": "", + "ACCOUNTNAME": { + "TOOLTIP": "User defined name for the Graphite account", + "VALIDATION_MESSAGE": { + "noSpecialCharacters": "Account Name cannot contain special characters other than -", + "cannotContainSpace": "Account Name cannot contain space", + "required": "Account Name cannot be empty", + "startingFromNumber": "Account Name cannot start with numbers" + } + }, + "URL": { + "TOOLTIP": "Graphite End Point", + "VALIDATION_MESSAGE": { + "required": "End Point cannot be empty", + "invalidUrl": "URL is invalid" + } + } + }, + "GRAYLOG": { + "HEADER": "GRAYLOG", + "BODY": "", + "ACCOUNTNAME": { + "TOOLTIP": "User defined name for the GRAYLOG account", + "VALIDATION_MESSAGE": { + "noSpecialCharacters": "Account Name cannot contain special characters other than -", + "cannotContainSpace": "Account Name cannot contain space", + "required": "Account Name cannot be empty", + "startingFromNumber": "Account Name cannot start with numbers" + } + }, + "ENDPOINT": { + "TOOLTIP": "GrayLog End Point", + "VALIDATION_MESSAGE": { + "required": "End Point cannot be empty", + "invalidUrl": "URL is invalid" + } + }, + "TOKEN": { + "TOOLTIP": "GrayLog Personal Access Token", + "VALIDATION_MESSAGE": { + "required": "Token cannot be empty" + } + } + }, + "NEWRELIC": { + "HEADER": "New Relic", + "BODY": "", + "ACCOUNTNAME": { + "TOOLTIP": "User defined name for the New Relic account", + "VALIDATION_MESSAGE": { + "noSpecialCharacters": "Account Name cannot contain special characters other than -", + "cannotContainSpace": "Account Name cannot contain space", + "required": "Account Name cannot be empty", + "startingFromNumber": "Account Name cannot start with numbers" + } + }, + "APIKEY": { + "TOOLTIP": "NewRelic Api Key", + "VALIDATION_MESSAGE": { + "required": "Token cannot be empty" + } + }, + "APPLICATIONKEY": { + "TOOLTIP": "NewRelic Application Key", + "VALIDATION_MESSAGE": { + "required": "Token cannot be empty" + } + }, + "ACCOUNTID": { + "TOOLTIP": "NewRelic Account Id", + "VALIDATION_MESSAGE": { + "required": "Token cannot be empty" + } + }, + "QUERYKEY": { + "TOOLTIP": "NewRelic Query Key", + "VALIDATION_MESSAGE": { + "required": "Token cannot be empty" + } + } + }, + "PROMETHEUS": { + "HEADER": "Prometheus", + "BODY": "", + "ACCOUNTNAME": { + "TOOLTIP": "User defined name for the Prometheus account", + "VALIDATION_MESSAGE": { + "noSpecialCharacters": "Account Name cannot contain special characters other than -", + "cannotContainSpace": "Account Name cannot contain space", + "required": "Account Name cannot be empty", + "startingFromNumber": "Account Name cannot start with numbers" + } + }, + "ENDPOINT": { + "TOOLTIP": "Prometheus End Point", + "VALIDATION_MESSAGE": { + "required": "End Point cannot be empty", + "invalidUrl": "URL is invalid" + } + }, + "USERNAME": { + "TOOLTIP": "Prometheus User Name", + "VALIDATION_MESSAGE": { + "noSpecialCharacters": "User Name cannot contain special characters other than - and _", + "cannotContainSpace": "User Name cannot contain space", + "required": "User Name cannot be empty", + "startingFromNumber": "User Name cannot start with numbers" + } + }, + "PASSWORD": { + "TOOLTIP": "Prometheus Password", + "VALIDATION_MESSAGE": { + "required": "Password cannot be empty" + } + } + }, + "SPLUNK": { + "HEADER": "Splunk", + "BODY": "", + "ACCOUNTNAME": { + "TOOLTIP": "User defined name for the Splunk account", + "VALIDATION_MESSAGE": { + "noSpecialCharacters": "Account Name cannot contain special characters other than -", + "cannotContainSpace": "Account Name cannot contain space", + "required": "Account Name cannot be empty", + "startingFromNumber": "Account Name cannot start with numbers" + } + }, + "END_POINT": { + "TOOLTIP": "Splunk Splunk URL", + "VALIDATION_MESSAGE": { + "required": "Splunk Url cannot be empty", + "invalidUrl": "URL is invalid" + } + }, + "PASSWORD": { + "TOOLTIP": "Splunk Password", + "VALIDATION_MESSAGE": { + "required": "Password cannot be empty" + } + }, + "USER_NAME": { + "TOOLTIP": "Splunk User Name", + "VALIDATION_MESSAGE": { + "noSpecialCharacters": "Account Name cannot contain special characters other than -", + "cannotContainSpace": "Account Name cannot contain space", + "required": "Account Name cannot be empty", + "startingFromNumber": "Account Name cannot start with numbers" + } + }, + "DASHBOARD_ENDPOINT": { + "TOOLTIP": "Splunk DashBoard URL", + "VALIDATION_MESSAGE": { + "required": "Splunk DashBoard Url cannot be empty", + "invalidUrl": "URL is invalid" + } + } + }, + "STACKDRIVER": { + "HEADER": "Stackdriver", + "BODY": "", + "ACCOUNTNAME": { + "TOOLTIP": "User defined name for the Stackdriver account", + "VALIDATION_MESSAGE": { + "noSpecialCharacters": "Account Name cannot contain special characters other than -", + "cannotContainSpace": "Account Name cannot contain space", + "required": "Account Name cannot be empty", + "startingFromNumber": "Account Name cannot start with numbers" + } + }, + "KEY_FILE": { + "TOOLTIP": "Stackdriver Encrypted Key file", + "VALIDATION_MESSAGE": { + "required": "Encrypted Key File cannot be empty" + } + } + }, + "SUMOLOGIC": { + "HEADER": "Sumo Logic", + "BODY": "", + "ACCOUNTNAME": { + "TOOLTIP": "User defined name for the Sumologic account", + "VALIDATION_MESSAGE": { + "noSpecialCharacters": "Account Name cannot contain special characters other than -", + "cannotContainSpace": "Account Name cannot contain space", + "required": "Account Name cannot be empty", + "startingFromNumber": "Account Name cannot start with numbers" + } + }, + "ACCESSID": { + "TOOLTIP": "sumologic Access Id. You can generate Access Id (Administration > Security > Access Keys)", + "VALIDATION_MESSAGE": { + "required": "Access Id cannot be empty" + } + }, + "ACCESSKEY": { + "TOOLTIP": "sumologic Access Key. You can generate Access Id (Administration > Security > Access Keys)", + "VALIDATION_MEeSSAGE": { + "required": "Access Key cannot be empty" + } + }, + "ZONE": { + "TOOLTIP": "sumologic Zone", + "VALIDATION_MESSAGE": { + "noSpecialCharacters": "Zone cannot contain special characters other than -", + "cannotContainSpace": "Zone cannot contain space", + "required": "Zone cannot be empty", + "startingFromNumber": "Zone cannot start with numbers" + } + } + }, + "VMWARETANZU": { + "HEADER": "VMWare Tanzu Observability", + "BODY": "", + "ACCOUNTNAME": { + "TOOLTIP": "User defined name for the VMWare Tanzu Observability account", + "VALIDATION_MESSAGE": { + "noSpecialCharacters": "Account Name cannot contain special characters other than -", + "cannotContainSpace": "Account Name cannot contain space", + "required": "Account Name cannot be empty", + "startingFromNumber": "Account Name cannot start with numbers" + } + }, + "END_POINT": { + "TOOLTIP": "VMWare Tanzu Observability URL", + "VALIDATION_MESSAGE": { + "required": "Url cannot be empty", + "invalidUrl": "URL is invalid" + } + }, + "EMAIL": { + "TOOLTIP": "VMWare Tanzu Observability Email Id", + "VALIDATION_MESSAGE": { + "email": "Email Id is invalid", + "required": "Email Id cannot be empty" + } + }, + "API_TOKEN": { + "TOOLTIP": "VMWare Tanzu Observability Personal Access Token", + "VALIDATION_MESSAGE": { + "required": "Api Token cannot be empty" + } + } + }, + "MSTEAMS": { + "HEADER": "Microsoft Teams", + "BODY": "" + }, + "SLACK": { + "HEADER": "Slack", + "BODY": "", + "ACCOUNTNAME": { + "TOOLTIP": "User defined name for the Slack account", + "VALIDATION_MESSAGE": { + "noSpecialCharacters": "Account Name cannot contain special characters other than -", + "cannotContainSpace": "Account Name cannot contain space", + "required": "Account Name cannot be empty", + "startingFromNumber": "Account Name cannot start with numbers" + } + }, + "BOTNAME": { + "TOOLTIP": "Slack Bot Name", + "VALIDATION_MESSAGE": { + "noSpecialCharacters": "Bot Name cannot contain special characters other than -", + "cannotContainSpace": "Bot Name cannot contain space", + "required": "Bot Name cannot be empty", + "startingFromNumber": "Bot Name cannot start with numbers" + } + }, + "TOKEN": { + "TOOLTIP": "Slack Personal Access Token", + "VALIDATION_MESSAGE": { + "required": "Token cannot be empty" + } + }, + "SPINNAKERTOGGLE": { + "TOOLTIP": "Switch On this toggle to configure the resource in a gitops enabled Spinnaker instance", + "VALIDATION_MESSAGE": {} + } + }, + "OPA": { + "HEADER": "OPA", + "BODY": "", + "ACCOUNTNAME": { + "TOOLTIP": "User defined name for the OPA account", + "VALIDATION_MESSAGE": { + "noSpecialCharacters": "Account Name cannot contain special characters other than -", + "cannotContainSpace": "Account Name cannot contain space", + "required": "Account Name cannot be empty", + "startingFromNumber": "Account Name cannot start with numbers" + } + }, + "ENDPOINT": { + "TOOLTIP": "OPA End Point", + "VALIDATION_MESSAGE": { + "required": "End Point cannot be empty", + "invalidUrl": "URL is invalid" + } + } + }, + "AQUAWAVE": { + "HEADER": "Aqua Wave", + "BODY": "", + "ACCOUNTNAME": { + "TOOLTIP": "User defined name for the Aqua Wave account", + "VALIDATION_MESSAGE": { + "noSpecialCharacters": "Account Name cannot contain special characters other than -", + "cannotContainSpace": "Account Name cannot contain space", + "required": "Account Name cannot be empty", + "startingFromNumber": "Account Name cannot start with numbers" + } + }, + "USERNAME": { + "TOOLTIP": "Aqua Wave User Name", + "VALIDATION_MESSAGE": { + "noSpecialCharacters": "User Name cannot contain special characters other than - and _", + "cannotContainSpace": "User Name cannot contain space", + "required": "User Name cannot be empty", + "startingFromNumber": "User Name cannot start with numbers" + } + }, + "TOKEN": { + "TOOLTIP": "Aqua Wave Personal Access Token", + "VALIDATION_MESSAGE": { + "required": "Token cannot be empty" + } + } + }, + "APPSCAN": { + "HEADER": "HCL AppScan", + "BODY": "", + "ACCOUNTNAME": { + "TOOLTIP": "User defined name for the HCL AppScan account", + "VALIDATION_MESSAGE": { + "noSpecialCharacters": "Account Name cannot contain special characters other than -", + "cannotContainSpace": "Account Name cannot contain space", + "required": "Account Name cannot be empty", + "startingFromNumber": "Account Name cannot start with numbers" + } + }, + "TOKEN": { + "TOOLTIP": "Appscan Personal Access Token", + "VALIDATION_MESSAGE": { + "required": "Token cannot be empty" + } + } + }, + "JFROG": { + "HEADER": "JFrog XRay Scanning", + "BODY": "", + "ACCOUNTNAME": { + "TOOLTIP": "User defined name for the JFrog XRay Scanning account", + "VALIDATION_MESSAGE": { + "noSpecialCharacters": "Account Name cannot contain special characters other than -", + "cannotContainSpace": "Account Name cannot contain space", + "required": "Account Name cannot be empty", + "startingFromNumber": "Account Name cannot start with numbers" + } + }, + "ENDPOINT": { + "TOOLTIP": "JFrog URL", + "VALIDATION_MESSAGE": { + "required": "Endpoint cannot be empty", + "invalidUrl": "URL is invalid" + } + }, + "TOKEN": { + "TOOLTIP": "JFrog Personal Access Token", + "VALIDATION_MESSAGE": { + "required": "Token cannot be empty" + } + } + }, + "PRISMACLOUD": { + "HEADER": "Prisma Cloud", + "BODY": "", + "ACCOUNTNAME": { + "TOOLTIP": "User defined name for the Prisma Cloud account", + "VALIDATION_MESSAGE": { + "noSpecialCharacters": "Account Name cannot contain special characters other than -", + "cannotContainSpace": "Account Name cannot contain space", + "required": "Account Name cannot be empty", + "startingFromNumber": "Account Name cannot start with numbers" + } + }, + "HOSTURL": { + "TOOLTIP": "Prisma Cloud Host URL", + "VALIDATION_MESSAGE": { + "required": "Host URL cannot be empty", + "invalidUrl": "URL is invalid" + } + }, + "APPLICATIONURL": { + "TOOLTIP": "Prisma Cloud Application URL", + "VALIDATION_MESSAGE": { + "required": "Application URL cannot be empty", + "invalidUrl": "URL is invalid" + } + }, + "ACCESSKEYID": { + "TOOLTIP": "Prisma Cloud Access Key Id", + "VALIDATION_MESSAGE": { + "required": "Access Key Id cannot be empty" + } + }, + "SECRETKEY": { + "TOOLTIP": "Prisma Cloud Secret Key", + "VALIDATION_MESSAGE": { + "required": "Secret Key cannot be empty" + } + } + }, + "SONARQUBE": { + "HEADER": "SonarQube", + "BODY": "", + "ACCOUNTNAME": { + "TOOLTIP": "User defined name for the SonarQube account", + "VALIDATION_MESSAGE": { + "noSpecialCharacters": "Account Name cannot contain special characters other than -", + "cannotContainSpace": "Account Name cannot contain space", + "required": "Account Name cannot be empty", + "startingFromNumber": "Account Name cannot start with numbers" + } + }, + "HOSTURL": { + "TOOLTIP": "Sonarqube Host URL", + "VALIDATION_MESSAGE": { + "required": "Host URL cannot be empty", + "invalidUrl": "URL is invalid" + } + }, + "TOKEN": { + "TOOLTIP": "Sonarqube Personal Access Token", + "VALIDATION_MESSAGE": { + "required": "Token cannot be empty" + } + } + }, + "AUTOPILOT": { + "HEADER": "Autopilot", + "BODY": "", + "ACCOUNTNAME": { + "TOOLTIP": "User defined name for the Autopilot account", + "VALIDATION_MESSAGE": { + "noSpecialCharacters": "Account Name cannot contain special characters other than -", + "cannotContainSpace": "Account Name cannot contain space", + "required": "Account Name cannot be empty", + "startingFromNumber": "Account Name cannot start with numbers" + } + }, + "USERNAME": { + "TOOLTIP": " Autopilot User Name", + "VALIDATION_MESSAGE": { + "noSpecialCharacters": "User Name cannot contain special characters other than - and _", + "cannotContainSpace": "User Name cannot contain space", + "required": "User Name cannot be empty", + "startingFromNumber": "User Name cannot start with numbers" + } + } + } + }, + "UNCHANGED_FORM": "Form is unchanged. Please make modifications in the form to enable the button.", + "INVALID_FORM": "Few fields are mandatory or invalid. Please fill the form to enable the button.", + "NO_WRITE_ACCESS": "You have only read permission. Please check with your administrator for updating permissions.", + "METRIC_TEMPLATE": { + "APM_INFRA": { + "TEMPLATE_NAME": { + "TOOLTIP": "The unique name of the template for identification", + "VALIDATION_MESSAGE": { + "required": "Template Name cannot be empty", + "noSpecialCharacters": "Template Name cannot contain special characters", + "cannotContainSpace": "Template Name cannot contain space", + "startingFromNumber": "Template Name cannot start with number", + "maxlength": "Template name should not have more than 63 characters!", + "exists": "Template already exists" + } + }, + "APM_MONITORING_PROVIDER": { + "TOOLTIP": "Select an APM datasource provider of choice", + "VALIDATION_MESSAGE": {} + }, + "APM_ACCOUNT": { + "TOOLTIP": "Select the account of interest in the configured APM datasource ", + "VALIDATION_MESSAGE": {} + }, + "APM_APPLICATION": { + "TOOLTIP": "Select the application of interest that you want to monitor", + "VALIDATION_MESSAGE": {} + }, + "APM_API_SELECTION": { + "TOOLTIP": "Select the relevant API metrics to monitor ", + "VALIDATION_MESSAGE": {} + }, + "INFRA_MONITORING_PROVIDER": { + "TOOLTIP": "Select an INFRA metrics datasource provider of choice", + "VALIDATION_MESSAGE": {} + }, + "INFRA_ACCOUNT": { + "TOOLTIP": "Select the account of interest in the configured INFRA metrics datasource ", + "VALIDATION_MESSAGE": {} + }, + "INFRA_METRIC_GROUPS": { + "TOOLTIP": "Metrics groups organized as groups for quick overview on each infrastructure component", + "VALIDATION_MESSAGE": {} + }, + "FILTER_KEY": { + "TOOLTIP": "A metric scope placeholder to filter the scope of the metric", + "VALIDATION_MESSAGE": { + "required": "Filter Key cannot be empty", + "cannotContainSpace": "Filter Key cannot contain space" + } + }, + "BASELINE": { + "TOOLTIP": "A unique metric scope to identify the baseline metric", + "VALIDATION_MESSAGE": { + "required": "Baseline cannot be empty", + "cannotContainSpace": "Baseline cannot contain space" + } + }, + "NEW_RELEASE": { + "TOOLTIP": "A unique metric scope to identify the canary metric", + "VALIDATION_MESSAGE": { + "required": "New Release cannot be empty", + "cannotContainSpace": "New Release cannot contain space" + } + }, + "NORMALIZATION": { + "TOOLTIP": "The selected Load metric will be dividing all the metrics to make the metrics more comparable to each other", + "VALIDATION_MESSAGE": {} + }, + "THRESHOLD": { + "TOOLTIP": "Select 'Hard' mode for a stringent analysis and 'Easy' mode for a more lenient analysis", + "VALIDATION_MESSAGE": {} + }, + "SPECIFY_CRITICAL_WATCHLIST": { + "TOOLTIP": "Metrics marked as critical, will affect the overall canary analysis score if they fail Metrics marked as in watchlist will be shown first in the metric analysis report", + "VALIDATION_MESSAGE": {} + } + }, + "CUSTOM": { + "TEMPLATE_NAME": { + "TOOLTIP": "The unique name of the template for identification", + "VALIDATION_MESSAGE": { + "required": "Template Name cannot be empty", + "noSpecialCharacters": "Template Name cannot contain special characters", + "cannotContainSpace": "Template Name cannot contain space", + "startingFromNumber": "Template Name cannot start with number", + "maxlength": "Template name should not have more than 63 characters!", + "exists": "Template already exists" + } + }, + "DATA_SOURCE": { + "TOOLTIP": "Select a datasource provider of choice", + "VALIDATION_MESSAGE": { + "required": "Data source cannot be empty" + } + }, + "ACCOUNT": { + "TOOLTIP": "Select the account of interest in the configured datasource ", + "VALIDATION_MESSAGE": { + "required": "Account cannot be empty" + } + }, + "FILTER_KEY": { + "TOOLTIP": "Metric Scope Placeholder will be replaced by Baseline & New Release values in the Metric Query; For example, Scope Placeholder “pod_name” will be replaced by Baseline & New Release values in the metric query avg(container_memory_usage_bytes{pod=~'pod_name',container!=''}) for getting baseline & New Release metrics data respectively from the monitoring provider", + "VALIDATION_MESSAGE": { + "required": "Filter Key cannot be empty", + "cannotContainSpace": "Filter Key cannot contain space" + } + }, + "BASELINE": { + "TOOLTIP": "Unique metric scope to identify the baseline metric data", + "VALIDATION_MESSAGE": { + "required": "Baseline cannot be empty", + "cannotContainSpace": "Baseline cannot contain space" + } + }, + "NEW_RELEASE": { + "TOOLTIP": "Unique metric scope to identify the canary metric data", + "VALIDATION_MESSAGE": { + "required": "New Release cannot be empty", + "cannotContainSpace": "New Release cannot contain space" + } + }, + "ADD_NEW_QUERY": { + "TOOLTIP": "Add New Query", + "VALIDATION_MESSAGE": {} + }, + "QUERY_SELECTION": { + "TOOLTIP": "Select the relevant metrics to monitor ", + "VALIDATION_MESSAGE": {} + }, + "QUERY_NAME": { + "TOOLTIP": "A meaningful name given to a query or a group of similar queries ", + "VALIDATION_MESSAGE": { + "required": "Query Name cannot be empty" + } + }, + "QUERY_STRING": { + "TOOLTIP": "Query to fetch the metric from the data source provider", + "VALIDATION_MESSAGE": { + "required": "Query String cannot be empty" + } + }, + "RISK_DIRECTION": { + "TOOLTIP": "Direction in which the metric difference is allowed to expand", + "VALIDATION_MESSAGE": {} + }, + "THRESHOLD": { + "TOOLTIP": "Percentage difference beyond which the Metric is treated as FAIL", + "VALIDATION_MESSAGE": {} + }, + "CRITICAL": { + "TOOLTIP": "Critical", + "VALIDATION_MESSAGE": {} + }, + "WATCHLIST": { + "TOOLTIP": "Metrics marked as in watchlist will be shown first in the metric analysis report", + "VALIDATION_MESSAGE": {} + }, + "WEIGHT": { + "TOOLTIP": "Numerical importance given to a metric; it can range from 0 as lowest to 1 as the highest", + "VALIDATION_MESSAGE": {} + }, + "CRITICALITY": { + "TOOLTIP": "Normal is selected to remove the metric from the metric group for score calculation if it has no data, Critical is selected to fail the entire analysis if this metric fails or has no data, Must Have Data is used to fail a metric if data is missing", + "VALIDATION_MESSAGE": {} + }, + "NAN_STRATEGY": { + "TOOLTIP": "Handles NaN values which can occur if there is no data in a particular interval for metric data. ", + "VALIDATION_MESSAGE": {} + } + } + }, + "USAGE_INSIGHTS": { + "APPLICATIONS": { + "TOOLTIP": "Application" + }, + "PIPELINES": { + "TOOLTIP": "Pipelines" + }, + "PIPELINES_WITH_INTELLIGENT_GATES": { + "TOOLTIP": "Pipelines with Intelligent Gates" + }, + "INTELLIGENT_GATES_BREAKDOWN": { + "TOOLTIP": "Intelligent Gates Breakdown" + }, + "GATES_USED": { + "TOOLTIP": "Gates Used" + }, + "USERS": { + "TOOLTIP": "Users" + } + }, + "DELIVERY_INSIGHTS": { + "PIPELINES": { + "TOOLTIP": "Pipelines" + }, + "MOST_ACTIVE_PIPELINES": { + "TOOLTIP": "Most Active Pipelines" + }, + "MOST_SUCCESSFUL_PIPELINES": { + "TOOLTIP": "Most Successful Pipelines" + }, + "MOST_FAILED_PIPELINES": { + "TOOLTIP": "Most Failed Pipelines" + }, + "FASTEST_PIPELINES": { + "TOOLTIP": "Fastest Pipelines " + }, + "SLOWEST_PIPELINES": { + "TOOLTIP": "Slowest Pipelines " + }, + "MANUAL_JUDGMENT": { + "TOOLTIP": "Manual Judgment" + } + }, + "ACCESS_MANAGEMENT": { + "ADMINISTRATOR": { + "INFO": "Super Administrator Groups will not appear in the dropdown since their Access Permissions cannot be modified. Administrators will have full Access to all Resources.", + "TOOLTIP": "Groups with Administration Permissions" + }, + "USER_ROLE_LISTING": { + "HEADER": "ROLE MANAGEMENT", + "BODY": "Users should be assigned user roles only if they need global access to one or more resources." + }, + "USER_ROLE_CREATION": { + "ROLENAME": { + "TOOLTIP": "", + "VALIDATION_MESSAGE": { + "required": "Role Name cannot be empty", + "cannotContainSpace": "Role Name cannot contain space", + "noSpecialCharacters": "Role Name cannot contain special character", + "startingFromNumber": "Role Name should not start with number" + } + }, + "USER_GROUPS": { + "TOOLTIP": "", + "VALIDATION_MESSAGE": { + "required": "Groups cannot be empty" + } + }, + "PERMISSIONS": { + "VALIDATION_MESSAGE": { + "required": "Atleast one feature has to be enabled with permissions" + } + } + }, + "FEATURE_VISIBILTY_LISTING": { + "HEADER": "FEATURE FLAG MANAGEMENT", + "BODY": "Feature Visibility is used for scenarios where one or more user groups need exclusive access to a specific feature. For example, the 'Compliance Team' should only access the Policy Management feature. Administrators can enable the feature flag for the compliance team user group. The feature visibility function will ensure that the policy management feature is not visible for all other user groups." + }, + "FEATURE_VISIBILTY_CREATION": { + "ROLENAME": { + "TOOLTIP": "", + "VALIDATION_MESSAGE": { + "required": "Role Name cannot be empty", + "cannotContainSpace": "Role Name cannot contain space", + "noSpecialCharacters": "Role Name cannot contain special character", + "startingFromNumber": "Role Name should not start with number" + } + }, + "USER_GROUPS": { + "TOOLTIP": "", + "VALIDATION_MESSAGE": { + "required": "Groups cannot be empty" + } + }, + "PERMISSIONS": { + "VALIDATION_MESSAGE": { + "required": "Atleast one feature has to be enabled" + } + } + } + }, + "LOG_TEMPLATE": { + "STRING_PATTERN": { + "TOOLTIP": "String Pattern", + "VALIDATION_MESSAGE": { + "required": "String Pattern cannot be empty" + } + }, + "LOG_TOPICS": { + "TOOLTIP": "Strings that appear in logs with their characterization" + }, + "LOG_TAGS": { + "TOOLTIP": "Create custom tags based on business logic." + }, + "CHARACTERIZATION_TOPIC": { + "TOOLTIP": "Characterization Topic", + "VALIDATION_MESSAGE": { + "required": "Characterization Topic cannot be empty" + } + }, + "TYPE": { + "TOOLTIP": "Type", + "VALIDATION_MESSAGE": {} + }, + "ENABLE_CLUSTER_TAG": { + "TOOLTIP": "Create custom tags based on business logic.", + "VALIDATION_MESSAGE": {} + }, + "CLUSTER_TAG_STRING": { + "TOOLTIP": "The string pattern that appears in logs", + "VALIDATION_MESSAGE": { + "required": "Cluster Tag String cannot be empty" + } + }, + "CLUSTER_TAG": { + "TOOLTIP": "Cluster Tag", + "VALIDATION_MESSAGE": { + "required": "Cluster Tag cannot be empty" + } + }, + "LOG_TEMPLATE_NAME": { + "TOOLTIP": "Log Template Name", + "VALIDATION_MESSAGE": { + "required": "Template Name cannot be empty", + "noSpecialCharacters": "Template Name cannot contain special characters", + "cannotContainSpace": "Template Name cannot contain space", + "startingFromNumber": "Template Name cannot start with number", + "maxlength": "Template name should not have more than 63 characters!", + "exists": "Template already exists" + } + }, + "PROVIDER": { + "TOOLTIP": "Data source for Risk Analysis", + "VALIDATION_MESSAGE": { + "required": "Provider cannot be empty" + } + }, + "LOG_ACCOUNT": { + "TOOLTIP": "Account of the Log provider; Refer Integrations tab under Setup", + "VALIDATION_MESSAGE": { + "required": "Log Account cannot be empty" + } + }, + "QUERY_FILTER_KEY": { + "TOOLTIP": "Unique Key which identify logs to be processed in the Index", + "VALIDATION_MESSAGE": { + "required": "Query Filter Key cannot be empty", + "cannotContainSpace": "Query Filter Key cannot contain space" + } + }, + "BASELINE": { + "TOOLTIP": "Unique value which identify baseline logs in the Index", + "VALIDATION_MESSAGE": { + "required": "Baseline cannot be empty", + "cannotContainSpace": "Baseline cannot contain space" + } + }, + "NEW_RELEASE": { + "TOOLTIP": "Unique value which identify New Release logs in the Index", + "VALIDATION_MESSAGE": { + "required": "New Release cannot be empty", + "cannotContainSpace": "New Release cannot contain space" + } + }, + "RESPONSE_KEYWORDS": { + "TOOLTIP": "Field name in the Index containing logs to be processed", + "VALIDATION_MESSAGE": { + "required": "Response Keywords cannot be empty", + "cannotContainSpace": "Response Keywords cannot contain space" + } + }, + "TIMESTAMP_KEY": { + "TOOLTIP": "Unique Key which identify the timestamp for log; this field is optional; by default, it is @timestamp for elasticsearch and timestamp for graylog", + "VALIDATION_MESSAGE": { + "cannotContainSpace": "Timestamp Key cannot contain space" + } + }, + "AUTOBASELINE": { + "TOOLTIP": "ML based learning of the baseline from historic analysis", + "VALIDATION_MESSAGE": {} + }, + "CONTEXTUAL_CLUSTER": { + "TOOLTIP": "Enable/disable cluster of unexpected events in similar context", + "VALIDATION_MESSAGE": {} + }, + "CONTEXTUAL_WINDOW_SIZE": { + "TOOLTIP": "Number of Log events to be seen in a Context. Allowed size in between 25 and 50", + "VALIDATION_MESSAGE": { + "max": "Allowed size is in between 25 to 50", + "min": "Allowed size is in between 25 to 50" + } + }, + "INFO_CLUSTER_SCORING": { + "TOOLTIP": "Enabling this option will include INFO clusters in scoring", + "VALIDATION_MESSAGE": {} + }, + "SENSITIVITY": { + "TOOLTIP": "Impact of Unexpected Issues on the log scoring", + "VALIDATION_MESSAGE": { + "required": "Sensitivity cannot be empty" + } + }, + "SCORING_ALGORITHM": { + "TOOLTIP": "Scoring Algorithm for Risk Analysis", + "VALIDATION_MESSAGE": {} + }, + "LOG_GROUP": { + "TOOLTIP": "Group of log streams that share the same retention, monitoring, and access control settings", + "VALIDATION_MESSAGE": { + "required": "Log Group cannot be empty", + "cannotContainSpace": "Log Group cannot contain space" + } + }, + "LOG_STREAM": { + "TOOLTIP": "Sequence of log events that share the same source", + "VALIDATION_MESSAGE": { + "required": "Log Stream cannot be empty", + "cannotContainSpace": "Log Stream cannot contain space" + } + }, + "REGION": { + "TOOLTIP": "Geographic area where AWS data center", + "VALIDATION_MESSAGE": { + "required": "Region cannot be empty" + } + }, + "INDEX_PATTERN": { + "TOOLTIP": "Index containing logs for processing", + "VALIDATION_MESSAGE": { + "required": "Intex Pattern cannot be empty", + "cannotContainSpace": "Intex Pattern cannot contain space" + } + }, + "CUSTOM_REGEX": { + "TOOLTIP": "Custom Regular Expression to filter the logs", + "VALIDATION_MESSAGE": {} + }, + "REGULAR_EXPRESSION": { + "TOOLTIP": "Sequence of characters that specifies a search pattern", + "VALIDATION_MESSAGE": { + "cannotContainSpace": "Regular Expression cannot contain space" + } + }, + "RESPONSE_KEY": { + "TOOLTIP": "Field name in the Index where regex to be searched", + "VALIDATION_MESSAGE": {} + }, + "STREAM_ID": { + "TOOLTIP": "The streams are a mechanism to route messages into categories in realtime while they are processed", + "VALIDATION_MESSAGE": { + "required": "Stream ID cannot be empty", + "cannotContainSpace": "Stream ID cannot contain space" + } + }, + "NAMESPACE": { + "TOOLTIP": "Namespace", + "VALIDATION_MESSAGE": { + "required": "Namespace cannot be empty", + "cannotContainSpace": "Namespace cannot contain space" + } + }, + "TEST_CASE_KEY": { + "TOOLTIP": "Field in the log index which holds the test case names", + "VALIDATION_MESSAGE": { + "required": "Test Case Key cannot be empty", + "cannotContainSpace": "Test Case Key cannot contain space" + } + }, + "TEST_SUITE_KEY": { + "TOOLTIP": "Field in the log index which holds the test suite names", + "VALIDATION_MESSAGE": { + "required": "Test Suite Key cannot be empty", + "cannotContainSpace": "Test Suite Key cannot contain space" + } + } + } } diff --git a/charts/oes/config/oes-visibility/visibility-local.yml b/charts/oes/config/oes-visibility/visibility-local.yml index 40cffe82..9bdb0233 100644 --- a/charts/oes/config/oes-visibility/visibility-local.yml +++ b/charts/oes/config/oes-visibility/visibility-local.yml @@ -35,7 +35,7 @@ management: ui: approval: - url: {{ .Values.global.oesUI.protocol }}://{{ .Values.global.oesUI.host }}/ui/application/visibility/{applicationId}/{serviceId}/{approvalGateId} + url: {{ .Values.global.oesUI.protocol }}://{{ .Values.global.oesUI.host }}/ui/plugin-isd/approval/{applicationId}/{serviceId}/{approvalGateId} gate: url: http://oes-gate:8084 @@ -47,9 +47,9 @@ jira: url: hosturl/browse/{issue_Id} git: - apiurl: /repos/{username}/{repo}/commits/{commitId} + apiurl: /repos/{account}/{repo}/commits/{commitId} userurl: /user - navigate.url: https://github.com/OpsMx/{repo_name}/commit/{commit_Id} + navigate.url: https://github.com/{account}/{repo_name}/commit/{commit_Id} jenkins: api: diff --git a/charts/oes/nightlyhelm-values.yml b/charts/oes/nightlyhelm-values.yml index 465dd30e..1b224e31 100644 --- a/charts/oes/nightlyhelm-values.yml +++ b/charts/oes/nightlyhelm-values.yml @@ -1,17 +1,3 @@ -global: - certManager: - installed: true - createIngress: true - gitea: - admin: - enabled: false - standardrepoBranch: 3.12 - oesUI: - host: isd-n.release.opsmx.org - protocol: https - ssl: - enabled: true - imageCredentials: repoUrl: https://docker.io/ registry: opsmx11 @@ -20,7 +6,7 @@ imagePullSecret: "opsmx11-secret" autopilot: image: - repository: autopilot + repository: oes-autopilot tag: autopilottagname audit: image: @@ -48,7 +34,7 @@ platform: tag: oesplatformtagname sapor: image: - repository: oes-sapor + repository: sapor tag: oessaportagname ui: image: diff --git a/charts/oes/templates/configmaps/datasource-creation.yaml b/charts/oes/templates/configmaps/datasource-creation.yaml index 669c78db..de33615f 100644 --- a/charts/oes/templates/configmaps/datasource-creation.yaml +++ b/charts/oes/templates/configmaps/datasource-creation.yaml @@ -83,6 +83,7 @@ data: {{- if .Values.spinnaker.gitopsHalyard.enabled }} STORAGE_TYPE={{ .Values.spinnaker.gitopsHalyard.repo.type }} + BASEURL_HOST={{ .Values.spinnaker.gitopsHalyard.repo.baseUrlHostName }} USERNAME={{ .Values.spinnaker.spinCli.auth.basic.username }} PASSWORD={{ .Values.spinnaker.spinCli.auth.basic.password }} TOKEN=$(echo -n "$USERNAME":"$PASSWORD" | base64) @@ -90,7 +91,7 @@ data: name=$(echo $response | jq '.[].name') if [ -z "$name" ]; then - if [[ "$STORAGE_TYPE" == "git" ]]; + if [[ "$STORAGE_TYPE" == "git" && "$BASEURL_HOST" == "github.com" ]]; then response=$(curl --header "Content-Type: application/json" --header "x-spinnaker-user: admin" --request POST http://oes-platform:8095/platformservice/v6/datasource --data '{"datasourceType": "GITHUB", "name": "gitops", "spinEnabled": "false", "configurationFields": {"token": "{{ .Values.spinnaker.gitopsHalyard.repo.token }}", "username": "{{ .Values.spinnaker.gitopsHalyard.repo.username }}", "hostUrl": "https://github.com/", "url": "https://api.github.com" } }') id=$(echo $response | jq '.id') @@ -98,6 +99,13 @@ data: #curl --header "Content-Type: application/json" --header "x-spinnaker-user: admin" --request POST http://oes-sapor:8085/oes/accountsConfig/v3/spinnaker --data '{"name": "preview-saas", "url": "{{ .Values.global.oesGate.protocol }}://{{ .Values.global.oesGate.host }}", "authenticationType": "LDAP", "token": "'"${TOKEN}"'", "externalAccountFlag": "true","pipelinePromotionFlag": "false","syncAccountFlag": "false", "externalAccountConfiguration": {"accountId": "'"${id}"'","accountName": "gitops", "provider": "GITHUB", "config": {"bucketName": "", "region": "","endPoint": "https://github.com/{{ .Values.spinnaker.gitopsHalyard.repo.organization }}/{{ .Values.spinnaker.gitopsHalyard.repo.repository }}.git", "sourcePath": "" }}}' break fi + if [[ "$STORAGE_TYPE" == "git" && "$BASEURL_HOST" == "gitlab.com" ]]; + then + response=$(curl --header "Content-Type: application/json" --header "x-spinnaker-user: admin" --request POST http://oes-platform:8095/platformservice/v6/datasource --data '{"datasourceType": "GITLAB", "name": "gitops", "spinEnabled": "false", "configurationFields": {"token": "{{ .Values.spinnaker.gitopsHalyard.repo.token }}", "hostUrl": "https://gitlab.com/" } }') + id=$(echo $response | jq '.id') + curl --header "Content-Type: application/json" --header "x-spinnaker-user: admin" --request POST http://oes-sapor:8085/oes/accountsConfig/v4/spinnaker --data '{"name":"preview-saas","url":"{{ .Values.spinnaker.spinCli.gate.endpoint }}","authenticationType":"LDAP","externalAccountFlag":true,"pipelinePromotionFlag":false,"syncAccountFlag":false,"externalAccountConfiguration":{"accountId": "'"${id}"'","accountName":"gitops","provider":"GITLAB","config":{"bucketName":"","region":"","endPoint":"https://gitlab.com/{{ .Values.spinnaker.gitopsHalyard.repo.organization }}/{{ .Values.spinnaker.gitopsHalyard.repo.repository }}.git","sourcePath":""}},"pipelinePromotionConfiguration":null,"password":"'"${PASSWORD}"'","userName":"'"${USERNAME}"'"}' + break + fi if [[ "$STORAGE_TYPE" == "stash" ]]; then if [[ "{{ .Values.spinnaker.gitopsHalyard.repo.projectName }}" ]] diff --git a/charts/oes/templates/configmaps/standard-error-codes.yaml b/charts/oes/templates/configmaps/standard-error-codes.yaml index 27060ffd..06295da8 100644 --- a/charts/oes/templates/configmaps/standard-error-codes.yaml +++ b/charts/oes/templates/configmaps/standard-error-codes.yaml @@ -10,12 +10,17 @@ data: standardErrorCodesMapping.ISD-EmptyKeyOrValueInJson-400-07 = ISD-EmptyKeyOrValueInJson-400-07 : {0} - {1} is missing in json ! standardErrorCodesMapping.ISD-UnableToParseJSON-400-08 = ISD-UnableToParseJSON-400-08 : {0} - Unable to parse Json. Please provide a valid json with required data ! standardErrorCodesMapping.ISD-MustBeANumber-400-09 = ISD-MustBeANumber-400-09 : {0} - {1} must be a number : {2} - standardErrorCodesMapping.ISD-Unauthorized-401-01 = ISD-Unauthorized-401-01 : {0} - {1} not authorized {2}. + standardErrorCodesMapping.ISD-Unauthorized-401-01 = ISD-Unauthorized-401-01 : {0} - {1} not authorized. {2}. standardErrorCodesMapping.ISD-Unauthorized-401-02 = ISD-Unauthorized-401-02 : {0} - User group not found for user : {1}. standardErrorCodesMapping.ISD-NotAdmin-401-03 = ISD-NotAdmin-401-03 : {0} - {1} is not an admin ! + standardErrorCodesMapping.ISD-Forbidden-403-01 = ISD-Forbidden-403-01 : {0} - {1} doesn't have {2} permission on this feature: {3} + standardErrorCodesMapping.ISD-Forbidden-403-02 = ISD-Forbidden-403-02 : {0} - {1} is invalid. + standardErrorCodesMapping.ISD-Forbidden-403-03 = ISD-Forbidden-403-03 : {0} - {1} : {2}. + standardErrorCodesMapping.ISD-Forbidden-403-04 = ISD-Forbidden-403-04 : {0} - {1} namespace is not accessible for given kubeconfig account {2}. standardErrorCodesMapping.ISD-IsNotFound-404-01 = ISD-IsNotFound-404-01 : {0} - {1} not found : {2} standardErrorCodesMapping.ISD-NoData-404-02 = ISD-NoData-404-02 : {0} - No data found for {1} standardErrorCodesMapping.ISD-DoesNotExist-404-03 = ISD-DoesNotExist-404-03 : {0} - {1} does not exist {2}. + standardErrorCodesMapping.ISD-IsNotFound-404-04 = ISD-IsNotFound-404-04 : {0} - {1} not found {2}. standardErrorCodesMapping.ISD-AlreadyExists-409-01 = ISD-AlreadyExists-409-01 : {0} - {1} already exists: {2} standardErrorCodesMapping.ISD-FailedToDelete-412-01 = ISD-FailedToDelete-412-01 : {0} - Unable to delete {1} as {1} is already in use ! standardErrorCodesMapping.ISD-FailedToDeletePolicy-412-02 = ISD-FailedToDeletePolicy-412-02 : {0} - Unable to delete policy as it is already in use for {1} gate ! @@ -25,18 +30,35 @@ data: standardErrorCodesMapping.ISD-InvalidCredentials-422-03 = ISD-InvalidCredentials-422-03 : {0} - {1} credentials are invalid ! standardErrorCodesMapping.ISD-InvalidEndpoint-422-04 = ISD-InvalidEndpoint-422-04 : {0} - {1} endpoint is invalid ! standardErrorCodesMapping.ISD-InvalidEndpointOrCredentials-422-05 = ISD-InvalidEndpointOrCredentials-422-05 : {0} - {1} endpoint or credentials are invalid ! - standardErrorCodesMapping.ISD-UsernameOrPasswordIsBlank-422-06 = ISD-UsernameOrPasswordIsBlank-422-06 : {0} - {Username} is blank but {Password) is supplied. Both must be present or blank. + standardErrorCodesMapping.ISD-UsernameOrPasswordIsBlank-422-06 = ISD-UsernameOrPasswordIsBlank-422-06 : {0} - {1} is blank but {2} is supplied. Both must be present or blank. standardErrorCodesMapping.ISD-UnknownDatasource-422-07 = ISD-UnknownDatasource-422-07 : {0} - Unknown datasource or datasource is currently not supported : {1} standardErrorCodesMapping.ISD-InvalidProvider-422-08 = ISD-InvalidProvider-422-08 : {0} - {1} provider is invalid ! standardErrorCodesMapping.ISD-InvalidPath-422-09 = ISD-InvalidPath-422-09 : {0} - {1} path is invalid ! + standardErrorCodesMapping.ISD-UnableToGenerate-422-10 = ISD-UnableToGenerate-422-10 : {0} - Unable to generate {1} ! + standardErrorCodesMapping.ISD-FailedToCreate-422-11 = ISD-FailedToCreate-422-11 : {0} - Failed to create {1}. + standardErrorCodesMapping.ISD-EndpointIsBlank-422-12 = ISD-EndpointIsBlank-422-12 : {0} - {1} endpoint is blank. {2} must be blank. + standardErrorCodesMapping.ISD-ConnectionOrAuthenticationFailed-422-13 = ISD-ConnectionOrAuthenticationFailed-422-13 : {0} - {1} connection or authentication failed. + standardErrorCodesMapping.ISD-FailedToUpdate-422-14 = ISD-FailedToUpdate-422-14 : {0} - Failed to Update {1}. + standardErrorCodesMapping.ISD-FailedToDelete-422-15 = ISD-FailedToDelete-422-15 : {0} - Failed to Delete {1}. + standardErrorCodesMapping.ISD-DoesNotMatch-422-16 = ISD-DoesNotMatch-422-16 : {0} - {1} does not match {2}. + standardErrorCodesMapping.ISD-DoesNotExist-422-17 = ISD-DoesNotExist-422-17 : {0} - {1} does not exist {2}. + standardErrorCodesMapping.ISD-DoesNotSupport-422-18 = ISD-DoesNotSupport-422-18 : {0} - {1} does not support {2}. + standardErrorCodesMapping.ISD-UnableToVerify-422-19 = ISD-UnableToVerify-422-19 : {0} - Unable to verify {1}. + standardErrorCodesMapping.ISD-FailedToInitialize-422-20 = ISD-FailedToInitialize-422-20 : {0} - Failed to initialize {1}. + standardErrorCodesMapping.ISD-DoesNotHave-422-21 = ISD-DoesNotHave-422-21 : {0} - {1} does not have {2}. standardErrorCodesMapping.ISD-UnableToAddStage-424-01 = ISD-UnableToAddStage-424-01 : {0} - Unable to add stage in {1} ! standardErrorCodesMapping.ISD-UnableToDelete-424-02 = ISD-UnableToDelete-424-02 : {0} - Unable to delete {1} while analysis is under process ! + standardErrorCodesMapping.ISD-UnableToDelete-424-03 = ISD-UnableToDelete-424-03 : {0} - Unable to delete {1} as already in use {2} + standardErrorCodesMapping.ISD-UnableToDelete-424-04 = ISD-UnableToDelete-424-04 : {0} - Unable to delete {1} as it is involved in multi-service analysis ! standardErrorCodesMapping.ISD-ShouldBeNumber-500-01 = ISD-ShouldBeNumber-500-01 : {0} - {1} should be an number ! standardErrorCodesMapping.ISD-ShouldBePositiveNumber-500-02 = ISD-ShouldBePositiveNumber-500-02 : {0} - {1} should be an positive number ! standardErrorCodesMapping.ISD-UnableToFetch-500-03 = ISD-UnableToFetch-500-03 : {0} - Unable to fetch {1} from database. Please try after some time ! standardErrorCodesMapping.ISD-UnableToCreate-500-04 = ISD-UnableToCreate-500-04 : {0} - Unable to create {1} ! standardErrorCodesMapping.ISD-UnableToDelete-500-05 = ISD-UnableToDelete-500-05 : {0} - Unable to delete {1} ! standardErrorCodesMapping.ISD-UnableToUpdate-500-06 = ISD-UnableToUpdate-500-06 : {0} - Unable to update {1} ! + standardErrorCodesMapping.ISD-UnableToValidate-500-07 = ISD-UnableToValidate-500-07 : {0} - Unable to validate {1} ! + standardErrorCodesMapping.ISD-ServiceUnavailable-503-01 = ISD-ServiceUnavailable-503-01 : {0} - {1} : {2} + standardErrorCodesMapping.ISD-ServiceUnavailable-503-02 = ISD-ServiceUnavailable-503-02 : {0} - {1} kind: ConfigMap metadata: labels: diff --git a/charts/oes/templates/sapor-gate/sapor-gate-deployment.yaml b/charts/oes/templates/sapor-gate/sapor-gate-deployment.yaml index b6677037..f20a4ff3 100644 --- a/charts/oes/templates/sapor-gate/sapor-gate-deployment.yaml +++ b/charts/oes/templates/sapor-gate/sapor-gate-deployment.yaml @@ -53,6 +53,10 @@ spec: periodSeconds: 10 successThreshold: 1 timeoutSeconds: 1 + {{- if .Values.imagePullSecret}} + imagePullSecrets: + - name: {{ .Values.imagePullSecret}} + {{- end }} {{- if .Values.global.nodeSelector }} nodeSelector: {{ toYaml .Values.global.nodeSelector | indent 8 }} diff --git a/charts/oes/values.yaml b/charts/oes/values.yaml index e8f6949c..489f87a9 100644 --- a/charts/oes/values.yaml +++ b/charts/oes/values.yaml @@ -68,7 +68,7 @@ global: gitea: enabled: true - standardrepoBranch: 3.12 + standardrepoBranch: v4.0 admin: existingSecret: gitea-secret username: opsmx @@ -78,7 +78,7 @@ global: # Spinnaker Deck URL configuration; url overwhich spinnaker deck will be accessed spinDeck: - protocol: https + protocol: http host: spin.example.ops.com #port: 31464 @@ -93,7 +93,7 @@ global: # Spinnaker Gate URL configuration; url overwhich spinnaker gate will be accessed spinGate: - protocol: https + protocol: http host: spin-gate.example.ops.com #port: 31465 @@ -120,7 +120,7 @@ global: ## OES-Gate url configuration oesGate: - protocol: https + protocol: http host: oes-gate.example.ops.com # Use below port when hostname above is an external IP instead of a hostname #port: 31467 @@ -136,6 +136,10 @@ global: # Set it to false if own LDAP is to be configured installOpenLdap: true + auth: + saml: false + oauth2: false + ## ldap configuration used in oes-gate, oes-platform and spinnaker gate for authentication and authorization ldap: enabled: true @@ -256,7 +260,7 @@ autopilot: ## Image specific details image: repository: ubi8-oes-autopilot - tag: v3.12.4 + tag: v3.12.5 pullPolicy: IfNotPresent annotations: @@ -289,7 +293,7 @@ audit: ## image: repository: ubi8-oes-audit-service - tag: v3.12.4 + tag: v3.12.5 pullPolicy: IfNotPresent serviceAnnotations: {} @@ -311,7 +315,7 @@ auditClient: ## image: repository: ubi8-oes-audit-client - tag: v3.12.4 + tag: v3.12.5 pullPolicy: IfNotPresent serviceAnnotations: {} @@ -333,7 +337,7 @@ datascience: ## image: repository: ubi8-oes-datascience - tag: v3.12.4 + tag: v3.12.5 pullPolicy: IfNotPresent serviceAnnotations: {} @@ -352,7 +356,7 @@ dashboard: ## Image specific details image: repository: ubi8-oes-dashboard - tag: v3.12.4 + tag: v3.12.5 pullPolicy: IfNotPresent annotations: @@ -405,7 +409,7 @@ gate: ## Image specific details image: repository: ubi8-gate - tag: v3.12.4 + tag: v3.12.5 pullPolicy: IfNotPresent serviceAnnotations: {} @@ -482,7 +486,7 @@ platform: ## Image specific details image: repository: ubi8-oes-platform - tag: v3.12.4 + tag: v3.12.5 pullPolicy: IfNotPresent annotations: @@ -544,7 +548,7 @@ sapor: ## Image specific details image: repository: ubi8-oes-sapor - tag: v3.12.4 + tag: v3.12.5 pullPolicy: IfNotPresent annotations: @@ -636,7 +640,7 @@ ui: ## Image specific details image: repository: ubi8-oes-ui - tag: v3.12.4 + tag: v3.12.5 pullPolicy: IfNotPresent annotations: @@ -654,7 +658,7 @@ visibility: ## Image specific details image: repository: ubi8-oes-visibility - tag: v3.12.4 + tag: v3.12.5 pullPolicy: IfNotPresent annotations: @@ -1145,7 +1149,8 @@ openldap: persistence: - enabled: false + enabled: true + size: 5Gi env: LDAP_REMOVE_CONFIG_AFTER_SETUP: "false" diff --git a/scripts/oes-data-migration-scripts/migration_v3.11.x_to_v3.12.py b/scripts/oes-data-migration-scripts/migration_v3.11.x_to_v3.12.py index e4fd4d49..06e1670d 100644 --- a/scripts/oes-data-migration-scripts/migration_v3.11.x_to_v3.12.py +++ b/scripts/oes-data-migration-scripts/migration_v3.11.x_to_v3.12.py @@ -8,7 +8,7 @@ def perform_migration(): try: - for step in tqdm(range(19), desc="Migrating from v3.11 to v3.12..."): + for step in tqdm(range(20), desc="Migrating from v3.11 to v3.12..."): if step == 0: drop_table_user_group_permission_3_11() elif step == 1: @@ -54,6 +54,9 @@ def perform_migration(): elif step == 18: updateautopilotconstraints() autopilot_conn.commit() + elif step == 19: + updateApprovalGateAUdit() + audit_conn.commit() print("Successfully migrated to v3.12") except Exception as e: @@ -70,7 +73,7 @@ def perform_migration(): def update_spinnaker_gate_url(): try: cur = oesdb_conn.cursor() - cur.execute("UPDATE spinnaker set url = '"+str(spinnaker_gate_url)+"'") + cur.execute("UPDATE spinnaker set url = '" + str(spinnaker_gate_url) + "'") except Exception as e: print("Exception occurred while updating the spinnaker gate url : ", e) raise e @@ -174,7 +177,6 @@ def update_gate(gate_response, pipeline_id, gate_id): except KeyError as e: gate_response["payloadConstraint"] = [] - req_payload = { "applicationId": gate_response["applicationId"], "approvalGatePolicies": gate_response["approvalGatePolicies"], @@ -220,7 +222,6 @@ def update_gate(gate_response, pipeline_id, gate_id): except KeyError as ke: pass - url = host_url + "/dashboardservice/v4/pipelines/" + str(pipeline_id) + "/gates/" + str(gate_id) headers = {'Cookie': cookie, 'Content-Type': 'application/json'} @@ -238,6 +239,8 @@ def updateautopilotconstraints(): cur.execute(" ALTER TABLE serviceriskanalysis DROP CONSTRAINT IF EXISTS fkmef9blhpcxhcj431kcu52nm1e ") cur.execute(" ALTER TABLE servicegate DROP CONSTRAINT IF EXISTS uk_lk3buh56ebai2gycw560j2oxm ") cur.execute(" ALTER TABLE canaryanalysis ALTER COLUMN metric_template_opsmx_id DROP not null ") + cur.execute(" ALTER TABLE userlogfeedback ALTER COLUMN logtemplate_id DROP not null ") + cur.execute(" ALTER TABLE loganalysis ALTER COLUMN log_template_opsmx_id DROP not null ") except Exception as e: print("Exception occured while updating script : ", e) raise e @@ -306,6 +309,7 @@ def clear_policy_data(): print("Exception occurred while clearing the policy : ", e) raise e + def migrate_policy(policies): try: cur = platform_conn.cursor() @@ -430,12 +434,73 @@ def migrate_user_group_permission(user_group_permissions): raise e +def updateApprovalGateAUdit(): + try: + cur_audit = audit_conn.cursor() + cur_platform = platform_conn.cursor() + cur_visibility = visibility_conn.cursor() + cur_audit.execute("select id,data from audit_events where data->>'eventType' = 'APPROVAL_GATE_AUDIT'") + approval_audit_details = cur_audit.fetchall() + for auditdata in approval_audit_details: + jsonData = json.loads(json.dumps(listData(auditdata))) + if 'gateId' in jsonData['auditData']['details']: + audit_events_table_id = auditdata[0] + gateId = jsonData['auditData']['details']['gateId'] + cur_visibility.execute('select pipeline_id from approval_gate where id =' + str(gateId)) + pipelineId = cur_visibility.fetchone() + if pipelineId is not None: + pipelineId = str(pipelineId[0]) + cur_platform.execute( + 'select distinct(a.name) as applicationName from applications a left outer join service s on a.id=s.application_id left outer join service_pipeline_map sp on s.id=sp.service_id where sp.pipeline_id =' + str( + pipelineId)) + applicationName = cur_platform.fetchone() + if applicationName is not None: + applicationName = str(applicationName[0]) + print("GateId: {},pipelineId: {} ,applicationName: {} ,audit_events_table_id :{}".format(gateId, + pipelineId, + applicationName, + audit_events_table_id)) + fetchJsonAndUpdate(audit_events_table_id, applicationName, jsonData) + except Exception as e: + print("Exception occurred while updating script : ", e) + raise e + + +def listData(results): + resultData = {} + for result in results: + resultData = result + return resultData + + +def fetchJsonAndUpdate(audit_events_table_id, applicationName, jsonData): + try: + oldAppName = jsonData['auditData']['details']['application'] + if oldAppName is not applicationName: + updateJson = json.loads(json.dumps(jsonData).replace(oldAppName, applicationName)) + updateApprovalAuditJson(audit_events_table_id, updateJson) + except Exception as e: + print("Exception occurred while mapping application name : ", e) + raise e + + +def updateApprovalAuditJson(audit_events_table_id, updateJson): + try: + cur_audit = audit_conn.cursor() + updatedConfig = "'" + str(json.dumps(updateJson)) + "'" + cur_audit.execute( + 'update audit_events set data =' + updatedConfig + ' where id ={}'.format(audit_events_table_id)) + except Exception as e: + print("Exception occurred while updating update json : ", e) + raise e + + if __name__ == '__main__': n = len(sys.argv) - if n != 8: + if n != 12: print( - "Please pass valid 7 arguments ") + "Please pass valid 9 arguments ") platform_db = sys.argv[1] platform_host = sys.argv[2] @@ -443,7 +508,11 @@ def migrate_user_group_permission(user_group_permissions): oes_host = sys.argv[4] autopilot_db = sys.argv[5] autopilot_host = sys.argv[6] - port = sys.argv[7] + audit_db = sys.argv[7] + audit_host = sys.argv[8] + visibility_db = sys.argv[9] + visibility_host = sys.argv[10] + port = sys.argv[11] # Establishing the platform db connection platform_conn = psycopg2.connect(database=platform_db, user='postgres', password='networks123', host=platform_host, @@ -461,7 +530,18 @@ def migrate_user_group_permission(user_group_permissions): port=port) print("autopilot database connection established successfully") - host_url = input('''Please enter the unified gate url, + # Establishing the audit db connection + audit_conn = psycopg2.connect(database=audit_db, user="postgres", password="networks123", host=audit_host, + port=port) + print('Opened audit database connection successfully') + + # Establishing the visibility db connection + visibility_conn = psycopg2.connect(database=visibility_db, user="postgres", password="networks123", + host=visibility_host, + port=port) + print("Visibility database connection established successfully") + + host_url = input('''Please enter the unified gate url, ex: https://sample-example.com/gate : ''') cookie = input('''Please enter the Cookie. Steps to retrieve the cookie are : @@ -469,6 +549,8 @@ def migrate_user_group_permission(user_group_permissions): 2. Open the browser network console. 3. Under Headers tab -> Request Headers -> cookie : ''') - spinnaker_gate_url = input('''Please enter the unified spinnaker gate url that has to be updated in the spinnaker setup : ''') + spinnaker_gate_url = input( + '''Please enter the unified spinnaker gate url that has to be updated in the spinnaker setup : ''') + + perform_migration() - perform_migration() \ No newline at end of file diff --git a/scripts/oes-data-migration-scripts/migration_v3.12.4_to_v3.12.5.py b/scripts/oes-data-migration-scripts/migration_v3.12.4_to_v3.12.5.py new file mode 100644 index 00000000..d092aecb --- /dev/null +++ b/scripts/oes-data-migration-scripts/migration_v3.12.4_to_v3.12.5.py @@ -0,0 +1,43 @@ +import psycopg2 +import sys +import datetime + + +def perform_migration(): + try: + update_autopilot_constraints() + autopilot_conn.commit() + print("successfully migrated autopilot db") + except Exception as e: + print("Exception occurred while migration : ", e) + autopilot_conn.rollback() + finally: + autopilot_conn.close() + + +def update_autopilot_constraints(): + + try: + cur_autopilot.execute(" ALTER TABLE userlogfeedback ALTER COLUMN logtemplate_id DROP not null ") + cur_autopilot.execute(" ALTER TABLE loganalysis ALTER COLUMN log_template_opsmx_id DROP not null ") + except Exception as e: + print("Exception occured while updating script : ", e) + raise e + + +if __name__ == '__main__': + n = len(sys.argv) + + if n != 6: + print("Please pass valid 5 arguments ") + + autopilot_db = sys.argv[1] + autopilot_host = sys.argv[2] + port = sys.argv[3] + user_name = sys.argv[4] + password = sys.argv[5] + + autopilot_conn = psycopg2.connect(database=autopilot_db, user=user_name, password=password, host=autopilot_host, + port=port) + cur_autopilot = autopilot_conn.cursor() + perform_migration() diff --git a/scripts/oes-data-migration-scripts/migration_v3.12.5_to_v3.12.6.py b/scripts/oes-data-migration-scripts/migration_v3.12.5_to_v3.12.6.py new file mode 100644 index 00000000..19758172 --- /dev/null +++ b/scripts/oes-data-migration-scripts/migration_v3.12.5_to_v3.12.6.py @@ -0,0 +1,102 @@ + +import psycopg2 +import sys +import json + + +def perform_migration(): + try: + updateApprovalGateAUdit() + audit_conn.commit() + print("successfully migrated audit db") + except Exception as e: + print("Exception occurred while migration : ", e) + audit_conn.rollback() + finally: + audit_conn.close() + + + +def updateApprovalGateAUdit(): + try: + cur_audit.execute("select id,data from audit_events where data->>'eventType' = 'APPROVAL_GATE_AUDIT'") + approval_audit_details = cur_audit.fetchall() + for auditdata in approval_audit_details: + jsonData = json.loads(json.dumps(listData(auditdata))) + if 'gateId' in jsonData['auditData']['details']: + audit_events_table_id = auditdata[0] + gateId = jsonData['auditData']['details']['gateId'] + cur_visibility.execute('select pipeline_id from approval_gate where id =' + str(gateId)) + pipelineId = cur_visibility.fetchone() + if pipelineId is not None: + pipelineId = str(pipelineId[0]) + cur_platform.execute('select distinct(a.name) as applicationName from applications a left outer join service s on a.id=s.application_id left outer join service_pipeline_map sp on s.id=sp.service_id where sp.pipeline_id =' + str(pipelineId)) + applicationName = cur_platform.fetchone() + if applicationName is not None: + applicationName = str(applicationName[0]) + print("GateId: {},pipelineId: {} ,applicationName: {} ,audit_events_table_id :{}".format(gateId,pipelineId,applicationName,audit_events_table_id)) + fetchJsonAndUpdate(audit_events_table_id,applicationName,jsonData) + except Exception as e: + print("Exception occurred while updating script : ", e) + raise e + +def listData(results): + resultData = {} + for result in results : + resultData = result + return resultData + + + +def fetchJsonAndUpdate(audit_events_table_id, applicationName,jsonData): + try: + oldAppName = jsonData['auditData']['details']['application'] + if oldAppName is not applicationName: + updateJson = json.loads(json.dumps(jsonData).replace(oldAppName,applicationName)) + updateApprovalAuditJson(audit_events_table_id,updateJson) + except Exception as e: + print("Exception occurred while mapping application name : ", e) + raise e + +def updateApprovalAuditJson(audit_events_table_id,updateJson): + try: + updatedConfig = "'" + str(json.dumps(updateJson)) + "'" + cur_audit.execute('update audit_events set data ='+updatedConfig+' where id ={}'.format(audit_events_table_id)) + except Exception as e: + print("Exception occurred while updating update json : ", e) + raise e + +if __name__ == '__main__': + n = len(sys.argv) + + if n != 10: + print( + "Please pass valid 9 arguments ") + + audit_db = sys.argv[1] + audit_host = sys.argv[2] + visibility_db = sys.argv[3] + visibility_host = sys.argv[4] + platform_db = sys.argv[5] + platform_host = sys.argv[6] + port = sys.argv[7] + user_name = sys.argv[8] + password = sys.argv[9] + + # Establishing the audit db connection + audit_conn = psycopg2.connect(database=audit_db, user=user_name, password=password, host=audit_host, port=port) + print('Opened audit database connection successfully') + + # Establishing the visibility db connection + visibility_conn = psycopg2.connect(database=visibility_db, user=user_name, password=password,host=visibility_host, port=port) + print("Visibility database connection established successfully") + + # Establishing the platform db connection + platform_conn = psycopg2.connect(database=platform_db, user=user_name, password=password, host=platform_host, + port=port) + print('Opened platform database connection successfully') + + cur_audit = audit_conn.cursor() + cur_visibility = visibility_conn.cursor() + cur_platform = platform_conn.cursor() + perform_migration() \ No newline at end of file diff --git a/scripts/oes-data-migration-scripts/migration_v3.12.x_to_v4.0.x.py b/scripts/oes-data-migration-scripts/migration_v3.12.x_to_v4.0.x.py new file mode 100644 index 00000000..b0a90f06 --- /dev/null +++ b/scripts/oes-data-migration-scripts/migration_v3.12.x_to_v4.0.x.py @@ -0,0 +1,207 @@ +import psycopg2 +import sys +import datetime +import json + + +def perform_migration(): + try: + getEnvironmentData() + #alterAppEnvironmentTable() + environmentUpdate() + updateRefId() + platform_conn.commit() + print("successfully migrated platform db") + oesdb_conn.commit() + print("successfully migrated oesdb") + update_autopilot_constraints() + autopilot_conn.commit() + print("successfully migrated autopilot db") + updateApprovalGateAUdit() + audit_conn.commit() + print("successfully migrated audit db") + + except Exception as e: + print("Exception occurred while migration : ", e) + platform_conn.rollback() + oesdb_conn.rollback() + autopilot_conn.rollback() + finally: + platform_conn.close() + oesdb_conn.close() + autopilot_conn.close() + + +def update_autopilot_constraints(): + try: + cur_autopilot.execute(" ALTER TABLE userlogfeedback ALTER COLUMN logtemplate_id DROP not null ") + cur_autopilot.execute(" ALTER TABLE loganalysis ALTER COLUMN log_template_opsmx_id DROP not null ") + except Exception as e: + print("Exception occured while updating script : ", e) + raise e + + +def alterAppEnvironmentTable(): + try: + cur_platform.execute("ALTER TABLE app_environment ADD COLUMN IF NOT EXISTS spinnaker_environment_id int") + print("Successfully altered app_environment table") + except Exception as e: + print("Exception occured in alterAppEnvironmentTable while updating script : ", e) + raise e + + +def getEnvironmentData(): + try: + cur_platform.execute("select distinct(environment) from app_environment") + appEnvironmentNameUnique = [item[0] for item in cur_platform.fetchall()] + cur_oesdb.execute("select * from spinnaker_environment") + spinakerEnvName = [item[1] for item in cur_oesdb.fetchall()] + appEnvironmentNameUniqueTuple = [tuple(x) for x in appEnvironmentNameUnique] + spinakerEnvNameTuple = [tuple(x) for x in spinakerEnvName] + appEnvInSpinakerEnv = list(set(appEnvironmentNameUniqueTuple) & set(spinakerEnvNameTuple)) + appEnvNotInSpinakerEnv = list(set(appEnvironmentNameUniqueTuple) - set(spinakerEnvNameTuple)) + for appEnvNotInSpinakerEnvName in appEnvNotInSpinakerEnv: + spinInsertData = "INSERT INTO spinnaker_environment (spinnaker_environment) VALUES ({})".format("'"+str("".join(appEnvNotInSpinakerEnvName)+"'")) + # print(spinInsertData) + cur_oesdb.execute(spinInsertData) + except Exception as e: + print("Exception occured in alterAppEnvironmentTable while updating script : ", e) + raise e + + +def environmentUpdate(): + try: + cur_oesdb.execute("select * from spinnaker_environment") + spinakerEnvDatas = cur_oesdb.fetchall() + if spinakerEnvDatas != None: + for spinakerEnvData in spinakerEnvDatas: + platScript = "UPDATE app_environment SET spinnaker_environment_id = {} WHERE environment = {}".format(spinakerEnvData[0], "'"+spinakerEnvData[1]+"'") + # print(platScript) + cur_platform.execute(platScript) + print("Successfully updated the spinnaker_environment_id in app_environment") + except Exception as e: + print("Exception occured in environmentUpdate while updating script : ", e) + raise e + +def updateRefId(): + try: + cur_platform.execute("select id, pipeline_json from pipeline where not pipeline_json::jsonb ->> 'stages' = '[]' limit 1") + pipelineDatas = cur_platform.fetchall() + for pipelineData in pipelineDatas: + strpipelineData = """{}""".format(pipelineData[1]) + jsonpipelineData = json.loads(strpipelineData) + if len(jsonpipelineData["stages"]): + platScriptdataformGatePipelineMap= "select service_gate_id from gate_pipeline_map WHERE pipeline_id = '{}'".format(pipelineData[0]) + cur_platform.execute(platScriptdataformGatePipelineMap) + serviceGateIds = cur_platform.fetchall() + if len(serviceGateIds): + for serviceGateId in serviceGateIds: + # print(serviceGateId[0]) + for stageData in jsonpipelineData["stages"]: + platScript = "UPDATE service_gate SET ref_id = {} WHERE id = '{}' and gate_name = '{}' and gate_type = '{}' and ref_id is null".format(stageData["refId"], serviceGateId[0],stageData["name"], stageData["type"]) + cur_platform.execute(platScript) + print("Successfully updated the ref_id in service_gate") + except Exception as e: + print("Exception occured in updateRefId while updating script : ", e) + raise e + +def updateApprovalGateAUdit(): + try: + cur_audit.execute("select id,data from audit_events where data->>'eventType' = 'APPROVAL_GATE_AUDIT'") + approval_audit_details = cur_audit.fetchall() + for auditdata in approval_audit_details: + jsonData = json.loads(json.dumps(listData(auditdata))) + if 'gateId' in jsonData['auditData']['details']: + audit_events_table_id = auditdata[0] + gateId = jsonData['auditData']['details']['gateId'] + cur_visibility.execute('select pipeline_id from approval_gate where id =' + str(gateId)) + pipelineId = cur_visibility.fetchone() + if pipelineId is not None: + pipelineId = str(pipelineId[0]) + cur_platform.execute('select distinct(a.name) as applicationName from applications a left outer join service s on a.id=s.application_id left outer join service_pipeline_map sp on s.id=sp.service_id where sp.pipeline_id =' + str(pipelineId)) + applicationName = cur_platform.fetchone() + if applicationName is not None: + applicationName = str(applicationName[0]) + print("GateId: {},pipelineId: {} ,applicationName: {} ,audit_events_table_id :{}".format(gateId,pipelineId,applicationName,audit_events_table_id)) + fetchJsonAndUpdate(audit_events_table_id,applicationName,jsonData) + except Exception as e: + print("Exception occurred while updating script : ", e) + raise e + +def listData(results): + resultData = {} + for result in results : + resultData = result + return resultData + + + +def fetchJsonAndUpdate(audit_events_table_id, applicationName,jsonData): + try: + oldAppName = jsonData['auditData']['details']['application'] + if oldAppName is not applicationName: + updateJson = json.loads(json.dumps(jsonData).replace(oldAppName,applicationName)) + updateApprovalAuditJson(audit_events_table_id,updateJson) + except Exception as e: + print("Exception occurred while mapping application name : ", e) + raise e + +def updateApprovalAuditJson(audit_events_table_id,updateJson): + try: + updatedConfig = "'" + str(json.dumps(updateJson)) + "'" + cur_audit.execute('update audit_events set data ='+updatedConfig+' where id ={}'.format(audit_events_table_id)) + except Exception as e: + print("Exception occurred while updating update json : ", e) + raise e + + +if __name__ == '__main__': + n = len(sys.argv) + + if n != 12: + print( + "Please pass valid 11 arguments ") + + platform_db = sys.argv[1] + platform_host = sys.argv[2] + oes_db = sys.argv[3] + oes_host = sys.argv[4] + autopilot_db = sys.argv[5] + autopilot_host = sys.argv[6] + audit_db = sys.argv[7] + audit_host = sys.argv[8] + visibility_db = sys.argv[9] + visibility_host = sys.argv[10] + port = sys.argv[11] + user_name = sys.argv[12] + password = sys.argv[13] + + # Establishing the platform db connection + platform_conn = psycopg2.connect(database=platform_db, user=user_name, password=password, host=platform_host, port=port) + print('Opened platform database connection successfully') + + # Establishing the oesdb db connection + oesdb_conn = psycopg2.connect(database=oes_db, user=user_name, password=password, + host=oes_host, port=port) + print("Sapor database connection established successfully") + + # Establishing the opsmx db connection + autopilot_conn = psycopg2.connect(database=autopilot_db, user=user_name, password=password, host=autopilot_host + , port=port) + print("autopilot database connection established successfully") + + # Establishing the audit db connection + audit_conn = psycopg2.connect(database=audit_db, user=user_name, password=password, host=audit_host, port=port) + print('Opened audit database connection successfully') + + # Establishing the visibility db connection + visibility_conn = psycopg2.connect(database=visibility_db, user=user_name, password=password, host=visibility_host, + port=port) + print("Visibility database connection established successfully") + + cur_platform = platform_conn.cursor() + cur_oesdb = oesdb_conn.cursor() + cur_autopilot = autopilot_conn.cursor() + cur_audit = audit_conn.cursor() + cur_visibility = visibility_conn.cursor() + perform_migration() \ No newline at end of file diff --git a/scripts/oes-data-migration-scripts/steps_to_migrate_from_v3.11.x_to_v3.12.txt b/scripts/oes-data-migration-scripts/steps_to_migrate_from_v3.11.x_to_v3.12.txt index 3fdf46c0..963a75a6 100644 --- a/scripts/oes-data-migration-scripts/steps_to_migrate_from_v3.11.x_to_v3.12.txt +++ b/scripts/oes-data-migration-scripts/steps_to_migrate_from_v3.11.x_to_v3.12.txt @@ -1,8 +1,8 @@ - Steps to migrate from v3.11.x to v3.12 +Steps to migrate from v3.11.x to v3.12 1. Copy the file : migration_v3.11.x_to_v3.12.py file from: