From 9cd6ade2940edffd780d1614fc8d5cbbb19be6fc Mon Sep 17 00:00:00 2001 From: Adam Lerman Date: Fri, 4 Oct 2024 19:29:16 +0000 Subject: [PATCH 01/16] Most ms added. Saving work for weekend. Still need query and query metrics --- datawave-accumulo-microservice/.gitignore | 5 + datawave-accumulo-microservice/.helmignore | 17 ++ datawave-accumulo-microservice/Chart.lock | 6 + datawave-accumulo-microservice/Chart.yaml | 22 ++ .../accumulo-microservice-deployment.yaml | 19 ++ .../accumulo-microservice-service.yaml | 4 + .../values.schema.json | 206 ++++++++++++++++++ datawave-accumulo-microservice/values.yaml | 65 ++++++ executor-pool/.gitignore | 5 + executor-pool/.helmignore | 17 ++ executor-pool/Chart.lock | 6 + executor-pool/Chart.yaml | 22 ++ .../accumulo-microservice-deployment.yaml | 19 ++ .../accumulo-microservice-service.yaml | 4 + executor-pool/values.schema.json | 206 ++++++++++++++++++ executor-pool/values.yaml | 67 ++++++ kafdrop/.gitignore | 5 + kafdrop/.helmignore | 17 ++ kafdrop/Chart.yaml | 18 ++ kafdrop/templates/kafdrop-deployment.yaml | 85 ++++++++ kafdrop/templates/kafdrop-service.yaml | 40 ++++ kafdrop/values.schema.json | 206 ++++++++++++++++++ kafdrop/values.yaml | 42 ++++ kafka/.gitignore | 5 + kafka/.helmignore | 17 ++ kafka/Chart.yaml | 18 ++ kafka/templates/kafka-service.yaml | 46 ++++ kafka/templates/kafka-statefulset.yaml | 104 +++++++++ kafka/values.schema.json | 206 ++++++++++++++++++ kafka/values.yaml | 32 +++ modification/.gitignore | 5 + modification/.helmignore | 17 ++ modification/Chart.yaml | 22 ++ .../templates/modification-deployment.yaml | 19 ++ .../templates/modification-service.yaml | 4 + modification/values.schema.json | 206 ++++++++++++++++++ modification/values.yaml | 67 ++++++ mr-query/.gitignore | 5 + mr-query/.helmignore | 17 ++ mr-query/Chart.yaml | 22 ++ mr-query/templates/mr-query-deployment.yaml | 19 ++ mr-query/templates/mr-query-service.yaml | 4 + mr-query/values.schema.json | 206 ++++++++++++++++++ mr-query/values.yaml | 67 ++++++ 44 files changed, 2211 insertions(+) create mode 100644 datawave-accumulo-microservice/.gitignore create mode 100644 datawave-accumulo-microservice/.helmignore create mode 100644 datawave-accumulo-microservice/Chart.lock create mode 100644 datawave-accumulo-microservice/Chart.yaml create mode 100644 datawave-accumulo-microservice/templates/accumulo-microservice-deployment.yaml create mode 100644 datawave-accumulo-microservice/templates/accumulo-microservice-service.yaml create mode 100644 datawave-accumulo-microservice/values.schema.json create mode 100644 datawave-accumulo-microservice/values.yaml create mode 100644 executor-pool/.gitignore create mode 100644 executor-pool/.helmignore create mode 100644 executor-pool/Chart.lock create mode 100644 executor-pool/Chart.yaml create mode 100644 executor-pool/templates/accumulo-microservice-deployment.yaml create mode 100644 executor-pool/templates/accumulo-microservice-service.yaml create mode 100644 executor-pool/values.schema.json create mode 100644 executor-pool/values.yaml create mode 100644 kafdrop/.gitignore create mode 100644 kafdrop/.helmignore create mode 100644 kafdrop/Chart.yaml create mode 100644 kafdrop/templates/kafdrop-deployment.yaml create mode 100644 kafdrop/templates/kafdrop-service.yaml create mode 100644 kafdrop/values.schema.json create mode 100644 kafdrop/values.yaml create mode 100644 kafka/.gitignore create mode 100644 kafka/.helmignore create mode 100644 kafka/Chart.yaml create mode 100644 kafka/templates/kafka-service.yaml create mode 100644 kafka/templates/kafka-statefulset.yaml create mode 100644 kafka/values.schema.json create mode 100644 kafka/values.yaml create mode 100644 modification/.gitignore create mode 100644 modification/.helmignore create mode 100644 modification/Chart.yaml create mode 100644 modification/templates/modification-deployment.yaml create mode 100644 modification/templates/modification-service.yaml create mode 100644 modification/values.schema.json create mode 100644 modification/values.yaml create mode 100644 mr-query/.gitignore create mode 100644 mr-query/.helmignore create mode 100644 mr-query/Chart.yaml create mode 100644 mr-query/templates/mr-query-deployment.yaml create mode 100644 mr-query/templates/mr-query-service.yaml create mode 100644 mr-query/values.schema.json create mode 100644 mr-query/values.yaml diff --git a/datawave-accumulo-microservice/.gitignore b/datawave-accumulo-microservice/.gitignore new file mode 100644 index 0000000..79f2743 --- /dev/null +++ b/datawave-accumulo-microservice/.gitignore @@ -0,0 +1,5 @@ +############################### +# Ignores Helm Chart Archives # +############################### + +**.tgz diff --git a/datawave-accumulo-microservice/.helmignore b/datawave-accumulo-microservice/.helmignore new file mode 100644 index 0000000..aa06c2c --- /dev/null +++ b/datawave-accumulo-microservice/.helmignore @@ -0,0 +1,17 @@ +########################################### +# Ignores All File or Path Related to Git # +########################################### + +.git + +##################################### +# Ignores All Development Resources # +##################################### + +development/ +setup.sh + +############################ +# Ignores package Archives # +############################ +dwv-accumulo-microservice-*.tgz diff --git a/datawave-accumulo-microservice/Chart.lock b/datawave-accumulo-microservice/Chart.lock new file mode 100644 index 0000000..c7d3c8d --- /dev/null +++ b/datawave-accumulo-microservice/Chart.lock @@ -0,0 +1,6 @@ +dependencies: +- name: common-service-library + repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts + version: 0.0.2 +digest: sha256:9f6737e1bdb7c4772bf295ccb128a1d540237dd1b7770e0edbd185d1b17a1a31 +generated: "2024-10-04T18:58:14.981876411Z" diff --git a/datawave-accumulo-microservice/Chart.yaml b/datawave-accumulo-microservice/Chart.yaml new file mode 100644 index 0000000..d735496 --- /dev/null +++ b/datawave-accumulo-microservice/Chart.yaml @@ -0,0 +1,22 @@ +################################# +# Core Helm Chart Configuration # +################################# + +apiVersion: v2 +name: dwv-accumulo-microservice +type: application +version: 1.0.0-SNAPSHOT + +################################# +# Basic Metadata for this Chart # +################################# + +appVersion: 4.0.2 +description: Deploys a datawave accumulo microservice +icon: https://code.nsa.gov/datawave/images/datawave-logo.png + +dependencies: + - name: common-service-library + repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts + version: 0.0.2 + diff --git a/datawave-accumulo-microservice/templates/accumulo-microservice-deployment.yaml b/datawave-accumulo-microservice/templates/accumulo-microservice-deployment.yaml new file mode 100644 index 0000000..194eb3e --- /dev/null +++ b/datawave-accumulo-microservice/templates/accumulo-microservice-deployment.yaml @@ -0,0 +1,19 @@ +{{- include "common-service-library.deployment" (list . "accumuloMicroservice.deployment") -}} +{{- define "accumuloMicroservice.deployment" -}} +#overrides go here +spec: + template: + spec: + initContainers: + - name: "{{ .Chart.Name }}-init-authorization" + image: "{{ .Values.global.initialization.image.name }}:{{ .Values.global.initialization.image.tag }}" + command: [ "sh", "-c", "until nc -z {{ .Values.global.serviceDns.authorization.name }} {{ .Values.global.serviceDns.authorization.port }}; do echo 'Waiting for Authorization...'; sleep 2; done" ] + + - name: "{{ .Chart.Name }}-init-cache" + image: "{{ .Values.global.initialization.image.name }}:{{ .Values.global.initialization.image.tag }}" + command: [ "sh", "-c", "until nc -z {{ .Values.global.serviceDns.cache.name }} {{ .Values.global.serviceDns.cache.port }}; do echo 'Waiting for Cache...'; sleep 2; done" ] + + - name: "{{ .Chart.Name }}-init-configuration" + image: "{{ .Values.global.initialization.image.name }}:{{ .Values.global.initialization.image.tag }}" + command: [ "sh", "-c", "until nc -z {{ .Values.global.serviceDns.configuration.name }} {{ .Values.global.serviceDns.configuration.port }}; do echo 'Waiting for Configuration...'; sleep 2; done" ] +{{- end -}} \ No newline at end of file diff --git a/datawave-accumulo-microservice/templates/accumulo-microservice-service.yaml b/datawave-accumulo-microservice/templates/accumulo-microservice-service.yaml new file mode 100644 index 0000000..2bcedaa --- /dev/null +++ b/datawave-accumulo-microservice/templates/accumulo-microservice-service.yaml @@ -0,0 +1,4 @@ +{{- include "common-service-library.service" (list . "accumuloMicroservice.service") -}} +{{- define "accumuloMicroservice.service" -}} +#overrides go here +{{- end -}} \ No newline at end of file diff --git a/datawave-accumulo-microservice/values.schema.json b/datawave-accumulo-microservice/values.schema.json new file mode 100644 index 0000000..068c816 --- /dev/null +++ b/datawave-accumulo-microservice/values.schema.json @@ -0,0 +1,206 @@ +{ + "$id": "https://code.nsa.org/datawave/schema", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "additionalProperties": true, + "description": "Schema for DataWave Helm values", + "properties": { + "args": { + "items": { + "type": "string" + }, + "type": "array" + }, + "global": { + "properties": { + "certSecretName": { + "type": "string" + }, + "dockerRegistry": { + "properties": { + "url": { + "type": "string" + } + }, + "type": "object" + }, + "initialization": { + "properties": { + "image": { + "properties": { + "name": { + "type": "string" + }, + "tag": { + "type": "number" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "pullSecrets": { + "items": { + "type": "string" + }, + "type": "array" + }, + "serviceDns": { + "properties": { + "authorization": { + "properties": { + "name": { + "type": "string" + } + }, + "type": "object" + }, + "cache": { + "properties": { + "name": { + "type": "string" + }, + "port": { + "type": "integer" + } + }, + "type": "object" + }, + "configuration": { + "properties": { + "name": { + "type": "string" + }, + "port": { + "type": "integer" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "volumes": { + "properties": { + "certificates": { + "properties": { + "destination": { + "type": "string" + }, + "name": { + "type": "string" + } + }, + "type": "object" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "image": { + "properties": { + "name": { + "type": "string" + }, + "pullPolicy": { + "type": "string" + }, + "tag": { + "type": "string" + } + }, + "type": "object" + }, + "livenessProbe": { + "properties": { + "delaySeconds": { + "type": "integer" + }, + "periodSeconds": { + "type": "integer" + }, + "port": { + "type": "integer" + }, + "scheme": { + "type": "string" + }, + "uri": { + "type": "string" + } + }, + "type": "object" + }, + "meta": { + "properties": { + "name": { + "type": "string" + } + }, + "type": "object" + }, + "ports": { + "properties": { + "http": { + "type": "integer" + }, + "https": { + "type": "integer" + } + }, + "type": "object" + }, + "readinessProbe": { + "properties": { + "delaySeconds": { + "type": "integer" + }, + "periodSeconds": { + "type": "integer" + }, + "port": { + "type": "integer" + }, + "scheme": { + "type": "string" + }, + "uri": { + "type": "string" + } + }, + "type": "object" + }, + "replication": { + "properties": { + "maxSurge": { + "type": "integer" + }, + "maxUnavailable": { + "type": "integer" + }, + "replicaCount": { + "type": "integer" + }, + "revisionHistoryLimit": { + "type": "integer" + } + }, + "type": "object" + }, + "restartPolicy": { + "type": "string" + }, + "service": { + "properties": { + "name": { + "type": "string" + } + }, + "type": "object" + } + }, + "title": "Helm Values Schema", + "type": "object" +} diff --git a/datawave-accumulo-microservice/values.yaml b/datawave-accumulo-microservice/values.yaml new file mode 100644 index 0000000..e8988ff --- /dev/null +++ b/datawave-accumulo-microservice/values.yaml @@ -0,0 +1,65 @@ +global: + dockerRegistry: + url: ghcr.io/nationalsecurityagency + volumes: + certificates: + name: certificates + destination: /data/certs + initialization: + image: + name: busybox + tag: 1.28 + certSecretName: certificates-secret + pullSecrets: + - dockerconfigjson-ghcr + serviceDns: + configuration: + name: configuration + port: 8888 + authorization: + name: authorization + cache: + name: cache + port: 8080 + + +################################################################ +# Default Values for Datawave Accumulo Microservice Deployment # +################################################################ +image: + name: datawave-accumulo-service + pullPolicy: IfNotPresent + tag: 4.0.2 +args: +- "--spring.output.ansi.enabled=ALWAYS" +- "--spring.profiles.active=default,k8s,remoteauth" +livenessProbe: + delaySeconds: 60 + periodSeconds: 5 + port: 8080 + scheme: HTTP + uri: accumulo/mgmt/health +meta: + name: accumulo-microservice +service: + name: accumulo +readinessProbe: + delaySeconds: 60 + periodSeconds: 5 + port: 8080 + scheme: HTTP + uri: accumulo/mgmt/health +replication: + maxSurge: 2 + maxUnavailable: 1 + replicaCount: 1 + revisionHistoryLimit: 10 +restartPolicy: Always + +#################################### +# Default Values for Audit Service # +#################################### + +ports: + http: 8080 + https: 8443 diff --git a/executor-pool/.gitignore b/executor-pool/.gitignore new file mode 100644 index 0000000..79f2743 --- /dev/null +++ b/executor-pool/.gitignore @@ -0,0 +1,5 @@ +############################### +# Ignores Helm Chart Archives # +############################### + +**.tgz diff --git a/executor-pool/.helmignore b/executor-pool/.helmignore new file mode 100644 index 0000000..aa06c2c --- /dev/null +++ b/executor-pool/.helmignore @@ -0,0 +1,17 @@ +########################################### +# Ignores All File or Path Related to Git # +########################################### + +.git + +##################################### +# Ignores All Development Resources # +##################################### + +development/ +setup.sh + +############################ +# Ignores package Archives # +############################ +dwv-accumulo-microservice-*.tgz diff --git a/executor-pool/Chart.lock b/executor-pool/Chart.lock new file mode 100644 index 0000000..c7d3c8d --- /dev/null +++ b/executor-pool/Chart.lock @@ -0,0 +1,6 @@ +dependencies: +- name: common-service-library + repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts + version: 0.0.2 +digest: sha256:9f6737e1bdb7c4772bf295ccb128a1d540237dd1b7770e0edbd185d1b17a1a31 +generated: "2024-10-04T18:58:14.981876411Z" diff --git a/executor-pool/Chart.yaml b/executor-pool/Chart.yaml new file mode 100644 index 0000000..6356828 --- /dev/null +++ b/executor-pool/Chart.yaml @@ -0,0 +1,22 @@ +################################# +# Core Helm Chart Configuration # +################################# + +apiVersion: v2 +name: dwv-executor +type: application +version: 1.0.0-SNAPSHOT + +################################# +# Basic Metadata for this Chart # +################################# + +appVersion: 1.0.9 +description: Deploys a datawave query executor service +icon: https://code.nsa.gov/datawave/images/datawave-logo.png + +dependencies: + - name: common-service-library + repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts + version: 0.0.2 + diff --git a/executor-pool/templates/accumulo-microservice-deployment.yaml b/executor-pool/templates/accumulo-microservice-deployment.yaml new file mode 100644 index 0000000..194eb3e --- /dev/null +++ b/executor-pool/templates/accumulo-microservice-deployment.yaml @@ -0,0 +1,19 @@ +{{- include "common-service-library.deployment" (list . "accumuloMicroservice.deployment") -}} +{{- define "accumuloMicroservice.deployment" -}} +#overrides go here +spec: + template: + spec: + initContainers: + - name: "{{ .Chart.Name }}-init-authorization" + image: "{{ .Values.global.initialization.image.name }}:{{ .Values.global.initialization.image.tag }}" + command: [ "sh", "-c", "until nc -z {{ .Values.global.serviceDns.authorization.name }} {{ .Values.global.serviceDns.authorization.port }}; do echo 'Waiting for Authorization...'; sleep 2; done" ] + + - name: "{{ .Chart.Name }}-init-cache" + image: "{{ .Values.global.initialization.image.name }}:{{ .Values.global.initialization.image.tag }}" + command: [ "sh", "-c", "until nc -z {{ .Values.global.serviceDns.cache.name }} {{ .Values.global.serviceDns.cache.port }}; do echo 'Waiting for Cache...'; sleep 2; done" ] + + - name: "{{ .Chart.Name }}-init-configuration" + image: "{{ .Values.global.initialization.image.name }}:{{ .Values.global.initialization.image.tag }}" + command: [ "sh", "-c", "until nc -z {{ .Values.global.serviceDns.configuration.name }} {{ .Values.global.serviceDns.configuration.port }}; do echo 'Waiting for Configuration...'; sleep 2; done" ] +{{- end -}} \ No newline at end of file diff --git a/executor-pool/templates/accumulo-microservice-service.yaml b/executor-pool/templates/accumulo-microservice-service.yaml new file mode 100644 index 0000000..2bcedaa --- /dev/null +++ b/executor-pool/templates/accumulo-microservice-service.yaml @@ -0,0 +1,4 @@ +{{- include "common-service-library.service" (list . "accumuloMicroservice.service") -}} +{{- define "accumuloMicroservice.service" -}} +#overrides go here +{{- end -}} \ No newline at end of file diff --git a/executor-pool/values.schema.json b/executor-pool/values.schema.json new file mode 100644 index 0000000..068c816 --- /dev/null +++ b/executor-pool/values.schema.json @@ -0,0 +1,206 @@ +{ + "$id": "https://code.nsa.org/datawave/schema", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "additionalProperties": true, + "description": "Schema for DataWave Helm values", + "properties": { + "args": { + "items": { + "type": "string" + }, + "type": "array" + }, + "global": { + "properties": { + "certSecretName": { + "type": "string" + }, + "dockerRegistry": { + "properties": { + "url": { + "type": "string" + } + }, + "type": "object" + }, + "initialization": { + "properties": { + "image": { + "properties": { + "name": { + "type": "string" + }, + "tag": { + "type": "number" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "pullSecrets": { + "items": { + "type": "string" + }, + "type": "array" + }, + "serviceDns": { + "properties": { + "authorization": { + "properties": { + "name": { + "type": "string" + } + }, + "type": "object" + }, + "cache": { + "properties": { + "name": { + "type": "string" + }, + "port": { + "type": "integer" + } + }, + "type": "object" + }, + "configuration": { + "properties": { + "name": { + "type": "string" + }, + "port": { + "type": "integer" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "volumes": { + "properties": { + "certificates": { + "properties": { + "destination": { + "type": "string" + }, + "name": { + "type": "string" + } + }, + "type": "object" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "image": { + "properties": { + "name": { + "type": "string" + }, + "pullPolicy": { + "type": "string" + }, + "tag": { + "type": "string" + } + }, + "type": "object" + }, + "livenessProbe": { + "properties": { + "delaySeconds": { + "type": "integer" + }, + "periodSeconds": { + "type": "integer" + }, + "port": { + "type": "integer" + }, + "scheme": { + "type": "string" + }, + "uri": { + "type": "string" + } + }, + "type": "object" + }, + "meta": { + "properties": { + "name": { + "type": "string" + } + }, + "type": "object" + }, + "ports": { + "properties": { + "http": { + "type": "integer" + }, + "https": { + "type": "integer" + } + }, + "type": "object" + }, + "readinessProbe": { + "properties": { + "delaySeconds": { + "type": "integer" + }, + "periodSeconds": { + "type": "integer" + }, + "port": { + "type": "integer" + }, + "scheme": { + "type": "string" + }, + "uri": { + "type": "string" + } + }, + "type": "object" + }, + "replication": { + "properties": { + "maxSurge": { + "type": "integer" + }, + "maxUnavailable": { + "type": "integer" + }, + "replicaCount": { + "type": "integer" + }, + "revisionHistoryLimit": { + "type": "integer" + } + }, + "type": "object" + }, + "restartPolicy": { + "type": "string" + }, + "service": { + "properties": { + "name": { + "type": "string" + } + }, + "type": "object" + } + }, + "title": "Helm Values Schema", + "type": "object" +} diff --git a/executor-pool/values.yaml b/executor-pool/values.yaml new file mode 100644 index 0000000..e71e1b7 --- /dev/null +++ b/executor-pool/values.yaml @@ -0,0 +1,67 @@ +global: + dockerRegistry: + url: ghcr.io/nationalsecurityagency + volumes: + certificates: + name: certificates + destination: /data/certs + initialization: + image: + name: busybox + tag: 1.28 + certSecretName: certificates-secret + pullSecrets: + - dockerconfigjson-ghcr + serviceDns: + configuration: + name: configuration + port: 8888 + authorization: + name: authorization + cache: + name: cache + port: 8080 + + +####################################### +# Default Values for Audit Deployment # +####################################### +image: + name: datawave-query-executor-service + pullPolicy: IfNotPresent + tag: 1.0.9 +args: +- "--spring.output.ansi.enabled=ALWAYS" +- "--spring.profiles.active= default,k8s,remoteauth,querymessaging,metricssource,federation,query,pool1" +livenessProbe: + delaySeconds: 20 + periodSeconds: 5 + failureThreshold: 60 + port: 8080 + scheme: HTTP + uri: executor/mgmt/health +meta: + name: executor +service: + name: executor +readinessProbe: + delaySeconds: 20 + periodSeconds: 5 + failureThreshold: 60 + port: 8080 + scheme: HTTP + uri: executor/mgmt/health +replication: + maxSurge: 2 + maxUnavailable: 1 + replicaCount: 1 + revisionHistoryLimit: 10 +restartPolicy: Always + +####################################### +# Default Values for Executor Service # +####################################### + +ports: + http: 8080 + https: 8443 diff --git a/kafdrop/.gitignore b/kafdrop/.gitignore new file mode 100644 index 0000000..79f2743 --- /dev/null +++ b/kafdrop/.gitignore @@ -0,0 +1,5 @@ +############################### +# Ignores Helm Chart Archives # +############################### + +**.tgz diff --git a/kafdrop/.helmignore b/kafdrop/.helmignore new file mode 100644 index 0000000..6a51bb8 --- /dev/null +++ b/kafdrop/.helmignore @@ -0,0 +1,17 @@ +########################################### +# Ignores All File or Path Related to Git # +########################################### + +.git + +##################################### +# Ignores All Development Resources # +##################################### + +development/ +setup.sh + +############################ +# Ignores package Archives # +############################ +dwv-kafdrop-*.tgz diff --git a/kafdrop/Chart.yaml b/kafdrop/Chart.yaml new file mode 100644 index 0000000..9d937a2 --- /dev/null +++ b/kafdrop/Chart.yaml @@ -0,0 +1,18 @@ +################################# +# Core Helm Chart Configuration # +################################# + +apiVersion: v2 +name: dwv-executor +type: application +version: 1.0.0-SNAPSHOT + +################################# +# Basic Metadata for this Chart # +################################# + +appVersion: latest +description: Deploys a Kafdrop instance +icon: https://code.nsa.gov/datawave/images/datawave-logo.png + + diff --git a/kafdrop/templates/kafdrop-deployment.yaml b/kafdrop/templates/kafdrop-deployment.yaml new file mode 100644 index 0000000..fd6e139 --- /dev/null +++ b/kafdrop/templates/kafdrop-deployment.yaml @@ -0,0 +1,85 @@ +#################################### +# Core Helm Template Configuration # +#################################### + +apiVersion: apps/v1 +kind: Deployment + +###################################### +# Basic Metadata for this Deployment # +###################################### + +metadata: + name: "{{ .Chart.Name }}-{{ .Values.meta.name }}" + labels: + application: "{{ .Chart.Name }}-{{ .Values.meta.name }}" + +##################################### +# Complete Deployment Specification # +##################################### + +spec: + + ###################################### + # Replication / Update Configuration # + ###################################### + + replicas: {{ .Values.replication.replicaCount }} + revisionHistoryLimit: {{ .Values.replication.revisionHistoryLimit }} + strategy: + type: RollingUpdate + rollingUpdate: + maxSurge: {{ .Values.replication.maxSurge }} + maxUnavailable: {{ .Values.replication.maxUnavailable }} + + ################################### + # Resource Selector Configuration # + ################################### + + selector: + matchLabels: + application: "{{ .Chart.Name }}-{{ .Values.meta.name }}" + + ##################################### + # Deployment Template Configuration # + ##################################### + + template: + + ################################################## + # Basic Metadata for this Deployment's Resources # + ################################################## + + metadata: + labels: + application: "{{ .Chart.Name }}-{{ .Values.meta.name }}" + + ####################################### + # Deployment Resources Specifications # + ####################################### + + spec: + {{- with .Values.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.pullSecrets }} + imagePullSecrets: + {{- range . }} + - name: {{ . }} + {{- end }} + {{- end }} + securityContext: + runAsUser: 1000 + fsGroup: 1000 + restartPolicy: "{{ .Values.restartPolicy }}" + ############################################## + # Containers Associated with this Deployment # + ############################################## + + containers: + + - name: "{{ .Chart.Name }}-{{ .Values.meta.name }}" + image: "{{ .Values.image.name }}:{{ .Values.image.tag }}" + imagePullPolicy: "{{ .Values.image.pullPolicy }}" + resources: {} diff --git a/kafdrop/templates/kafdrop-service.yaml b/kafdrop/templates/kafdrop-service.yaml new file mode 100644 index 0000000..002e33d --- /dev/null +++ b/kafdrop/templates/kafdrop-service.yaml @@ -0,0 +1,40 @@ +#################################### +# Core Helm Template Configuration # +#################################### + +apiVersion: v1 +kind: Service + +###################################### +# Basic Metadata for this Deployment # +###################################### + +metadata: + name: "{{ .Values.service.name }}" + labels: + application: "{{ .Values.service.name }}" + +################################## +# Complete Service Specification # +################################## + +spec: + + ############################### + # Pod Selection Configuration # + ############################### + + selector: + application: "{{ .Values.service.name }}" + + ############################## + # Service Port Configuration # + ############################## + + ports: + + - name: kafdrop + port: {{ .Values.ports.kafdrop }} + targetPort: 9000 + + diff --git a/kafdrop/values.schema.json b/kafdrop/values.schema.json new file mode 100644 index 0000000..068c816 --- /dev/null +++ b/kafdrop/values.schema.json @@ -0,0 +1,206 @@ +{ + "$id": "https://code.nsa.org/datawave/schema", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "additionalProperties": true, + "description": "Schema for DataWave Helm values", + "properties": { + "args": { + "items": { + "type": "string" + }, + "type": "array" + }, + "global": { + "properties": { + "certSecretName": { + "type": "string" + }, + "dockerRegistry": { + "properties": { + "url": { + "type": "string" + } + }, + "type": "object" + }, + "initialization": { + "properties": { + "image": { + "properties": { + "name": { + "type": "string" + }, + "tag": { + "type": "number" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "pullSecrets": { + "items": { + "type": "string" + }, + "type": "array" + }, + "serviceDns": { + "properties": { + "authorization": { + "properties": { + "name": { + "type": "string" + } + }, + "type": "object" + }, + "cache": { + "properties": { + "name": { + "type": "string" + }, + "port": { + "type": "integer" + } + }, + "type": "object" + }, + "configuration": { + "properties": { + "name": { + "type": "string" + }, + "port": { + "type": "integer" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "volumes": { + "properties": { + "certificates": { + "properties": { + "destination": { + "type": "string" + }, + "name": { + "type": "string" + } + }, + "type": "object" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "image": { + "properties": { + "name": { + "type": "string" + }, + "pullPolicy": { + "type": "string" + }, + "tag": { + "type": "string" + } + }, + "type": "object" + }, + "livenessProbe": { + "properties": { + "delaySeconds": { + "type": "integer" + }, + "periodSeconds": { + "type": "integer" + }, + "port": { + "type": "integer" + }, + "scheme": { + "type": "string" + }, + "uri": { + "type": "string" + } + }, + "type": "object" + }, + "meta": { + "properties": { + "name": { + "type": "string" + } + }, + "type": "object" + }, + "ports": { + "properties": { + "http": { + "type": "integer" + }, + "https": { + "type": "integer" + } + }, + "type": "object" + }, + "readinessProbe": { + "properties": { + "delaySeconds": { + "type": "integer" + }, + "periodSeconds": { + "type": "integer" + }, + "port": { + "type": "integer" + }, + "scheme": { + "type": "string" + }, + "uri": { + "type": "string" + } + }, + "type": "object" + }, + "replication": { + "properties": { + "maxSurge": { + "type": "integer" + }, + "maxUnavailable": { + "type": "integer" + }, + "replicaCount": { + "type": "integer" + }, + "revisionHistoryLimit": { + "type": "integer" + } + }, + "type": "object" + }, + "restartPolicy": { + "type": "string" + }, + "service": { + "properties": { + "name": { + "type": "string" + } + }, + "type": "object" + } + }, + "title": "Helm Values Schema", + "type": "object" +} diff --git a/kafdrop/values.yaml b/kafdrop/values.yaml new file mode 100644 index 0000000..67b46c3 --- /dev/null +++ b/kafdrop/values.yaml @@ -0,0 +1,42 @@ +global: + dockerRegistry: + url: ghcr.io/nationalsecurityagency + volumes: + certificates: + name: certificates + destination: /data/certs + initialization: + image: + name: busybox + tag: 1.28 + certSecretName: certificates-secret + pullSecrets: + - dockerconfigjson-ghcr + +####################################### +# Default Values for Audit Deployment # +####################################### +image: + name: obsidiandynamics/kafdrop + pullPolicy: IfNotPresent + tag: latest +args: [] + +meta: + name: kafdrop +service: + name: kafdrop + +replication: + maxSurge: 2 + maxUnavailable: 1 + replicaCount: 1 + revisionHistoryLimit: 10 +restartPolicy: Always + +####################################### +# Default Values for Executor Service # +####################################### + +ports: + kafdrop: 9000 diff --git a/kafka/.gitignore b/kafka/.gitignore new file mode 100644 index 0000000..79f2743 --- /dev/null +++ b/kafka/.gitignore @@ -0,0 +1,5 @@ +############################### +# Ignores Helm Chart Archives # +############################### + +**.tgz diff --git a/kafka/.helmignore b/kafka/.helmignore new file mode 100644 index 0000000..832a84e --- /dev/null +++ b/kafka/.helmignore @@ -0,0 +1,17 @@ +########################################### +# Ignores All File or Path Related to Git # +########################################### + +.git + +##################################### +# Ignores All Development Resources # +##################################### + +development/ +setup.sh + +############################ +# Ignores package Archives # +############################ +dwv-kafka-*.tgz diff --git a/kafka/Chart.yaml b/kafka/Chart.yaml new file mode 100644 index 0000000..8942d69 --- /dev/null +++ b/kafka/Chart.yaml @@ -0,0 +1,18 @@ +################################# +# Core Helm Chart Configuration # +################################# + +apiVersion: v2 +name: dwv-kafka +type: application +version: 1.0.0-SNAPSHOT + +################################# +# Basic Metadata for this Chart # +################################# + +appVersion: 3.2.3 +description: Deploys a kafka deployment +icon: https://code.nsa.gov/datawave/images/datawave-logo.png + + diff --git a/kafka/templates/kafka-service.yaml b/kafka/templates/kafka-service.yaml new file mode 100644 index 0000000..9dd33f5 --- /dev/null +++ b/kafka/templates/kafka-service.yaml @@ -0,0 +1,46 @@ +#################################### +# Core Helm Template Configuration # +#################################### + +apiVersion: v1 +kind: Service + +###################################### +# Basic Metadata for this Deployment # +###################################### + +metadata: + name: "{{ .Values.service.name }}" + labels: + application: "{{ .Values.meta.name }}" + +################################## +# Complete Service Specification # +################################## + +spec: + + ############################### + # Pod Selection Configuration # + ############################### + + selector: + application: "{{ .Values.meta.name }}" + + ############################## + # Service Port Configuration # + ############################## + + ports: + + - name: kafka-controller + port: {{ .Values.ports.controller }} + targetPort: 9093 + + - name: kafka-client + port: {{ .Values.ports.client }} + targetPort: 9092 + + - name: kafka-external + port: {{ .Values.ports.external }} + targetPort: 9094 diff --git a/kafka/templates/kafka-statefulset.yaml b/kafka/templates/kafka-statefulset.yaml new file mode 100644 index 0000000..22c9d97 --- /dev/null +++ b/kafka/templates/kafka-statefulset.yaml @@ -0,0 +1,104 @@ +#################################### +# Core Helm Template Configuration # +#################################### + +apiVersion: apps/v1 +kind: StatefulSet + +###################################### +# Basic Metadata for this Deployment # +###################################### + +metadata: + name: "{{ .Values.meta.name }}" + labels: + application: "{{ .Values.meta.name }}" + +##################################### +# Complete Deployment Specification # +##################################### + +spec: + + ###################################### + # Replication / Update Configuration # + ###################################### + serviceName: "{{ .Values.meta.name }}" + replicas: {{ .Values.replication.replicaCount }} + revisionHistoryLimit: {{ .Values.replication.revisionHistoryLimit }} + + ################################### + # Resource Selector Configuration # + ################################### + + selector: + matchLabels: + application: "{{ .Values.meta.name }}" + + ##################################### + # Deployment Template Configuration # + ##################################### + + template: + + ################################################## + # Basic Metadata for this Deployment's Resources # + ################################################## + + metadata: + labels: + application: "{{ .Values.meta.name }}" + + ####################################### + # Deployment Resources Specifications # + ####################################### + + spec: + {{- with .Values.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.image.pullSecrets }} + imagePullSecrets: + {{- range . }} + - name: {{ . }} + {{- end }} + {{- end }} + securityContext: + runAsUser: 1000 + fsGroup: 1000 + restartPolicy: "{{ .Values.restartPolicy }}" + ############################################## + # Containers Associated with this Deployment # + ############################################## + + containers: + - name: "{{ .Values.meta.name }}" + image: "{{ .Values.image.name }}:{{ .Values.image.tag }}" + imagePullPolicy: "{{ .Values.image.pullPolicy }}" + resources: {} + env: + - name: KAFKA_CFG_NODE_ID + value: "1" + - name: KAFKA_CFG_PROCESS_ROLES + value: controller,broker + - name: ALLOW_PLAINTEXT_LISTENER + value: "yes" + - name: KAFKA_CFG_LISTENER_SECURITY_PROTOCOL_MAP + value: CLIENT:PLAINTEXT,CONTROLLER:PLAINTEXT,EXTERNAL:PLAINTEXT + - name: KAFKA_CFG_LISTENERS + value: CLIENT://:9092,CONTROLLER://:9093,EXTERNAL://:9094 + - name: KAFKA_CFG_MAX_REQUEST_SIZE + value: "10485880" + - name: KAFKA_CFG_ADVERTISED_LISTENERS + value: CLIENT://{{ .Values.meta.name }}:9092,EXTERNAL://{{ .Values.meta.name }}-0:9094 + - name: KAFKA_CFG_CONTROLLER_QUORUM_VOTERS + value: 1@{{ .Values.meta.name }}:9093 + - name: KAFKA_CFG_CONTROLLER_LISTENER_NAMES + value: CONTROLLER + - name: KAFKA_INTER_BROKER_LISTENER_NAME + value: CLIENT + - name: KAFKA_CFG_AUTO_CREATE_TOPICS_ENABLE + value: "false" + - name: KAFKA_CFG_DELETE_TOPICS_ENABLE + value: "true" diff --git a/kafka/values.schema.json b/kafka/values.schema.json new file mode 100644 index 0000000..068c816 --- /dev/null +++ b/kafka/values.schema.json @@ -0,0 +1,206 @@ +{ + "$id": "https://code.nsa.org/datawave/schema", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "additionalProperties": true, + "description": "Schema for DataWave Helm values", + "properties": { + "args": { + "items": { + "type": "string" + }, + "type": "array" + }, + "global": { + "properties": { + "certSecretName": { + "type": "string" + }, + "dockerRegistry": { + "properties": { + "url": { + "type": "string" + } + }, + "type": "object" + }, + "initialization": { + "properties": { + "image": { + "properties": { + "name": { + "type": "string" + }, + "tag": { + "type": "number" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "pullSecrets": { + "items": { + "type": "string" + }, + "type": "array" + }, + "serviceDns": { + "properties": { + "authorization": { + "properties": { + "name": { + "type": "string" + } + }, + "type": "object" + }, + "cache": { + "properties": { + "name": { + "type": "string" + }, + "port": { + "type": "integer" + } + }, + "type": "object" + }, + "configuration": { + "properties": { + "name": { + "type": "string" + }, + "port": { + "type": "integer" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "volumes": { + "properties": { + "certificates": { + "properties": { + "destination": { + "type": "string" + }, + "name": { + "type": "string" + } + }, + "type": "object" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "image": { + "properties": { + "name": { + "type": "string" + }, + "pullPolicy": { + "type": "string" + }, + "tag": { + "type": "string" + } + }, + "type": "object" + }, + "livenessProbe": { + "properties": { + "delaySeconds": { + "type": "integer" + }, + "periodSeconds": { + "type": "integer" + }, + "port": { + "type": "integer" + }, + "scheme": { + "type": "string" + }, + "uri": { + "type": "string" + } + }, + "type": "object" + }, + "meta": { + "properties": { + "name": { + "type": "string" + } + }, + "type": "object" + }, + "ports": { + "properties": { + "http": { + "type": "integer" + }, + "https": { + "type": "integer" + } + }, + "type": "object" + }, + "readinessProbe": { + "properties": { + "delaySeconds": { + "type": "integer" + }, + "periodSeconds": { + "type": "integer" + }, + "port": { + "type": "integer" + }, + "scheme": { + "type": "string" + }, + "uri": { + "type": "string" + } + }, + "type": "object" + }, + "replication": { + "properties": { + "maxSurge": { + "type": "integer" + }, + "maxUnavailable": { + "type": "integer" + }, + "replicaCount": { + "type": "integer" + }, + "revisionHistoryLimit": { + "type": "integer" + } + }, + "type": "object" + }, + "restartPolicy": { + "type": "string" + }, + "service": { + "properties": { + "name": { + "type": "string" + } + }, + "type": "object" + } + }, + "title": "Helm Values Schema", + "type": "object" +} diff --git a/kafka/values.yaml b/kafka/values.yaml new file mode 100644 index 0000000..3bd8527 --- /dev/null +++ b/kafka/values.yaml @@ -0,0 +1,32 @@ +####################################### +# Default Values for Kafka Deployment # +####################################### +image: + name: bitnami/kafka + pullPolicy: IfNotPresent + tag: 3.2.3 + + +meta: + name: kafka +service: + name: kafka + +replication: + maxSurge: 2 + maxUnavailable: 1 + replicaCount: 1 + revisionHistoryLimit: 10 +restartPolicy: Always + +####################################### +# Default Values for Executor Service # +####################################### + +ports: + client: 9092 + controller: 9093 + external: 9094 + +tolerations: [] + \ No newline at end of file diff --git a/modification/.gitignore b/modification/.gitignore new file mode 100644 index 0000000..79f2743 --- /dev/null +++ b/modification/.gitignore @@ -0,0 +1,5 @@ +############################### +# Ignores Helm Chart Archives # +############################### + +**.tgz diff --git a/modification/.helmignore b/modification/.helmignore new file mode 100644 index 0000000..0d2ae28 --- /dev/null +++ b/modification/.helmignore @@ -0,0 +1,17 @@ +########################################### +# Ignores All File or Path Related to Git # +########################################### + +.git + +##################################### +# Ignores All Development Resources # +##################################### + +development/ +setup.sh + +############################ +# Ignores package Archives # +############################ +dwv-amodification-*.tgz diff --git a/modification/Chart.yaml b/modification/Chart.yaml new file mode 100644 index 0000000..ee1adf4 --- /dev/null +++ b/modification/Chart.yaml @@ -0,0 +1,22 @@ +################################# +# Core Helm Chart Configuration # +################################# + +apiVersion: v2 +name: dwv-modification +type: application +version: 1.0.0-SNAPSHOT + +################################# +# Basic Metadata for this Chart # +################################# + +appVersion: 1.0.3 +description: Deploys a datawave modification service +icon: https://code.nsa.gov/datawave/images/datawave-logo.png + +dependencies: + - name: common-service-library + repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts + version: 0.0.2 + diff --git a/modification/templates/modification-deployment.yaml b/modification/templates/modification-deployment.yaml new file mode 100644 index 0000000..194eb3e --- /dev/null +++ b/modification/templates/modification-deployment.yaml @@ -0,0 +1,19 @@ +{{- include "common-service-library.deployment" (list . "accumuloMicroservice.deployment") -}} +{{- define "accumuloMicroservice.deployment" -}} +#overrides go here +spec: + template: + spec: + initContainers: + - name: "{{ .Chart.Name }}-init-authorization" + image: "{{ .Values.global.initialization.image.name }}:{{ .Values.global.initialization.image.tag }}" + command: [ "sh", "-c", "until nc -z {{ .Values.global.serviceDns.authorization.name }} {{ .Values.global.serviceDns.authorization.port }}; do echo 'Waiting for Authorization...'; sleep 2; done" ] + + - name: "{{ .Chart.Name }}-init-cache" + image: "{{ .Values.global.initialization.image.name }}:{{ .Values.global.initialization.image.tag }}" + command: [ "sh", "-c", "until nc -z {{ .Values.global.serviceDns.cache.name }} {{ .Values.global.serviceDns.cache.port }}; do echo 'Waiting for Cache...'; sleep 2; done" ] + + - name: "{{ .Chart.Name }}-init-configuration" + image: "{{ .Values.global.initialization.image.name }}:{{ .Values.global.initialization.image.tag }}" + command: [ "sh", "-c", "until nc -z {{ .Values.global.serviceDns.configuration.name }} {{ .Values.global.serviceDns.configuration.port }}; do echo 'Waiting for Configuration...'; sleep 2; done" ] +{{- end -}} \ No newline at end of file diff --git a/modification/templates/modification-service.yaml b/modification/templates/modification-service.yaml new file mode 100644 index 0000000..2bcedaa --- /dev/null +++ b/modification/templates/modification-service.yaml @@ -0,0 +1,4 @@ +{{- include "common-service-library.service" (list . "accumuloMicroservice.service") -}} +{{- define "accumuloMicroservice.service" -}} +#overrides go here +{{- end -}} \ No newline at end of file diff --git a/modification/values.schema.json b/modification/values.schema.json new file mode 100644 index 0000000..068c816 --- /dev/null +++ b/modification/values.schema.json @@ -0,0 +1,206 @@ +{ + "$id": "https://code.nsa.org/datawave/schema", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "additionalProperties": true, + "description": "Schema for DataWave Helm values", + "properties": { + "args": { + "items": { + "type": "string" + }, + "type": "array" + }, + "global": { + "properties": { + "certSecretName": { + "type": "string" + }, + "dockerRegistry": { + "properties": { + "url": { + "type": "string" + } + }, + "type": "object" + }, + "initialization": { + "properties": { + "image": { + "properties": { + "name": { + "type": "string" + }, + "tag": { + "type": "number" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "pullSecrets": { + "items": { + "type": "string" + }, + "type": "array" + }, + "serviceDns": { + "properties": { + "authorization": { + "properties": { + "name": { + "type": "string" + } + }, + "type": "object" + }, + "cache": { + "properties": { + "name": { + "type": "string" + }, + "port": { + "type": "integer" + } + }, + "type": "object" + }, + "configuration": { + "properties": { + "name": { + "type": "string" + }, + "port": { + "type": "integer" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "volumes": { + "properties": { + "certificates": { + "properties": { + "destination": { + "type": "string" + }, + "name": { + "type": "string" + } + }, + "type": "object" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "image": { + "properties": { + "name": { + "type": "string" + }, + "pullPolicy": { + "type": "string" + }, + "tag": { + "type": "string" + } + }, + "type": "object" + }, + "livenessProbe": { + "properties": { + "delaySeconds": { + "type": "integer" + }, + "periodSeconds": { + "type": "integer" + }, + "port": { + "type": "integer" + }, + "scheme": { + "type": "string" + }, + "uri": { + "type": "string" + } + }, + "type": "object" + }, + "meta": { + "properties": { + "name": { + "type": "string" + } + }, + "type": "object" + }, + "ports": { + "properties": { + "http": { + "type": "integer" + }, + "https": { + "type": "integer" + } + }, + "type": "object" + }, + "readinessProbe": { + "properties": { + "delaySeconds": { + "type": "integer" + }, + "periodSeconds": { + "type": "integer" + }, + "port": { + "type": "integer" + }, + "scheme": { + "type": "string" + }, + "uri": { + "type": "string" + } + }, + "type": "object" + }, + "replication": { + "properties": { + "maxSurge": { + "type": "integer" + }, + "maxUnavailable": { + "type": "integer" + }, + "replicaCount": { + "type": "integer" + }, + "revisionHistoryLimit": { + "type": "integer" + } + }, + "type": "object" + }, + "restartPolicy": { + "type": "string" + }, + "service": { + "properties": { + "name": { + "type": "string" + } + }, + "type": "object" + } + }, + "title": "Helm Values Schema", + "type": "object" +} diff --git a/modification/values.yaml b/modification/values.yaml new file mode 100644 index 0000000..3550ed8 --- /dev/null +++ b/modification/values.yaml @@ -0,0 +1,67 @@ +global: + dockerRegistry: + url: ghcr.io/nationalsecurityagency + volumes: + certificates: + name: certificates + destination: /data/certs + initialization: + image: + name: busybox + tag: 1.28 + certSecretName: certificates-secret + pullSecrets: + - dockerconfigjson-ghcr + serviceDns: + configuration: + name: configuration + port: 8888 + authorization: + name: authorization + cache: + name: cache + port: 8080 + + +####################################### +# Default Values for Audit Deployment # +####################################### +image: + name: datawave-modification-service + pullPolicy: IfNotPresent + tag: 1.0.2 +args: +- "--spring.output.ansi.enabled=ALWAYS" +- "--spring.profiles.active=default,k8s,remoteauth,query" +livenessProbe: + delaySeconds: 20 + periodSeconds: 5 + failureThreshold: 60 + port: 8080 + scheme: HTTP + uri: modification/mgmt/health +meta: + name: modification +service: + name: modification +readinessProbe: + delaySeconds: 20 + periodSeconds: 5 + failureThreshold: 60 + port: 8080 + scheme: HTTP + uri: modification/mgmt/health +replication: + maxSurge: 2 + maxUnavailable: 1 + replicaCount: 1 + revisionHistoryLimit: 10 +restartPolicy: Always + +####################################### +# Default Values for Executor Service # +####################################### + +ports: + http: 8080 + https: 8443 diff --git a/mr-query/.gitignore b/mr-query/.gitignore new file mode 100644 index 0000000..79f2743 --- /dev/null +++ b/mr-query/.gitignore @@ -0,0 +1,5 @@ +############################### +# Ignores Helm Chart Archives # +############################### + +**.tgz diff --git a/mr-query/.helmignore b/mr-query/.helmignore new file mode 100644 index 0000000..0d2ae28 --- /dev/null +++ b/mr-query/.helmignore @@ -0,0 +1,17 @@ +########################################### +# Ignores All File or Path Related to Git # +########################################### + +.git + +##################################### +# Ignores All Development Resources # +##################################### + +development/ +setup.sh + +############################ +# Ignores package Archives # +############################ +dwv-amodification-*.tgz diff --git a/mr-query/Chart.yaml b/mr-query/Chart.yaml new file mode 100644 index 0000000..a9ebe00 --- /dev/null +++ b/mr-query/Chart.yaml @@ -0,0 +1,22 @@ +################################# +# Core Helm Chart Configuration # +################################# + +apiVersion: v2 +name: dwv-mr-query +type: application +version: 1.0.0-SNAPSHOT + +################################# +# Basic Metadata for this Chart # +################################# + +appVersion: 1.0.4 +description: Deploys a datawave mr-query service +icon: https://code.nsa.gov/datawave/images/datawave-logo.png + +dependencies: + - name: common-service-library + repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts + version: 0.0.2 + diff --git a/mr-query/templates/mr-query-deployment.yaml b/mr-query/templates/mr-query-deployment.yaml new file mode 100644 index 0000000..7e0c3ed --- /dev/null +++ b/mr-query/templates/mr-query-deployment.yaml @@ -0,0 +1,19 @@ +{{- include "common-service-library.deployment" (list . "mrQuery.deployment") -}} +{{- define "mrQuery.deployment" -}} +#overrides go here +spec: + template: + spec: + initContainers: + - name: "{{ .Chart.Name }}-init-authorization" + image: "{{ .Values.global.initialization.image.name }}:{{ .Values.global.initialization.image.tag }}" + command: [ "sh", "-c", "until nc -z {{ .Values.global.serviceDns.authorization.name }} {{ .Values.global.serviceDns.authorization.port }}; do echo 'Waiting for Authorization...'; sleep 2; done" ] + + - name: "{{ .Chart.Name }}-init-cache" + image: "{{ .Values.global.initialization.image.name }}:{{ .Values.global.initialization.image.tag }}" + command: [ "sh", "-c", "until nc -z {{ .Values.global.serviceDns.cache.name }} {{ .Values.global.serviceDns.cache.port }}; do echo 'Waiting for Cache...'; sleep 2; done" ] + + - name: "{{ .Chart.Name }}-init-configuration" + image: "{{ .Values.global.initialization.image.name }}:{{ .Values.global.initialization.image.tag }}" + command: [ "sh", "-c", "until nc -z {{ .Values.global.serviceDns.configuration.name }} {{ .Values.global.serviceDns.configuration.port }}; do echo 'Waiting for Configuration...'; sleep 2; done" ] +{{- end -}} \ No newline at end of file diff --git a/mr-query/templates/mr-query-service.yaml b/mr-query/templates/mr-query-service.yaml new file mode 100644 index 0000000..4b7c554 --- /dev/null +++ b/mr-query/templates/mr-query-service.yaml @@ -0,0 +1,4 @@ +{{- include "common-service-library.service" (list . "mrQuery.service") -}} +{{- define "mrQuery.service" -}} +#overrides go here +{{- end -}} \ No newline at end of file diff --git a/mr-query/values.schema.json b/mr-query/values.schema.json new file mode 100644 index 0000000..068c816 --- /dev/null +++ b/mr-query/values.schema.json @@ -0,0 +1,206 @@ +{ + "$id": "https://code.nsa.org/datawave/schema", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "additionalProperties": true, + "description": "Schema for DataWave Helm values", + "properties": { + "args": { + "items": { + "type": "string" + }, + "type": "array" + }, + "global": { + "properties": { + "certSecretName": { + "type": "string" + }, + "dockerRegistry": { + "properties": { + "url": { + "type": "string" + } + }, + "type": "object" + }, + "initialization": { + "properties": { + "image": { + "properties": { + "name": { + "type": "string" + }, + "tag": { + "type": "number" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "pullSecrets": { + "items": { + "type": "string" + }, + "type": "array" + }, + "serviceDns": { + "properties": { + "authorization": { + "properties": { + "name": { + "type": "string" + } + }, + "type": "object" + }, + "cache": { + "properties": { + "name": { + "type": "string" + }, + "port": { + "type": "integer" + } + }, + "type": "object" + }, + "configuration": { + "properties": { + "name": { + "type": "string" + }, + "port": { + "type": "integer" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "volumes": { + "properties": { + "certificates": { + "properties": { + "destination": { + "type": "string" + }, + "name": { + "type": "string" + } + }, + "type": "object" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "image": { + "properties": { + "name": { + "type": "string" + }, + "pullPolicy": { + "type": "string" + }, + "tag": { + "type": "string" + } + }, + "type": "object" + }, + "livenessProbe": { + "properties": { + "delaySeconds": { + "type": "integer" + }, + "periodSeconds": { + "type": "integer" + }, + "port": { + "type": "integer" + }, + "scheme": { + "type": "string" + }, + "uri": { + "type": "string" + } + }, + "type": "object" + }, + "meta": { + "properties": { + "name": { + "type": "string" + } + }, + "type": "object" + }, + "ports": { + "properties": { + "http": { + "type": "integer" + }, + "https": { + "type": "integer" + } + }, + "type": "object" + }, + "readinessProbe": { + "properties": { + "delaySeconds": { + "type": "integer" + }, + "periodSeconds": { + "type": "integer" + }, + "port": { + "type": "integer" + }, + "scheme": { + "type": "string" + }, + "uri": { + "type": "string" + } + }, + "type": "object" + }, + "replication": { + "properties": { + "maxSurge": { + "type": "integer" + }, + "maxUnavailable": { + "type": "integer" + }, + "replicaCount": { + "type": "integer" + }, + "revisionHistoryLimit": { + "type": "integer" + } + }, + "type": "object" + }, + "restartPolicy": { + "type": "string" + }, + "service": { + "properties": { + "name": { + "type": "string" + } + }, + "type": "object" + } + }, + "title": "Helm Values Schema", + "type": "object" +} diff --git a/mr-query/values.yaml b/mr-query/values.yaml new file mode 100644 index 0000000..d6931d5 --- /dev/null +++ b/mr-query/values.yaml @@ -0,0 +1,67 @@ +global: + dockerRegistry: + url: ghcr.io/nationalsecurityagency + volumes: + certificates: + name: certificates + destination: /data/certs + initialization: + image: + name: busybox + tag: 1.28 + certSecretName: certificates-secret + pullSecrets: + - dockerconfigjson-ghcr + serviceDns: + configuration: + name: configuration + port: 8888 + authorization: + name: authorization + cache: + name: cache + port: 8080 + + +####################################### +# Default Values for Audit Deployment # +####################################### +image: + name: datawave-mapreduce-query-service + pullPolicy: IfNotPresent + tag: 1.0.4 +args: +- "--spring.output.ansi.enabled=ALWAYS" +- "--spring.profiles.active=default,k8s,remoteauth,query" +livenessProbe: + delaySeconds: 20 + periodSeconds: 5 + failureThreshold: 60 + port: 8080 + scheme: HTTP + uri: mrquery/mgmt/health +meta: + name: mr-query +service: + name: mr-query +readinessProbe: + delaySeconds: 20 + periodSeconds: 5 + failureThreshold: 60 + port: 8080 + scheme: HTTP + uri: mrquery/mgmt/health +replication: + maxSurge: 2 + maxUnavailable: 1 + replicaCount: 1 + revisionHistoryLimit: 10 +restartPolicy: Always + +####################################### +# Default Values for Executor Service # +####################################### + +ports: + http: 8080 + https: 8443 From 356f4da2abfae4c83a96a6712d7050a9c681714e Mon Sep 17 00:00:00 2001 From: Adam Lerman Date: Tue, 8 Oct 2024 23:50:38 +0000 Subject: [PATCH 02/16] QMS next step complete --- datawave-qms-stack/.helmignore | 19 ++ datawave-qms-stack/.schema.yaml | 13 ++ datawave-qms-stack/Chart.lock | 21 ++ datawave-qms-stack/Chart.yaml | 38 ++++ datawave-qms-stack/README.md | 3 + datawave-qms-stack/certificates/keystore.p12 | Bin 0 -> 3586 bytes .../certificates/truststore.jks | Bin 0 -> 163715 bytes datawave-qms-stack/templates/_helpers.tpl | 23 ++ datawave-qms-stack/templates/hdfs.yaml | 19 ++ datawave-qms-stack/templates/yarn.yaml | 19 ++ datawave-qms-stack/templates/zookeeper.yaml | 24 ++ datawave-qms-stack/values-testing.yaml | 8 + datawave-qms-stack/values.schema.json | 88 ++++++++ datawave-qms-stack/values.yaml | 27 +++ datawave-qms-umbrella/.schema.yaml | 13 ++ datawave-qms-umbrella/Chart.lock | 42 ++++ datawave-qms-umbrella/Chart.yaml | 57 +++++ datawave-qms-umbrella/README.md | 3 + datawave-qms-umbrella/values.schema.json | 74 +++++++ datawave-qms-umbrella/values.yaml | 22 ++ executor/.gitignore | 5 + executor/.helmignore | 17 ++ executor/Chart.lock | 6 + executor/Chart.yaml | 22 ++ .../accumulo-microservice-deployment.yaml | 19 ++ .../accumulo-microservice-service.yaml | 4 + executor/values.schema.json | 206 ++++++++++++++++++ executor/values.yaml | 67 ++++++ query-metrics/.gitignore | 5 + query-metrics/.helmignore | 17 ++ query-metrics/Chart.lock | 6 + query-metrics/Chart.yaml | 22 ++ .../templates/query-metrics-deployment.yaml | 19 ++ .../templates/query-metrics-service.yaml | 4 + query-metrics/values.schema.json | 206 ++++++++++++++++++ query-metrics/values.yaml | 67 ++++++ query/.gitignore | 5 + query/.helmignore | 17 ++ query/Chart.lock | 6 + query/Chart.yaml | 22 ++ query/templates/query-deployment.yaml | 19 ++ query/templates/query-service.yaml | 4 + query/values.schema.json | 206 ++++++++++++++++++ query/values.yaml | 67 ++++++ shared-functions.sh | 92 ++++++++ startLocalQMSTest.sh | 64 ++++++ startLocalTest.sh | 120 +--------- 47 files changed, 1718 insertions(+), 109 deletions(-) create mode 100644 datawave-qms-stack/.helmignore create mode 100644 datawave-qms-stack/.schema.yaml create mode 100644 datawave-qms-stack/Chart.lock create mode 100644 datawave-qms-stack/Chart.yaml create mode 100644 datawave-qms-stack/README.md create mode 100644 datawave-qms-stack/certificates/keystore.p12 create mode 100644 datawave-qms-stack/certificates/truststore.jks create mode 100644 datawave-qms-stack/templates/_helpers.tpl create mode 100644 datawave-qms-stack/templates/hdfs.yaml create mode 100644 datawave-qms-stack/templates/yarn.yaml create mode 100644 datawave-qms-stack/templates/zookeeper.yaml create mode 100644 datawave-qms-stack/values-testing.yaml create mode 100644 datawave-qms-stack/values.schema.json create mode 100644 datawave-qms-stack/values.yaml create mode 100644 datawave-qms-umbrella/.schema.yaml create mode 100644 datawave-qms-umbrella/Chart.lock create mode 100644 datawave-qms-umbrella/Chart.yaml create mode 100644 datawave-qms-umbrella/README.md create mode 100644 datawave-qms-umbrella/values.schema.json create mode 100644 datawave-qms-umbrella/values.yaml create mode 100644 executor/.gitignore create mode 100644 executor/.helmignore create mode 100644 executor/Chart.lock create mode 100644 executor/Chart.yaml create mode 100644 executor/templates/accumulo-microservice-deployment.yaml create mode 100644 executor/templates/accumulo-microservice-service.yaml create mode 100644 executor/values.schema.json create mode 100644 executor/values.yaml create mode 100644 query-metrics/.gitignore create mode 100644 query-metrics/.helmignore create mode 100644 query-metrics/Chart.lock create mode 100644 query-metrics/Chart.yaml create mode 100644 query-metrics/templates/query-metrics-deployment.yaml create mode 100644 query-metrics/templates/query-metrics-service.yaml create mode 100644 query-metrics/values.schema.json create mode 100644 query-metrics/values.yaml create mode 100644 query/.gitignore create mode 100644 query/.helmignore create mode 100644 query/Chart.lock create mode 100644 query/Chart.yaml create mode 100644 query/templates/query-deployment.yaml create mode 100644 query/templates/query-service.yaml create mode 100644 query/values.schema.json create mode 100644 query/values.yaml create mode 100644 shared-functions.sh create mode 100755 startLocalQMSTest.sh diff --git a/datawave-qms-stack/.helmignore b/datawave-qms-stack/.helmignore new file mode 100644 index 0000000..1c1043d --- /dev/null +++ b/datawave-qms-stack/.helmignore @@ -0,0 +1,19 @@ +########################################### +# Ignores All File or Path Related to Git # +########################################### + +.git + +##################################### +# Ignores All Development Resources # +##################################### + +development/ +setup.sh + +######################## +# Ignores All Archives # +######################## + +*.tar.gz +datawave-system-*.tgz diff --git a/datawave-qms-stack/.schema.yaml b/datawave-qms-stack/.schema.yaml new file mode 100644 index 0000000..546b749 --- /dev/null +++ b/datawave-qms-stack/.schema.yaml @@ -0,0 +1,13 @@ +# Required +input: + - values.yaml + +draft: 2020 +indent: 4 +output: values.schema.json + +schemaRoot: + id: https://code.nsa.org/datawave/schema + title: Helm Values Schema + description: Schema for DataWave Helm values + additionalProperties: true diff --git a/datawave-qms-stack/Chart.lock b/datawave-qms-stack/Chart.lock new file mode 100644 index 0000000..2e6bde4 --- /dev/null +++ b/datawave-qms-stack/Chart.lock @@ -0,0 +1,21 @@ +dependencies: +- name: dwv-ingest + repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts + version: 1.0.0 +- name: dwv-hadoop + repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts + version: 1.0.0 +- name: dwv-hadoop-config + repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts + version: 1.0.0 +- name: dwv-zookeeper + repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts + version: 1.0.0 +- name: dwv-accumulo + repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts + version: 1.0.0 +- name: datawave-qms-umbrella + repository: file://../datawave-qms-umbrella + version: 1.0.0-SNAPSHOT +digest: sha256:425b773c0ee3abf3d311df05c0213f9ba5af887792be8f8edaaf628c4ac3207a +generated: "2024-10-08T11:06:21.957957643Z" diff --git a/datawave-qms-stack/Chart.yaml b/datawave-qms-stack/Chart.yaml new file mode 100644 index 0000000..0c1b7a6 --- /dev/null +++ b/datawave-qms-stack/Chart.yaml @@ -0,0 +1,38 @@ +##################################### +# DataWave Helm Chart Configuration # +##################################### + +apiVersion: v2 +name: datawave-qms +type: application +version: 1.0.0-SNAPSHOT + +################################# +# Basic Metadata for this Chart # +################################# + +appVersion: 1.0.0 +description: Deploys an Entire DataWave Stack w/ Dependencies using Query Microservices +icon: https://code.nsa.gov/datawave/images/datawave-logo.png + +dependencies: + - name: dwv-ingest + repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts + version: 1.0.0 + - name: dwv-hadoop + repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts + version: 1.0.0 + condition: charts.hadoop.enabled + - name: dwv-hadoop-config + repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts + version: 1.0.0 + - name: dwv-zookeeper + repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts + version: 1.0.0 + condition: charts.zookeeper.enabled + - name: dwv-accumulo + repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts + version: 1.0.0 + - name: datawave-qms-umbrella + repository: file://../datawave-qms-umbrella + version: 1.0.0-SNAPSHOT diff --git a/datawave-qms-stack/README.md b/datawave-qms-stack/README.md new file mode 100644 index 0000000..19d864d --- /dev/null +++ b/datawave-qms-stack/README.md @@ -0,0 +1,3 @@ +# DataWave Web Helm Chart + +Manages All Helm Resources Required to Support a Deployment of DataWave Web diff --git a/datawave-qms-stack/certificates/keystore.p12 b/datawave-qms-stack/certificates/keystore.p12 new file mode 100644 index 0000000000000000000000000000000000000000..ee6ca90def7f6a8888e37560a8a0f1d0aed6a9d7 GIT binary patch literal 3586 zcmY+Gc{mh|7RG06Gxo`z7$!^E#}cw{5eg+nc2QZgj%HF~hHPWaUfI_X#!eU`TlOu> zhYVRVNyy$Px9@rGz2CimocEmPJ?A-pzRwSiVf{@5q=jQxyBQcIUtE82#0mrf^DwLp zbQso}KXxS?16KKG#gK;qU;bl>(f|Q}n&3YhAY6cf>E9n%fDCXpIxt{4$XXPeFGNEF z283ZiJCmnZ*UX@3M;e)>t(o!Q*dCiXCOpv+Fe&uDbcF=pUmVXUvqR~;bLh44WwT3N zTH??)wCp1lYFs>`OVpJl^@{eTuOF0MzGxCk+KNZ;!jxn&l71{qn;y@hx0A-HdI| zPiwMU0=>P-HNAGi-HckqO*Q6EpB6rDgkpX-XZco8TUm<(w)Ig`xiaB>_@d_3+X18V z^;NBr^aAkRj_rEijy;RpuwNmB#CC{S4k{LDoSHNu{iDF0P-gv(yKW8&&oy+TxQ-)E zVk*#*>#}<(#ez>g{?Z(s{^~r~a90KUe&lhZ)_ll=wU1!IC2SE*syt32Gu0&@huB;p zY^-b3(^zhXzJQ#uaY*SY`wYJ3OK*->Zu7?dE?Ez`Z%K1dU8!dT4>cG5yeeT!f4d-1 zaQOTIZ)=P^Zb;Pi>AZ*lW8_=JIhjbU!#eLN&W|S7iodjUtJ_9tFx@&*aTm}_r|8!L zYHk!hccn2Vre1b#`kdIZh_2d znzzmSOV`HJ-_~f<@0{ z8xOV~UCM9^M<`<~j~=n@x>u)1*SaO@Xn7@dwXO5~N<|W5y69E-Z#*antZhU4J@9ot z$z#{agPz{3+Df;E4MRgsl*xJF=u=u|X`gMY_hmD0eX%TDlo2n^&>pnw*od-vb|4z& z`FN>frZ3Ou`=b_(t72=Y;YjJ-C^?Zy{HB$;-A5h$b1kG>)^xB^H`#YHEch$6qj33) z@0y%*i&rqgY0E3}MboNbui7KZH>y3pYJTv4nj1v4pGgc&BYE(FOvlp~XGdsH$P>i*YLOlR(Z(yaF-^A1m zFJ-A5tJl{Q2Y5hs6T)L;PORw~q^9(segZ#OS3m(XteK4h3*VK@&7|hVq>)v&cMhMj zS@wqp%P0qu>Y0ajHUze>4rhM0G^QZnZTOby+_JX=hUqoDR~)f)Esik^tBPf1YNwvn z5#xDcs_rVnzjz;to08JoOR0KLQceJ(bYxkbu?!D!`9fF@dT(EOD5MMlnH3cpuD%$L z&v(*V*0$+jjaZOec-Zdm15W!2I-%wm6QYQoAUhjnfAc(N)p^$9 zeUG+Jsv=nHg)mBncAuXctM%Te3+|$uUPMQYkpV5dploKrle0P{VL61=?8^bcGp~}4 zI@QPL$GLGqhuk>86euNQn&(o;lEaqyJGu{nLaz<7GEhwB5Y{~&Cy|lJ@iL^@JjTcH z?LbqfSqp!x^6`#q;qF}Qg``I>7q7GUL#s{j`gk@_Ii}knS*?4L%SLG*wvFa^B4m4h zKz3fAqCQ#MAHpELPMZ+#yvUEZAuv^qTk=&tvjTI$!eJ!LzSdNb|C(#+iH#6Xen!=Y zYOHMBH|teyebv4Dk!`%IfPrPnBd$u$ybh9nWqxSr&u`K7JxO+H>}%)VPEX4A7mU^U zgwS0wbncWKK&_WiA%npH^bp^`?6s0F#4DVy)G=1!m#&r+_PLedlP$cS)ccH=f(b!R zUJ;t7$m3hpAG3y6fnvh&@-T-*K(E&&h{nw2y{1_gL3^QG=OuG-%Zi-+Z@V5H4v|FL zY#K><{B{UW1lX_1 z{!TGLiRBLPY&30gXYLsRu_Dc{JkE5E#q)G;6SEH7%i6y3ydOx66D@0}jbL?pF~Oe} zeny|rJ(@&M3L1TyCcw>sYlGcs;y7P-T;Y7#g?jbCWQMnV2_?8MvV>8$DF}|fl$n;P z_|xhl97F%;e*hs5L+?a~p||^EBmR^n1M`1yfeA>HhoSop$IyNKKZ>CJn26S@}wV;{%V(A6Qwi3Iqq3O+`E%s8;B#-vxDTF`V z|KiXyOb53qh~~9TANRW>g7E!+oVM1FxUP7QueR#q^g_QIO5k)~oaWf~(hS+kGN6I>5 zc2!!=AelWUy!Z!6kuA4n{67?HCx>4%ZRoh?-MeNFTA9j*2It_KGuhemUN1p~T(+VL8Z{@ubX{%nfM%}^)>8hM!&OK}iWM}U%;*bXcu71M zNA|xft?g*2r{aTDiEWao)HRl>J8|xKSD9cV3Z)M2nIdp_@Z|TziRfnURI9L|t9lh@ z%UyUbXGpzhi7E~@1KpfRFyb)~<77A7O`_haxB3=ytIFkh<*ed4>i#`OU0T9XfzaXB zP8Qi-=i-oidi0xiF-iM5ed1 zu|=j+?ROJ9?LZ(VH9CiEgqtI6_nnp zZr?D+>?Ps`um@=lT0REvbbh*v=@If<-QjoL9aW*%uwp zW8fpW|C>ml_S3$*{$=xFAnwAmiA6|ED8;M!hj#@s3blDbCKx3`YT!<~HfgT026{hc zquzS)Q+(~b@o>HTSth$X>C&)Rp+B3Yo#$9y;_ThnYV`cV(PcaAm(n;(p_eqaiF2wo zCx{i9?zarawCg?D5?91*zGk)dWpe719f#!J^1-N~C5H2$9z|V0Kn2=ll=PhdP+;4! zjR{N7_SBz88adwE=yai``L8PTYAzN!j|sH}d2uzwbsbCFTF)&gL_6`vYx`ocvc@HZ z*fERnvJi`E@I?vkt+rq%2)gG!@N?#pRQ? zmEs^`!_oJoqx3i1#f#hwbv$7PV5}4;dYsR`?sCmy(FKDI7jTf~o!*+CWyuXf-#Bly zm%4}yM}%4CH{!hrt@BE2`K7G+^dl2$`r^>19ek5J;rs@f;xy6bm01r3QIu8BApYbC z`FD)Qz)C+VAxibamZa_EFOT{$Obuj6#X{_c zo%h5@-+C0_Ro&Pd!mAOQIfT4n!2TjMQL@fASEI`Fh!TnUWJ+CYzp#N_V9ZwS z9X<6M>*0+OX->S|V`ezI_}Ao5A(GqKWa7At4<`{bDkiXHOCJ(&@maH#qxXg~vD0RpukyIP4vX{OC|4O@VSPsMat zYIvt1veS>q?dDlj9NqNqX4>5OtkylpOY^fCn(00&c=_9Kk^iP6Bey&c9aoX;6~mON z7D7t7`UWxK-ij;zPz+q^pCc}LC{zG&AAkb50DJ&`0PjDu3?T521^|NpR=7MI24`fT vmtv!(;im`Cab4~lW9rOFo>w>i__AU{n~g30t2P~&$dKIL{Z)wd?@0X@5C_Jbc0fhE`hb^PU$Y`Zs`^f>5`W2Mvzdt8ziJlL>lQXK@j*Cpj-Cd z?>YNF=X%fizU$+<@NusBtTiVv#y#$Fk1?OCovR%P2nZ;Gk7u z;IN>il|WQLikkrJOg(k?P2oGAW++#c1bE3`-E`*BJ{Ew9CnEsp||`cCKjVM2mu$V-h+-cAi* z>%=}cXhF4^rfXzEMzYVZz!gYc{obFU%(eubnTg-haL{}_85V>hdHKL^|8}>h41_NWfAwpEufjmE)Hl0TXYmm3ZkqloZcgJ7Z;3d z@u&XKdF01P|FP=mNgDSXJcIab`!TzC9N8Kf$K8k8U0VD?SH;fyJOoCA5VO+=QHGT( z47(C+w$QCrCif234-IiYdRy-B?VOMR^GcM7^0tgM_?>fdTs*91!hhjCC`H1ww-__pJ=KZbp2dP-N zWmd>+2-ZbL4m&f=+udrbK!E+^C-gQfRmdtmC?FLK z4QxW$*OilIZ{Putyb^x8i1et%W0*|j@sqHN6}n0*Lc;pk1+15(tI6#jyM&D^iDNww zD0}StgGAK=#xiIP$@~-(An+4hpC!KTeW7nPZ{;cV)lQ~8y_V>7n6(?N|KiOxbaRPa z)HKp;k9C4xveyG%JiOiQwd_6{Qz>o;~sy`x=GD!67b1_raHt zCy8&fBpd9N4qLumQ)jWitF3kop5@N9PGOCj!PWt`)NJ8>4XUvp&idqvGcNq;@CcNo zlQN5IEwBkkekPVpwiEMhHhGmUs4P+Cfb7&#ba^Slg(x|^6E2*+2Ky*Y#iAyHcOut1 z#;2y_Ta&Rzd#^cH=Ihh}*1+hfb7RG{tE;WN6X&^*Q-@oO2br5#S((^?LEXr}*u)xq zwJ~-uaWpY-FfzBWadfh9a=t-($6Ne2Ug>O(B5sOFS=js5VpUVTl>jRX2ZU7*8ZwI${&iEV0L4rX3n@@qp;`pz8 z%1vkx5dz%&B)5?O1dbu>AQo0Gw%bT>GX(t{{$IOqU&z0Q4al3Y0SOKpkdP3C$`H$p z`QIYW^`{u(_|G2GsmKk~`5VNl%SZBseib=#4hdKM+QBjUDp=NyxCV1piUqkUW_7dl0Aj+z^vv2=izh z9HT{&-;Brx_}3LWMPdtf&&(AI8Cz98Oo1}8rZA3tQck%!sN;le#H<}2v~mZVJ|RG# zz`r9Q(k)c}#L3^VnjbBEiDe)~o{o@9yE26ZL%u6S2^7D%mly_YX_>r0SYK#HGl$!Y zi8Bz+7lzTq`0i@!UI%8zC1yn zhCI|s#RH}znV@;Pk8v*``-|D#Te2P9Pb1r^lC!YOBUv&~_Q+;TJ^Y(Q@!-MpC(1 zLHTwC5Xo&E1=B^`d$0avi$VaGTSNfA83^LMVU}#b8*a#aZ}{K;;D2Iz?af=%`=mKX z7F4P))4Eh~qqQ&hNL!S>-5Exs!;C=t+Z6j9d7}<5(5;U-YF1WXxNU}2`G%HCR2M_c zm^g3K$?CNQod8VeeG0_+L&)QRxKUo~YVZ5~j0G-uUv0ZE;7z zqYxPWaO^>ZxtUH2Zvwt@1Fd0KpRPk&cl`JlhRjM53+V05C4~cI-u>buWrlsilN~EA zE=O0}K2!v%KP&4Q#KL63s)KS6Uo)N6+(iFn4|=;uli6%+N@q0|>{wa9tU8 zY`sq<8GCiAT?Lp%>bE3B$(1Wyj*! zD>(Fwj8a&z_Zg@xm0yH}F}K@n^N~Vu^=6qbDfltI=cYem&n#y8YHQH0_<)N)RJpFf zYxgp`Gfm4>QhO^NcTzPRce)G zSwwvY!+~h{$-I`HB+H%7hpR<07@S?Upd}m09sw6`DrhR&1@>>>0LsgFcC2`5M&`tp z+a0ojwOBwV9WfMfkqLsg8mM*J;cyZqPCIP}FOP3Evf-*l&sOhdL~3{}q-@+4Jobt}bCLzC8)v*!jvL?Fv!H`fOi zc_BY4?4p8PBFD%Yga?}(kpNV5!zp}r#1vKoK`w=O@ijvzuP-9-3lk+r(y#QNIFQyo z+-W}n9dJnmM^QMd;Fb&?pIKlVb6w=r*4qhoQxmpyK2<(9G8sN1M8!R^3{;oJAODIH zk(Z_wJ>x>5An<|i;&V-E)#U2%=kF(G-G{VikPoO7Myt)JfFEUJr>gR`TFk`}{Ho>gnY$!Q=W90E9JALN69h6ak?qjVy2AVT1yTfD`>vQPo9BmyRn z2H+f>@v)4PF(c>^5dUTt8VkeaW)>hSBJvA$Z%G&@kb?yTddkTfEd;LWGW-?13wdr$VlmRI$PhL<0z49Lu$w zkA_m^e2-hs45$LECIhq_>_#uY7*@_Jhc=ZxQ8yHR(0%Tug}!zrc-cDDLC?HqmtT_) zP$ly4){%}hlQ}^DOZt|`HPAd&9(Gz@v{*v%&f`Va7m}gB`}|+?xqH8PXmbdl2^3H* zZT9Iw_wq)qq=IFNMThNnhbQG%wKy!n6s0kqBf*D_RNV}4=~W)=87GwEMwSpzAc&2z z59v>n>H4##1$s>B$JA2+0p~^0uk7qFIQ5N@3?D?RLwuLLU^Sn9P(liaA3Jz!IcO%< zjuvJ%cXq>I_A5GD{t=y_6Ty)=7HmE*?o0;}bn?{@*-Cw9a_T-DA%XJ%vwJopDF?y= zV%%5-5*DI~wK8}OfP%Cnh!RMCXGnx5vd+fl4h8@f6C-mQTPs^L3lm3xjD@v@lZo*! zdxOTp`uW})UJn2hdj^2`9kJ&GGK0f7CkqgG6UMEh>M_y{8>X*z)3hd7 zV}=QcJJ!-`jaj^mo|{(=FxoqRN&$S3rERP>*MD_Nn*5Ya^T?%XY9RSK=Bad^23%GQ zEA1>UtFzppPi1$!T**TmC8;Z3J7>Frcl1R#$t=8YD?;B6h+Lj*+FkDqVerHb$}!`P zkqgqfR=nedd~CIo^f>ghoJC^!X{6A5=H~{JD0&^|*@CZ$wDDH$_}SL7YuXK$igGz+ zs<_x}H=!-gxmC;qtS1kdL{y2RQBbEQp5?}mVDUbFuCUJidKB;J3fm(=LjLf_J6!X^ z3w}aQ^Em_Uf%+2W%N9r~5TRdPEJ#t@?s{cwYQJ_Fd^8{g(s|u&LcLY>n%~u#+H9d%m0u0fba9@OF@~0jQy)L$r=x-+zu;A&c#$n1~`(RE-sP>L)FMOD-10UG~ z;wj-k=tHNuW;D!&;kQ`=P^@KkgK7Aa2+$A2cJ&utR(DFmD0uc5`sgC*sqi zJL_AzFw0rUE>V6t(Sx=j!`OykAP)`Y(pPv#pDPvBl2}p2dviC;0#NU|3@?zt#tPvBXdC zXFN%PqIvVh{dyv&aJLCMa|rVp(O-R8;+`)H%Yq&P@$TFfUD4V0>CJk7xGFJ_@DBWO z{+RmZtSkU=mfHYulXNpP1DV-bZnALJ`$OQrZ>4`C;T0cI(aj<@u@l}f(;+@(_cE91 zuCV1M$Bw>!=#|%3yj$Ut=Drb1P-F@Ea*m`d^R6rJksI$Tnd{Ij$5ptBsB%~~oqeVm2GHccLXYg>BoJ6ebwNeN zm_m`3iO+>5OL^C+Mpk7rwNA2_O~34XQwj5AOZ;M0z3vow--Eua)sD79(2#*g!eWM; zS7OWKfm@;VbOA7N$lC!rIA2Sw)WPiq0yL>fY0V;GUKw3BXwDSowAE?de(su2qd%Ss zGc+Jh?NO1XGtv`23>sb!gPNsCGx?QmUKxFF3pGw+NUdrl0;bApaH)KHv>E7HmR^91_4K z>Ci_3>OQ4@{fo2Q@^Dsz&rho`gH&Z_bJ##)4Y}|Rjd})#>vQPUI6+$%LM&z^dd&g-mhaHp^Ef6KP$rbB#>FFpgX^Hj>=*LcxZ z-`j&DXwc^{X;(a2vrqUnkamA?&)jIZ3h)ZYAo*orVr6f;%SC@Z5Vt?a;DZy^isfDo z&L;E~R;cmUv9{55{|m_xbXhmkt+$uQ;UHo=?2?%|Gb|Y&9D~N1&(W^-4}J6-_SN&M zQjtz0$yBLZr6H|(l2FEpQjE-)hIdi=OdDh6^GkMq>>3rT37Ak0l?O%+BV5DNya|CnjJ|r(0U4}?IV@DzvJg3JGT?k>4BW5Z$KmTtl`)!Jttw_W$gz5+yD%JXSH4?*{0Jeckjh>8=0e($d);d1_!7`I^jp*p7&ZKRw>EGQK z_0z^mVDOJ$Z0W{CDoc^ko=MR2%LW!}d3}US($Jq$H;D^>GIHwmlG@9&)cXWprkX$1 zUL^@e`cnOS;_)312Xk;|2a~&+nvucZpcuLp48x6JGL?G=#pv))$#U1nUxmmXWA*Hx zZRXv#tQ%=n>K+WMDuVz(;yW0|Q@&m3hHZms5x7=n>u_7P`vug{Sm<|m0DhLtM1*dD z7%YW?c{qrRm6@3n48+V_AZ8X22&|0)*){*IYyA^3ddJ2%Rcxhd0cXF0Wlm8cKh;kv zes-YG84?1$(X^>6ru<+=`$Tj7RFn>C3uN$#mPKZ;`voG$OSF3C#6_ZncahyQy`1q! zUmpEX+%f+!Y?J$fVx&~KCtksbapB7OD)Eh;BxBq%7mINOajss}s2Okh=PRK))i)0! z9AJqHIuTqh!7)q0-Qem+6NBgO_}MhI{z){GJ1p{ z=$WgljN&@wUP^+3q=*Z>hyS8y`Q0=17;OFMa{rlNxn{0c+()avAv%y86-5-eIH<4L zG^L*C%Bh_@50Xd>njZ5CQoT;JBG{!6L&mF6%KMTR9X-S`X1hj>z%BQXg!_%UHr|k% zKk!ogx|2pBE$l(UW{z98()n(Byu9^)z?br5d z??@!Hl*9Gja(`|jnho*j9WsilF{?!F>$-zV1=>S-a*}DQVv;9|v*gbewYqU{-JAwo zNO7=rv^8~daJDDeTapF_ z0}v-OGaHzx-H|j7@DQ9|F|%m?Z*AkB7+jxLb1X|3ZCo@iVqBBBVOz*i68pSZRBztS z^Jli=(dK8=W(q7sS@{7msS<*|%IJ+P-8|+|)xHcX$0o!5)(`vRzIzl) z#g?GXNsAB#!N10e^7b=k~MFHdRjbzOU0x zs#HIBw&L^l51t7%hem;(-tswV%QJE-=vLUKxb6W*9#e1Q~1sRJzax%Gzu7{zF&{JBm zPkcmz+Ce91YeIBY!X)jTQdGTGHol1(W`=p)IF4m(rv+K!G0Vcvcf|-HgIMBW{2ssNS#k}&?K5c%MvhF4&@UF4$dc4*!?P@7r*1zX~&2UiO5-dJ(+-0i{@}pv*G6i?}JJ7-6egR9_Vok5>)Em@ z4qvTx2VyQ}n?-=lyzzl@(xQ|zAT18<>*Ngdfd>A%cu2XLW^8rg6dpaEzl z9A(!QkE5ew7UyMhI9z12GR~}tiN?;iFOEftu&jqpHCD)|9q0p()Ea<06tXj(PaAS7 z&RE?-+7=F>3{LZZpfwQUA(aY!e$hmobIHg(5))hINJJ6(P74rHQe$T7cEbH3Kc3}E z`E`$28AkMnB(KQcNmCF&2t9}ad9v*tYhs_V-vyT1NZUTIdstrEWgKayeOru~J?3U) zFrvjn<0SH@7sYgpcFm@p$o_jPp+_;0XV0Qy%%scBbE*s@Hw41md34d%!fHRf*yFf# zTI!K!aafGyvTnkB*NiM@_kzGSyn;E#@d>W=`tj*PoOfir4rlIh(HtT$C}v6)!roAn zTAEwfU(3s+#*9^oAr;s1ZNZdBj--11rqodVLpfqv070Ld<(ECkNVCD5E)LZ=_oI!zwGpHNk?9m<6BRr-})xzC@ zjk~9_LIJ)0jPIyGzXCsa)Ayhstkd2iKRZ}FyOGb>z)%lP&q4Qw|K~UOALzPo zF~y@22`=_J1mXPvatA=)Y`Brb*MSCy-$>2-AUeA@MIclHXD&(RA!>yTwP);bndeB7 z#{0YAdk{zraN!mCJhkDKm)SVO<_9u9GonaUKV;Oj(}de;-p_j9H~fG$#|UU}uPsNb zPj_W*)aUI$0fVt(^=F5agjM;!>$)U2#ETpT{5SH({+I9gbDkM^-xThIUl7ErRlyLB zt&It+&wb;T6i4s*g2dDxZI{j4UOcV0v+U;VUoQ)jM>{<*b3yeRCRU7u0`h$$r=gPh zpdS=Nl~T?|Tt9irJ3=^kPRX19$OlL32oud}*W^`iP{DWj1;gYp?K|NJ#nIis)WYFT z_+|c^^+LOVNs0s5dNuE?7n}c;4*a(2DDy@`F|;zr)g_BnaB^))zZ#rcTJFK_QMxrcpLhJ2DG0+^zd>jj!+@vT;B8&vauxvHV*%7!nk z>gx-q!`w^QX$R)^(z#z8$&wQ!v9M+`o)jVpjO#28`DZLWY}b1=2_Rl}toc`>F6a+Y z_jh#po2dI-U5~Nk@k8ll4tO?JESjqLag&(8{DS{IQY+|BqArMond7dicPr}t9R3?u z`lpm2vsnQ>V&l+Cuo5OUpbpeG!|)ZO5QdjPwQWruNJLTDu@^8G_IR<4Z{BxRzC=98 zYFkUPO=_YcayzKl%Qrc2n-4lk338Mzy?AsZL4d(0X4NXJZL$XGr;Vezq@DwD-{+$aVX}b>~-Z2 z^0A?bPHM@8blwz%oKPJ)(uE&fZ1x1mI!RP~z60s4Vq(|dhfoBUbIc4*VtBbX7vCArYRW7`$KOlp5! zn6{IsCLmwuUV%j;XG$)(WMepO(Fz$~`ms}ybrbpRHED!Kq?GnogXA}(8+6aZ75TVv zcC$4i3bp6DzDJR*1dH0wMkiUhXYlbQzR>;FjBB2$TZ%;fLlf;SnF~X27CO<_u_xqF z!5JUuRzIC2SEv&+0YeZ7RI;lQ$+r<)3FCAOMm~n5>SaqsC-0HImBd9TXfmJy^*WUV zeEZy07CN$m&Md1J3gG6IBw-2AK>70VfwPE(- z-$J9Dgvle_Z1lw<(F|TZW8PgzyVU-_ILoc5i+`@={Da@UThFz-Z+=Lx1G7_5XPo(M z?Xyo4I5=X7bgo4 zgMOozpBP=k;tA=<%`F4eT) z5JX;W^N;n#wzwctq7-^S5f%>f=pnWGaPt{2w!C4GYm)7pqWwUIKipO90Oc$2mOGo9 zECDo&VASD^U8hgOpk=;*TWIP_u6VMgJOxVe*r-X9-U`MY`mV$IN)i~kbFlUB*!2+z zU)D^;ipkdG`xm}#(rw-2iqj5V zG}#Zaj^8aj=r*9UI$cOBZ3vX2v1Qz?bQ_3b>8NlyKiRiRgN!;)kNTGCFeE9Q54A+eITygppz9c=q$Aup$S1w{{h>e6M7Bb|(1j3oN7H1lW{#05ly?&> zH;;JgHUyQ-Nw8u|0l61G{ClLGP^v8BF$1YB?TopKcV^HPB(v5!7UmX3y4>3@EE>Cc z0_4(h>MC*MJL25cKlNH|Sk)cT8tGO(-e=(3(KJ~o)Dmo$Nb<2xCxN5m#jFfPOUb6# z&kvt;Uy!agjyH<)ZDfMPpX5qys(*VQgS*Z1Tq$2_rC*2Gb{N13L#> zQxnIVWWdVE!qk8rT;pN|vUC28P{H8?ec`adr0U1dbU=BVXZNC9Lhrua-AKOoNtCEE z2;3ch$LhJjM;z|90WdcCefr^MBLK0#>;xbpDFzVwwU=AvmkS71d4ZfPV3rT&_$*Hqf!*Lbojeo7APE-t$kn`WzYzBN0f`VP=b2Pp1A$v9NQ0>gQWL0hu0?` zhLz5`1%B2mvtxeKk+EaJAzedOG&?wc0KVqnsRIF}Rg4pMOpaq2>f0c6at%EI>_hP# z^N81&eL6oT>C0d90)`g#-T|63UA$aYwjTu=u<);WR0?FGMP%1Kv#krFvK6ul&R4j6 zW`uMSgG=x*vV12cr8nvX5_$e19~wU=c`s8W@(9!wf$F5(a5(Qf`P`$ccXVU0X>JHv zAJssWsXbBUX2k@a+vN{m7@DF7~0^Or?(`DAa?bXTcgd79Ja zti7t8#%RD}NJ_(^5IgN!n#zdq>W*}>)+}FlI4RzxKrdm!p1x*C7PA*`7M^c_{BrCy zMiU9r&>HK7%CA)Fvq`uR=|Z5geRbS$nL+awWkU1_i<@Yw^?9U_8830Haj6GV*ZOD3 zV6I0AfyP1;JVD4d=V%|AB(Ph!WXIEmsw3lxjN)TH$H6@ZnWuBW@py-b8gP+!6FkYm zSs^@o4Q%)+fbRi)wr^WG?@luy0O7!=8K58`|Dx}}-OI#G2DXaWh#~l2PB^s^RyvBK zJ~Czk`sCkaUH}-Mbf8ZP&?gZN20Q|Hrbhyq;1Iy-IxH+a6eR918Qj&?mGQ66d#i;T z**OBW|9ArwP=QzuLIJ`6!V$s*!WIGmVGOv+`hsJ!EyV# z0fYmD5%^B4pLc*a0>KIX20?KA#o2Fz44!A^_sZF>uB{SjimEKAqS?G)sd6+`X?nFV zo)ysSRVVYonwD`qJ2U=v9<%GGPpP=$On|HKu(rvdBs7OMgvm z^6ml`r<2j%f2HdBJXgHQn7QE_rGGZH@Co33I~F>|06I>+a1`C>lf`(dEszA}CEau{ z+>jG-q4Y!$&38A}*Zho6*1tu{N3sb}R&dQ2(M4GT^g5L=werX@| zi_15ClTL}Yfy5GRf~eW?Sp{?UU56Yh36(C&Ohx$igpb|as5}Mik(JzujHGG!$n_`^ zrI5sxqW=fsciu2V!!L~`zaGwKZgfP$7N3QP%@{W80m?c(j|d6Ej#DH^_3M;MyE`N?_2p={3i$(pd|lA5LGOj0AC zAI+wBOn8@!Nt>NdE$0srQ294#R`K%U3o^Km#ItzfgnFiRV~?_@G0Jiq$$P&x2VK|2 zR-fqrq{j8un#?^+4snP_xeFOKrYtFn6V#uGmuTQ0keb-d4YKMN2p$~q=62AKhh0&# zhzMrl@osJMym!dYsgsh{#g#ZNZ|n(s-IbP6?7-g0>dk6d82Y-k7H?;{tn8yk7dmx#P+akoJR^R6uOyBF(^lNi>2C`!=w;P7D$&dF8pLI~JR z{@i#DRKJ&iODTZB<)7OG9E(iKz|O$tchI;w^8rvcad5FPGI4wiK8In%c(3K^u5x(W zvUStRAtH2lmIBBHWCd~pS=rcGIlv)=`Tp>KaOHnW$1h#q<`G80@_dv@VF}g57R_CY z!X24c8zn{0#k-s@o+Nqm^~;OX?fF{h=~(qk9fucT0(y{UPB`()P`p83N%y% z2oODn`oLXfSPpLCX~|t3_XZ{&p;X627LHG`AHM(bs_$_Y4oe(px|QH?*Dxv2NT6jl zhR(0Rr4EavW>8KzAd+m2@zG)2gL2raCvvV?fTqGjIYdu|k`q`IQF$@@OB#OV3z#W} zPbNfC1m{CM??K6IHa($mV-V4Yu?QwIWvp-z?jcM2-Ow6C6O-$2m@8Hj1p~VVs4+wP zJqBwqcn$U8$@%F8ZDPG2SXWory4tcKC|p1Vb@7M%CcwX|f?8*?^5uDf4~g|JDTYXJfi8_hn{r;+itPc}hZ>3U^MlQ%BatNi`)Wzn$adHYY}!733NT zkC0rR+w~5OIT7iFDQ$I%C#904NRbR9y^XuwJ6zOdD60$MRs1y3Db=2Jp4qj^xtJKn{N(IcwyhX%P=aTF|7VvEj+~u}7)T%jfE|<=8344(0sW z+V|XZhXj9Rl)PbPd_@-xY%8>_Z9VTWXA!@SfW&K=bOw~Ku6{9cRq^nlG*~HN55tA1 zB?WiqR>_}m&18{H)VE02L$-Hj*Se%+|I;30?u#C|i@{P!>TAE>bdDH9pqeu&!- zq>gZ<__c>zi|5Q>QHbEHXK*hxL$SXs+3R=Ki^gGuL~O#%pVHwH=GJv}F)u(b5c}eD zhJF&ALVRYk3gLPIrRYgEg=mwkryuSP={ z)I3u&&lweF!@H`M`TW$mJ^Sk9nawu{d73YC=7CmEVyerGF0nB!TS!JXK`Ep!M_734 zB~E7D<|}HiF%L+SrQ2Qw+FMAOnp#D^ z1iA7$XQ@1*tsmovq*|D_Q}r~{FlV?2v>hpd^C6J;JhF6l+Nfv?SH3+0L;B?q()x9k zE8}swhtz@$CMB|6I5chMqB6xc*5}=aE$9_eVFDpJ28wgVLGZE1M)uo`OSW2xK8qpR ztZr5=dpuEwZmVB%lbNWxhS3*M=RTuH;9k_67MymkK*1+QvLnQ;Epf!7usf$;pgNQh zr8Gi+mxP`2nT4&Sn-tn8hIENTM4OtQXu>36W1_*c8cl2~cwp>mBhFDjSgfIIp62B+ z8PWwOM9Z(iKTCB&(Tnj$Ge<^{L@X<*>J7J|O(0LYr^6de*ykEM{EE+Ukf0;OhnZl@ z`8}ivr5#~0e|*?nP{4X265~|S=d>0<0*NpT9M`gEuY|8}0|K=rYJ7PT^F8%nW#`cP z_SZN0!4PEoK?`L~!X6N`SML|R2;>nfke~~maY=S*A$gX^_b_sc^T>FvhaLry=KA!@ z5{~dV*)X-vqT3bznq6>--0J60?hmuniZ<7c#wRQy^1ox+f5GS7Dm7L;s#m^3I(j1n z_dHVnwvl3UpCH{z%;2^bRTA~W#_|G%VdS!@M-~8TT7+T)XYE%uXTB>IOcURpO4rpo zqHBziCcIpevA-xE)i2>HK-$D3eHw6}fU2=IxS+97-;1*sm=@{p{q5^Ubkq!9iXnmM zzG>X(3)}Who;{MGkCUa;2Zir@N-sTMCZChRY+Zl$+Ki?rE5k#LJbcBfr9SlovR9?9 zma6|%FiVIGgFmnD{BFD&Z2jYg)6SZ1IUe6;P!E}-;B#L?@+&srpwO`VgMw#VzAx zo#yWJKGw^-xGtuFVr>58(Xedq5rsPj5AL&i!2vHEHr5%RI+0XGw-EQpTcT8k3x2R) zJXa}>zP|RNWRykObA?FOdLpZ=TiAA0keW?9ho%NTd@YF8TJQgcHT2bEoD>(` zYj)DemzozQXkf5-LD1>5?pBc>;PF3r&51_{(4@n_4dtn@x;AZxq-@}c%xitoyNV!I z%N`I+dud2EJ%>+yi^$l<7G_}b>)>?n`4b`y5h&Kj*4)8ytHX;`C6Yz33Ppr7%+P|9gkg(8iGSOcvNRv|kQ$u+7sJ8u_r zFkTDt0iYi;=8YV%M)_2v(*i;*Z7G~=HV94-!so%@Ac0@Y`~Z)=*wUnFH*AFqHEyIw zI&qxmZjD3^!t~@jcVsR&6E7(pl199_-vLK3)w}U>oCgYtg1Nw;b-Ck0A+<7u5(cPa}`-o%u{OgsTfw5v)tn zWZO-HU}jItaSvq><=_i;r1*5JymF#C-cjGd*G&QW&+zr1wy8kRDX={qk!dj9&sicM z=twB%8&L(`FDU=Z8~z1n|Cq}0RsstX@qG44s=U(sK|*ZQ{A1`5^0Mts+R3Cvj${>lVZZ6?Ustr2%BRHuZUfKBleJWeLb=|xd~x;l2{A#Me@Q^xg9HAyQ2Qv3;+lIOgSxxFplY`w$5 z-k1t$tK+mgsoH z4g--GAAaApZ&=s;+*(cs^s5sO8AthMC9o#z0Fe8=)-P@kjSTpg^S^sDZao@Y;bsOu zvj*IY%gl9?TZ8*CZihf{pYH$Q%KyZ}mb+hue5a7+9%b=kdu*{i^B{Lwv4E1^trmfA zA-di_;6p%e-)b+Ta&9jL@ujM%z0TtG<>hY=* z3Ri(8xkg^vLEj=)sb8Dny@rB*JTqzPv@>gV-DVJOB#)M2jR&OKD;gz1&-~uyg=^sh zExto+9`2AOTTb<%-b&AU^4&-oRzzXRk*~0S49)rT523^a{Eup5kmFLqkP5J#mO>C#t$U@2JahLTVKi z!KT?eM!q%H+Wfp&m`2?+Pt4j5>J$2RX_X&3fl@(3UVWm)7@Ac8#c-xz@dU2cq54)~ zNWmltQY6baqnGg$Bh6xIk_$-rnPhUD!)?64M!U$z&i%t(VTwF_u?WUg2A*{tCXv{w zq{DA7@f@Hdn^MA7b(PcW()N5C78{owgtSOw$3!_|N9G@J>8z2zO(yEIEFYQhq_x63md^i%C;b?@;`@OomJ`%Je)3ywML=-vAC;GkACy8zljBZMz;F`?Nt#(RAM^CkHY>(uP&%-TYxqN zJb!VfTitWW^|8&L?MkmeOZKn`Nx` z5bLxQ4*gp3LyD{_rF={hI;67m0oGu5zL3ypOK_f-=#S#syebxC-_8s8Z_idJ{q^Ab z+5)*SzNinl@;q*rLDNlM-Y?=eAW)!aZ#_PExQ{_wore#V^2tcXE=)WJT12}}M=TS? z_F5yNc{anLLyLYsOlxojS$d7l@XD;zm zj%Gm@vR>M|7JZKB7q1F0)0@~iB_)H7QL*ewUseIGs24c=5Z(^&EoqeWVNqP-YbZ4s4>ZJSW)Gi1J(l-yjkw&-Aj)f`BR9t0EEqr&4GDhCtMl(J!O!ucQa^*5wX#sVE^e$TMG#etSu( z_KCU?M@=SItZl)M7+FS^L>}(p()WU6Zr`kOHxakV5?gobDCpcxiXef{O`kUo^%Nut zceg(=-r_XI9sl~Jdz!Ga|BZy*99)J%0!u8>cj%0XG1^eiVl&>jN@3oG;!l*gF7hXl zMeH626BhkNwh*z z*7*-4l~mNSp_=t{C0A$G^E|OPCCm?*E8z>N`(hiAM-kDxr$gQ+AlqR*fQ*>h6yIzv z_og5CL4)$8xG^`7W5*5w!g(_W$%9cTmE4>hPGtKvld}Jp3vq1tb-h?KonChzUckSQ zRQ^+b0z!<6tp1QT`b65hDtncr3{#%qUq~t-h^vBG2RQK_ol@ ztzJ3CGfl^jT_M0%u!c0kW}FfS?uOdk8qQ;IfOjypFtIXr{HbH#wzB=vp82~GpTX>x zYq?fOGl8c_7!{jB2ib#qZB)=)!_qx19E<^u2~Uzp0}a9bBv?Xoh~qd?cP z%!_Z8S%y=7P8swW5fx*Ow+otsLX{K=sJ3!!Fy1r}D()RunGa&>CM&1v&(KgY&-l?y z$JD7x=q#v@7XYQo73u~1-wL>?dJyw(AwL1>IfJunt))^AF{1tc7I49jB$8&&_jk3J z<$0K4Mvh>MYS4S>KchFr?lUk&AjFWNKimDt{PT!S;9@ZO5Z0W?&=P9}Od1L8M9Z0O z&qQ0(?rU3Sr^9GprY2uu_Y%4qfTwJuyDDZo&Sul;vp7a8r;H)O%EKG$o`*!if<3l(aHB1@%aKMnZNCZ!NwMpJ*67#J8i8CY33 z-kj4hv2ptOxXWAY_>~yg{*nK~wty3Z1~63Q+`$Bb8X`u5aOd)0n}vXu_rO9@1@yCx z8y*=})&iV+fXIQQw?aSiBcZ$1!ELX0;Ko-bAPWl{C%7?#i=6{R4Wzuq1Z3i0H-S4o z?(Oj>F5Kk{ARrewNw_^!edGUN(f^O(|L$h~DTR3Rp)-#*_wn8ee%E`299u=63`EV| zb_q_zcEU`2ujs0vIzfS1B6AW1zX=B7;LNkgr;*l4P_LtKC-e}kLOv}PHv-zr7W@=n zS;#`fYuYlkK6#mg`Zan$eRt-fn^;tQmbwlBG9#aq=tPKtN#>HKWZ_i_S>;och(MLd z7!lezF0to1K=S&5eNQa4R-I8lO9`3Iq6}|ME$*h?H)I0d)GS)4HLs9$;5iUJT8+Ak zlRaVU>hEWan5EmP@iaxzGf*T`C0G_)UgjHSGfe*S4!cJyt3QNb5lHnTGlj(GjW`L+ zRu0!|xQwK+ma$EFh17>v@j=AACf{=KDf|M_*HrimxLqjZeMq~O(V)&^V#NUsSL3K- z=5@23?*6{Z$|`QNUs6X8;Zqo^8~JwvtoJA}4ig>;8=OidtcRAN!=Ib@lxK4do$_Ae zUwk;w4AoeID)x9iEQc+xA^HtjmqzdXx`61=(7P1d3;!`!%{bfQSpW3h##X6FshG1T zq)Q-C0|hzssb#hoG7l@~U|VwFGJ2{8zLI>xgF|tTb5cbyfAj;Lz|c6&dLb^eBNko_ z1$(s#_M$dpbv|_I!`jREZ^~WXtO_*h`B5fY>ev4(I z&+uh(vo4Or00vH7E3J0rdhjVfduff~C9&b0-E(w839aeIT+Vv49aVl^wfS*qK^dRi zQF)^`4}>3J|9~iL_jZ(LY!&>B;UTf<4%IrgMFUBt?$p-mNM;=qcgf}1K)3wOclmLG zo*YSZ?D^H>oGF(_wX)@$@+s#;68dgbOGlT5!^!J*k&^C{D@}-~Ul@+UTeg;SJwJBG z*{@IMyy$8_b9xO!5Llc`rYu-pd?n*DbP>zk%9i0GV6zfslbKJIUHiCsgg)T%jd@Q! zBz>8c6H%>W+}dtUH|0Kr3`F_MYNSxYqgI7<%DM%FId;=)j=Yfu730Uf)K${2Uz%Kx zF)Y@}HG1U=kwyu*=5vv3rY~mBERg``mV}Qp(6E`t*HvvDaM%vcM0Q`Wu zUtN5NSX?U34we>fCIDdzD+_B!6Dxp=378;S-aG;4nS~`l$iV>oR8DYTAwc?OSI*$i zP*D|@R1uN}fsgav#0MlS3Tf~Ua?`%?^CxfvH*?6EI9QsvTih&pJ1GmU0N)$~zBvl| z^8?WS3f72GNK#}MfA|Kbn*PrUS< zGmzzNgXLJ#V@wYJ&*2^k-eWdv*C`5d{84dFg+D!fLFNDdk@pr*Rqfr{INd27(o)jh zN_Tg6cbC##(%lULQj$_i2}+|hlF}fJ)VBaVay;j~=icvo?;Za;{^JbrthLwLYq9tG zJ#)@y&iTy9*zceZxsVr)IO-$btc9F~lf9(NJ7Qmc8ioDH-QSsz``W6wt6Sx?b~{Wc z@1>R0#lxYQU9*L&}|n4&5clC>mt1}zCJU`I$w9`xv_K6g|x@(J*WTZU~!`Itpbu>j)Q zD%Q(d?3=aRK=a-ksd7Y;U3;T(9A1Z|<`rVH zcHpQf%1Pvn@$_mZR+I|f-iKF8kdGTDDL@SS7Kg;Agj6~4US?*Wkx6C4=xpP42BwLC z!-4l`6{FxqeiYU>YtonTCa2}+$S^kKwBA_Iu+9yscm3FM;&jo zNOW?MbCzyF3Q^x$9|$Y&98s1ZB*-r?0zC!@kbU6C?GB94pscb!cQm6&Q3e3Mc;7;)Pm1 zw5yg#|7kPBD?0M=po#K3nkC8-J2+9KJ$Cg6*R(0|lrq$^tkTRHK>5gqGl&d#Cs+J~ znD=TT8N_G~MIq^7%Tf~4iDPBqmX_iV6q(CEFSn9iyoPfbD|mzQ*JtCWz|*~FqX~E} z>VO~3U(d$4QxcoW6K?p_$+b)u@O_DUcMtY|{{`NuIkDb*7;X!W{vFQ-GlM!%;`E1r z-<=X6I4Cr@00;zCQc*X*cROO*8YrGh_r5|w6K(Z_wGq0{-`{sllv)!y`f_t8TXH^Q zF6fd8it@oSGZ0pNE~NIbhJD2pX47QuzxwsRtegG}mC0Vl5Ck1#*OT6fQ{~ov{{sXU z2VoEaBL?{r7@LPxA9?l|svxcmH`z?z;rl|)&^f-FUZG%0S3@UoNIKZ=xA^p$#IwzA z>eD)!E3RmC%+C>qWMcU949~~SxNpB-v_F%ehWfM)KWR|AU$JN~5R3W)?ug~xw~Qpb z+6?Z`{4UT~Z1q}L{(iuJBOD?1GnEXFhV?tUDR`r!r@;1;!Gc4B`*p<6o#6L(-a-Nk z&?Eed3uV5)`ES13KgE;@&})u;CTCmdeV#lgh%n!3h2d%ZYQ?%YHF+xh8~9_H(erJ+ z*Qq~rSB6-2)rAgsS6`zK$fFZ)NzCGDbbkuok>3tw)Enq?~-RMp!t$-Vb>r;>8i{#ZA_Qptx7+=urGcQkASGCD_bZR{#R9EYwH4{`J z!CB*GXnW^{4%op(MB#I^@tsv=hruJ&DM&GV$UK_pgFEhs$KQHzHCJB zl-A}SA0$XTfVRGjs16+*%GP)7RdcEwBjq~L=IYCx&VZfM7NU**=KE1K_Pf^`IS50R zdCNHLR!g>O&gC*Pw)(x@I(#(MxVpLO)5XAg$J_?iQsMnC8EiSWN@3p|RBY%%y5t3f zFyeRex;PTkWMnkpMGv6Z#9bNQ*t4$`ZV|&cU##k5K5-qNj7bWBvl;`Fc4|l8zT`aj z-`7FUfvALEzuI}RU;|$bQ=@MJYf%NoWt^zqzQ=m`eu^>@7d6<<7p^$f`C%qk5F|+E zw9ltUXETtQ6zWngoSGYF1vwM`$ivt345(*;gUn(_ebz?kG#+ZQqmnSP?BYUSwy!tORm!8lqxi}ubTg(l@551F2cU<6;Mn=Q$0Ws!;Zn4* z6EHzfpd0c~O8w|S{cC>xZ`_Sv?n;FfWL_NFV(!<)&-kBu_Pl#d6|?`8U;oF<;dh3YeQI&y`&hb^BzTT%uXb6Z{M;Y}lqA({WX|T`76o zskP(dB5F)IDK_uyf`d?EZGuj_XH<$CrXZS%YE5np_iNXgrw(O#n`x|kRWQUkUpoca z-I;)#OgfF!8$qg+D2CB8;x9`NzfV9jyC{K>P&Y~w(b<_zttejjYmH{?Ukf1!ne2}& zwTOV=T7xw`(vHkwl%G`+!Iz#+N!-Q7htMj-*me8jex*IlS1P4^nTk7>C08K1vAlb9{t7OO$a0n&?ZtzLMSff{565g*^PV~_ zZ@*rGD>XdI$Hi9VI@axwBcAn}K39*}ufWpG$^^9E?HqlW*^_e~VKYx(^@NzWfika~ zgM$@Q58m`d*YhwcH5c5C>5V^f(Ajt38&v9TG2O~XmJ+@mZDb&YmU@BG z7L+)dqEVZoil6_X86#A&i3SpRxib@|3Y%qIDx+!pgzyzv0)$&Jc=L|$%9QT2aEY8~ zr$bhnwECb#US7ldve4?f;k1GZn<5DD3r8lR?yloX znuO(K?ES(TGTB06y%UuwT^Iqd$DhQ-+l?DmaqVrgi@*7;3G-Qf0{aYS>JO>$KL2k_ z^3VLjJ+KxAz?vTbYpP!+c_fiFC<_jGCCKemle{_XPrV>Fi2Z-$lXCM|&e}4Ruio6FG~6V$nm6z&g=xOBApkUzHXJ z{!VjRVy*Wy+GSExc1daticR`MY8fv=^yAnuC>*^qb|LpbU%zq<_AiJZG76;>Ts8zV z>LG^Zj+MWRj}(druCuTAc~xj7NQA=XzfQA=DT!Zq8NvJt^)|dj!o_k8-gmCKP39)jtEb>-`-$It< zr0{6-o^J3q4-IF~)RVa_2jxxoyz=SUXO&I(0~d3$tS*Ddr*4E6Z1N%$`kL#RgL}Ek z&!0UCv!$=?8VsO&e2FNJVs);I_Xf|atAaZjlri=iUiC1wx>0rg7u?aFR+$ox>Jrdy@=wcj=0PbGTNNQN_<_{ZW7SMNnHb|Zt>;CnlWY<^yBCP&{ zk_T~dmPKpyim{z~YLy?r&k2AQqRdxKq%U^mD!zA-phF}snZE9(LCDO zl45eL&B9%m)F$ehy2KC0>=s-bYbH+>w$mwrXIESl@uax?BC;P^|3RRxpOV~Wvfw>e zFF%^ziChFmMYT092Ck~xYAp4nakSqPE3j7;54b22*&seY%=IxWN&B|aRQn9QQs#XX zp_4AhvHV8bcbZ((u@YJeT;Zx$)iU;o?P?;Q%%S=f`)jT&`9Jb|J(og$=HTw3{!vE) zsVuD|+0p%3?cs;U255w8C#{Aa+mM{-qQla&HdC%cTnqz(`m9#oDymneIS=;LP;eB% z8Sol#Lyyy2lE9<#U=JPwfllrGGX8LuF&NZ_)+e-@fZf~ztq51DBC~eOil-yRwHqJz zA|*M}aZ>Rpl^Q~$cl(@u`3Uxn$a=6}$y|$OLLajl=a0gvTpwW>S?v~+JQ9zqn+L&~ zQuET@>B6fV9@ZsB={Y-S0)wM~?)vtrXY|WCte(|hqo1EN-7lyG2cQ-lfLgG7P&=5? z76He(xaSroxSGhO*?0fhx*_iVuc7v5t^BWu2S~nf0P42vKZ*qYU*7tkNT_NzANxMH z@g@6LqCRp?&uu0?hqxT3n4PE*>zz3TfYO(N(FToX3wp>@=MS+pfwo3Yi}gZdu}K~7 zgpl^|ZL%M|#yJ%?tDO7X=)&<(KQsTzkF8)uLS^#!Jq`Oc@e);@xy?L-XX@8G=l5giV^1HuK)aoQcg` z53e!MKBslEWBnXLc9PktZqw`-jJ3}sLfIhrz5ZcoU+sPt84|7JiM^JN`SnHuSU*Qt zg&c?N^f|2oURMu+(t_(3(_ZBCVA4-do)UQz`E>e7@o|%pM*$jGsleQ-UnJCjA(Rim z{t(Er^#&n6o(@Jmy{8&Q1`g)8$KkfqDS4k=gFiY4x64JIl8B8IsbZC~x%4!?LM)%b z8}EWFQnI!;C+WEEn}=PmV%!H9%BAE-gQWRqbHt<10%6N#Qk}Wp!dry8xd@438(T&4 zM{#?n_8-13lKTuv!@dSCS-!5H4Q6w+zt>g0tyw?wJzmQ-6Rp5op*&&#G>&^NTuZZ0 zLqSvT75a(fZr*v;(*$cqr3-=49uY#)@=0VdyVOZ%H~V1+K^A8lRrR-ETI70EgQPf^ zQ6Yi_W6S+8=cK5DYl2h`2010#Ixu6=6%7*u=x>LV_k)f*;{;tz^xGTP_&+DP>4Dow zI8+o2KW{?G46?!tYgA`G-Rz8R{nq%e0@0sz!@UJ}!-?wx3r_UTw}FQM&IJJ_R#Sw@ z{q2+ePsD}HKLgJHToekFJum}GRX;0ofF{IWoB!sk{nK*%@W>_F9m@1=}c$q3U|WiN9=pKZu3CDdz|p^iMYQk&tFm4i#2|r&t6qfNlSCz9@#aJjSpKpaw4fkLXy!i4Rj0-# z5Za1-xY46;-;l%F98D$sdxSjQzPz%rvIVD#V&)Wn7q#4|YE^piAaP5vn|7JZsxjX1 zd`8jCRE5vKVUU&h-FvgEfvLBOr5~ch*7vkUA`)gj)F^T3AI^OQVdsCbEoA*!kuu5a zz!ZW2<8xSI?dY5oMZOfCqod0qR?1sK52Phpm~uFLnrohy%1FpDUTmB1RK;5t=xCqm zg}>vMMtx3eWGelbZ?jA1AUX5HuYPrRyzk^e4DfN4`TS&YJ`*kA`KB>Mbh1^ zMi}b|bdjn;xSji->P>jT|7X_r*90a0+l$;v3I9S(pt*$>#-XnnGlwklAWe`gJ6!PKZ&V)h)EfNY4i%C}O7)kmbt0*vk!s??0sS z9?4hRA(wt%TI`uR`JH1Y!MNY;vqq=f8e9~rc!1858xz{v@wz4tD&z< zde*NWuk(~mjnuqbFiQ_T^#Dlwy`#+PMkRw(d-YY?oi5*>%NFKgQagcoq<}XOXZU<8Ybz4E8-BdsyVxU{xV2) zsp(Uon`@KchM4#9L@TK^LEA8!m73PKoqQZ6+#~Q2m(_)c7M_|>G0DZ=Q}5Vf7m;)U zW4?TX4rp)<5!!~NgZlAmW#ZkY87YvYbMyoX=C(CKQIQdt6ihwtRIicMZH|pCPy!w? z6>-=eDRz*|5Ttg;1zVGK2T=w-lofdJ_o)IPR$cL4`ki6(-hR07>YeILt~GD;%vCrq zYoR=8J{hr1wuo&95PB7myr6CnIP|L@Q;c?#p~b!QwH5lz4eFFA@C9U%&T^w`$Dypb z?P{a6_;lvD+C8k!^p_9t3sW-MO$!l7CdrS4UltlGpi)c-ml^)GoZxqm`Wt4aMpYWc zK!$6%Y@-4H6%%Q1jktzseP*Fn`=7QWO+J~>wDz(gnqo> zVlsD32LcJJ{EB~XrP|@UkRP+a8m-!iN`%3aCV|Ry1T8N*V{$D;S&(WsuN=e_+Q^27 zQMsL!mwH1C`BA+P1|^-_taBbo+ejQbvGj3v1tsaWMbFV5dUeByRq2>+%ELTbUwve$ zKoyfd!s!U3I+p@ftC@iUweS|CxB*`R3=Vy$gTL=Qf|dBWAIE-)QVb4jT)edfS6B5= zb7)Z9TH1SLt|E_yoIN*@?-%U!D`5c#^H&g)IcC}PWQ(u~P~!=G3uK9#&yM3Do3|a; zX@{LTKYt~go{-TMe33bX&e^7HCzf&}T(TpP44%k9s0X!!M|$O}M~W+I5Loa5hsDRX zrVMu}YtK`xd>nMrw64SsEX|*e zX3cziXKvZJU=4fttyInh&f~cUR*rI_Knf%5tR8A4B!ky#l*n)f`cx0rGGt;zC)sPf zL3HTqr>A+D{6TLZhAb0%seM>3+jgPyX4Sd^dHG&kWm0{qYk)Pw!N(T71zk*l#=ofw zvvT|??hMSuWcnF**#F|=0U2k=d;oYO?tmACvo8*RSMZ=aDz4|yD3rtNJ^`&%`CFRKqYBtkw z=az$J-(p*M8F9Oe)TYO*Ry9@amsxd>DLYU5yBe#8(@3Vq;*Dao3guGmc9 zx2!SQ6Z!BWIpv%t-_LT7nlK7p*IrAjLco(M)VCizFQqRe6aFbIKlAjen#W~Die0+~ z@+Y()dwLi1i|E;DTAShhv?E;0Ok0cyk3C7sY!VJ1GAp)x?tO-s12?q6jwh@yzdb}H zeJx0m2^w3E4Yq^F@8@%VIHXkx$W2W24~$bj%n} zH@6W-A9g=a!B$qGFs6$X?jqY7So#I)|AFraCq`PRmmdqqyb-6_rMmG*y5+&nZv_WI zzb(337KtxftklK;RGpPYCnx}bE46bunb${n(DV;?G8@Z*U>nejBk z!Wc~IDhrgBDF&7$sIaNLT!xJ3DxM%3g8z2x?? zkUpcn7{u;cqPQa8h0GWnWbYdCoZ_y;3_#$D`_zgxjm(FH;|AMP0_H#>dBX0}ByADMC67lT*5UEizUXR3%zxnCx_ zV6^5%sdUz`T(pWFcGMPMj5CCo?etf?H|%t2E#tsm(9s&K;3ARV91gEJc+3o~6#Tum z8qKpw5yAj8<6FDz&H~q1I1$QsFxA!F4*2?Lk#roYh#A{#33K!KdNSke>#`>Upy$MN zmu9DF`vrrH99kHqt4Sao^BM(3oTcjl-aPWfT$Ayd5pA+C_AArHT4N)HS0H)am_5jA zJ_GoaMou^|qXJ6kV?bCA&>R7}3w~99u-|kQGu}A)H{AtHz$PFM0gMUxU;hXG zlP#*+q7m3x9A>yKh!tI=eb;1^WZidy_*%WAroY$>XW~_WHG`eD*8$xKpuT=Zs52?{ zN*gV5`r43LdK3igP3P$_6imFkS{TM0Rn6sPr|eqkVm7z?$2LnrrrAj+l*W@ov$5u( z;PFz)Flt+Bh}YGHJ=q?sVlPLA)jxdlB3(_g+7nork(b2a-xim6KZla^$)#hr;58e1 z66=H;39G`cV9PYcw7!ZT%S?ZW9s<0^3Jqwt(yPy<9Vnh7kQxn7GlPoWMF)YYD8PE8 zk5Kq2N*F6x9PxZD-cNrO-ZF|bHl||}oN2);{BT$s?{FQiOfTg;wDvlgX7Jg=b+A&1 zRDyHS|Z;`{#W*r&Jjt;WZY=tESMcG^TLWgc{X+s-2_6#D>NS zF?dxeQSM%=n~@-s8l@YKYxw{>lz62XrKF#?NiWGz8BXf#@Qj$J_xPLB7`|s7r1DO) zG&fUgs;fz6nRzq`G@(9MV(Ut(><365O7+nW1f^ni{gz$_skND`VDFZ6F*coqJfubr zGUW?rlTENC7#1pt?xn}{%-K_UK?M(zE`1(Pp$jazF#x;fIJ)vFI)`6{kO9 zk7!B;NeUNFB)EJORyH#=q3vX2Qh6;jpM%}qDn`#9?{=CX@x&WVM_c{UDM--JQT#u! zMZd=ozhaOqj!qTQcbse4_Eu|3Qp;;xRc(J73;nYo`N4`np=UTU!m>y~o!-;nh(})K z4Q6zj-A`S3z)#<+A0E6k7(j`v)i8=MYp(?8z7ah5V;aSgzG%rHlZ#S+lEZLZTXL~7 z7gw0Ju4Ju4^3Y7rca26&px&eJX4R~>s$K>tJGllxP$*aiNe#?48ef0v*2zjmNs)B6 zxUyJJB3fQ{@#r2RD~ zagg+swz=kbZq>`wqo95jZp{$Tm1mTafEbDYvuf{WOWRR7-g=5r${BJj50LAVJgtHy zguWhGZ~3tAso~g2n7Ql`#x8HXjvdvPM}aRdn$+#logvKAipcRwtIr%&u{F_wP9)lf zcRDwb2}i|P_Z9cDtsIl{Ci$#u42D>E7)USy%ypG08euefdpfWJQaBr6H9`$YjFur$cAM!~3dQ{Kbis9B3mja&##m~FGTSsi?{N~;)67^D0ouZzonRH#{De)E~uW_m1KJUDp&_a_mISO}j)oUUI5aT~%i+<*mf7v1k0l*IN0Rad3oh^cp zP>i7bpEo}Yod1pH=Vx;pJ20h+9VkD(nHPJbReG}t6eF|zPne(o=0EVCXyvAWI)~{@ z1k1&gbq3HPmkp+d1b*E2Q~EM$4ue<6e(r6K`cQBM6caVNqrx)y4xeP0_8r2IPyBI) zEPQ-Ggb6BpzNWT4P^G}nGoyzKZn3aL(lI{3cO4%KjI<-Jtzr5ao;x1I30BoGB08}A zUc8gLXzpC;xoYd)n$27HYA$%?MY&{5CNwR2H~ zDclv2--NR3tkyWNqgG0354}1Yg(8z*Js8uU zhQkpNJ=i=k?05?Kv|yzE@O3I%TS=9dvA5|Rae2?{GHiHiVS zg_1B4zp|2;tb(|bI+36(Fh5#Jh>nr)w)7U5T!JYobi-%d+}h1yL<+38lOTSSA2I?Z z$gBW^aodw{M?AB#a&Qd6;{>PEM|AyUd8(P+rOxuk~KI1U(RVu42L$ z;=5p9m{+#)(u)h0iT-1HaLl_?T%`2RV*ED?N)f71o1j}Y!;lW%M@)UM38X0FVMog`0ysCf&T=(gS6ybd8)8b zP4#D*kKI&@awrvA{eDqc*lf>}Rzp%NrCDGPX&N<5s4KD3G6`HVBup6j=bxN+LG9wz zdEtt%ofsK%FL7d%el>MQA9q%bWp8P_lvUV|9h?%y5ZrAsrtEQum zuqzto=BbHUwyEpnw%fOgO@jR>`W(Ccpg9xyQ+Ne*od)s%Jc4M^3SUFZ^PV);Z2crI zerK!?j}u*~V~GhS6I_T)%?1%$=06d_TBI(1aJ0{-fBwLyUXejWM^Y&T+4Oxu?>cu&`Z`h`O5&CltZ-(j9&yj~7Z{xW%E^{iMp5{Dk zDD?r6^7~rt4cqXBA)6lYNFg)oB(??)rE#v1r*6OOu+Xa#9PZhH; zB(v?0afz3v?4XF%(1QbA-An!4f8o|IuW<4G(=6$MwbYzvgGf(|yQo4eaOD4qnf_Y} z0}!P9QuM)0tqBzQG0w-xN_{|EWZO{A{FKnU74yYq#wL6zlc>vxDcN?*GiIhF>K@1- z6GW`%=ooloo0o*C$2v*o^|+7n;c8-@=(3fCZ>bjZef15)R^<$I!WHOQ*F@8OaR##< z>lAq;I`WeH)47|84BPXw_1JZYxl3`w3+r=q`#4j2QHlD-YXWLVI}wI9jeUCef`v$g z$+K!h_6T<4KsyU9O<0Gpw1v}Jz@cBmuOcdnUOaWQf zAY5oosX${(1G*haRo~<20jdtWL;4Kw{b+(u8uRrc7ppfwYZE{WvdPx=`S0q+*4f#IV>itdh1z#Ms?srg2lUV%=E z?q@SIJOaTVN8QMu0WEic>A9z9a1Ze()$P%JmdO5s&MqYNL8AHY&cEF*GgOzP(#q|XD zR#H3`K;VVrzq>{~tJ4^Ej-H$$L)JWt|sbq#riI(wk zir@Yu_2*rCkOs#5Ru3}hcLGHFVPim_r?HBZ)!2ERzJ@4i?Sy%4J=c&E4}x<}gp5nh z`ZRR`_xFLyYcC7ROA7qns&%Swsy0ToLme2_NUd~8BE33?@>jb^hFskCO@p@TeF#fw z+TsmTi>g)0VFIe@F1x!e!)C=Jhp^4AtgVmyU^+2rgosp1giu{~wQC=i>R9rHGaW@4S{~ zom93i{oukFHc^RT{N^1U7j4n^Ru#G)~o}+%={;C z>5S&#DfuB1Q8p&hyO^EG?v%uOh=G{TKPz#3i&eRN%`D|V^BE;e^0NC>prz@VBiNVg z=N~l}#>(_PRmUYfHOB(gD74#7AM2H6lUJYi-=Mt9w-YjehQEw}3{*af@yJ`jrj?$7X>{MvK z$I}hz*yU4SM6k*RweQTwpNEc3UJ(O|&zW!1c+;OJ6XC2xFc?(-sbu|c5BQ6l{AWM< zZ|zH_a3%tG-R=Tc@3UbL-oeEUsMpn8%}|nN9z&!_PDM0(Fca zw(BZ5d%2Pq8afO5eQOr56iL&SA_51a2BisCjHc-3YSD0|@H_0JJ#zB3M_!pro+ry6 z1ej>W5&Eyi5z+`)E^TZQ!`#8^Y^P!SFLjO4*%vsD4)ihAmS0;V!b9Lak)!pl>G8nD z^wB#FBV5O$?mlY*#WimmQR`7sg?X{Sspl$LrXGMB@@=+X*6s7x1!mfd9sch`m970J z9P#Z7LxIT6+cb_Zx36MdaE-h*5t(73nLVMNpyq4Y@dUOHE=3pnyMCWu?TRonMKLW< zpxx_CdEwnQY`OSa^wZ=}V2X5n8nR^M4v2>6LsalGe(YDl^|lCHFZu>&z&mnbdsi-f zbb9p!K=E)DHJaHA>)$j5tP@z_ju}mj30}p8OYYOSW1@`3!H2xanFvA`i4jesB->S0 zkkJxIFFg_8qF8%MP*WI6;*frX$Xu(I$G|;1W}y_pMyvdtwNV?YPj-NdHeE8Pu#G_0)R?*D1>*EQuH1?$wnDzPc~rHn=Abw-{g6zO z`cq2gVdho4mjKsS_yonNdNZVGsdKw0FC=K<56EW?%}e4ZP-MD9VWLy;u%sKUYRTf#clp<&s5n4D7aUaKfeQ|*ovZjAhQ0J~!;&g1a}aj6QnKCJg8PL?CH+}A$=?B5>nUj|s< z(|?3L7V`pa=LNw-RK+P;Au60~0!zkBX{5|@UM+sxgvVq#?#WynZ0F4;nPS(`(Yw53 z4QaK(&QFNa1{?-+lslx2a&e$?pqUZisaC#iyv*Br4d)cy^W0(ovsPBjZcKRn%(hAH zV3Y~>n=CG{FBG$w$?XYaaQVx=sm}4N>Cw6&>`>+E32>FerlUB0pINt4um`8TMvU_cJEO1|JI=jarbh#p)T&)QT)3_1IR2S3VH>s>q>}6$pG;0&ap|o0 zk66^5wwj^vzqUKPTC1R6;8zMpFP5lYd*-*QY4Lid#(5wdYAA@bO=LU@`3c0~XZ%>N z;{wCCN4imTvN_l|V2_#L{EVJs#tq*#(f$f;pJ{^yppAV9OYYyOMc5KuLh0$-85{^qp*h^e;dy85`X^emC<9f3RMTe*{n9o`7L<1)f0NAHkCr zbH4$NZVl7#wvFef04z8H20!q|cchiE(M{}flcQy1L}Y-!P5dH2+`N7-)DjZD<+B(W zZb)txR^W;HL3006aQlCI_kXek34z>6w$$8o+=GP&RIIIo*kydBlc&-^1R>h^CUt)Q z>I0wXnn&VWvMAQW5`+uCOY05?1B#Xn%gwK0AC&l_ zjdp>rSH(6Wi1oWLHc+TK?uj9X{0IG_n5LRzzIBDIk;te;B)im*6nVS1@ z%zt|ZHt>}LW2jIWZuA!5fx%M{pp~@X5Wu9Ke{#YB8$s^MG951#M9rT;!v__u*BMa; zuhc-;=s60_x%{2avzk|CJBzd>>A+HJcjxkH;e1Y94qQ;#F42%XXp7qk&IB1F3j}Ck z6GrMgikS&n{z*d^p|k$&YxLb()N3S+*GEUw-7T9MMSChFB|OGT z-5A9!L75-@6U{vAeM1-E7dBAw%wRs4XKrQkX9_Wqdn^XS+4F8LYvhkicYW-h)AMdT zkQIvErLM>3E5ezCe_qATFHqT}_i+CT7PWFO*t00(c9}vM8`A3kF;4r}%7oMa_-K`z z4A|YuMA>=FyE#TYhhA(@25~Uk`6qFn8!2|*gL`WZ7^L?@auE)ViQm-N#?V}!NKhY8 zf&-|I-{dW*ZMBAji?O*Qk({#uFvZyM_j4Ip8JO>? zHE2|fO^uz2%$%I;9J%P}Zz?f=Uo{@NSHAIzUxho#0|0l+S0%#(;ZX(|Ibh5 zpAfNzq(^o!NgyFa)c@)6L#zXTM=}EWgXFMxu?^Qxqap2r_1=S&ypA`I9u4&U_~ZDNh%vYSSdwLG}S!kg*5f zv@G;t5v<-6mq1ESwRa6>0)EdK%j@{S@f4kGv23reSjG*x&J6?yD+147Z6Ab*8EN~W z$4#^^U)RVv?7JM-XbZ@>55@CYB7n3`SR%<#Z}E+M@XN(EW=3<(Ox4Ckn|L?P+neOE zW4B$j`fS>MkT%|6-ulxKN9&V#LKQIO=T#EnXa=UNH z0hqYW3TBIG`hgxxi#2d6v!?raD5i{STvyq1f8d0T*ZDNH+X||wJxVZf`CRs6Hvbov zxVHYqpmg@wXchdKO)AKh&deUx`7nf!UBrUxr6DVqf)d)vMAn4L_bF(L?Td*hUt^UmYJ76Pt~KLXF1gGko7*tky8YE{nZ@~+6E z`1H_ebB@+6EhLp5WBC=ikdQWk@yEO?XHA)OHGPMUv0(76QYM>3SB?FzQ@mH}(7yLc zN>A=6ia>F9%aq4y_q*Gm_hCA<5tOFBOiw=*o2S zWDG3{EvMiyM)A9tf0rS%$4uHe!gPdRInRux-L+R0cDCDCkKRWm@fNwn+u2y0n!)tY z=;RZw>(slqN%{hw;^ldMpol=!1N+wn_RHt?MghfS=gOyCmOITq*|KD+yIK$b&9Q)D z@a?`?VT2IAtqi`+41C!<*<3*!H&zHRLWT}jbU(i4TO$N))Bo7kHFnXx`QmjA^>rC_ zZ$5K6;8h0qY}ah(AV(`B{hRZR%pHskfhn}^e|i@|8QvdX+#@CiVHM!ljTa33BghZ@ zVg!C}{-cq-IqJs$26o(h?=*tELc&jO4C0ThfP=9MAeVPDn-I`vb-Mo`{frg*c)F>b z-|9FUaI%5uX@qygrF@v2=I7=PPQl_H{~+5(a+2-Se^y(Cr*h;la)ARhvw_5%FvLAU z5qWH%Kg2DR)=mWmS8HJuLBQT=rd%$7={*{D7PIDVaRuJ=cEnw)|m^j`{ zVl%!Gmo~mjxaj|7F+c(;(vX0PH24n{X&A)Or8ib*mR0vb=2j>$fbjtX%FRO#i3Tgm z#>~XQ&I*|2Uou*NfAT~A6%LJnUq}}X_BODEMZ!s|3&H3U4W&qy`NdubwZ>qQ(%qK7tC04cKRePyD=q#kDGu-YnhV!xy>Jt(YPuDOK2U7sIYKV}c!Pi$U0o z@6Tk*^<2{_MCS%rYc%3KozRcT|=OO8qUrFI&FO(G6 zRhd>w3OqeZSmB}fc(4No<@PAO~ChkwT!=l zPVkM59~6xKxnt3szz3=IP(+oJte7$IZmah%rYG>fJWbX%NlEsxp}hv}8t4}xECcHn zT&>6r;OUYf;I)2_F119*-`vO9#>PX9Q_3GKQ!pUOke5N=IO@u z#U;a(M+6tpXmzmP3-JE-wa(vf}oFad>G=LN^fwESdx}&++(ftYN=<7P=oU$Jc_ohyh;A_M92i zN(|$3NOTHB*N0W;!#9V~+h~g$;qPALF(Y?SNukM1VW`+UI{3*Qr!qgwtt!T4aWd8# z7~XuT_yyNzVuMS3nVcbQ1wX8~1cNCkB^C~aROP{!;{mC~=GN)RSVvG3dIP>{2MS@f zZE2OIq?BteR=xry2?cdYz3H7RH&kzl8FY8OI!hz)X$=2`+}2~#B)L6UX0{^x#775> z0?(&8p3tb3tqCk3O^k9&(fO_W(^)c3&WZ-fS|`QO$u3gbvtkbKJ6=6{3@u7#NYQ(G zJZX9HfKdgeT~Xjw`Vh0%1=Jp+5IFibwT*oX#1hnM|JE+tHs}rYnY<9z-Ev*Bxl)(}6R{504ro>ZtZUCWbXL0ITs!Q z4S;VZA{Gut7B*&JOwbLOv;86Hh=6jFI|pc1{XgM85C#G`&jF;+Z-)0W-``~T@4WUu zf%!*lPGem4stqGdq=$4r7rAGTJl+Rr!I#Yn$UOe)mrEAfA6-4PL)v5_)ocKa{?st?e3tw@Pb?ETp`r-; z&|-@YT=>Lh%imvU^JjFeG0;n(?3DD~~?|S)}C( z)i&dxmnVUji0of)*5+&0;;o{*T2@p>8_bEu1AC}zA_B`yxqwKPWH*XJxM8H4*sMME zwKGCi%1Gp)R`8PgoWO8eu~%W}>KckfYN>Mtoid3UH$M$Pb;0afAFU0UQ#$wkV?|fyPZi27~PX5}ZyZgL|on^>4AiqjUy@HI2a;W@lY*yi zXJiyF>u?NwRzS2Jd174!X(>Js79-+#cuc=n?C6SQT$U4QqG0YNX@<~4z)s;`5YYp+ zjQ&v^w9>KWvOAi~cEoC%duJ=AHCIqO97Mw8k&xZoQ{>ZU7$>;{JfC&YB7Cv1v4&f| zxuS558FO|}l&R7@Qo7Eak`2@6)T!W=h-kSB*&SWY9UX5{YL4bsfTIu8gZ(k<=9evk z>;R&a79dI~_>t3)#T%nnY6jYJ?mbsGjH&276C@~hFIrc;xy)@=jbD_J_;!&2(K`08 z-HNxDzllZu7*NA@ry0)7#B$q0c7OBVccFhWE}h?ky+_>`PdMJ6zDp5&({u8M{i}?9 zljMs6$A?-r$ra$L6&&n>^jN%vy#r<_9c~pk;Ez$h)42N|uQi%AD(^!G6>*+jK!g)~ z%ax`$)AwwuU&%$Q+tlY9vKn4J|E{zBur@QBRWm2He@{I2Di98mZ*>xWQMP#|f&C(8 zor#rXn2<|`A~2&8Bc5qWA5m0VPoN@Jbj@EwPHjCbyiq%6W;R8Fkj=DNY}vn#eN&9< z6|(6IEa)|ezFiB(;Ia0)vv_+?Q=^8u7zqJSV>$*4grn%4gw_3zep{0{5?jaBk}JZ2 ztJZFD5OnE&)@&u6j7Ee({_xa?tZ;7cl?VANMb{a!Qd;$kp#mByJ#;xH@k%%<{k6e8AthVc1H9tXSJda8LWghsMrHz z%}n0-b6k0H(v8aP5uWSl)s+-}r{MpVhV8I_6yPNB-n3JxLd_f)mjPgigcqnL!6{b4j1VJ5Ea$eszS3=*V90P%jhtzDj>OXrC@(-Pnl{$>9zz zEVkRJ{TXH_n3E)^8WCAd@Wj4EjP7#d6XBh4@hxNUE%^&i@|P_BFP;S}`(wv4e;t=5 zcfW8(3;x^W??GyRGA)05fXJO`dBOk~7bsZ0KqpXjfY$_Np!+MY2~a5x#&))j=C@qR zAFKEl|9@MRw;jxm-M(KaMre`0Brq(d@_WnC=;|8imjqduVjE0 zpl04q>dDW94m(%!IVAj5_F#s%ew79I7E~L-vdIe9tBc4l1+w-12Dy^{_=Jqgw;3{Rc5t)2cJOyXfCKSIA#tT<)f43_ zSUR3=1S#HjT7|T+KJ%Sn;V7w6E}p%7%}Q*pv=e)NR*z^Kd73He(zN-UjpEG1b`U1z z#!+42t*_z1FZ0wi!mp(VN_4Oxd-tQsm{d4N8LS0@>Z4(-PxOUc?K@HZpo?h?;{`bT zHBbSrqZ+jjAIFJ6CW`hYTZ&CEgSe^eVjQMC6 zyKezM%H^|#@qn)&%|!?DPV&Y zqXn;W)UKn{-8{*Lwk**jL>~g#n83vC#AaXmA49^f`Ezfo)un|w4G^#09 zXm-r>N=J5hvEj8v-oFanB+pucgq~#;MvI^1axIY+3i`bNT5_Z^{eY$D;C0)3`J=;3 zcav4HZc>@{BmqTJdeyHr-+5_xvlr)S?^YihWm^b#Cel4ky!C}?||)X2ltZr&nPhvvk6~vj#o>h#@cPs z9u3kIox!|X;=t%HuQT7p3tIVpx>tZ@Rr|Tnh&TI)X*$5!pG^wO4}nk16ScunfF>S z&|xj_JN?&^XBKCvQzl~}mygor`w0{!AXUoxxz<8*!rLKvKsm+)q?SCk$awhNw2Tc$ll9PC=f5hgD=T4GA&dJf&e2Us{%) zHZn3$!3nQ$PS?i=<~;}^hv4!PA60|LAqMWpCk18r8tUypeURMJXcnmkqKMg5*C&Rd z4q+)icj!w5RA+ZEbpZCR-Nkfwa|{pJBmR;C0*eM#$-;pzV-QD0Rawxi zbdyxthXoEmV8{b3mJnuo1i-y57r>ySNjRGUCnlVU<&5l2EX{!3OU_I`v?!s`p;e4* zf!q(KOn89X&J&=#2dapIoPwyrttu31(0=ADI!)ocg(t&45 zUFzfuKeMLatr&ya_)`;{n^OUQ|!wF1L{%FGH z0{Rqe+W)~P{ZlW<+x)<7f?}!@Cod{*EOEb7X&uEmh8?ZXl{uq6ymQ-{6>Q}9y1C~0KRL7Xo0UW1@*4K z_vjj_)SN;RA{kyUuK}wQMqxz!6hn8vS06Oh?&{fK=$m#2CShA;e#?OaT-Gm*VL0jm zlwHHKZ4O`Nb2{R&a!gTWM4JeY*UnAm&5Paho$|KX6D_?x^2^td9tV0aRXd07=GsJl zNB%sfCD7p9BubvK>{5ABs_|HuGPBUN0YrIU=7Y);33&DpB=bU;6f9PacJq^f|GCA5C;Yr1Qa0zhzN+#U0WjoG6V!T80gT=MY!ddNSUfS0}Q91ll5{cba6t;xtgp3_z1Zl|vCq_8<}VV0YeyLMo~vLU%bc zlwa$>1igJO$e%XiT^9%7n}YPBCbzP)PW9_NGo06rN<1DLnVVzTx(i}vK8XD~OOA>a ziI5m2Qa#Z^&}c4+eh6eFS4}AXhA7(3M=y|yx9k1qydCt$@DFdEL0SnHLOS)<7E`V> zRz+FgIL+3Te@Sh6LZV8yqM6&MK~s`dn1@S=oXQAOwtHnYl!^x%yH4Ltg1A zn}nSYMM+p=s?2U+Xfc!V9?}(l&4O$c=JMG_Nu>WG;E==bs+;)}LzXB2V7mi7KgxPJ zdLwu&b7(FOrTTiG8P0?fV3R&F8!6GSSU+JroSSoK0qIF&g69A+dD<ng7;*%}bybverX5{6_Is}FhgOFcw zkB9t#lIn$i0?s1{ZOiVyuJc;-oENpIbhVQjgHN)sM+PXaL*>aC)e$`9vOv*Z(-nZ4 z**`HRc>46qW}8j*E83*sP8C!H7XtVS@wgFT?vH}@N$+mD6W`gVJdN>n$chL+l(KVK z@<|}&}6vKF+@TH4UL@*H~yNNFPIb3LEBpM0Pb9-VMT|z zVNE&2PTy*1eVV!8n>EyLfnwm1#}-=a?NF%Ab3*}O3TA?yx)O@L>8nJ6J}aVcbVAaW z=Cvn!&bUR*WmcF~pRCwsR3h5k!l?ArWS0;#UlE$!a;=UauEk-CX$Qz zsF_E4RAT3VKPv`jn+_wJ*- zdOoAQ@V7r1&|Th!5=!53&5Wft$bKdRoBNTsc?IaPCy$l>_~PY&h~G*bM21LT}=F&?7d*{Gb6I`B2->aH_ouB zm7~5d1g})*sek&MRNt@t7)?2Hlis4~nqBs&ZfK-ZDuHK=1}XJX@`+I$PZwQ{r)?FP z!}qJP3Vk=C)TB4X$DbD8Gx=PMh*yp_SyUOTHo%^kls(T)JKIoZj5I`hdwFE2zKfz8 z*@Y)O8?0lBG*I0%snGs}*FGBE?!spaFgz<)`hKG3m8_0a-#SyvIwzFmOT4Ac(Rnm3 zO}v``q#(D|+CFGoq}?0Ny%$bhwf;z$!xUD{q?vTzAdkf*iodmeALm)x-bvPpLzgF1 z=iVyYO>RskLv7d>33WA1>ZNx3LcrEA$`Q<|!pY7vWV>-@gEV{rv991TWd`aQir~#p zV!Y>X;)KwbE&BNlRjyl$eIWl-+t#BO$d0kOp&i)vnB+!Q$$`_K}-- z-dAbtjr=M2J4hz~rBr{HyZPmK|D8hpZ=?oa1fujD&=-4ukJNuW^KKD3F!ljN1HG^R ztU~>7>bTzu^>;Y_J92n1#{E0*|8Irq|Ie-XpPa$wZ|&fh$FY}SMLAqt?Xb=bf7O3QwM6Dr%~=Bs_Y~VnYm1N?+Vy>=WQ%RpVSd?x zDTh}=+qSsA|Dv6Wta0fFB6yQV?#zozFOU~Tu0xbTf+hzQ&ephysr}TxH zd&d3-l?G;j(}G$#cWpvAA`4ZlD_TAjb_+$M_K`){G+69i_Wf*F8+m#<}>@tc<)-$Lt9 z{RJI?^A4z5=M)Oy4vDEeX+%LGT;uMLiTaDw&+Ux$U^{Z&jF-7_?y*{Du4G4qQYx*| zk90HGClO00fNs}CSokn4SujQ=fm1SyWJ)s~BUK|b)-G}QlQw|lA^9j@*fjEVjd>}_ ze~3G@fX40R757F2^?k3oX15vwz)mCYLRo+~S=jd8jG3P^ z&@I{J+%mR&;3Lud?eh%3A;0oHXoi~0*8cp~;S@;ercE4bu()PbPgoMCu@PT_8LYBG zBfeoc5Yo#Yp8;4?F?b%qz!Tpm%ttT!HDi2fcjB~MOwZU|^(kH+nL{%Ab72IFAUYGwEsD zKjae>fATcIqd)pB?nnH`$u?!SpMKqcO?&|;0La92H&<{!S#UcaaVx;U3IGxc|L33h zFJgQNF{I=RU%l21t`U;cZ1|c9AHoD~NiF>E#!L)t-qhE41-g|rgDGobg04ubZa(Z!< zw&aV}_w9-4*Z?F&r20(Gn!cVqd~k-2J53HOC5g2$7{FIYq(%&MHDG=QginL$4e*VJ1^J+fI`TzFv|H%;aL3kP0%}u?mU}s z*9I)7B1#*0Eb&a(Ij&vf1)!@H3H;WX-;mB+UkHu~fCoSY39gqf6(|)D1XJ3)oj=Ep zrcWE5t?ornfAOpt4iQw-H@IIVznq4h(rGC{qBA7Wi& zH^Q-t29~y;NIa1mcekA=L{UazMuBWNc5q1^guZe>Bq16FD()15uP>9R(B|jTGW^}Z zVfy!JBX8XM(@<)0U(JaZMK|9Iu92x&>E%L{~DXD3p ze<;)c?G1lH@;^fTU+GbRo(d#Cn=YnfdS8!=k%Kecct`BMh#uI-uEhF8)L;v}B@0_O z_tr*)BKGcg63JL8Lu~RnK{AzF^)l8=(Wm8pcXHRagq@7Zc>v^=%~^s$Oj4L z+PN2Ah?aG&@OzZI6q?c>pxux)IVU$Vp8Vuj zgKv8TMleo0rxv$Giz>m(sP9@4MEc5Cg-C3hD&BXE6l=ZBl6|^+Pa!~*`D}4ygrI2t z&D#u!(s#s2rZ41P*|bS&CR@qPLPse*&;62(%ok}`6%<_rBX2CWa0WlRu)wP`uj@ob z(Xk317>S~?+@qFTl|8k3ha{-K;usTKBNrFuUkPN-Urq`HIuK2efsV?_-vuqV8Dq-_ zAOeh8C;(*l8Dsq4QHH9SiKV@Rt%HS?nadBd>>t4hJUY$q+eB^`LCpMbD;cZ+c3>Kr zgN5sk)`R8Y<^SSJfKaTnzI{7=7Uts88Ar4l`&el6fLzd-xFw^ZeERzD=@bHZ42 ze69kybL|=z2nzEp5C1i-Zs}AC4Am{lo&$f}34mj4X_+|f&ATm{Z&TSt5Mg=aXW_3{ z4L*y+2eHqX^Oo1u2VG@w^P}|g>_VBDd#B^#@ZC5m@d6kPTKGI%D)gXiJIU13=t3wH z@C(2yR|F7CVZ4Is*!eay#@H&Gton}zGuN+7qp<^6?DeJfQu_$QsxtA~ChXDK$n?LY z8}RK;p15~x@;7=S;tN~YKun)besYN17tH~E3kC|F7x*3!*zurv+iFld@^OwR^iW5w z7)a05fmHZx4G@?B+$;oS5P=bZz_0*}zq{w9ZNByY-d7t0jLH#i*MtrM2>|x`+&uiA ze@+)dW(qvZ9O=VTds%FCaG>=m9W)G2L8I`c7cA}PlgAZ=gFX7z)4^dcQ+B1;_&uP6 zG>uzhH0$6j1hy;ZNX&`)RL`9U`D6vB14})!g1sAadyZJKV`fkV4=?Fyu(BLOoPC1h;|_2w%{kx*3fm%A^<$PgAW7@ z;rl;NETqD~#R;VCVPOF>*8iwSfg@o5eETP8+-EZG%1*cA(LiERPGFt$)@uMNTK&ER z{HLGyPub|H9{rPc=y8t=5t75hBde7iX3)=hp+qZMhz)CQ!OB~k_(qtLjResBQ6*)w z$(fs-h6$lT)Git7P&YEB-w|jzq^iFTAw1dHlWueYm>o?TZcEXJonO@^5lJ_%QBkfm+uh)XQTX~OFVYA`e0hag>WO03!-&wo^!rRW!nlr*RLyf<&opN z{oJ#Q6D(76t86Ky+$BsL3n*#-3EOJ9N|ptqExneF7s$+01Twsg+Mvquu=`&&qo<(+ zO^Q%gt~)uhFq8!jmj?HZo{wBv*i0#xv|7Fu6v@$GQ}O(+a%vIz#8ct+8=j-y`as8$0{5O3pDh4D+4Q1TQT=WTLwjh1G zABlIN_LH+V@?HJCu`X+mYA!Gz3A}yX=B$TO?zGdSu>7tV+>X(Sv9xRXU0yQ+YC+YF zbcGKJ3Q>WEP(@qGA-&e51j@4m5+xcyzhP*p_*;T++&X26^P%+hH*>lXBVVSGrpC4;;mIrOXKj7W6`WjcXtTA zOTeTfu<6{di&ewP=@kTODhlMI-o&R|&~*FgGSm;4*VMkzK~oB;hV?V{bi6LKHmo5) z@`spg>`qh9KJyF*)l@br6nKbwJG4up^4HMhUC2d8;CnMf+TjS76k|(4w zW%=3GA7d&i3=i{2hsm}QwY{z8kXr>cifyzMXYx`P?XROjy{O1A=Myr0VCA&eWF!IF zIID1WtFa5CjjLat*pmdcTXM-&z0fo_9+ZyL?>wi1DEGp2O&x4`M?6nyh`*(-^g3^I zB~PH>#%Oj=Th5l5Ok}6{&CZTA8Z57#Q%8%}c}JKf0sNJ&)gaVxny+dqZ66mNZmA5d z$bpHTw&v2~WrCH$$zizRtk$VO*uB0UO2pz9Sn4@Y4et9FQhqUvUU-#zdUsezNLw@A&#!FH!T$ok;&e`5*%1m2w= z#x9#7ROS$fxhI}6Ldpmo1qb<^Xk}+*nXJ2fI)*A#AgVfpC*q1qBOdmH8sBD}32k!I z348W^bY?scuEO@wmJ~gIvEFndc+NKKS3nn=?**mYBYS}A^ihCV2G_fcJ_-oAv^aiw zLHh`s4>T6tgA5C<>yR37l8WcvBA@)Wb<&WG-LE$@2|}E=Q5)ITiKtrJU-mRgV$G>f z4a(;%))#-C2*$+=8A(i;>d!NSKj1tAE15gC80r%^ilCRkOLc%myc#A5V!EUm1kp^1 zmkj{HX9-DuJRsB&iSo1)mOPxO8hK{MLjoru(NMQ16`c3_B&onx@nt|qVemW6WHpk{ zp<3gm-A!|W_RyaVjjy*+>_1t89tJ-uV1n=CAtfP{b3r`L8Bhw{3dgH7(s&|<_Vs;lO*<_2*sBxzvc3@gDM0rf*N{OkU_pxd$fAN)tDg+Y@d zmQwgoNPLeo@!zw)+@?o@Q>I5#b0p^*=)hnT(W8=YX=^TelDu}AW%N#T3?$|6VpOQK zbRresy`%izu~7b(E?QM5qW{1v^tZq9#~2mrPxg0LYb=7aubIQ_Ypv`iK8BJg3w=&8 z7G2*9B9L;VO!dsE&-H4n-}JN2E}>pS>&VuQu2ln8??HX+7(1h&6f~mNd?ZSl6y(xP zynsyY99Yb0Ahqt`tX-)AMuxAZC*pAcZ2bmO3Jq>u?ba#QfEwCLw{K(D_GvY~JikTj zdxJ-Ib`sP@5Sm7l?yaQ$!_d|RrYhf4qB8>o8rz{io0YDnGpBW`KJUVZ=@h;2F+mj> zvBop9_Ogpppox)yY)7-Qn(St0TD&|DXwX&Y+NxzPK6Nv~o`p0~p49&eThM(`>kA9N-=pj1V;l5SLm)7=2T^W#qKGMrvGmqHAiK zjTL3VP9=5(>(hFS0=HKdttt`)(U2#wyTsOW=DOg(Dm2{cVx~cSmTuu~Zb>d5VAhP1 z3Z=DgR$A9B(RdZ-87bt#SgJ-e%ah=2|8#8FNEUI>U1NzMgcK84Q3uW3n%?SqntIWO zFvz^V?C~jBG%`z#x-C+33FO;&Rfyex^GU6tj2w9*TP%NLsZr`v-D~vTPjFrnKYp39som zV_DM2^PGH>3vV{?=|6j-Zp2tBVLJC5u!ODT=)vnQXh72fjy`m8cu>pX#ILqaC|@}- zIP$M`cSS6Jr-natfAKOhOs#?&{j!#yiX(<}`HceYu3;lzEmtQJs6?tBn!;z1bB&kZ z&N5q2B`9^!U%b`BiYVj2*T@vRd6vxH+Sm{6;}B*tHOy>1sb`C@S830+WW&VB1ww@} z&)K$(YaWWWp6QH*ZmQf<$bo+q1o-w8hv2Y8_r?(&WUKs$#am`l?G!Rv#;WY7lA2u? zqf5y}&IW#u75Xza*VHVvkIhl`0b{!YHZ97*VE_8omCakmv}}eTdx&vm(B}+%p_hJ_ zUv`BFUfb-}6L+69=M*Ge6|9DnPY*`1+AfhjoCW11Ga8||~^=TROt6bVR73u8YVlh@(`ut=)R`mKn@-c-8*>z`+2ptL!( zDTZOtJjNYh6;t?n2|B+-i2>BR$4uXvAGGNwXLNS$c0RF*{OI8AVwPuTAHF#mxpGCKFL_Hw93{5iz9a>u9ty1sAS@h2eZ{+vRVk5q zIT}FHH83pUDD<*F7#D`#ZePzMBLV|`oE<;m`&THA+1IOa>722;Hjl(ZMT8CbL7`Pt z^~`)vB3xdkscI9^h+t54gdkTx^TFdutR*lksLoiUvC_~^f9@>;cmzIW+$;FH=+bmW zdMaK8^bPSd`wRoo`T@g0)@_F|-%pYTTUBvQ42Agc#rPAsmc#)Nlb7YOj~k_#5T!%$ zx0cvxD33l(ckR0w4f&P0n@D>LnmrFYB@BoP{TezMi*%_%Z@7+SgqO=N;`4#aP}TZq zKb#WOGFUQ~WxWp~z5c^txx5}(GQkp1F7PRmxG$p^c^l~eX2%gk@h zdMS>gh&4!Tvx^9NjX6q*1AbUrsE_j!#Cm0&W}5m^l{Lg4D-JcYSsn6WeuR2OkIa7@ z*pS%R+1P64IU4G9BgKOkjPQNlbGvt6P8M%Ih~~6i`_s3bRVw{;vEfX7r8kyuMVE&o zt(Q-E8fWFEO!t*qR*T+hZ!qmZHMz8+8^dMy)Ti75F`=2Gjny6g{_6Mmn{IKhUztwl=-Y#?OF~)(3>i{T;HOJ;tMQ9mH9as@tk}T`q z3GgFBtJuNsq$@;gC)T7)we*<#3)djlA~#`X-PL&Q1+sRejwBIG`zfyBuxOO{S^YC; zxktl{ z{YW5}$XWVk+f&IgLKh`iiR1*8k2O^PtK^52z#ukR+-QIcU#3Jcm@j>4<0M1t7(Xv`^|7U^HaE zjwY87)M|C+tYEk0xJez+L(+nKYjx6A0U_qC3R2Rda$LQ(c*>i{G+KB~qHOy9wZ(Tg zXsAStK(%hF70_7hc5A1p7MY7gOYAp5_6DVQD+SIrhJp_cMbN`f|1rGgN&_aVi0Ehko47ZKM zuuzb6NZ??2K$C)og0!Fo2LXY=5G(8Gfm467qvMH?bcUnS{u+N8+k&XfWbeN&Cx;fbrtN+eYgW!+`r}i1!KvZ`)xU$xul#@-q z^Yd+nLh3{w^|?_c#*(&X7|bXSW!B`$^x`ps7$amhpY#$gD|ll=L1OmU(hK$-1{i6A zy4G~v)6G|pa$H_dpV}|5Kp0pSQH6b*X^+eJ*1T-ZR%-I)EzV5C>W1{DVg$0$bHXJC z+$BIFTY?@^4Rk4PK&(WZk_@BVT*%TWoH87C+9h6@BG^~ZJQEHQS<$X^rBqZTmkg*_ zRmK8peNnD3bq0>+5Yfa%1R45_&V&$FqXFc)bZHUgYgTUGx(%9H_rhMlDTY%(HzB*E zE2)rfSkO9-Q>0M1=$fCV&YQYu^o;`BPKj@oc$vl}(LtMuS#w$_o$uzBUbf!2;gpua*@f@B!Q+>3EgY=eX5cAm#vRnd{3Ln!(X;a# z)WM5^fDV)i2aCH0by$$=*=11VKFL4V34n}Tzq!Ev1^Ww-Q}!0T!4Y8YI`Dw}E_WEs zaaZC3%3|G(UNS$t{BQo%e=0@yTJH5tPFAwIQ3eriSG8>FE>eC&l`vY&eS+mFNU~y> zrQK_?*j1jKaD!uKMYc$1d@{Gh{x}}GUUCR&+pC6tja9}Gh9ZwQ>=EvMAT%;(9PSwE zb!gT8h&~}<@`nK1k33AzYxZ-73zN`%U!@J&^gdOOU@2T9#Z(&?n4AgL9 zBoB;gzC@U?6AHqK3PX@>2U=AzAo`G|J9OZ&-Ti{ly{ ztY?6SpVa1)5u^XOGv6Fwkx*6;Hwt+wV38 z9;&o5vJooE-km#)^Oa5%?HhW0J1-ySozU|3kr7zGC3sn|cd(r^Av%OPGYJjZrxbj;@sV{LK>I_;0=3n;95sy=>Kc!KrEq_LIbN(qV8?KN+NT7TVhh_&$ zi=I^q?+w({n`fio&fd&Ro0f9+^vPyE{aWYyOLIE_`invF;x3ad2Y+@tRu{BH|1X1- zS$ocUie_4|R+VA;%nqG65!FetW!@a~+G0FC?2Ee=BV1!CIxfbzk_=(^P#3N*h^1V< zLykTw&&jKOxCXMTN{*1Ux1jfAxe(fRzSi+tO-n?%qorJ9CoM$jd%WZme!6WL{eKl`X zRTw>)E%<``U576gYak8l9Y4pwpP_3yI2ocSqtv$x!R|T}SulCtBtu63PI^8h<6FLF zxS}40uWqQx?P`T8f{c28@%XP``DdK^4W57d`+rl?qUdh0*$Nw&58_JZ`z~5w^V9`= zK9f$Nf!M#vvtlTv>`}(Slo#WXWX-I_3Zu0&NN=#B)q@k&GRB`nW*h=%7zvBP@D2whc>uZTSs^c6troxJwog! zy{?c?xstdh;d%0@&S9o?2~Qyml~Jjw!Ebg|%t2mBvtpS)xq{6v$+Ez65Q4XXLQjtk zb%LyV935`XLgTKQhI&eMULg>_@DcIR0RZn^E2-Y2u~rI5xy1xL|I}<=(dYf+f>J;t zf++~@PG)5`B=yr*bG}`Xh^Ry=1B4aWHI^RQ3*!U5&?QIQj4>Rw!=N%EG#*i0DX~G? zr%GSLb8yxy{q^7&FY+Xi_+FEFcZ2rC_UgCV1*o?~kT{M%#UWO5!Q|P*<&Vpa02ZmBX z;6UI}lRl}7fj@)Gwiur9Dt{9#XouM0EqH!lU@DO?pigXY*0c6px%Ydf6x`d0HEE0Iy(GMT@fjJlb`e%;OOW- zWJG?Hu7I-9~Mj&c;}(U#BA z)2N1r&b;tk4G6rrE_F^FV-^yWPgW?-RD)*-#(K3w1oV4qpm+G&KBkoxs|(X|Q8-Sv zR{OBOD?WCa{V+uk5&Y_cE)J8!2A@)5mWM|Dxpif`HFqZ8QF{ufCS)W&>heleon8n* z@U^D_yqG19B6wD47F#(Of_6J8SA=F(XC_uLf+tZ0{C0`R2r#|x8AvcmOq!;2FK z-dLuWMwn532;Z5DsRo2d?osf^d<63Nk5;2<`5-!k@!z)E);L41{B^&9Kz zJwk3P+GtSKKQN(FP*5DduJ=ie;%j4U0;3!25?qOZW+F`gNSTU$fx4MSihzpSqyH#S z5zw2AX1_Kd&apXY3>r7H}bjhTV>hB zy)XSO!HB|lE)~{oeB@?#*N1FoYH#N1;oxlZt9j7-R|*Wg6=f-}&~GJ5bi&)X$qkqf`}>U7&p!sFA^&mX zT>;w6lvw_L$v{qpdwK+5gAntrBst41lje^x_4~{J=j;0?YhS+b&2w((_}+&Rc4Px8 zzi2NA-C#$h=YOKZP^sOcWbihh`L$74jXiScC;%+wbjnKOB@UOKwW(J(s8%sAlQid( zQHW6)>UClR9_ZXbIhW4|B?>+26WRsI;pYc$Eyu}1wWx+*shW!IorCcK&R-UCH%1p- z-Ef;}vwSdBAs$VMaJ^Hbe!qm*c-Xd5!YRcv=pK^IB{rI$wT~91boyk4!T+e(U<)g| zoMEJ4FkaY0mZC3?)8X^?!HXEe6fOPTgnB=rRqGpC6w&k8$;16HT)^A5{qs zF@bh&&!aM6>k-u{j_BhSSj|JTQ1>e)ofW7KsD>(v6`o1`mlFRl?jHuAZ^)0|fB4oI z*R=GML)`7;FXsQi+J83sy?*nK^dl(W>%1G|Vad!$edjVy(dAkEQrIgp$@6B~u6i|y zYLvWas(JVzli{6t1P(7D9ny-jG$GyBjtk?%9s^`!APctYj~A^F5od~8NdgsTpkBSX zN#YnTx?ZY0N@Wmx8u3*acFGm(@k#h}>P8dQxI}aVqBy?C5JokSJo z<*N-u*INFRZufPn$%H)iwNC~qyq`j*_eSZ zAd4>7ok2gi1pE&_{-5l17?Vr6T)DF0y;e|{o^lDdh*^M4&wg^#XZDoI*QQZ#^uI5| z;h%g-;gcyj*4rkj7JB=k-p@U|<&2-5HHWADmYD`f2GioD+6>KWS@T>vU`-KSNuzAZ2Vrp+Qz5AAy_+B} zvjJCZXW+$}6J@2sbG!I$ufJmhxR62*GsqWD1OrczQ|LMO;I?^({$ig0mD5?4J5RK@ zUaY+5xnD0lobVUZP5d1#TbPD$1M7b2q%7}P==Yz*oP(T@xJL&a3aVa`H6D{^4`5$M zz5duS`gt(=(&-YMrrlPL#lW=2j3?Xy$KCU2Hdm4eS0Lv3*4{bx&IkEr2sE|HuPbvG z{E$zU2=u!Pno<-jxsNs&;Y4amHFS+FpVVIEMLf+ZHg2JV4P*Uo4ceGaqt1H`!ZAc< zyC+{%<0_738^6Okv7HvbCfX9mBVOHdqnFK!i@1 z6HR<`ew8<3bJ~#x83;59wtzI(2&5EzK@CUXE4`>97X3i#Ck4J#TOcLT_v2!C4nVC1 zGa$jInT?s({Vd|Gv09k?%?S+#WRCy?vPXdK-k;DYB(&-XC7%%93W~MTi@^S#J7&w5;%E`id+hf3de+iUWW6}QKUe3Q5 zUX44I z;kPkKhG7&hcV@*Ia!>V#?~J{Rs!}uuDpmZXefdeZ@)yb?0A-Jr&g{fm#ab^yR8;4j zSJWeui9Y2-dAT5I7s85wr-c-4vf6f1G=`q&OMa4Dra+RT&#c7EFgIyZU^UO?F-rAp zQ=Ovm1R|#va@j-ip@X>HRjxX6zwP>z1t@4D%cyYObKH`;0VO!@d`D*&qgzk%UM%Eq zim5)oJW0qUV4`jw=uLM2*r%XZc7V&gex)~$noN<{z!@I8l?Xt$GVs}hz4|-)fJ33%zK?JK9iW2kEeTrw<&V34}PC*%96b< zg-m86($KEG`FO@xOJ8%WI@h~~#w}MO8&Rv9R#i*P*Y8itTH?oJX$~s71}ZPElFnjy zlGvic5$7Uuz}%^_`?=`aRo<${Cd%;nd{+;`mqq51!RI_mo=FywJACTb2*Xy$kB|>2 zC~a8mPV6PlT|~b6A-ys$r+LEs)I=@33$gvVDgYO~c+8ihU`vnNmQDAw&=lIILMiw! z(*Y5%&y8cM&4(zSeRx_|E|AZKJOh@sg(jQy9X)eUCumHz@|(`h z{8yJ^G9CtyRyH+PSgC0#O+5bu_En_>qytJ{d^zl-&^hpFWI}1!rBN<~)nU^Xo zk@_1EHz-H0`=yFv+tc)J8~KJP5{29tHRJdLE6nMpXUknh@K?KUHe}Rjp@{9&JZW%u z3;?<^*+b8KW3dub~o+qY$yKY<+4?^gm~cN+@QB( zCZdjA(Kie%4ew%osvVz|@Z$~%Qcqv@#x?4tk{&6qYQ86W#w4=yj9{uehF8Rzpa5sy zmk(>t_^dzf&DCA7LH;9~;NoEGb{l56{5~Llv#b256z&N5d-6mHGJNc+ePN zap=&+T9v@UUXEk3TzGgq+-4n&|9Cq5U_ggM$N8BVQ2F_MVp&F6MiIuJWgl>Ks=way zJOA*2K;1maDXAx?TI zN?32_lXFGp(~jq3R=H#!g~|t4CWzQaBDhbZOqMXTtiBlBSp*V)B?BUxlytx=9qJtK$ErawxoY_=i4GDIu$D+71rvq`u9+9U1efNLVEV$ zVm^F4lu@o7Uq?rLD^SNTG?_`$0{UjJ5H|ev!Bal+fMA4CIdT@p*jG}yzff9$Tqb#o zHxWY0OH-YO^*-RuVWSNo_OUovZaD(!!q|_>ZweqV@j=%K383!+WJ>5A}ySUii(ct~qLcccIgAD|f3A4Nv zrSQ6=$$J2kKXVd|B{FNZ8e9HF47Dy2A=d3HuLxGwcsCBU%si^Sb+n@?*cZH07&+TC z41-@l1!vd0d)q56G(4lf6dS}TOHEQj+9s%bb`z$EAJnnDz#Pz;1256r$+Vkl!5pA~ zP2z=Mr3o&V@zIfN2g% zu}!7Q53rQr`9s7L82?A0_|dWfgAOBQYinf>jI@}3Q?~-^!6rr)4nOr2fM{};Z@gV4 zv802osg=FO&+%t&0O!3A$@Ke{9|6!Up^GB$|MGABNe%#zzZFQV$G`E z;L?$bH6h-fu=^&G<)_0%M84g+;-WC$)4z@?i5Bw8gf;v~T{sqDcQ7e7zW?GWr&&&( z2teqsMasKO0y1#67XlI-92yGbf#s_eJ`EpjXKuzBuzd|J-@BIC5)}7vLx5X=08GIE z9H0p)VrYIj2mJ4Fxt-?@6`zBnwTO-?2<1m*WD?~acOE>{51Or%5 zz?CED?-ZIOIDCzRzcwfBm$-^xItjk^ZbfOqp(BhvrXft!+KnOM7*Klg%3kJfm!tjC z5wHMmpNCo?{=bes$QEE^)BrsGa_{#tEJ&juzQ~cjLfN0sJh2B``Cp5H5Z!$m!0;UF zw-|^7@ae#S{5K^SJ1}9+cB?bUa?1`6l&boD3HT2^=AS~5(v=;*NOB}J`$9zqEK#0> z1l|5Ry{8Gn=(J5{8bN~m8sr}oBPnQW9WHlshuet2$fePfW6980sWn0JBzm9SJfm zY{qH+RU8g&TIaJ*#&HQr{X`iX{~vd60aaz!tqs%N9nz`PrbD{BOOWpF4(U*&Q#z$n z5b18|Zs`&fP)gw2gpWM+KIa|(d(Qd4k1;lkb??3JwKjXMYt6XkoK@U3{YRka%^E|k z)o{9v3)M-6O0^mBRW>V>E>U62`Y2%OEXX+%(aZ{qO|R<$+;zFl=hA8R78gPJtYy~a zgZkf|Y%wsTv*y@+17Y-(pBc`--Wx*XslB1*2oFVub^8pVC6r1e>!GuUS35L>KPdsG3J% zl(R-zuvV=r%Bvsxq@{f#Ts(B&5H8gmiW4H$$tqhVE`Q3x%W{z)>M)4j6T?m2-LM$E zFCX%6Hv-Y5@QBYbQt+460`{M21VUA}8teJBv}F-{ zV|{w!n{v7Tas5YaNDsMmC*v~iEmiLy_O2Y@Gc@}6ARkV*bw3UaD!lBLXSDt#>5ao+ z_N<1-(3fV_KVXA2INWP_A1q0)mhiZiCIk&Dpp7wxBc3tu!&4=`cJdfiO|$5|&enPk zkkvixg4+3RPf-7KCb2q2QWgRxcUaZ8o)l~aJW{hQel~FRXg$GFRH$c!blow0X>&T1 z7K$_UFTY}R3BSfHc;DQ(n1{DtN_Qddf_+uLSBCTLiNY7ofP^?pYy5Va4o6)#igGxr zr6uiA&LI&mL8+xGTEfmQtv(g5j1;ps5wi!C<=pAPmS{9awwQ{Hc;rJijAZgeVR8{< z?T!Klk5uw87I>Ex|55bI3DVgQ_Lb&Bcc3 z;Z@_5`v>35nZL`coD+ZvqH;Mg&k(eP2exu@l4pu;TcQDwiVsf+a8PLFY-^==#X1d( zTmlk=A|i|6x`P~aCC%s-b6uyPX3f*2cwM-N(Mdsvn@!UUbS+qA;H~O1d0JwYUyxO) zl-N_qik^*P9h4ikf~IZvWtb--4NdDFGDy^}34Y>W#X9b>mOJrP-KxuOA}cGsv;kiR zdkSzq$F~v~0$B1b7ah!a{rp@=(N3kXW|AtEF&b)jWNG@QQMb_sR+!`YoSTNkUBaXF4uCI?9cz zbaUyJi+1mA1=fgX2XYnJfhhtv-qxE2AioX&zuo+w?2z}&AG~`gB*Uxc-cjQhszq*% zkd7JFjm2z@7YFI_o9n8XDhJ3km@9)pUN0rTc~Ytc9U<9H{o>$)=G^UTcgYtNCGyBu z#=ZF=MP(Y_0=ak!2*rXP71^U|Mra7OcX*MF8IE@Hp;iqTtH?p6UyFFVGhhd@#YdLs3^${z zhsx}QY+s$V2XLbodPgU#DaD-IwnZT^0#h%ww&OXpb*da>LoiJi)0|QCiJMf+;)Fmr zWxns1Ysg9nE34}W`v2NuPF6++bT@W_-u)Ky`Av_yiGqL`0V5&1_bvq22&(74Xo|$S z5W{o}bq>c5)j)vbgPjIsE&TEy2si+vr8dOEdX9R(#W4Rp(gH33`_44D?fMC1H;4$` zEct$mG6LD6z>IldV;*&mWY!}2 zNlXPjPS1=zT-9|=^mT=jIox}L1TPQD80FqM?~H6MY;Wh=X<4+-L~5zeSZoH{)&UVhB9^}cjh_@J!zP16!T(eK+%!< zlM(;tCm+8lW1GZdRUCwkGUr#rK3ZNWzI^!5}CFP7TT z?;+pR>}Nh1u*cs|hTAWBgtP|g_2xj>SG<=;x`pCF{e;*|p{??d&gR;>4|nIO(mn}n5`U!SeaGpO{i^AY8=q*SfBJkJolayiG#;Mn>6#(t5eF;!cH?&vMyufL<6Pp^j&8ytY8uZt%{j)>rxvNM32u`dOkU z3yPwKoJWF#GieA_%7(@J}8p}OL_J@(P^^WYKwe3gP~8gu5`s0j;!)C~aXqSdwv5n(Z+<(F8{ z@uMWjN-duYyvJqtl41AC1d9Qa%_Arx%XwIpxt(Kj4zbL3V43FGlgtTnBnE_<5i_mY zB6cpwzFImYZ%X_J&b23Blj-2|2$T^!8EZ&>ProR_Ik9W0Az<8lO1#^@Qv0nmy7J^x zfYf2uVayxSv@r}DHswYl?Pr)D9P(Q|Z9Me1u`I!0FTHbl(mM`$B z+GL)6UqchWgnEIdR#QMGrwQJ^Z1;rh{YiPn(}u*x$;5mFi|^rRCV7XI>T6)I=-dVM zDDOrAB477TKv0*APUmTaRGP68I*=!5^#Tg*gRVBXyxaJ^_J1&7@NNVy$lJV^`234H z@GrLgp$qo8cK+3O9=i$Cx?WKPj_I=UKWzIy7X$>Rjmax~ahkVL^c*jlizE| zf(eNVT`olIVZ}C&)i#H4 zQCBDq+O6la#vR8wUsQ3KA8QyzLyCz?76r5uQe_gMMki4@#UMAZJxx%HpwvXDPeC5H z20)L`>#&&`bNa_qQNHZy;JkW6Vl!bMwEaSVJwbMue3-v{*a;@Q(R3eX%GwjfRutcJ zIixbpJ}3!vwK-h^_Z>x(s!=Jn!8+m6*0oq}^CwEkfVJ|LvQ3zzd<1PuACd7>Q-=76 z(iO=^DOd>THXOm<>w8#qqQMp1Z1a}-za`1IeUxobOBa&0pr^q(HFpTB>tsFPG#4No zvdhn^41(6=>iu-UX9VFR#w2VTC(CGJ?x=|(;QvY7m`W9o$H@D}0ECnnw6kQ4(q5f-{Ly4KZ{%X{$g~=-0kgA*ppl34o;V zZRIZQe82AbQevf;k6o0k_XACVb&cY(tk67&^HxbfadZKC@GNcg^(=pH`pp0S}@0zhTOM0^@SXxt`sy4(pdB2jMa)c5p_Jo+>ltxp+!r#}r&CyJlABG!u?9+fk zM~_zxgDuH_S1B__>R%SqWuRf=WL4y%_CNK&>cXkjpA@5r8vKHbCR1YYZH&)J=kb?J zz@sM_iFuff`U_w`)lX zAA9FHCdb-hZa40GP^;_uG{ZhgPei9-4pksStSb6eTWCM#byyU z7Sw-=1%H4)_e*WE$wXq*)3*Vxag;e4FsC$*??529mufM>x0VWCTbe{O6STY^-HYyN zf^DXK3~2*qk#^9~{G>s%MLt5n)-JeG<~>9~KsHlZ>AnT_tICQi%TJMEA^8d7gFQ0+ zM^HmL=5T@)goG{(;TapzNKii@Nk=I^F)Da5&EJQDfl2Cr09U9#`&%CbF@TE7ZLC*^ z#n<^Do?v3VdIroO0IRh$!&c$#iL@AN5BwB0PpI8YA+x{^2EHW;NQ;fByh84W)Aj< zO)OWjuS(hpS*No657s%la|4NrhFJFasIL&dss+jRs+>F;pU(Aya<`dSLRs>aB{8a~ z`GoBjCjvF7GcYe2YG5k-I_B8WHiIXX8nT_!wpQPR_;PJ-8z!?hjR&?{?t=C-##vxd zaru+lXexMvOWIZ1V_?BQ1zn=WS@=pir}skQF`M7rx&pL(p6SN^a7~Qhj#2o`9|^r= zXh7aCYX_M*6^j?b^p(_+v@|zw8qG{vHydo9W^dde8eY4J!Pz3ahO!|7d>ZZ$*wMR@ zQ-3{vm&E{;dLZs=$-%+AkGlA_RPByY@%9g&>gpbmv*OnDnGZYqA>kcgrTo!KHeLlx zrnT+*;XBIJ2Dd$mVlpP_2H~<6ea3A+&I8Ix^GP&7!My2u`&U66 zCRVn88N~7ZWw03n4K`ii1Nsh$5fIIFVECw?^D4wGX+1F3!2Z_)BEZk`Ukc)|GTxAa zfZVpbAkNM3|Cek2`-1D<7nU1js}4*seYzV;DRqvoamrmI6@3;sS|kZZ@&{sa5}-Kx z5Ha<;!a<)Hr4}x+MA7@Ut}#b5c3i@8(Cp@vq%{lm8GcZ!JReNW{VU}ry1{Ij)VuFEWwZ5)e|~B- z5M))A!Xj=E0NeT61#e{_<&)!Gr%2R0mEfm?&Yp$s-hJ>(8X>iTdVvN|FA%(wMl{sX z`VUiNIBEPkaH({|OB5y}5A}o_ikj#HJwZ_9r)v%l9p&!uR|2{NiLIUK9P}P22M?aQ z)f^Oome~!z4A`>)=(M~2xe+C{2gCo^JpZH-6c;-(ZB-eq*L@bEB*+Uz6sdb0Qkg?w zurSt23#%5&nW?gE!s3Epy{1B-NHL0Tq5X-V;JsHUlMZ59I<32bEb z6d?5|_y>A6mwlE7D$OL79o1)FIxAz}=-_ww>h1%4aOa|OGOo{0X~b6{0{XSSzca5g z`XQL6KuJd2&x3L1``HK!L=Mj|!5C&J%wv_NCG`yB5dW*HIaV`mVBkkrjyJo4=3p#1 z{@Ajys;4!6)kpCQJV#A0h+TL+aLFua$L$@2)V!8~IT>=;Y!GKHk-F?6iyH{jj;~8o zvaB4n1e>6~%@|sPp%jOfOFxB{;rAx*e3|Iy7M}CgkN7p&Ih9@SQkQ^ZhRpXUta;He zoyP`@&+HJUZQ5#>ye>Ahl=8eWf7Cm9YVDnV$9}ZeZGqc=P1)Hp^--QR z(zY8yKACy;5L_8#9YU-^F`7Yh?LbrO}3aVo<{e~ zRCwnK`0mupp~QTsw$mrsnf@8?DeQB>R)3jizjs;w%hn0t&x;&bgTAcGu(*#+9%ra*OIZvJnn-Lbzh-Axhznvyms8oIw zBinJ{5fi9OxdSV{{H?xw+jO+voY8K;trRu?OVZ^!Q3FH%fZDEe2T7iol8TIJGi1*G z6lIbAtPs1@N>}xIr9UoL_t>0F8jSnV{t&PJMe&yIz({xIbAOQzk%1#@3yfX}Fy2w} zJhyGa!K}^JXPD^(D^hQG)16`HET-$!FlPOCuEJEdhh+-}To@~aQQe3_ka7WjjQvMhda2{iK>6x)^WFDP~A(EmNxR(X8u;TdP_eU5v%_xx`fEDzR>i zW%0OIuN^7qyHtSgKB7l8le$}!3azhDl_QaRAw?R&ROYJ>9|h?la*X|DLRo7p^VuZb zNL)#W1sg{A86z{BAcp!(K7ae-Gp5_?|AZ8B82YJVGeTM+%~|~hQ3OR@;A?C`uq!Qj z2(_Urx`u=2EqFyW>EvBY4yNLfv>3;Hig;_I{TS_fWW$1_+Fe-V3PR9Fjv+2mQBaYIy?5JR|yrajB-_*HQ?xj%BiIk&jwzw>cE`v zi!i!Aalcg~15gIihOqz`cg7o{$lcWU41HG ztsH>J%zkqRcys`@!DC_|8;l7^g}-I5+}#QoR0sC^CDyy6{kQ{@(}477VjF8qH(&t} z#ygwv$^AR-$nn3(LO_zsuli2F8;RU!r2=!=7&#bOnOK=`s;b_2?QVvwH^cu2KH=Z^ zn*-2$hwH2aJXS1+cU5$Z!SKkBHABtBR%_e5z8->gre}QDoOlI=8ziTMVg*f3m6>rm zA%?3b?bR1Uwd06zU=t5}Ww2+f1Qa?VgAC_ z`Q?9pZ?K8C@Om32PsKlH*<4=02vtzxp{(6gN%Y*N*9FCv9+fI3Vb|C^^7_<_8ao0W z;T>ZO4z+3Txy6a4IG4UUc`Yh)vObMt!v{n@<*Slt)E!N|zM z%6OModE-oG0x)qfacBT^ZxgZMV52ERV-9HzL2|L4j1=tUg6hvDKom1o zq8ri5W0!t`u6V`*=2-aGkH zqn;Q|q11>YqZN0HJ6OjqIiEcL5Qf3s8tdJ&@r&>bW&(_%n zE7RsW0tu$+;}&CXmPsvY4O0k)7#61`f6K5O8u9$0wq%tFE6u5S3L#CmuOVJp@KZT_ zKF?;XUR`GyP6<9rQ=3EyH9txTe-CC5Jgs$9qy^5>=d)tIpJ~KT?)w>j65cS}<;SXT4=siz>mCjefX|n`D@UiIdnjg^4u*beK=V(qoqX z_EB$>NU0qUZ1V)k$D4>! zeFW!Ze?1B1b;+ZN97zJzc>ZDVj5l%})Un;9`!rUT>R9}PiT7w=h0L4&Lv+~$fS(X! zXOnsjqfCiXgtAr}d03;&M;Y&D9{baj4G516$#R8Ew!AUyiWt0@n)r(3E*T=&?fAEI zMFg!0*jI_YGgg00Umz^7`?w|F=_`JqT)?0o+h1hJ{MyPVoyk}4x!xQ;PMqulaoU?+ zVM!SUc60xkQUmOyj6etnq6FduqW@p$r~I(0#^=Ryv2hck{Sn*L{6{`W+>e>I-2p;C z)CUqtxdA|yUB7=G?Ox*LN4=v<^@yk(9WLcstV zJwrl50}BMH15^RZKgR&DAn||iem`fRU;^CC0sM16i{l?K;Z{>aHKG^{J#s4vbw#pz z!HXkFI4cR#D}J6P7WFYboceVl2gGf}R)bC^zU%1uPWz{R2xfr%n?Fc9eW1Af$NCWdvSQu31wW!^OFIXKI!hV{739 z_PSs%rH-q2Iu7OnhGG>Qu7TB9Wsm3mO35Ny9E1(ZS^`&Ly5+Qo4;j47^`m7N_Xutu|qA_d32{=liR zUB5JZ)dMZSU9V!}pKX4jU+xqQ!j{6=8{5|=QX8=I%w2=`r_)_ zVZp5)^9$Q9G{lE}i1`omw?UxIa9!SRv>*Q$a&P|>HwQ++ry0OPFKeXr>x5*{1MI6y z7alE6R?n+OsPk*kEfPzU`uD};d+($1cTWb(oh}7}0Ulu(u6f4$qo$OPXy{4hAxn&b z{K)*VmV5o8WC}3c?ee0@7g_}%PmJ+RjRP*9QQ=myFb&O2%x+wSw>q?uq5Vy2>(5?@ ze!qDKA!C95m`I>M#`R9PP#}}>)zZRAm{vHU8{fJ(J%0#YH{O^(WMg0g(C-v~1YzKO zH!3&rO+}b{at4q;b))nDT*?in|0f3o93AJkcieKjfg1g-t456FR@#_>^}ZN^Ss}om z8{Pb7z{x+Oj<{rzCpGEW40h z+IyOK4ZFQVAB$P|bt>GA_g#9#^NrQi(v{W25oq4ay#>su?)Q0Ut(Nr4X|J@9A`DEI`#?qbI}OHlUB13 z=R{|oXIg^J!J!Fe?&4pTv(WI3-#GRyN)c`%8I*2}A4ErUrSZ&ztcg&B*1QqMrSWcw zeK)FSwaYxyxg-SvGT`+nu07&}q_PtAef^8Wi7;DQ0o}q1103NvJZF9H?>^-hTZVbe zBcafr8sBdS<>1ujxqyB`jzu6Ls8oJT5o)=Pq^Ka~*hE=eBjB{?Uaa$)ueV`L02NJh z9YubZv9r$}ixhUrQ`(8oV2?zngIK}BrlKh5m0a7Th)yc;k4(bOmWZqhZ#c@NZ);`@ zi3D`tW(q0^*71LNasCu!|D#*y7l`alt@@4HX&Fi{(VOsX)+LrcLYDi(2D{Y_>h)&4 z3M`wjJEHL0GqXTmuNs;ns}8x8+MZp$kxcr~>-ro4L1%3Pr=C%j0s=pLH<97ujd;dM zswBMIqXpjgS>D}Cp9IdQ$H90c15#IKEBD>oviuV())Y^Tmy=l>Nk^`)j%7xP;TIwH z!;-~(?Galrm<|BX=u4OF4prC86Kta8t>Rysy1%Jp!*GW>B>w=5DnA8NQ5)(WK&B`7 zcs=`L7O}w8NQ&Xi4rS&mj45f{N_hc09zGdcvLFP>dEe0irq}>P7}$hIaxME7#EyW` zWlk29KoU$)m@O5iMLUTZYHWF#jV759r{dwh3xQgp+`_STNMSizw&a!b6_HvpB}*t9 z6O|XD)zW;{)EaJ-qdEEd38RE7pCw;4;9rVKA}*O2dsk`-3_o2vetHaHuzk>`45E%hcLFa%E3V3|Zn*->;-P1S}T@@OE)raayneq1VU=7*Gu+Bw-c z>lp&0b3o`e&|@$Z(wW(5*XV77r#Sq3}H1Ea!udRWY)vMTAHVtZz;bxQ9l&0 z8-rB*fu0~J^AoCp{&WQ=8`Ycnh^5V}%p8Fw2<|hy!O<~)d+HXVfq{1>VzE1|0O+Z? zahtGmGBe!;XMPR;gERdT8fTVLRD$BntA+51?w*yc?2_57ycy9mCebM@qf%J6#>X0` z^O7%Da%pts(p@nGOZE&(p2Q0;xhBGVF%d_I*1v%f0MWX{R)v-Ra4%2appTu^sYDU))4JLzAJB{3UCpXaZQUn~8D;ES z#9Zn5Otc6Cumodi;aUySiTj;+rXG7rdD|GQ*-IaN(hsLKAd>j3iSXB)omt9Q`x;DjJQ?yvasfnEoI zkuC>0c?6VdhPtq9AUv+p?7s*6|)?Ma^c15cGDcM|Jb zCKxXQrYKBFefyzRm&}F(dj&Kk|SdlH&mxi0ngSa!)BJb&0Mw`d%-uuL|vRf4r@kybwfye2LTC1laDcM7-aJ}yn+{squSo(qqqjw!>VYj)!)5vj{=astV zkzaZS!S&BxeZH`MG7lxg{TMkE>!rH1IPzA2-VV2Yp39nGX-Kw^x|?@tU#=2j0gr7X zF|J;YCC3jTrcbS6*Qa}5QAwHNQ`)|3n#Fq%BM1q+(fs}lH)K&Igk1sN^*J12w%}!V zY6x=6p(_}61D+Yr3yB_it&&`T%u6F$=^(N`gVqnP+vVKdV^fop?-2z6G;hc+;+ zh!tgyRL8tiJ3;A?2@DpHt^NfObi%%?!qd#7{TrLefS$FsbZn<~=@ydqtLBrB%bzom z@R|3OajuY?4!i>_gjQ`6=d_$E5uZT^Vv=!AeqAb{M4lAyuF50*2COF*CzkF}hl6Qz zJ&9rHFEI*dLNbTUYM@I^x>^zE|1mIcfdP5bMA5pQA<*-iq{C(>Z%ZQy8YJJ3_uvv> znmrU7E6N<-+=9ahlqzKdJ)k(cX-`kf?O#)@yC@!mKN8QA*9jp8SReWc74aklY${!l zw8|lqz6q**_T;-54{iwER^X?!y+9cA3QLw=f<1AXr>>ukJHp+}{1;z@-J&tFiH)J2 zp`qI!I>7$IVh9MJUl7>Z6m07bi+^9x=_c*K-~sRgedfQ&&^Prn#BRvY!21)6+1ohT z-n-9%wc2mAYj||(-=6;2$MJ8x+qc=&_uXEBB&b{6`Qh+?W)c6?_jNIKYDW!6B2#mB zN=H0sr)lAO?ZD*Gv5{$&nq7vrOa13$iEUdS9#tFz7@OI{fnmNEV9KP*DASd`<1J1+ zQZKq)+Id}z@W88yEf~ycDmp{FJL(C`Tc<^+Yzo=cPl73@rs=*HV817_XOqpt<}*r+ zo_k`gm30-e48Qnd{Wa#N-F~i#6|^jLy6NyT9W=IOacG!3$(w__UuFY5d6K&*{U(x~l9s&~`xFcWHd{-7T@9 z0@@@C6LBF!y-U~wj#r;rr%nJ`Nqq>_o5Qj5^t#$CG9tinCjr0gw(n~Tz_;-M8jW_8 zk4BA4quN#J_48z2E##YzuL68u-}tzIeP06szJ5L!fAyM7lN_V}k#E%xDAE7e@|8*I zsIreY>IYg^CUjW1O9nF(#`8!*oD-Nl9yr{yU>{U#v$c3^z%@&hfj!6mz$4IXf>`Pt z#_#SO%2VIh8P&nF1_t%#VnrOPn?-ubt0(-xO32*IUf0&h3=T>6F_UdQ3Mou|C18!! zOS~SM_VMYg?TL31B{7CFMUk~b;6^e@Dx9SsQvPWh!Z`||W&A-fVh6I`tCD?xnz+;O z=m2}pUE&@8&;B11tYI2~dTN?xns1tU9&(+??_VP}A$>BUWq z@K>Tp?{^fV2<7Fb!A->Jzd;-d@#|zlSffc7*+5LEPO13tL_@8F9l4C)#av_hEmlz6 z+T6dgu5Zlnzb)SL3qfuQ_dw19wYj!C1VMm2K?<6cI1**0ulrNA);|{R`I&Kz@aK$c z1n56zTqFE_#`QhqfFn@fTIIJ%+4n5Ve*rnb#)o&L9AKxEJ2mjv@J}^{{uh_}PkQ7B zEd^>RZuaOAzrjX=#*YiNMMH4BpS0HJ3t>N~f$?q_=q(*0`x%sGpA5L#~RMQZJvkLv~y52Zh#!fT!A% z1VxrcfalJqhfw!tM@t~@4I{5u3CsDISB`IHz$t;&g(pNgTQ~feuwdKZ51I5}(1F~d zwL(4GtZa%FmL5&Wxf-?i6@pILM&Xkx-R)BCg|1io*;}lR!6% z+sv_ko6v_Us&dl)GakimfLK*8Z>{;t=9aImw%{u{%G@iiHe&1gQ>^fh2nFx(EuB$5 zsk@2tDi8YPtHH8A#!o_zKDEIyUfbS2E!Qh&e)RHTo=UjklZ+Iwam3>=2&)g7DFBZR>_sX^4rKEa^p zL4HKYl&8iHOOFWx8Bj~5M}GCTCJSIR>G)ym{OOrrEUDsHKu&-_Isb$Is(XL3 z>VH}BNz1qBGql`$we`0t31(`F^!FHv5>@(+{wC+p+S`ap2{P31C z^;1JSlDyMYRdjQ49=UGb$8%Qd{>nVTUSyEtYmer)IE;cio!)B9u|hVwEY?3}=ZA!D zk5x?XGhFzJPcttHhXTfUDQSubZ5X*h`0Yt%em%F=SvCwjD#BMjI+R$Os}+`D|H+|s zd{(Pb@K5E4`5A?xRDNu4F>7G*1eMilk~CJ}-6E&dfDCWk5CKz)adzwg%nMNa`M5HuCG}&&$7c(R*+~;p*sYr>C{d5>DM-+aPmauq~=Vl&i zCnrUPEq=9kERQTF;WZ$#+UU;TDKM|6N(E)MZZF_FRs$NE!N6tjcEtr~7TD|7=Z%u; zo?&zrJUihw*rN<{K=8sN*va<{&Tpgg{KPDPJT&wJB!ko^P4cY`NV$N>d(u8r@lL_4 z(glLUWoubT^@^5AtS31I(7A^U(a@=mu23QlvTZ7*I&%RhNM445=WihZQK;_rO@V!u}xR>eD4D;rQzyl2JTxLO|$0spay{>F=c`s4Jh#4#Oh z^&lhU%m5>(k@;7>-3~or<_zl{MI!_+|ALM1FL_oz(v!Q6*Ai^m6VpGcc{|Oe!( z{Lh1%fdGtwxolhf*Zzy($LXa6?r-Tol*xVfCqSYL1SJ@mG2cUOE9=%))qXzlNS%}# z{sd6NP~i!D%NITFx5pWNt0WTv1P(zdbY*=k$zRhykg=^a=z^#ERJ~E{`Lt4x;nw$& zWIVQ7Lg@G6^3(Yf@SE%Yuf(O+ZhuO8mYi80%@v-7nBP2HY@3q*?j{d7^1IA4!ncH_A0y?t_$o^ zaRNjj1XQePb|_!eM}n?O;nuAw$BV#LOjt$YEp$PjV3E89!wK#pOqWvGKYP7P|jJ_Yy-B2FGX6!3u0VRHyAm@CZupfc0M8 zytpalXYV&rX+y_9>|_64Tz(cD4*X4AAT@#7r5aGX6sC802tZe!#@F!NtqGi@iMz7H()L4a;XIxU35& zt*I)7V;`U9#MmFeom-`T{}Skco()d{^cID8X90T#t6M7rVinFsecsW{P-`CW^8;fj7{J0{Vx63MS&TaH}Cn|P!S zKBIsW3c+sDr%%yJ;_18EouLbf-?K`nZAVLNIb+!~n$X01zs&BARV8gUm+}TBsU%}s zT6-gG^-NRi8%V~Zn44}|=Z~<>#!2wauc6+@Biv-uL zaw8Pp$*^ytr~$SWC-Zt-IWv&^5`!GPGI%WKLFdyy#%KP8s#kyA7fzNgm((}6Vw#tW zNrg=~gY;0!e%53p>Kk0>Zpuubp^}E5$4*2w4_V~duv4|KOv95+nV?A|*GjhVC};MA zZCs)d-APQV!N2n79@W=th4?(U+}YcMj;^wqZ%`8E0ea;E_%vvm40(#S@5Y!RAi_!w zXO}}R7dFrB2d!f~?}c)OpjQPMxBscs7dij5J3=O(42;r(z+X{iu$lp+&xe2clVh>& zw_u;tQZ~aVt#VVGotJvOF8K)^z1_J#RHTl+y!c?mLuEQVU~#UL`Y8&pR|_xRiYfRr zIB^fyphnZo&Sj-c2Lt|+j{CRMS6%yzToei_Ca(>dJhs!?{pz03Z4dE71WWG z>M-0Z-i1>vpyo zMf-&vp%5XxOlWfPv*L>&&}xvNY8;S5{xs+u1VPr>5{9OEITw&Y{#E?i&~v!yIo8NQ zQb`NZMSp1n2PqV#;p}Vz5+60DaK0Q!-cw+tLjJ8 z^#zWMMka)vnT6av7Fw)I=|ucl>G;#Y=I&&63#_tHK? z60G%15(M?%f-mx2`opd952Wt_?wK49AUFsJ!G1spHot>lcnzsWjSIP#n&(FA52flR zN+a_?!xK>ct;;Doo)O(meR(5$10!N98*4L1U=ciP6Jjwdees{69B^Q2gtVNXfb?BG z-kYV|xCMc~neJ;W-saH&0BpYv|I^d`6Bw7$tCrwDI`|$Jk>P?*GiDGGAS056oUSQS z^vpwn{;_CVe%`AUux0fWB5YqJPb zq&T+qfe&G@eNqdIk?}nPM3<`ZEOX(Hc4(Ud=?xYN3*yEuAIG78=}C;4p~Di3MD@?& zBF&;!%i6ta38T))^V)nO_|(tGAlHBhcfhmKIKOSoirr?#8%kkDB!CEQkX+F)5MJCz zHn@V66i~QZ+O!O|%)eDG=mV}$_|CgfcuGj`D9ZvXR3axkhvp?%hwHKF%hok_wh9~k zczhR$*WzBUV;*%G_- zu?x7VC>p%hL`&~9?FdONJ_HoK&t^<8DT%;Fw(NHJOde~|e_@D6eGvpR<=<~NZBb@e+S6}uPkWicNL}b3o}(I%h7zP&mta4t z4Dc+$oggr^xxf&devNcgJ(9Z$Ca68XC8`e13IS{?wx{u zmd~Mw3tB^Tg|`y}v2;!&`an?zDca9;@iRIT+Q(=^7_%Ayd&9#mXkS}7SJ%ItPD(DY ze7vw}m0JaQrMeP*LR~57Vozq$&4-Fv*#QpORFCQb*PL&?d95xqlx&jW16@PVS7Nmz zfa*=>7<19q(4-*Td0h_eNw8H|rFDb$ZwI{kBDBgZW<466B;c3XaQsCy$~UQ=#t?}BrRbIlPJB*(P(a6F!TB(FqdmK>DiND! zBWKh%E5v4xsp#LU%0Fw0JizI{P?ckB7|YQmLM*bdA0qXCP*uJwB=SF?Dl`70s$7E# z_KI*d(2sfLd!$e=Udjq=dzE)R{u2G@TS|02`Y<{t90zHaCl?qpd+Idpj%<5$1dmL>W; zD@$CY>S=FEJP~l7a<`mV>JsD^lLFF{zBH`f(M-lXv20_MiF; zPd5BeUT>wgy$m_$Fn;;N;0*N4_0r?H%eiy#`QB0ml3SeGyGF``Nzjp9EV%k``0CEi zmnubL#XC__j|Xsbm?&hQd^Hjt1{*9Klz6w3?&)97@3ARV^wu&v!YkDGTsrr9BD{T2 zYPov4DqLj9x#crI&7~4@`P+%7h!rohz!w=y23&S*Ja{LUqDav;n$D-0exMj&DA+G* zO=86~J~m}O;4lO0}phfdP^Q^5RWCNligTTzT#XL@d4SdG`cI7KD4U)*i)l=%8$c_UU_bZzI zdocc&o|CmQ8cI7n8gZ&X21R4qgD;`zcD#SsD!0+}^g=<(Ir!wJYr^8g&#AFA zFvpEy<8M)Az4DNy#BMC+6Z{7zJOSzAfAd1FSK058tC7U*<#rOZp+L)yS#s>5_}jo{4n^ld^62 zz5NXLVFfzlwTHVTx83LpcqS1O^aB2x;2;8sh@MY1Jn^%~u8n6Z{RW-f(#JK|bLKjX z7D;Ketrqe*QyVxKje&e7MWX2$*Me`kUOeyDDz_z|Vfi-h42!VqD*X)dh*_{*4-*C7 zMP`sRY&`H##OuA%&H=whEZlQq9a(-YeNyM8>p{K7Ff!LscCh8}#Sv8Y(C^KkC7|_7 zqxbmn$}nJOhGi?WPMY@jr?2Pn=oV|)>{foby^p0B5qHqcWZkSvGI46f<)RUj9TN<{ zWbDB*o*hNto~sJ)%|!G;_P}z%Xuh6De2Ynpp$$RUGfCn*T_v)yuDSpn<-c1FNWBHB$54XB_4Q`_!_|95?uzwzEhX9#Rb`2{>* zIb}pm3Nn<1rC>-EV1O%Sm2-@%R4}x7ZLz^;8}|iLSS-(;L*6+KOe4IMI_->3HtB#? z+(w$>@z#i)<`O}x6Z^ZVa}RgH6mvLL4No)pLLXRiOYc_ETkqYUtoh$#*h7W#9VxtD z5;-VRO8pwrW%ES>aZJ*ahZ1z3dS)_+rO%O7tS|DmAdb8Rk1B=fX-msQUBTulgpg9; zz9PwD>Ng61-ZXV7hA9(tBoZ(HT4Mbpnuh-9Q;VG#GEN(`~7H=PDWjO|L7sq{?UFE7Wvs*84dwKnC>n(aBDH%cMAhYAOv1kR8dmC&rG|So|qX}a0f{A zyII05t%Q@25!hCUgPE0;11O%rBK^OHzq23z1JnIe9n7&x$su>K1E*xNb1sHSd67_7 zt}ctYt2q$U{AF-d0(NxL%b3yzP~;Thy^X{cw*#lT=_W^ZHw z^fI{7-^=H1>aLJ1&%MMv$acDs8sL!mHuDMii|OV8lpb2Sn-||S00LgPkvm!;9$^u_ zU$h7#dn0F?yMB3=z@}UPp$vfxz963a^sCzxg1fzOJGX(oCByw%bZ$0_&MhZPhgru! zPlrk8X2L)A1ORS`+X|mA66OFsOF1cCBK+W@&_`8MNe@7I88 zTgL4bv+g6?IbzJ9VZ<*@#h^|BgWl;f&F^)erX2MVtZ17~XQw8t^XrbXkz5VGtHqvm z%ziPxRGtV{Y-3?TOF?d*X|zwFvA)5ydAL+0aefqOMm7gAv-w>8htYUK)4&gUxB-eM ztPrQVQJ79V0@q|jxILD;eo7E|Ytp1LufysFH68X0mF2BQQdBO?+S%H}8n^@VEZ`^+ zmtzujOTD|u6JF}+M1>ni!v?c`e3eYc`(0sNe*77AqyOOmwTDuW)ih;@?bJ@xN8S&8 zEs@q5UD}RDQ_rumS8j0z&4|vy9auEO=AKs!U<6iM1r00eb@*igfe8aoReqpwt=}OG z0;sb10m)^;GsJHYa1S98VE5pR6<7ILOBWgeM$ic;KSmCYKl4uE5D;a|4D4-ybw7!v z9S!Lju>qJjr>`CYlB$5RxC$Mx-v_H9j=pTqx+CH;NLm-u;}m(%4QHeFOr!jTnKs+b<(LgZd}0nhdgOe?#zgNHH2 z3G*XM8kMqU7r7$ybahObs)GcUf;DM9I3Ty1N^dk`8GQ5RgVn8Wj*wK%_ysk?t-@3F(#+{)_O)(es}3-S2(x zckkaZ(6QK?y%xjYd}ch)obxS(uDkmYn_&4?V*CPW!^qv>-k8%0@r?x`9P}Z_ZA6xN zdTNW8a+-M`NChgz-J$ntUYcX&c`A?^HFG%g!a}rjeQ%ZAT-k9Za=_Y+&nRtkcN-UZ zPybZ!yoXvb{gDqxzF4IiF(HW6g)dB@xUu|9G=F-m*U>Giq4zuT1yhJo7ZYQvDGy^Je)n*{26ewy`G6JFS|9eI zP`c}pFA%;DRboG&t$AXWs3kp6Lc}Hil*Us6MqjigfJwlih}u&zI{RZYT~ZENJZ9na z^TC{8tT9WN@~tq5 zHBLU_&Suk)+OZ~J3qyV`_>k-MV28CAyBBhby>lo*iv4#L4qeSuw+aSMlQ*_G=)qdtyNHD@SmIn3) zEJ7fGtK15SOPo>7sX4{ofK*&Wl2pXp%KTG`xizq^+S10>%GSc%%EaEB^m6lyxx2NA z$D-rRQ;4gTGzHsyx9rVt76QrA0yn4SAJIO_? z?aiT@Ss!XxIM!=^P=$!xEZ zU}bGmb!A8#5s+^cqli{AP?mpU&>JE=(l@SYioSn0Q;=pSoOqB<2|8VUymOgHwLT&F zxtd`pb-_2!Fpn=S$&WJgY{tITv8$woD`+}R2LxWR_sRjO=llt-Reki zUYjI#Q$(O5H;dI@I$q*jmL)=`GuKg)Ialt*$$$4+vQ%XjQr#eY&QKQWeRVX{cN@0FUH-U$ued6&Y#ih|nj z7<+pF!(aZyKY=iyx`5{5-Ip&DpBHzcjQHrHvO+k97HzV(s|}MOKuo)?-`|(xF^do> z<+`De0GW7x_hA$fh^XAiBWsDH^kmS$d1(Yzw!=KB$j{v+S{w%}g|aUJot5`&`n@=4BrT~8OyU`(U5JIA@*IW;Qs)g7i3T3z_)w(Ka-(k48g$yEO;>shr zjvlqTMuK56h2|=AsKRDhn&llU@WWDf!$I41@d!HCyd5;91`l|rI`ELsL-eV7NOdfJ z!(ARZ648OEeS7VY3XL3y7T*2VU^HqqSgOyN8E z^ZN-WcSuOb>NAo2KSl2IF~(6BGStfDtQ8J~v`@NXpc2EswvGTxftYAGA#rzyZq4mnwXNm&MScLhrb|VuREuR=NjNSxrYpcSTf0%o@1*= z^wDdj*q40+MvwB!3E})`00;6zCwmiP^XqQ(ACk78?gs*xuLA+h*8%Uoc0Xu{Z*)$G zW>QO~#qzr;Q?1r-r5=zVlUptbhy?%Zt>}~>@=Ff`i9zs3E4uLY6Ou}c-E^a0Yu^5@ z8~y*$WBiMn8s2jC2Qib4?s7q`)38F#Y%xY?tlcfd3pB@+QbUyokGx10rwGK|5W8Ab z5nhMsLyTu@PebS&#?qmLam$2Aw^X-4a>G7QpYVdWnSXk}Pn;B0+Zk;nm2#VLnse8R zmgoPZrWSCkjis}%CVMUcTKSDUSK2eTo-iW1FMhZG*KTTRR2e?v5SDjjog5Y0C>HE? zo$RMQg1394>T!GCyb7yy#*bIUsw~%Dft9WMLxyA{M;lx8wtuIObw&ZwaU+{yF*ZP=w+k z97_Dty5!3iu74vfxY=b0-2P9=2RG~0#(?WF)xa1i;PO9omw!q=O8mOmaF{G(tSk*w zQrFUZ-D2bxW4seP)s4kWB210vVHWhbqz{>2`uPzv?mm1CQt0yYpJ(VLPCn<%VRPXS z8{>$>zsI@ajxshZ`NqOLbo{J}H_uIHcz@(^RZ=8{Wl~v?V;~aogNkIvlN?q0sVZlI zXgN5z=fr6gghLj&Zwh=PeTES`1+_(z-ZU_CARN9tP@lkn4%U|PR8UCfl9a2%pwTfU_5!U z`5a*(`%y4nr||J-F;0Wtc^8Q`&%^x}KAhht*>~){_K>h^O0fPa`G6%ESbjCpXp<&X zQsAzHrsUY%R`a`K{2RXq9FnU_Q?Ou8c~~S&u;fczmq1X{I#Ynta^jNTqH& z?IRjf$oh zU-sAZgd`Vr3WZl!OIC+0&AMm#LreetHSCODV`)ZO%s$&f7%8^T3QXW0jVKU0j! zty~bQS}!$ljv!w-ynCJDMZAaD9BvX;7zFR)|urAxH zMx!*IGjrsZV|Hc99dFg2FSH5UnA2oBp>OdAaM}*MZgJ%%GLK7pVa~*D_0kh+DEMt5 z3s*=xSyzr#cPL@fNS)LG>!XH{`aNdet@?$bsDOT@1;|MU7h4$~)s1QD)>6-WdXau7 z!vz_7h*l-pS@ZcgD-^LuXkrn$&}&C-AKnqHaIwEuZ8vzIrjjpXhaJ$!+g6BS$2r!! zxsSj;tSk2&_ElQtIJmvuo_xb+ltMz}W~18NeazF~^)z7=xvn-%p*|bP_uWY0!HJ1h z+x(z>?it(a^jca{njFUq406}$colWxXQgVSkehk+iW<{gT}@BlL(xfj}YG4HnWi)2N2jN~9 z70^Ymp68OF`Z28HrkxrR30GKH_==>xZn-qMEE`<4!CaA8>;R*BYtuCM<$8!8o2LIq zAMT%wyjJM-zRldKb0DF-xLA0tMB6i%*9~;%xFq3UAWnesgi0aUEQm=keV^>eyQLY` zjJiJBm`Nb2u6D{%)>qprtnOgt?W-l-L1=O>VtY705v;yPuC+Hk)w}g9AnkdKVv5;r zLZpNrO{;U=LKg=^=zUmY6W@BNf~=@xgA`{{rL3sdN2P17hL9TDA@~@pEa}9liQl;o z4{2DnY+(;9%TF=s^UL0MjTk*}cs>E0n8lsdiQ~$t{NZczzAJB7FY36+d;(Gqa|#Oh z^j1ou^bX_92S<5=gi^^*i?sd6k+`jfuWFyQQa=$0p=z!F{CbJQ42|@4#Mtyeliw@k z`zy@t*GBI1OV@NNIs%12+z#yed_L`#@7t$+pp25=_^sbi;R$ex0KUr+WdF=+^S;>z};hsQ%{X{%jFf7z3wq2C@Be z|dl4te~;qsaS?LupB>HM`knvuQSsqgI9KsL6F} zX3HA8dAker+`RBUrI!AqwTv5r_+>>#^9P0uzC#vZ!b&?l&r)K)a>gatTwx6UU-922 z&X;`N??5970F5XBH1yX%12EwGx1r{e0av;OHUFBDrUTu*$^ntc{xt(GuJIcQ&H-Y- zB%Xed;8&Ob4R`z}P)OYIW4EhhE(4{8*LXnn)*4nPe)o+Za7QqWK0m@ zmlR5nrkxV=*=|1BfVzVSqdKO-h+ z3+OC^WiCGFKOt78UJE>=ou1tpYN3Sx+R&>`Py!n7!9RyleutI8xK$)uM|zh^y8j)g z3;T-kj7lMTtAl$tPjX}K^T%YnI+pn}{0i#%MSdoj!4)o@bS$;K>DIlrQZcL&w#$#7 zr@r&Ua%iiwu^fIi=*FCy0G1@p!VDAdbB?9`=j!J}|SM%*+`#B8fJS)Wr96&>Y$g1u!w zC&kn1G1vMCS3JL1^?V4E+&y}4kSQIjI%|n~(Y9%-9FlA`1$&1y{2kso)t8tHsV zZD1gXUf%GUvn0Q6;)TS(`{RwIKVQBoM_olQpiBOOg&SC2aoNTJ>=y?vFC!S>^1t=o z|Aa;9P*vnP3HLNtsO^(V-G*rA=T>693kw!>!|7?0jA!2HZxp~oTTk9)>M=|+JTD2F zxUyi^Ns!ARVMJ?XMNp{){IbIex=?0+SBGI3<6;EjJEegvC14QjK@L@5 zNKzbOwrRN_((t!q6%6J^f?+$m?TGq29Wb3qbK@Os?k*!o>lHg@Vj@x)1NDs=dG{Zl ze|!ghR`MBE8)8TsH^J!Ote>)w-hDrT2Nzfy=GDhMoc2z=E-LbS z?U4)>_ZHhJR0T;W6Ug*n6KQK&c-NP00(dRs9gWy(%y3z@UBjH~&VYGcbOD+2kyAAI zJl9wx4iddp4O@Jz4f2)L>iTd3r^XrZgtrt*ej9Y>5@j&J!7rfTKrp~Rz%-cOpy)4x z1b-y`@GrK?W+Kq3pQ{vUsQe&nz8QaK90e_8py8}d(9(W%6Ldbr!=NZfLpavT7&5S{ zfikeT6M{30Q1hu8B?z_N$|KN3UX;gKOMIgm<0X=^p6%TfrYeH6U8Nw07mf1^*kMVm5INzvpTDA^Z+da$MCJ>C zV%+=K?q!;w9-M_I8}>?yF@Wn=5tXtINDgo_^_}}nv04z9Zt@SGE&CARHBpMJ8u4Ub znJVE;boO@>Rf2xzBV<6BKm^z<^i5qs!G|%#*JKtEVpD(vLSpex6MLh0+i&fEQRNGmh!*h8UG0j z`h-G5?H8g5z9}~ls6izRX4f?=h3NAIo>m3*ATKZr!o+Q-(JCe8P4d0bEO1nQ+`SIdT96D(avUoH+E0JzDWj1~RB^B&4UHbLZ z)LQs!HBSxexFN(&Vb(nxu2=KS^Mh&Bp)KX=qCs;M0&fQ>c`PJzz=qxwXH%Uc3uY2k z4k|YwW=wqG-cnbhgf@|gW>;hk%WWAV!y5?ifHrsx>ma!pf_J9|O1?+o)my0#Rn*^Z zl9h0fPv|W)K-5|cZIQ#`$`Hy1Ws}uPa_VSY{AT&TB`ea`L5T!Q}bIl{N$CVxo{37bRCfNS|Aggps z-GfZU|@*d2yO$oEMgyodS+5);n1ilDe>x^mg!1oOSU#J zMivRVjpf(9K`|F>^%^Ub0o3JV+}tyCmY?r*wF*k&$fY&H#KDhDo(u9z2+wHEYoPM; zH4sK~jB~4e*lb&80x86Blu(k$x|&byLU4D*szh(wQE9&-HErHJ4%IZ+f8p#Y=ohA5 zwzBwPc;^65E^+9KhQX}mrZN-g5EcR0@~KzC9mMgq^YD zq_>dWtp$m*5VyM4Y8h~U;F||Gxk43kV3)|X+Xn>ae=C*vi7gP(KpYSOd|};Si(Y8r zC!Ls21CKSPyMw*EsBg0#zs*3pna&M|fuLaGLMmfo?_lEgL(2q^EcHM5sQ-fV!vCPAlYMMPvFtufX{*|zGbWqUGW@ZB$>DL{=T{?02Hz)BgCWbI zG1oPFHuVMP$%=aby@T6q`ZF)a_&$T?ox~}sD5IRGp!5>E`PMgVulDMg^i&HU6nnBh z4Pjq!bGzcae&!CmbMOH}y?Bjr&W_T~Q?nc`Mn*~hY_>lob&!x|U?39+5U1%IY`Cc} z@nFJ43bk`a;JtkBMbM2?U&ru3pu6ckAv!Ux*u)kot_x{|Z(jdWC=U#Q_)2FW`CLUt zRsq-Ua71jx=HOYSwN?$~xQ5i~R&$z!Pml$#M1S^6`F4Yeetk^~+^f@!`scy1KWNsU zM;GP|pz?VQxJLi$qYDAu@@o()e#;O3{gBunyRk9u{5B-^iaQ0mj9FOOSpc;->(xS5 zmg`FpCp*A&{fBPzPa2pmO%ZIhS4#?=kcE?;ONhXlnEx{cdr@bG@864DJ!cfi#Ypk7lD{+S__`0-TQb6 zmDc&9P{U1}o+Q~_Z6%$S!z=?_5jBH}Ym1<6Ap$MSK1WM)SuLQgeNT6SVM0ILhCf|k z;?#HX^R8YIG@ES*XHOr7!bP1761&{HCbAkODD}0%s@JFD#Ku_D>fp~IoJ%|32#T0j zGuN1jVrvA`aT!E?f0w6F--&4w!zKFyW(%sX?N!hu;uD|z!h3YhCcLg6H>bP{2L=;g z@ork`SQdws4fniitbHrXj9r*)#s_1Y=b3Uez1~HenUGE;%DlDnfO;-S{^-8V=s2bg z9-Db4pI>lvv#L7A8)a9aqw@B&%_o&ABF~aBH=tE?v^6s0&t3~6(2h+hMxkI-Pse7= zgeKO0c*z#DRqB&Z&_b@-cG$WZk6G}^!&RkiyT``mq2If&bk3w3THrXK=&$&pvkpe% z7B6C?6-sht{F~FsL1*wAX5R(W-#Q z?GELFe6OiwCoY86ev}DffigkV?_~m?xl0#I3gt5n@)-dEYWVAoCAC_>HXol)AfMQF{_9}` zS4B)CI|mTr<*$ee1qBHKe!B%`w;p5GS5)A1li8Ftjze#Q-YzmRR#TxPkDYza~`Fqg6U|R8d8~QnMu8zi*QUCpuz;lGpvS;B3 z)L(4uL~PjBS(2YbH+*R~$G=x^sX%VMnWH7&(kI+Nzp8jA@cx?knAJf7#9-=}dI(G+ zURtV4KPdS_m(%96g91aIUMtOcxq&D|6sNlcNp;`xMRz(}PWd7X%FXX$i$LACqa!36 zi@)X%8~uxjej~a=qg~KMj4RbrTlPY@c%82?1~A#ab(=UcJZsR zy4Q{j2%CUKgRE#OGdwxV(C=9^%mPIzD3qc^aspcW&g&E)Ar49a!4pmLVWAe*Y@4h0s!r_I0XJ z0_RBod&a~?vb4^tCAKBXxNm}$y7YwZ9E~HU=Q)p*LapyUq~98S*wh+b9mW~8_w;BI z9i#b`i*rL>8H9z8d$#zqdFZ7IjfNPm2&u9dIkf6TE^(pJ=;6{_jaiPeN-(S_~Vt;rsxq9yAk-L`v4ZCx)n~HvsISvnKkYJ@3T1N{6l3LpH-vhD zjW(7{BYDb4ws5pYqUpVmY*Gkoxzq*JdkHHE%N(5E_UXkm{RY)Df1ZF`UUnJrSLTHPa}`&+zj^k3Fj(&_4HGlzK%)N;H9Bs;@K1h5SR%_ zap4D*>BrrF)w)Gv2sa;vr#G-e_PG*A#5ex2k19)c%Au!Wo&8*TG*MRwwGKRYU(YDA zH+G5ZTi!squ#mUI67jnXXcg6Jk~T*gT}$HP>&nL z#mWv~KQIIFTD`|{oj?D#Kfpf~-wM3!%QGNjmNKW|xuayzg#t4@w2d*Jl%k`3KCc_D zuhN+Jr`qSRM?F&Q6P^4uFnq z*6#CgMJw>uE1PSjck1*=$t&%DO~GZ9IVFOuJys;S&*E@BQA#m+{C4hsWlT?gLhNp@ z^Q_p-cB|y958?AGt~%YS*a;-?BxAq(PJW(clXxl5$eNIZid~R-tLW z5QnLm7I?Xt^@)oiRgpLCyM{#M&-mj%9pf3&d@vy&9prCW3@=jclJ2Pnoj*Zgi#**J zz>Fe+&A+l*%p0oS(EiGF4S;I(ALGt`+A72hV5gJ7*Tb6%nMZpBz2E4}Dr&n)(x9w- z+@C6Bx7X6#qU$mK+_3(WB>O?vi>Ta~t1u}GK+^+qfgiKZSb!!Uj_X*B0~mdFdCAVf zqw}Y=H2>b6{zZMNrL*;J|Eb?W(v}D&>71ygjZ^L!J*3}|b2QbcHlMJGCGiqFU6teE zot_oz<(x143W8#Aq21VzJL_H~?q`hhE2*hO`ag4xF*QvmgvYz*#O^=6@zApssYF<% z!e(((B;6Mr7!?c-|9c4V^E^95q2*kt7wdSyQwt$~k%7@luD`2V)T{DnZUKDZ2_bA%5x5TK@Erjkjr#Xv z8@SB{dHVt<)Ihau@9uodBz@v(nQ}R0dPa;pzTgt)JftRD2&mJybp#WA*vUv2Gxik; zc<=_yS=C+`lfkdSqa9vq9ra)Y$tyJFb%_Rr(ZB1RV zbmKPEAOl2{`zRNDv`p2Dt`?ueQBUklxCN$~!ZU^WmVunA z*xvputawoXju?}U3o(elqhPaEpl_e3M(?#O2#9_TJa1k-P!*6fx!{xObk(uMd4Sy7q^OWYm$soP zPd*P2XsA)_l%DDf&ttg;@wegW83x+JN|3>FOlj|qfgj*OeI%-NKDXCv_U{<*7M_95 zN+0%%R7BjH6?};|z!faG`$UEC`Qh9*e%ScuC~4Y0NJWwN1{bs?Hc+!Or@bw8-ot*x z>#Ww?izjnODx`N5SewW+Wt3}9Nalohe)Q-JUvO1Qjj$F}QZQQ8A`h-5InObI!= z0PcfQGv?18R8z#6^+XSDQOx_f?Gf`ZSqBke-)VDcU_Y-yt8*!bROwIO|2Mw=`6;1O zHN;?w0+ZDE@k6!u&Bcl*zhUDo1|BfTtBge|Z5RxZsZX$)aJW=Wnpnqj|I6;I5Z7!M z=97x{6OK|RoM;PZbN^S}ig>QNcs_eZ0!=--5eLlo!JRP#8Ne#K<5YO0t)Ub?eMJpG zo;xXi;Cp9>x91TIB|H5}SI4sXRN(7I_EEQfK!y8WTkHHa^$B-?!0V7eW6ebz-udIO ziUl^;hRCt<&t=b)zchDI48wRVDGzqDv(z6-R3YY`-9v+>XeuY=m>7n{nDDGJlk zF)dq=$AR3AR89c$ub;N1fZ1Cl!b4<)&|&@ph& zh@Ef-AM-^kQD~=b@JFe=b_V;@RL*_f)PU+_WN=+uHD$ewetyS#pot9{Xkvq8y1{z= znZgO3^bP%59TQR$$jGhRSbr&0ymt%hMHN_X)}tUG!KvGrUrU32a4bl7)Pd|o(#jSP zERjmG{-Fs1CTz0-@y*qrOSrzuM{X|v-H-n##Qn5HZ|ku|4Na5oLpfpF34WZIl+D^m z9%vvO#n;(nMga3kE}Oo=6o;IMe&d)nI6BR>=7nWyI&zv>Ldr~Mj1%=o-vd{w^avyxzaDuFqt0bZz-mO`)DO{>FN z83SzH1j4iVab%wsBrX&@emI4AVBFLrT5bKfVqls^H)Lh3C2vmKv-d6|M|rFU{!WpW zY}p;IHjm;BS?{^96IP0kwq;VWaD`$D{?BNFMkcq7S18>l(dNY??Ddwol% zPS(94mk&ot&u|P?R%VL+#HQNeMfZBE(u#20XttO2*jJ*6kkSgR7nL$E=#ezOd#}N5 z->0=9AVkWKhz`!3tVvHM>j=hMpDAs^U&B6k<&+z-=@Y;qjKr~|t~_;Tu0topMPYP+ zj7VMNNY$B_b0T^?$HT4aD%ABXdK4k~wQfYnm&IABFH%L4-3oM0bWe8458G?uqvAB( zgMvP6+I={lqFq2Du9d`(g!-%;nyQJXmoI}o zxXkSiv*f4c?0ECDcP^%-Gf#HhO|ZTgXqfy&-2Xzh<);FM;w=)~gXdVLWRBo7 zGryR{72;x;kROE8=Zbylyr?i+YVwx42leEHg4un8bE2rn`fw?E@qt!ECl~9RHj|He z-1j&L1giNyLiJT2OCP-a=KqQFV`ueI8_)2U2e36*YVnR89UF?3mB!8~KIMMm(sE(8 zX={aD{Y^0wVvS4ltGFv^Bs9>Kql+Wi-JiFd6T-kyx(QAo%fh|2P-p~IPGizK?whoa z_)S!BJl>C^xv;sV>pLtklI!|nQjdRcEcc|`@@X^Y-H#AhA!-b-3UD04`?%6E`4eKn zkZ7TGlcl8#AG9uX_R^SybKsO|wt>clbt^DGt~8>?uw=$0bXlyG&e0s8Wr44R-!WVX z>MDII5nulj?GZOVr^EwtvwJh`Ef_R8sxTkY_yb@}Yzw^#X~mM#E2Yivnn#Q-KFEa% zFt)`{MfwD1*yEkvx3_LKUCY*rqx;mmSx&C-onJ^3Upag?rcWjAf|@4h`6RQ46ND{)z0sI}09Nn(1sX)4jbk9q1~( zg}p!zG0N43GblJDXf+d81BV}#B3L9?DO*5SVQa&J3&I9+CMX0XR8>_uV4{q@ovpor zBS6vt_{)6x3a~i~c;%9J``a?or9|T@(&hwGQ$WrM%%Qo8v{`Ol{trLhzsPRIZL*b` z-%)TTKe!u)(-}u@EI8#JPSgcgoc5TqGF-X>ia;_>D~B<*Z6g_uqm5=Q__?aqnqkQK zwl1nAi;9sjUvT&O`o}Q5L3Y@wsuq~1jpDKEolmnUX5qj3oa{*sUQImunaKL~`#XS^ zIiLo^Azqv=X7o3ct#tpM_}-pX@RvXFXK)I*ReFH9X-T$SUeiX;c-U)D5cgyQ`j{Cb zYHDNgOvw^mLZXS67zj*uwejm)g{l71U$n#eXsd#SU5B50S|MV2Q!Nn*IFZVS9=3%yXy$zy7c+m(S>3Mv>6~E zg226rAe3UP)^S&dU&#;0Z#hMz=H7n85_Np}CHD*~|tR=~o-1svw9 zu4WEE#0U%t1O{3HWf!0S4G;NGwbKMj;u@@y%9+;ZZ)rYqBbx7hRLEjrA|uihn<3Np zqHsLF?^PmG_AZwsZx#l7{-y4?siUR7cLeS00D|#X$O+cYXm_=~m=rvfNpMSXqJoOGb8&c_{uF56U@?3e=iiREl|cYE$E;V%9dbkDW6chAcLIy>0-#_w^3p1KPJFf2QaB4~av zeu=lXj|v4B@&OVD&v;*liad;+q3Ffx;Rgd8ps1IR!rC&c1fH<$qP0S$RXrYXxRYFWoYcpZ#^1a6PlpN(+eIW0AhqH=g^oh%y>`n)XanKs5-njN;wp4dEuHV5+^-Vcp$vsrF`oyJ3? z(b2;<1irlllB)X3SK^x+1L}}V4Ip6Wms=u$VP`ir+8dY&`GZS=HU<)vhXBmnY!636 z02lEF-X%`aCU(^raT{hX6BU_1qs-6F25I1?*O|&smGd9pyES(0XQlSa^#OSbP*nn2 zFt3$iw=e&r_xh(4CQ}J-S}^h65Szq~t+Ih{QMO`)X|TTExaw!5yW^wV7kROw_KC-( z`W_(-B6BQCj{QE!9^Eg=azy7pq7b$>&Iop3|JS4_`OGK2|9RtqDAipr=5faOV5QHrEceXMQZ3HmgwW70u%Z`%TQw z>l{{RvG7AbZr3iyqO>$zherFoQ&e2fP`(C?M)`<#MHH^DByUhGW(=7+Ibf9C7}}_~ z_fKRqgY{kwEFkj)$T)foYX>$8Dj?~p?BDyQ;=8k&{^7ecJO150;UHd&&6VkkM4|_k zoh!t<6-p25Sq2>zw`x;2*bp6SNlBYct+wGH-POIHN+`r-?h^~l9ge}zu^H1Fjk4ZP zIj(<#>S`Nb9i4Ri>Q1DqyLTYgsJ-JWbw}62$~hZ5s7l4uO0%XX7cAQj_wL2e6(S0w zq@K$MnOM59mE77M{^uwG=Jz<`XI!!&hF3qh4HLSV@uXH{nOdzaoYVOigSkp!kn}pVDVyIHgsIT{o z0X$fAE;8m)Ps1)(jBCMzSH)=#+h3_-#_#vVB~A^ zyQdivNBqjEd=S+A5bjyzV7S_j{G)n(M@XUcO@FUO5|>vnD-D^r`YN#-?VqWVtxvKy z(s|kYw4Y3DDD837ZLDF+v$Q_kpV$d}H7_;a@`>vd2JOU2`w@#I?Syj@;aA_ht)vR& zZ$T7E=COwSi|XE-qiPTrI~DppLlm}S;(ju^CR@QspD{B@J8|Dql^`F3Z>J6HgS9z^ zzoC-~H<`p}o~Od`T&oS##UWKwj+Rk{L|oVJVB0YKF5b$lJEfKC&9ihedX9nlZsT5z zjELh1wRJliuLXj+U~1c{eZ+I40E!xG{4#-VcW1=k5hJY&V&yd zLf65#^x+p3ythsY^|)c)63EO=aWnEy<&Z?;56isT?6OtLH=RxQw-je4prwYV<3x>sSPr#Jc5m!(W zzor9jRNIh92-1Jt`Vw@30pqMJY%IW33)ag4c$c%ruP(S)IduMwPyQ!}Z69>+KqdZ= z8L)zFVo}&gAkO+YcKjSow<~}7ts8hma8t*w`r~gdwJtGx_8AOfW63XGV)DLOri?^D z&*)K2+d+t*h!T{M<`Ms{A{9sO2fR-1OP;A7JuVXGfDE8n7~9*ob%f>5YgksgxJ zw9d!=DOT9r%c+r{^pioQvScc0Wb~Uz**yghe{r>>erRgpf>L=Rw%TUMHY$$>yGg!% zct$lEsSnI^%^w8XI$y}C@^DeC4}u@h!i&kv8`sYv>jaWl=Mto!QhBVQzJyy|TUUu^VE)LM_XKmRQ`$!d{omz_}4F9fExJKt2VR zVIVq`PZr4Mtq-cX%_Cc(pZ1aA69w`KX8{DJm&peLlEAG~P0C0rDlI`O46sscT&$cR zMipQPq!E+G)fOxRMo9yJ4>NZsRReMk4pIqDR#H`N7EzG!9#Xsq;vU6F;mWQbVlk#$zI&GAN6O{AfNb3m0q;Q_D?CYiG563q z&)pLKeGBcTnY1a$o6?;Hn@87chmh&B6@2b4OM|aMMb&X_9i6{my-+%@_L;UU|6R(- z5-g`Yhx!_=z(tYWwfmdIAo9dcE+E~u@>#F7rd}faB0`!hS@7YRwjBeVF4m5kmc=)%-USNvs>ZVhVFk~y)fAZvFh>NccM{Og(EM4H@A`_nj(`#>NAH# zLJ^wTm$xj92wF^dK4|SqPG_q+*gfc@n_Egjj0P8iA`Z|oqQl|*3gEnWZ%HH+T>A7E zeaOiI&tp9O#-eja%tWP%Cf6J&m!qDlWqkA&c%9BKXWyvVoI2FSP17?Blbj|s{xzk? z*N!tfiEk#3Y(cvWX(Ebi`@6PIablafl_)hhhtWgzU`Sr4u}Yb7wTsPZ?=i-H?&154 zhzXtoR+DGcL9JJQ0S_P(Ok5pJY>Z8eoeiwajju{cw`hf1(fWPBP3Qn_LgdCxC=Sp^ z92mE;B`dOPJ)*FC_{$;t(+bbOrWL3_6qlv}i9~owD~R7b2dTy%5Au^>-~b2)wm%34 zwyUuzKM01~yF&l18~u|L$%co$ivdxPIBWc#SQOjcp)e}dNg(TFfg8+yJ=lU2HS|-# zOEyTIfEKNQ;RgRI#g@*TCC=5gh@KAr}Aeu3RXQ$Yh zr(DD(9Yj4zKy(@MT7exfERE$^*xRv2MKSRUF;e^F{c$!~)>D!?6C6&zKPY*$iB;^x zR|dgM?J2h^WLE|lo3XMsV!CgX`~7w7#yz?v!wI@cZ9_CF89E^DW-q4?XQwDoRqzZwju|VmtsP6mr`0 zcu7Njr_Gde`vR>w8B>9+8YWRp6lUIgtZyfv3m;euXm!44Z}PVD!k=d0v! z`lhU`wbusw`AZ4p)1OqsPq-a-43Nd@qw>ivzg6n`^OyvrXIm6<+ zM6ir$xn5E;jGX3SnKM}8<9~bb@fcQ4dv&k9ts<|hlF5Cl{-A)do-aSe4jSDeg-Q{e z)^1@DX>L`=V@kTJftb$c09)2Rsx6JB;{C+gYmz;EAqb2!1wxpPV$4W29K1XDJ0zn> z<~oOuUH4-=qY%T_Bh|vIZQsb{oH-hQf1GqA4Ev@#>I;9;>`PW2ha9?L^ETHgY8KD= zR?yBFrmM>x6pa1P*fDjorcdlt{W}V(_PFI4B6;eO8}%)}&MyuJg^e)Oqvxzq0H>SDYv)u@B-blahvjO?%+u( zfA)#~)Z5f8v5eZ0mBlX@aX3$41Xwp(%S5W3)5lD>>A5+S$xu*inbWS?*v;5PC>u$O9T6k%>4CMH+;k9v*`XZXm$C!{D^n{GcnsAxC(}G{xN+2B? z8>qdj5JgCGk@KnTC%S5j)1PS}`+g#kP+oY2+ZFaQY+ZWINon}`UF{A>_KD|+WI4pE z1dFZTu>|UI-k(y~P)l^492Ww!9DB+A5Dig3jN^gDq&f2sF(z$5B{RYpqH(DZ`r8xG zEOxc9taGg!X}?4ya_;hCO$v&I<5a1dc7EV2EuH(c#)Pz}y@B2t*EvO_@Va~gtRlKv zQSj@Igg<7``~+ku6rf6r01ynj*MJNU*61Y)r64JY_sjA6bLI2Dwj|+4Jq3yQkL3w} zu@nKsbEWEmrwfn@_=XG)4~~s?6;=KCEtt%lu3~>4poaly#{=}LHyd1l`PVm>|2rP? zpUSgek0SPrawh`DGG|3jd!we`Q6D9~HL}Znnb*N4)?Yl#%FrhUZ!T<_=-3waorl z>sxs?CVw6wCofD7?>h-ft-_||son-^@2nI^W?!Sger>O0TRyK>zsmsOor!mlJf*G* z8UF-U>LT%!D}=IHyGsepDExgket{o;!105sLM5AweuS>!$6h3v1Re*fHslXF>6eB) z^z%jB)_}#m5`u^-magyUD8)wPi*`wCi4HsT9Qmi(t!mFKEI!) zTk05~GI&*gZSP09&otas>><#3cJBiDZfrDETiryrTe)cDc1G>i?iN`>_0W($%;BcU zI>;*ZeRjuAe#nU+qJxFNDwB{GNuHX4+Zq!b*C@r_^ORbm!nq8m$<%o@%)&}S+6>&o zJC$jemI5LmZ`nVDJ%AuKfSPmf zCag0&WVKpsUNF-mF#P2>TarV0||`sdXDr&L5jLH_@v?kk|OYP)S|q`Nz%J0+9` zL0Uq(yBkHirMtVkTTnU$k(Q87Ns;Dmz~GDje*d}m+;i?>3?1*@@V~#0%n| zA3_XZ%#|dBW#mN^fR|#=$NwPT7ZpHjo|Tu8QM}(6{U==FpSBlmoenq=Zo>BV{#S@Rv7aYFF$cct zMXbSD4e`L5;J$jlROS`xH=!A(yfsRqddbZx$n;irvlgi!V3L8}gk)`m6I*q(~)eCw|9=^qA{O`IVP2SK$lX zATvD`u4;_YS`?F)goG#yuueP3k4}c?T^s;J&EbhicuFYj9}dpw|*}ju$t$ zoL_c4BAq`KWJ5m4!Pgwyv2R{by7B?Rk_w?5v8GS%r89avF{ArA`tvU+372EA8L41P zx>{T8l63X9>->B&#dJ*!ev4U-VJlHIA99L%)I%hpu2Dsco%_+D*%u1tgEz`BWH1BO zT8=}yR7(SV5#I%F5gB!ggkD>4a?m;(dPm67@?Fb0IqGI?8}ajddM_vy$Py8`CKTzl z`d~TjBk;_BPu8hoj}LlOxy_5q`S^8M|tlqPP@1h%Du%{~O zS?K%G;bkYi4ZOcLsDJ2(d?9s)6K6KAfj0VHU9p+PF5UUtz6D`_T25{n>E{u-R4*5O zZE7_BtV4YVN0)&(Md`4+_es3@SGCTUO%ROEs^oCs%=?fTJLsBqK z9ongimf(LfkK65q_8e~g+JUy$7&xnEKUB~@sl>+mW`uhetEMpyxF3%Y=m%))&%^sKt(Rcea$V)|6ofy0M>|2L$2Sp*V$0YUh?+XGKP?XmV9N&b{!3~|ipj1o~ zYl(t5gOKD9f>7x=Tjhg-hNZA2ULSFVpVyC6*+TW&ta^63?7-!^9H7A^f7d{KNgh=# zKI5k~C+p|D_GFbgKitt;r!1M14yDGcuCSDxP0beG1YuA$?bxO)8EyoY>lBLATY&=p zLat-=?IL#!9C=CENX&BVguT9*jWifc4cykLUn~m)G z(6P=HC9#%9UHB}_Bzmb38SG_S;ip6&A^Y{_J>E#)cHhczQZcbv^@im<@RKlo>+&G{ z7z|UNe`Q+gH9TAIsa9lwl8BT2AWNl#4QnqyHg$}7M`F*&Jxb+rLh-aa%{h;_dena3>&P*(wwNm5~d@%raV`c%u|Lx)by9@tQ`ag}hnh-LSwImbt`g}jwo5E~UoM@k> zydee!qGeBSWYNg*1ODs>JaO8uA%UTZWz-%9MH}7psQpFwQr6HJe6UP|7$Gtzv!C9` zV&Lz}e(hlRez75c5aG69F~-gmswrf5Ah0oJx>OnXNQs-v3W_(tM2+TIXP#ocdEh|O zDR1A(W#Bhd-bm-z@z3^_QNlVSA>E>t4v2p1I6-3;=3~y7F_{}Zuv}XQicx63 zkMNoa*=m9z-!wP{SIiI*M-;&*ScVV1(%~_o(m>zdh8S9nxPs*6#|5_De%t5rnwDKv_mN zh(Wge>x;`j@Tvb~f*QA5dnMyI9MZbonE95ilZvJ0)rEO79c>FtszR%oW+94r?aG6! zsy;rQXQQGpRs8MgOM1`o4jOk$xW5QBaAmDB22t|trpqdwcEMh94R*j;%SFe7X0@yR2RS@`{MA;rz7{tAE@By#{ z(ult;6cPu>iZB2Rz5J1|J5^a3a~4@w z%cQV9>uxo1zHg>CQxgO~S+2p+P^As5L~lO*=O6_Ao$5O`6ASPK?8;fVZ;b87A&{wa zz4)iM|5H+vw!~i8%h!?Uh*Ug2hI9G`4N}h8Ub_l|8ILNaNUMbL!cE>&`+|utW_59? zz`Bx0_&F0I?L+SH4|HX*GidP`O6bsJzDQSb&`EHv4z&Y*+`^j}SIfe(tu-EK=BK0O zqL9aE>DzBjyE}uU=4u$eyvm%gMQrn89Yu zAKI=;g;4mlYMuFw=6b)q`uS*B()q2@!_9@rMC|--0Z(BHS3---FUpL^X9zn=d zg!DuF!lK7f@dbhZ5mW!h5#$(C+yj=4XlV^Yq*!joP)Z-d8Wfj61r^`-h|}DW^Ik|5 zIpSQ<5u-x8+2<7xGEwCp!Iqkz?Tt6;6NF!!-8W>q31ov5F5Qj%3U*R$Kllo)gr;tl!3oGO_ z{D`M_E<=t<=HH&&+L4p=uagg2&6Xx>AH~8Lw!3GTC@1Hw#o+bLgS4d>#!TWM;Kj}CWtSl zO>^s~-^r=M*IvMnZfz#@2~~NwtRh#I&JGKCbod0!{orP>!-UZ;!H=$R&dI z>#gaH+1br-t=A#176`m)bVg}*nA=RpVO(YGkB%pg1x2qoGj?|#C|@414f$^>2hVe3 z^%uSE$0Pt}%C^NJx3rlXx63>w`*0MIU@M_HM3-wj^OW)dw$m`BnGq~6?0mmW>a!VW zX@WA5d<;@K_BCA{C`ITq!)MnBl>B`#bUA6zxu6-KXdEO#wV>&l_6@S2dY_*6wIj^Y z!&Bjf?yne&dd_Nv5qgylQ1o1oUVfkms-|VeT93tGB+OI9Lqi$>J7MXEhwcizoIf}; z`s5QoOGd`E>6OYOpBp&OuM25h<4J&R9>zu2${Isc+P~(k zf2e%|o64Kf)H{d_^UWUfPc&rz7nk`Ll?VhTO+1Vg@Zk&>_PR&Bk*<9h_=CEK$&~8Q zd@G7)S>pq!n@8wc>!CPBj11zd#n?j5#lxKKEtP|Gt740|t9tc(42;elGBZa=*~U`O zZOvi`q_G8KoCi30BNmekXsQ21R|n)hu5Bpn?38j$Anm4CPsU2edH=aucppJ)1j3{b z#)JiP=pP{aqO7M)uvJX!o4KjqLdQe)^(f!MeMH?_C zK~;aDPjd5(qcAKlh5}wI^CfEuntg+&ui5j8I#snQ)jtCWFbS9R-qv^yT7kU**c||U zSOj|ma}%AraO?Q92=RNJKsp2A)*eWT)$hVB5~z{Z!|^NErRCzcFlvygfAT|r&`uJS zxThGQcyk$IQ4>pZ9ZP*;85h%^2{Sl6^4<4-q`$-fK%HhY*&5JLG%@R%)olMq-QnJCDy(}`WJPnAX9u|iJ-v8wmlPO4BmA&!n z%Chb;-743|vVCtjgvs?ja%{l+9t$~+No8o;8ZA<>=JYeyKO!Y#t9NTrB7KswdGr#z z#Q37pQzm}celujnZBVa0>v%5my$a4kY*S}P0bh=N>{Z!mU|~xPmg1zd@IJf~M&v@g zU|#lkA#vp3yY#Bq%11teA#P(a%i}W}x*aN2E}d^i*;&2Q95Un|>TvC=@`cJSw7BrD zna5sfPJtOzhpG>wu+3|<%IA54w7VyWBw&nT^}s4@>m4Sz4Va+%y~o-EO>OmQ9+B_I zi!>a{R#?es?U;cXUky~E?OA#?w{#u2!fr{mZVpE#S3m)|C4Mqn(RXJ4KyJ4V+g!Mh z@{3(pAe84yP;vPpbyovjyJWe%C0dCUg<~b$W=Pt$6%0t46o?T zKZA=}vPX@%#xTwiPpZ9+4u>#pRON$!bV%XML}cLGdY3KleKl-UIrEZ&(jYMi2uPX=BdXN(kc7ommC_U<>SO&g~KEfE`xH3q<^fb<^0x z*Fimyjr)c8nVfa2;@P5f(VO{>x?;h|3ee)p=8KWfYD*#eKfimb8CJ}PBmI6y+ktlG zU7z6CUF^OQfW8lJuq|F@btx3_KfWv`NFDEH^qVB-zDF|qx8MH9?ZThy`G9m|I*)1| zOf)}-&&St{+&QsvXDB5XMu#>q2bF<7M#5zcyF0Pl$@()aOjbsT#jmw0i$FPEd!8-( zXnri_STNJ=bdyB%viRtzJ8~6wlE(B3`?Ol#$&0{oW|W{{?_DBDi-p6a+uB(-S5~t1 zx~L0y8H4?d!-=H=Ja|t6ZXi1j?`W^$tNcB>RZD0WE7LEln-N|numtU|RWnn~L^0yk zM$1GAbbE$8j4}yjS!D?mOp9xmj9ki#puX@8t_daY{3B-`tUMlQP7q)=-<}8aJ8LKw^t)8J#?Ze8RX^JGHiXFWSeFr}O zQPtxj3`8CrfuQVn%BY4mQfCTF%3HcIFsX{OBky^Yd0V(j;`Qt5!4nmfv^A%RyR$ajC>!eee;C=Z)*Uwbe zjh(|V@0@dus(W&{B*!E=Z2jFl`3W90v%lx0#_>AU_efo&gYmXTPl@!!s!AShhFXwU^jCwr5znn3?G4w^x}F zQ~eR3@>8>gni-g3xyuvietw?7%~JtyxOpsMv76^27VV4x9_`-8-ZoBw(g#5I#tsZk zGT&B1fJz9*k3**aIZyIW<&_R{O}n>}7U=C6M@wE-t_ujR=q3C@ayvW%ZdE9wrC-^+A-DKRHb2ZB5Rkj8E!=c z1BWRLfoRY&&F$lm{p%9_E8@fn^{uO1q6hj}!H&;M2zjWq8T={M3(JVQ^hJs5tlfF% z#Ajj^>bRYjaTmKWeH`P|7@Ke~d{0b#za``q9I)jT)aHU;So!fOzH)>}GCO^u0m9bJ zkl>KA5&&NK>;(Lypko^z7&u6NaMlfj|6eKkA^t)T@Vmk?aAp*>S6e@v(?)oxaQQ}I z-g_eUPwV}*Lt5ni6(6%8nO6=Zy$$67WM0Cm6=(pki1!RYH-qPe?r5|@$Cp(LuMq-*JceZjwZ|K^6!rNbjHGVkC zGsxMBA32At6m`HLGqv*7WAfM=OC_Sle{WtctEv&M#*>f0^r6+weP}<$yQNpuk~sHN zN3M~C@#Whb484p`G5-6h4Tph;e7^PdGjD4es86RkAweXf!F`0+T7{TDI0RFS9OdeN zi##rZ+~V8Ff#cAf9)Qx~2(Hy+uBSQIJhqt^rcCWvMTn?oaES4cGnHh@E!WM6+E1Ds z>dPEJ;C)|+Au+Z~|u?(o0)?*1v?JVlz#qIK&Zrn%ZS^37diz-x5+vh=Mid;9FE zMns3Qm>IT{nd8A_)G{B^d(2cg!*-?UR4i}bA*I~|%u5j6Z=^7a>jqfT0u2i?qH%?I zJ@uBlnkE%mGc;hYFUcP6?(+eaP**A^1!SsG|n9>eaqnX;Boisr0-fQ%u2& zM``Cue$D4+o`dwn?-kgQI+zSqf2mCx(xV>MD-;U$&5OoPZN8~j*khFiqYlpCwxoTJ z+KG1QRu~G-Qt4{tL@&$0$2YZ&H+?ZV%zQTp+p1h>}{!opBx*P*OtvjwQ)f!06h<(?@a#{&=RILI# z`vvE6`>_V*TN1muNZ6BfJ=5mcNK^ikW`pNRbKejGDIqQ>aC0e4`rljhy;@Y&iYwmQ zW$0<1z*FU=9XP=0i86brhx6fLgYu-$CdobOip|JJI$`Ug${B{$y3sJ#aR<+C3pWR$ zgA|Q8S_xK~&Rn|U@EFKNj|u4C4&V`EqeN4mQ>Ne(5?br*$Jj>Mke3)osf4nW;Z<3KUr^B6`-by5n;ta; z=fv^UU`I3&=AAxKi#UCrP)3L{tWJ<;xKt4h4bQ@zyNOrsGD(nZExZ&o+i@C06vQR; z7}PgMERRpLvU!En`1{M`NjiR5k{){2;?_>j1ZMkp4mO={EB44lj#A7naP(5LnjyNd z;V7CE0+FgbWamV_3cD9YJL|`f9#hTwPg)z;pCdM)ZRH{96tKh&%r))kNntk?Jo%ok zXh|Gk#<_gkv$0OLJARhF&o<15Vj)n*m*<6yJ~!sHH?57FNz3pftu=Uv zxLunjsJ(3TzGhkgu46P<2e0{zD1vrE7+SNDx_GK{V^=}^#g@lDl?usVIn?v>hmRG) ztqULsl^-_TRs%?WpcilJ0e_42|51?t9U35FfP@nO`-8jOg$4)_Gg-y^Vc`}bU4Ad! z1WG)ZOz3ybG6a!3xFp>T#l_9^jyPyaFB6HhUiJ)N_TvQj| zkwpy|o)O|!;7WImw8aFJ_g*sxvx3jmdB5Z*_R-v_RHDi|S!j4-!`ay{h8Ra<+(sIs zi!mcM^=+8;+Do#xgnv$ICfq~zF-(vT2p}iVhdp?HNu!!b7K246l1gMLMp%7pEHdKft(F-SQn5tsaYbPhQ1Z4ptXMu)vQRE$8I2idUHVztOmUUz zSTnbxO`of)d-$vyfyb0*lPcwVl&jUK#qS==2Ip*?h}0gyj5U`ZL#n%SSt?fP7Jfe! ziB>KCK>FMb7WdEH5_PnL{{iDbH8z|xpIG+F+0>JWnAlff2x=njy+d=fkOxX;Cp4WZ+?oq1&@3c z&CJ>-pEr8PNd1(c5whk-TIh>W_HAgXOpj!js9d{-@11F>iaZL)?+VE{b@9V z7GwgiyuiX>wcZC%p~htI&tcj;hcBwDUzSe8g>yOVdJ-6Z{H|=xQPp}uRc1rstA=(( z=>DRb_tu?Z>6;jt+zeU)8%zgV0CuE*SLpnU69WgB%)tRBbFd#w=E(4C3oBTYqE}%n z+820xKr{Ych33Yg{Z}Yp-*ExntgIj0Qa^dme;xi;-NrvTjuJ$Sp=BWt^$P#PI_*;% z)SS}Kl+gi&M?>F;xv5mN;ZHoK3ov3>ba-njsC&&MSPY^9uOkH8?e?(Q&I#t1DZx$QO;5apN|5VP!{|>MH z4eQh-BlZ;)QdOS!c)O)=n+|&{=9Ox4u%pGqex@V>?KPb3bgK4nXgGV9^K*aVj1Mao zusss5nB!T^NjLn5Szcr|qIse0aATz;JhIJLJrgHeGDq?pF| zic4d` zHZ`YIl{PShPSt=Ar>%}ErLsKA=Pe0UF({3G0ul*!(i8cVg8+wM3u%?B@E3L<&N`Px5u=Hb(HKDT7jUo5^8CnkV!>+ z6z>LV-QVw9`E{M?8*h2iM{fz%oxLHP)!lz9YgA|6a=1@q2G0SF>CXA8K+VE+A5~P_ zd*UI)Tgjogx9vtW#whb1Yw)awt!N17mWS>{ddP%lA$SxP=3zN?I-nIFvnVr=ZBj}W z+fUmQL4ZM@>%jbt-+@*HArptZiuPZy$UZo_Hs(KNhgy zDH+X1SLJX{0T=p;jAm{-R~nF)VOAqFWb~Qr8XP}sk^kQr;Jq&xUo|71eVWlZS;`?W zfTCxjOWiElb^ot*r}D%MQqp{2{uuS?2t9W@EKHo;Q2@uAfQL=10U@%!d3vX*EOUlY zNc#g7Fk!RiMQ3L2>0nIUhHCHiL+VpyKj)80WbSl-9+7az0n7E?$s_G%uzg%xW+h@Pm8+arTS3-d`=lEk<1^m(eY92~KdJ~m?1p&<2%Kf-< zGp+Lf{O^6&T>Ecba)8bTDCzwN2fc+bAb|kqVZppWK|z{02iZQqH0!N24ljA?a4p(M z0{bB38;)Y{dBDtJ>A|DG2wvCKA}Cz555@HBnlR+Tjk<}i$FuTZFDN0_59EM}dS&Lt$Pi=RUmgvC@< zlQl_Mi0mB~RK_q>UrIfH^YE!M`YW%LLA%IN%%@QBZ)8Wp2w~o0Wvr6)U3#w|H+$#6 zb{J6|+o7ZLi8{9XqX&|(Ju5>JfzOr5XlzREtYGz~_PvWIHx%lB87%vAfcaf2kS0|m z#*SHCvRp+vJ8MAQfx-&=L)!8aD57md6>WtmuD8WJyJ>_y7U;&?8T{0JsBpby!Bh!OjCKzDwH6aVQO1#O3oC`{h(W_*#G^=aIH(9s$go1I5U{xlpy`o8CVoC~h%U0SAbhmx zAHx!bc%>kEMwfCOOxhqh1tXF@mtCKzGK=RXpBAbr6yTYiN;zg#GK9zwNiMQgU z<@l91q(ehVEpy7yvWlH^g{Ah^d|^%Wtj$brq6FKIWH97c3kAFcFxmpZXd~{778+DZ z!A_af>;9632W<7(AH%~>YC1He=L`xAKtIFLz}E6cEQ%Q(@Kd*=_u#_P5*vO0ti-ISTe9jvOixY|bzXyDh8 zqMX7Lry{KV;FlSNXOA1GXxOf4d8Tfy;26ZiC^TCL=CA?(jAx_7e>lELdM6!DOgf;n zi7)nQK0k!3hGKZoZhWD}0OI$e0zyZDB`;%P9 zOguN+Knj2|j^(Ey7&z#!S75(hf&Y31@$1zCCKML+qkh*&t!B+1Q zeF|OJ4ETo{xpSIgSd=z31bBLIZ8Fbm}P`Z z2SZlW2`ppiA{Fm0O6k`Gz739e1=mfnfW#g@v{$_?auqq|a;>qu1WDr3GKto6=HS<$Pd}9Bm(a`Tg@K)< ziR_LMYx=rq$G1#{R;o7DZ{L}x%Gi>xLXNn#@Cvh)TgkNUtdF^JOXXd4HV@s~SU42- zPhG_$&}p#bEb9r5A)o7XKE^)Q{*yibO#1%8o(=R-|MbiJ&o!{S)b6Hj`5U(njBx)x z{LjAJKiP9`AH&;~PkWaBjazyKoNtAdA-5@By<&s(VM_LB(30+H%NoR`nRb_jSk*dQ zo3ly#@;wSP9b};~DCR3^VNrtUGjvyxt1(06i1O{(;S$D1Z=_ef<=Cf(%vBQRb07-f zxV-cDX;P4AaU7w~D8o#N!^G0OKFMWCS4$!$Eg5w4l)^8Kb*BNdTZ;UT`>U62p|5I#d2PmD7@5IW#^i<)~_o_G_e)1lCt?IB%|eZ zKfH*A%YVB)TU}yN@Pd6owS2liF9E*BBjIz2_NOIyYtJa3^cWQp2AxALH?D>GS!|Apep{2@9L z>qN{Z?@o=X7Ol+N^=fEE1sd&_C9p4dY}O@=!py>UKNqd@4vl#Y?W(=U<<3MRfh?C> zKUYmj%_xR#7UH@-Q|5_3P-rks->{3PEISfQ<$0%knWS-&8+=LMI|PO`2Bl1Zli2Id ziQsgJm{q!}d}*tJG;E88`KgxNx9u}XWy4UZL6g_o8Q7kpYUb1s0ss1pIub9h03UxK zNiU1|6V5G0reXMCdZlM<*O|H!Im4Q`}elUB2qv73b4;?Ise~LQ*BM&!EaD%pEVIsu_ z3WT>+9S$ZgR&I8V7dI!^IDop&&lCSY+~z;^D_c&TPgch~;PnCa%~*Y-$E1%49YEc7 z&()3I^bV+-6-2By2(A!ICQT>3Y)H_UO7f7L@OeV}aCE(qsfiy3H%}sFm-Y$y`?&7B zuSpcU`LG~yzAp+>K2!HDvO{lKKYKdx@04h!01{E8rW1}TYa8h&tFxgZB3;v#FK63nmJ+8%nX$9;Ai`P7PZsF z(KQxPUJmyXY!V#b(^+_z#b=nMafJOfpf?0dggSx60gU-8HD!+(*lLZgh&w073o_%t zPyBPz56kzSz&Ag`>VKA5MK}!gV)i)dgR(=yw=+LnBj>8t*ekZrEo<^hD^)8FFDC>d zAU|uEEX5!QHC%Yda>u+h_jnuHdEXM#{C4DsvGi|*af2Oo*F;k-~`FVwo0;4CD!CCrbIyu#ku21<8ccmvX7}qP- zwY^yu)npR!g=p}jEy^>p-r91{w}K$qC*xO44Ba0^k5@t+E)ND8hW*tBppdnjyxHqC zjpoF*6U6tkGcc}7-spyMKbPUgY^cynxvu-)>{5R3N@_C{xxw1gABP4tpM5&P&mDP$ zc=?xEj(bI|pJER-Ifz5c8?BGI#sXh-fa#n|b)sX@2g@j!A!A(__;e#ngwM@%Q$__) zT3L^SX>zB34=akT$w5>1M7Kcn^g_W4lJ1hpnbjo}o`+FAQgedi+z2M_I)RmDP{H3~ z9sb~_-8+5m!I&zg?c>ZxqCb8vK!lC7*6U!?(xN`c=Fcxsj(FTK{ul-=7M*b}k>Evx z(h&QjaxLp;noHFCWK_1QwMFmW7*gUp(NQ|G2UF#lq@VJ9Bb)U_w(kuGSBh9GYZUv0 z8izu! z*;kH7>6%DEl$hv|DoOMBJS*|aj>YDEYM1SoAmfMo%ShE7QaL(NCvnKoG)xo)4LvsX zyT$|bufHw4M)JzHs%40Kg)HfgYE(8>}D29kgt{Ex^0hlV2~p`a*2ENbOo zdB+e1bQS?t0XqYIW-2Din|Fbu5#9aFkN5r*iIBg6^oa=qZvS?B#|D)3ZsypSSa14? ztlW2p%mBI5i~s7|`KNSo5~~jXDLKt}Tt(j^;kg^vZv3}O?s(~k^(Y!IKT<>ocwtbQ z;xRYntC5hv#jsc|Nf;gmwL5`-KG{{TYYr45C#q@G}KJ?E_joTrve zjApF*Dp4gStzme(UgF(%&h0+}++j!R;n34u%-TNXF~k^>lV6HR(J3zVXiPX7& zWrAn;>y*y&a>~Jgm$WP)mh~hyDsgV5oaklzYu^(W-HvVI6CetO?47fgBy{-g-aLz5 zIJN1h#Y9waCK}K5X9VN+q~Jf2t%}v@DsJ*t(@K=OpC)GlnXQ0! z;rmfteD*;p6AVS%@c6kcLajch?*33dA(P}pm0@z8dAujFuh~mHyQOU!1JG`5od_W3 zw7Rh>otxCp#Lz_VmW=I}$iQF9G?1Tx%x@Af`nDeiFI9NjH=}2@K=fUDQVrZM<-Wn+ z)N4F_?^(Q<;7?rO0|10;YXAs)+Y&zmw8D)I0GDI?(;YygK`ZE(1CT`hUswh-6d{>s zGQu)9xtx@V1wdt}&rHiiedh*9e|!&^M*CL^V7HzCfWrX84!2)7p5Ued07x0%DOmph za-aW{|3$1TMt+15i<_l4fmNr{mr$ ziG-EMw^RIEyohjFo&r;1$unV2PD`*lg6^$53mwDcaploL)g>Femf)Yk<$?{*kbX$$^@vly)DSFFkcydiQs zaJA}Xbb7e+$~}*pH#9nu%0vW z)#@rCNabTZqD9|`Dw`Ug8kravz zQ6)o(IJSCWKdc@rt?rjyH9L~>vtioEoyYWBn7n>6dp;}};GV_$h(VoD0L4>p2;0Vt zb~`tyj#>SYsn|lhi|RNrZrOope4%Z#^3#u!DNV>1Kb==cf z*rhGJFvizDNxWm@aNtYIsp#KFwq$x*{K@KSC4^jj)f=}W;WE0`jq{~2D{vEF*A?g@ zn=)Xq9pDY}U-pyL;l8KxZO6MFrq$ieehCv1Z}bKobkG>eRFA{~+#?{!(zDC=pdg!m z?I?#FSJZr2;Bx4VPvr1#}`BsBu5-+nZT00OkLtl+a5UD#6#Z0t1YHN<{Ku zdOaB!Q0-cMw1diE!fPH=aal<4(%tVZAtHJaHkrl6ew`h0(89qa2lquj_pkxFt-CR zjCZ3Oz+}x&Pcp+ycyj|5=y;EF0kDZ$>x(Rn!{}=o@VgK$qjc_HO<~ zvzP0^RYiL2N7v#qiATe23++5qh5NP^1|VVqJ{O6UW`&ZC<`A#}npg+V{V$lx*%sMU zlyQ9&HkhUg4r1-w<%m=ym)cU<^1?p4C&}j~#bOKKWgRiWq}Gs8 zA*7+#@+xFXL7BLnnMZWdNQkU%*P(rRWPZC0;eWCc=;{1oB>27fpzxTyps;{EDFLu_0P&VTlM;wA-|&mW!bDOAMjg=UgW_O< z1GEOWWMlVFKKOax_j*phC=i4M0QQ4_3h^OS4@TFU1S173eS*ho_PjQsn!^2&i9(pWI;${Coh&J&%bQD%xkL+CaFQa z3bSZ1<|9huV0j6fr1gve2q&CG~_Rm)cO1d~8nl60atxB%DR*=hXU^@e%&zN52GK;+$0oDNzGDeKV=E{I4SqpvO&D0|y~7 zmqb%aArVL+s@axJP*%`R4VgMaO>4f<+ls_If$7l^WhtZ-%)Sg*cGIW>w)J|gPYaDF zV2JtC+Crafb71b{m0$^xL!tSGQRsXg)6Lqn1BdZ~oey*kB^vf%AEAILy?dd6m2A0M%7H-cZ>ERBv3d&KH}i4a_gH7(>W1 z)eo;iGQvl~LfKMWw7*3nfQ>`IVBCdxFHmy8w-W!&X6CmA+o(@_h&bsY;CCN=^_IPw z%#Va10<}15XGGq5$FmqWfWDZkHI>5IHf?G7IAdYN2Z*fiYGf6jHvaH z89d&eS!6~sXq`$R?XLS=oZAnN>P}P+_pqz1U^ce~1Y^0|l z=Ff8=zG@B%sfPIYN4E3IoY4~a$j(rZzw;t5W_mi`CCo%0g}O$iu;5?jslPZh_M|Jm zO4jI;Ju(%>V?qst#1YQIWx26hE_JGgj9h}ViIY-P{VLtquY|Sl$;QSDyBZ5K32O~) z$2MU(s0A4Pqr3rsl(mJNxukH7ifi-H_-n}97Vz|#LK6>$O}fdt&wH?A&(IX%< zfg@pAuQUUK$i0&b*b0lpj$LQ@_`A!Ta)g!U%aE&=0Fo+xmXCYLd;Fuz8su-N-)gHB zhF6nCf)5$EMZtc5GhyM#h@?ZZR|GmFF)ZhqW}ubky^?b@#fJRW%i;vHQ&JoBMGoqX z^9O+i#Oy4r%?;>(m930_r7qx(K;*Cm9Px|0=z)&toW12>XofZr_ZaTIn^)g?Q2bvw zZTRnHFu*kZ@4+;Yy9?b4Q4x41D0{0wO$=b3fi1`Cg#GG9UPq(GL<`9$=YX>mn0`z1}7!@ zrv-{F+?CI(Q?DvEmN&u}bjpSo9thDwnItT=7J;;AIzj99*JaX>YWlWymTW}#!hG9h zc6&>+UbN@*D!$2BNAtzYD3Ux6gq?E?UcVHG!$p20gQIuB>QrSbg{NyDpw?7T&_@e5 z-RjfO+plZ5)BP5q)}Is(P^ID^Lp>#sc$GQm2(9;g9d3YI2%;s7_9?y8W2bVpWOQgUbj)Pmtl+Dd3~amxqpL zL!QiRzsCvCW1~kqOFO!|Mya-jYO`v`V#D1ac7@8v0EO-p?J9;&PKlNN8^ z0**fnjsEQq+}mIMoB~4F#?Pvm{ZxBcmx|22-2HA>j;o!k!<TC>L!nUh{n)KriK?)PgPJE_>6c z1>3B6wpd@Y&jhv?$0bM*0YgNhEU4es7WVZMB>c-O)w4o_jQM7C9aYA&7#G_}9Mn9w z#b-Rep84wIWWqY5oZ?OIF^(#(shl8tDaEUW2D2bP&a_^#n8kEd$Z!k?SGXJVHmxBB z+r`CjTjM-OSg*{x=pm%raFKAtW@S4#j^ZNA_cx&Y+MS?yw7=m}2dYWhumc|>Rn9IR zYJ0#vLOCm=XXCll&gS4=VZI47H^V^aoPPsx(Ym?(50DGP4}1#)F_rmE znaPeAV9?NIpl1G|8vuufe}i;k=H}-9iFCQSz^|GVz%6}OlcKqI`F~ZEBBr{zGWAVu ziW?|Pv#>F9vNN&YqOAc;4sgiE49uhgsF(klkM&RPsN|Vs0jgi+W)?9t2Btm@t>j26 z+|y^FJ06ZXMs?0l+Ux{-jN4`uXlFI+9pl-ff^kz`p*=z*QmZ5UutJVbSm9X^;#NOk zCJDX|2LHJz=LtE8yM1&<$^+`E0Jv}dPASg^m)l=YnCch#qWi_D#j(g*@%1zs!Y^I4 z)Jwc`43xmRY|C#6%rau^N^7>k(XOZ8pz95HG<+GoSmr!#prFA!o?Q8X8vK+oTek9( z_z)z^^PtO0eJRA{cxZE3e24gK-iq==J2r`~p^)|XSR3@0-=&;C&KLd-?&WvN_k7uN1jXa+ zWMIRCEauY;av018>pz*n?LY%hQkYT_)0#rUD_57iXK@oaG2!P>M18EUMD@aA4av`* z;E_D+TeY=2khx+`xa@(KGFIsF@Is3}t1X$<;M*UvJjOtY_JaTVIHnAx2x)?GjtD$V znU1ixDG^sVW(!*;muS#U8JRH&0_KHJjpZc4qc7vBBjzreF8Ju3OT$u8JO;cw^L%e} zS7LD6YjE0IG}W4}$##u#`cb1Es)N&8F%1*e;ug=n_&!pY|1kH;#k0dDfmOK?wY*?K z&^)S7Y3|Cx2kt@e>yXWfc#^KeHC`7+&Eyd&jF2zeq?`kZLU3`PJ;Fn(jFPOxA7Chb zXx*oMrJ3lsp&H)#%9|at*z<>u%Lk8xcwC>-G1I&WDKBVe zHp_Q%^r5UR_7p^Tu=QM}$rV8Bx*eoj1m}xw=sFUje0_jEQYnmiv^ji6$f!BfZzoXN z3{w7-_DN;&7aqy?^eM|3N!z%O2=^XT4KI_kL#HKI_sUz$K=*~!sO@A`^py0+ z5N9(}DXY9#4#7(-N=1M_fMw+-<%W%8I8<E|H!RHaX}vJe;7>64mQ7%7u) z7EUW-H1oFIb?}&mV#U+wnbzxiHdt)PJUBAP?~ly!r6JpOS6jBSzb{v5fwQcL4UL;( zo!f9Z-n9@lK3Ub!kH2KUypJCW>E#}ZBxky?#moNuH#SFOH4z*Gdl+4`b8=V}aZ<8; z6)~!>Al>Lm#z0y@jWRV~=BgijC*2Q6h?*%BmNOi1a|GWq&8OkQiE~6S3(`4lKK|-> zX-zvz&3gh%s3wRXti<>n4?lyUrWwi<)T9>lU5#H#AQBu`wBq{a=Ttt5W(CTf zu_Erm&L>ieMU~Z4QzsL)Gx*IGEe2Y<0qit}j9-td4E9(j3pC|1)Q2I2h6=S<& zq4ixHTXZ^`+ZntP+XS1;7 zC=pyG&osWTAjT=;c!~QfzA4mCn0#>+0NSaNlTbmXNLFV`K&-q1sw;ps3Nz!-Z>bpW zaD|)Z3HyF_;ycW+nk~jMA&e;>>mf1j)RFeWgrj!0r+>7j#& z(N_PVQvy|f;O(PYrEp~rNDZ88;q_wW_Q%jUo4W! z*4EP;oTZ9Hc@l?OA+a@{Ven!m;>bcIRwh~*1j}pjsz6Xtv>EC!ziwD?Xu!?)9Jj@) z>I7$IM{#z}T-acGgBeLwe2DTWZabdEjV4@S_-~y-le3c77x3KLKykTRuW%-?PAp|eAdLx?lRq^^%2bT|3dJtG(cl%u!I zqxWijVZU~1Q0zdB4=9&G;M}Y6LDJcyDn1u?)dD^N1mw>uWB*=_j~mcz1{f>YIR8@P z)A^6q_^_BT{!kKxHnsxl)&Hx#uYiiO?baTK?nauS8;0)g5+nr)>5v8y5D7t2O1c~A zE=5W@C8SkaNi!hnjuFT!xMWF;&(A5r2a6aSO_8ZER-7;hf*_J3rpV@q z%sH&+?kPEyGewx`PxwldZ;Y7kLnn;IRL(r7hEPN6Rm{|hRWOmF3Qm{I{dp1`>Z?H9 zDM)_8Xd2_G?u($112*O-CEh+lH%-{mr1f{cV@S%62f?RGnRdfBI%hQxmSN_gjZ zb0z%dCrb6vcdp|dXbOs)WeD*4&2gxNXNO!*>M*g&Cwd?E6MsDGz~Ui~72F2JKG^BS z(;`gTgOh5cawCb`IH|I-nG=W?ViBI(8osPogXepa; zOCCwJx~%LG?#PTKg%DgHWde?8%y-Jg;MZ;^BymyHnm6LzK#wh_cS)IW*uf?**bYor z^4`YSUW1g{z1ZD0PTN&k$d?GFXHqgM7D&RwKj>b z9Bdsi>nSduRo{nT6LeO-VQ+ktP+jyLV%HfGNBsO{3;$YH*}W}z`GTzXkK&n=s_1Pe ztP)muBWLe4Zt7)Au4iDCfx&VXNAzy34gkBUkB1mJg z_2XtC^$dRko$i6f?L4 zwf5_FZG{H03^kwf-uz~tctm@qy5Dpg)kTVrmV%D6J`N|NxoB#MiQQ7~6j`58mn9Ja z851>jq?oDyVVtor3#z*H@J!pO3=AuYSK6!tk#Y!yj5+GNe4BGjZWgAfga@t5X&oWP ze(!Il?~us7PZ#H@gG1hSXAF$fUTSxK(C*&!AcP;{*MOHuSC;loh{lr7$BWGOt;gZi zr-6-K6+-PwO+~;dJZnL3|*+(y;QQtD#Vf^NOS#8=`+)Bhbzd`ey z_t>09c4LW$1L2u@6WB7lEJ1K~R8^-2yt>|;r1>5H^O%7I7B?>>d5o&h<+7W^ z`C9Q&U|N(d{8pFx;>hq*am8iKe#52^ww=&%<%HO)=pWh7l29vaORLL5bO2>yZtiwv z`~QHo{90;YdjYe*69@>F{xJQ)CHizWsNyM+s2;mzva}Db+b|cAhU*E$KLrE-s5u3w zHGZ;f{#BLgFYwAAXUGGhLL@GV<}YN0$Y}rc4K4x%|Fk0ge^;8n^Xt0?R$M-Qd)v6e z%F3BPx8f((J4mZg=fu=L9?NZ+jY3*sWSuWw*->8=Ih>eVD4{Dj_AYipc-ECaS8+gv z_VJNoo(2y8_MU>BQ?$2fU2(oqdv3t7s>!Y9z(EpT-AyBt{Jg{tgr^5r{}Ole7D}Ro1l3J*;~+l?wR{i#kPk$P zI^%2~4M;Uuyb}kB5eRavT!y*faP_mC#`L_jW)002_=2F?a4Xm~jJ`NuJOqNX!Ps8( z7WKjP?z?>`1^mS*X0KZ;4B`UXvS`VJ42acGAvgmPjrORw_#2ddFj`ztSpM0s|EGoN zm7?v|u*WTOFmDs-h>^fMre@6Te~K~wG+cpBP6_=OwAAuwm?AAp`4|Z zJ7%&hY9Zuw6UWkN3*Gaa#x{@OIY~d2sZF0&=1^*gUXx;psCFNkUDEJynpmNXg_+R` zN~SS847C{ekjgh$z+GvbLfw<@PQ~mfwWKA-VNA4hyYmVAP3U1J2LW}@>Y_OTSAPpJ zNv6ngpJ5nB*j=O$Rx|{C_4rWS3v2+@G z+;F0`cIB<7UNM31U`oG*aLn$%bfhzgx|{w==>{@;O+UGmRWBla+o=B02IUJYoK)e| zmh@9!{S?!|PjW@H^p=@?d!WaUG$#v>*V%A$9;{I)URsvO#-^rj7fq>tdilRp9dQ!+ z7;y~n^c$~K9m%l0K3~cwcm8)3m*n{2(8Ho3OGrs+U$l$j_z6)%MMDIt2ro8spkLOe z0bP6HE{CX4SmRLjODN@ppcFN?~z}v0_3w zdxAx>tI_au{P#DD%N9En6mndzrE}(zKTy_LmLAtaxQoF;gMCC{t> z*|a)JPoIWwGH0S6+3Cd>80UbBN3$xvgQsH-y~i_k7>`F~o)nN+6^N|uOWQVOz3zu? zekzI!3Yb%rZ(X87SzG6OPN-aoj83iX1E(^5BY-fkXGT2MWpfBaM;O*mFbyS3N6NZH z$Ic_leWkWWXbNcT%#igw=lM(UP1+HrvaK>$s)lf)|8%xCAr+4u(<$WEl^GPnUB=?stOgGo_N3F-=5 z5E?$427oiW^ggY+&N-Il_|tAobSDJGJnsq(<;JCBor1^#Y|NxcA3jYr@oWZkmLA z4x%~nmuw3<8E0i=(sS}Ovzes7Yl=QQq;L>U5f#FDWuF9TWpqMmHUD8yg8PBxtsDC2 zXSx+gzdAu3pvphTK>AhuM>_W+Mt-3{Z00WP7S^`r#%6Zb_UsY>9LL(t!G-+~sHhn* zxKOf-V=t1suE2za#Ebv~5040i3B>(zH3w4{$DfzGmQ)!Hs#%)jqmR)#)ZXx0;T?EN zF4pvqmDksE(tmlzV;C1e-N+ztk70oD9Sjh@gE2vX12$X~wgU(y7^;y)hC-{$JekWvB% zIAis@l%>2h-ZEp*mNJ9Ia3s%+igCSSf=cad)I2;JMwiF%Zh|#t6P(<1^K32SOv-dw zVbb`RFf`^MJgeXoAzXUDk08#A>zzqh0pBtG6f!HxP7fYEq|i+IoNeNMk*&&IaUumN zP1BjhftMC5s?wf!rfvL~#m9ZV!qDGl>DiKx_7cknz3E_d!RGxCNF2}qj`$$8>^R{{X${1?cK=pEe>p!bfWz21+9hFjW_54 z%Qxz?z4AV2(IRXQvLm1JZ8(2cVtxkDh-~f5e%7H~wLMZ}b86^Z#@1|3}#h5-y^Iv$dy#{Z-fq zSoINcQ8Y{)TwPtvjBU-Yf!F06q%Wkp;HUXPy2k-!zlskr$T>hRcmA;Ue+m7I7Z1Yv zqg^1ti3PN%`UPRemXSvUKa5Kis+_+SC7}X3TBPmXC~ISXyJ{CrTw0=6iUTY&y@)JC1Wsl zk`}HTkk_TBLs0~Vz6ASzQ!*If{Pe^`ik2I!O%D@YBjm^=W?#9M8VvI&i;NQA0+P|Z<(>Z_@B_TgE*?KiGZ zU26CxXW$ji z+BMx*RQn0=LBYk;kOAsWu8NH>K?XniR-@vQ1F60H&VT>_Bz5_2K`(9sf=#tEbNx)fZLsNyJi(4? z9_o=|;;vXaNvYgD(;+0eO?5H%)N+-w<8jqD$%#x@5(4TS@268Rc4A=4s@VFhBxxjV zE2;%W2iIrhJMjD0zanBjQ&R|i&yir%yUtf6q-&lK%h_9-5K0|TFF~+aPF*E;#%DIpP=#uki zQ6N$ZvJi=%!d%vmaRbaiTpTU8ZuxhPeP8^&h>hcKU$S}TeUxYB z+tnu@)nWC34XdS?I#g|{`bZ5JlHIY1t#x(EYax=$VVEE1?&QNhV?V%NHkssf;-7{? zb1D|O<&B9rX9};s-V*E3#`w6kX69B!n{Z<(pQ3)>7bRW{n&OuBfCt|T)b=Y^yVyrr zb;CVTZpH(JP({3npH5Hk{L%O*dY|$6O!~2|bi9}s83c{k+HG;qs$!%FhJj3ZTIGtdwdL|5cvtU#XY0h->aa;LB z9B9lXy85t2EE6*#`-P3eiy%4&3ESX&weL2js0T3wBt(%_TPZ2MQ3o(+b3`JTqWsjo z?2%|A;4>1fiJQaW!sV*DduQcLWAJGnNLl?l95tyuQB{`vgak2yr*cyx?(rNHFPYJd z43bJsL-c4MZc}sLi*M#r6{Q(|qz`>$#h9}i+AxFNc!M=54VOmtsB>{DBf_UU($!9{ zYR&neWSa)7lpSy8oHbe2Nv>IPt`TN--)D>=l0)~-ST8ugM!nBI;hR(^5}iZne&hEH zh9dNFnLS)VvZ+@0NC`_}@>sL7hp3%v(=fpT#0i0B65~QaX!a+VT}|?MEdnZU(m9`4uBVW&%96kqdtl#%FYI>d1#^S=fMXRQ*-^T=%fYkU7mYup;xD=GxFL=$suEjz= zQsoR&L>WLd@aS}AG!y0sq_JSggDoPR`D5Ng>baXIzigXE$aydzobKt$(B7ruBFQl- zc*!(FEHWs*@pKy=KW;pa1;YM3kzrfr^h-l9h$T{T=GJ)X3a*utj8s@UDy6WJKKwi4 zjKqkUCaQGj!BUj|fgH;e2G@?1Nn&BR+xd^vO1mFAocqSFABWpC5k`@nD-cJi^Tn_W zgAE?Lq25|0=+-&r|N49|g-UbBv;yBw!yH!8P%*RWd4vK;mw&u_-`DKGK2EIx+Z*4J zU$MexxP#NNmFT>epB0bAVqa4Fqm~+|PD0!33}j>Bv(H)Cy1jJN|=O=`b~ zeuh4Y?JcJPvpY<@w>(>_&{Bm;ZToQ#+FdS1qL%@d z^q8+C4Vq{)(La$nA{gbqI)Qj;U9K_=K=GKfgNuWO>(9cqU%u2I4j_QF=KGQU`L(cs z4FCgB7YG*3{Yd{m+(6UefO!p&W+Nam1k^yD?bs3w{ieOI=p`A4vl4Du$GAd0+|+eL0jqfN^il z(S)l1ruqLgf6~*R5U}T7SCVQ&RqL{yy7l}-riN&K>KQBxP6zg zUvPJJf-`_f%xj$eb>%=znOY+!S5~0w9{_MR{l%$q z*;@)gMPIhtjs6vo=mu<@cHogL{^66r{5I!7{T^SlaHM5^mcpZ;QE9SjcmTEZb}kq2 zWOHXnXMo28fEqfx0hHW8zb88r`9Dbe(FlGWd`X!ESVR}+{KPuLqLFH{0&N1#0e9vH zw}$!!wZ>KJs7tOjC_fO40E#L(FZh&z7w9F_TXV@9LrF zEiU?4i4GfTzaS>jEeGNmKNvgG6!jCCQLss_-oX<2xaly`LnYTg@CJtC*)-u2RWmX< zv8Z0v@;x+7&qq=>8$$9PPG*b52M+AgakJVyOG_pmhAtZ1gsU(LgLpq^6N!5~BAYBE z?B3vzHH>bS?M}{kGp0RP6YtJHSA5R@n~Hx)X8cp}0f6#Fr_g^p#s7P{<07LO5~DSj z=#?4${p^o&D|=R2cj3vvxz#DUd*q?z+@+`JuczgSwyh(3A*Yl@h(ucz`X%PwMq6O7 zhhD5C6E9!*z9xK35O88qfz+i*?YBJmLP6|M)t*nDfgiK8dDY7CyFh}#gZuGmqx?A4;VSl>6*_$iRKGy#; z_X%b3Muc;wSndbtot;1xo47kt(gj%fq$@BworzyQA}~Z3K|1R-=x#|>p<>6~UTDR1 zn{EyF^4oKEOm{dVj+i#$>8f(z_G*?_UDOkpoJw;~&j=KSH6#j?&L024wev43ev2-I z7vzzdNpT<&K_9G6Z3!kr1#+8bKObCKMgI}H+Q-9=2fqLHKHF;PHM;&n6d~udJbd^?v z&qTxM)eMXYV|G5h(?>xn?=}arI7f&gBKO?JIlk}8%Sq3vJNLcdJsIV^#S1ua9}J2M z)!dTvWW!#P!~T$FF&s9oX>sDOwc+)eF@$8@p?YW$KA@Lf)cuKxeXmiQyQ%B#R(V3S zB!SJ`0peN@y>R^0DLnK;Peh$=Dt~xZ;S^dr5yI+1DX*TMVzWq$oR(CQH0bQiFcDjk z@Rx5~zHZBdr9`Um^bxpO_OCA$ALVMHcd@p#{|8NnSplp~puZbT(A5%;&BUKe8jk|^ zL9&V=4|R<@5q!<$1e~g$ya%YbBv)ki8o*Wm#CyOBQRluyuU^`sD8G*Sxe*rk+Qv)k z^3O!6mwY$^04)|b5Z?G7xT7u<7Xk6ohz0{>y_a8LVGv;@L2wOS9%GTVv=|v|0z{;+ zxn;>K0*J^2eWsN!0*^y=+H{5_Ph7H&%q7ps+dx(JE*R(Clq-a}Mbl1V1#e#rJtey& zI`}L<#u#xef99wqK2)E{?m9459{z#__9j!k@PP zgrPyM=ymx3zDzElXjOpw!sG)Y*uRGV`vU!4jI26%a$^V+aL;gq2kOK*hz7;y+ z!N>ECGeV4wX)}{CtK)Xu(Jsm74LB)M18^?t@~!t>2O5VUb z-9Goiv`7>?A;uzQ{b~zHg3T3?rV<)ZBwgV|vIj3sqdohu)b6%?o_rM-6q(R@mS6)D zo8xuo2^o`s;IL-ah=5btcgnA|4?i!?gCp(ZX=qt8$yo|ILZ0tzB_Xiap(v})W)JWY zm&-k24K?cE=2ixMCycSg9pU>ZUlWGVsq>I15XGY()T>@DdCnKPkVEb%qE>8*u!>(R zRwu(3%U9{WE8p(ZdH*aSTqctEInZX1SRC`pyuHBU{lk3l`-E{FYH}lOkUVTcfZ1_O z|7~UiMFr@z)A(A9?Jsv<3;tiGo1*Uc0U_kk1bWo z?)rq|{}?E4Ytu0mOt=e%6A{ZN07vmmRrL4VJhjKJFy$u?}|2L{i+*__{&UfJ|ZFV9RW zZ7zhd=;tRBo|B^3SFx{oc|-Q}(f1%f4;yqY%oFxwycfRJ1}a4f3tyKBJCDctpVA3` z-(^_b)>8;(nez~dNRJY3l28cjac8#Z?MooAN%2m6?CLb~r-B~6hj zqi@Pr16lehkR5Uy3IpD{w5VjclH8=eyE}kUl0jsgS z?Fj=WaDTh@x>?pO7*~v{Q67g(9aIDMrX(g$rQP2XF(e-){aVdhcf_aP)lYe|;wVXu z@JSo^EM@ z8cu%`YcsUy)Qp4;SAy>p*a*of`~T7O|1-65&E@9?rhX{k@)KT7|6tg)>y!OO9#Zbl zll^~n691Wg1Tq&u_5xV#fk_;QFkK9}fz$>-j`ZJlqrdaLOV0W0)-AvaOW8FGQD4O) zJ-#kBd7OcpwrQS`Q60`aakf626hnUdKDrj1IvlRIpw+Gx_=1t{_0n|a7i(Ash_4J4 ztM+pt%{Xl;T?&Rd3W$hZHg7X^W~F^?CB2w{2J%L+&6;b~YjgdG7O!^qfWdTv(*rhD z2oqAqgS}4jj%0NUa(TlgEQCm^#0B#R5(8=rp@uxpTRnkAS%v97Zn3ZPZR;gIkM|(( ze|(F!xF@7+r}nhNpS}$@KvyLFzH8kS*ibOavsIGU`IC*xyPXcu94?`b5uJO_1d7Ll zmZS1|w-5}a4sBDu}clGcEDxD^oZ>`ypCbmv9 z?PooHINmFfO%3D9uN8**g3U4;0>?L#iaK_Kay~M_gWDlM9t`0k`N%Du5$(9|YZxH) znsL+?2XEOpyaX#MJwUDTbG(C0M(AFjt?CK3AU?iq`yhq?9aagPEj3FCToKCR*wCVz zUTu}%o=?=$vnLeW&yy{Vkg`xnFP=6>XQh6dVAOC4%+Q#U!Z4UHee6W$>)Lm?2);M1 zcd1_tE-tngnTQ|Y{yze$7YW7tu2w+a(bWSWxOD#MZa@1Y&IZ2&*j$@{;*DJ?9g=n( z;~@7d_rvSI^+loYpTcbb+#lnzIRzXN8oVaJGUDpH7d?y!;GJU`w~kG*j_wb&>zEp4Z zmYng2VTivOI#O5lX9z64>AczX%#N<>VPo|SeHu#Ox*s3>*=HxGPwk}Zrr9^}(soEJ z$DU|`!4nF-19}UUM-H4By>EqrB??lT`ip1n9wJj@D?3NcFe9D55!M{C#4LDY5Kn~K zvE;m2I`W8&e&^XHR?D4Dq4GDr@7qS>;qG{P=N1a{yXBfhWC|E=Ja}UO(v7rW5k<_- zfv3Z^PS|)-j~S1u)FZy2_L42M{|GagYSky14|i}^1@|81Nb3OAZkFt!v~_BqF%Kfh zVZs;*d*fxp;d=Gm6_ppCGVm;Vb#BiN23a462I9cVwOHV~l{|RFP4mQmaIz>hia3Lk z#mBwgtYK;`f8V`Yt3P0rv%|eCC(`)+5Ryjer{Gikso zpFjZ=S9%35v@9N%Ruc1tMn}r&;4pJdThn21vj!AUXlCem9Qa&`)Xb$#IXXdv;N5W`3EZWCN5gpr)JOS zmPFZ1<7ZNyiX0OnPr?p73Vb}@2Zwk|ZSwrtINHukU`Ep9W_`KUq5xg&ORM@8|FI2E zOA!;xGTIgAwZ-L6WjKdQ%)%M#72=2$xtQBg z=>ByRucS)~{#7+^NZP&!JKT~hbw5yp&=Z9X znUpsp`upQhDy0z&HQM+6uxK}W{Xs}Kc~nBfwmySnEm)*|`s3*1Z%Y4gqf&IBxIX!nH5IRRS(94*o*8R(a^7U_0xS^IkQAGosvO+FQ{uSaNF})lCwx^ zfMGCY!}vbS>9nJ|s(V9|FmqU3;z9L@)f)(&x3a#`YS_vFj~@}=BsNmLMe~^AkiQN{ zu-)(YM*lNjgOQx6`y>lt^c$Y?65nNr5K8HjZninfy|2yi)4*A&d@66iA$4QvX_u#I zyb>eyX24AoB17S!gs40pn9a2Lb!TRzuda@h?TC#TGx2K#HN9X7aPt~ zt%);RoGXu2$T{3M`Fu+^G@br;?0R?$-4 zgRa~tj4Zw|4r;kJWTZ{|Blnca$EN|1Bn6^69NEfmGFk+MIp!s)h?pDq-chh2IDZNZ z##v^aHG*ef{tP=t$F=JFdQdX!1~=+|DbeMGZ`sq++jQT+d6=KjCT-7&Miccnh5+wk-Fq$s_@<0g~akZBI~B4V&yP$FbLjWNi$A*1Ie;oXilXqe+`WNlg$ zQIC=%+e(N#E%zL_M^9W#pY9M;6y(Y>9dF`%a<17qX7+xn-WnF5`ITLCNvq(UMdkE@ z(Ny(QU2fgnVpZEl3c}g@#Z&#y24ne+F%S_blw`5K;5Uaq(HBx=_Vd83vCdFXOHcs{ z5e!=6Y+m!WlUVg0FujvYZmt^Yq+L6KeKGTuz&<+QfRv%>G)nuqk%J)It3me= z)Cf%WoFdh15*!f%Byr3yvdWW150TnX4(#YZfFt|bYnl7jH+v{G`11yYrXKJ?vsI@Z zMs~$ZB|L9*PAKw()Ju$e1^Q^I_$%hQKw1UMqrN25L`+9G^*w9|oT-XT5+%b$$HCry zTl{$)-wnJxKUV}HzhnHwOuR5E0lidXRF5pk29#iKQq$~U^ZbBCa*MOHjxxRZl>?S^ WLMG(VGG1zJH>f(sOX)Tk@&5rX1>|@D literal 0 HcmV?d00001 diff --git a/datawave-qms-stack/templates/_helpers.tpl b/datawave-qms-stack/templates/_helpers.tpl new file mode 100644 index 0000000..9713615 --- /dev/null +++ b/datawave-qms-stack/templates/_helpers.tpl @@ -0,0 +1,23 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +*/}} +{{- define "datawave.stack.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). +*/}} +{{- define "datawave.stack.fullname" -}} +{{- $name := default .Chart.Name .Values.nameOverride -}} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "datawave.stack.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} +{{- end -}} diff --git a/datawave-qms-stack/templates/hdfs.yaml b/datawave-qms-stack/templates/hdfs.yaml new file mode 100644 index 0000000..2c78769 --- /dev/null +++ b/datawave-qms-stack/templates/hdfs.yaml @@ -0,0 +1,19 @@ +{{- if not .Values.charts.hadoop.enabled }} +{{- with .Values.external.hdfs.hosts }} +{{- range . }} +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ . }} + labels: + app: hdfs + chart: {{ include "datawave.stack.chart" $ }} + release: {{ $.Release.Name }} + app.kubernetes.io/component: {{ . }} +spec: + externalName: {{ . }} + type: ExternalName +{{- end }} +{{- end }} +{{- end }} \ No newline at end of file diff --git a/datawave-qms-stack/templates/yarn.yaml b/datawave-qms-stack/templates/yarn.yaml new file mode 100644 index 0000000..15a15fb --- /dev/null +++ b/datawave-qms-stack/templates/yarn.yaml @@ -0,0 +1,19 @@ +{{- if not .Values.charts.hadoop.enabled }} +{{- with .Values.external.yarn.hosts }} +{{- range . }} +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ . }} + labels: + app: yarn + chart: {{ include "datawave.stack.chart" $ }} + release: {{ $.Release.Name }} + app.kubernetes.io/component: {{ . }} +spec: + externalName: {{ . }} + type: ExternalName +{{- end }} +{{- end }} +{{- end }} diff --git a/datawave-qms-stack/templates/zookeeper.yaml b/datawave-qms-stack/templates/zookeeper.yaml new file mode 100644 index 0000000..83bf769 --- /dev/null +++ b/datawave-qms-stack/templates/zookeeper.yaml @@ -0,0 +1,24 @@ +{{- if not .Values.charts.zookeeper.enabled }} +{{- with .Values.external.zookeeper.hosts }} +{{- range . }} +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ . }} + labels: + app: zookeeper + chart: {{ include "datawave.stack.chart" $ }} + release: {{ $.Release.Name }} + app.kubernetes.io/component: zookeeper +spec: + externalName: {{ . }} + ports: + - name: zk + port: 2181 + protocol: TCP + targetPort: 2181 + type: ExternalName +{{- end }} +{{- end }} +{{- end }} \ No newline at end of file diff --git a/datawave-qms-stack/values-testing.yaml b/datawave-qms-stack/values-testing.yaml new file mode 100644 index 0000000..9e9294b --- /dev/null +++ b/datawave-qms-stack/values-testing.yaml @@ -0,0 +1,8 @@ +dwv-accumulo: + image: + tag: 2.1.3 + initContainer: + tag: 3.3.6 +dwv-hadoop: + image: + tag: 3.3.6 diff --git a/datawave-qms-stack/values.schema.json b/datawave-qms-stack/values.schema.json new file mode 100644 index 0000000..161c3c1 --- /dev/null +++ b/datawave-qms-stack/values.schema.json @@ -0,0 +1,88 @@ +{ + "$id": "https://code.nsa.org/datawave/schema", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "additionalProperties": true, + "description": "Schema for DataWave Helm values", + "properties": { + "charts": { + "properties": { + "hadoop": { + "properties": { + "enabled": { + "type": "boolean" + } + }, + "type": "object" + }, + "zookeeper": { + "properties": { + "enabled": { + "type": "boolean" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "dockerRegistry": { + "properties": { + "url": { + "type": "string" + } + }, + "type": "object" + }, + "external": { + "properties": { + "hdfs": { + "properties": { + "hosts": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "yarn": { + "properties": { + "hosts": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "zookeeper": { + "properties": { + "hosts": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "global": { + "properties": { + "accumuloConfigMap": { + "type": "string" + }, + "hadoopConfigMap": { + "type": "string" + } + }, + "type": "object" + } + }, + "title": "Helm Values Schema", + "type": "object" +} diff --git a/datawave-qms-stack/values.yaml b/datawave-qms-stack/values.yaml new file mode 100644 index 0000000..dfb8f9c --- /dev/null +++ b/datawave-qms-stack/values.yaml @@ -0,0 +1,27 @@ +###################################### +# Default Values for Docker Registry # +###################################### + +global: + hadoopConfigMap: dwv-hadoop-config + accumuloConfigMap: dwv-accumulo-config + +dockerRegistry: + url: ghcr.io/nationalsecurityagency/ +charts: + zookeeper: + enabled: true + hadoop: + enabled: true +external: + zookeeper: + hosts: + - zookeeper + hdfs: + hosts: + - hdfs-nn + - hdfs-dn + yarn: + hosts: + - yarn-rm + - yarn-nm \ No newline at end of file diff --git a/datawave-qms-umbrella/.schema.yaml b/datawave-qms-umbrella/.schema.yaml new file mode 100644 index 0000000..546b749 --- /dev/null +++ b/datawave-qms-umbrella/.schema.yaml @@ -0,0 +1,13 @@ +# Required +input: + - values.yaml + +draft: 2020 +indent: 4 +output: values.schema.json + +schemaRoot: + id: https://code.nsa.org/datawave/schema + title: Helm Values Schema + description: Schema for DataWave Helm values + additionalProperties: true diff --git a/datawave-qms-umbrella/Chart.lock b/datawave-qms-umbrella/Chart.lock new file mode 100644 index 0000000..03b34c0 --- /dev/null +++ b/datawave-qms-umbrella/Chart.lock @@ -0,0 +1,42 @@ +dependencies: +- name: dwv-audit + repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts + version: 1.0.0 +- name: dwv-authorization + repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts + version: 1.0.0 +- name: dwv-cache + repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts + version: 1.0.0 +- name: dwv-configuration + repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts + version: 1.0.0 +- name: dwv-dictionary + repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts + version: 1.0.0 +- name: dwv-executor + repository: file://../executor/ + version: 1.0.0-SNAPSHOT +- name: dwv-kafdrop + repository: file://../kafdrop + version: 1.0.0-SNAPSHOT +- name: dwv-kafka + repository: file://../kafka + version: 1.0.0-SNAPSHOT +- name: dwv-modification + repository: file://../modification + version: 1.0.0-SNAPSHOT +- name: dwv-mr-query + repository: file://../mr-query + version: 1.0.0-SNAPSHOT +- name: dwv-query + repository: file://../query + version: 1.0.0-SNAPSHOT +- name: dwv-query-metrics + repository: file://../query-metrics + version: 1.0.0-SNAPSHOT +- name: dwv-rabbitmq + repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts + version: 1.0.0 +digest: sha256:00d0cd83713ad19d971fd74c64b57032c24250c05f5ae25df1f6549261a99e4f +generated: "2024-10-08T10:51:03.152002577Z" diff --git a/datawave-qms-umbrella/Chart.yaml b/datawave-qms-umbrella/Chart.yaml new file mode 100644 index 0000000..4810478 --- /dev/null +++ b/datawave-qms-umbrella/Chart.yaml @@ -0,0 +1,57 @@ +##################################### +# DataWave Helm Chart Configuration # +##################################### + +apiVersion: v2 +name: datawave-qms-umbrella +type: application +version: 1.0.0-SNAPSHOT + +################################# +# Basic Metadata for this Chart # +################################# + +appVersion: 1.0.0 +description: Deploys The web stack of DataWave using Query Microservices +icon: https://code.nsa.gov/datawave/images/datawave-logo.png + +dependencies: + - name: dwv-audit + repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts + version: 1.0.0 + - name: dwv-authorization + repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts + version: 1.0.0 + - name: dwv-cache + repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts + version: 1.0.0 + - name: dwv-configuration + repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts + version: 1.0.0 + - name: dwv-dictionary + repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts + version: 1.0.0 + - name: dwv-executor + repository: file://../executor/ + version: 1.0.0-SNAPSHOT + - name: dwv-kafdrop + repository: file://../kafdrop + version: 1.0.0-SNAPSHOT + - name: dwv-kafka + repository: file://../kafka + version: 1.0.0-SNAPSHOT + - name: dwv-modification + repository: file://../modification + version: 1.0.0-SNAPSHOT + - name: dwv-mr-query + repository: file://../mr-query + version: 1.0.0-SNAPSHOT + - name: dwv-query + repository: file://../query + version: 1.0.0-SNAPSHOT + - name: dwv-query-metrics + repository: file://../query-metrics + version: 1.0.0-SNAPSHOT + - name: dwv-rabbitmq + repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts + version: 1.0.0 \ No newline at end of file diff --git a/datawave-qms-umbrella/README.md b/datawave-qms-umbrella/README.md new file mode 100644 index 0000000..19d864d --- /dev/null +++ b/datawave-qms-umbrella/README.md @@ -0,0 +1,3 @@ +# DataWave Web Helm Chart + +Manages All Helm Resources Required to Support a Deployment of DataWave Web diff --git a/datawave-qms-umbrella/values.schema.json b/datawave-qms-umbrella/values.schema.json new file mode 100644 index 0000000..0fde354 --- /dev/null +++ b/datawave-qms-umbrella/values.schema.json @@ -0,0 +1,74 @@ +{ + "$id": "https://code.nsa.org/datawave/schema", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "additionalProperties": true, + "description": "Schema for DataWave Helm values", + "properties": { + "dockerRegistry": { + "properties": { + "url": { + "type": "string" + } + }, + "type": "object" + }, + "global": { + "properties": { + "serviceDns": { + "properties": { + "accumuloManager": { + "properties": { + "name": { + "type": "string" + } + }, + "type": "object" + }, + "authorization": { + "properties": { + "name": { + "type": "string" + } + }, + "type": "object" + }, + "cache": { + "properties": { + "name": { + "type": "string" + }, + "port": { + "type": "integer" + } + }, + "type": "object" + }, + "configuration": { + "properties": { + "name": { + "type": "string" + }, + "port": { + "type": "integer" + } + }, + "type": "object" + }, + "rabbitmq": { + "properties": { + "name": { + "type": "string" + } + }, + "type": "object" + } + }, + "type": "object" + } + }, + "type": "object" + } + }, + "title": "Helm Values Schema", + "type": "object" +} diff --git a/datawave-qms-umbrella/values.yaml b/datawave-qms-umbrella/values.yaml new file mode 100644 index 0000000..7d7d890 --- /dev/null +++ b/datawave-qms-umbrella/values.yaml @@ -0,0 +1,22 @@ +global: + serviceDns: + accumuloManager: + name: accumulo-manager + authorization: + name: authorization + cache: + name: cache + port: 8080 + configuration: + name: configuration + port: 8888 + rabbitmq: + name: rabbitmq + + +###################################### +# Default Values for Docker Registry # +###################################### + +dockerRegistry: + url: ghcr.io/nationalsecurityagency/ diff --git a/executor/.gitignore b/executor/.gitignore new file mode 100644 index 0000000..79f2743 --- /dev/null +++ b/executor/.gitignore @@ -0,0 +1,5 @@ +############################### +# Ignores Helm Chart Archives # +############################### + +**.tgz diff --git a/executor/.helmignore b/executor/.helmignore new file mode 100644 index 0000000..aa06c2c --- /dev/null +++ b/executor/.helmignore @@ -0,0 +1,17 @@ +########################################### +# Ignores All File or Path Related to Git # +########################################### + +.git + +##################################### +# Ignores All Development Resources # +##################################### + +development/ +setup.sh + +############################ +# Ignores package Archives # +############################ +dwv-accumulo-microservice-*.tgz diff --git a/executor/Chart.lock b/executor/Chart.lock new file mode 100644 index 0000000..c7d3c8d --- /dev/null +++ b/executor/Chart.lock @@ -0,0 +1,6 @@ +dependencies: +- name: common-service-library + repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts + version: 0.0.2 +digest: sha256:9f6737e1bdb7c4772bf295ccb128a1d540237dd1b7770e0edbd185d1b17a1a31 +generated: "2024-10-04T18:58:14.981876411Z" diff --git a/executor/Chart.yaml b/executor/Chart.yaml new file mode 100644 index 0000000..6356828 --- /dev/null +++ b/executor/Chart.yaml @@ -0,0 +1,22 @@ +################################# +# Core Helm Chart Configuration # +################################# + +apiVersion: v2 +name: dwv-executor +type: application +version: 1.0.0-SNAPSHOT + +################################# +# Basic Metadata for this Chart # +################################# + +appVersion: 1.0.9 +description: Deploys a datawave query executor service +icon: https://code.nsa.gov/datawave/images/datawave-logo.png + +dependencies: + - name: common-service-library + repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts + version: 0.0.2 + diff --git a/executor/templates/accumulo-microservice-deployment.yaml b/executor/templates/accumulo-microservice-deployment.yaml new file mode 100644 index 0000000..194eb3e --- /dev/null +++ b/executor/templates/accumulo-microservice-deployment.yaml @@ -0,0 +1,19 @@ +{{- include "common-service-library.deployment" (list . "accumuloMicroservice.deployment") -}} +{{- define "accumuloMicroservice.deployment" -}} +#overrides go here +spec: + template: + spec: + initContainers: + - name: "{{ .Chart.Name }}-init-authorization" + image: "{{ .Values.global.initialization.image.name }}:{{ .Values.global.initialization.image.tag }}" + command: [ "sh", "-c", "until nc -z {{ .Values.global.serviceDns.authorization.name }} {{ .Values.global.serviceDns.authorization.port }}; do echo 'Waiting for Authorization...'; sleep 2; done" ] + + - name: "{{ .Chart.Name }}-init-cache" + image: "{{ .Values.global.initialization.image.name }}:{{ .Values.global.initialization.image.tag }}" + command: [ "sh", "-c", "until nc -z {{ .Values.global.serviceDns.cache.name }} {{ .Values.global.serviceDns.cache.port }}; do echo 'Waiting for Cache...'; sleep 2; done" ] + + - name: "{{ .Chart.Name }}-init-configuration" + image: "{{ .Values.global.initialization.image.name }}:{{ .Values.global.initialization.image.tag }}" + command: [ "sh", "-c", "until nc -z {{ .Values.global.serviceDns.configuration.name }} {{ .Values.global.serviceDns.configuration.port }}; do echo 'Waiting for Configuration...'; sleep 2; done" ] +{{- end -}} \ No newline at end of file diff --git a/executor/templates/accumulo-microservice-service.yaml b/executor/templates/accumulo-microservice-service.yaml new file mode 100644 index 0000000..2bcedaa --- /dev/null +++ b/executor/templates/accumulo-microservice-service.yaml @@ -0,0 +1,4 @@ +{{- include "common-service-library.service" (list . "accumuloMicroservice.service") -}} +{{- define "accumuloMicroservice.service" -}} +#overrides go here +{{- end -}} \ No newline at end of file diff --git a/executor/values.schema.json b/executor/values.schema.json new file mode 100644 index 0000000..068c816 --- /dev/null +++ b/executor/values.schema.json @@ -0,0 +1,206 @@ +{ + "$id": "https://code.nsa.org/datawave/schema", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "additionalProperties": true, + "description": "Schema for DataWave Helm values", + "properties": { + "args": { + "items": { + "type": "string" + }, + "type": "array" + }, + "global": { + "properties": { + "certSecretName": { + "type": "string" + }, + "dockerRegistry": { + "properties": { + "url": { + "type": "string" + } + }, + "type": "object" + }, + "initialization": { + "properties": { + "image": { + "properties": { + "name": { + "type": "string" + }, + "tag": { + "type": "number" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "pullSecrets": { + "items": { + "type": "string" + }, + "type": "array" + }, + "serviceDns": { + "properties": { + "authorization": { + "properties": { + "name": { + "type": "string" + } + }, + "type": "object" + }, + "cache": { + "properties": { + "name": { + "type": "string" + }, + "port": { + "type": "integer" + } + }, + "type": "object" + }, + "configuration": { + "properties": { + "name": { + "type": "string" + }, + "port": { + "type": "integer" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "volumes": { + "properties": { + "certificates": { + "properties": { + "destination": { + "type": "string" + }, + "name": { + "type": "string" + } + }, + "type": "object" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "image": { + "properties": { + "name": { + "type": "string" + }, + "pullPolicy": { + "type": "string" + }, + "tag": { + "type": "string" + } + }, + "type": "object" + }, + "livenessProbe": { + "properties": { + "delaySeconds": { + "type": "integer" + }, + "periodSeconds": { + "type": "integer" + }, + "port": { + "type": "integer" + }, + "scheme": { + "type": "string" + }, + "uri": { + "type": "string" + } + }, + "type": "object" + }, + "meta": { + "properties": { + "name": { + "type": "string" + } + }, + "type": "object" + }, + "ports": { + "properties": { + "http": { + "type": "integer" + }, + "https": { + "type": "integer" + } + }, + "type": "object" + }, + "readinessProbe": { + "properties": { + "delaySeconds": { + "type": "integer" + }, + "periodSeconds": { + "type": "integer" + }, + "port": { + "type": "integer" + }, + "scheme": { + "type": "string" + }, + "uri": { + "type": "string" + } + }, + "type": "object" + }, + "replication": { + "properties": { + "maxSurge": { + "type": "integer" + }, + "maxUnavailable": { + "type": "integer" + }, + "replicaCount": { + "type": "integer" + }, + "revisionHistoryLimit": { + "type": "integer" + } + }, + "type": "object" + }, + "restartPolicy": { + "type": "string" + }, + "service": { + "properties": { + "name": { + "type": "string" + } + }, + "type": "object" + } + }, + "title": "Helm Values Schema", + "type": "object" +} diff --git a/executor/values.yaml b/executor/values.yaml new file mode 100644 index 0000000..e71e1b7 --- /dev/null +++ b/executor/values.yaml @@ -0,0 +1,67 @@ +global: + dockerRegistry: + url: ghcr.io/nationalsecurityagency + volumes: + certificates: + name: certificates + destination: /data/certs + initialization: + image: + name: busybox + tag: 1.28 + certSecretName: certificates-secret + pullSecrets: + - dockerconfigjson-ghcr + serviceDns: + configuration: + name: configuration + port: 8888 + authorization: + name: authorization + cache: + name: cache + port: 8080 + + +####################################### +# Default Values for Audit Deployment # +####################################### +image: + name: datawave-query-executor-service + pullPolicy: IfNotPresent + tag: 1.0.9 +args: +- "--spring.output.ansi.enabled=ALWAYS" +- "--spring.profiles.active= default,k8s,remoteauth,querymessaging,metricssource,federation,query,pool1" +livenessProbe: + delaySeconds: 20 + periodSeconds: 5 + failureThreshold: 60 + port: 8080 + scheme: HTTP + uri: executor/mgmt/health +meta: + name: executor +service: + name: executor +readinessProbe: + delaySeconds: 20 + periodSeconds: 5 + failureThreshold: 60 + port: 8080 + scheme: HTTP + uri: executor/mgmt/health +replication: + maxSurge: 2 + maxUnavailable: 1 + replicaCount: 1 + revisionHistoryLimit: 10 +restartPolicy: Always + +####################################### +# Default Values for Executor Service # +####################################### + +ports: + http: 8080 + https: 8443 diff --git a/query-metrics/.gitignore b/query-metrics/.gitignore new file mode 100644 index 0000000..79f2743 --- /dev/null +++ b/query-metrics/.gitignore @@ -0,0 +1,5 @@ +############################### +# Ignores Helm Chart Archives # +############################### + +**.tgz diff --git a/query-metrics/.helmignore b/query-metrics/.helmignore new file mode 100644 index 0000000..e60a303 --- /dev/null +++ b/query-metrics/.helmignore @@ -0,0 +1,17 @@ +########################################### +# Ignores All File or Path Related to Git # +########################################### + +.git + +##################################### +# Ignores All Development Resources # +##################################### + +development/ +setup.sh + +############################ +# Ignores package Archives # +############################ +dwv-query-metrics-*.tgz diff --git a/query-metrics/Chart.lock b/query-metrics/Chart.lock new file mode 100644 index 0000000..2840813 --- /dev/null +++ b/query-metrics/Chart.lock @@ -0,0 +1,6 @@ +dependencies: +- name: common-service-library + repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts + version: 0.0.2 +digest: sha256:9f6737e1bdb7c4772bf295ccb128a1d540237dd1b7770e0edbd185d1b17a1a31 +generated: "2024-10-08T10:50:10.666522838Z" diff --git a/query-metrics/Chart.yaml b/query-metrics/Chart.yaml new file mode 100644 index 0000000..9c41707 --- /dev/null +++ b/query-metrics/Chart.yaml @@ -0,0 +1,22 @@ +################################# +# Core Helm Chart Configuration # +################################# + +apiVersion: v2 +name: dwv-query-metrics +type: application +version: 1.0.0-SNAPSHOT + +################################# +# Basic Metadata for this Chart # +################################# + +appVersion: 4.0.8 +description: Deploys a datawave query metric service +icon: https://code.nsa.gov/datawave/images/datawave-logo.png + +dependencies: + - name: common-service-library + repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts + version: 0.0.2 + diff --git a/query-metrics/templates/query-metrics-deployment.yaml b/query-metrics/templates/query-metrics-deployment.yaml new file mode 100644 index 0000000..c9b755e --- /dev/null +++ b/query-metrics/templates/query-metrics-deployment.yaml @@ -0,0 +1,19 @@ +{{- include "common-service-library.deployment" (list . "queryMetrics.deployment") -}} +{{- define "queryMetrics.deployment" -}} +#overrides go here +spec: + template: + spec: + initContainers: + - name: "{{ .Chart.Name }}-init-authorization" + image: "{{ .Values.global.initialization.image.name }}:{{ .Values.global.initialization.image.tag }}" + command: [ "sh", "-c", "until nc -z {{ .Values.global.serviceDns.authorization.name }} {{ .Values.global.serviceDns.authorization.port }}; do echo 'Waiting for Authorization...'; sleep 2; done" ] + + - name: "{{ .Chart.Name }}-init-cache" + image: "{{ .Values.global.initialization.image.name }}:{{ .Values.global.initialization.image.tag }}" + command: [ "sh", "-c", "until nc -z {{ .Values.global.serviceDns.cache.name }} {{ .Values.global.serviceDns.cache.port }}; do echo 'Waiting for Cache...'; sleep 2; done" ] + + - name: "{{ .Chart.Name }}-init-configuration" + image: "{{ .Values.global.initialization.image.name }}:{{ .Values.global.initialization.image.tag }}" + command: [ "sh", "-c", "until nc -z {{ .Values.global.serviceDns.configuration.name }} {{ .Values.global.serviceDns.configuration.port }}; do echo 'Waiting for Configuration...'; sleep 2; done" ] +{{- end -}} \ No newline at end of file diff --git a/query-metrics/templates/query-metrics-service.yaml b/query-metrics/templates/query-metrics-service.yaml new file mode 100644 index 0000000..3b1aa11 --- /dev/null +++ b/query-metrics/templates/query-metrics-service.yaml @@ -0,0 +1,4 @@ +{{- include "common-service-library.service" (list . "queryMetrics.service") -}} +{{- define "queryMetrics.service" -}} +#overrides go here +{{- end -}} \ No newline at end of file diff --git a/query-metrics/values.schema.json b/query-metrics/values.schema.json new file mode 100644 index 0000000..068c816 --- /dev/null +++ b/query-metrics/values.schema.json @@ -0,0 +1,206 @@ +{ + "$id": "https://code.nsa.org/datawave/schema", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "additionalProperties": true, + "description": "Schema for DataWave Helm values", + "properties": { + "args": { + "items": { + "type": "string" + }, + "type": "array" + }, + "global": { + "properties": { + "certSecretName": { + "type": "string" + }, + "dockerRegistry": { + "properties": { + "url": { + "type": "string" + } + }, + "type": "object" + }, + "initialization": { + "properties": { + "image": { + "properties": { + "name": { + "type": "string" + }, + "tag": { + "type": "number" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "pullSecrets": { + "items": { + "type": "string" + }, + "type": "array" + }, + "serviceDns": { + "properties": { + "authorization": { + "properties": { + "name": { + "type": "string" + } + }, + "type": "object" + }, + "cache": { + "properties": { + "name": { + "type": "string" + }, + "port": { + "type": "integer" + } + }, + "type": "object" + }, + "configuration": { + "properties": { + "name": { + "type": "string" + }, + "port": { + "type": "integer" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "volumes": { + "properties": { + "certificates": { + "properties": { + "destination": { + "type": "string" + }, + "name": { + "type": "string" + } + }, + "type": "object" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "image": { + "properties": { + "name": { + "type": "string" + }, + "pullPolicy": { + "type": "string" + }, + "tag": { + "type": "string" + } + }, + "type": "object" + }, + "livenessProbe": { + "properties": { + "delaySeconds": { + "type": "integer" + }, + "periodSeconds": { + "type": "integer" + }, + "port": { + "type": "integer" + }, + "scheme": { + "type": "string" + }, + "uri": { + "type": "string" + } + }, + "type": "object" + }, + "meta": { + "properties": { + "name": { + "type": "string" + } + }, + "type": "object" + }, + "ports": { + "properties": { + "http": { + "type": "integer" + }, + "https": { + "type": "integer" + } + }, + "type": "object" + }, + "readinessProbe": { + "properties": { + "delaySeconds": { + "type": "integer" + }, + "periodSeconds": { + "type": "integer" + }, + "port": { + "type": "integer" + }, + "scheme": { + "type": "string" + }, + "uri": { + "type": "string" + } + }, + "type": "object" + }, + "replication": { + "properties": { + "maxSurge": { + "type": "integer" + }, + "maxUnavailable": { + "type": "integer" + }, + "replicaCount": { + "type": "integer" + }, + "revisionHistoryLimit": { + "type": "integer" + } + }, + "type": "object" + }, + "restartPolicy": { + "type": "string" + }, + "service": { + "properties": { + "name": { + "type": "string" + } + }, + "type": "object" + } + }, + "title": "Helm Values Schema", + "type": "object" +} diff --git a/query-metrics/values.yaml b/query-metrics/values.yaml new file mode 100644 index 0000000..4e11960 --- /dev/null +++ b/query-metrics/values.yaml @@ -0,0 +1,67 @@ +global: + dockerRegistry: + url: ghcr.io/nationalsecurityagency + volumes: + certificates: + name: certificates + destination: /data/certs + initialization: + image: + name: busybox + tag: 1.28 + certSecretName: certificates-secret + pullSecrets: + - dockerconfigjson-ghcr + serviceDns: + configuration: + name: configuration + port: 8888 + authorization: + name: authorization + cache: + name: cache + port: 8080 + + +####################################### +# Default Values for Audit Deployment # +####################################### +image: + name: datawave-mapreduce-query-service + pullPolicy: IfNotPresent + tag: 4.0.8 +args: +- "--spring.output.ansi.enabled=ALWAYS" +- "--spring.profiles.active=default,k8s,remoteauth" +livenessProbe: + delaySeconds: 20 + periodSeconds: 5 + failureThreshold: 60 + port: 8080 + scheme: HTTP + uri: querymetric/mgmt/health +meta: + name: querymetric +service: + name: querymetric +readinessProbe: + delaySeconds: 20 + periodSeconds: 5 + failureThreshold: 60 + port: 8080 + scheme: HTTP + uri: querymetric/mgmt/health +replication: + maxSurge: 2 + maxUnavailable: 1 + replicaCount: 1 + revisionHistoryLimit: 10 +restartPolicy: Always + +####################################### +# Default Values for Executor Service # +####################################### + +ports: + http: 8080 + https: 8443 diff --git a/query/.gitignore b/query/.gitignore new file mode 100644 index 0000000..79f2743 --- /dev/null +++ b/query/.gitignore @@ -0,0 +1,5 @@ +############################### +# Ignores Helm Chart Archives # +############################### + +**.tgz diff --git a/query/.helmignore b/query/.helmignore new file mode 100644 index 0000000..b02f2f3 --- /dev/null +++ b/query/.helmignore @@ -0,0 +1,17 @@ +########################################### +# Ignores All File or Path Related to Git # +########################################### + +.git + +##################################### +# Ignores All Development Resources # +##################################### + +development/ +setup.sh + +############################ +# Ignores package Archives # +############################ +dwv-query-*.tgz diff --git a/query/Chart.lock b/query/Chart.lock new file mode 100644 index 0000000..18b66ee --- /dev/null +++ b/query/Chart.lock @@ -0,0 +1,6 @@ +dependencies: +- name: common-service-library + repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts + version: 0.0.2 +digest: sha256:9f6737e1bdb7c4772bf295ccb128a1d540237dd1b7770e0edbd185d1b17a1a31 +generated: "2024-10-08T10:49:49.636075467Z" diff --git a/query/Chart.yaml b/query/Chart.yaml new file mode 100644 index 0000000..2c3dce3 --- /dev/null +++ b/query/Chart.yaml @@ -0,0 +1,22 @@ +################################# +# Core Helm Chart Configuration # +################################# + +apiVersion: v2 +name: dwv-query +type: application +version: 1.0.0-SNAPSHOT + +################################# +# Basic Metadata for this Chart # +################################# + +appVersion: 1.0.10 +description: Deploys a datawave query service +icon: https://code.nsa.gov/datawave/images/datawave-logo.png + +dependencies: + - name: common-service-library + repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts + version: 0.0.2 + diff --git a/query/templates/query-deployment.yaml b/query/templates/query-deployment.yaml new file mode 100644 index 0000000..110c488 --- /dev/null +++ b/query/templates/query-deployment.yaml @@ -0,0 +1,19 @@ +{{- include "common-service-library.deployment" (list . "query.deployment") -}} +{{- define "query.deployment" -}} +#overrides go here +spec: + template: + spec: + initContainers: + - name: "{{ .Chart.Name }}-init-authorization" + image: "{{ .Values.global.initialization.image.name }}:{{ .Values.global.initialization.image.tag }}" + command: [ "sh", "-c", "until nc -z {{ .Values.global.serviceDns.authorization.name }} {{ .Values.global.serviceDns.authorization.port }}; do echo 'Waiting for Authorization...'; sleep 2; done" ] + + - name: "{{ .Chart.Name }}-init-cache" + image: "{{ .Values.global.initialization.image.name }}:{{ .Values.global.initialization.image.tag }}" + command: [ "sh", "-c", "until nc -z {{ .Values.global.serviceDns.cache.name }} {{ .Values.global.serviceDns.cache.port }}; do echo 'Waiting for Cache...'; sleep 2; done" ] + + - name: "{{ .Chart.Name }}-init-configuration" + image: "{{ .Values.global.initialization.image.name }}:{{ .Values.global.initialization.image.tag }}" + command: [ "sh", "-c", "until nc -z {{ .Values.global.serviceDns.configuration.name }} {{ .Values.global.serviceDns.configuration.port }}; do echo 'Waiting for Configuration...'; sleep 2; done" ] +{{- end -}} \ No newline at end of file diff --git a/query/templates/query-service.yaml b/query/templates/query-service.yaml new file mode 100644 index 0000000..1a0ed78 --- /dev/null +++ b/query/templates/query-service.yaml @@ -0,0 +1,4 @@ +{{- include "common-service-library.service" (list . "query.service") -}} +{{- define "query.service" -}} +#overrides go here +{{- end -}} \ No newline at end of file diff --git a/query/values.schema.json b/query/values.schema.json new file mode 100644 index 0000000..068c816 --- /dev/null +++ b/query/values.schema.json @@ -0,0 +1,206 @@ +{ + "$id": "https://code.nsa.org/datawave/schema", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "additionalProperties": true, + "description": "Schema for DataWave Helm values", + "properties": { + "args": { + "items": { + "type": "string" + }, + "type": "array" + }, + "global": { + "properties": { + "certSecretName": { + "type": "string" + }, + "dockerRegistry": { + "properties": { + "url": { + "type": "string" + } + }, + "type": "object" + }, + "initialization": { + "properties": { + "image": { + "properties": { + "name": { + "type": "string" + }, + "tag": { + "type": "number" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "pullSecrets": { + "items": { + "type": "string" + }, + "type": "array" + }, + "serviceDns": { + "properties": { + "authorization": { + "properties": { + "name": { + "type": "string" + } + }, + "type": "object" + }, + "cache": { + "properties": { + "name": { + "type": "string" + }, + "port": { + "type": "integer" + } + }, + "type": "object" + }, + "configuration": { + "properties": { + "name": { + "type": "string" + }, + "port": { + "type": "integer" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "volumes": { + "properties": { + "certificates": { + "properties": { + "destination": { + "type": "string" + }, + "name": { + "type": "string" + } + }, + "type": "object" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "image": { + "properties": { + "name": { + "type": "string" + }, + "pullPolicy": { + "type": "string" + }, + "tag": { + "type": "string" + } + }, + "type": "object" + }, + "livenessProbe": { + "properties": { + "delaySeconds": { + "type": "integer" + }, + "periodSeconds": { + "type": "integer" + }, + "port": { + "type": "integer" + }, + "scheme": { + "type": "string" + }, + "uri": { + "type": "string" + } + }, + "type": "object" + }, + "meta": { + "properties": { + "name": { + "type": "string" + } + }, + "type": "object" + }, + "ports": { + "properties": { + "http": { + "type": "integer" + }, + "https": { + "type": "integer" + } + }, + "type": "object" + }, + "readinessProbe": { + "properties": { + "delaySeconds": { + "type": "integer" + }, + "periodSeconds": { + "type": "integer" + }, + "port": { + "type": "integer" + }, + "scheme": { + "type": "string" + }, + "uri": { + "type": "string" + } + }, + "type": "object" + }, + "replication": { + "properties": { + "maxSurge": { + "type": "integer" + }, + "maxUnavailable": { + "type": "integer" + }, + "replicaCount": { + "type": "integer" + }, + "revisionHistoryLimit": { + "type": "integer" + } + }, + "type": "object" + }, + "restartPolicy": { + "type": "string" + }, + "service": { + "properties": { + "name": { + "type": "string" + } + }, + "type": "object" + } + }, + "title": "Helm Values Schema", + "type": "object" +} diff --git a/query/values.yaml b/query/values.yaml new file mode 100644 index 0000000..6e930c4 --- /dev/null +++ b/query/values.yaml @@ -0,0 +1,67 @@ +global: + dockerRegistry: + url: ghcr.io/nationalsecurityagency + volumes: + certificates: + name: certificates + destination: /data/certs + initialization: + image: + name: busybox + tag: 1.28 + certSecretName: certificates-secret + pullSecrets: + - dockerconfigjson-ghcr + serviceDns: + configuration: + name: configuration + port: 8888 + authorization: + name: authorization + cache: + name: cache + port: 8080 + + +####################################### +# Default Values for Audit Deployment # +####################################### +image: + name: datawave-mapreduce-query-service + pullPolicy: IfNotPresent + tag: 1.0.10 +args: +- "--spring.output.ansi.enabled=ALWAYS" +- "--spring.profiles.active=default,k8s,remoteauth,querymessaging,metricssource,query,mrquery,cachedresults,federation" +livenessProbe: + delaySeconds: 20 + periodSeconds: 5 + failureThreshold: 60 + port: 8080 + scheme: HTTP + uri: query/mgmt/health +meta: + name: query +service: + name: query +readinessProbe: + delaySeconds: 20 + periodSeconds: 5 + failureThreshold: 60 + port: 8080 + scheme: HTTP + uri: query/mgmt/health +replication: + maxSurge: 2 + maxUnavailable: 1 + replicaCount: 1 + revisionHistoryLimit: 10 +restartPolicy: Always + +####################################### +# Default Values for Executor Service # +####################################### + +ports: + http: 8080 + https: 8443 diff --git a/shared-functions.sh b/shared-functions.sh new file mode 100644 index 0000000..8b1f758 --- /dev/null +++ b/shared-functions.sh @@ -0,0 +1,92 @@ + +function start_minikube() { + # Cache images and reset minikube. Then Setup minikube ingress. + docker pull rabbitmq:3.11.4-alpine && \ + docker pull busybox:1.28 && \ + minikube delete --all --purge && \ + minikube start --nodes 3 --cpus 4 --memory 15960 --disk-size 20480 && \ + minikube image load rabbitmq:3.11.4-alpine && \ + minikube image load busybox:1.28 && \ + minikube image load mysql:8.0.32 && \ + minikube addons enable ingress && \ + minikube kubectl -- delete -A ValidatingWebhookConfiguration ingress-nginx-admission && \ + minikube kubectl -- patch deployment -n ingress-nginx ingress-nginx-controller --type='json' -p='[{"op": "add", "path": "/spec/template/spec/containers/0/args/-", "value":"--enable-ssl-passthrough"}]' && \ + + #Apply GHCR credentials + if test -f "${BASEDIR}"/ghcr-image-pull-secret.yaml; then + minikube kubectl -- apply -f "${BASEDIR}"/ghcr-image-pull-secret.yaml + fi + + minikube kubectl -- create secret generic certificates-secret --from-file=keystore.p12="${DATAWAVE_STACK}"/certificates/keystore.p12 --from-file=truststore.jks="${DATAWAVE_STACK}"/certificates/truststore.jks +} + +function docker_login() { + if test -f "${BASEDIR}"/ghcr-image-pull-secret.yaml; then + # File path + FILE_PATH="./ghcr-image-pull-secret.yaml" + + # Extract the base64-encoded .dockerconfigjson value + ENCODED_JSON=$(grep '.dockerconfigjson:' $FILE_PATH | awk '{print $2}') + + # Decode the JSON value + DECODED_JSON=$(echo $ENCODED_JSON | base64 --decode) + + # Extract the base64-encoded auth value for ghcr.io + ENCODED_AUTH=$(echo $DECODED_JSON | jq -r '.auths["ghcr.io"].auth') + + # Decode the auth value to get username:password + AUTH=$(echo $ENCODED_AUTH | base64 --decode) + + # Split the username and password + USERNAME=$(echo $AUTH | cut -d ':' -f 1) + PASSWORD=$(echo $AUTH | cut -d ':' -f 2) + + echo $PASSWORD | docker login ghcr.io --username $USERNAME --password-stdin + fi +} + +function initialize_hosts_file() { + sudo sed -i "/^$/d" /etc/hosts + sudo sed -i "/.*datawave\.org.*/d" /etc/hosts + sudo sed -i "/.*zookeeper.*/d" /etc/hosts + sudo sed -i "/.*hdfs.*/d" /etc/hosts + sudo sed -i "/.*yarn.*/d" /etc/hosts + echo "$(minikube ip) accumulo.datawave.org" | sudo tee -a /etc/hosts + echo "$(minikube ip) web.datawave.org" | sudo tee -a /etc/hosts + echo "$(minikube ip) dictionary.datawave.org" | sudo tee -a /etc/hosts +} + +function updateCoreDns() { + if ${USE_LOCAL_ZOOKEEPER} && ${USE_LOCAL_HADOOP}; then + "${BASEDIR}"/updateCorefile.sh coredns.corefile-both.template + elif ${USE_LOCAL_ZOOKEEPER}; then + "${BASEDIR}"/updateCorefile.sh coredns.corefile-zookeeper.template + elif ${USE_LOCAL_HADOOP}; then + "${BASEDIR}"/updateCorefile.sh coredns.corefile-hadoop.template + else + "${BASEDIR}"/updateCorefile.sh coredns.corefile-default.template + fi +} + +function update_hosts_file_for_hadoop() { + echo "$(minikube ip) namenode.datawave.org" | sudo tee -a /etc/hosts + echo "$(minikube ip) resourcemanager.datawave.org" | sudo tee -a /etc/hosts + echo "$(minikube ip) historyserver.datawave.org" | sudo tee -a /etc/hosts +} + +function start_zk() { + "${BASEDIR}"/startZookeeper.sh + echo "$(minikube ip | cut -f1,2,3 -d .).1 zookeeper" | sudo tee -a /etc/hosts +} + +function start_hadoop() { + "${BASEDIR}"/startHadoop.sh + echo "$(minikube ip | cut -f1,2,3 -d .).1 hdfs-nn" | sudo tee -a /etc/hosts + echo "$(minikube ip | cut -f1,2,3 -d .).1 hdfs-dn" | sudo tee -a /etc/hosts + echo "$(minikube ip | cut -f1,2,3 -d .).1 yarn-rn" | sudo tee -a /etc/hosts + echo "$(minikube ip | cut -f1,2,3 -d .).1 yarn-nm" | sudo tee -a /etc/hosts + + echo "$(minikube ip | cut -f1,2,3 -d .).1 namenode.datawave.org" | sudo tee -a /etc/hosts + echo "$(minikube ip | cut -f1,2,3 -d .).1 resourcemanager.datawave.org" | sudo tee -a /etc/hosts + echo "$(minikube ip | cut -f1,2,3 -d .).1 historyserver.datawave.org" | sudo tee -a /etc/hosts +} diff --git a/startLocalQMSTest.sh b/startLocalQMSTest.sh new file mode 100755 index 0000000..4326755 --- /dev/null +++ b/startLocalQMSTest.sh @@ -0,0 +1,64 @@ +#!/usr/bin/env bash + +VALUES_FILE=${1:-values.yaml} +USE_LOCAL_ZOOKEEPER=${USE_LOCAL_ZOOKEEPER:-false} +USE_LOCAL_HADOOP=${USE_LOCAL_HADOOP:-false} +INIT_LOCAL_HADOOP=${INIT_LOCAL_HADOOP:-false} +EXTRA_HELM_ARGS=${EXTRA_HELM_ARGS:""} +BASEDIR="$( cd -- "$(dirname "$0")" >/dev/null 2>&1 || exit; pwd -P )" +DATAWAVE_STACK="${BASEDIR}/datawave-stack" + +. ./shared-functions.sh +function helm_install() { + if ${USE_LOCAL_ZOOKEEPER}; then + start_zk + EXTRA_HELM_ARGS="${EXTRA_HELM_ARGS} --set charts.zookeeper.enabled=false" + fi + if ${USE_LOCAL_HADOOP}; then + start_hadoop + EXTRA_HELM_ARGS="${EXTRA_HELM_ARGS} --set charts.hadoop.enabled=false" + else + update_hosts_file_for_hadoop + fi + + # shellcheck disable=SC2086 + helm install dwv "${DATAWAVE_STACK}"/datawave-qms*.tgz -f "${DATAWAVE_STACK}"/${VALUES_FILE} ${EXTRA_HELM_ARGS} +} + + +function helm_package() { + find . -name "*.tgz" -delete + cd "${BASEDIR}"/common-service-library || exit + helm package . + cd "${BASEDIR}" || exit + for chart in executor query query-metrics kafka kafdrop modification mr-query audit authorization cache configuration dictionary hadoop ingest mysql rabbitmq zookeeper; do + cd "${BASEDIR}"/$chart || exit + helm dependency update + helm package . + done + cd "${BASEDIR}"/datawave-qms-umbrella || exit + helm dependency update + helm package . + cd "${BASEDIR}"/datawave-qms-stack || exit + helm dependency update + helm package . + cd "${BASEDIR}" || exit +} + +echo "Login to Helm Charts repo using docker" +docker_login +echo "Package helm charts" +helm_package +echo "Purge and restart Minikube" +start_minikube +echo "Initialize Hosts file" +initialize_hosts_file +echo "Update COREDNS" +updateCoreDns +echo "Running Helm Install" +helm_install +echo "Deploy to MiniKube complete!" + +#Currently Disabled. See DataWave repo on how to get this json file. +#kubectl cp tv-show-raw-data-stock.json dwv-dwv-hadoop-hdfs-nn-0:/tmp && \ +#kubectl exec -it dwv-dwv-hadoop-hdfs-nn-0 -- hdfs dfs -put /tmp/tv-show-raw-data-stock.json /data/myjson diff --git a/startLocalTest.sh b/startLocalTest.sh index 99c9b2c..8e4c13a 100755 --- a/startLocalTest.sh +++ b/startLocalTest.sh @@ -12,107 +12,24 @@ EXTRA_HELM_ARGS=${EXTRA_HELM_ARGS:""} BASEDIR="$( cd -- "$(dirname "$0")" >/dev/null 2>&1 || exit; pwd -P )" DATAWAVE_STACK="${BASEDIR}/datawave-stack" -function start_minikube() { - # Cache images and reset minikube. Then Setup minikube ingress. - docker pull rabbitmq:3.11.4-alpine && \ - docker pull mysql:8.0.32 && \ - docker pull busybox:1.28 && \ - minikube delete --all --purge && \ - minikube start --nodes 3 --cpus 4 --memory 15960 --disk-size 20480 && \ - minikube image load rabbitmq:3.11.4-alpine && \ - minikube image load busybox:1.28 && \ - minikube image load mysql:8.0.32 && \ - minikube addons enable ingress && \ - minikube kubectl -- delete -A ValidatingWebhookConfiguration ingress-nginx-admission && \ - minikube kubectl -- patch deployment -n ingress-nginx ingress-nginx-controller --type='json' -p='[{"op": "add", "path": "/spec/template/spec/containers/0/args/-", "value":"--enable-ssl-passthrough"}]' && \ +. ./shared-functions.sh - # update default storage provisioner, set csi-hostpath-sc as the default storage driver - echo "Enabling volumesnapshots and csi-hostpath-driver" - minikube addons enable volumesnapshots - minikube addons enable csi-hostpath-driver - minikube addons disable storage-provisioner - minikube addons disable default-storageclass - minikube kubectl -- patch storageclass csi-hostpath-sc -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}' - - #Apply GHCR credentials - if test -f "${BASEDIR}"/ghcr-image-pull-secret.yaml; then - minikube kubectl -- apply -f "${BASEDIR}"/ghcr-image-pull-secret.yaml - fi - - minikube kubectl -- create secret generic certificates-secret --from-file=keystore.p12="${DATAWAVE_STACK}"/certificates/keystore.p12 --from-file=truststore.jks="${DATAWAVE_STACK}"/certificates/truststore.jks -} - -function ghcr_login() { - if test -f "${BASEDIR}"/ghcr-image-pull-secret.yaml; then - # File path - FILE_PATH="./ghcr-image-pull-secret.yaml" - - # Extract the base64-encoded .dockerconfigjson value - ENCODED_JSON=$(grep '.dockerconfigjson:' $FILE_PATH | awk '{print $2}') - - # Decode the JSON value - DECODED_JSON=$(echo $ENCODED_JSON | base64 --decode) - - # Extract the base64-encoded auth value for ghcr.io - ENCODED_AUTH=$(echo $DECODED_JSON | jq -r '.auths["ghcr.io"].auth') - - # Decode the auth value to get username:password - AUTH=$(echo $ENCODED_AUTH | base64 --decode) - - # Split the username and password - USERNAME=$(echo $AUTH | cut -d ':' -f 1) - PASSWORD=$(echo $AUTH | cut -d ':' -f 2) - - echo $PASSWORD | docker login ghcr.io --username $USERNAME --password-stdin - echo $PASSWORD | helm registry login ghcr.io --username $USERNAME --password-stdin +function helm_install() { + if ${USE_LOCAL_ZOOKEEPER}; then + start_zk + EXTRA_HELM_ARGS="${EXTRA_HELM_ARGS} --set charts.zookeeper.enabled=false" fi -} - -function initialize_hosts_file() { - sudo sed -i "/^$/d" /etc/hosts - sudo sed -i "/.*datawave\.org.*/d" /etc/hosts - sudo sed -i "/.*zookeeper.*/d" /etc/hosts - sudo sed -i "/.*hdfs.*/d" /etc/hosts - sudo sed -i "/.*yarn.*/d" /etc/hosts - echo "$(minikube ip) accumulo.datawave.org" | sudo tee -a /etc/hosts - echo "$(minikube ip) web.datawave.org" | sudo tee -a /etc/hosts - echo "$(minikube ip) dictionary.datawave.org" | sudo tee -a /etc/hosts -} - -function updateCoreDns() { - if ${USE_LOCAL_ZOOKEEPER} && ${USE_LOCAL_HADOOP}; then - "${BASEDIR}"/updateCorefile.sh coredns.corefile-both.template - elif ${USE_LOCAL_ZOOKEEPER}; then - "${BASEDIR}"/updateCorefile.sh coredns.corefile-zookeeper.template - elif ${USE_LOCAL_HADOOP}; then - "${BASEDIR}"/updateCorefile.sh coredns.corefile-hadoop.template + if ${USE_LOCAL_HADOOP}; then + start_hadoop + EXTRA_HELM_ARGS="${EXTRA_HELM_ARGS} --set charts.hadoop.enabled=false" else - "${BASEDIR}"/updateCorefile.sh coredns.corefile-default.template + update_hosts_file_for_hadoop fi -} - -function update_hosts_file_for_hadoop() { - echo "$(minikube ip) namenode.datawave.org" | sudo tee -a /etc/hosts - echo "$(minikube ip) resourcemanager.datawave.org" | sudo tee -a /etc/hosts - echo "$(minikube ip) historyserver.datawave.org" | sudo tee -a /etc/hosts -} -function start_zk() { - "${BASEDIR}"/startZookeeper.sh - echo "$(minikube ip | cut -f1,2,3 -d .).1 zookeeper" | sudo tee -a /etc/hosts + # shellcheck disable=SC2086 + helm install dwv "${DATAWAVE_STACK}"/datawave-system-*.tgz -f "${DATAWAVE_STACK}"/${VALUES_FILE} ${EXTRA_HELM_ARGS} } -function start_hadoop() { - "${BASEDIR}"/startHadoop.sh - echo "$(minikube ip | cut -f1,2,3 -d .).1 hdfs-nn" | sudo tee -a /etc/hosts - echo "$(minikube ip | cut -f1,2,3 -d .).1 hdfs-dn" | sudo tee -a /etc/hosts - echo "$(minikube ip | cut -f1,2,3 -d .).1 yarn-rn" | sudo tee -a /etc/hosts - echo "$(minikube ip | cut -f1,2,3 -d .).1 yarn-nm" | sudo tee -a /etc/hosts - - echo "$(minikube ip | cut -f1,2,3 -d .).1 namenode.datawave.org" | sudo tee -a /etc/hosts - echo "$(minikube ip | cut -f1,2,3 -d .).1 resourcemanager.datawave.org" | sudo tee -a /etc/hosts - echo "$(minikube ip | cut -f1,2,3 -d .).1 historyserver.datawave.org" | sudo tee -a /etc/hosts -} function helm_package() { find . -name "*.tgz" -delete @@ -132,21 +49,6 @@ function helm_package() { helm package . cd "${BASEDIR}" || exit } -function helm_install() { - if ${USE_LOCAL_ZOOKEEPER}; then - start_zk - EXTRA_HELM_ARGS="${EXTRA_HELM_ARGS} --set charts.zookeeper.enabled=false" - fi - if ${USE_LOCAL_HADOOP}; then - start_hadoop - EXTRA_HELM_ARGS="${EXTRA_HELM_ARGS} --set charts.hadoop.enabled=false" - else - update_hosts_file_for_hadoop - fi - - # shellcheck disable=SC2086 - helm install dwv "${DATAWAVE_STACK}"/datawave-system-*.tgz -f "${DATAWAVE_STACK}"/${VALUES_FILE} ${EXTRA_HELM_ARGS} -} echo "Login to Docker and Helm Charts GHCR repo" ghcr_login From 2a3b4cc4cd32159a56670ad0d2c37a9655735b70 Mon Sep 17 00:00:00 2001 From: Adam Lerman Date: Tue, 8 Oct 2024 23:51:27 +0000 Subject: [PATCH 03/16] some additional cleanup --- executor-pool/.gitignore | 5 - executor-pool/.helmignore | 17 -- executor-pool/Chart.lock | 6 - executor-pool/Chart.yaml | 22 -- .../accumulo-microservice-deployment.yaml | 19 -- .../accumulo-microservice-service.yaml | 4 - executor-pool/values.schema.json | 206 ------------------ executor-pool/values.yaml | 67 ------ kafdrop/Chart.yaml | 2 +- 9 files changed, 1 insertion(+), 347 deletions(-) delete mode 100644 executor-pool/.gitignore delete mode 100644 executor-pool/.helmignore delete mode 100644 executor-pool/Chart.lock delete mode 100644 executor-pool/Chart.yaml delete mode 100644 executor-pool/templates/accumulo-microservice-deployment.yaml delete mode 100644 executor-pool/templates/accumulo-microservice-service.yaml delete mode 100644 executor-pool/values.schema.json delete mode 100644 executor-pool/values.yaml diff --git a/executor-pool/.gitignore b/executor-pool/.gitignore deleted file mode 100644 index 79f2743..0000000 --- a/executor-pool/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -############################### -# Ignores Helm Chart Archives # -############################### - -**.tgz diff --git a/executor-pool/.helmignore b/executor-pool/.helmignore deleted file mode 100644 index aa06c2c..0000000 --- a/executor-pool/.helmignore +++ /dev/null @@ -1,17 +0,0 @@ -########################################### -# Ignores All File or Path Related to Git # -########################################### - -.git - -##################################### -# Ignores All Development Resources # -##################################### - -development/ -setup.sh - -############################ -# Ignores package Archives # -############################ -dwv-accumulo-microservice-*.tgz diff --git a/executor-pool/Chart.lock b/executor-pool/Chart.lock deleted file mode 100644 index c7d3c8d..0000000 --- a/executor-pool/Chart.lock +++ /dev/null @@ -1,6 +0,0 @@ -dependencies: -- name: common-service-library - repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts - version: 0.0.2 -digest: sha256:9f6737e1bdb7c4772bf295ccb128a1d540237dd1b7770e0edbd185d1b17a1a31 -generated: "2024-10-04T18:58:14.981876411Z" diff --git a/executor-pool/Chart.yaml b/executor-pool/Chart.yaml deleted file mode 100644 index 6356828..0000000 --- a/executor-pool/Chart.yaml +++ /dev/null @@ -1,22 +0,0 @@ -################################# -# Core Helm Chart Configuration # -################################# - -apiVersion: v2 -name: dwv-executor -type: application -version: 1.0.0-SNAPSHOT - -################################# -# Basic Metadata for this Chart # -################################# - -appVersion: 1.0.9 -description: Deploys a datawave query executor service -icon: https://code.nsa.gov/datawave/images/datawave-logo.png - -dependencies: - - name: common-service-library - repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts - version: 0.0.2 - diff --git a/executor-pool/templates/accumulo-microservice-deployment.yaml b/executor-pool/templates/accumulo-microservice-deployment.yaml deleted file mode 100644 index 194eb3e..0000000 --- a/executor-pool/templates/accumulo-microservice-deployment.yaml +++ /dev/null @@ -1,19 +0,0 @@ -{{- include "common-service-library.deployment" (list . "accumuloMicroservice.deployment") -}} -{{- define "accumuloMicroservice.deployment" -}} -#overrides go here -spec: - template: - spec: - initContainers: - - name: "{{ .Chart.Name }}-init-authorization" - image: "{{ .Values.global.initialization.image.name }}:{{ .Values.global.initialization.image.tag }}" - command: [ "sh", "-c", "until nc -z {{ .Values.global.serviceDns.authorization.name }} {{ .Values.global.serviceDns.authorization.port }}; do echo 'Waiting for Authorization...'; sleep 2; done" ] - - - name: "{{ .Chart.Name }}-init-cache" - image: "{{ .Values.global.initialization.image.name }}:{{ .Values.global.initialization.image.tag }}" - command: [ "sh", "-c", "until nc -z {{ .Values.global.serviceDns.cache.name }} {{ .Values.global.serviceDns.cache.port }}; do echo 'Waiting for Cache...'; sleep 2; done" ] - - - name: "{{ .Chart.Name }}-init-configuration" - image: "{{ .Values.global.initialization.image.name }}:{{ .Values.global.initialization.image.tag }}" - command: [ "sh", "-c", "until nc -z {{ .Values.global.serviceDns.configuration.name }} {{ .Values.global.serviceDns.configuration.port }}; do echo 'Waiting for Configuration...'; sleep 2; done" ] -{{- end -}} \ No newline at end of file diff --git a/executor-pool/templates/accumulo-microservice-service.yaml b/executor-pool/templates/accumulo-microservice-service.yaml deleted file mode 100644 index 2bcedaa..0000000 --- a/executor-pool/templates/accumulo-microservice-service.yaml +++ /dev/null @@ -1,4 +0,0 @@ -{{- include "common-service-library.service" (list . "accumuloMicroservice.service") -}} -{{- define "accumuloMicroservice.service" -}} -#overrides go here -{{- end -}} \ No newline at end of file diff --git a/executor-pool/values.schema.json b/executor-pool/values.schema.json deleted file mode 100644 index 068c816..0000000 --- a/executor-pool/values.schema.json +++ /dev/null @@ -1,206 +0,0 @@ -{ - "$id": "https://code.nsa.org/datawave/schema", - "$schema": "https://json-schema.org/draft/2020-12/schema", - "additionalProperties": true, - "description": "Schema for DataWave Helm values", - "properties": { - "args": { - "items": { - "type": "string" - }, - "type": "array" - }, - "global": { - "properties": { - "certSecretName": { - "type": "string" - }, - "dockerRegistry": { - "properties": { - "url": { - "type": "string" - } - }, - "type": "object" - }, - "initialization": { - "properties": { - "image": { - "properties": { - "name": { - "type": "string" - }, - "tag": { - "type": "number" - } - }, - "type": "object" - } - }, - "type": "object" - }, - "pullSecrets": { - "items": { - "type": "string" - }, - "type": "array" - }, - "serviceDns": { - "properties": { - "authorization": { - "properties": { - "name": { - "type": "string" - } - }, - "type": "object" - }, - "cache": { - "properties": { - "name": { - "type": "string" - }, - "port": { - "type": "integer" - } - }, - "type": "object" - }, - "configuration": { - "properties": { - "name": { - "type": "string" - }, - "port": { - "type": "integer" - } - }, - "type": "object" - } - }, - "type": "object" - }, - "volumes": { - "properties": { - "certificates": { - "properties": { - "destination": { - "type": "string" - }, - "name": { - "type": "string" - } - }, - "type": "object" - } - }, - "type": "object" - } - }, - "type": "object" - }, - "image": { - "properties": { - "name": { - "type": "string" - }, - "pullPolicy": { - "type": "string" - }, - "tag": { - "type": "string" - } - }, - "type": "object" - }, - "livenessProbe": { - "properties": { - "delaySeconds": { - "type": "integer" - }, - "periodSeconds": { - "type": "integer" - }, - "port": { - "type": "integer" - }, - "scheme": { - "type": "string" - }, - "uri": { - "type": "string" - } - }, - "type": "object" - }, - "meta": { - "properties": { - "name": { - "type": "string" - } - }, - "type": "object" - }, - "ports": { - "properties": { - "http": { - "type": "integer" - }, - "https": { - "type": "integer" - } - }, - "type": "object" - }, - "readinessProbe": { - "properties": { - "delaySeconds": { - "type": "integer" - }, - "periodSeconds": { - "type": "integer" - }, - "port": { - "type": "integer" - }, - "scheme": { - "type": "string" - }, - "uri": { - "type": "string" - } - }, - "type": "object" - }, - "replication": { - "properties": { - "maxSurge": { - "type": "integer" - }, - "maxUnavailable": { - "type": "integer" - }, - "replicaCount": { - "type": "integer" - }, - "revisionHistoryLimit": { - "type": "integer" - } - }, - "type": "object" - }, - "restartPolicy": { - "type": "string" - }, - "service": { - "properties": { - "name": { - "type": "string" - } - }, - "type": "object" - } - }, - "title": "Helm Values Schema", - "type": "object" -} diff --git a/executor-pool/values.yaml b/executor-pool/values.yaml deleted file mode 100644 index e71e1b7..0000000 --- a/executor-pool/values.yaml +++ /dev/null @@ -1,67 +0,0 @@ -global: - dockerRegistry: - url: ghcr.io/nationalsecurityagency - volumes: - certificates: - name: certificates - destination: /data/certs - initialization: - image: - name: busybox - tag: 1.28 - certSecretName: certificates-secret - pullSecrets: - - dockerconfigjson-ghcr - serviceDns: - configuration: - name: configuration - port: 8888 - authorization: - name: authorization - cache: - name: cache - port: 8080 - - -####################################### -# Default Values for Audit Deployment # -####################################### -image: - name: datawave-query-executor-service - pullPolicy: IfNotPresent - tag: 1.0.9 -args: -- "--spring.output.ansi.enabled=ALWAYS" -- "--spring.profiles.active= default,k8s,remoteauth,querymessaging,metricssource,federation,query,pool1" -livenessProbe: - delaySeconds: 20 - periodSeconds: 5 - failureThreshold: 60 - port: 8080 - scheme: HTTP - uri: executor/mgmt/health -meta: - name: executor -service: - name: executor -readinessProbe: - delaySeconds: 20 - periodSeconds: 5 - failureThreshold: 60 - port: 8080 - scheme: HTTP - uri: executor/mgmt/health -replication: - maxSurge: 2 - maxUnavailable: 1 - replicaCount: 1 - revisionHistoryLimit: 10 -restartPolicy: Always - -####################################### -# Default Values for Executor Service # -####################################### - -ports: - http: 8080 - https: 8443 diff --git a/kafdrop/Chart.yaml b/kafdrop/Chart.yaml index 9d937a2..488e11e 100644 --- a/kafdrop/Chart.yaml +++ b/kafdrop/Chart.yaml @@ -3,7 +3,7 @@ ################################# apiVersion: v2 -name: dwv-executor +name: dwv-kafdrop type: application version: 1.0.0-SNAPSHOT From d621b7b6363e20afcf53dbcd34470ed705282f3d Mon Sep 17 00:00:00 2001 From: Adam Lerman Date: Wed, 9 Oct 2024 22:00:43 +0000 Subject: [PATCH 04/16] Add lock files --- modification/Chart.lock | 6 ++++++ mr-query/Chart.lock | 6 ++++++ 2 files changed, 12 insertions(+) create mode 100644 modification/Chart.lock create mode 100644 mr-query/Chart.lock diff --git a/modification/Chart.lock b/modification/Chart.lock new file mode 100644 index 0000000..3536bfe --- /dev/null +++ b/modification/Chart.lock @@ -0,0 +1,6 @@ +dependencies: +- name: common-service-library + repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts + version: 0.0.2 +digest: sha256:9f6737e1bdb7c4772bf295ccb128a1d540237dd1b7770e0edbd185d1b17a1a31 +generated: "2024-10-08T10:50:11.424962441Z" diff --git a/mr-query/Chart.lock b/mr-query/Chart.lock new file mode 100644 index 0000000..8fbd758 --- /dev/null +++ b/mr-query/Chart.lock @@ -0,0 +1,6 @@ +dependencies: +- name: common-service-library + repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts + version: 0.0.2 +digest: sha256:9f6737e1bdb7c4772bf295ccb128a1d540237dd1b7770e0edbd185d1b17a1a31 +generated: "2024-10-08T10:50:11.918150861Z" From 7a1b6498d4da1ceb955e06094658500d6d43cebb Mon Sep 17 00:00:00 2001 From: Adam Lerman Date: Wed, 13 Nov 2024 14:55:36 +0000 Subject: [PATCH 05/16] Everything working in new charts. Config issue stopping a few microservices from running --- configuration/configMapFiles/accumulo.yml | 23 + .../application-cachedresults.yml | 79 +++ .../configMapFiles/application-federation.yml | 15 + .../configMapFiles/application-k8s.yml | 28 +- .../application-metricssource.yml | 23 + .../configMapFiles/application-mrquery.yml | 54 ++ .../configMapFiles/application-query.yml | 573 ++++++++++++++++++ .../application-querymessaging.yml | 11 + configuration/configMapFiles/application.yml | 8 +- configuration/configMapFiles/audit.yml | 17 +- .../configMapFiles/executor-pool1.yml | 20 + .../configMapFiles/executor-pool2.yml | 20 + configuration/configMapFiles/executor.yml | 67 ++ configuration/configMapFiles/modification.yml | 68 +++ configuration/configMapFiles/mrquery.yml | 31 + configuration/configMapFiles/query.yml | 74 +++ configuration/configMapFiles/querymetric.yml | 124 ++++ configuration/values.yaml | 25 +- datawave-driver.sh | 2 + datawave-qms-stack/.helmignore | 19 - datawave-qms-stack/.schema.yaml | 13 - datawave-qms-stack/Chart.lock | 21 - datawave-qms-stack/Chart.yaml | 38 -- datawave-qms-stack/README.md | 3 - datawave-qms-stack/certificates/keystore.p12 | Bin 3586 -> 0 bytes .../certificates/truststore.jks | Bin 163715 -> 0 bytes datawave-qms-stack/templates/_helpers.tpl | 23 - datawave-qms-stack/templates/hdfs.yaml | 19 - datawave-qms-stack/templates/yarn.yaml | 19 - datawave-qms-stack/templates/zookeeper.yaml | 24 - datawave-qms-stack/values-testing.yaml | 8 - datawave-qms-stack/values.schema.json | 88 --- datawave-qms-stack/values.yaml | 27 - datawave-qms-umbrella/.schema.yaml | 13 - datawave-qms-umbrella/Chart.lock | 42 -- datawave-qms-umbrella/Chart.yaml | 57 -- datawave-qms-umbrella/README.md | 3 - datawave-qms-umbrella/values.schema.json | 74 --- datawave-qms-umbrella/values.yaml | 22 - datawave-stack/Chart.yaml | 35 ++ datawave-stack/values.yaml | 2 + executor/Chart.yaml | 1 + .../accumulo-microservice-deployment.yaml | 4 +- .../accumulo-microservice-service.yaml | 4 +- executor/values.yaml | 1 + hadoop-config/.helmignore | 2 + hadoop/.helmignore | 2 + modification/Chart.yaml | 1 + modification/values.yaml | 3 +- mr-query/Chart.yaml | 1 + mr-query/values.yaml | 3 +- query-metrics/Chart.yaml | 1 + query-metrics/values.yaml | 7 +- query/Chart.yaml | 1 + query/values.yaml | 5 +- 55 files changed, 1318 insertions(+), 530 deletions(-) create mode 100644 configuration/configMapFiles/accumulo.yml create mode 100755 configuration/configMapFiles/application-cachedresults.yml create mode 100644 configuration/configMapFiles/application-federation.yml create mode 100755 configuration/configMapFiles/application-metricssource.yml create mode 100755 configuration/configMapFiles/application-mrquery.yml create mode 100644 configuration/configMapFiles/application-query.yml create mode 100755 configuration/configMapFiles/application-querymessaging.yml create mode 100755 configuration/configMapFiles/executor-pool1.yml create mode 100755 configuration/configMapFiles/executor-pool2.yml create mode 100755 configuration/configMapFiles/executor.yml create mode 100644 configuration/configMapFiles/modification.yml create mode 100755 configuration/configMapFiles/mrquery.yml create mode 100755 configuration/configMapFiles/query.yml create mode 100755 configuration/configMapFiles/querymetric.yml delete mode 100644 datawave-qms-stack/.helmignore delete mode 100644 datawave-qms-stack/.schema.yaml delete mode 100644 datawave-qms-stack/Chart.lock delete mode 100644 datawave-qms-stack/Chart.yaml delete mode 100644 datawave-qms-stack/README.md delete mode 100644 datawave-qms-stack/certificates/keystore.p12 delete mode 100644 datawave-qms-stack/certificates/truststore.jks delete mode 100644 datawave-qms-stack/templates/_helpers.tpl delete mode 100644 datawave-qms-stack/templates/hdfs.yaml delete mode 100644 datawave-qms-stack/templates/yarn.yaml delete mode 100644 datawave-qms-stack/templates/zookeeper.yaml delete mode 100644 datawave-qms-stack/values-testing.yaml delete mode 100644 datawave-qms-stack/values.schema.json delete mode 100644 datawave-qms-stack/values.yaml delete mode 100644 datawave-qms-umbrella/.schema.yaml delete mode 100644 datawave-qms-umbrella/Chart.lock delete mode 100644 datawave-qms-umbrella/Chart.yaml delete mode 100644 datawave-qms-umbrella/README.md delete mode 100644 datawave-qms-umbrella/values.schema.json delete mode 100644 datawave-qms-umbrella/values.yaml diff --git a/configuration/configMapFiles/accumulo.yml b/configuration/configMapFiles/accumulo.yml new file mode 100644 index 0000000..3a1f087 --- /dev/null +++ b/configuration/configMapFiles/accumulo.yml @@ -0,0 +1,23 @@ +warehouse-cluster: + accumulo: + zookeepers: "{{ .Values.global.zookeeper.quorum }}" + instanceName: '{{ .Values.global.accumulo.instanceName }}' + username: '{{ .Values.global.accumulo.user }}' + password: '{{ .Values.global.accumulo.password }}' + +accumulo: + lookup: + audit: + defaultAuditType: 'ACTIVE' + stats: + enabled: true + +audit-client: + discovery: + enabled: false + uri: '${AUDIT_SERVER_URL:http://localhost:11111/audit}' + +datawave: + swagger: + title: "Accumulo Service" + description: "REST API provided by the Accumulo Service" \ No newline at end of file diff --git a/configuration/configMapFiles/application-cachedresults.yml b/configuration/configMapFiles/application-cachedresults.yml new file mode 100755 index 0000000..fdcf0aa --- /dev/null +++ b/configuration/configMapFiles/application-cachedresults.yml @@ -0,0 +1,79 @@ +spring: + datasource: + cachedResults: + url: 'jdbc:mysql://{{.Values.global.serviceDns.mysql.name}}:3306/cachedresults?zeroDateTimeBehavior=convertToNull' + username: '{{ .Values.global.mysql.user }}' + password: 'secret' + driver-class-name: 'com.mysql.cj.jdbc.Driver' + hikari: + # default: 30000 + connection-timeout: 5000 + # default: 600000 + idle-timeout: 900000 + # default: maximum-pool-size + minimum-idle: {{ .Values.global.mysql.minIdle }} + # default: 10 + maximum-pool-size: {{ .Values.global.mysql.maxSize }} + +datawave: + mysql: + host: 'mysql' + dbname: 'cachedresults' + pool: + min-size: '5' + max-size: '20' + username: 'datawave' + password: 'secret' + query: + cachedResults: + enabled: ${CACHED_RESULTS:false} + remoteQuery: + queryServiceUri: "https://dwv-web-query:8443/query/v1/query" + # unlimited + maxBytesToBuffer: -1 + numFields: 900 + statementTemplates: + createTableTemplate: | + CREATE TABLE IF NOT EXISTS template ( + _user_ VARCHAR(200) NOT NULL, + _queryId_ VARCHAR(200) NOT NULL, + _logicName_ VARCHAR(200) NOT NULL, + _datatype_ VARCHAR(35) NOT NULL, + _eventId_ VARCHAR(50) NOT NULL, + _row_ LONGTEXT NOT NULL, + _colf_ LONGTEXT NOT NULL, + _markings_ VARCHAR(400) NOT NULL, + _column_markings_ LONGTEXT NOT NULL, + _column_timestamps_ LONGTEXT NOT NULL, + %FIELD_DEFINITIONS% + ) ENGINE = MyISAM + createTable: "CREATE TABLE %TABLE% LIKE template" + dropTable: "DROP TABLE %TABLE%" + dropView: "DROP VIEW %TABLE%" + insert: | + INSERT INTO %TABLE% ( + _user_, + _queryId_, + _logicName_, + _datatype_, + _eventId_, + _row_, + _colf_, + _markings_, + _column_markings_, + _column_timestamps_, + %PREPARED_FIELDS% + ) VALUES ( + ?, + ?, + ?, + ?, + ?, + ?, + ?, + ?, + ?, + ?, + %PREPARED_VALUES% + ) + createView: "CREATE VIEW %VIEW%(%VIEW_COLS%) AS SELECT %TABLE_COLS% FROM %TABLE%" diff --git a/configuration/configMapFiles/application-federation.yml b/configuration/configMapFiles/application-federation.yml new file mode 100644 index 0000000..baf261d --- /dev/null +++ b/configuration/configMapFiles/application-federation.yml @@ -0,0 +1,15 @@ +# This serves as a set of sensible defaults for authorization and query federation. +datawave: + authorization: + federation: + # Each entry in the following map will be registered as a FederatedAuthorizationService bean, named after the key + services: + FederatedAuthorizationService: + federatedAuthorizationUri: "https://{{ .Values.global.serviceDns.authorization.name }}:{{ .Values.global.serviceDns.authorization.port }}/{{ .Values.global.serviceDns.authorization.endpoint }}" + query: + federation: + # Each entry in the following map will be registered as a FederatedQueryService (RemoteQueryService) bean, named after the key + services: + FederatedQueryService: + queryServiceUri: 'https://{{ .Values.global.serviceDns.query.name }}:{{ .Values.global.serviceDns.query.port }}/query/v1' + queryMetricServiceUri: 'https://{{ .Values.global.serviceDns.metrics.name }}:{{ .Values.global.serviceDns.metrics.port }}/querymetric/v1/id' diff --git a/configuration/configMapFiles/application-k8s.yml b/configuration/configMapFiles/application-k8s.yml index e66ab62..25cc4fa 100644 --- a/configuration/configMapFiles/application-k8s.yml +++ b/configuration/configMapFiles/application-k8s.yml @@ -1,4 +1,30 @@ hazelcast: client: + clusterName: cache k8s: - service-dns-name: {{ .Values.global.serviceDns.cache.name }}.{{ .Release.Namespace }}.svc.cluster.local \ No newline at end of file + service-dns-name: {{ .Values.global.serviceDns.cache.name }}.{{ .Release.Namespace }}.svc.cluster.local + # This template is for configuring your site-specific properties for all microservices. +system.name: CONTAINERS +# Define the client certificates (in lower-case subjectDN form) that are allowed to call a service. Note that you only need to +# specify one value in the list below. +# Since enforce-allowed-callers is false, you can skip configuring this section if you want. +spring: + kafka: + bootstrap-servers: {{ .Values.global.serviceDns.kafka.name }}.{{ .Release.Namespace }}.svc.cluster.local:{{ .Values.global.serviceDns.kafka.port }} + consumer: + autoOffsetReset: earliest + enableAutoCommit: false + properties: + allow.auto.create.topics: false +# This is the accumulo configuration we use in services. These don't map directly to a properties class, but +# they are here to be used as a reference for other properties. +accumulo: + zookeepers: '{{ .Values.global.zookeeper.quorum }}' + instanceName: '{{ .Values.global.accumulo.instanceName }}' + username: '{{ .Values.global.accumulo.user }}' + password: '{{ .Values.global.accumulo.password }}' +# Configuration placeholders which 1) determines what backend will be used for transmitting query results +# and 2) determines the message size limit before claim checks are used with RabbitMQ messaging +messaging: + backend: kafka + maxMessageSizeBytes: 536870912 \ No newline at end of file diff --git a/configuration/configMapFiles/application-metricssource.yml b/configuration/configMapFiles/application-metricssource.yml new file mode 100755 index 0000000..b1bdb11 --- /dev/null +++ b/configuration/configMapFiles/application-metricssource.yml @@ -0,0 +1,23 @@ +# This profile should be added to your service if you depend on the +# query metric starter to send metrics to the query metric service. +spring: + cloud: + stream: + bindings: + queryMetricSource-out-0: + destination: queryMetricChannel + producer: + requiredGroups: queryMetricService + errorChannelEnabled: true + # NOTE: When defining your functions, be sure to include busConsumer, or else spring cloud bus will not work + function: + definition: queryMetricSource;busConsumer + +datawave: + query: + metric: + client: + confirmAckTimeoutMillis: 30000 +# To send metrics via REST, uncomment the following +# host: metrics +# transport: HTTPS diff --git a/configuration/configMapFiles/application-mrquery.yml b/configuration/configMapFiles/application-mrquery.yml new file mode 100755 index 0000000..6b2c940 --- /dev/null +++ b/configuration/configMapFiles/application-mrquery.yml @@ -0,0 +1,54 @@ +datawave: + query: + mapreduce: + fsConfigResources: + - ${HADOOP_CONF_DIR:/etc/hadoop/conf}/core-site.xml + - ${HADOOP_CONF_DIR:/etc/hadoop/conf}/hdfs-site.xml + - ${HADOOP_CONF_DIR:/etc/hadoop/conf}/mapred-site.xml + - ${HADOOP_CONF_DIR:/etc/hadoop/conf}/yarn-site.xml + callbackServletURL: "http://query:8080/query/v1/mapreduce/updateState" + mapReduceBaseDirectory: "/datawave/MapReduceService" + restrictInputFormats: true + validInputFormats: + - "org.apache.accumulo.core.client.mapreduce.AccumuloInputFormat" + - "datawave.mr.bulk.BulkInputFormat" + jobs: + 'BulkResultsJob': + startingClass: datawave.microservice.query.mapreduce.MapReduce + jobJarName: "MapReduceQueryCoreJob.jar" + description: "MapReduce job that runs a query and either puts the results into a table or files in HDFS" + hdfsUri: "hdfs://${HADOOP_HOST}:9000/" + jobTracker: "${HADOOP_HOST}:8021" + requiredRuntimeParameters: + queryId: java.lang.String + format: datawave.microservice.mapreduce.bulkresults.map.SerializationFormat + optionalRuntimeParameters: + outputTableName: java.lang.String + outputFormat: java.lang.String + jobConfigurationProperties: + "mapreduce.map.speculative": "false" + "mapreduce.map.output.compress": "false" + "mapreduce.output.fileoutputformat.compress": "false" + "mapreduce.job.user.classpath.first": "true" + # NOTE: Disable spring components which should not be run in a map-reduce context + jobSystemProperties: + "datawave.table.cache.enabled": "false" + "spring.profiles.active": "query,mrquery" + "spring.cloud.bus.enabled": "false" + "spring.cloud.discovery.enabled": "false" + "spring.cloud.consul.enabled": "false" + "spring.rabbitmq.discovery.enabled": "false" + "datawave.query.messaging.backend": "none" + "datawave.query.messaging.claimCheck.enabled": "false" + "datawave.query.storage.cache.enabled": "false" + "hazelcast.client.enabled": "false" + "spring.cloud.config.enabled": "false" + "datawave.query.metric.client.enabled": "false" + accumulo: + zookeepers: '${accumulo.zookeepers}' + instanceName: '${accumulo.instanceName}' + username: '${accumulo.username}' + password: '${accumulo.password}' + 'OozieJob': + hdfsUri: "hdfs://${HADOOP_HOST}:9000/" + jobTracker: "${HADOOP_HOST}:8021" \ No newline at end of file diff --git a/configuration/configMapFiles/application-query.yml b/configuration/configMapFiles/application-query.yml new file mode 100644 index 0000000..fb47737 --- /dev/null +++ b/configuration/configMapFiles/application-query.yml @@ -0,0 +1,573 @@ +# This profile should be included by any service which depends on the query starter. This +# file contains all of the configuration required to use the QueryLogicFactory. +warehouse: + accumulo: + zookeepers: '{{.Values.global.zookeeper.quorum}}' + instanceName: '{{.Values.global.accumulo.instanceName}}' + username: '{{.Values.global.accumulo.user}}' + password: '{{.Values.global.accumulo.password}}' + statsd: + host: localhost + port: 8125 + tables: + shard: + name: 'datawave.shard' + index: + name: 'datawave.shardIndex' + reverseIndex: + name: 'datawave.shardReverseIndex' + dateIndex: + name: 'datawave.dateIndex' + metadata: + name: 'datawave.metadata' + model: + name: 'datawave.metadata' + edge: + name: 'datawave.edge' + errorTables: + shard: + name: "datawave.error_s" + index: + name: "datawave.error_i" + reverseIndex: + name: "datawave.error_r" + dateIndex: + name: "" + metadata: + name: "datawave.error_m" + model: + name: "datawave.error_m" + metricTables: + shard: + name: "datawave.queryMetrics_s" + index: + name: "datawave.queryMetrics_i" + reverseIndex: + name: "datawave.queryMetrics_r" + dateIndex: + name: "" + metadata: + name: "datawave.queryMetrics_m" + model: + name: "datawave.queryMetrics_m" + defaults: + checkpointable: true + queryThreads: 100 + indexLookupThreads: 100 + dateIndexThreads: 20 + fullTableScanEnabled: false + baseIteratorPriority: 100 + maxIndexScanTimeMillis: 31536000000 + eventPerDayThreshold: 40000 + shardsPerDayThreshold: 20 + initialMaxTermThreshold: 2000 + finalMaxTermThreshold: 2000 + maxDepthThreshold: 2000 + maxUnfieldedExpansionThreshold: 50 + maxValueExpansionThreshold: 50 + maxOrExpansionThreshold: 500 + maxOrRangeThreshold: 10 + maxRangesPerRangeIvarator: 5 + maxOrRangeIvarators: 10 + maxOrExpansionFstThreshold: 750 + maxFieldIndexRangeSplit: 16 + maxIvaratorSources: 20 + maxEvaluationPipelines: 16 + maxPipelineCachedResults: 16 + hdfsSiteConfigURLs: 'file://${HADOOP_CONF_DIR:/etc/hadoop/conf}/core-site.xml,file://${HADOOP_CONF_DIR:/etc/hadoop/conf}/hdfs-site.xml' + ivaratorFstHdfsBaseURIs: "hdfs://${HADOOP_HOST:localhost}:9000/IvaratorCache" + ivaratorCacheBufferSize: 10000 + ivaratorMaxOpenFiles: 100 + ivaratorCacheScanPersistThreshold: 100000 + ivaratorCacheScanTimeoutMinutes: 60 + modelName: 'DATAWAVE' + edgeModelName: 'DATAWAVE_EDGE' + +datawave: + metadata: + all-metadata-auths: + - PRIVATE,PUBLIC + type-substitutions: + "[datawave.data.type.DateType]": "datawave.data.type.RawDateType" + + query: + parser: + skipTokenizeUnfieldedFields: + - "DOMETA" + tokenizedFields: + - "CONTENT" + logic: + factory: + enabled: true + # Uncomment the following line to override the query logic beans to load + # xmlBeansPath: "classpath:MyTestQueryLogicFactory.xml" + + # If desired, you may populate this map to redefine the name for each query logic. + # This can also be used to limit the available query logics. + queryLogicsByName: + "EventQuery": "EventQuery" + "ErrorEventQuery": "ErrorEventQuery" + "DiscoveryQuery": "DiscoveryQuery" + "ErrorDiscoveryQuery": "ErrorDiscoveryQuery" + "LuceneUUIDEventQuery": "LuceneUUIDEventQuery" + "ContentQuery": "ContentQuery" + "EdgeQuery": "EdgeQuery" + "CountQuery": "CountQuery" + "ErrorCountQuery": "ErrorCountQuery" + "FieldIndexCountQuery": "FieldIndexCountQuery" + "ErrorFieldIndexCountQuery": "ErrorFieldIndexCountQuery" + "TermFrequencyQuery": "TermFrequencyQuery" + "IndexStatsQuery": "IndexStatsQuery" + "QueryMetricsQuery": "QueryMetricsQuery" + "InternalQueryMetricsQuery": "InternalQueryMetricsQuery" + "FacetedQuery": "FacetedQuery" + "HitHighlights": "HitHighlights" + "EdgeEventQuery": "EdgeEventQuery" + "FederatedEventQuery": "FederatedEventQuery" + + # The max page size that a user can request. 0 turns off this feature + maxPageSize: 10000 + + # The number of bytes at which a page will be returned, event if the pagesize has not been reached. 0 turns off this feature + pageByteTrigger: 0 + logics: + BaseEventQuery: + checkpointable: ${warehouse.defaults.checkpointable} + accumuloPassword: ${warehouse.accumulo.password} + tableName: ${warehouse.tables.shard.name} + dateIndexTableName: ${warehouse.tables.dateIndex.name} + defaultDateTypeName: "EVENT" + metadataTableName: ${warehouse.tables.metadata.name} + indexTableName: ${warehouse.tables.index.name} + reverseIndexTableName: ${warehouse.tables.reverseIndex.name} + maxResults: -1 + queryThreads: ${warehouse.defaults.queryThreads} + indexLookupThreads: ${warehouse.defaults.indexLookupThreads} + dateIndexThreads: ${warehouse.defaults.dateIndexThreads} + fullTableScanEnabled: ${warehouse.defaults.fullTableScanEnabled} + includeDataTypeAsField: false + disableIndexOnlyDocuments: false + indexOnlyFilterFunctionsEnabled: false + includeHierarchyFields: false + hierarchyFieldOptions: + "FOO": "BAR" + baseIteratorPriority: ${warehouse.defaults.baseIteratorPriority} + maxIndexScanTimeMillis: ${warehouse.defaults.maxIndexScanTimeMillis} + collapseUids: false + collapseUidsThreshold: -1 + useEnrichers: true + contentFieldNames: + - 'CONTENT' + realmSuffixExclusionPatterns: + - '<.*>$' + minimumSelectivity: .2 + enricherClassNames: + - 'datawave.query.enrich.DatawaveTermFrequencyEnricher' + useFilters: false + filterClassNames: + - 'foo.bar' + filterOptions: + 'bar': "foo" + auditType: "ACTIVE" + logicDescription: "Retrieve sharded events/documents, leveraging the global index tables as needed" + eventPerDayThreshold: ${warehouse.defaults.eventPerDayThreshold} + shardsPerDayThreshold: ${warehouse.defaults.shardsPerDayThreshold} + initialMaxTermThreshold: ${warehouse.defaults.initialMaxTermThreshold} + finalMaxTermThreshold: ${warehouse.defaults.finalMaxTermThreshold} + maxDepthThreshold: ${warehouse.defaults.maxDepthThreshold} + maxUnfieldedExpansionThreshold: ${warehouse.defaults.maxUnfieldedExpansionThreshold} + maxValueExpansionThreshold: ${warehouse.defaults.maxValueExpansionThreshold} + maxOrExpansionThreshold: ${warehouse.defaults.maxOrExpansionThreshold} + maxOrRangeThreshold: ${warehouse.defaults.maxOrRangeThreshold} + maxOrExpansionFstThreshold: ${warehouse.defaults.maxOrExpansionFstThreshold} + maxFieldIndexRangeSplit: ${warehouse.defaults.maxFieldIndexRangeSplit} + maxIvaratorSources: ${warehouse.defaults.maxIvaratorSources} + maxEvaluationPipelines: ${warehouse.defaults.maxEvaluationPipelines} + maxPipelineCachedResults: ${warehouse.defaults.maxPipelineCachedResults} + hdfsSiteConfigURLs: ${warehouse.defaults.hdfsSiteConfigURLs} + zookeeperConfig: ${warehouse.accumulo.zookeepers} + ivaratorCacheDirConfigs: + - basePathURI: "hdfs://${HADOOP_HOST:localhost}:9000/IvaratorCache" + ivaratorFstHdfsBaseURIs: ${warehouse.defaults.ivaratorFstHdfsBaseURIs} + ivaratorCacheBufferSize: ${warehouse.defaults.ivaratorCacheBufferSize} + ivaratorMaxOpenFiles: ${warehouse.defaults.ivaratorMaxOpenFiles} + ivaratorCacheScanPersistThreshold: ${warehouse.defaults.ivaratorCacheScanPersistThreshold} + ivaratorCacheScanTimeoutMinutes: ${warehouse.defaults.ivaratorCacheScanTimeoutMinutes} + eventQueryDataDecoratorTransformer: + requestedDecorators: + - "CSV" + - "WIKIPEDIA" + dataDecorators: + "CSV": + "EVENT_ID": "https://localhost:8443/DataWave/Query/lookupUUID/EVENT_ID?uuid=@field_value@&parameters=data.decorators:CSV" + "UUID": "https://localhost:8443/DataWave/Query/lookupUUID/UUID?uuid=@field_value@&parameters=data.decorators:CSV" + "PARENT_UUID": "https://localhost:8443/DataWave/Query/lookupUUID/PARENT_UUID?uuid=@field_value@&parameters=data.decorators:CSV" + "WIKIPEDIA": + "PAGE_ID": "https://localhost:8443/DataWave/Query/lookupUUID/PAGE_ID?uuid=@field_value@&parameters=data.decorators:WIKIPEDIA" + "PAGE_TITLE": "https://localhost:8443/DataWave/Query/lookupUUID/PAGE_TITLE?uuid=@field_value@&parameters=data.decorators:WIKIPEDIA" + modelTableName: ${warehouse.tables.model.name} + modelName: ${warehouse.defaults.modelName} + querySyntaxParsers: + JEXL: "" + LUCENE: "LuceneToJexlQueryParser" + LUCENE-UUID: "LuceneToJexlUUIDQueryParser" + TOKENIZED-LUCENE: "TokenizedLuceneToJexlQueryParser" + sendTimingToStatsd: false + collectQueryMetrics: true + logTimingDetails: true + statsdHost: ${warehouse.statsd.host} + statsdPort: ${warehouse.statsd.port} + evaluationOnlyFields: "" + maxConcurrentTasks: 10 + requiredRoles: + - "AuthorizedUser" + + EventQuery: + checkpointable: ${warehouse.defaults.checkpointable} + logicDescription: "Query the sharded event/document schema, leveraging the global index tables as needed" + + ErrorEventQuery: + checkpointable: ${warehouse.defaults.checkpointable} + logicDescription: "Retrieve events/documents that encountered one or more errors during ingest" + tableName: ${warehouse.errorTables.shard.name} + metadataTableName: ${warehouse.errorTables.metadata.name} + dateIndexTableName: "" + indexTableName: ${warehouse.errorTables.index.name} + reverseIndexTableName: ${warehouse.errorTables.reverseIndex.name} + includeHierarchyFields: false + + DiscoveryQuery: + checkpointable: ${warehouse.defaults.checkpointable} + tableName: ${warehouse.tables.shard.name} + indexTableName: ${warehouse.tables.index.name} + reverseIndexTableName: ${warehouse.tables.reverseIndex.name} + metadataTableName: ${warehouse.tables.metadata.name} + modelTableName: ${warehouse.tables.model.name} + modelName: ${warehouse.defaults.modelName} + fullTableScanEnabled: ${warehouse.defaults.fullTableScanEnabled} + allowLeadingWildcard: true + auditType: "NONE" + maxResults: -1 + maxWork: -1 + logicDescription: "Discovery query that returns information from the index about the supplied term(s)" + + ErrorDiscoveryQuery: + checkpointable: ${warehouse.defaults.checkpointable} + tableName: ${warehouse.errorTables.shard.name} + indexTableName: ${warehouse.errorTables.index.name} + reverseIndexTableName: ${warehouse.errorTables.reverseIndex.name} + maxResults: -1 + maxWork: -1 + metadataTableName: ${warehouse.errorTables.metadata.name} + modelTableName: ${warehouse.errorTables.model.name} + modelName: ${warehouse.defaults.modelName} + fullTableScanEnabled: ${warehouse.defaults.fullTableScanEnabled} + allowLeadingWildcard: true + auditType: "NONE" + logicDescription: "Discovery query that returns information from the ingest errors index about the supplied term(s)" + + LuceneUUIDEventQuery: + checkpointable: ${warehouse.defaults.checkpointable} + logicDescription: "Composite query logic that retrieves records from the event and error tables, based on known UUID fields, ie, those configured via UUIDTypeList in QueryLogicFactory.xml" + auditType: "NONE" + eventQuery: + auditType: "NONE" + logicDescription: "Lucene query for event/document UUIDs" + mandatoryQuerySyntax: + - "LUCENE-UUID" + connPoolName: "UUID" + errorEventQuery: + auditType: "NONE" + logicDescription: "Lucene query for event/document UUIDs for events that encountered errors at ingest time" + mandatoryQuerySyntax: + - "LUCENE-UUID" + connPoolName: "UUID" + tableName: ${warehouse.errorTables.shard.name} + dateIndexTableName: ${warehouse.errorTables.dateIndex.name} + metadataTableName: ${warehouse.errorTables.metadata.name} + indexTableName: ${warehouse.errorTables.index.name} + reverseIndexTableName: ${warehouse.errorTables.reverseIndex.name} + + ContentQuery: + checkpointable: ${warehouse.defaults.checkpointable} + tableName: ${warehouse.tables.shard.name} + maxResults: -1 + maxWork: -1 + auditType: "NONE" + logicDescription: "Query that returns a document given the document identifier" + + EdgeQuery: + checkpointable: ${warehouse.defaults.checkpointable} + tableName: ${warehouse.tables.edge.name} + metadataTableName: ${warehouse.tables.metadata.name} + modelTableName: ${warehouse.tables.model.name} + modelName: ${warehouse.defaults.edgeModelName} + maxResults: 25000 + maxConcurrentTasks: 10 + maxWork: -1 + queryThreads: 16 + auditType: "NONE" + logicDescription: "Retrieve graph edges matching the search term(s)" + querySyntaxParsers: + "JEXL": "" + "LIST": "" + "LIMITED_JEXL": "" + "LUCENE": "" + + CountQuery: + checkpointable: ${warehouse.defaults.checkpointable} + logicDescription: "Retrieve event/document counts based on your search criteria" + + ErrorCountQuery: + checkpointable: ${warehouse.defaults.checkpointable} + logicDescription: "Retrieve counts of errored events based on your search criteria" + tableName: ${warehouse.errorTables.shard.name} + metadataTableName: ${warehouse.errorTables.metadata.name} + indexTableName: ${warehouse.errorTables.index.name} + reverseIndexTableName: ${warehouse.errorTables.reverseIndex.name} + + FieldIndexCountQuery: + checkpointable: false + tableName: ${warehouse.tables.shard.name} + indexTableName: ${warehouse.tables.index.name} + reverseIndexTableName: ${warehouse.tables.reverseIndex.name} + metadataTableName: ${warehouse.tables.metadata.name} + maxResults: -1 + maxWork: -1 + queryThreads: ${warehouse.defaults.queryThreads} + modelTableName: ${warehouse.tables.model.name} + modelName: "DATAWAVE" + maxUniqueValues: 20000 + maxConcurrentTasks: 10 + auditType: "NONE" + logicDescription: "Indexed Fields Only: Given FIELDNAME returns counts for each unique value. Given FIELDNAME:FIELDVALUE returns count for only that value." + + ErrorFieldIndexCountQuery: + checkpointable: false + tableName: ${warehouse.errorTables.shard.name} + indexTableName: ${warehouse.errorTables.index.name} + reverseIndexTableName: ${warehouse.errorTables.reverseIndex.name} + metadataTableName: ${warehouse.errorTables.metadata.name} + maxResults: -1 + maxWork: -1 + queryThreads: ${warehouse.defaults.queryThreads} + modelTableName: ${warehouse.errorTables.model.name} + modelName: "DATAWAVE" + maxUniqueValues: 20000 + maxConcurrentTasks: 10 + auditType: "NONE" + logicDescription: "FieldIndex count query (experimental)" + + TermFrequencyQuery: + tableName: ${warehouse.tables.shard.name} + maxResults: -1 + maxWork: -14 + auditType: "NONE" + logicDescription: "Query that returns data from the term frequency query table" + + IndexStatsQuery: + auditType: "NONE" + + QueryMetricsQuery: + checkpointable: ${warehouse.defaults.checkpointable} + logicDescription: "Retrieve query metrics based on the given search term(s)" + includeHierarchyFields: false + modelTableName: ${warehouse.metricTables.model.name} + modelName: "NONE" + tableName: ${warehouse.metricTables.shard.name} + dateIndexTableName: ${warehouse.metricTables.dateIndex.name} + metadataTableName: ${warehouse.metricTables.metadata.name} + indexTableName: ${warehouse.metricTables.index.name} + reverseIndexTableName: ${warehouse.metricTables.reverseIndex.name} + auditType: "NONE" + collectQueryMetrics: true + + InternalQueryMetricsQuery: + collectQueryMetrics: false + requiredRoles: + - "AuthorizedServer" + + FacetedQuery: + checkpointable: ${warehouse.defaults.checkpointable} + auditType: "NONE" + logicDescription: "Faceted search over indexed fields, returning aggregate counts for field values" + facetedSearchType: "FIELD_VALUE_FACETS" + facetTableName: "datawave.facets" + facetMetadataTableName: "datawave.facetMetadata" + facetHashTableName: "datawave.facetHashes" + maximumFacetGrouping: 200 + minimumFacet: 1 + streaming: true + querySyntaxParsers: + JEXL: "" + LUCENE: "LuceneToJexlQueryParser" + LUCENE-UUID: "LuceneToJexlUUIDQueryParser" + + HitHighlights: + checkpointable: ${warehouse.defaults.checkpointable} + accumuloPassword: ${warehouse.accumulo.password} + tableName: ${warehouse.tables.shard.name} + dateIndexTableName: ${warehouse.tables.dateIndex.name} + defaultDateTypeName: "EVENT" + metadataTableName: ${warehouse.tables.metadata.name} + indexTableName: ${warehouse.tables.index.name} + reverseIndexTableName: ${warehouse.tables.reverseIndex.name} + queryThreads: ${warehouse.defaults.indexLookupThreads} + fullTableScanEnabled: ${warehouse.defaults.fullTableScanEnabled} + minimumSelectivity: .2 + includeDataTypeAsField: false + includeGroupingContext: false + useEnrichers: false + auditType: "NONE" + logicDescription: "Fast boolean query over indexed fields, only returning fields queried on" + eventPerDayThreshold: 40000 + shardsPerDayThreshold: ${warehouse.defaults.shardsPerDayThreshold} + initialMaxTermThreshold: ${warehouse.defaults.initialMaxTermThreshold} + finalMaxTermThreshold: ${warehouse.defaults.finalMaxTermThreshold} + maxConcurrentTasks: 10 + maxDepthThreshold: ${warehouse.defaults.maxDepthThreshold} + maxUnfieldedExpansionThreshold: ${warehouse.defaults.maxUnfieldedExpansionThreshold} + maxValueExpansionThreshold: ${warehouse.defaults.maxValueExpansionThreshold} + maxOrExpansionThreshold: ${warehouse.defaults.maxOrExpansionThreshold} + maxOrRangeThreshold: ${warehouse.defaults.maxOrRangeThreshold} + maxRangesPerRangeIvarator: ${warehouse.defaults.maxRangesPerRangeIvarator} + maxOrRangeIvarators: ${warehouse.defaults.maxOrRangeIvarators} + maxOrExpansionFstThreshold: ${warehouse.defaults.maxOrExpansionFstThreshold} + maxFieldIndexRangeSplit: ${warehouse.defaults.maxFieldIndexRangeSplit} + maxEvaluationPipelines: ${warehouse.defaults.maxEvaluationPipelines} + maxPipelineCachedResults: ${warehouse.defaults.maxPipelineCachedResults} + hdfsSiteConfigURLs: ${warehouse.defaults.hdfsSiteConfigURLs} + zookeeperConfig: ${warehouse.accumulo.zookeepers} + ivaratorCacheDirConfigs: + - basePathURI: "hdfs://${HADOOP_HOST:localhost}:9000/IvaratorCache" + ivaratorFstHdfsBaseURIs: ${warehouse.defaults.ivaratorFstHdfsBaseURIs} + ivaratorCacheBufferSize: 10000 + ivaratorMaxOpenFiles: ${warehouse.defaults.ivaratorMaxOpenFiles} + ivaratorCacheScanPersistThreshold: 100000 + ivaratorCacheScanTimeoutMinutes: ${warehouse.defaults.ivaratorCacheScanTimeoutMinutes} + querySyntaxParsers: + JEXL: "" + LUCENE: "LuceneToJexlQueryParser" + LUCENE-UUID: "LuceneToJexlUUIDQueryParser" + + EdgeEventQuery: + checkpointable: ${warehouse.defaults.checkpointable} + logicDescription: "Use results of an EdgeQuery to obtain events/documents that created the given edge" + edgeModelName: "DATAWAVE_EDGE" + modelTableName: ${warehouse.tables.model.name} + + uuidTypes: &defaultUuidTypes + 'EVENT_ID': + fieldName: 'EVENT_ID' + queryLogics: + 'default': 'LuceneUUIDEventQuery' + allowedWildcardAfter: 28 + 'UUID': + fieldName: 'UUID' + queryLogics: + 'default': 'LuceneUUIDEventQuery' + 'PARENT_UUID': + fieldName: 'PARENT_UUID' + queryLogics: + 'default': 'LuceneUUIDEventQuery' + 'PAGE_ID': + fieldName: 'PAGE_ID' + queryLogics: + 'default': 'LuceneUUIDEventQuery' + 'PAGE_TITLE': + fieldName: 'PAGE_TITLE' + queryLogics: + 'default': 'LuceneUUIDEventQuery' + + lookup: + columnVisibility: "" + beginDate: "20100101 000000.000" + types: *defaultUuidTypes + + translateid: + columnVisibility: "" + beginDate: "20100101 000000.000" + types: *defaultUuidTypes + + edge: + # Uncomment the following line to override the edge beans to load + # xmlBeansPath: "classpath:EdgeBeans.xml" + model: + baseFieldMap: + EDGE_SOURCE: 'SOURCE' + EDGE_SINK: 'SINK' + EDGE_TYPE: 'TYPE' + EDGE_RELATIONSHIP: 'RELATION' + EDGE_ATTRIBUTE1: 'ATTRIBUTE1' + EDGE_ATTRIBUTE2: 'ATTRIBUTE2' + EDGE_ATTRIBUTE3: 'ATTRIBUTE3' + DATE: 'DATE' + STATS_EDGE: 'STATS_TYPE' + keyUtilFieldMap: + ENRICHMENT_TYPE: 'ENRICHMENT_TYPE' + FACT_TYPE: 'FACT_TYPE' + GROUPED_FIELDS: 'GROUPED_FIELDS' + transformFieldMap: + COUNT: 'COUNT' + COUNTS: 'COUNTS' + LOAD_DATE: 'LOADDATE' + ACTIVITY_DATE: 'ACTIVITY_DATE' + fieldMappings: + - fieldName: "SOURCE" + modelFieldName: "VERTEXA" + direction: "REVERSE" + indexOnly: false + - fieldName: "SOURCE" + modelFieldName: "VERTEXA" + direction: "FORWARD" + indexOnly: false + - fieldName: "SINK" + modelFieldName: "VERTEXB" + direction: "REVERSE" + indexOnly: false + - fieldName: "SINK" + modelFieldName: "VERTEXB" + direction: "FORWARD" + indexOnly: false + - fieldName: "RELATION" + modelFieldName: "RELATION" + direction: "REVERSE" + indexOnly: false + - fieldName: "RELATION" + modelFieldName: "RELATION" + direction: "FORWARD" + indexOnly: false + - fieldName: "TYPE" + modelFieldName: "TYPE" + direction: "REVERSE" + indexOnly: false + - fieldName: "TYPE" + modelFieldName: "TYPE" + direction: "FORWARD" + indexOnly: false + - fieldName: "ATTRIBUTE1" + modelFieldName: "ATTR1" + direction: "REVERSE" + indexOnly: false + - fieldName: "ATTRIBUTE1" + modelFieldName: "ATTR1" + direction: "FORWARD" + indexOnly: false + - fieldName: "ATTRIBUTE2" + modelFieldName: "ATTR2" + direction: "REVERSE" + indexOnly: false + - fieldName: "ATTRIBUTE2" + modelFieldName: "ATTR2" + direction: "FORWARD" + indexOnly: false + - fieldName: "ATTRIBUTE3" + modelFieldName: "ATTR3" + direction: "REVERSE" + indexOnly: false + - fieldName: "ATTRIBUTE3" + modelFieldName: "ATTR3" + direction: "FORWARD" + indexOnly: false + + diff --git a/configuration/configMapFiles/application-querymessaging.yml b/configuration/configMapFiles/application-querymessaging.yml new file mode 100755 index 0000000..fd5b0c9 --- /dev/null +++ b/configuration/configMapFiles/application-querymessaging.yml @@ -0,0 +1,11 @@ +# This profile should be included by any service which depends on the query starter and +# wants to read/write query stats from/to the query storage cache, or read/write query +# results from/to the query results messaging backend. +datawave: + query: + messaging: + backend: ${messaging.backend} + rabbitmq: + maxMessageSizeBytes: ${messaging.maxMessageSizeBytes} + kafka: + partitions: 2 diff --git a/configuration/configMapFiles/application.yml b/configuration/configMapFiles/application.yml index 1b58eae..b2befe5 100644 --- a/configuration/configMapFiles/application.yml +++ b/configuration/configMapFiles/application.yml @@ -13,6 +13,7 @@ management: endpoints.web.base-path: /mgmt endpoints.web.exposure.include: "*" server: + cdn-uri: /${spring.application.name}/ non-secure-port: 8080 outbound-ssl: key-store: ${server.ssl.key-store} @@ -32,6 +33,8 @@ server: trust-store-type: '{{ .Values.global.secrets.truststore.type }}' trust-store-password: '{{ .Values.global.secrets.truststore.password }}' spring: + jackson: + default-property-include: non_null cloud: consul: enabled: false @@ -40,10 +43,13 @@ spring: enabled: false failFast: true host: '{{ .Values.global.serviceDns.rabbitmq.name }}' + publisher-confirm-type: simple + publisher-confirms: true + publisher-returns: true security: datawave: enforce-allowed-callers: false issuers-required: true jwt.ttl: 86400 - manager-role: Administator,JBossAdministrator + manager-roles: Administator,JBossAdministrator user.password: passwordNotUsed \ No newline at end of file diff --git a/configuration/configMapFiles/audit.yml b/configuration/configMapFiles/audit.yml index 46d64e1..0a0fa55 100644 --- a/configuration/configMapFiles/audit.yml +++ b/configuration/configMapFiles/audit.yml @@ -1,14 +1,25 @@ audit: + confirmAckEnabled: false + replay: + enabled: true auditors: - accumulo: + dump: enabled: false + pathUri: file:///audit + accumulo: + enabled: true + accumuloConfig: + zookeepers: '${accumulo.zookeepers}' + instanceName: '${accumulo.instanceName}' + username: '${accumulo.username}' + password: '${accumulo.password}' file: enabled: false maxFileAgeSeconds: 60 maxLengthFileMB: 1 - pathUri: s3a://signus-audits/ + pathUri: file:///audit log: - enabled: false + enabled: true logging: level: datawave.microservice.audit: DEBUG diff --git a/configuration/configMapFiles/executor-pool1.yml b/configuration/configMapFiles/executor-pool1.yml new file mode 100755 index 0000000..8850c4a --- /dev/null +++ b/configuration/configMapFiles/executor-pool1.yml @@ -0,0 +1,20 @@ +# This is where you set properties which are specific to pool1 +executor: + poolName: 'pool1' + +datawave: + swagger: + title: "Query Executor Service (Pool 1)" + description: "REST API provided by the Query Executor Service" + connection: + factory: + pools: + 'pool1': + zookeepers: '${accumulo.zookeepers}' + instance: '${accumulo.instanceName}' + username: '${accumulo.username}' + password: '${accumulo.password}' + lowPriorityPoolSize: 40 + normalPriorityPoolSize: 40 + highPriorityPoolSize: 40 + adminPriorityPoolSize: 40 diff --git a/configuration/configMapFiles/executor-pool2.yml b/configuration/configMapFiles/executor-pool2.yml new file mode 100755 index 0000000..a4757d9 --- /dev/null +++ b/configuration/configMapFiles/executor-pool2.yml @@ -0,0 +1,20 @@ +# This is where you set properties which are specific to pool2 +executor: + poolName: 'pool2' + +datawave: + swagger: + title: "Query Executor Service (Pool 2)" + description: "REST API provided by the Query Executor Service" + connection: + factory: + pools: + 'pool2': + zookeepers: '${accumulo.zookeepers}' + instance: '${accumulo.instanceName}' + username: '${accumulo.username}' + password: '${accumulo.password}' + lowPriorityPoolSize: 40 + normalPriorityPoolSize: 40 + highPriorityPoolSize: 40 + adminPriorityPoolSize: 40 diff --git a/configuration/configMapFiles/executor.yml b/configuration/configMapFiles/executor.yml new file mode 100755 index 0000000..da54229 --- /dev/null +++ b/configuration/configMapFiles/executor.yml @@ -0,0 +1,67 @@ +# This is where you set properties which are common to all executors +server: + # since the application names include the pools, lets override the context path to simply be executor + servlet.context-path: /executor + cdn-uri: /executor/ + +logging: + level: + root: INFO + datawave.query: DEBUG + datawave.microservice.query: DEBUG + datawave.microservice.query.executor: DEBUG + org.apache.kafka: ERROR + datawave.microservice.query.storage: WARN + +warehouse: + accumulo: + zookeepers: '${accumulo.zookeepers}' + instanceName: '${accumulo.instanceName}' + username: '${accumulo.username}' + password: '${accumulo.password}' + +datawave: + table: + cache: + zookeepers: '${accumulo.zookeepers}' + tableNames: + - '${warehouse.tables.metadata.name}' + poolName: 'default' + reloadInterval: 360000 + evictionReaperIntervalInSeconds: 360 + numLocks: 3 + maxRetries: 3 + reload-crontab: '* * * * * ?' + connection: + factory: + defaultPool: "default" + pools: + "default": + zookeepers: '${accumulo.zookeepers}' + instance: '${accumulo.instanceName}' + username: '${accumulo.username}' + password: '${accumulo.password}' + lowPriorityPoolSize: 40 + normalPriorityPoolSize: 40 + highPriorityPoolSize: 40 + adminPriorityPoolSize: 40 + query: + executor: + pool: "${executor.poolName}" + availableResultsPageMultiplier: 2.5 + maxQueueSize: 400 + coreThreads: 10 + maxThreads: 40 + keepAliveMs: 600000 + queryStatusExpirationMs: 60000 + checkpointFlushMs: 1000 + checkpointFlushResults: 2 + orphanThresholdMs: 60000 + monitorTaskLease: 30 + monitorTaskLeaseUnit: SECONDS + monitor: + enabled: true + scheduler-crontab: '* * * * * ?' + logStatusPeriodMs: 600000 + logStatusWhenChangedMs: 300000 + queryMetricsUrlPrefix: https://localhost:8543/querymetric/v1/id/ diff --git a/configuration/configMapFiles/modification.yml b/configuration/configMapFiles/modification.yml new file mode 100644 index 0000000..0ed3ebb --- /dev/null +++ b/configuration/configMapFiles/modification.yml @@ -0,0 +1,68 @@ +# This file contains all of the configuration required to use the modification service +logging: + level: + root: INFO + datawave.modification: DEBUG + datawave.microservice.modification: DEBUG + datawave.microservice.modification.query: DEBUG + +datawave: + swagger: + title: "Modification (Mutable Metadata) Service" + description: "REST API provided by the Modification (Mutable Metadata) Service" + + modification: + query: + queryURI: https://dwv-web-query:8443/query/v1 + queryPool: pool1 + remoteQueryTimeout: 1 + remoteQueryTimeoutUnit: MINUTES + data: + tableName: ${warehouse.tables.metadata.name} + poolName: "default" + handlers: + authorizedRoles: + - "AuthorizedUser" + eventTableName: ${warehouse.tables.shard.name} + metadataTableName: ${warehouse.tables.metadata.name} + indexTableName: ${warehouse.tables.index.name} + reverseIndexTableName: ${warehouse.tables.reverseIndex.name} + securityMarkingExemptFields: + - "ExampleExemptField" + requiresAudit: false + indexOnlyMap: + "SomeEventField": "SomeIndexField1,SomeIndexField2" + indexOnlySuffixes: + - "ExampleSuffix" + contentFields: + - "ExampleContentField" + + table: + cache: + zookeepers: '${accumulo.zookeepers}' + tableNames: + - '${warehouse.tables.metadata.name}' + poolName: 'default' + reloadInterval: 360000 + evictionReaperIntervalInSeconds: 360 + numLocks: 3 + maxRetries: 3 + reload-crontab: '* * * * * ?' + connection: + factory: + defaultPool: "default" + pools: + "default": + zookeepers: '${accumulo.zookeepers}' + instance: '${accumulo.instanceName}' + username: '${accumulo.username}' + password: '${accumulo.password}' + lowPriorityPoolSize: 40 + normalPriorityPoolSize: 40 + highPriorityPoolSize: 40 + adminPriorityPoolSize: 40 + + security: + util: + subjectDnPattern: "(?:^|,)\\s*OU\\s*=\\s*My Department\\s*(?:,|$)" + npeOuList: "EXAMPLE_SERVER_OU1,EXAMPLE_SERVER_OU2" \ No newline at end of file diff --git a/configuration/configMapFiles/mrquery.yml b/configuration/configMapFiles/mrquery.yml new file mode 100755 index 0000000..2e3a573 --- /dev/null +++ b/configuration/configMapFiles/mrquery.yml @@ -0,0 +1,31 @@ +logging: + level: + root: INFO + org.springframework.cloud.bootstrap.config: DEBUG + datawave.microservice.query: DEBUG + +datawave: + table: + cache: + zookeepers: '${accumulo.zookeepers}' + tableNames: + - '${warehouse.tables.metadata.name}' + poolName: 'default' + reloadInterval: 360000 + evictionReaperIntervalInSeconds: 360 + numLocks: 3 + maxRetries: 3 + reload-crontab: '* * * * * ?' + connection: + factory: + defaultPool: "default" + pools: + "default": + zookeepers: '${accumulo.zookeepers}' + instance: '${accumulo.instanceName}' + username: '${accumulo.username}' + password: '${accumulo.password}' + lowPriorityPoolSize: 40 + normalPriorityPoolSize: 40 + highPriorityPoolSize: 40 + adminPriorityPoolSize: 40 \ No newline at end of file diff --git a/configuration/configMapFiles/query.yml b/configuration/configMapFiles/query.yml new file mode 100755 index 0000000..c8ee1de --- /dev/null +++ b/configuration/configMapFiles/query.yml @@ -0,0 +1,74 @@ +spring: + lifecycle: + # Set the shutdown grace period + timeout-per-shutdown-phase: 5s + +management: + endpoint: + # Enable the shutdown endpoint for the query service + shutdown: + enabled: true + +# Query requires a client certificate +server: + ssl: + client-auth: NEED + # Enable graceful shutdown + shutdown: "graceful" + +logging: + level: + root: DEBUG + org.springframework.cloud.bootstrap.config: DEBUG + datawave.microservice.query: DEBUG + org.apache.kafka: ERROR + datawave.microservice.query.storage: WARN + +datawave: + swagger: + title: "Query Service" + description: "REST API provided by the Query Service" + query: + nextCall: + resultPollInterval: 500 + statusUpdateInterval: 500 + expiration: + callTimeout: 1 + callTimeoutUnit: HOURS + shortCircuitCheckTime: 60 + shortCircuitCheckTimeUnit: MINUTES + shortCircuitTimeout: 55 + shortCircuitTimeoutUnit: MINUTES + longRunningQueryTimeout: 24 + longRunningQueryTimeoutUnit: HOURS + monitor: + monitorInterval: 30 + monitorIntervalUnit: SECONDS + doc: + menu: + extras: '' + table: + cache: + enabled: false + web: + accumulo: + uri: 'https://accumulo:9143/accumulo' + cache: + uri: 'https://cache:8843/cache' + config: + uri: 'https://configuration:8888/configserver' + authorization: + uri: 'https://authorization:8343/authorization' + audit: + uri: 'https://audit-service:9043/audit' + metrics: + uri: 'https://querymetric:8543/querymetric' + dictionary: + uri: 'https://dictionary:8643/dictionary' + executor: + uri: 'https://executor:8743/executor' + +audit-client: + discovery: + enabled: false + uri: '${AUDIT_SERVER_URL:http://localhost:11111/audit}' diff --git a/configuration/configMapFiles/querymetric.yml b/configuration/configMapFiles/querymetric.yml new file mode 100755 index 0000000..325380f --- /dev/null +++ b/configuration/configMapFiles/querymetric.yml @@ -0,0 +1,124 @@ +# Query Metrics requires a client certificate +server: + ssl: + client-auth: NEED + +spring: + cloud: + stream: + bindings: + queryMetricSource-out-0: + destination: queryMetricChannel + producer: + errorChannelEnabled: true + queryMetricSink-in-0: + destination: queryMetricChannel + group: queryMetricService + # NOTE: When defining your functions, be sure to include busConsumer, or else spring cloud bus will not work + function: + definition: queryMetricSource;queryMetricSink;busConsumer + +warehouse-cluster: + accumulo: + zookeepers: '${accumulo.zookeepers}' + instanceName: '${accumulo.instanceName}' + username: '${accumulo.username}' + password: '${accumulo.password}' + +logging: + level: + ROOT: DEBUG + datawave: + microservice.querymetric: DEBUG + iterators: error + query: error + ingest: error + security: error + +datawave: + swagger: + title: "Query Metric Service" + description: "REST API provided by the Query Metric Service" + query: + metric: + handler: + zookeepers: ${warehouse-cluster.accumulo.zookeepers} + instanceName: ${warehouse-cluster.accumulo.instanceName} + username: ${warehouse-cluster.accumulo.username} + password: ${warehouse-cluster.accumulo.password} + accumuloClientPoolSize: 16 + mapStoreWriteThreads: 1 + numShards: 10 + fieldLengthThreshold: 4049 + shardTableName: datawave.queryMetrics_s + indexTableName: datawave.queryMetrics_i + dateIndexTableName: datawave.queryMetrics_di + reverseIndexTableName: datawave.queryMetrics_r + metadataTableName: datawave.queryMetrics_m + metadataDefaultAuths: PUBLIC + recordWriterMaxMemory: 10 + recordWriterMaxLatency: 16 + recordWriterNumThreads: 4 + enableBloomFilter: false + queryVisibility: PUBLIC + defaultMetricVisibility: PUBLIC + defaultMetricMarkings: + columnVisibility: PUBLIC + baseMaps: "{}" + queryPool: "pool1" + timely: + enabled: false + confirmAckTimeoutMillis: 30000 + + # this should be consolidated into a metadata application profile + metadata: + all-metadata-auths: + - PRIVATE + - PUBLIC + type-substitutions: + "[datawave.data.type.DateType]": "datawave.data.type.RawDateType" + +hazelcast: + client.enabled: false + server: + enabled: true + xml-config: | + + + + 1 + + 600 + + 3600 + com.hazelcast.spi.merge.LatestUpdateMergePolicy + true + + + + datawave.microservice.querymetric.persistence.AccumuloMapStore$Factory + 1 + 1000 + + + + + 1 + + 600 + + 3600 + com.hazelcast.spi.merge.LatestUpdateMergePolicy + true + + + + datawave.microservice.querymetric.persistence.AccumuloMapLoader$Factory + + + + clusterName: '${spring.application.name}' diff --git a/configuration/values.yaml b/configuration/values.yaml index fd3a866..c736a0d 100644 --- a/configuration/values.yaml +++ b/configuration/values.yaml @@ -1,4 +1,17 @@ global: + mysql: + user: datawave + minIdle: 10 + maxSize: 10 + configMap: + name: mysql-init-config + init: + - name: init-db + fileName: init-db.sql + fileContents: |- + create database cachedresults; + use cachedresults; + GRANT ALL PRIVILEGES ON *.* TO 'datawave'@'%' WITH GRANT OPTION; dockerRegistry: url: ghcr.io/nationalsecurityagency volumes: @@ -49,7 +62,17 @@ global: endpoint: authorization/v1/authorize rabbitmq: name: rabbitmq - + kafka: + name: kafka + port: 9092 + mysql: + name: mysql + query: + name: query + port: 8080 + metrics: + name: query-metrics + port: 8080 image: name: datawave-config-service pullPolicy: IfNotPresent diff --git a/datawave-driver.sh b/datawave-driver.sh index 1d9435e..279444e 100755 --- a/datawave-driver.sh +++ b/datawave-driver.sh @@ -55,6 +55,8 @@ package_helm_dependencies() { local base_dir="$1" local chart_file="$base_dir"/Chart.yaml + echo "Processing $chart_file" + local dependencies=$(yq eval '.dependencies[]' "$chart_file") if [ -z "$dependencies" ]; then return diff --git a/datawave-qms-stack/.helmignore b/datawave-qms-stack/.helmignore deleted file mode 100644 index 1c1043d..0000000 --- a/datawave-qms-stack/.helmignore +++ /dev/null @@ -1,19 +0,0 @@ -########################################### -# Ignores All File or Path Related to Git # -########################################### - -.git - -##################################### -# Ignores All Development Resources # -##################################### - -development/ -setup.sh - -######################## -# Ignores All Archives # -######################## - -*.tar.gz -datawave-system-*.tgz diff --git a/datawave-qms-stack/.schema.yaml b/datawave-qms-stack/.schema.yaml deleted file mode 100644 index 546b749..0000000 --- a/datawave-qms-stack/.schema.yaml +++ /dev/null @@ -1,13 +0,0 @@ -# Required -input: - - values.yaml - -draft: 2020 -indent: 4 -output: values.schema.json - -schemaRoot: - id: https://code.nsa.org/datawave/schema - title: Helm Values Schema - description: Schema for DataWave Helm values - additionalProperties: true diff --git a/datawave-qms-stack/Chart.lock b/datawave-qms-stack/Chart.lock deleted file mode 100644 index 2e6bde4..0000000 --- a/datawave-qms-stack/Chart.lock +++ /dev/null @@ -1,21 +0,0 @@ -dependencies: -- name: dwv-ingest - repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts - version: 1.0.0 -- name: dwv-hadoop - repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts - version: 1.0.0 -- name: dwv-hadoop-config - repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts - version: 1.0.0 -- name: dwv-zookeeper - repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts - version: 1.0.0 -- name: dwv-accumulo - repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts - version: 1.0.0 -- name: datawave-qms-umbrella - repository: file://../datawave-qms-umbrella - version: 1.0.0-SNAPSHOT -digest: sha256:425b773c0ee3abf3d311df05c0213f9ba5af887792be8f8edaaf628c4ac3207a -generated: "2024-10-08T11:06:21.957957643Z" diff --git a/datawave-qms-stack/Chart.yaml b/datawave-qms-stack/Chart.yaml deleted file mode 100644 index 0c1b7a6..0000000 --- a/datawave-qms-stack/Chart.yaml +++ /dev/null @@ -1,38 +0,0 @@ -##################################### -# DataWave Helm Chart Configuration # -##################################### - -apiVersion: v2 -name: datawave-qms -type: application -version: 1.0.0-SNAPSHOT - -################################# -# Basic Metadata for this Chart # -################################# - -appVersion: 1.0.0 -description: Deploys an Entire DataWave Stack w/ Dependencies using Query Microservices -icon: https://code.nsa.gov/datawave/images/datawave-logo.png - -dependencies: - - name: dwv-ingest - repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts - version: 1.0.0 - - name: dwv-hadoop - repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts - version: 1.0.0 - condition: charts.hadoop.enabled - - name: dwv-hadoop-config - repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts - version: 1.0.0 - - name: dwv-zookeeper - repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts - version: 1.0.0 - condition: charts.zookeeper.enabled - - name: dwv-accumulo - repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts - version: 1.0.0 - - name: datawave-qms-umbrella - repository: file://../datawave-qms-umbrella - version: 1.0.0-SNAPSHOT diff --git a/datawave-qms-stack/README.md b/datawave-qms-stack/README.md deleted file mode 100644 index 19d864d..0000000 --- a/datawave-qms-stack/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# DataWave Web Helm Chart - -Manages All Helm Resources Required to Support a Deployment of DataWave Web diff --git a/datawave-qms-stack/certificates/keystore.p12 b/datawave-qms-stack/certificates/keystore.p12 deleted file mode 100644 index ee6ca90def7f6a8888e37560a8a0f1d0aed6a9d7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3586 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 WLMG(VGG1zJH>f(sOX)Tk@&5rX1>|@D diff --git a/datawave-qms-stack/templates/_helpers.tpl b/datawave-qms-stack/templates/_helpers.tpl deleted file mode 100644 index 9713615..0000000 --- a/datawave-qms-stack/templates/_helpers.tpl +++ /dev/null @@ -1,23 +0,0 @@ -{{/* vim: set filetype=mustache: */}} -{{/* -Expand the name of the chart. -*/}} -{{- define "datawave.stack.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). -*/}} -{{- define "datawave.stack.fullname" -}} -{{- $name := default .Chart.Name .Values.nameOverride -}} -{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} -{{- end -}} - -{{/* -Create chart name and version as used by the chart label. -*/}} -{{- define "datawave.stack.chart" -}} -{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} -{{- end -}} diff --git a/datawave-qms-stack/templates/hdfs.yaml b/datawave-qms-stack/templates/hdfs.yaml deleted file mode 100644 index 2c78769..0000000 --- a/datawave-qms-stack/templates/hdfs.yaml +++ /dev/null @@ -1,19 +0,0 @@ -{{- if not .Values.charts.hadoop.enabled }} -{{- with .Values.external.hdfs.hosts }} -{{- range . }} ---- -apiVersion: v1 -kind: Service -metadata: - name: {{ . }} - labels: - app: hdfs - chart: {{ include "datawave.stack.chart" $ }} - release: {{ $.Release.Name }} - app.kubernetes.io/component: {{ . }} -spec: - externalName: {{ . }} - type: ExternalName -{{- end }} -{{- end }} -{{- end }} \ No newline at end of file diff --git a/datawave-qms-stack/templates/yarn.yaml b/datawave-qms-stack/templates/yarn.yaml deleted file mode 100644 index 15a15fb..0000000 --- a/datawave-qms-stack/templates/yarn.yaml +++ /dev/null @@ -1,19 +0,0 @@ -{{- if not .Values.charts.hadoop.enabled }} -{{- with .Values.external.yarn.hosts }} -{{- range . }} ---- -apiVersion: v1 -kind: Service -metadata: - name: {{ . }} - labels: - app: yarn - chart: {{ include "datawave.stack.chart" $ }} - release: {{ $.Release.Name }} - app.kubernetes.io/component: {{ . }} -spec: - externalName: {{ . }} - type: ExternalName -{{- end }} -{{- end }} -{{- end }} diff --git a/datawave-qms-stack/templates/zookeeper.yaml b/datawave-qms-stack/templates/zookeeper.yaml deleted file mode 100644 index 83bf769..0000000 --- a/datawave-qms-stack/templates/zookeeper.yaml +++ /dev/null @@ -1,24 +0,0 @@ -{{- if not .Values.charts.zookeeper.enabled }} -{{- with .Values.external.zookeeper.hosts }} -{{- range . }} ---- -apiVersion: v1 -kind: Service -metadata: - name: {{ . }} - labels: - app: zookeeper - chart: {{ include "datawave.stack.chart" $ }} - release: {{ $.Release.Name }} - app.kubernetes.io/component: zookeeper -spec: - externalName: {{ . }} - ports: - - name: zk - port: 2181 - protocol: TCP - targetPort: 2181 - type: ExternalName -{{- end }} -{{- end }} -{{- end }} \ No newline at end of file diff --git a/datawave-qms-stack/values-testing.yaml b/datawave-qms-stack/values-testing.yaml deleted file mode 100644 index 9e9294b..0000000 --- a/datawave-qms-stack/values-testing.yaml +++ /dev/null @@ -1,8 +0,0 @@ -dwv-accumulo: - image: - tag: 2.1.3 - initContainer: - tag: 3.3.6 -dwv-hadoop: - image: - tag: 3.3.6 diff --git a/datawave-qms-stack/values.schema.json b/datawave-qms-stack/values.schema.json deleted file mode 100644 index 161c3c1..0000000 --- a/datawave-qms-stack/values.schema.json +++ /dev/null @@ -1,88 +0,0 @@ -{ - "$id": "https://code.nsa.org/datawave/schema", - "$schema": "https://json-schema.org/draft/2020-12/schema", - "additionalProperties": true, - "description": "Schema for DataWave Helm values", - "properties": { - "charts": { - "properties": { - "hadoop": { - "properties": { - "enabled": { - "type": "boolean" - } - }, - "type": "object" - }, - "zookeeper": { - "properties": { - "enabled": { - "type": "boolean" - } - }, - "type": "object" - } - }, - "type": "object" - }, - "dockerRegistry": { - "properties": { - "url": { - "type": "string" - } - }, - "type": "object" - }, - "external": { - "properties": { - "hdfs": { - "properties": { - "hosts": { - "items": { - "type": "string" - }, - "type": "array" - } - }, - "type": "object" - }, - "yarn": { - "properties": { - "hosts": { - "items": { - "type": "string" - }, - "type": "array" - } - }, - "type": "object" - }, - "zookeeper": { - "properties": { - "hosts": { - "items": { - "type": "string" - }, - "type": "array" - } - }, - "type": "object" - } - }, - "type": "object" - }, - "global": { - "properties": { - "accumuloConfigMap": { - "type": "string" - }, - "hadoopConfigMap": { - "type": "string" - } - }, - "type": "object" - } - }, - "title": "Helm Values Schema", - "type": "object" -} diff --git a/datawave-qms-stack/values.yaml b/datawave-qms-stack/values.yaml deleted file mode 100644 index dfb8f9c..0000000 --- a/datawave-qms-stack/values.yaml +++ /dev/null @@ -1,27 +0,0 @@ -###################################### -# Default Values for Docker Registry # -###################################### - -global: - hadoopConfigMap: dwv-hadoop-config - accumuloConfigMap: dwv-accumulo-config - -dockerRegistry: - url: ghcr.io/nationalsecurityagency/ -charts: - zookeeper: - enabled: true - hadoop: - enabled: true -external: - zookeeper: - hosts: - - zookeeper - hdfs: - hosts: - - hdfs-nn - - hdfs-dn - yarn: - hosts: - - yarn-rm - - yarn-nm \ No newline at end of file diff --git a/datawave-qms-umbrella/.schema.yaml b/datawave-qms-umbrella/.schema.yaml deleted file mode 100644 index 546b749..0000000 --- a/datawave-qms-umbrella/.schema.yaml +++ /dev/null @@ -1,13 +0,0 @@ -# Required -input: - - values.yaml - -draft: 2020 -indent: 4 -output: values.schema.json - -schemaRoot: - id: https://code.nsa.org/datawave/schema - title: Helm Values Schema - description: Schema for DataWave Helm values - additionalProperties: true diff --git a/datawave-qms-umbrella/Chart.lock b/datawave-qms-umbrella/Chart.lock deleted file mode 100644 index 03b34c0..0000000 --- a/datawave-qms-umbrella/Chart.lock +++ /dev/null @@ -1,42 +0,0 @@ -dependencies: -- name: dwv-audit - repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts - version: 1.0.0 -- name: dwv-authorization - repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts - version: 1.0.0 -- name: dwv-cache - repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts - version: 1.0.0 -- name: dwv-configuration - repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts - version: 1.0.0 -- name: dwv-dictionary - repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts - version: 1.0.0 -- name: dwv-executor - repository: file://../executor/ - version: 1.0.0-SNAPSHOT -- name: dwv-kafdrop - repository: file://../kafdrop - version: 1.0.0-SNAPSHOT -- name: dwv-kafka - repository: file://../kafka - version: 1.0.0-SNAPSHOT -- name: dwv-modification - repository: file://../modification - version: 1.0.0-SNAPSHOT -- name: dwv-mr-query - repository: file://../mr-query - version: 1.0.0-SNAPSHOT -- name: dwv-query - repository: file://../query - version: 1.0.0-SNAPSHOT -- name: dwv-query-metrics - repository: file://../query-metrics - version: 1.0.0-SNAPSHOT -- name: dwv-rabbitmq - repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts - version: 1.0.0 -digest: sha256:00d0cd83713ad19d971fd74c64b57032c24250c05f5ae25df1f6549261a99e4f -generated: "2024-10-08T10:51:03.152002577Z" diff --git a/datawave-qms-umbrella/Chart.yaml b/datawave-qms-umbrella/Chart.yaml deleted file mode 100644 index 4810478..0000000 --- a/datawave-qms-umbrella/Chart.yaml +++ /dev/null @@ -1,57 +0,0 @@ -##################################### -# DataWave Helm Chart Configuration # -##################################### - -apiVersion: v2 -name: datawave-qms-umbrella -type: application -version: 1.0.0-SNAPSHOT - -################################# -# Basic Metadata for this Chart # -################################# - -appVersion: 1.0.0 -description: Deploys The web stack of DataWave using Query Microservices -icon: https://code.nsa.gov/datawave/images/datawave-logo.png - -dependencies: - - name: dwv-audit - repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts - version: 1.0.0 - - name: dwv-authorization - repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts - version: 1.0.0 - - name: dwv-cache - repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts - version: 1.0.0 - - name: dwv-configuration - repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts - version: 1.0.0 - - name: dwv-dictionary - repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts - version: 1.0.0 - - name: dwv-executor - repository: file://../executor/ - version: 1.0.0-SNAPSHOT - - name: dwv-kafdrop - repository: file://../kafdrop - version: 1.0.0-SNAPSHOT - - name: dwv-kafka - repository: file://../kafka - version: 1.0.0-SNAPSHOT - - name: dwv-modification - repository: file://../modification - version: 1.0.0-SNAPSHOT - - name: dwv-mr-query - repository: file://../mr-query - version: 1.0.0-SNAPSHOT - - name: dwv-query - repository: file://../query - version: 1.0.0-SNAPSHOT - - name: dwv-query-metrics - repository: file://../query-metrics - version: 1.0.0-SNAPSHOT - - name: dwv-rabbitmq - repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts - version: 1.0.0 \ No newline at end of file diff --git a/datawave-qms-umbrella/README.md b/datawave-qms-umbrella/README.md deleted file mode 100644 index 19d864d..0000000 --- a/datawave-qms-umbrella/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# DataWave Web Helm Chart - -Manages All Helm Resources Required to Support a Deployment of DataWave Web diff --git a/datawave-qms-umbrella/values.schema.json b/datawave-qms-umbrella/values.schema.json deleted file mode 100644 index 0fde354..0000000 --- a/datawave-qms-umbrella/values.schema.json +++ /dev/null @@ -1,74 +0,0 @@ -{ - "$id": "https://code.nsa.org/datawave/schema", - "$schema": "https://json-schema.org/draft/2020-12/schema", - "additionalProperties": true, - "description": "Schema for DataWave Helm values", - "properties": { - "dockerRegistry": { - "properties": { - "url": { - "type": "string" - } - }, - "type": "object" - }, - "global": { - "properties": { - "serviceDns": { - "properties": { - "accumuloManager": { - "properties": { - "name": { - "type": "string" - } - }, - "type": "object" - }, - "authorization": { - "properties": { - "name": { - "type": "string" - } - }, - "type": "object" - }, - "cache": { - "properties": { - "name": { - "type": "string" - }, - "port": { - "type": "integer" - } - }, - "type": "object" - }, - "configuration": { - "properties": { - "name": { - "type": "string" - }, - "port": { - "type": "integer" - } - }, - "type": "object" - }, - "rabbitmq": { - "properties": { - "name": { - "type": "string" - } - }, - "type": "object" - } - }, - "type": "object" - } - }, - "type": "object" - } - }, - "title": "Helm Values Schema", - "type": "object" -} diff --git a/datawave-qms-umbrella/values.yaml b/datawave-qms-umbrella/values.yaml deleted file mode 100644 index 7d7d890..0000000 --- a/datawave-qms-umbrella/values.yaml +++ /dev/null @@ -1,22 +0,0 @@ -global: - serviceDns: - accumuloManager: - name: accumulo-manager - authorization: - name: authorization - cache: - name: cache - port: 8080 - configuration: - name: configuration - port: 8888 - rabbitmq: - name: rabbitmq - - -###################################### -# Default Values for Docker Registry # -###################################### - -dockerRegistry: - url: ghcr.io/nationalsecurityagency/ diff --git a/datawave-stack/Chart.yaml b/datawave-stack/Chart.yaml index 5cad822..52078a2 100644 --- a/datawave-stack/Chart.yaml +++ b/datawave-stack/Chart.yaml @@ -42,3 +42,38 @@ dependencies: repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts version: 1.0.0 path: ../datawave-monolith-umbrella + - name: dwv-executor + repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts + version: 1.0.0-SNAPSHOT + path: ../executor + condition: charts.qms.enabled + - name: dwv-kafdrop + repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts + version: 1.0.0-SNAPSHOT + path: ../kafdrop + condition: charts.qms.enabled + - name: dwv-kafka + repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts + version: 1.0.0-SNAPSHOT + path: ../kafka + condition: charts.qms.enabled + - name: dwv-modification + repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts + version: 1.0.0-SNAPSHOT + path: ../modification + condition: charts.qms.enabled + - name: dwv-mr-query + repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts + version: 1.0.0-SNAPSHOT + path: ../mr-query + condition: charts.qms.enabled + - name: dwv-query-metrics + repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts + version: 1.0.0-SNAPSHOT + path: ../query-metrics + condition: charts.qms.enabled + - name: dwv-query + repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts + version: 1.0.0-SNAPSHOT + path: ../query + condition: charts.qms.enabled diff --git a/datawave-stack/values.yaml b/datawave-stack/values.yaml index dfb8f9c..1861cf7 100644 --- a/datawave-stack/values.yaml +++ b/datawave-stack/values.yaml @@ -13,6 +13,8 @@ charts: enabled: true hadoop: enabled: true + qms: + enabled: true external: zookeeper: hosts: diff --git a/executor/Chart.yaml b/executor/Chart.yaml index 6356828..2d55c77 100644 --- a/executor/Chart.yaml +++ b/executor/Chart.yaml @@ -19,4 +19,5 @@ dependencies: - name: common-service-library repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts version: 0.0.2 + path: ../common-service-library diff --git a/executor/templates/accumulo-microservice-deployment.yaml b/executor/templates/accumulo-microservice-deployment.yaml index 194eb3e..afb20a8 100644 --- a/executor/templates/accumulo-microservice-deployment.yaml +++ b/executor/templates/accumulo-microservice-deployment.yaml @@ -1,5 +1,5 @@ -{{- include "common-service-library.deployment" (list . "accumuloMicroservice.deployment") -}} -{{- define "accumuloMicroservice.deployment" -}} +{{- include "common-service-library.deployment" (list . "executorService.deployment") -}} +{{- define "executorService.deployment" -}} #overrides go here spec: template: diff --git a/executor/templates/accumulo-microservice-service.yaml b/executor/templates/accumulo-microservice-service.yaml index 2bcedaa..5ca7728 100644 --- a/executor/templates/accumulo-microservice-service.yaml +++ b/executor/templates/accumulo-microservice-service.yaml @@ -1,4 +1,4 @@ -{{- include "common-service-library.service" (list . "accumuloMicroservice.service") -}} -{{- define "accumuloMicroservice.service" -}} +{{- include "common-service-library.service" (list . "executorService.service") -}} +{{- define "executorService.service" -}} #overrides go here {{- end -}} \ No newline at end of file diff --git a/executor/values.yaml b/executor/values.yaml index e71e1b7..28b9b4b 100644 --- a/executor/values.yaml +++ b/executor/values.yaml @@ -18,6 +18,7 @@ global: port: 8888 authorization: name: authorization + port: 8080 cache: name: cache port: 8080 diff --git a/hadoop-config/.helmignore b/hadoop-config/.helmignore index f0c1319..c8c5fc0 100644 --- a/hadoop-config/.helmignore +++ b/hadoop-config/.helmignore @@ -19,3 +19,5 @@ .project .idea/ *.tmproj + +dwv-*.tgz diff --git a/hadoop/.helmignore b/hadoop/.helmignore index f0c1319..001d084 100644 --- a/hadoop/.helmignore +++ b/hadoop/.helmignore @@ -19,3 +19,5 @@ .project .idea/ *.tmproj + +dwv-hadoop*.tgz \ No newline at end of file diff --git a/modification/Chart.yaml b/modification/Chart.yaml index ee1adf4..12f2eba 100644 --- a/modification/Chart.yaml +++ b/modification/Chart.yaml @@ -19,4 +19,5 @@ dependencies: - name: common-service-library repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts version: 0.0.2 + path: ../common-service-library diff --git a/modification/values.yaml b/modification/values.yaml index 3550ed8..e0413a0 100644 --- a/modification/values.yaml +++ b/modification/values.yaml @@ -18,6 +18,7 @@ global: port: 8888 authorization: name: authorization + port: 8080 cache: name: cache port: 8080 @@ -29,7 +30,7 @@ global: image: name: datawave-modification-service pullPolicy: IfNotPresent - tag: 1.0.2 + tag: latest args: - "--spring.output.ansi.enabled=ALWAYS" - "--spring.profiles.active=default,k8s,remoteauth,query" diff --git a/mr-query/Chart.yaml b/mr-query/Chart.yaml index a9ebe00..832af4c 100644 --- a/mr-query/Chart.yaml +++ b/mr-query/Chart.yaml @@ -19,4 +19,5 @@ dependencies: - name: common-service-library repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts version: 0.0.2 + path: ../common-service-library diff --git a/mr-query/values.yaml b/mr-query/values.yaml index d6931d5..d3aa5ea 100644 --- a/mr-query/values.yaml +++ b/mr-query/values.yaml @@ -18,6 +18,7 @@ global: port: 8888 authorization: name: authorization + port: 8080 cache: name: cache port: 8080 @@ -29,7 +30,7 @@ global: image: name: datawave-mapreduce-query-service pullPolicy: IfNotPresent - tag: 1.0.4 + tag: latest args: - "--spring.output.ansi.enabled=ALWAYS" - "--spring.profiles.active=default,k8s,remoteauth,query" diff --git a/query-metrics/Chart.yaml b/query-metrics/Chart.yaml index 9c41707..1018bea 100644 --- a/query-metrics/Chart.yaml +++ b/query-metrics/Chart.yaml @@ -19,4 +19,5 @@ dependencies: - name: common-service-library repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts version: 0.0.2 + path: ../common-service-library diff --git a/query-metrics/values.yaml b/query-metrics/values.yaml index 4e11960..eb16cef 100644 --- a/query-metrics/values.yaml +++ b/query-metrics/values.yaml @@ -18,6 +18,7 @@ global: port: 8888 authorization: name: authorization + port: 8080 cache: name: cache port: 8080 @@ -27,9 +28,9 @@ global: # Default Values for Audit Deployment # ####################################### image: - name: datawave-mapreduce-query-service - pullPolicy: IfNotPresent - tag: 4.0.8 + name: datawave-query-metric-service + pullPolicy: Always + tag: latest args: - "--spring.output.ansi.enabled=ALWAYS" - "--spring.profiles.active=default,k8s,remoteauth" diff --git a/query/Chart.yaml b/query/Chart.yaml index 2c3dce3..5407622 100644 --- a/query/Chart.yaml +++ b/query/Chart.yaml @@ -19,4 +19,5 @@ dependencies: - name: common-service-library repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts version: 0.0.2 + path: ../common-service-library diff --git a/query/values.yaml b/query/values.yaml index 6e930c4..50c6c30 100644 --- a/query/values.yaml +++ b/query/values.yaml @@ -18,6 +18,7 @@ global: port: 8888 authorization: name: authorization + port: 8080 cache: name: cache port: 8080 @@ -27,9 +28,9 @@ global: # Default Values for Audit Deployment # ####################################### image: - name: datawave-mapreduce-query-service + name: datawave-query-service pullPolicy: IfNotPresent - tag: 1.0.10 + tag: 1.0.11 args: - "--spring.output.ansi.enabled=ALWAYS" - "--spring.profiles.active=default,k8s,remoteauth,querymessaging,metricssource,query,mrquery,cachedresults,federation" From 6264a36f12b8539129db83ac160428a43f75bd8b Mon Sep 17 00:00:00 2001 From: Adam Lerman Date: Fri, 4 Oct 2024 19:29:16 +0000 Subject: [PATCH 06/16] Most ms added. Saving work for weekend. Still need query and query metrics --- datawave-accumulo-microservice/.gitignore | 5 + datawave-accumulo-microservice/.helmignore | 17 ++ datawave-accumulo-microservice/Chart.lock | 6 + datawave-accumulo-microservice/Chart.yaml | 22 ++ .../accumulo-microservice-deployment.yaml | 19 ++ .../accumulo-microservice-service.yaml | 4 + .../values.schema.json | 206 ++++++++++++++++++ datawave-accumulo-microservice/values.yaml | 65 ++++++ executor-pool/.gitignore | 5 + executor-pool/.helmignore | 17 ++ executor-pool/Chart.lock | 6 + executor-pool/Chart.yaml | 22 ++ .../accumulo-microservice-deployment.yaml | 19 ++ .../accumulo-microservice-service.yaml | 4 + executor-pool/values.schema.json | 206 ++++++++++++++++++ executor-pool/values.yaml | 67 ++++++ kafdrop/.gitignore | 5 + kafdrop/.helmignore | 17 ++ kafdrop/Chart.yaml | 18 ++ kafdrop/templates/kafdrop-deployment.yaml | 85 ++++++++ kafdrop/templates/kafdrop-service.yaml | 40 ++++ kafdrop/values.schema.json | 206 ++++++++++++++++++ kafdrop/values.yaml | 42 ++++ kafka/.gitignore | 5 + kafka/.helmignore | 17 ++ kafka/Chart.yaml | 18 ++ kafka/templates/kafka-service.yaml | 46 ++++ kafka/templates/kafka-statefulset.yaml | 104 +++++++++ kafka/values.schema.json | 206 ++++++++++++++++++ kafka/values.yaml | 32 +++ modification/.gitignore | 5 + modification/.helmignore | 17 ++ modification/Chart.yaml | 22 ++ .../templates/modification-deployment.yaml | 19 ++ .../templates/modification-service.yaml | 4 + modification/values.schema.json | 206 ++++++++++++++++++ modification/values.yaml | 67 ++++++ mr-query/.gitignore | 5 + mr-query/.helmignore | 17 ++ mr-query/Chart.yaml | 22 ++ mr-query/templates/mr-query-deployment.yaml | 19 ++ mr-query/templates/mr-query-service.yaml | 4 + mr-query/values.schema.json | 206 ++++++++++++++++++ mr-query/values.yaml | 67 ++++++ 44 files changed, 2211 insertions(+) create mode 100644 datawave-accumulo-microservice/.gitignore create mode 100644 datawave-accumulo-microservice/.helmignore create mode 100644 datawave-accumulo-microservice/Chart.lock create mode 100644 datawave-accumulo-microservice/Chart.yaml create mode 100644 datawave-accumulo-microservice/templates/accumulo-microservice-deployment.yaml create mode 100644 datawave-accumulo-microservice/templates/accumulo-microservice-service.yaml create mode 100644 datawave-accumulo-microservice/values.schema.json create mode 100644 datawave-accumulo-microservice/values.yaml create mode 100644 executor-pool/.gitignore create mode 100644 executor-pool/.helmignore create mode 100644 executor-pool/Chart.lock create mode 100644 executor-pool/Chart.yaml create mode 100644 executor-pool/templates/accumulo-microservice-deployment.yaml create mode 100644 executor-pool/templates/accumulo-microservice-service.yaml create mode 100644 executor-pool/values.schema.json create mode 100644 executor-pool/values.yaml create mode 100644 kafdrop/.gitignore create mode 100644 kafdrop/.helmignore create mode 100644 kafdrop/Chart.yaml create mode 100644 kafdrop/templates/kafdrop-deployment.yaml create mode 100644 kafdrop/templates/kafdrop-service.yaml create mode 100644 kafdrop/values.schema.json create mode 100644 kafdrop/values.yaml create mode 100644 kafka/.gitignore create mode 100644 kafka/.helmignore create mode 100644 kafka/Chart.yaml create mode 100644 kafka/templates/kafka-service.yaml create mode 100644 kafka/templates/kafka-statefulset.yaml create mode 100644 kafka/values.schema.json create mode 100644 kafka/values.yaml create mode 100644 modification/.gitignore create mode 100644 modification/.helmignore create mode 100644 modification/Chart.yaml create mode 100644 modification/templates/modification-deployment.yaml create mode 100644 modification/templates/modification-service.yaml create mode 100644 modification/values.schema.json create mode 100644 modification/values.yaml create mode 100644 mr-query/.gitignore create mode 100644 mr-query/.helmignore create mode 100644 mr-query/Chart.yaml create mode 100644 mr-query/templates/mr-query-deployment.yaml create mode 100644 mr-query/templates/mr-query-service.yaml create mode 100644 mr-query/values.schema.json create mode 100644 mr-query/values.yaml diff --git a/datawave-accumulo-microservice/.gitignore b/datawave-accumulo-microservice/.gitignore new file mode 100644 index 0000000..79f2743 --- /dev/null +++ b/datawave-accumulo-microservice/.gitignore @@ -0,0 +1,5 @@ +############################### +# Ignores Helm Chart Archives # +############################### + +**.tgz diff --git a/datawave-accumulo-microservice/.helmignore b/datawave-accumulo-microservice/.helmignore new file mode 100644 index 0000000..aa06c2c --- /dev/null +++ b/datawave-accumulo-microservice/.helmignore @@ -0,0 +1,17 @@ +########################################### +# Ignores All File or Path Related to Git # +########################################### + +.git + +##################################### +# Ignores All Development Resources # +##################################### + +development/ +setup.sh + +############################ +# Ignores package Archives # +############################ +dwv-accumulo-microservice-*.tgz diff --git a/datawave-accumulo-microservice/Chart.lock b/datawave-accumulo-microservice/Chart.lock new file mode 100644 index 0000000..c7d3c8d --- /dev/null +++ b/datawave-accumulo-microservice/Chart.lock @@ -0,0 +1,6 @@ +dependencies: +- name: common-service-library + repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts + version: 0.0.2 +digest: sha256:9f6737e1bdb7c4772bf295ccb128a1d540237dd1b7770e0edbd185d1b17a1a31 +generated: "2024-10-04T18:58:14.981876411Z" diff --git a/datawave-accumulo-microservice/Chart.yaml b/datawave-accumulo-microservice/Chart.yaml new file mode 100644 index 0000000..d735496 --- /dev/null +++ b/datawave-accumulo-microservice/Chart.yaml @@ -0,0 +1,22 @@ +################################# +# Core Helm Chart Configuration # +################################# + +apiVersion: v2 +name: dwv-accumulo-microservice +type: application +version: 1.0.0-SNAPSHOT + +################################# +# Basic Metadata for this Chart # +################################# + +appVersion: 4.0.2 +description: Deploys a datawave accumulo microservice +icon: https://code.nsa.gov/datawave/images/datawave-logo.png + +dependencies: + - name: common-service-library + repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts + version: 0.0.2 + diff --git a/datawave-accumulo-microservice/templates/accumulo-microservice-deployment.yaml b/datawave-accumulo-microservice/templates/accumulo-microservice-deployment.yaml new file mode 100644 index 0000000..194eb3e --- /dev/null +++ b/datawave-accumulo-microservice/templates/accumulo-microservice-deployment.yaml @@ -0,0 +1,19 @@ +{{- include "common-service-library.deployment" (list . "accumuloMicroservice.deployment") -}} +{{- define "accumuloMicroservice.deployment" -}} +#overrides go here +spec: + template: + spec: + initContainers: + - name: "{{ .Chart.Name }}-init-authorization" + image: "{{ .Values.global.initialization.image.name }}:{{ .Values.global.initialization.image.tag }}" + command: [ "sh", "-c", "until nc -z {{ .Values.global.serviceDns.authorization.name }} {{ .Values.global.serviceDns.authorization.port }}; do echo 'Waiting for Authorization...'; sleep 2; done" ] + + - name: "{{ .Chart.Name }}-init-cache" + image: "{{ .Values.global.initialization.image.name }}:{{ .Values.global.initialization.image.tag }}" + command: [ "sh", "-c", "until nc -z {{ .Values.global.serviceDns.cache.name }} {{ .Values.global.serviceDns.cache.port }}; do echo 'Waiting for Cache...'; sleep 2; done" ] + + - name: "{{ .Chart.Name }}-init-configuration" + image: "{{ .Values.global.initialization.image.name }}:{{ .Values.global.initialization.image.tag }}" + command: [ "sh", "-c", "until nc -z {{ .Values.global.serviceDns.configuration.name }} {{ .Values.global.serviceDns.configuration.port }}; do echo 'Waiting for Configuration...'; sleep 2; done" ] +{{- end -}} \ No newline at end of file diff --git a/datawave-accumulo-microservice/templates/accumulo-microservice-service.yaml b/datawave-accumulo-microservice/templates/accumulo-microservice-service.yaml new file mode 100644 index 0000000..2bcedaa --- /dev/null +++ b/datawave-accumulo-microservice/templates/accumulo-microservice-service.yaml @@ -0,0 +1,4 @@ +{{- include "common-service-library.service" (list . "accumuloMicroservice.service") -}} +{{- define "accumuloMicroservice.service" -}} +#overrides go here +{{- end -}} \ No newline at end of file diff --git a/datawave-accumulo-microservice/values.schema.json b/datawave-accumulo-microservice/values.schema.json new file mode 100644 index 0000000..068c816 --- /dev/null +++ b/datawave-accumulo-microservice/values.schema.json @@ -0,0 +1,206 @@ +{ + "$id": "https://code.nsa.org/datawave/schema", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "additionalProperties": true, + "description": "Schema for DataWave Helm values", + "properties": { + "args": { + "items": { + "type": "string" + }, + "type": "array" + }, + "global": { + "properties": { + "certSecretName": { + "type": "string" + }, + "dockerRegistry": { + "properties": { + "url": { + "type": "string" + } + }, + "type": "object" + }, + "initialization": { + "properties": { + "image": { + "properties": { + "name": { + "type": "string" + }, + "tag": { + "type": "number" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "pullSecrets": { + "items": { + "type": "string" + }, + "type": "array" + }, + "serviceDns": { + "properties": { + "authorization": { + "properties": { + "name": { + "type": "string" + } + }, + "type": "object" + }, + "cache": { + "properties": { + "name": { + "type": "string" + }, + "port": { + "type": "integer" + } + }, + "type": "object" + }, + "configuration": { + "properties": { + "name": { + "type": "string" + }, + "port": { + "type": "integer" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "volumes": { + "properties": { + "certificates": { + "properties": { + "destination": { + "type": "string" + }, + "name": { + "type": "string" + } + }, + "type": "object" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "image": { + "properties": { + "name": { + "type": "string" + }, + "pullPolicy": { + "type": "string" + }, + "tag": { + "type": "string" + } + }, + "type": "object" + }, + "livenessProbe": { + "properties": { + "delaySeconds": { + "type": "integer" + }, + "periodSeconds": { + "type": "integer" + }, + "port": { + "type": "integer" + }, + "scheme": { + "type": "string" + }, + "uri": { + "type": "string" + } + }, + "type": "object" + }, + "meta": { + "properties": { + "name": { + "type": "string" + } + }, + "type": "object" + }, + "ports": { + "properties": { + "http": { + "type": "integer" + }, + "https": { + "type": "integer" + } + }, + "type": "object" + }, + "readinessProbe": { + "properties": { + "delaySeconds": { + "type": "integer" + }, + "periodSeconds": { + "type": "integer" + }, + "port": { + "type": "integer" + }, + "scheme": { + "type": "string" + }, + "uri": { + "type": "string" + } + }, + "type": "object" + }, + "replication": { + "properties": { + "maxSurge": { + "type": "integer" + }, + "maxUnavailable": { + "type": "integer" + }, + "replicaCount": { + "type": "integer" + }, + "revisionHistoryLimit": { + "type": "integer" + } + }, + "type": "object" + }, + "restartPolicy": { + "type": "string" + }, + "service": { + "properties": { + "name": { + "type": "string" + } + }, + "type": "object" + } + }, + "title": "Helm Values Schema", + "type": "object" +} diff --git a/datawave-accumulo-microservice/values.yaml b/datawave-accumulo-microservice/values.yaml new file mode 100644 index 0000000..e8988ff --- /dev/null +++ b/datawave-accumulo-microservice/values.yaml @@ -0,0 +1,65 @@ +global: + dockerRegistry: + url: ghcr.io/nationalsecurityagency + volumes: + certificates: + name: certificates + destination: /data/certs + initialization: + image: + name: busybox + tag: 1.28 + certSecretName: certificates-secret + pullSecrets: + - dockerconfigjson-ghcr + serviceDns: + configuration: + name: configuration + port: 8888 + authorization: + name: authorization + cache: + name: cache + port: 8080 + + +################################################################ +# Default Values for Datawave Accumulo Microservice Deployment # +################################################################ +image: + name: datawave-accumulo-service + pullPolicy: IfNotPresent + tag: 4.0.2 +args: +- "--spring.output.ansi.enabled=ALWAYS" +- "--spring.profiles.active=default,k8s,remoteauth" +livenessProbe: + delaySeconds: 60 + periodSeconds: 5 + port: 8080 + scheme: HTTP + uri: accumulo/mgmt/health +meta: + name: accumulo-microservice +service: + name: accumulo +readinessProbe: + delaySeconds: 60 + periodSeconds: 5 + port: 8080 + scheme: HTTP + uri: accumulo/mgmt/health +replication: + maxSurge: 2 + maxUnavailable: 1 + replicaCount: 1 + revisionHistoryLimit: 10 +restartPolicy: Always + +#################################### +# Default Values for Audit Service # +#################################### + +ports: + http: 8080 + https: 8443 diff --git a/executor-pool/.gitignore b/executor-pool/.gitignore new file mode 100644 index 0000000..79f2743 --- /dev/null +++ b/executor-pool/.gitignore @@ -0,0 +1,5 @@ +############################### +# Ignores Helm Chart Archives # +############################### + +**.tgz diff --git a/executor-pool/.helmignore b/executor-pool/.helmignore new file mode 100644 index 0000000..aa06c2c --- /dev/null +++ b/executor-pool/.helmignore @@ -0,0 +1,17 @@ +########################################### +# Ignores All File or Path Related to Git # +########################################### + +.git + +##################################### +# Ignores All Development Resources # +##################################### + +development/ +setup.sh + +############################ +# Ignores package Archives # +############################ +dwv-accumulo-microservice-*.tgz diff --git a/executor-pool/Chart.lock b/executor-pool/Chart.lock new file mode 100644 index 0000000..c7d3c8d --- /dev/null +++ b/executor-pool/Chart.lock @@ -0,0 +1,6 @@ +dependencies: +- name: common-service-library + repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts + version: 0.0.2 +digest: sha256:9f6737e1bdb7c4772bf295ccb128a1d540237dd1b7770e0edbd185d1b17a1a31 +generated: "2024-10-04T18:58:14.981876411Z" diff --git a/executor-pool/Chart.yaml b/executor-pool/Chart.yaml new file mode 100644 index 0000000..6356828 --- /dev/null +++ b/executor-pool/Chart.yaml @@ -0,0 +1,22 @@ +################################# +# Core Helm Chart Configuration # +################################# + +apiVersion: v2 +name: dwv-executor +type: application +version: 1.0.0-SNAPSHOT + +################################# +# Basic Metadata for this Chart # +################################# + +appVersion: 1.0.9 +description: Deploys a datawave query executor service +icon: https://code.nsa.gov/datawave/images/datawave-logo.png + +dependencies: + - name: common-service-library + repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts + version: 0.0.2 + diff --git a/executor-pool/templates/accumulo-microservice-deployment.yaml b/executor-pool/templates/accumulo-microservice-deployment.yaml new file mode 100644 index 0000000..194eb3e --- /dev/null +++ b/executor-pool/templates/accumulo-microservice-deployment.yaml @@ -0,0 +1,19 @@ +{{- include "common-service-library.deployment" (list . "accumuloMicroservice.deployment") -}} +{{- define "accumuloMicroservice.deployment" -}} +#overrides go here +spec: + template: + spec: + initContainers: + - name: "{{ .Chart.Name }}-init-authorization" + image: "{{ .Values.global.initialization.image.name }}:{{ .Values.global.initialization.image.tag }}" + command: [ "sh", "-c", "until nc -z {{ .Values.global.serviceDns.authorization.name }} {{ .Values.global.serviceDns.authorization.port }}; do echo 'Waiting for Authorization...'; sleep 2; done" ] + + - name: "{{ .Chart.Name }}-init-cache" + image: "{{ .Values.global.initialization.image.name }}:{{ .Values.global.initialization.image.tag }}" + command: [ "sh", "-c", "until nc -z {{ .Values.global.serviceDns.cache.name }} {{ .Values.global.serviceDns.cache.port }}; do echo 'Waiting for Cache...'; sleep 2; done" ] + + - name: "{{ .Chart.Name }}-init-configuration" + image: "{{ .Values.global.initialization.image.name }}:{{ .Values.global.initialization.image.tag }}" + command: [ "sh", "-c", "until nc -z {{ .Values.global.serviceDns.configuration.name }} {{ .Values.global.serviceDns.configuration.port }}; do echo 'Waiting for Configuration...'; sleep 2; done" ] +{{- end -}} \ No newline at end of file diff --git a/executor-pool/templates/accumulo-microservice-service.yaml b/executor-pool/templates/accumulo-microservice-service.yaml new file mode 100644 index 0000000..2bcedaa --- /dev/null +++ b/executor-pool/templates/accumulo-microservice-service.yaml @@ -0,0 +1,4 @@ +{{- include "common-service-library.service" (list . "accumuloMicroservice.service") -}} +{{- define "accumuloMicroservice.service" -}} +#overrides go here +{{- end -}} \ No newline at end of file diff --git a/executor-pool/values.schema.json b/executor-pool/values.schema.json new file mode 100644 index 0000000..068c816 --- /dev/null +++ b/executor-pool/values.schema.json @@ -0,0 +1,206 @@ +{ + "$id": "https://code.nsa.org/datawave/schema", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "additionalProperties": true, + "description": "Schema for DataWave Helm values", + "properties": { + "args": { + "items": { + "type": "string" + }, + "type": "array" + }, + "global": { + "properties": { + "certSecretName": { + "type": "string" + }, + "dockerRegistry": { + "properties": { + "url": { + "type": "string" + } + }, + "type": "object" + }, + "initialization": { + "properties": { + "image": { + "properties": { + "name": { + "type": "string" + }, + "tag": { + "type": "number" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "pullSecrets": { + "items": { + "type": "string" + }, + "type": "array" + }, + "serviceDns": { + "properties": { + "authorization": { + "properties": { + "name": { + "type": "string" + } + }, + "type": "object" + }, + "cache": { + "properties": { + "name": { + "type": "string" + }, + "port": { + "type": "integer" + } + }, + "type": "object" + }, + "configuration": { + "properties": { + "name": { + "type": "string" + }, + "port": { + "type": "integer" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "volumes": { + "properties": { + "certificates": { + "properties": { + "destination": { + "type": "string" + }, + "name": { + "type": "string" + } + }, + "type": "object" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "image": { + "properties": { + "name": { + "type": "string" + }, + "pullPolicy": { + "type": "string" + }, + "tag": { + "type": "string" + } + }, + "type": "object" + }, + "livenessProbe": { + "properties": { + "delaySeconds": { + "type": "integer" + }, + "periodSeconds": { + "type": "integer" + }, + "port": { + "type": "integer" + }, + "scheme": { + "type": "string" + }, + "uri": { + "type": "string" + } + }, + "type": "object" + }, + "meta": { + "properties": { + "name": { + "type": "string" + } + }, + "type": "object" + }, + "ports": { + "properties": { + "http": { + "type": "integer" + }, + "https": { + "type": "integer" + } + }, + "type": "object" + }, + "readinessProbe": { + "properties": { + "delaySeconds": { + "type": "integer" + }, + "periodSeconds": { + "type": "integer" + }, + "port": { + "type": "integer" + }, + "scheme": { + "type": "string" + }, + "uri": { + "type": "string" + } + }, + "type": "object" + }, + "replication": { + "properties": { + "maxSurge": { + "type": "integer" + }, + "maxUnavailable": { + "type": "integer" + }, + "replicaCount": { + "type": "integer" + }, + "revisionHistoryLimit": { + "type": "integer" + } + }, + "type": "object" + }, + "restartPolicy": { + "type": "string" + }, + "service": { + "properties": { + "name": { + "type": "string" + } + }, + "type": "object" + } + }, + "title": "Helm Values Schema", + "type": "object" +} diff --git a/executor-pool/values.yaml b/executor-pool/values.yaml new file mode 100644 index 0000000..e71e1b7 --- /dev/null +++ b/executor-pool/values.yaml @@ -0,0 +1,67 @@ +global: + dockerRegistry: + url: ghcr.io/nationalsecurityagency + volumes: + certificates: + name: certificates + destination: /data/certs + initialization: + image: + name: busybox + tag: 1.28 + certSecretName: certificates-secret + pullSecrets: + - dockerconfigjson-ghcr + serviceDns: + configuration: + name: configuration + port: 8888 + authorization: + name: authorization + cache: + name: cache + port: 8080 + + +####################################### +# Default Values for Audit Deployment # +####################################### +image: + name: datawave-query-executor-service + pullPolicy: IfNotPresent + tag: 1.0.9 +args: +- "--spring.output.ansi.enabled=ALWAYS" +- "--spring.profiles.active= default,k8s,remoteauth,querymessaging,metricssource,federation,query,pool1" +livenessProbe: + delaySeconds: 20 + periodSeconds: 5 + failureThreshold: 60 + port: 8080 + scheme: HTTP + uri: executor/mgmt/health +meta: + name: executor +service: + name: executor +readinessProbe: + delaySeconds: 20 + periodSeconds: 5 + failureThreshold: 60 + port: 8080 + scheme: HTTP + uri: executor/mgmt/health +replication: + maxSurge: 2 + maxUnavailable: 1 + replicaCount: 1 + revisionHistoryLimit: 10 +restartPolicy: Always + +####################################### +# Default Values for Executor Service # +####################################### + +ports: + http: 8080 + https: 8443 diff --git a/kafdrop/.gitignore b/kafdrop/.gitignore new file mode 100644 index 0000000..79f2743 --- /dev/null +++ b/kafdrop/.gitignore @@ -0,0 +1,5 @@ +############################### +# Ignores Helm Chart Archives # +############################### + +**.tgz diff --git a/kafdrop/.helmignore b/kafdrop/.helmignore new file mode 100644 index 0000000..6a51bb8 --- /dev/null +++ b/kafdrop/.helmignore @@ -0,0 +1,17 @@ +########################################### +# Ignores All File or Path Related to Git # +########################################### + +.git + +##################################### +# Ignores All Development Resources # +##################################### + +development/ +setup.sh + +############################ +# Ignores package Archives # +############################ +dwv-kafdrop-*.tgz diff --git a/kafdrop/Chart.yaml b/kafdrop/Chart.yaml new file mode 100644 index 0000000..9d937a2 --- /dev/null +++ b/kafdrop/Chart.yaml @@ -0,0 +1,18 @@ +################################# +# Core Helm Chart Configuration # +################################# + +apiVersion: v2 +name: dwv-executor +type: application +version: 1.0.0-SNAPSHOT + +################################# +# Basic Metadata for this Chart # +################################# + +appVersion: latest +description: Deploys a Kafdrop instance +icon: https://code.nsa.gov/datawave/images/datawave-logo.png + + diff --git a/kafdrop/templates/kafdrop-deployment.yaml b/kafdrop/templates/kafdrop-deployment.yaml new file mode 100644 index 0000000..fd6e139 --- /dev/null +++ b/kafdrop/templates/kafdrop-deployment.yaml @@ -0,0 +1,85 @@ +#################################### +# Core Helm Template Configuration # +#################################### + +apiVersion: apps/v1 +kind: Deployment + +###################################### +# Basic Metadata for this Deployment # +###################################### + +metadata: + name: "{{ .Chart.Name }}-{{ .Values.meta.name }}" + labels: + application: "{{ .Chart.Name }}-{{ .Values.meta.name }}" + +##################################### +# Complete Deployment Specification # +##################################### + +spec: + + ###################################### + # Replication / Update Configuration # + ###################################### + + replicas: {{ .Values.replication.replicaCount }} + revisionHistoryLimit: {{ .Values.replication.revisionHistoryLimit }} + strategy: + type: RollingUpdate + rollingUpdate: + maxSurge: {{ .Values.replication.maxSurge }} + maxUnavailable: {{ .Values.replication.maxUnavailable }} + + ################################### + # Resource Selector Configuration # + ################################### + + selector: + matchLabels: + application: "{{ .Chart.Name }}-{{ .Values.meta.name }}" + + ##################################### + # Deployment Template Configuration # + ##################################### + + template: + + ################################################## + # Basic Metadata for this Deployment's Resources # + ################################################## + + metadata: + labels: + application: "{{ .Chart.Name }}-{{ .Values.meta.name }}" + + ####################################### + # Deployment Resources Specifications # + ####################################### + + spec: + {{- with .Values.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.pullSecrets }} + imagePullSecrets: + {{- range . }} + - name: {{ . }} + {{- end }} + {{- end }} + securityContext: + runAsUser: 1000 + fsGroup: 1000 + restartPolicy: "{{ .Values.restartPolicy }}" + ############################################## + # Containers Associated with this Deployment # + ############################################## + + containers: + + - name: "{{ .Chart.Name }}-{{ .Values.meta.name }}" + image: "{{ .Values.image.name }}:{{ .Values.image.tag }}" + imagePullPolicy: "{{ .Values.image.pullPolicy }}" + resources: {} diff --git a/kafdrop/templates/kafdrop-service.yaml b/kafdrop/templates/kafdrop-service.yaml new file mode 100644 index 0000000..002e33d --- /dev/null +++ b/kafdrop/templates/kafdrop-service.yaml @@ -0,0 +1,40 @@ +#################################### +# Core Helm Template Configuration # +#################################### + +apiVersion: v1 +kind: Service + +###################################### +# Basic Metadata for this Deployment # +###################################### + +metadata: + name: "{{ .Values.service.name }}" + labels: + application: "{{ .Values.service.name }}" + +################################## +# Complete Service Specification # +################################## + +spec: + + ############################### + # Pod Selection Configuration # + ############################### + + selector: + application: "{{ .Values.service.name }}" + + ############################## + # Service Port Configuration # + ############################## + + ports: + + - name: kafdrop + port: {{ .Values.ports.kafdrop }} + targetPort: 9000 + + diff --git a/kafdrop/values.schema.json b/kafdrop/values.schema.json new file mode 100644 index 0000000..068c816 --- /dev/null +++ b/kafdrop/values.schema.json @@ -0,0 +1,206 @@ +{ + "$id": "https://code.nsa.org/datawave/schema", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "additionalProperties": true, + "description": "Schema for DataWave Helm values", + "properties": { + "args": { + "items": { + "type": "string" + }, + "type": "array" + }, + "global": { + "properties": { + "certSecretName": { + "type": "string" + }, + "dockerRegistry": { + "properties": { + "url": { + "type": "string" + } + }, + "type": "object" + }, + "initialization": { + "properties": { + "image": { + "properties": { + "name": { + "type": "string" + }, + "tag": { + "type": "number" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "pullSecrets": { + "items": { + "type": "string" + }, + "type": "array" + }, + "serviceDns": { + "properties": { + "authorization": { + "properties": { + "name": { + "type": "string" + } + }, + "type": "object" + }, + "cache": { + "properties": { + "name": { + "type": "string" + }, + "port": { + "type": "integer" + } + }, + "type": "object" + }, + "configuration": { + "properties": { + "name": { + "type": "string" + }, + "port": { + "type": "integer" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "volumes": { + "properties": { + "certificates": { + "properties": { + "destination": { + "type": "string" + }, + "name": { + "type": "string" + } + }, + "type": "object" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "image": { + "properties": { + "name": { + "type": "string" + }, + "pullPolicy": { + "type": "string" + }, + "tag": { + "type": "string" + } + }, + "type": "object" + }, + "livenessProbe": { + "properties": { + "delaySeconds": { + "type": "integer" + }, + "periodSeconds": { + "type": "integer" + }, + "port": { + "type": "integer" + }, + "scheme": { + "type": "string" + }, + "uri": { + "type": "string" + } + }, + "type": "object" + }, + "meta": { + "properties": { + "name": { + "type": "string" + } + }, + "type": "object" + }, + "ports": { + "properties": { + "http": { + "type": "integer" + }, + "https": { + "type": "integer" + } + }, + "type": "object" + }, + "readinessProbe": { + "properties": { + "delaySeconds": { + "type": "integer" + }, + "periodSeconds": { + "type": "integer" + }, + "port": { + "type": "integer" + }, + "scheme": { + "type": "string" + }, + "uri": { + "type": "string" + } + }, + "type": "object" + }, + "replication": { + "properties": { + "maxSurge": { + "type": "integer" + }, + "maxUnavailable": { + "type": "integer" + }, + "replicaCount": { + "type": "integer" + }, + "revisionHistoryLimit": { + "type": "integer" + } + }, + "type": "object" + }, + "restartPolicy": { + "type": "string" + }, + "service": { + "properties": { + "name": { + "type": "string" + } + }, + "type": "object" + } + }, + "title": "Helm Values Schema", + "type": "object" +} diff --git a/kafdrop/values.yaml b/kafdrop/values.yaml new file mode 100644 index 0000000..67b46c3 --- /dev/null +++ b/kafdrop/values.yaml @@ -0,0 +1,42 @@ +global: + dockerRegistry: + url: ghcr.io/nationalsecurityagency + volumes: + certificates: + name: certificates + destination: /data/certs + initialization: + image: + name: busybox + tag: 1.28 + certSecretName: certificates-secret + pullSecrets: + - dockerconfigjson-ghcr + +####################################### +# Default Values for Audit Deployment # +####################################### +image: + name: obsidiandynamics/kafdrop + pullPolicy: IfNotPresent + tag: latest +args: [] + +meta: + name: kafdrop +service: + name: kafdrop + +replication: + maxSurge: 2 + maxUnavailable: 1 + replicaCount: 1 + revisionHistoryLimit: 10 +restartPolicy: Always + +####################################### +# Default Values for Executor Service # +####################################### + +ports: + kafdrop: 9000 diff --git a/kafka/.gitignore b/kafka/.gitignore new file mode 100644 index 0000000..79f2743 --- /dev/null +++ b/kafka/.gitignore @@ -0,0 +1,5 @@ +############################### +# Ignores Helm Chart Archives # +############################### + +**.tgz diff --git a/kafka/.helmignore b/kafka/.helmignore new file mode 100644 index 0000000..832a84e --- /dev/null +++ b/kafka/.helmignore @@ -0,0 +1,17 @@ +########################################### +# Ignores All File or Path Related to Git # +########################################### + +.git + +##################################### +# Ignores All Development Resources # +##################################### + +development/ +setup.sh + +############################ +# Ignores package Archives # +############################ +dwv-kafka-*.tgz diff --git a/kafka/Chart.yaml b/kafka/Chart.yaml new file mode 100644 index 0000000..8942d69 --- /dev/null +++ b/kafka/Chart.yaml @@ -0,0 +1,18 @@ +################################# +# Core Helm Chart Configuration # +################################# + +apiVersion: v2 +name: dwv-kafka +type: application +version: 1.0.0-SNAPSHOT + +################################# +# Basic Metadata for this Chart # +################################# + +appVersion: 3.2.3 +description: Deploys a kafka deployment +icon: https://code.nsa.gov/datawave/images/datawave-logo.png + + diff --git a/kafka/templates/kafka-service.yaml b/kafka/templates/kafka-service.yaml new file mode 100644 index 0000000..9dd33f5 --- /dev/null +++ b/kafka/templates/kafka-service.yaml @@ -0,0 +1,46 @@ +#################################### +# Core Helm Template Configuration # +#################################### + +apiVersion: v1 +kind: Service + +###################################### +# Basic Metadata for this Deployment # +###################################### + +metadata: + name: "{{ .Values.service.name }}" + labels: + application: "{{ .Values.meta.name }}" + +################################## +# Complete Service Specification # +################################## + +spec: + + ############################### + # Pod Selection Configuration # + ############################### + + selector: + application: "{{ .Values.meta.name }}" + + ############################## + # Service Port Configuration # + ############################## + + ports: + + - name: kafka-controller + port: {{ .Values.ports.controller }} + targetPort: 9093 + + - name: kafka-client + port: {{ .Values.ports.client }} + targetPort: 9092 + + - name: kafka-external + port: {{ .Values.ports.external }} + targetPort: 9094 diff --git a/kafka/templates/kafka-statefulset.yaml b/kafka/templates/kafka-statefulset.yaml new file mode 100644 index 0000000..22c9d97 --- /dev/null +++ b/kafka/templates/kafka-statefulset.yaml @@ -0,0 +1,104 @@ +#################################### +# Core Helm Template Configuration # +#################################### + +apiVersion: apps/v1 +kind: StatefulSet + +###################################### +# Basic Metadata for this Deployment # +###################################### + +metadata: + name: "{{ .Values.meta.name }}" + labels: + application: "{{ .Values.meta.name }}" + +##################################### +# Complete Deployment Specification # +##################################### + +spec: + + ###################################### + # Replication / Update Configuration # + ###################################### + serviceName: "{{ .Values.meta.name }}" + replicas: {{ .Values.replication.replicaCount }} + revisionHistoryLimit: {{ .Values.replication.revisionHistoryLimit }} + + ################################### + # Resource Selector Configuration # + ################################### + + selector: + matchLabels: + application: "{{ .Values.meta.name }}" + + ##################################### + # Deployment Template Configuration # + ##################################### + + template: + + ################################################## + # Basic Metadata for this Deployment's Resources # + ################################################## + + metadata: + labels: + application: "{{ .Values.meta.name }}" + + ####################################### + # Deployment Resources Specifications # + ####################################### + + spec: + {{- with .Values.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.image.pullSecrets }} + imagePullSecrets: + {{- range . }} + - name: {{ . }} + {{- end }} + {{- end }} + securityContext: + runAsUser: 1000 + fsGroup: 1000 + restartPolicy: "{{ .Values.restartPolicy }}" + ############################################## + # Containers Associated with this Deployment # + ############################################## + + containers: + - name: "{{ .Values.meta.name }}" + image: "{{ .Values.image.name }}:{{ .Values.image.tag }}" + imagePullPolicy: "{{ .Values.image.pullPolicy }}" + resources: {} + env: + - name: KAFKA_CFG_NODE_ID + value: "1" + - name: KAFKA_CFG_PROCESS_ROLES + value: controller,broker + - name: ALLOW_PLAINTEXT_LISTENER + value: "yes" + - name: KAFKA_CFG_LISTENER_SECURITY_PROTOCOL_MAP + value: CLIENT:PLAINTEXT,CONTROLLER:PLAINTEXT,EXTERNAL:PLAINTEXT + - name: KAFKA_CFG_LISTENERS + value: CLIENT://:9092,CONTROLLER://:9093,EXTERNAL://:9094 + - name: KAFKA_CFG_MAX_REQUEST_SIZE + value: "10485880" + - name: KAFKA_CFG_ADVERTISED_LISTENERS + value: CLIENT://{{ .Values.meta.name }}:9092,EXTERNAL://{{ .Values.meta.name }}-0:9094 + - name: KAFKA_CFG_CONTROLLER_QUORUM_VOTERS + value: 1@{{ .Values.meta.name }}:9093 + - name: KAFKA_CFG_CONTROLLER_LISTENER_NAMES + value: CONTROLLER + - name: KAFKA_INTER_BROKER_LISTENER_NAME + value: CLIENT + - name: KAFKA_CFG_AUTO_CREATE_TOPICS_ENABLE + value: "false" + - name: KAFKA_CFG_DELETE_TOPICS_ENABLE + value: "true" diff --git a/kafka/values.schema.json b/kafka/values.schema.json new file mode 100644 index 0000000..068c816 --- /dev/null +++ b/kafka/values.schema.json @@ -0,0 +1,206 @@ +{ + "$id": "https://code.nsa.org/datawave/schema", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "additionalProperties": true, + "description": "Schema for DataWave Helm values", + "properties": { + "args": { + "items": { + "type": "string" + }, + "type": "array" + }, + "global": { + "properties": { + "certSecretName": { + "type": "string" + }, + "dockerRegistry": { + "properties": { + "url": { + "type": "string" + } + }, + "type": "object" + }, + "initialization": { + "properties": { + "image": { + "properties": { + "name": { + "type": "string" + }, + "tag": { + "type": "number" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "pullSecrets": { + "items": { + "type": "string" + }, + "type": "array" + }, + "serviceDns": { + "properties": { + "authorization": { + "properties": { + "name": { + "type": "string" + } + }, + "type": "object" + }, + "cache": { + "properties": { + "name": { + "type": "string" + }, + "port": { + "type": "integer" + } + }, + "type": "object" + }, + "configuration": { + "properties": { + "name": { + "type": "string" + }, + "port": { + "type": "integer" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "volumes": { + "properties": { + "certificates": { + "properties": { + "destination": { + "type": "string" + }, + "name": { + "type": "string" + } + }, + "type": "object" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "image": { + "properties": { + "name": { + "type": "string" + }, + "pullPolicy": { + "type": "string" + }, + "tag": { + "type": "string" + } + }, + "type": "object" + }, + "livenessProbe": { + "properties": { + "delaySeconds": { + "type": "integer" + }, + "periodSeconds": { + "type": "integer" + }, + "port": { + "type": "integer" + }, + "scheme": { + "type": "string" + }, + "uri": { + "type": "string" + } + }, + "type": "object" + }, + "meta": { + "properties": { + "name": { + "type": "string" + } + }, + "type": "object" + }, + "ports": { + "properties": { + "http": { + "type": "integer" + }, + "https": { + "type": "integer" + } + }, + "type": "object" + }, + "readinessProbe": { + "properties": { + "delaySeconds": { + "type": "integer" + }, + "periodSeconds": { + "type": "integer" + }, + "port": { + "type": "integer" + }, + "scheme": { + "type": "string" + }, + "uri": { + "type": "string" + } + }, + "type": "object" + }, + "replication": { + "properties": { + "maxSurge": { + "type": "integer" + }, + "maxUnavailable": { + "type": "integer" + }, + "replicaCount": { + "type": "integer" + }, + "revisionHistoryLimit": { + "type": "integer" + } + }, + "type": "object" + }, + "restartPolicy": { + "type": "string" + }, + "service": { + "properties": { + "name": { + "type": "string" + } + }, + "type": "object" + } + }, + "title": "Helm Values Schema", + "type": "object" +} diff --git a/kafka/values.yaml b/kafka/values.yaml new file mode 100644 index 0000000..3bd8527 --- /dev/null +++ b/kafka/values.yaml @@ -0,0 +1,32 @@ +####################################### +# Default Values for Kafka Deployment # +####################################### +image: + name: bitnami/kafka + pullPolicy: IfNotPresent + tag: 3.2.3 + + +meta: + name: kafka +service: + name: kafka + +replication: + maxSurge: 2 + maxUnavailable: 1 + replicaCount: 1 + revisionHistoryLimit: 10 +restartPolicy: Always + +####################################### +# Default Values for Executor Service # +####################################### + +ports: + client: 9092 + controller: 9093 + external: 9094 + +tolerations: [] + \ No newline at end of file diff --git a/modification/.gitignore b/modification/.gitignore new file mode 100644 index 0000000..79f2743 --- /dev/null +++ b/modification/.gitignore @@ -0,0 +1,5 @@ +############################### +# Ignores Helm Chart Archives # +############################### + +**.tgz diff --git a/modification/.helmignore b/modification/.helmignore new file mode 100644 index 0000000..0d2ae28 --- /dev/null +++ b/modification/.helmignore @@ -0,0 +1,17 @@ +########################################### +# Ignores All File or Path Related to Git # +########################################### + +.git + +##################################### +# Ignores All Development Resources # +##################################### + +development/ +setup.sh + +############################ +# Ignores package Archives # +############################ +dwv-amodification-*.tgz diff --git a/modification/Chart.yaml b/modification/Chart.yaml new file mode 100644 index 0000000..ee1adf4 --- /dev/null +++ b/modification/Chart.yaml @@ -0,0 +1,22 @@ +################################# +# Core Helm Chart Configuration # +################################# + +apiVersion: v2 +name: dwv-modification +type: application +version: 1.0.0-SNAPSHOT + +################################# +# Basic Metadata for this Chart # +################################# + +appVersion: 1.0.3 +description: Deploys a datawave modification service +icon: https://code.nsa.gov/datawave/images/datawave-logo.png + +dependencies: + - name: common-service-library + repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts + version: 0.0.2 + diff --git a/modification/templates/modification-deployment.yaml b/modification/templates/modification-deployment.yaml new file mode 100644 index 0000000..194eb3e --- /dev/null +++ b/modification/templates/modification-deployment.yaml @@ -0,0 +1,19 @@ +{{- include "common-service-library.deployment" (list . "accumuloMicroservice.deployment") -}} +{{- define "accumuloMicroservice.deployment" -}} +#overrides go here +spec: + template: + spec: + initContainers: + - name: "{{ .Chart.Name }}-init-authorization" + image: "{{ .Values.global.initialization.image.name }}:{{ .Values.global.initialization.image.tag }}" + command: [ "sh", "-c", "until nc -z {{ .Values.global.serviceDns.authorization.name }} {{ .Values.global.serviceDns.authorization.port }}; do echo 'Waiting for Authorization...'; sleep 2; done" ] + + - name: "{{ .Chart.Name }}-init-cache" + image: "{{ .Values.global.initialization.image.name }}:{{ .Values.global.initialization.image.tag }}" + command: [ "sh", "-c", "until nc -z {{ .Values.global.serviceDns.cache.name }} {{ .Values.global.serviceDns.cache.port }}; do echo 'Waiting for Cache...'; sleep 2; done" ] + + - name: "{{ .Chart.Name }}-init-configuration" + image: "{{ .Values.global.initialization.image.name }}:{{ .Values.global.initialization.image.tag }}" + command: [ "sh", "-c", "until nc -z {{ .Values.global.serviceDns.configuration.name }} {{ .Values.global.serviceDns.configuration.port }}; do echo 'Waiting for Configuration...'; sleep 2; done" ] +{{- end -}} \ No newline at end of file diff --git a/modification/templates/modification-service.yaml b/modification/templates/modification-service.yaml new file mode 100644 index 0000000..2bcedaa --- /dev/null +++ b/modification/templates/modification-service.yaml @@ -0,0 +1,4 @@ +{{- include "common-service-library.service" (list . "accumuloMicroservice.service") -}} +{{- define "accumuloMicroservice.service" -}} +#overrides go here +{{- end -}} \ No newline at end of file diff --git a/modification/values.schema.json b/modification/values.schema.json new file mode 100644 index 0000000..068c816 --- /dev/null +++ b/modification/values.schema.json @@ -0,0 +1,206 @@ +{ + "$id": "https://code.nsa.org/datawave/schema", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "additionalProperties": true, + "description": "Schema for DataWave Helm values", + "properties": { + "args": { + "items": { + "type": "string" + }, + "type": "array" + }, + "global": { + "properties": { + "certSecretName": { + "type": "string" + }, + "dockerRegistry": { + "properties": { + "url": { + "type": "string" + } + }, + "type": "object" + }, + "initialization": { + "properties": { + "image": { + "properties": { + "name": { + "type": "string" + }, + "tag": { + "type": "number" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "pullSecrets": { + "items": { + "type": "string" + }, + "type": "array" + }, + "serviceDns": { + "properties": { + "authorization": { + "properties": { + "name": { + "type": "string" + } + }, + "type": "object" + }, + "cache": { + "properties": { + "name": { + "type": "string" + }, + "port": { + "type": "integer" + } + }, + "type": "object" + }, + "configuration": { + "properties": { + "name": { + "type": "string" + }, + "port": { + "type": "integer" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "volumes": { + "properties": { + "certificates": { + "properties": { + "destination": { + "type": "string" + }, + "name": { + "type": "string" + } + }, + "type": "object" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "image": { + "properties": { + "name": { + "type": "string" + }, + "pullPolicy": { + "type": "string" + }, + "tag": { + "type": "string" + } + }, + "type": "object" + }, + "livenessProbe": { + "properties": { + "delaySeconds": { + "type": "integer" + }, + "periodSeconds": { + "type": "integer" + }, + "port": { + "type": "integer" + }, + "scheme": { + "type": "string" + }, + "uri": { + "type": "string" + } + }, + "type": "object" + }, + "meta": { + "properties": { + "name": { + "type": "string" + } + }, + "type": "object" + }, + "ports": { + "properties": { + "http": { + "type": "integer" + }, + "https": { + "type": "integer" + } + }, + "type": "object" + }, + "readinessProbe": { + "properties": { + "delaySeconds": { + "type": "integer" + }, + "periodSeconds": { + "type": "integer" + }, + "port": { + "type": "integer" + }, + "scheme": { + "type": "string" + }, + "uri": { + "type": "string" + } + }, + "type": "object" + }, + "replication": { + "properties": { + "maxSurge": { + "type": "integer" + }, + "maxUnavailable": { + "type": "integer" + }, + "replicaCount": { + "type": "integer" + }, + "revisionHistoryLimit": { + "type": "integer" + } + }, + "type": "object" + }, + "restartPolicy": { + "type": "string" + }, + "service": { + "properties": { + "name": { + "type": "string" + } + }, + "type": "object" + } + }, + "title": "Helm Values Schema", + "type": "object" +} diff --git a/modification/values.yaml b/modification/values.yaml new file mode 100644 index 0000000..3550ed8 --- /dev/null +++ b/modification/values.yaml @@ -0,0 +1,67 @@ +global: + dockerRegistry: + url: ghcr.io/nationalsecurityagency + volumes: + certificates: + name: certificates + destination: /data/certs + initialization: + image: + name: busybox + tag: 1.28 + certSecretName: certificates-secret + pullSecrets: + - dockerconfigjson-ghcr + serviceDns: + configuration: + name: configuration + port: 8888 + authorization: + name: authorization + cache: + name: cache + port: 8080 + + +####################################### +# Default Values for Audit Deployment # +####################################### +image: + name: datawave-modification-service + pullPolicy: IfNotPresent + tag: 1.0.2 +args: +- "--spring.output.ansi.enabled=ALWAYS" +- "--spring.profiles.active=default,k8s,remoteauth,query" +livenessProbe: + delaySeconds: 20 + periodSeconds: 5 + failureThreshold: 60 + port: 8080 + scheme: HTTP + uri: modification/mgmt/health +meta: + name: modification +service: + name: modification +readinessProbe: + delaySeconds: 20 + periodSeconds: 5 + failureThreshold: 60 + port: 8080 + scheme: HTTP + uri: modification/mgmt/health +replication: + maxSurge: 2 + maxUnavailable: 1 + replicaCount: 1 + revisionHistoryLimit: 10 +restartPolicy: Always + +####################################### +# Default Values for Executor Service # +####################################### + +ports: + http: 8080 + https: 8443 diff --git a/mr-query/.gitignore b/mr-query/.gitignore new file mode 100644 index 0000000..79f2743 --- /dev/null +++ b/mr-query/.gitignore @@ -0,0 +1,5 @@ +############################### +# Ignores Helm Chart Archives # +############################### + +**.tgz diff --git a/mr-query/.helmignore b/mr-query/.helmignore new file mode 100644 index 0000000..0d2ae28 --- /dev/null +++ b/mr-query/.helmignore @@ -0,0 +1,17 @@ +########################################### +# Ignores All File or Path Related to Git # +########################################### + +.git + +##################################### +# Ignores All Development Resources # +##################################### + +development/ +setup.sh + +############################ +# Ignores package Archives # +############################ +dwv-amodification-*.tgz diff --git a/mr-query/Chart.yaml b/mr-query/Chart.yaml new file mode 100644 index 0000000..a9ebe00 --- /dev/null +++ b/mr-query/Chart.yaml @@ -0,0 +1,22 @@ +################################# +# Core Helm Chart Configuration # +################################# + +apiVersion: v2 +name: dwv-mr-query +type: application +version: 1.0.0-SNAPSHOT + +################################# +# Basic Metadata for this Chart # +################################# + +appVersion: 1.0.4 +description: Deploys a datawave mr-query service +icon: https://code.nsa.gov/datawave/images/datawave-logo.png + +dependencies: + - name: common-service-library + repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts + version: 0.0.2 + diff --git a/mr-query/templates/mr-query-deployment.yaml b/mr-query/templates/mr-query-deployment.yaml new file mode 100644 index 0000000..7e0c3ed --- /dev/null +++ b/mr-query/templates/mr-query-deployment.yaml @@ -0,0 +1,19 @@ +{{- include "common-service-library.deployment" (list . "mrQuery.deployment") -}} +{{- define "mrQuery.deployment" -}} +#overrides go here +spec: + template: + spec: + initContainers: + - name: "{{ .Chart.Name }}-init-authorization" + image: "{{ .Values.global.initialization.image.name }}:{{ .Values.global.initialization.image.tag }}" + command: [ "sh", "-c", "until nc -z {{ .Values.global.serviceDns.authorization.name }} {{ .Values.global.serviceDns.authorization.port }}; do echo 'Waiting for Authorization...'; sleep 2; done" ] + + - name: "{{ .Chart.Name }}-init-cache" + image: "{{ .Values.global.initialization.image.name }}:{{ .Values.global.initialization.image.tag }}" + command: [ "sh", "-c", "until nc -z {{ .Values.global.serviceDns.cache.name }} {{ .Values.global.serviceDns.cache.port }}; do echo 'Waiting for Cache...'; sleep 2; done" ] + + - name: "{{ .Chart.Name }}-init-configuration" + image: "{{ .Values.global.initialization.image.name }}:{{ .Values.global.initialization.image.tag }}" + command: [ "sh", "-c", "until nc -z {{ .Values.global.serviceDns.configuration.name }} {{ .Values.global.serviceDns.configuration.port }}; do echo 'Waiting for Configuration...'; sleep 2; done" ] +{{- end -}} \ No newline at end of file diff --git a/mr-query/templates/mr-query-service.yaml b/mr-query/templates/mr-query-service.yaml new file mode 100644 index 0000000..4b7c554 --- /dev/null +++ b/mr-query/templates/mr-query-service.yaml @@ -0,0 +1,4 @@ +{{- include "common-service-library.service" (list . "mrQuery.service") -}} +{{- define "mrQuery.service" -}} +#overrides go here +{{- end -}} \ No newline at end of file diff --git a/mr-query/values.schema.json b/mr-query/values.schema.json new file mode 100644 index 0000000..068c816 --- /dev/null +++ b/mr-query/values.schema.json @@ -0,0 +1,206 @@ +{ + "$id": "https://code.nsa.org/datawave/schema", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "additionalProperties": true, + "description": "Schema for DataWave Helm values", + "properties": { + "args": { + "items": { + "type": "string" + }, + "type": "array" + }, + "global": { + "properties": { + "certSecretName": { + "type": "string" + }, + "dockerRegistry": { + "properties": { + "url": { + "type": "string" + } + }, + "type": "object" + }, + "initialization": { + "properties": { + "image": { + "properties": { + "name": { + "type": "string" + }, + "tag": { + "type": "number" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "pullSecrets": { + "items": { + "type": "string" + }, + "type": "array" + }, + "serviceDns": { + "properties": { + "authorization": { + "properties": { + "name": { + "type": "string" + } + }, + "type": "object" + }, + "cache": { + "properties": { + "name": { + "type": "string" + }, + "port": { + "type": "integer" + } + }, + "type": "object" + }, + "configuration": { + "properties": { + "name": { + "type": "string" + }, + "port": { + "type": "integer" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "volumes": { + "properties": { + "certificates": { + "properties": { + "destination": { + "type": "string" + }, + "name": { + "type": "string" + } + }, + "type": "object" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "image": { + "properties": { + "name": { + "type": "string" + }, + "pullPolicy": { + "type": "string" + }, + "tag": { + "type": "string" + } + }, + "type": "object" + }, + "livenessProbe": { + "properties": { + "delaySeconds": { + "type": "integer" + }, + "periodSeconds": { + "type": "integer" + }, + "port": { + "type": "integer" + }, + "scheme": { + "type": "string" + }, + "uri": { + "type": "string" + } + }, + "type": "object" + }, + "meta": { + "properties": { + "name": { + "type": "string" + } + }, + "type": "object" + }, + "ports": { + "properties": { + "http": { + "type": "integer" + }, + "https": { + "type": "integer" + } + }, + "type": "object" + }, + "readinessProbe": { + "properties": { + "delaySeconds": { + "type": "integer" + }, + "periodSeconds": { + "type": "integer" + }, + "port": { + "type": "integer" + }, + "scheme": { + "type": "string" + }, + "uri": { + "type": "string" + } + }, + "type": "object" + }, + "replication": { + "properties": { + "maxSurge": { + "type": "integer" + }, + "maxUnavailable": { + "type": "integer" + }, + "replicaCount": { + "type": "integer" + }, + "revisionHistoryLimit": { + "type": "integer" + } + }, + "type": "object" + }, + "restartPolicy": { + "type": "string" + }, + "service": { + "properties": { + "name": { + "type": "string" + } + }, + "type": "object" + } + }, + "title": "Helm Values Schema", + "type": "object" +} diff --git a/mr-query/values.yaml b/mr-query/values.yaml new file mode 100644 index 0000000..d6931d5 --- /dev/null +++ b/mr-query/values.yaml @@ -0,0 +1,67 @@ +global: + dockerRegistry: + url: ghcr.io/nationalsecurityagency + volumes: + certificates: + name: certificates + destination: /data/certs + initialization: + image: + name: busybox + tag: 1.28 + certSecretName: certificates-secret + pullSecrets: + - dockerconfigjson-ghcr + serviceDns: + configuration: + name: configuration + port: 8888 + authorization: + name: authorization + cache: + name: cache + port: 8080 + + +####################################### +# Default Values for Audit Deployment # +####################################### +image: + name: datawave-mapreduce-query-service + pullPolicy: IfNotPresent + tag: 1.0.4 +args: +- "--spring.output.ansi.enabled=ALWAYS" +- "--spring.profiles.active=default,k8s,remoteauth,query" +livenessProbe: + delaySeconds: 20 + periodSeconds: 5 + failureThreshold: 60 + port: 8080 + scheme: HTTP + uri: mrquery/mgmt/health +meta: + name: mr-query +service: + name: mr-query +readinessProbe: + delaySeconds: 20 + periodSeconds: 5 + failureThreshold: 60 + port: 8080 + scheme: HTTP + uri: mrquery/mgmt/health +replication: + maxSurge: 2 + maxUnavailable: 1 + replicaCount: 1 + revisionHistoryLimit: 10 +restartPolicy: Always + +####################################### +# Default Values for Executor Service # +####################################### + +ports: + http: 8080 + https: 8443 From 9b37255018b5a17cf53c5a4bf9a03d21a860c1a2 Mon Sep 17 00:00:00 2001 From: Adam Lerman Date: Tue, 8 Oct 2024 23:50:38 +0000 Subject: [PATCH 07/16] QMS next step complete --- datawave-qms-stack/.helmignore | 19 ++ datawave-qms-stack/.schema.yaml | 13 ++ datawave-qms-stack/Chart.lock | 21 ++ datawave-qms-stack/Chart.yaml | 38 ++++ datawave-qms-stack/README.md | 3 + datawave-qms-stack/certificates/keystore.p12 | Bin 0 -> 3586 bytes .../certificates/truststore.jks | Bin 0 -> 163715 bytes datawave-qms-stack/templates/_helpers.tpl | 23 ++ datawave-qms-stack/templates/hdfs.yaml | 19 ++ datawave-qms-stack/templates/yarn.yaml | 19 ++ datawave-qms-stack/templates/zookeeper.yaml | 24 ++ datawave-qms-stack/values-testing.yaml | 8 + datawave-qms-stack/values.schema.json | 88 ++++++++ datawave-qms-stack/values.yaml | 27 +++ datawave-qms-umbrella/.schema.yaml | 13 ++ datawave-qms-umbrella/Chart.lock | 42 ++++ datawave-qms-umbrella/Chart.yaml | 57 +++++ datawave-qms-umbrella/README.md | 3 + datawave-qms-umbrella/values.schema.json | 74 +++++++ datawave-qms-umbrella/values.yaml | 22 ++ executor/.gitignore | 5 + executor/.helmignore | 17 ++ executor/Chart.lock | 6 + executor/Chart.yaml | 22 ++ .../accumulo-microservice-deployment.yaml | 19 ++ .../accumulo-microservice-service.yaml | 4 + executor/values.schema.json | 206 ++++++++++++++++++ executor/values.yaml | 67 ++++++ query-metrics/.gitignore | 5 + query-metrics/.helmignore | 17 ++ query-metrics/Chart.lock | 6 + query-metrics/Chart.yaml | 22 ++ .../templates/query-metrics-deployment.yaml | 19 ++ .../templates/query-metrics-service.yaml | 4 + query-metrics/values.schema.json | 206 ++++++++++++++++++ query-metrics/values.yaml | 67 ++++++ query/.gitignore | 5 + query/.helmignore | 17 ++ query/Chart.lock | 6 + query/Chart.yaml | 22 ++ query/templates/query-deployment.yaml | 19 ++ query/templates/query-service.yaml | 4 + query/values.schema.json | 206 ++++++++++++++++++ query/values.yaml | 67 ++++++ shared-functions.sh | 92 ++++++++ startLocalQMSTest.sh | 64 ++++++ startLocalTest.sh | 120 +--------- 47 files changed, 1718 insertions(+), 109 deletions(-) create mode 100644 datawave-qms-stack/.helmignore create mode 100644 datawave-qms-stack/.schema.yaml create mode 100644 datawave-qms-stack/Chart.lock create mode 100644 datawave-qms-stack/Chart.yaml create mode 100644 datawave-qms-stack/README.md create mode 100644 datawave-qms-stack/certificates/keystore.p12 create mode 100644 datawave-qms-stack/certificates/truststore.jks create mode 100644 datawave-qms-stack/templates/_helpers.tpl create mode 100644 datawave-qms-stack/templates/hdfs.yaml create mode 100644 datawave-qms-stack/templates/yarn.yaml create mode 100644 datawave-qms-stack/templates/zookeeper.yaml create mode 100644 datawave-qms-stack/values-testing.yaml create mode 100644 datawave-qms-stack/values.schema.json create mode 100644 datawave-qms-stack/values.yaml create mode 100644 datawave-qms-umbrella/.schema.yaml create mode 100644 datawave-qms-umbrella/Chart.lock create mode 100644 datawave-qms-umbrella/Chart.yaml create mode 100644 datawave-qms-umbrella/README.md create mode 100644 datawave-qms-umbrella/values.schema.json create mode 100644 datawave-qms-umbrella/values.yaml create mode 100644 executor/.gitignore create mode 100644 executor/.helmignore create mode 100644 executor/Chart.lock create mode 100644 executor/Chart.yaml create mode 100644 executor/templates/accumulo-microservice-deployment.yaml create mode 100644 executor/templates/accumulo-microservice-service.yaml create mode 100644 executor/values.schema.json create mode 100644 executor/values.yaml create mode 100644 query-metrics/.gitignore create mode 100644 query-metrics/.helmignore create mode 100644 query-metrics/Chart.lock create mode 100644 query-metrics/Chart.yaml create mode 100644 query-metrics/templates/query-metrics-deployment.yaml create mode 100644 query-metrics/templates/query-metrics-service.yaml create mode 100644 query-metrics/values.schema.json create mode 100644 query-metrics/values.yaml create mode 100644 query/.gitignore create mode 100644 query/.helmignore create mode 100644 query/Chart.lock create mode 100644 query/Chart.yaml create mode 100644 query/templates/query-deployment.yaml create mode 100644 query/templates/query-service.yaml create mode 100644 query/values.schema.json create mode 100644 query/values.yaml create mode 100644 shared-functions.sh create mode 100755 startLocalQMSTest.sh diff --git a/datawave-qms-stack/.helmignore b/datawave-qms-stack/.helmignore new file mode 100644 index 0000000..1c1043d --- /dev/null +++ b/datawave-qms-stack/.helmignore @@ -0,0 +1,19 @@ +########################################### +# Ignores All File or Path Related to Git # +########################################### + +.git + +##################################### +# Ignores All Development Resources # +##################################### + +development/ +setup.sh + +######################## +# Ignores All Archives # +######################## + +*.tar.gz +datawave-system-*.tgz diff --git a/datawave-qms-stack/.schema.yaml b/datawave-qms-stack/.schema.yaml new file mode 100644 index 0000000..546b749 --- /dev/null +++ b/datawave-qms-stack/.schema.yaml @@ -0,0 +1,13 @@ +# Required +input: + - values.yaml + +draft: 2020 +indent: 4 +output: values.schema.json + +schemaRoot: + id: https://code.nsa.org/datawave/schema + title: Helm Values Schema + description: Schema for DataWave Helm values + additionalProperties: true diff --git a/datawave-qms-stack/Chart.lock b/datawave-qms-stack/Chart.lock new file mode 100644 index 0000000..2e6bde4 --- /dev/null +++ b/datawave-qms-stack/Chart.lock @@ -0,0 +1,21 @@ +dependencies: +- name: dwv-ingest + repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts + version: 1.0.0 +- name: dwv-hadoop + repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts + version: 1.0.0 +- name: dwv-hadoop-config + repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts + version: 1.0.0 +- name: dwv-zookeeper + repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts + version: 1.0.0 +- name: dwv-accumulo + repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts + version: 1.0.0 +- name: datawave-qms-umbrella + repository: file://../datawave-qms-umbrella + version: 1.0.0-SNAPSHOT +digest: sha256:425b773c0ee3abf3d311df05c0213f9ba5af887792be8f8edaaf628c4ac3207a +generated: "2024-10-08T11:06:21.957957643Z" diff --git a/datawave-qms-stack/Chart.yaml b/datawave-qms-stack/Chart.yaml new file mode 100644 index 0000000..0c1b7a6 --- /dev/null +++ b/datawave-qms-stack/Chart.yaml @@ -0,0 +1,38 @@ +##################################### +# DataWave Helm Chart Configuration # +##################################### + +apiVersion: v2 +name: datawave-qms +type: application +version: 1.0.0-SNAPSHOT + +################################# +# Basic Metadata for this Chart # +################################# + +appVersion: 1.0.0 +description: Deploys an Entire DataWave Stack w/ Dependencies using Query Microservices +icon: https://code.nsa.gov/datawave/images/datawave-logo.png + +dependencies: + - name: dwv-ingest + repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts + version: 1.0.0 + - name: dwv-hadoop + repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts + version: 1.0.0 + condition: charts.hadoop.enabled + - name: dwv-hadoop-config + repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts + version: 1.0.0 + - name: dwv-zookeeper + repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts + version: 1.0.0 + condition: charts.zookeeper.enabled + - name: dwv-accumulo + repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts + version: 1.0.0 + - name: datawave-qms-umbrella + repository: file://../datawave-qms-umbrella + version: 1.0.0-SNAPSHOT diff --git a/datawave-qms-stack/README.md b/datawave-qms-stack/README.md new file mode 100644 index 0000000..19d864d --- /dev/null +++ b/datawave-qms-stack/README.md @@ -0,0 +1,3 @@ +# DataWave Web Helm Chart + +Manages All Helm Resources Required to Support a Deployment of DataWave Web diff --git a/datawave-qms-stack/certificates/keystore.p12 b/datawave-qms-stack/certificates/keystore.p12 new file mode 100644 index 0000000000000000000000000000000000000000..ee6ca90def7f6a8888e37560a8a0f1d0aed6a9d7 GIT binary patch literal 3586 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 WLMG(VGG1zJH>f(sOX)Tk@&5rX1>|@D literal 0 HcmV?d00001 diff --git a/datawave-qms-stack/templates/_helpers.tpl b/datawave-qms-stack/templates/_helpers.tpl new file mode 100644 index 0000000..9713615 --- /dev/null +++ b/datawave-qms-stack/templates/_helpers.tpl @@ -0,0 +1,23 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +*/}} +{{- define "datawave.stack.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). +*/}} +{{- define "datawave.stack.fullname" -}} +{{- $name := default .Chart.Name .Values.nameOverride -}} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "datawave.stack.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} +{{- end -}} diff --git a/datawave-qms-stack/templates/hdfs.yaml b/datawave-qms-stack/templates/hdfs.yaml new file mode 100644 index 0000000..2c78769 --- /dev/null +++ b/datawave-qms-stack/templates/hdfs.yaml @@ -0,0 +1,19 @@ +{{- if not .Values.charts.hadoop.enabled }} +{{- with .Values.external.hdfs.hosts }} +{{- range . }} +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ . }} + labels: + app: hdfs + chart: {{ include "datawave.stack.chart" $ }} + release: {{ $.Release.Name }} + app.kubernetes.io/component: {{ . }} +spec: + externalName: {{ . }} + type: ExternalName +{{- end }} +{{- end }} +{{- end }} \ No newline at end of file diff --git a/datawave-qms-stack/templates/yarn.yaml b/datawave-qms-stack/templates/yarn.yaml new file mode 100644 index 0000000..15a15fb --- /dev/null +++ b/datawave-qms-stack/templates/yarn.yaml @@ -0,0 +1,19 @@ +{{- if not .Values.charts.hadoop.enabled }} +{{- with .Values.external.yarn.hosts }} +{{- range . }} +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ . }} + labels: + app: yarn + chart: {{ include "datawave.stack.chart" $ }} + release: {{ $.Release.Name }} + app.kubernetes.io/component: {{ . }} +spec: + externalName: {{ . }} + type: ExternalName +{{- end }} +{{- end }} +{{- end }} diff --git a/datawave-qms-stack/templates/zookeeper.yaml b/datawave-qms-stack/templates/zookeeper.yaml new file mode 100644 index 0000000..83bf769 --- /dev/null +++ b/datawave-qms-stack/templates/zookeeper.yaml @@ -0,0 +1,24 @@ +{{- if not .Values.charts.zookeeper.enabled }} +{{- with .Values.external.zookeeper.hosts }} +{{- range . }} +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ . }} + labels: + app: zookeeper + chart: {{ include "datawave.stack.chart" $ }} + release: {{ $.Release.Name }} + app.kubernetes.io/component: zookeeper +spec: + externalName: {{ . }} + ports: + - name: zk + port: 2181 + protocol: TCP + targetPort: 2181 + type: ExternalName +{{- end }} +{{- end }} +{{- end }} \ No newline at end of file diff --git a/datawave-qms-stack/values-testing.yaml b/datawave-qms-stack/values-testing.yaml new file mode 100644 index 0000000..9e9294b --- /dev/null +++ b/datawave-qms-stack/values-testing.yaml @@ -0,0 +1,8 @@ +dwv-accumulo: + image: + tag: 2.1.3 + initContainer: + tag: 3.3.6 +dwv-hadoop: + image: + tag: 3.3.6 diff --git a/datawave-qms-stack/values.schema.json b/datawave-qms-stack/values.schema.json new file mode 100644 index 0000000..161c3c1 --- /dev/null +++ b/datawave-qms-stack/values.schema.json @@ -0,0 +1,88 @@ +{ + "$id": "https://code.nsa.org/datawave/schema", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "additionalProperties": true, + "description": "Schema for DataWave Helm values", + "properties": { + "charts": { + "properties": { + "hadoop": { + "properties": { + "enabled": { + "type": "boolean" + } + }, + "type": "object" + }, + "zookeeper": { + "properties": { + "enabled": { + "type": "boolean" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "dockerRegistry": { + "properties": { + "url": { + "type": "string" + } + }, + "type": "object" + }, + "external": { + "properties": { + "hdfs": { + "properties": { + "hosts": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "yarn": { + "properties": { + "hosts": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "zookeeper": { + "properties": { + "hosts": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "global": { + "properties": { + "accumuloConfigMap": { + "type": "string" + }, + "hadoopConfigMap": { + "type": "string" + } + }, + "type": "object" + } + }, + "title": "Helm Values Schema", + "type": "object" +} diff --git a/datawave-qms-stack/values.yaml b/datawave-qms-stack/values.yaml new file mode 100644 index 0000000..dfb8f9c --- /dev/null +++ b/datawave-qms-stack/values.yaml @@ -0,0 +1,27 @@ +###################################### +# Default Values for Docker Registry # +###################################### + +global: + hadoopConfigMap: dwv-hadoop-config + accumuloConfigMap: dwv-accumulo-config + +dockerRegistry: + url: ghcr.io/nationalsecurityagency/ +charts: + zookeeper: + enabled: true + hadoop: + enabled: true +external: + zookeeper: + hosts: + - zookeeper + hdfs: + hosts: + - hdfs-nn + - hdfs-dn + yarn: + hosts: + - yarn-rm + - yarn-nm \ No newline at end of file diff --git a/datawave-qms-umbrella/.schema.yaml b/datawave-qms-umbrella/.schema.yaml new file mode 100644 index 0000000..546b749 --- /dev/null +++ b/datawave-qms-umbrella/.schema.yaml @@ -0,0 +1,13 @@ +# Required +input: + - values.yaml + +draft: 2020 +indent: 4 +output: values.schema.json + +schemaRoot: + id: https://code.nsa.org/datawave/schema + title: Helm Values Schema + description: Schema for DataWave Helm values + additionalProperties: true diff --git a/datawave-qms-umbrella/Chart.lock b/datawave-qms-umbrella/Chart.lock new file mode 100644 index 0000000..03b34c0 --- /dev/null +++ b/datawave-qms-umbrella/Chart.lock @@ -0,0 +1,42 @@ +dependencies: +- name: dwv-audit + repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts + version: 1.0.0 +- name: dwv-authorization + repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts + version: 1.0.0 +- name: dwv-cache + repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts + version: 1.0.0 +- name: dwv-configuration + repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts + version: 1.0.0 +- name: dwv-dictionary + repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts + version: 1.0.0 +- name: dwv-executor + repository: file://../executor/ + version: 1.0.0-SNAPSHOT +- name: dwv-kafdrop + repository: file://../kafdrop + version: 1.0.0-SNAPSHOT +- name: dwv-kafka + repository: file://../kafka + version: 1.0.0-SNAPSHOT +- name: dwv-modification + repository: file://../modification + version: 1.0.0-SNAPSHOT +- name: dwv-mr-query + repository: file://../mr-query + version: 1.0.0-SNAPSHOT +- name: dwv-query + repository: file://../query + version: 1.0.0-SNAPSHOT +- name: dwv-query-metrics + repository: file://../query-metrics + version: 1.0.0-SNAPSHOT +- name: dwv-rabbitmq + repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts + version: 1.0.0 +digest: sha256:00d0cd83713ad19d971fd74c64b57032c24250c05f5ae25df1f6549261a99e4f +generated: "2024-10-08T10:51:03.152002577Z" diff --git a/datawave-qms-umbrella/Chart.yaml b/datawave-qms-umbrella/Chart.yaml new file mode 100644 index 0000000..4810478 --- /dev/null +++ b/datawave-qms-umbrella/Chart.yaml @@ -0,0 +1,57 @@ +##################################### +# DataWave Helm Chart Configuration # +##################################### + +apiVersion: v2 +name: datawave-qms-umbrella +type: application +version: 1.0.0-SNAPSHOT + +################################# +# Basic Metadata for this Chart # +################################# + +appVersion: 1.0.0 +description: Deploys The web stack of DataWave using Query Microservices +icon: https://code.nsa.gov/datawave/images/datawave-logo.png + +dependencies: + - name: dwv-audit + repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts + version: 1.0.0 + - name: dwv-authorization + repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts + version: 1.0.0 + - name: dwv-cache + repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts + version: 1.0.0 + - name: dwv-configuration + repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts + version: 1.0.0 + - name: dwv-dictionary + repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts + version: 1.0.0 + - name: dwv-executor + repository: file://../executor/ + version: 1.0.0-SNAPSHOT + - name: dwv-kafdrop + repository: file://../kafdrop + version: 1.0.0-SNAPSHOT + - name: dwv-kafka + repository: file://../kafka + version: 1.0.0-SNAPSHOT + - name: dwv-modification + repository: file://../modification + version: 1.0.0-SNAPSHOT + - name: dwv-mr-query + repository: file://../mr-query + version: 1.0.0-SNAPSHOT + - name: dwv-query + repository: file://../query + version: 1.0.0-SNAPSHOT + - name: dwv-query-metrics + repository: file://../query-metrics + version: 1.0.0-SNAPSHOT + - name: dwv-rabbitmq + repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts + version: 1.0.0 \ No newline at end of file diff --git a/datawave-qms-umbrella/README.md b/datawave-qms-umbrella/README.md new file mode 100644 index 0000000..19d864d --- /dev/null +++ b/datawave-qms-umbrella/README.md @@ -0,0 +1,3 @@ +# DataWave Web Helm Chart + +Manages All Helm Resources Required to Support a Deployment of DataWave Web diff --git a/datawave-qms-umbrella/values.schema.json b/datawave-qms-umbrella/values.schema.json new file mode 100644 index 0000000..0fde354 --- /dev/null +++ b/datawave-qms-umbrella/values.schema.json @@ -0,0 +1,74 @@ +{ + "$id": "https://code.nsa.org/datawave/schema", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "additionalProperties": true, + "description": "Schema for DataWave Helm values", + "properties": { + "dockerRegistry": { + "properties": { + "url": { + "type": "string" + } + }, + "type": "object" + }, + "global": { + "properties": { + "serviceDns": { + "properties": { + "accumuloManager": { + "properties": { + "name": { + "type": "string" + } + }, + "type": "object" + }, + "authorization": { + "properties": { + "name": { + "type": "string" + } + }, + "type": "object" + }, + "cache": { + "properties": { + "name": { + "type": "string" + }, + "port": { + "type": "integer" + } + }, + "type": "object" + }, + "configuration": { + "properties": { + "name": { + "type": "string" + }, + "port": { + "type": "integer" + } + }, + "type": "object" + }, + "rabbitmq": { + "properties": { + "name": { + "type": "string" + } + }, + "type": "object" + } + }, + "type": "object" + } + }, + "type": "object" + } + }, + "title": "Helm Values Schema", + "type": "object" +} diff --git a/datawave-qms-umbrella/values.yaml b/datawave-qms-umbrella/values.yaml new file mode 100644 index 0000000..7d7d890 --- /dev/null +++ b/datawave-qms-umbrella/values.yaml @@ -0,0 +1,22 @@ +global: + serviceDns: + accumuloManager: + name: accumulo-manager + authorization: + name: authorization + cache: + name: cache + port: 8080 + configuration: + name: configuration + port: 8888 + rabbitmq: + name: rabbitmq + + +###################################### +# Default Values for Docker Registry # +###################################### + +dockerRegistry: + url: ghcr.io/nationalsecurityagency/ diff --git a/executor/.gitignore b/executor/.gitignore new file mode 100644 index 0000000..79f2743 --- /dev/null +++ b/executor/.gitignore @@ -0,0 +1,5 @@ +############################### +# Ignores Helm Chart Archives # +############################### + +**.tgz diff --git a/executor/.helmignore b/executor/.helmignore new file mode 100644 index 0000000..aa06c2c --- /dev/null +++ b/executor/.helmignore @@ -0,0 +1,17 @@ +########################################### +# Ignores All File or Path Related to Git # +########################################### + +.git + +##################################### +# Ignores All Development Resources # +##################################### + +development/ +setup.sh + +############################ +# Ignores package Archives # +############################ +dwv-accumulo-microservice-*.tgz diff --git a/executor/Chart.lock b/executor/Chart.lock new file mode 100644 index 0000000..c7d3c8d --- /dev/null +++ b/executor/Chart.lock @@ -0,0 +1,6 @@ +dependencies: +- name: common-service-library + repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts + version: 0.0.2 +digest: sha256:9f6737e1bdb7c4772bf295ccb128a1d540237dd1b7770e0edbd185d1b17a1a31 +generated: "2024-10-04T18:58:14.981876411Z" diff --git a/executor/Chart.yaml b/executor/Chart.yaml new file mode 100644 index 0000000..6356828 --- /dev/null +++ b/executor/Chart.yaml @@ -0,0 +1,22 @@ +################################# +# Core Helm Chart Configuration # +################################# + +apiVersion: v2 +name: dwv-executor +type: application +version: 1.0.0-SNAPSHOT + +################################# +# Basic Metadata for this Chart # +################################# + +appVersion: 1.0.9 +description: Deploys a datawave query executor service +icon: https://code.nsa.gov/datawave/images/datawave-logo.png + +dependencies: + - name: common-service-library + repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts + version: 0.0.2 + diff --git a/executor/templates/accumulo-microservice-deployment.yaml b/executor/templates/accumulo-microservice-deployment.yaml new file mode 100644 index 0000000..194eb3e --- /dev/null +++ b/executor/templates/accumulo-microservice-deployment.yaml @@ -0,0 +1,19 @@ +{{- include "common-service-library.deployment" (list . "accumuloMicroservice.deployment") -}} +{{- define "accumuloMicroservice.deployment" -}} +#overrides go here +spec: + template: + spec: + initContainers: + - name: "{{ .Chart.Name }}-init-authorization" + image: "{{ .Values.global.initialization.image.name }}:{{ .Values.global.initialization.image.tag }}" + command: [ "sh", "-c", "until nc -z {{ .Values.global.serviceDns.authorization.name }} {{ .Values.global.serviceDns.authorization.port }}; do echo 'Waiting for Authorization...'; sleep 2; done" ] + + - name: "{{ .Chart.Name }}-init-cache" + image: "{{ .Values.global.initialization.image.name }}:{{ .Values.global.initialization.image.tag }}" + command: [ "sh", "-c", "until nc -z {{ .Values.global.serviceDns.cache.name }} {{ .Values.global.serviceDns.cache.port }}; do echo 'Waiting for Cache...'; sleep 2; done" ] + + - name: "{{ .Chart.Name }}-init-configuration" + image: "{{ .Values.global.initialization.image.name }}:{{ .Values.global.initialization.image.tag }}" + command: [ "sh", "-c", "until nc -z {{ .Values.global.serviceDns.configuration.name }} {{ .Values.global.serviceDns.configuration.port }}; do echo 'Waiting for Configuration...'; sleep 2; done" ] +{{- end -}} \ No newline at end of file diff --git a/executor/templates/accumulo-microservice-service.yaml b/executor/templates/accumulo-microservice-service.yaml new file mode 100644 index 0000000..2bcedaa --- /dev/null +++ b/executor/templates/accumulo-microservice-service.yaml @@ -0,0 +1,4 @@ +{{- include "common-service-library.service" (list . "accumuloMicroservice.service") -}} +{{- define "accumuloMicroservice.service" -}} +#overrides go here +{{- end -}} \ No newline at end of file diff --git a/executor/values.schema.json b/executor/values.schema.json new file mode 100644 index 0000000..068c816 --- /dev/null +++ b/executor/values.schema.json @@ -0,0 +1,206 @@ +{ + "$id": "https://code.nsa.org/datawave/schema", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "additionalProperties": true, + "description": "Schema for DataWave Helm values", + "properties": { + "args": { + "items": { + "type": "string" + }, + "type": "array" + }, + "global": { + "properties": { + "certSecretName": { + "type": "string" + }, + "dockerRegistry": { + "properties": { + "url": { + "type": "string" + } + }, + "type": "object" + }, + "initialization": { + "properties": { + "image": { + "properties": { + "name": { + "type": "string" + }, + "tag": { + "type": "number" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "pullSecrets": { + "items": { + "type": "string" + }, + "type": "array" + }, + "serviceDns": { + "properties": { + "authorization": { + "properties": { + "name": { + "type": "string" + } + }, + "type": "object" + }, + "cache": { + "properties": { + "name": { + "type": "string" + }, + "port": { + "type": "integer" + } + }, + "type": "object" + }, + "configuration": { + "properties": { + "name": { + "type": "string" + }, + "port": { + "type": "integer" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "volumes": { + "properties": { + "certificates": { + "properties": { + "destination": { + "type": "string" + }, + "name": { + "type": "string" + } + }, + "type": "object" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "image": { + "properties": { + "name": { + "type": "string" + }, + "pullPolicy": { + "type": "string" + }, + "tag": { + "type": "string" + } + }, + "type": "object" + }, + "livenessProbe": { + "properties": { + "delaySeconds": { + "type": "integer" + }, + "periodSeconds": { + "type": "integer" + }, + "port": { + "type": "integer" + }, + "scheme": { + "type": "string" + }, + "uri": { + "type": "string" + } + }, + "type": "object" + }, + "meta": { + "properties": { + "name": { + "type": "string" + } + }, + "type": "object" + }, + "ports": { + "properties": { + "http": { + "type": "integer" + }, + "https": { + "type": "integer" + } + }, + "type": "object" + }, + "readinessProbe": { + "properties": { + "delaySeconds": { + "type": "integer" + }, + "periodSeconds": { + "type": "integer" + }, + "port": { + "type": "integer" + }, + "scheme": { + "type": "string" + }, + "uri": { + "type": "string" + } + }, + "type": "object" + }, + "replication": { + "properties": { + "maxSurge": { + "type": "integer" + }, + "maxUnavailable": { + "type": "integer" + }, + "replicaCount": { + "type": "integer" + }, + "revisionHistoryLimit": { + "type": "integer" + } + }, + "type": "object" + }, + "restartPolicy": { + "type": "string" + }, + "service": { + "properties": { + "name": { + "type": "string" + } + }, + "type": "object" + } + }, + "title": "Helm Values Schema", + "type": "object" +} diff --git a/executor/values.yaml b/executor/values.yaml new file mode 100644 index 0000000..e71e1b7 --- /dev/null +++ b/executor/values.yaml @@ -0,0 +1,67 @@ +global: + dockerRegistry: + url: ghcr.io/nationalsecurityagency + volumes: + certificates: + name: certificates + destination: /data/certs + initialization: + image: + name: busybox + tag: 1.28 + certSecretName: certificates-secret + pullSecrets: + - dockerconfigjson-ghcr + serviceDns: + configuration: + name: configuration + port: 8888 + authorization: + name: authorization + cache: + name: cache + port: 8080 + + +####################################### +# Default Values for Audit Deployment # +####################################### +image: + name: datawave-query-executor-service + pullPolicy: IfNotPresent + tag: 1.0.9 +args: +- "--spring.output.ansi.enabled=ALWAYS" +- "--spring.profiles.active= default,k8s,remoteauth,querymessaging,metricssource,federation,query,pool1" +livenessProbe: + delaySeconds: 20 + periodSeconds: 5 + failureThreshold: 60 + port: 8080 + scheme: HTTP + uri: executor/mgmt/health +meta: + name: executor +service: + name: executor +readinessProbe: + delaySeconds: 20 + periodSeconds: 5 + failureThreshold: 60 + port: 8080 + scheme: HTTP + uri: executor/mgmt/health +replication: + maxSurge: 2 + maxUnavailable: 1 + replicaCount: 1 + revisionHistoryLimit: 10 +restartPolicy: Always + +####################################### +# Default Values for Executor Service # +####################################### + +ports: + http: 8080 + https: 8443 diff --git a/query-metrics/.gitignore b/query-metrics/.gitignore new file mode 100644 index 0000000..79f2743 --- /dev/null +++ b/query-metrics/.gitignore @@ -0,0 +1,5 @@ +############################### +# Ignores Helm Chart Archives # +############################### + +**.tgz diff --git a/query-metrics/.helmignore b/query-metrics/.helmignore new file mode 100644 index 0000000..e60a303 --- /dev/null +++ b/query-metrics/.helmignore @@ -0,0 +1,17 @@ +########################################### +# Ignores All File or Path Related to Git # +########################################### + +.git + +##################################### +# Ignores All Development Resources # +##################################### + +development/ +setup.sh + +############################ +# Ignores package Archives # +############################ +dwv-query-metrics-*.tgz diff --git a/query-metrics/Chart.lock b/query-metrics/Chart.lock new file mode 100644 index 0000000..2840813 --- /dev/null +++ b/query-metrics/Chart.lock @@ -0,0 +1,6 @@ +dependencies: +- name: common-service-library + repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts + version: 0.0.2 +digest: sha256:9f6737e1bdb7c4772bf295ccb128a1d540237dd1b7770e0edbd185d1b17a1a31 +generated: "2024-10-08T10:50:10.666522838Z" diff --git a/query-metrics/Chart.yaml b/query-metrics/Chart.yaml new file mode 100644 index 0000000..9c41707 --- /dev/null +++ b/query-metrics/Chart.yaml @@ -0,0 +1,22 @@ +################################# +# Core Helm Chart Configuration # +################################# + +apiVersion: v2 +name: dwv-query-metrics +type: application +version: 1.0.0-SNAPSHOT + +################################# +# Basic Metadata for this Chart # +################################# + +appVersion: 4.0.8 +description: Deploys a datawave query metric service +icon: https://code.nsa.gov/datawave/images/datawave-logo.png + +dependencies: + - name: common-service-library + repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts + version: 0.0.2 + diff --git a/query-metrics/templates/query-metrics-deployment.yaml b/query-metrics/templates/query-metrics-deployment.yaml new file mode 100644 index 0000000..c9b755e --- /dev/null +++ b/query-metrics/templates/query-metrics-deployment.yaml @@ -0,0 +1,19 @@ +{{- include "common-service-library.deployment" (list . "queryMetrics.deployment") -}} +{{- define "queryMetrics.deployment" -}} +#overrides go here +spec: + template: + spec: + initContainers: + - name: "{{ .Chart.Name }}-init-authorization" + image: "{{ .Values.global.initialization.image.name }}:{{ .Values.global.initialization.image.tag }}" + command: [ "sh", "-c", "until nc -z {{ .Values.global.serviceDns.authorization.name }} {{ .Values.global.serviceDns.authorization.port }}; do echo 'Waiting for Authorization...'; sleep 2; done" ] + + - name: "{{ .Chart.Name }}-init-cache" + image: "{{ .Values.global.initialization.image.name }}:{{ .Values.global.initialization.image.tag }}" + command: [ "sh", "-c", "until nc -z {{ .Values.global.serviceDns.cache.name }} {{ .Values.global.serviceDns.cache.port }}; do echo 'Waiting for Cache...'; sleep 2; done" ] + + - name: "{{ .Chart.Name }}-init-configuration" + image: "{{ .Values.global.initialization.image.name }}:{{ .Values.global.initialization.image.tag }}" + command: [ "sh", "-c", "until nc -z {{ .Values.global.serviceDns.configuration.name }} {{ .Values.global.serviceDns.configuration.port }}; do echo 'Waiting for Configuration...'; sleep 2; done" ] +{{- end -}} \ No newline at end of file diff --git a/query-metrics/templates/query-metrics-service.yaml b/query-metrics/templates/query-metrics-service.yaml new file mode 100644 index 0000000..3b1aa11 --- /dev/null +++ b/query-metrics/templates/query-metrics-service.yaml @@ -0,0 +1,4 @@ +{{- include "common-service-library.service" (list . "queryMetrics.service") -}} +{{- define "queryMetrics.service" -}} +#overrides go here +{{- end -}} \ No newline at end of file diff --git a/query-metrics/values.schema.json b/query-metrics/values.schema.json new file mode 100644 index 0000000..068c816 --- /dev/null +++ b/query-metrics/values.schema.json @@ -0,0 +1,206 @@ +{ + "$id": "https://code.nsa.org/datawave/schema", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "additionalProperties": true, + "description": "Schema for DataWave Helm values", + "properties": { + "args": { + "items": { + "type": "string" + }, + "type": "array" + }, + "global": { + "properties": { + "certSecretName": { + "type": "string" + }, + "dockerRegistry": { + "properties": { + "url": { + "type": "string" + } + }, + "type": "object" + }, + "initialization": { + "properties": { + "image": { + "properties": { + "name": { + "type": "string" + }, + "tag": { + "type": "number" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "pullSecrets": { + "items": { + "type": "string" + }, + "type": "array" + }, + "serviceDns": { + "properties": { + "authorization": { + "properties": { + "name": { + "type": "string" + } + }, + "type": "object" + }, + "cache": { + "properties": { + "name": { + "type": "string" + }, + "port": { + "type": "integer" + } + }, + "type": "object" + }, + "configuration": { + "properties": { + "name": { + "type": "string" + }, + "port": { + "type": "integer" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "volumes": { + "properties": { + "certificates": { + "properties": { + "destination": { + "type": "string" + }, + "name": { + "type": "string" + } + }, + "type": "object" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "image": { + "properties": { + "name": { + "type": "string" + }, + "pullPolicy": { + "type": "string" + }, + "tag": { + "type": "string" + } + }, + "type": "object" + }, + "livenessProbe": { + "properties": { + "delaySeconds": { + "type": "integer" + }, + "periodSeconds": { + "type": "integer" + }, + "port": { + "type": "integer" + }, + "scheme": { + "type": "string" + }, + "uri": { + "type": "string" + } + }, + "type": "object" + }, + "meta": { + "properties": { + "name": { + "type": "string" + } + }, + "type": "object" + }, + "ports": { + "properties": { + "http": { + "type": "integer" + }, + "https": { + "type": "integer" + } + }, + "type": "object" + }, + "readinessProbe": { + "properties": { + "delaySeconds": { + "type": "integer" + }, + "periodSeconds": { + "type": "integer" + }, + "port": { + "type": "integer" + }, + "scheme": { + "type": "string" + }, + "uri": { + "type": "string" + } + }, + "type": "object" + }, + "replication": { + "properties": { + "maxSurge": { + "type": "integer" + }, + "maxUnavailable": { + "type": "integer" + }, + "replicaCount": { + "type": "integer" + }, + "revisionHistoryLimit": { + "type": "integer" + } + }, + "type": "object" + }, + "restartPolicy": { + "type": "string" + }, + "service": { + "properties": { + "name": { + "type": "string" + } + }, + "type": "object" + } + }, + "title": "Helm Values Schema", + "type": "object" +} diff --git a/query-metrics/values.yaml b/query-metrics/values.yaml new file mode 100644 index 0000000..4e11960 --- /dev/null +++ b/query-metrics/values.yaml @@ -0,0 +1,67 @@ +global: + dockerRegistry: + url: ghcr.io/nationalsecurityagency + volumes: + certificates: + name: certificates + destination: /data/certs + initialization: + image: + name: busybox + tag: 1.28 + certSecretName: certificates-secret + pullSecrets: + - dockerconfigjson-ghcr + serviceDns: + configuration: + name: configuration + port: 8888 + authorization: + name: authorization + cache: + name: cache + port: 8080 + + +####################################### +# Default Values for Audit Deployment # +####################################### +image: + name: datawave-mapreduce-query-service + pullPolicy: IfNotPresent + tag: 4.0.8 +args: +- "--spring.output.ansi.enabled=ALWAYS" +- "--spring.profiles.active=default,k8s,remoteauth" +livenessProbe: + delaySeconds: 20 + periodSeconds: 5 + failureThreshold: 60 + port: 8080 + scheme: HTTP + uri: querymetric/mgmt/health +meta: + name: querymetric +service: + name: querymetric +readinessProbe: + delaySeconds: 20 + periodSeconds: 5 + failureThreshold: 60 + port: 8080 + scheme: HTTP + uri: querymetric/mgmt/health +replication: + maxSurge: 2 + maxUnavailable: 1 + replicaCount: 1 + revisionHistoryLimit: 10 +restartPolicy: Always + +####################################### +# Default Values for Executor Service # +####################################### + +ports: + http: 8080 + https: 8443 diff --git a/query/.gitignore b/query/.gitignore new file mode 100644 index 0000000..79f2743 --- /dev/null +++ b/query/.gitignore @@ -0,0 +1,5 @@ +############################### +# Ignores Helm Chart Archives # +############################### + +**.tgz diff --git a/query/.helmignore b/query/.helmignore new file mode 100644 index 0000000..b02f2f3 --- /dev/null +++ b/query/.helmignore @@ -0,0 +1,17 @@ +########################################### +# Ignores All File or Path Related to Git # +########################################### + +.git + +##################################### +# Ignores All Development Resources # +##################################### + +development/ +setup.sh + +############################ +# Ignores package Archives # +############################ +dwv-query-*.tgz diff --git a/query/Chart.lock b/query/Chart.lock new file mode 100644 index 0000000..18b66ee --- /dev/null +++ b/query/Chart.lock @@ -0,0 +1,6 @@ +dependencies: +- name: common-service-library + repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts + version: 0.0.2 +digest: sha256:9f6737e1bdb7c4772bf295ccb128a1d540237dd1b7770e0edbd185d1b17a1a31 +generated: "2024-10-08T10:49:49.636075467Z" diff --git a/query/Chart.yaml b/query/Chart.yaml new file mode 100644 index 0000000..2c3dce3 --- /dev/null +++ b/query/Chart.yaml @@ -0,0 +1,22 @@ +################################# +# Core Helm Chart Configuration # +################################# + +apiVersion: v2 +name: dwv-query +type: application +version: 1.0.0-SNAPSHOT + +################################# +# Basic Metadata for this Chart # +################################# + +appVersion: 1.0.10 +description: Deploys a datawave query service +icon: https://code.nsa.gov/datawave/images/datawave-logo.png + +dependencies: + - name: common-service-library + repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts + version: 0.0.2 + diff --git a/query/templates/query-deployment.yaml b/query/templates/query-deployment.yaml new file mode 100644 index 0000000..110c488 --- /dev/null +++ b/query/templates/query-deployment.yaml @@ -0,0 +1,19 @@ +{{- include "common-service-library.deployment" (list . "query.deployment") -}} +{{- define "query.deployment" -}} +#overrides go here +spec: + template: + spec: + initContainers: + - name: "{{ .Chart.Name }}-init-authorization" + image: "{{ .Values.global.initialization.image.name }}:{{ .Values.global.initialization.image.tag }}" + command: [ "sh", "-c", "until nc -z {{ .Values.global.serviceDns.authorization.name }} {{ .Values.global.serviceDns.authorization.port }}; do echo 'Waiting for Authorization...'; sleep 2; done" ] + + - name: "{{ .Chart.Name }}-init-cache" + image: "{{ .Values.global.initialization.image.name }}:{{ .Values.global.initialization.image.tag }}" + command: [ "sh", "-c", "until nc -z {{ .Values.global.serviceDns.cache.name }} {{ .Values.global.serviceDns.cache.port }}; do echo 'Waiting for Cache...'; sleep 2; done" ] + + - name: "{{ .Chart.Name }}-init-configuration" + image: "{{ .Values.global.initialization.image.name }}:{{ .Values.global.initialization.image.tag }}" + command: [ "sh", "-c", "until nc -z {{ .Values.global.serviceDns.configuration.name }} {{ .Values.global.serviceDns.configuration.port }}; do echo 'Waiting for Configuration...'; sleep 2; done" ] +{{- end -}} \ No newline at end of file diff --git a/query/templates/query-service.yaml b/query/templates/query-service.yaml new file mode 100644 index 0000000..1a0ed78 --- /dev/null +++ b/query/templates/query-service.yaml @@ -0,0 +1,4 @@ +{{- include "common-service-library.service" (list . "query.service") -}} +{{- define "query.service" -}} +#overrides go here +{{- end -}} \ No newline at end of file diff --git a/query/values.schema.json b/query/values.schema.json new file mode 100644 index 0000000..068c816 --- /dev/null +++ b/query/values.schema.json @@ -0,0 +1,206 @@ +{ + "$id": "https://code.nsa.org/datawave/schema", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "additionalProperties": true, + "description": "Schema for DataWave Helm values", + "properties": { + "args": { + "items": { + "type": "string" + }, + "type": "array" + }, + "global": { + "properties": { + "certSecretName": { + "type": "string" + }, + "dockerRegistry": { + "properties": { + "url": { + "type": "string" + } + }, + "type": "object" + }, + "initialization": { + "properties": { + "image": { + "properties": { + "name": { + "type": "string" + }, + "tag": { + "type": "number" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "pullSecrets": { + "items": { + "type": "string" + }, + "type": "array" + }, + "serviceDns": { + "properties": { + "authorization": { + "properties": { + "name": { + "type": "string" + } + }, + "type": "object" + }, + "cache": { + "properties": { + "name": { + "type": "string" + }, + "port": { + "type": "integer" + } + }, + "type": "object" + }, + "configuration": { + "properties": { + "name": { + "type": "string" + }, + "port": { + "type": "integer" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "volumes": { + "properties": { + "certificates": { + "properties": { + "destination": { + "type": "string" + }, + "name": { + "type": "string" + } + }, + "type": "object" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "image": { + "properties": { + "name": { + "type": "string" + }, + "pullPolicy": { + "type": "string" + }, + "tag": { + "type": "string" + } + }, + "type": "object" + }, + "livenessProbe": { + "properties": { + "delaySeconds": { + "type": "integer" + }, + "periodSeconds": { + "type": "integer" + }, + "port": { + "type": "integer" + }, + "scheme": { + "type": "string" + }, + "uri": { + "type": "string" + } + }, + "type": "object" + }, + "meta": { + "properties": { + "name": { + "type": "string" + } + }, + "type": "object" + }, + "ports": { + "properties": { + "http": { + "type": "integer" + }, + "https": { + "type": "integer" + } + }, + "type": "object" + }, + "readinessProbe": { + "properties": { + "delaySeconds": { + "type": "integer" + }, + "periodSeconds": { + "type": "integer" + }, + "port": { + "type": "integer" + }, + "scheme": { + "type": "string" + }, + "uri": { + "type": "string" + } + }, + "type": "object" + }, + "replication": { + "properties": { + "maxSurge": { + "type": "integer" + }, + "maxUnavailable": { + "type": "integer" + }, + "replicaCount": { + "type": "integer" + }, + "revisionHistoryLimit": { + "type": "integer" + } + }, + "type": "object" + }, + "restartPolicy": { + "type": "string" + }, + "service": { + "properties": { + "name": { + "type": "string" + } + }, + "type": "object" + } + }, + "title": "Helm Values Schema", + "type": "object" +} diff --git a/query/values.yaml b/query/values.yaml new file mode 100644 index 0000000..6e930c4 --- /dev/null +++ b/query/values.yaml @@ -0,0 +1,67 @@ +global: + dockerRegistry: + url: ghcr.io/nationalsecurityagency + volumes: + certificates: + name: certificates + destination: /data/certs + initialization: + image: + name: busybox + tag: 1.28 + certSecretName: certificates-secret + pullSecrets: + - dockerconfigjson-ghcr + serviceDns: + configuration: + name: configuration + port: 8888 + authorization: + name: authorization + cache: + name: cache + port: 8080 + + +####################################### +# Default Values for Audit Deployment # +####################################### +image: + name: datawave-mapreduce-query-service + pullPolicy: IfNotPresent + tag: 1.0.10 +args: +- "--spring.output.ansi.enabled=ALWAYS" +- "--spring.profiles.active=default,k8s,remoteauth,querymessaging,metricssource,query,mrquery,cachedresults,federation" +livenessProbe: + delaySeconds: 20 + periodSeconds: 5 + failureThreshold: 60 + port: 8080 + scheme: HTTP + uri: query/mgmt/health +meta: + name: query +service: + name: query +readinessProbe: + delaySeconds: 20 + periodSeconds: 5 + failureThreshold: 60 + port: 8080 + scheme: HTTP + uri: query/mgmt/health +replication: + maxSurge: 2 + maxUnavailable: 1 + replicaCount: 1 + revisionHistoryLimit: 10 +restartPolicy: Always + +####################################### +# Default Values for Executor Service # +####################################### + +ports: + http: 8080 + https: 8443 diff --git a/shared-functions.sh b/shared-functions.sh new file mode 100644 index 0000000..8b1f758 --- /dev/null +++ b/shared-functions.sh @@ -0,0 +1,92 @@ + +function start_minikube() { + # Cache images and reset minikube. Then Setup minikube ingress. + docker pull rabbitmq:3.11.4-alpine && \ + docker pull busybox:1.28 && \ + minikube delete --all --purge && \ + minikube start --nodes 3 --cpus 4 --memory 15960 --disk-size 20480 && \ + minikube image load rabbitmq:3.11.4-alpine && \ + minikube image load busybox:1.28 && \ + minikube image load mysql:8.0.32 && \ + minikube addons enable ingress && \ + minikube kubectl -- delete -A ValidatingWebhookConfiguration ingress-nginx-admission && \ + minikube kubectl -- patch deployment -n ingress-nginx ingress-nginx-controller --type='json' -p='[{"op": "add", "path": "/spec/template/spec/containers/0/args/-", "value":"--enable-ssl-passthrough"}]' && \ + + #Apply GHCR credentials + if test -f "${BASEDIR}"/ghcr-image-pull-secret.yaml; then + minikube kubectl -- apply -f "${BASEDIR}"/ghcr-image-pull-secret.yaml + fi + + minikube kubectl -- create secret generic certificates-secret --from-file=keystore.p12="${DATAWAVE_STACK}"/certificates/keystore.p12 --from-file=truststore.jks="${DATAWAVE_STACK}"/certificates/truststore.jks +} + +function docker_login() { + if test -f "${BASEDIR}"/ghcr-image-pull-secret.yaml; then + # File path + FILE_PATH="./ghcr-image-pull-secret.yaml" + + # Extract the base64-encoded .dockerconfigjson value + ENCODED_JSON=$(grep '.dockerconfigjson:' $FILE_PATH | awk '{print $2}') + + # Decode the JSON value + DECODED_JSON=$(echo $ENCODED_JSON | base64 --decode) + + # Extract the base64-encoded auth value for ghcr.io + ENCODED_AUTH=$(echo $DECODED_JSON | jq -r '.auths["ghcr.io"].auth') + + # Decode the auth value to get username:password + AUTH=$(echo $ENCODED_AUTH | base64 --decode) + + # Split the username and password + USERNAME=$(echo $AUTH | cut -d ':' -f 1) + PASSWORD=$(echo $AUTH | cut -d ':' -f 2) + + echo $PASSWORD | docker login ghcr.io --username $USERNAME --password-stdin + fi +} + +function initialize_hosts_file() { + sudo sed -i "/^$/d" /etc/hosts + sudo sed -i "/.*datawave\.org.*/d" /etc/hosts + sudo sed -i "/.*zookeeper.*/d" /etc/hosts + sudo sed -i "/.*hdfs.*/d" /etc/hosts + sudo sed -i "/.*yarn.*/d" /etc/hosts + echo "$(minikube ip) accumulo.datawave.org" | sudo tee -a /etc/hosts + echo "$(minikube ip) web.datawave.org" | sudo tee -a /etc/hosts + echo "$(minikube ip) dictionary.datawave.org" | sudo tee -a /etc/hosts +} + +function updateCoreDns() { + if ${USE_LOCAL_ZOOKEEPER} && ${USE_LOCAL_HADOOP}; then + "${BASEDIR}"/updateCorefile.sh coredns.corefile-both.template + elif ${USE_LOCAL_ZOOKEEPER}; then + "${BASEDIR}"/updateCorefile.sh coredns.corefile-zookeeper.template + elif ${USE_LOCAL_HADOOP}; then + "${BASEDIR}"/updateCorefile.sh coredns.corefile-hadoop.template + else + "${BASEDIR}"/updateCorefile.sh coredns.corefile-default.template + fi +} + +function update_hosts_file_for_hadoop() { + echo "$(minikube ip) namenode.datawave.org" | sudo tee -a /etc/hosts + echo "$(minikube ip) resourcemanager.datawave.org" | sudo tee -a /etc/hosts + echo "$(minikube ip) historyserver.datawave.org" | sudo tee -a /etc/hosts +} + +function start_zk() { + "${BASEDIR}"/startZookeeper.sh + echo "$(minikube ip | cut -f1,2,3 -d .).1 zookeeper" | sudo tee -a /etc/hosts +} + +function start_hadoop() { + "${BASEDIR}"/startHadoop.sh + echo "$(minikube ip | cut -f1,2,3 -d .).1 hdfs-nn" | sudo tee -a /etc/hosts + echo "$(minikube ip | cut -f1,2,3 -d .).1 hdfs-dn" | sudo tee -a /etc/hosts + echo "$(minikube ip | cut -f1,2,3 -d .).1 yarn-rn" | sudo tee -a /etc/hosts + echo "$(minikube ip | cut -f1,2,3 -d .).1 yarn-nm" | sudo tee -a /etc/hosts + + echo "$(minikube ip | cut -f1,2,3 -d .).1 namenode.datawave.org" | sudo tee -a /etc/hosts + echo "$(minikube ip | cut -f1,2,3 -d .).1 resourcemanager.datawave.org" | sudo tee -a /etc/hosts + echo "$(minikube ip | cut -f1,2,3 -d .).1 historyserver.datawave.org" | sudo tee -a /etc/hosts +} diff --git a/startLocalQMSTest.sh b/startLocalQMSTest.sh new file mode 100755 index 0000000..4326755 --- /dev/null +++ b/startLocalQMSTest.sh @@ -0,0 +1,64 @@ +#!/usr/bin/env bash + +VALUES_FILE=${1:-values.yaml} +USE_LOCAL_ZOOKEEPER=${USE_LOCAL_ZOOKEEPER:-false} +USE_LOCAL_HADOOP=${USE_LOCAL_HADOOP:-false} +INIT_LOCAL_HADOOP=${INIT_LOCAL_HADOOP:-false} +EXTRA_HELM_ARGS=${EXTRA_HELM_ARGS:""} +BASEDIR="$( cd -- "$(dirname "$0")" >/dev/null 2>&1 || exit; pwd -P )" +DATAWAVE_STACK="${BASEDIR}/datawave-stack" + +. ./shared-functions.sh +function helm_install() { + if ${USE_LOCAL_ZOOKEEPER}; then + start_zk + EXTRA_HELM_ARGS="${EXTRA_HELM_ARGS} --set charts.zookeeper.enabled=false" + fi + if ${USE_LOCAL_HADOOP}; then + start_hadoop + EXTRA_HELM_ARGS="${EXTRA_HELM_ARGS} --set charts.hadoop.enabled=false" + else + update_hosts_file_for_hadoop + fi + + # shellcheck disable=SC2086 + helm install dwv "${DATAWAVE_STACK}"/datawave-qms*.tgz -f "${DATAWAVE_STACK}"/${VALUES_FILE} ${EXTRA_HELM_ARGS} +} + + +function helm_package() { + find . -name "*.tgz" -delete + cd "${BASEDIR}"/common-service-library || exit + helm package . + cd "${BASEDIR}" || exit + for chart in executor query query-metrics kafka kafdrop modification mr-query audit authorization cache configuration dictionary hadoop ingest mysql rabbitmq zookeeper; do + cd "${BASEDIR}"/$chart || exit + helm dependency update + helm package . + done + cd "${BASEDIR}"/datawave-qms-umbrella || exit + helm dependency update + helm package . + cd "${BASEDIR}"/datawave-qms-stack || exit + helm dependency update + helm package . + cd "${BASEDIR}" || exit +} + +echo "Login to Helm Charts repo using docker" +docker_login +echo "Package helm charts" +helm_package +echo "Purge and restart Minikube" +start_minikube +echo "Initialize Hosts file" +initialize_hosts_file +echo "Update COREDNS" +updateCoreDns +echo "Running Helm Install" +helm_install +echo "Deploy to MiniKube complete!" + +#Currently Disabled. See DataWave repo on how to get this json file. +#kubectl cp tv-show-raw-data-stock.json dwv-dwv-hadoop-hdfs-nn-0:/tmp && \ +#kubectl exec -it dwv-dwv-hadoop-hdfs-nn-0 -- hdfs dfs -put /tmp/tv-show-raw-data-stock.json /data/myjson diff --git a/startLocalTest.sh b/startLocalTest.sh index 99c9b2c..8e4c13a 100755 --- a/startLocalTest.sh +++ b/startLocalTest.sh @@ -12,107 +12,24 @@ EXTRA_HELM_ARGS=${EXTRA_HELM_ARGS:""} BASEDIR="$( cd -- "$(dirname "$0")" >/dev/null 2>&1 || exit; pwd -P )" DATAWAVE_STACK="${BASEDIR}/datawave-stack" -function start_minikube() { - # Cache images and reset minikube. Then Setup minikube ingress. - docker pull rabbitmq:3.11.4-alpine && \ - docker pull mysql:8.0.32 && \ - docker pull busybox:1.28 && \ - minikube delete --all --purge && \ - minikube start --nodes 3 --cpus 4 --memory 15960 --disk-size 20480 && \ - minikube image load rabbitmq:3.11.4-alpine && \ - minikube image load busybox:1.28 && \ - minikube image load mysql:8.0.32 && \ - minikube addons enable ingress && \ - minikube kubectl -- delete -A ValidatingWebhookConfiguration ingress-nginx-admission && \ - minikube kubectl -- patch deployment -n ingress-nginx ingress-nginx-controller --type='json' -p='[{"op": "add", "path": "/spec/template/spec/containers/0/args/-", "value":"--enable-ssl-passthrough"}]' && \ +. ./shared-functions.sh - # update default storage provisioner, set csi-hostpath-sc as the default storage driver - echo "Enabling volumesnapshots and csi-hostpath-driver" - minikube addons enable volumesnapshots - minikube addons enable csi-hostpath-driver - minikube addons disable storage-provisioner - minikube addons disable default-storageclass - minikube kubectl -- patch storageclass csi-hostpath-sc -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}' - - #Apply GHCR credentials - if test -f "${BASEDIR}"/ghcr-image-pull-secret.yaml; then - minikube kubectl -- apply -f "${BASEDIR}"/ghcr-image-pull-secret.yaml - fi - - minikube kubectl -- create secret generic certificates-secret --from-file=keystore.p12="${DATAWAVE_STACK}"/certificates/keystore.p12 --from-file=truststore.jks="${DATAWAVE_STACK}"/certificates/truststore.jks -} - -function ghcr_login() { - if test -f "${BASEDIR}"/ghcr-image-pull-secret.yaml; then - # File path - FILE_PATH="./ghcr-image-pull-secret.yaml" - - # Extract the base64-encoded .dockerconfigjson value - ENCODED_JSON=$(grep '.dockerconfigjson:' $FILE_PATH | awk '{print $2}') - - # Decode the JSON value - DECODED_JSON=$(echo $ENCODED_JSON | base64 --decode) - - # Extract the base64-encoded auth value for ghcr.io - ENCODED_AUTH=$(echo $DECODED_JSON | jq -r '.auths["ghcr.io"].auth') - - # Decode the auth value to get username:password - AUTH=$(echo $ENCODED_AUTH | base64 --decode) - - # Split the username and password - USERNAME=$(echo $AUTH | cut -d ':' -f 1) - PASSWORD=$(echo $AUTH | cut -d ':' -f 2) - - echo $PASSWORD | docker login ghcr.io --username $USERNAME --password-stdin - echo $PASSWORD | helm registry login ghcr.io --username $USERNAME --password-stdin +function helm_install() { + if ${USE_LOCAL_ZOOKEEPER}; then + start_zk + EXTRA_HELM_ARGS="${EXTRA_HELM_ARGS} --set charts.zookeeper.enabled=false" fi -} - -function initialize_hosts_file() { - sudo sed -i "/^$/d" /etc/hosts - sudo sed -i "/.*datawave\.org.*/d" /etc/hosts - sudo sed -i "/.*zookeeper.*/d" /etc/hosts - sudo sed -i "/.*hdfs.*/d" /etc/hosts - sudo sed -i "/.*yarn.*/d" /etc/hosts - echo "$(minikube ip) accumulo.datawave.org" | sudo tee -a /etc/hosts - echo "$(minikube ip) web.datawave.org" | sudo tee -a /etc/hosts - echo "$(minikube ip) dictionary.datawave.org" | sudo tee -a /etc/hosts -} - -function updateCoreDns() { - if ${USE_LOCAL_ZOOKEEPER} && ${USE_LOCAL_HADOOP}; then - "${BASEDIR}"/updateCorefile.sh coredns.corefile-both.template - elif ${USE_LOCAL_ZOOKEEPER}; then - "${BASEDIR}"/updateCorefile.sh coredns.corefile-zookeeper.template - elif ${USE_LOCAL_HADOOP}; then - "${BASEDIR}"/updateCorefile.sh coredns.corefile-hadoop.template + if ${USE_LOCAL_HADOOP}; then + start_hadoop + EXTRA_HELM_ARGS="${EXTRA_HELM_ARGS} --set charts.hadoop.enabled=false" else - "${BASEDIR}"/updateCorefile.sh coredns.corefile-default.template + update_hosts_file_for_hadoop fi -} - -function update_hosts_file_for_hadoop() { - echo "$(minikube ip) namenode.datawave.org" | sudo tee -a /etc/hosts - echo "$(minikube ip) resourcemanager.datawave.org" | sudo tee -a /etc/hosts - echo "$(minikube ip) historyserver.datawave.org" | sudo tee -a /etc/hosts -} -function start_zk() { - "${BASEDIR}"/startZookeeper.sh - echo "$(minikube ip | cut -f1,2,3 -d .).1 zookeeper" | sudo tee -a /etc/hosts + # shellcheck disable=SC2086 + helm install dwv "${DATAWAVE_STACK}"/datawave-system-*.tgz -f "${DATAWAVE_STACK}"/${VALUES_FILE} ${EXTRA_HELM_ARGS} } -function start_hadoop() { - "${BASEDIR}"/startHadoop.sh - echo "$(minikube ip | cut -f1,2,3 -d .).1 hdfs-nn" | sudo tee -a /etc/hosts - echo "$(minikube ip | cut -f1,2,3 -d .).1 hdfs-dn" | sudo tee -a /etc/hosts - echo "$(minikube ip | cut -f1,2,3 -d .).1 yarn-rn" | sudo tee -a /etc/hosts - echo "$(minikube ip | cut -f1,2,3 -d .).1 yarn-nm" | sudo tee -a /etc/hosts - - echo "$(minikube ip | cut -f1,2,3 -d .).1 namenode.datawave.org" | sudo tee -a /etc/hosts - echo "$(minikube ip | cut -f1,2,3 -d .).1 resourcemanager.datawave.org" | sudo tee -a /etc/hosts - echo "$(minikube ip | cut -f1,2,3 -d .).1 historyserver.datawave.org" | sudo tee -a /etc/hosts -} function helm_package() { find . -name "*.tgz" -delete @@ -132,21 +49,6 @@ function helm_package() { helm package . cd "${BASEDIR}" || exit } -function helm_install() { - if ${USE_LOCAL_ZOOKEEPER}; then - start_zk - EXTRA_HELM_ARGS="${EXTRA_HELM_ARGS} --set charts.zookeeper.enabled=false" - fi - if ${USE_LOCAL_HADOOP}; then - start_hadoop - EXTRA_HELM_ARGS="${EXTRA_HELM_ARGS} --set charts.hadoop.enabled=false" - else - update_hosts_file_for_hadoop - fi - - # shellcheck disable=SC2086 - helm install dwv "${DATAWAVE_STACK}"/datawave-system-*.tgz -f "${DATAWAVE_STACK}"/${VALUES_FILE} ${EXTRA_HELM_ARGS} -} echo "Login to Docker and Helm Charts GHCR repo" ghcr_login From 66d62498bce7bb62c896168b56448cf01d83120a Mon Sep 17 00:00:00 2001 From: Adam Lerman Date: Tue, 8 Oct 2024 23:51:27 +0000 Subject: [PATCH 08/16] some additional cleanup --- executor-pool/.gitignore | 5 - executor-pool/.helmignore | 17 -- executor-pool/Chart.lock | 6 - executor-pool/Chart.yaml | 22 -- .../accumulo-microservice-deployment.yaml | 19 -- .../accumulo-microservice-service.yaml | 4 - executor-pool/values.schema.json | 206 ------------------ executor-pool/values.yaml | 67 ------ kafdrop/Chart.yaml | 2 +- 9 files changed, 1 insertion(+), 347 deletions(-) delete mode 100644 executor-pool/.gitignore delete mode 100644 executor-pool/.helmignore delete mode 100644 executor-pool/Chart.lock delete mode 100644 executor-pool/Chart.yaml delete mode 100644 executor-pool/templates/accumulo-microservice-deployment.yaml delete mode 100644 executor-pool/templates/accumulo-microservice-service.yaml delete mode 100644 executor-pool/values.schema.json delete mode 100644 executor-pool/values.yaml diff --git a/executor-pool/.gitignore b/executor-pool/.gitignore deleted file mode 100644 index 79f2743..0000000 --- a/executor-pool/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -############################### -# Ignores Helm Chart Archives # -############################### - -**.tgz diff --git a/executor-pool/.helmignore b/executor-pool/.helmignore deleted file mode 100644 index aa06c2c..0000000 --- a/executor-pool/.helmignore +++ /dev/null @@ -1,17 +0,0 @@ -########################################### -# Ignores All File or Path Related to Git # -########################################### - -.git - -##################################### -# Ignores All Development Resources # -##################################### - -development/ -setup.sh - -############################ -# Ignores package Archives # -############################ -dwv-accumulo-microservice-*.tgz diff --git a/executor-pool/Chart.lock b/executor-pool/Chart.lock deleted file mode 100644 index c7d3c8d..0000000 --- a/executor-pool/Chart.lock +++ /dev/null @@ -1,6 +0,0 @@ -dependencies: -- name: common-service-library - repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts - version: 0.0.2 -digest: sha256:9f6737e1bdb7c4772bf295ccb128a1d540237dd1b7770e0edbd185d1b17a1a31 -generated: "2024-10-04T18:58:14.981876411Z" diff --git a/executor-pool/Chart.yaml b/executor-pool/Chart.yaml deleted file mode 100644 index 6356828..0000000 --- a/executor-pool/Chart.yaml +++ /dev/null @@ -1,22 +0,0 @@ -################################# -# Core Helm Chart Configuration # -################################# - -apiVersion: v2 -name: dwv-executor -type: application -version: 1.0.0-SNAPSHOT - -################################# -# Basic Metadata for this Chart # -################################# - -appVersion: 1.0.9 -description: Deploys a datawave query executor service -icon: https://code.nsa.gov/datawave/images/datawave-logo.png - -dependencies: - - name: common-service-library - repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts - version: 0.0.2 - diff --git a/executor-pool/templates/accumulo-microservice-deployment.yaml b/executor-pool/templates/accumulo-microservice-deployment.yaml deleted file mode 100644 index 194eb3e..0000000 --- a/executor-pool/templates/accumulo-microservice-deployment.yaml +++ /dev/null @@ -1,19 +0,0 @@ -{{- include "common-service-library.deployment" (list . "accumuloMicroservice.deployment") -}} -{{- define "accumuloMicroservice.deployment" -}} -#overrides go here -spec: - template: - spec: - initContainers: - - name: "{{ .Chart.Name }}-init-authorization" - image: "{{ .Values.global.initialization.image.name }}:{{ .Values.global.initialization.image.tag }}" - command: [ "sh", "-c", "until nc -z {{ .Values.global.serviceDns.authorization.name }} {{ .Values.global.serviceDns.authorization.port }}; do echo 'Waiting for Authorization...'; sleep 2; done" ] - - - name: "{{ .Chart.Name }}-init-cache" - image: "{{ .Values.global.initialization.image.name }}:{{ .Values.global.initialization.image.tag }}" - command: [ "sh", "-c", "until nc -z {{ .Values.global.serviceDns.cache.name }} {{ .Values.global.serviceDns.cache.port }}; do echo 'Waiting for Cache...'; sleep 2; done" ] - - - name: "{{ .Chart.Name }}-init-configuration" - image: "{{ .Values.global.initialization.image.name }}:{{ .Values.global.initialization.image.tag }}" - command: [ "sh", "-c", "until nc -z {{ .Values.global.serviceDns.configuration.name }} {{ .Values.global.serviceDns.configuration.port }}; do echo 'Waiting for Configuration...'; sleep 2; done" ] -{{- end -}} \ No newline at end of file diff --git a/executor-pool/templates/accumulo-microservice-service.yaml b/executor-pool/templates/accumulo-microservice-service.yaml deleted file mode 100644 index 2bcedaa..0000000 --- a/executor-pool/templates/accumulo-microservice-service.yaml +++ /dev/null @@ -1,4 +0,0 @@ -{{- include "common-service-library.service" (list . "accumuloMicroservice.service") -}} -{{- define "accumuloMicroservice.service" -}} -#overrides go here -{{- end -}} \ No newline at end of file diff --git a/executor-pool/values.schema.json b/executor-pool/values.schema.json deleted file mode 100644 index 068c816..0000000 --- a/executor-pool/values.schema.json +++ /dev/null @@ -1,206 +0,0 @@ -{ - "$id": "https://code.nsa.org/datawave/schema", - "$schema": "https://json-schema.org/draft/2020-12/schema", - "additionalProperties": true, - "description": "Schema for DataWave Helm values", - "properties": { - "args": { - "items": { - "type": "string" - }, - "type": "array" - }, - "global": { - "properties": { - "certSecretName": { - "type": "string" - }, - "dockerRegistry": { - "properties": { - "url": { - "type": "string" - } - }, - "type": "object" - }, - "initialization": { - "properties": { - "image": { - "properties": { - "name": { - "type": "string" - }, - "tag": { - "type": "number" - } - }, - "type": "object" - } - }, - "type": "object" - }, - "pullSecrets": { - "items": { - "type": "string" - }, - "type": "array" - }, - "serviceDns": { - "properties": { - "authorization": { - "properties": { - "name": { - "type": "string" - } - }, - "type": "object" - }, - "cache": { - "properties": { - "name": { - "type": "string" - }, - "port": { - "type": "integer" - } - }, - "type": "object" - }, - "configuration": { - "properties": { - "name": { - "type": "string" - }, - "port": { - "type": "integer" - } - }, - "type": "object" - } - }, - "type": "object" - }, - "volumes": { - "properties": { - "certificates": { - "properties": { - "destination": { - "type": "string" - }, - "name": { - "type": "string" - } - }, - "type": "object" - } - }, - "type": "object" - } - }, - "type": "object" - }, - "image": { - "properties": { - "name": { - "type": "string" - }, - "pullPolicy": { - "type": "string" - }, - "tag": { - "type": "string" - } - }, - "type": "object" - }, - "livenessProbe": { - "properties": { - "delaySeconds": { - "type": "integer" - }, - "periodSeconds": { - "type": "integer" - }, - "port": { - "type": "integer" - }, - "scheme": { - "type": "string" - }, - "uri": { - "type": "string" - } - }, - "type": "object" - }, - "meta": { - "properties": { - "name": { - "type": "string" - } - }, - "type": "object" - }, - "ports": { - "properties": { - "http": { - "type": "integer" - }, - "https": { - "type": "integer" - } - }, - "type": "object" - }, - "readinessProbe": { - "properties": { - "delaySeconds": { - "type": "integer" - }, - "periodSeconds": { - "type": "integer" - }, - "port": { - "type": "integer" - }, - "scheme": { - "type": "string" - }, - "uri": { - "type": "string" - } - }, - "type": "object" - }, - "replication": { - "properties": { - "maxSurge": { - "type": "integer" - }, - "maxUnavailable": { - "type": "integer" - }, - "replicaCount": { - "type": "integer" - }, - "revisionHistoryLimit": { - "type": "integer" - } - }, - "type": "object" - }, - "restartPolicy": { - "type": "string" - }, - "service": { - "properties": { - "name": { - "type": "string" - } - }, - "type": "object" - } - }, - "title": "Helm Values Schema", - "type": "object" -} diff --git a/executor-pool/values.yaml b/executor-pool/values.yaml deleted file mode 100644 index e71e1b7..0000000 --- a/executor-pool/values.yaml +++ /dev/null @@ -1,67 +0,0 @@ -global: - dockerRegistry: - url: ghcr.io/nationalsecurityagency - volumes: - certificates: - name: certificates - destination: /data/certs - initialization: - image: - name: busybox - tag: 1.28 - certSecretName: certificates-secret - pullSecrets: - - dockerconfigjson-ghcr - serviceDns: - configuration: - name: configuration - port: 8888 - authorization: - name: authorization - cache: - name: cache - port: 8080 - - -####################################### -# Default Values for Audit Deployment # -####################################### -image: - name: datawave-query-executor-service - pullPolicy: IfNotPresent - tag: 1.0.9 -args: -- "--spring.output.ansi.enabled=ALWAYS" -- "--spring.profiles.active= default,k8s,remoteauth,querymessaging,metricssource,federation,query,pool1" -livenessProbe: - delaySeconds: 20 - periodSeconds: 5 - failureThreshold: 60 - port: 8080 - scheme: HTTP - uri: executor/mgmt/health -meta: - name: executor -service: - name: executor -readinessProbe: - delaySeconds: 20 - periodSeconds: 5 - failureThreshold: 60 - port: 8080 - scheme: HTTP - uri: executor/mgmt/health -replication: - maxSurge: 2 - maxUnavailable: 1 - replicaCount: 1 - revisionHistoryLimit: 10 -restartPolicy: Always - -####################################### -# Default Values for Executor Service # -####################################### - -ports: - http: 8080 - https: 8443 diff --git a/kafdrop/Chart.yaml b/kafdrop/Chart.yaml index 9d937a2..488e11e 100644 --- a/kafdrop/Chart.yaml +++ b/kafdrop/Chart.yaml @@ -3,7 +3,7 @@ ################################# apiVersion: v2 -name: dwv-executor +name: dwv-kafdrop type: application version: 1.0.0-SNAPSHOT From 89a8457024cd5644582a9b76e51f7ac84e1caa7a Mon Sep 17 00:00:00 2001 From: Adam Lerman Date: Wed, 9 Oct 2024 22:00:43 +0000 Subject: [PATCH 09/16] Add lock files --- modification/Chart.lock | 6 ++++++ mr-query/Chart.lock | 6 ++++++ 2 files changed, 12 insertions(+) create mode 100644 modification/Chart.lock create mode 100644 mr-query/Chart.lock diff --git a/modification/Chart.lock b/modification/Chart.lock new file mode 100644 index 0000000..3536bfe --- /dev/null +++ b/modification/Chart.lock @@ -0,0 +1,6 @@ +dependencies: +- name: common-service-library + repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts + version: 0.0.2 +digest: sha256:9f6737e1bdb7c4772bf295ccb128a1d540237dd1b7770e0edbd185d1b17a1a31 +generated: "2024-10-08T10:50:11.424962441Z" diff --git a/mr-query/Chart.lock b/mr-query/Chart.lock new file mode 100644 index 0000000..8fbd758 --- /dev/null +++ b/mr-query/Chart.lock @@ -0,0 +1,6 @@ +dependencies: +- name: common-service-library + repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts + version: 0.0.2 +digest: sha256:9f6737e1bdb7c4772bf295ccb128a1d540237dd1b7770e0edbd185d1b17a1a31 +generated: "2024-10-08T10:50:11.918150861Z" From e1731dabb67a8912ff54f88f37faea4112c85f95 Mon Sep 17 00:00:00 2001 From: Adam Lerman Date: Wed, 13 Nov 2024 14:55:36 +0000 Subject: [PATCH 10/16] Everything working in new charts. Config issue stopping a few microservices from running --- configuration/configMapFiles/accumulo.yml | 23 + .../application-cachedresults.yml | 79 +++ .../configMapFiles/application-federation.yml | 15 + .../configMapFiles/application-k8s.yml | 28 +- .../application-metricssource.yml | 23 + .../configMapFiles/application-mrquery.yml | 54 ++ .../configMapFiles/application-query.yml | 573 ++++++++++++++++++ .../application-querymessaging.yml | 11 + configuration/configMapFiles/application.yml | 8 +- configuration/configMapFiles/audit.yml | 17 +- .../configMapFiles/executor-pool1.yml | 20 + .../configMapFiles/executor-pool2.yml | 20 + configuration/configMapFiles/executor.yml | 67 ++ configuration/configMapFiles/modification.yml | 68 +++ configuration/configMapFiles/mrquery.yml | 31 + configuration/configMapFiles/query.yml | 74 +++ configuration/configMapFiles/querymetric.yml | 124 ++++ configuration/values.yaml | 25 +- datawave-driver.sh | 2 + datawave-qms-stack/.helmignore | 19 - datawave-qms-stack/.schema.yaml | 13 - datawave-qms-stack/Chart.lock | 21 - datawave-qms-stack/Chart.yaml | 38 -- datawave-qms-stack/README.md | 3 - datawave-qms-stack/certificates/keystore.p12 | Bin 3586 -> 0 bytes .../certificates/truststore.jks | Bin 163715 -> 0 bytes datawave-qms-stack/templates/_helpers.tpl | 23 - datawave-qms-stack/templates/hdfs.yaml | 19 - datawave-qms-stack/templates/yarn.yaml | 19 - datawave-qms-stack/templates/zookeeper.yaml | 24 - datawave-qms-stack/values-testing.yaml | 8 - datawave-qms-stack/values.schema.json | 88 --- datawave-qms-stack/values.yaml | 27 - datawave-qms-umbrella/.schema.yaml | 13 - datawave-qms-umbrella/Chart.lock | 42 -- datawave-qms-umbrella/Chart.yaml | 57 -- datawave-qms-umbrella/README.md | 3 - datawave-qms-umbrella/values.schema.json | 74 --- datawave-qms-umbrella/values.yaml | 22 - datawave-stack/Chart.yaml | 35 ++ datawave-stack/values.yaml | 2 + executor/Chart.yaml | 1 + .../accumulo-microservice-deployment.yaml | 4 +- .../accumulo-microservice-service.yaml | 4 +- executor/values.yaml | 1 + hadoop-config/.helmignore | 2 + hadoop/.helmignore | 2 + modification/Chart.yaml | 1 + modification/values.yaml | 3 +- mr-query/Chart.yaml | 1 + mr-query/values.yaml | 3 +- query-metrics/Chart.yaml | 1 + query-metrics/values.yaml | 7 +- query/Chart.yaml | 1 + query/values.yaml | 5 +- 55 files changed, 1318 insertions(+), 530 deletions(-) create mode 100644 configuration/configMapFiles/accumulo.yml create mode 100755 configuration/configMapFiles/application-cachedresults.yml create mode 100644 configuration/configMapFiles/application-federation.yml create mode 100755 configuration/configMapFiles/application-metricssource.yml create mode 100755 configuration/configMapFiles/application-mrquery.yml create mode 100644 configuration/configMapFiles/application-query.yml create mode 100755 configuration/configMapFiles/application-querymessaging.yml create mode 100755 configuration/configMapFiles/executor-pool1.yml create mode 100755 configuration/configMapFiles/executor-pool2.yml create mode 100755 configuration/configMapFiles/executor.yml create mode 100644 configuration/configMapFiles/modification.yml create mode 100755 configuration/configMapFiles/mrquery.yml create mode 100755 configuration/configMapFiles/query.yml create mode 100755 configuration/configMapFiles/querymetric.yml delete mode 100644 datawave-qms-stack/.helmignore delete mode 100644 datawave-qms-stack/.schema.yaml delete mode 100644 datawave-qms-stack/Chart.lock delete mode 100644 datawave-qms-stack/Chart.yaml delete mode 100644 datawave-qms-stack/README.md delete mode 100644 datawave-qms-stack/certificates/keystore.p12 delete mode 100644 datawave-qms-stack/certificates/truststore.jks delete mode 100644 datawave-qms-stack/templates/_helpers.tpl delete mode 100644 datawave-qms-stack/templates/hdfs.yaml delete mode 100644 datawave-qms-stack/templates/yarn.yaml delete mode 100644 datawave-qms-stack/templates/zookeeper.yaml delete mode 100644 datawave-qms-stack/values-testing.yaml delete mode 100644 datawave-qms-stack/values.schema.json delete mode 100644 datawave-qms-stack/values.yaml delete mode 100644 datawave-qms-umbrella/.schema.yaml delete mode 100644 datawave-qms-umbrella/Chart.lock delete mode 100644 datawave-qms-umbrella/Chart.yaml delete mode 100644 datawave-qms-umbrella/README.md delete mode 100644 datawave-qms-umbrella/values.schema.json delete mode 100644 datawave-qms-umbrella/values.yaml diff --git a/configuration/configMapFiles/accumulo.yml b/configuration/configMapFiles/accumulo.yml new file mode 100644 index 0000000..3a1f087 --- /dev/null +++ b/configuration/configMapFiles/accumulo.yml @@ -0,0 +1,23 @@ +warehouse-cluster: + accumulo: + zookeepers: "{{ .Values.global.zookeeper.quorum }}" + instanceName: '{{ .Values.global.accumulo.instanceName }}' + username: '{{ .Values.global.accumulo.user }}' + password: '{{ .Values.global.accumulo.password }}' + +accumulo: + lookup: + audit: + defaultAuditType: 'ACTIVE' + stats: + enabled: true + +audit-client: + discovery: + enabled: false + uri: '${AUDIT_SERVER_URL:http://localhost:11111/audit}' + +datawave: + swagger: + title: "Accumulo Service" + description: "REST API provided by the Accumulo Service" \ No newline at end of file diff --git a/configuration/configMapFiles/application-cachedresults.yml b/configuration/configMapFiles/application-cachedresults.yml new file mode 100755 index 0000000..fdcf0aa --- /dev/null +++ b/configuration/configMapFiles/application-cachedresults.yml @@ -0,0 +1,79 @@ +spring: + datasource: + cachedResults: + url: 'jdbc:mysql://{{.Values.global.serviceDns.mysql.name}}:3306/cachedresults?zeroDateTimeBehavior=convertToNull' + username: '{{ .Values.global.mysql.user }}' + password: 'secret' + driver-class-name: 'com.mysql.cj.jdbc.Driver' + hikari: + # default: 30000 + connection-timeout: 5000 + # default: 600000 + idle-timeout: 900000 + # default: maximum-pool-size + minimum-idle: {{ .Values.global.mysql.minIdle }} + # default: 10 + maximum-pool-size: {{ .Values.global.mysql.maxSize }} + +datawave: + mysql: + host: 'mysql' + dbname: 'cachedresults' + pool: + min-size: '5' + max-size: '20' + username: 'datawave' + password: 'secret' + query: + cachedResults: + enabled: ${CACHED_RESULTS:false} + remoteQuery: + queryServiceUri: "https://dwv-web-query:8443/query/v1/query" + # unlimited + maxBytesToBuffer: -1 + numFields: 900 + statementTemplates: + createTableTemplate: | + CREATE TABLE IF NOT EXISTS template ( + _user_ VARCHAR(200) NOT NULL, + _queryId_ VARCHAR(200) NOT NULL, + _logicName_ VARCHAR(200) NOT NULL, + _datatype_ VARCHAR(35) NOT NULL, + _eventId_ VARCHAR(50) NOT NULL, + _row_ LONGTEXT NOT NULL, + _colf_ LONGTEXT NOT NULL, + _markings_ VARCHAR(400) NOT NULL, + _column_markings_ LONGTEXT NOT NULL, + _column_timestamps_ LONGTEXT NOT NULL, + %FIELD_DEFINITIONS% + ) ENGINE = MyISAM + createTable: "CREATE TABLE %TABLE% LIKE template" + dropTable: "DROP TABLE %TABLE%" + dropView: "DROP VIEW %TABLE%" + insert: | + INSERT INTO %TABLE% ( + _user_, + _queryId_, + _logicName_, + _datatype_, + _eventId_, + _row_, + _colf_, + _markings_, + _column_markings_, + _column_timestamps_, + %PREPARED_FIELDS% + ) VALUES ( + ?, + ?, + ?, + ?, + ?, + ?, + ?, + ?, + ?, + ?, + %PREPARED_VALUES% + ) + createView: "CREATE VIEW %VIEW%(%VIEW_COLS%) AS SELECT %TABLE_COLS% FROM %TABLE%" diff --git a/configuration/configMapFiles/application-federation.yml b/configuration/configMapFiles/application-federation.yml new file mode 100644 index 0000000..baf261d --- /dev/null +++ b/configuration/configMapFiles/application-federation.yml @@ -0,0 +1,15 @@ +# This serves as a set of sensible defaults for authorization and query federation. +datawave: + authorization: + federation: + # Each entry in the following map will be registered as a FederatedAuthorizationService bean, named after the key + services: + FederatedAuthorizationService: + federatedAuthorizationUri: "https://{{ .Values.global.serviceDns.authorization.name }}:{{ .Values.global.serviceDns.authorization.port }}/{{ .Values.global.serviceDns.authorization.endpoint }}" + query: + federation: + # Each entry in the following map will be registered as a FederatedQueryService (RemoteQueryService) bean, named after the key + services: + FederatedQueryService: + queryServiceUri: 'https://{{ .Values.global.serviceDns.query.name }}:{{ .Values.global.serviceDns.query.port }}/query/v1' + queryMetricServiceUri: 'https://{{ .Values.global.serviceDns.metrics.name }}:{{ .Values.global.serviceDns.metrics.port }}/querymetric/v1/id' diff --git a/configuration/configMapFiles/application-k8s.yml b/configuration/configMapFiles/application-k8s.yml index e66ab62..25cc4fa 100644 --- a/configuration/configMapFiles/application-k8s.yml +++ b/configuration/configMapFiles/application-k8s.yml @@ -1,4 +1,30 @@ hazelcast: client: + clusterName: cache k8s: - service-dns-name: {{ .Values.global.serviceDns.cache.name }}.{{ .Release.Namespace }}.svc.cluster.local \ No newline at end of file + service-dns-name: {{ .Values.global.serviceDns.cache.name }}.{{ .Release.Namespace }}.svc.cluster.local + # This template is for configuring your site-specific properties for all microservices. +system.name: CONTAINERS +# Define the client certificates (in lower-case subjectDN form) that are allowed to call a service. Note that you only need to +# specify one value in the list below. +# Since enforce-allowed-callers is false, you can skip configuring this section if you want. +spring: + kafka: + bootstrap-servers: {{ .Values.global.serviceDns.kafka.name }}.{{ .Release.Namespace }}.svc.cluster.local:{{ .Values.global.serviceDns.kafka.port }} + consumer: + autoOffsetReset: earliest + enableAutoCommit: false + properties: + allow.auto.create.topics: false +# This is the accumulo configuration we use in services. These don't map directly to a properties class, but +# they are here to be used as a reference for other properties. +accumulo: + zookeepers: '{{ .Values.global.zookeeper.quorum }}' + instanceName: '{{ .Values.global.accumulo.instanceName }}' + username: '{{ .Values.global.accumulo.user }}' + password: '{{ .Values.global.accumulo.password }}' +# Configuration placeholders which 1) determines what backend will be used for transmitting query results +# and 2) determines the message size limit before claim checks are used with RabbitMQ messaging +messaging: + backend: kafka + maxMessageSizeBytes: 536870912 \ No newline at end of file diff --git a/configuration/configMapFiles/application-metricssource.yml b/configuration/configMapFiles/application-metricssource.yml new file mode 100755 index 0000000..b1bdb11 --- /dev/null +++ b/configuration/configMapFiles/application-metricssource.yml @@ -0,0 +1,23 @@ +# This profile should be added to your service if you depend on the +# query metric starter to send metrics to the query metric service. +spring: + cloud: + stream: + bindings: + queryMetricSource-out-0: + destination: queryMetricChannel + producer: + requiredGroups: queryMetricService + errorChannelEnabled: true + # NOTE: When defining your functions, be sure to include busConsumer, or else spring cloud bus will not work + function: + definition: queryMetricSource;busConsumer + +datawave: + query: + metric: + client: + confirmAckTimeoutMillis: 30000 +# To send metrics via REST, uncomment the following +# host: metrics +# transport: HTTPS diff --git a/configuration/configMapFiles/application-mrquery.yml b/configuration/configMapFiles/application-mrquery.yml new file mode 100755 index 0000000..6b2c940 --- /dev/null +++ b/configuration/configMapFiles/application-mrquery.yml @@ -0,0 +1,54 @@ +datawave: + query: + mapreduce: + fsConfigResources: + - ${HADOOP_CONF_DIR:/etc/hadoop/conf}/core-site.xml + - ${HADOOP_CONF_DIR:/etc/hadoop/conf}/hdfs-site.xml + - ${HADOOP_CONF_DIR:/etc/hadoop/conf}/mapred-site.xml + - ${HADOOP_CONF_DIR:/etc/hadoop/conf}/yarn-site.xml + callbackServletURL: "http://query:8080/query/v1/mapreduce/updateState" + mapReduceBaseDirectory: "/datawave/MapReduceService" + restrictInputFormats: true + validInputFormats: + - "org.apache.accumulo.core.client.mapreduce.AccumuloInputFormat" + - "datawave.mr.bulk.BulkInputFormat" + jobs: + 'BulkResultsJob': + startingClass: datawave.microservice.query.mapreduce.MapReduce + jobJarName: "MapReduceQueryCoreJob.jar" + description: "MapReduce job that runs a query and either puts the results into a table or files in HDFS" + hdfsUri: "hdfs://${HADOOP_HOST}:9000/" + jobTracker: "${HADOOP_HOST}:8021" + requiredRuntimeParameters: + queryId: java.lang.String + format: datawave.microservice.mapreduce.bulkresults.map.SerializationFormat + optionalRuntimeParameters: + outputTableName: java.lang.String + outputFormat: java.lang.String + jobConfigurationProperties: + "mapreduce.map.speculative": "false" + "mapreduce.map.output.compress": "false" + "mapreduce.output.fileoutputformat.compress": "false" + "mapreduce.job.user.classpath.first": "true" + # NOTE: Disable spring components which should not be run in a map-reduce context + jobSystemProperties: + "datawave.table.cache.enabled": "false" + "spring.profiles.active": "query,mrquery" + "spring.cloud.bus.enabled": "false" + "spring.cloud.discovery.enabled": "false" + "spring.cloud.consul.enabled": "false" + "spring.rabbitmq.discovery.enabled": "false" + "datawave.query.messaging.backend": "none" + "datawave.query.messaging.claimCheck.enabled": "false" + "datawave.query.storage.cache.enabled": "false" + "hazelcast.client.enabled": "false" + "spring.cloud.config.enabled": "false" + "datawave.query.metric.client.enabled": "false" + accumulo: + zookeepers: '${accumulo.zookeepers}' + instanceName: '${accumulo.instanceName}' + username: '${accumulo.username}' + password: '${accumulo.password}' + 'OozieJob': + hdfsUri: "hdfs://${HADOOP_HOST}:9000/" + jobTracker: "${HADOOP_HOST}:8021" \ No newline at end of file diff --git a/configuration/configMapFiles/application-query.yml b/configuration/configMapFiles/application-query.yml new file mode 100644 index 0000000..fb47737 --- /dev/null +++ b/configuration/configMapFiles/application-query.yml @@ -0,0 +1,573 @@ +# This profile should be included by any service which depends on the query starter. This +# file contains all of the configuration required to use the QueryLogicFactory. +warehouse: + accumulo: + zookeepers: '{{.Values.global.zookeeper.quorum}}' + instanceName: '{{.Values.global.accumulo.instanceName}}' + username: '{{.Values.global.accumulo.user}}' + password: '{{.Values.global.accumulo.password}}' + statsd: + host: localhost + port: 8125 + tables: + shard: + name: 'datawave.shard' + index: + name: 'datawave.shardIndex' + reverseIndex: + name: 'datawave.shardReverseIndex' + dateIndex: + name: 'datawave.dateIndex' + metadata: + name: 'datawave.metadata' + model: + name: 'datawave.metadata' + edge: + name: 'datawave.edge' + errorTables: + shard: + name: "datawave.error_s" + index: + name: "datawave.error_i" + reverseIndex: + name: "datawave.error_r" + dateIndex: + name: "" + metadata: + name: "datawave.error_m" + model: + name: "datawave.error_m" + metricTables: + shard: + name: "datawave.queryMetrics_s" + index: + name: "datawave.queryMetrics_i" + reverseIndex: + name: "datawave.queryMetrics_r" + dateIndex: + name: "" + metadata: + name: "datawave.queryMetrics_m" + model: + name: "datawave.queryMetrics_m" + defaults: + checkpointable: true + queryThreads: 100 + indexLookupThreads: 100 + dateIndexThreads: 20 + fullTableScanEnabled: false + baseIteratorPriority: 100 + maxIndexScanTimeMillis: 31536000000 + eventPerDayThreshold: 40000 + shardsPerDayThreshold: 20 + initialMaxTermThreshold: 2000 + finalMaxTermThreshold: 2000 + maxDepthThreshold: 2000 + maxUnfieldedExpansionThreshold: 50 + maxValueExpansionThreshold: 50 + maxOrExpansionThreshold: 500 + maxOrRangeThreshold: 10 + maxRangesPerRangeIvarator: 5 + maxOrRangeIvarators: 10 + maxOrExpansionFstThreshold: 750 + maxFieldIndexRangeSplit: 16 + maxIvaratorSources: 20 + maxEvaluationPipelines: 16 + maxPipelineCachedResults: 16 + hdfsSiteConfigURLs: 'file://${HADOOP_CONF_DIR:/etc/hadoop/conf}/core-site.xml,file://${HADOOP_CONF_DIR:/etc/hadoop/conf}/hdfs-site.xml' + ivaratorFstHdfsBaseURIs: "hdfs://${HADOOP_HOST:localhost}:9000/IvaratorCache" + ivaratorCacheBufferSize: 10000 + ivaratorMaxOpenFiles: 100 + ivaratorCacheScanPersistThreshold: 100000 + ivaratorCacheScanTimeoutMinutes: 60 + modelName: 'DATAWAVE' + edgeModelName: 'DATAWAVE_EDGE' + +datawave: + metadata: + all-metadata-auths: + - PRIVATE,PUBLIC + type-substitutions: + "[datawave.data.type.DateType]": "datawave.data.type.RawDateType" + + query: + parser: + skipTokenizeUnfieldedFields: + - "DOMETA" + tokenizedFields: + - "CONTENT" + logic: + factory: + enabled: true + # Uncomment the following line to override the query logic beans to load + # xmlBeansPath: "classpath:MyTestQueryLogicFactory.xml" + + # If desired, you may populate this map to redefine the name for each query logic. + # This can also be used to limit the available query logics. + queryLogicsByName: + "EventQuery": "EventQuery" + "ErrorEventQuery": "ErrorEventQuery" + "DiscoveryQuery": "DiscoveryQuery" + "ErrorDiscoveryQuery": "ErrorDiscoveryQuery" + "LuceneUUIDEventQuery": "LuceneUUIDEventQuery" + "ContentQuery": "ContentQuery" + "EdgeQuery": "EdgeQuery" + "CountQuery": "CountQuery" + "ErrorCountQuery": "ErrorCountQuery" + "FieldIndexCountQuery": "FieldIndexCountQuery" + "ErrorFieldIndexCountQuery": "ErrorFieldIndexCountQuery" + "TermFrequencyQuery": "TermFrequencyQuery" + "IndexStatsQuery": "IndexStatsQuery" + "QueryMetricsQuery": "QueryMetricsQuery" + "InternalQueryMetricsQuery": "InternalQueryMetricsQuery" + "FacetedQuery": "FacetedQuery" + "HitHighlights": "HitHighlights" + "EdgeEventQuery": "EdgeEventQuery" + "FederatedEventQuery": "FederatedEventQuery" + + # The max page size that a user can request. 0 turns off this feature + maxPageSize: 10000 + + # The number of bytes at which a page will be returned, event if the pagesize has not been reached. 0 turns off this feature + pageByteTrigger: 0 + logics: + BaseEventQuery: + checkpointable: ${warehouse.defaults.checkpointable} + accumuloPassword: ${warehouse.accumulo.password} + tableName: ${warehouse.tables.shard.name} + dateIndexTableName: ${warehouse.tables.dateIndex.name} + defaultDateTypeName: "EVENT" + metadataTableName: ${warehouse.tables.metadata.name} + indexTableName: ${warehouse.tables.index.name} + reverseIndexTableName: ${warehouse.tables.reverseIndex.name} + maxResults: -1 + queryThreads: ${warehouse.defaults.queryThreads} + indexLookupThreads: ${warehouse.defaults.indexLookupThreads} + dateIndexThreads: ${warehouse.defaults.dateIndexThreads} + fullTableScanEnabled: ${warehouse.defaults.fullTableScanEnabled} + includeDataTypeAsField: false + disableIndexOnlyDocuments: false + indexOnlyFilterFunctionsEnabled: false + includeHierarchyFields: false + hierarchyFieldOptions: + "FOO": "BAR" + baseIteratorPriority: ${warehouse.defaults.baseIteratorPriority} + maxIndexScanTimeMillis: ${warehouse.defaults.maxIndexScanTimeMillis} + collapseUids: false + collapseUidsThreshold: -1 + useEnrichers: true + contentFieldNames: + - 'CONTENT' + realmSuffixExclusionPatterns: + - '<.*>$' + minimumSelectivity: .2 + enricherClassNames: + - 'datawave.query.enrich.DatawaveTermFrequencyEnricher' + useFilters: false + filterClassNames: + - 'foo.bar' + filterOptions: + 'bar': "foo" + auditType: "ACTIVE" + logicDescription: "Retrieve sharded events/documents, leveraging the global index tables as needed" + eventPerDayThreshold: ${warehouse.defaults.eventPerDayThreshold} + shardsPerDayThreshold: ${warehouse.defaults.shardsPerDayThreshold} + initialMaxTermThreshold: ${warehouse.defaults.initialMaxTermThreshold} + finalMaxTermThreshold: ${warehouse.defaults.finalMaxTermThreshold} + maxDepthThreshold: ${warehouse.defaults.maxDepthThreshold} + maxUnfieldedExpansionThreshold: ${warehouse.defaults.maxUnfieldedExpansionThreshold} + maxValueExpansionThreshold: ${warehouse.defaults.maxValueExpansionThreshold} + maxOrExpansionThreshold: ${warehouse.defaults.maxOrExpansionThreshold} + maxOrRangeThreshold: ${warehouse.defaults.maxOrRangeThreshold} + maxOrExpansionFstThreshold: ${warehouse.defaults.maxOrExpansionFstThreshold} + maxFieldIndexRangeSplit: ${warehouse.defaults.maxFieldIndexRangeSplit} + maxIvaratorSources: ${warehouse.defaults.maxIvaratorSources} + maxEvaluationPipelines: ${warehouse.defaults.maxEvaluationPipelines} + maxPipelineCachedResults: ${warehouse.defaults.maxPipelineCachedResults} + hdfsSiteConfigURLs: ${warehouse.defaults.hdfsSiteConfigURLs} + zookeeperConfig: ${warehouse.accumulo.zookeepers} + ivaratorCacheDirConfigs: + - basePathURI: "hdfs://${HADOOP_HOST:localhost}:9000/IvaratorCache" + ivaratorFstHdfsBaseURIs: ${warehouse.defaults.ivaratorFstHdfsBaseURIs} + ivaratorCacheBufferSize: ${warehouse.defaults.ivaratorCacheBufferSize} + ivaratorMaxOpenFiles: ${warehouse.defaults.ivaratorMaxOpenFiles} + ivaratorCacheScanPersistThreshold: ${warehouse.defaults.ivaratorCacheScanPersistThreshold} + ivaratorCacheScanTimeoutMinutes: ${warehouse.defaults.ivaratorCacheScanTimeoutMinutes} + eventQueryDataDecoratorTransformer: + requestedDecorators: + - "CSV" + - "WIKIPEDIA" + dataDecorators: + "CSV": + "EVENT_ID": "https://localhost:8443/DataWave/Query/lookupUUID/EVENT_ID?uuid=@field_value@&parameters=data.decorators:CSV" + "UUID": "https://localhost:8443/DataWave/Query/lookupUUID/UUID?uuid=@field_value@&parameters=data.decorators:CSV" + "PARENT_UUID": "https://localhost:8443/DataWave/Query/lookupUUID/PARENT_UUID?uuid=@field_value@&parameters=data.decorators:CSV" + "WIKIPEDIA": + "PAGE_ID": "https://localhost:8443/DataWave/Query/lookupUUID/PAGE_ID?uuid=@field_value@&parameters=data.decorators:WIKIPEDIA" + "PAGE_TITLE": "https://localhost:8443/DataWave/Query/lookupUUID/PAGE_TITLE?uuid=@field_value@&parameters=data.decorators:WIKIPEDIA" + modelTableName: ${warehouse.tables.model.name} + modelName: ${warehouse.defaults.modelName} + querySyntaxParsers: + JEXL: "" + LUCENE: "LuceneToJexlQueryParser" + LUCENE-UUID: "LuceneToJexlUUIDQueryParser" + TOKENIZED-LUCENE: "TokenizedLuceneToJexlQueryParser" + sendTimingToStatsd: false + collectQueryMetrics: true + logTimingDetails: true + statsdHost: ${warehouse.statsd.host} + statsdPort: ${warehouse.statsd.port} + evaluationOnlyFields: "" + maxConcurrentTasks: 10 + requiredRoles: + - "AuthorizedUser" + + EventQuery: + checkpointable: ${warehouse.defaults.checkpointable} + logicDescription: "Query the sharded event/document schema, leveraging the global index tables as needed" + + ErrorEventQuery: + checkpointable: ${warehouse.defaults.checkpointable} + logicDescription: "Retrieve events/documents that encountered one or more errors during ingest" + tableName: ${warehouse.errorTables.shard.name} + metadataTableName: ${warehouse.errorTables.metadata.name} + dateIndexTableName: "" + indexTableName: ${warehouse.errorTables.index.name} + reverseIndexTableName: ${warehouse.errorTables.reverseIndex.name} + includeHierarchyFields: false + + DiscoveryQuery: + checkpointable: ${warehouse.defaults.checkpointable} + tableName: ${warehouse.tables.shard.name} + indexTableName: ${warehouse.tables.index.name} + reverseIndexTableName: ${warehouse.tables.reverseIndex.name} + metadataTableName: ${warehouse.tables.metadata.name} + modelTableName: ${warehouse.tables.model.name} + modelName: ${warehouse.defaults.modelName} + fullTableScanEnabled: ${warehouse.defaults.fullTableScanEnabled} + allowLeadingWildcard: true + auditType: "NONE" + maxResults: -1 + maxWork: -1 + logicDescription: "Discovery query that returns information from the index about the supplied term(s)" + + ErrorDiscoveryQuery: + checkpointable: ${warehouse.defaults.checkpointable} + tableName: ${warehouse.errorTables.shard.name} + indexTableName: ${warehouse.errorTables.index.name} + reverseIndexTableName: ${warehouse.errorTables.reverseIndex.name} + maxResults: -1 + maxWork: -1 + metadataTableName: ${warehouse.errorTables.metadata.name} + modelTableName: ${warehouse.errorTables.model.name} + modelName: ${warehouse.defaults.modelName} + fullTableScanEnabled: ${warehouse.defaults.fullTableScanEnabled} + allowLeadingWildcard: true + auditType: "NONE" + logicDescription: "Discovery query that returns information from the ingest errors index about the supplied term(s)" + + LuceneUUIDEventQuery: + checkpointable: ${warehouse.defaults.checkpointable} + logicDescription: "Composite query logic that retrieves records from the event and error tables, based on known UUID fields, ie, those configured via UUIDTypeList in QueryLogicFactory.xml" + auditType: "NONE" + eventQuery: + auditType: "NONE" + logicDescription: "Lucene query for event/document UUIDs" + mandatoryQuerySyntax: + - "LUCENE-UUID" + connPoolName: "UUID" + errorEventQuery: + auditType: "NONE" + logicDescription: "Lucene query for event/document UUIDs for events that encountered errors at ingest time" + mandatoryQuerySyntax: + - "LUCENE-UUID" + connPoolName: "UUID" + tableName: ${warehouse.errorTables.shard.name} + dateIndexTableName: ${warehouse.errorTables.dateIndex.name} + metadataTableName: ${warehouse.errorTables.metadata.name} + indexTableName: ${warehouse.errorTables.index.name} + reverseIndexTableName: ${warehouse.errorTables.reverseIndex.name} + + ContentQuery: + checkpointable: ${warehouse.defaults.checkpointable} + tableName: ${warehouse.tables.shard.name} + maxResults: -1 + maxWork: -1 + auditType: "NONE" + logicDescription: "Query that returns a document given the document identifier" + + EdgeQuery: + checkpointable: ${warehouse.defaults.checkpointable} + tableName: ${warehouse.tables.edge.name} + metadataTableName: ${warehouse.tables.metadata.name} + modelTableName: ${warehouse.tables.model.name} + modelName: ${warehouse.defaults.edgeModelName} + maxResults: 25000 + maxConcurrentTasks: 10 + maxWork: -1 + queryThreads: 16 + auditType: "NONE" + logicDescription: "Retrieve graph edges matching the search term(s)" + querySyntaxParsers: + "JEXL": "" + "LIST": "" + "LIMITED_JEXL": "" + "LUCENE": "" + + CountQuery: + checkpointable: ${warehouse.defaults.checkpointable} + logicDescription: "Retrieve event/document counts based on your search criteria" + + ErrorCountQuery: + checkpointable: ${warehouse.defaults.checkpointable} + logicDescription: "Retrieve counts of errored events based on your search criteria" + tableName: ${warehouse.errorTables.shard.name} + metadataTableName: ${warehouse.errorTables.metadata.name} + indexTableName: ${warehouse.errorTables.index.name} + reverseIndexTableName: ${warehouse.errorTables.reverseIndex.name} + + FieldIndexCountQuery: + checkpointable: false + tableName: ${warehouse.tables.shard.name} + indexTableName: ${warehouse.tables.index.name} + reverseIndexTableName: ${warehouse.tables.reverseIndex.name} + metadataTableName: ${warehouse.tables.metadata.name} + maxResults: -1 + maxWork: -1 + queryThreads: ${warehouse.defaults.queryThreads} + modelTableName: ${warehouse.tables.model.name} + modelName: "DATAWAVE" + maxUniqueValues: 20000 + maxConcurrentTasks: 10 + auditType: "NONE" + logicDescription: "Indexed Fields Only: Given FIELDNAME returns counts for each unique value. Given FIELDNAME:FIELDVALUE returns count for only that value." + + ErrorFieldIndexCountQuery: + checkpointable: false + tableName: ${warehouse.errorTables.shard.name} + indexTableName: ${warehouse.errorTables.index.name} + reverseIndexTableName: ${warehouse.errorTables.reverseIndex.name} + metadataTableName: ${warehouse.errorTables.metadata.name} + maxResults: -1 + maxWork: -1 + queryThreads: ${warehouse.defaults.queryThreads} + modelTableName: ${warehouse.errorTables.model.name} + modelName: "DATAWAVE" + maxUniqueValues: 20000 + maxConcurrentTasks: 10 + auditType: "NONE" + logicDescription: "FieldIndex count query (experimental)" + + TermFrequencyQuery: + tableName: ${warehouse.tables.shard.name} + maxResults: -1 + maxWork: -14 + auditType: "NONE" + logicDescription: "Query that returns data from the term frequency query table" + + IndexStatsQuery: + auditType: "NONE" + + QueryMetricsQuery: + checkpointable: ${warehouse.defaults.checkpointable} + logicDescription: "Retrieve query metrics based on the given search term(s)" + includeHierarchyFields: false + modelTableName: ${warehouse.metricTables.model.name} + modelName: "NONE" + tableName: ${warehouse.metricTables.shard.name} + dateIndexTableName: ${warehouse.metricTables.dateIndex.name} + metadataTableName: ${warehouse.metricTables.metadata.name} + indexTableName: ${warehouse.metricTables.index.name} + reverseIndexTableName: ${warehouse.metricTables.reverseIndex.name} + auditType: "NONE" + collectQueryMetrics: true + + InternalQueryMetricsQuery: + collectQueryMetrics: false + requiredRoles: + - "AuthorizedServer" + + FacetedQuery: + checkpointable: ${warehouse.defaults.checkpointable} + auditType: "NONE" + logicDescription: "Faceted search over indexed fields, returning aggregate counts for field values" + facetedSearchType: "FIELD_VALUE_FACETS" + facetTableName: "datawave.facets" + facetMetadataTableName: "datawave.facetMetadata" + facetHashTableName: "datawave.facetHashes" + maximumFacetGrouping: 200 + minimumFacet: 1 + streaming: true + querySyntaxParsers: + JEXL: "" + LUCENE: "LuceneToJexlQueryParser" + LUCENE-UUID: "LuceneToJexlUUIDQueryParser" + + HitHighlights: + checkpointable: ${warehouse.defaults.checkpointable} + accumuloPassword: ${warehouse.accumulo.password} + tableName: ${warehouse.tables.shard.name} + dateIndexTableName: ${warehouse.tables.dateIndex.name} + defaultDateTypeName: "EVENT" + metadataTableName: ${warehouse.tables.metadata.name} + indexTableName: ${warehouse.tables.index.name} + reverseIndexTableName: ${warehouse.tables.reverseIndex.name} + queryThreads: ${warehouse.defaults.indexLookupThreads} + fullTableScanEnabled: ${warehouse.defaults.fullTableScanEnabled} + minimumSelectivity: .2 + includeDataTypeAsField: false + includeGroupingContext: false + useEnrichers: false + auditType: "NONE" + logicDescription: "Fast boolean query over indexed fields, only returning fields queried on" + eventPerDayThreshold: 40000 + shardsPerDayThreshold: ${warehouse.defaults.shardsPerDayThreshold} + initialMaxTermThreshold: ${warehouse.defaults.initialMaxTermThreshold} + finalMaxTermThreshold: ${warehouse.defaults.finalMaxTermThreshold} + maxConcurrentTasks: 10 + maxDepthThreshold: ${warehouse.defaults.maxDepthThreshold} + maxUnfieldedExpansionThreshold: ${warehouse.defaults.maxUnfieldedExpansionThreshold} + maxValueExpansionThreshold: ${warehouse.defaults.maxValueExpansionThreshold} + maxOrExpansionThreshold: ${warehouse.defaults.maxOrExpansionThreshold} + maxOrRangeThreshold: ${warehouse.defaults.maxOrRangeThreshold} + maxRangesPerRangeIvarator: ${warehouse.defaults.maxRangesPerRangeIvarator} + maxOrRangeIvarators: ${warehouse.defaults.maxOrRangeIvarators} + maxOrExpansionFstThreshold: ${warehouse.defaults.maxOrExpansionFstThreshold} + maxFieldIndexRangeSplit: ${warehouse.defaults.maxFieldIndexRangeSplit} + maxEvaluationPipelines: ${warehouse.defaults.maxEvaluationPipelines} + maxPipelineCachedResults: ${warehouse.defaults.maxPipelineCachedResults} + hdfsSiteConfigURLs: ${warehouse.defaults.hdfsSiteConfigURLs} + zookeeperConfig: ${warehouse.accumulo.zookeepers} + ivaratorCacheDirConfigs: + - basePathURI: "hdfs://${HADOOP_HOST:localhost}:9000/IvaratorCache" + ivaratorFstHdfsBaseURIs: ${warehouse.defaults.ivaratorFstHdfsBaseURIs} + ivaratorCacheBufferSize: 10000 + ivaratorMaxOpenFiles: ${warehouse.defaults.ivaratorMaxOpenFiles} + ivaratorCacheScanPersistThreshold: 100000 + ivaratorCacheScanTimeoutMinutes: ${warehouse.defaults.ivaratorCacheScanTimeoutMinutes} + querySyntaxParsers: + JEXL: "" + LUCENE: "LuceneToJexlQueryParser" + LUCENE-UUID: "LuceneToJexlUUIDQueryParser" + + EdgeEventQuery: + checkpointable: ${warehouse.defaults.checkpointable} + logicDescription: "Use results of an EdgeQuery to obtain events/documents that created the given edge" + edgeModelName: "DATAWAVE_EDGE" + modelTableName: ${warehouse.tables.model.name} + + uuidTypes: &defaultUuidTypes + 'EVENT_ID': + fieldName: 'EVENT_ID' + queryLogics: + 'default': 'LuceneUUIDEventQuery' + allowedWildcardAfter: 28 + 'UUID': + fieldName: 'UUID' + queryLogics: + 'default': 'LuceneUUIDEventQuery' + 'PARENT_UUID': + fieldName: 'PARENT_UUID' + queryLogics: + 'default': 'LuceneUUIDEventQuery' + 'PAGE_ID': + fieldName: 'PAGE_ID' + queryLogics: + 'default': 'LuceneUUIDEventQuery' + 'PAGE_TITLE': + fieldName: 'PAGE_TITLE' + queryLogics: + 'default': 'LuceneUUIDEventQuery' + + lookup: + columnVisibility: "" + beginDate: "20100101 000000.000" + types: *defaultUuidTypes + + translateid: + columnVisibility: "" + beginDate: "20100101 000000.000" + types: *defaultUuidTypes + + edge: + # Uncomment the following line to override the edge beans to load + # xmlBeansPath: "classpath:EdgeBeans.xml" + model: + baseFieldMap: + EDGE_SOURCE: 'SOURCE' + EDGE_SINK: 'SINK' + EDGE_TYPE: 'TYPE' + EDGE_RELATIONSHIP: 'RELATION' + EDGE_ATTRIBUTE1: 'ATTRIBUTE1' + EDGE_ATTRIBUTE2: 'ATTRIBUTE2' + EDGE_ATTRIBUTE3: 'ATTRIBUTE3' + DATE: 'DATE' + STATS_EDGE: 'STATS_TYPE' + keyUtilFieldMap: + ENRICHMENT_TYPE: 'ENRICHMENT_TYPE' + FACT_TYPE: 'FACT_TYPE' + GROUPED_FIELDS: 'GROUPED_FIELDS' + transformFieldMap: + COUNT: 'COUNT' + COUNTS: 'COUNTS' + LOAD_DATE: 'LOADDATE' + ACTIVITY_DATE: 'ACTIVITY_DATE' + fieldMappings: + - fieldName: "SOURCE" + modelFieldName: "VERTEXA" + direction: "REVERSE" + indexOnly: false + - fieldName: "SOURCE" + modelFieldName: "VERTEXA" + direction: "FORWARD" + indexOnly: false + - fieldName: "SINK" + modelFieldName: "VERTEXB" + direction: "REVERSE" + indexOnly: false + - fieldName: "SINK" + modelFieldName: "VERTEXB" + direction: "FORWARD" + indexOnly: false + - fieldName: "RELATION" + modelFieldName: "RELATION" + direction: "REVERSE" + indexOnly: false + - fieldName: "RELATION" + modelFieldName: "RELATION" + direction: "FORWARD" + indexOnly: false + - fieldName: "TYPE" + modelFieldName: "TYPE" + direction: "REVERSE" + indexOnly: false + - fieldName: "TYPE" + modelFieldName: "TYPE" + direction: "FORWARD" + indexOnly: false + - fieldName: "ATTRIBUTE1" + modelFieldName: "ATTR1" + direction: "REVERSE" + indexOnly: false + - fieldName: "ATTRIBUTE1" + modelFieldName: "ATTR1" + direction: "FORWARD" + indexOnly: false + - fieldName: "ATTRIBUTE2" + modelFieldName: "ATTR2" + direction: "REVERSE" + indexOnly: false + - fieldName: "ATTRIBUTE2" + modelFieldName: "ATTR2" + direction: "FORWARD" + indexOnly: false + - fieldName: "ATTRIBUTE3" + modelFieldName: "ATTR3" + direction: "REVERSE" + indexOnly: false + - fieldName: "ATTRIBUTE3" + modelFieldName: "ATTR3" + direction: "FORWARD" + indexOnly: false + + diff --git a/configuration/configMapFiles/application-querymessaging.yml b/configuration/configMapFiles/application-querymessaging.yml new file mode 100755 index 0000000..fd5b0c9 --- /dev/null +++ b/configuration/configMapFiles/application-querymessaging.yml @@ -0,0 +1,11 @@ +# This profile should be included by any service which depends on the query starter and +# wants to read/write query stats from/to the query storage cache, or read/write query +# results from/to the query results messaging backend. +datawave: + query: + messaging: + backend: ${messaging.backend} + rabbitmq: + maxMessageSizeBytes: ${messaging.maxMessageSizeBytes} + kafka: + partitions: 2 diff --git a/configuration/configMapFiles/application.yml b/configuration/configMapFiles/application.yml index 1b58eae..b2befe5 100644 --- a/configuration/configMapFiles/application.yml +++ b/configuration/configMapFiles/application.yml @@ -13,6 +13,7 @@ management: endpoints.web.base-path: /mgmt endpoints.web.exposure.include: "*" server: + cdn-uri: /${spring.application.name}/ non-secure-port: 8080 outbound-ssl: key-store: ${server.ssl.key-store} @@ -32,6 +33,8 @@ server: trust-store-type: '{{ .Values.global.secrets.truststore.type }}' trust-store-password: '{{ .Values.global.secrets.truststore.password }}' spring: + jackson: + default-property-include: non_null cloud: consul: enabled: false @@ -40,10 +43,13 @@ spring: enabled: false failFast: true host: '{{ .Values.global.serviceDns.rabbitmq.name }}' + publisher-confirm-type: simple + publisher-confirms: true + publisher-returns: true security: datawave: enforce-allowed-callers: false issuers-required: true jwt.ttl: 86400 - manager-role: Administator,JBossAdministrator + manager-roles: Administator,JBossAdministrator user.password: passwordNotUsed \ No newline at end of file diff --git a/configuration/configMapFiles/audit.yml b/configuration/configMapFiles/audit.yml index 46d64e1..0a0fa55 100644 --- a/configuration/configMapFiles/audit.yml +++ b/configuration/configMapFiles/audit.yml @@ -1,14 +1,25 @@ audit: + confirmAckEnabled: false + replay: + enabled: true auditors: - accumulo: + dump: enabled: false + pathUri: file:///audit + accumulo: + enabled: true + accumuloConfig: + zookeepers: '${accumulo.zookeepers}' + instanceName: '${accumulo.instanceName}' + username: '${accumulo.username}' + password: '${accumulo.password}' file: enabled: false maxFileAgeSeconds: 60 maxLengthFileMB: 1 - pathUri: s3a://signus-audits/ + pathUri: file:///audit log: - enabled: false + enabled: true logging: level: datawave.microservice.audit: DEBUG diff --git a/configuration/configMapFiles/executor-pool1.yml b/configuration/configMapFiles/executor-pool1.yml new file mode 100755 index 0000000..8850c4a --- /dev/null +++ b/configuration/configMapFiles/executor-pool1.yml @@ -0,0 +1,20 @@ +# This is where you set properties which are specific to pool1 +executor: + poolName: 'pool1' + +datawave: + swagger: + title: "Query Executor Service (Pool 1)" + description: "REST API provided by the Query Executor Service" + connection: + factory: + pools: + 'pool1': + zookeepers: '${accumulo.zookeepers}' + instance: '${accumulo.instanceName}' + username: '${accumulo.username}' + password: '${accumulo.password}' + lowPriorityPoolSize: 40 + normalPriorityPoolSize: 40 + highPriorityPoolSize: 40 + adminPriorityPoolSize: 40 diff --git a/configuration/configMapFiles/executor-pool2.yml b/configuration/configMapFiles/executor-pool2.yml new file mode 100755 index 0000000..a4757d9 --- /dev/null +++ b/configuration/configMapFiles/executor-pool2.yml @@ -0,0 +1,20 @@ +# This is where you set properties which are specific to pool2 +executor: + poolName: 'pool2' + +datawave: + swagger: + title: "Query Executor Service (Pool 2)" + description: "REST API provided by the Query Executor Service" + connection: + factory: + pools: + 'pool2': + zookeepers: '${accumulo.zookeepers}' + instance: '${accumulo.instanceName}' + username: '${accumulo.username}' + password: '${accumulo.password}' + lowPriorityPoolSize: 40 + normalPriorityPoolSize: 40 + highPriorityPoolSize: 40 + adminPriorityPoolSize: 40 diff --git a/configuration/configMapFiles/executor.yml b/configuration/configMapFiles/executor.yml new file mode 100755 index 0000000..da54229 --- /dev/null +++ b/configuration/configMapFiles/executor.yml @@ -0,0 +1,67 @@ +# This is where you set properties which are common to all executors +server: + # since the application names include the pools, lets override the context path to simply be executor + servlet.context-path: /executor + cdn-uri: /executor/ + +logging: + level: + root: INFO + datawave.query: DEBUG + datawave.microservice.query: DEBUG + datawave.microservice.query.executor: DEBUG + org.apache.kafka: ERROR + datawave.microservice.query.storage: WARN + +warehouse: + accumulo: + zookeepers: '${accumulo.zookeepers}' + instanceName: '${accumulo.instanceName}' + username: '${accumulo.username}' + password: '${accumulo.password}' + +datawave: + table: + cache: + zookeepers: '${accumulo.zookeepers}' + tableNames: + - '${warehouse.tables.metadata.name}' + poolName: 'default' + reloadInterval: 360000 + evictionReaperIntervalInSeconds: 360 + numLocks: 3 + maxRetries: 3 + reload-crontab: '* * * * * ?' + connection: + factory: + defaultPool: "default" + pools: + "default": + zookeepers: '${accumulo.zookeepers}' + instance: '${accumulo.instanceName}' + username: '${accumulo.username}' + password: '${accumulo.password}' + lowPriorityPoolSize: 40 + normalPriorityPoolSize: 40 + highPriorityPoolSize: 40 + adminPriorityPoolSize: 40 + query: + executor: + pool: "${executor.poolName}" + availableResultsPageMultiplier: 2.5 + maxQueueSize: 400 + coreThreads: 10 + maxThreads: 40 + keepAliveMs: 600000 + queryStatusExpirationMs: 60000 + checkpointFlushMs: 1000 + checkpointFlushResults: 2 + orphanThresholdMs: 60000 + monitorTaskLease: 30 + monitorTaskLeaseUnit: SECONDS + monitor: + enabled: true + scheduler-crontab: '* * * * * ?' + logStatusPeriodMs: 600000 + logStatusWhenChangedMs: 300000 + queryMetricsUrlPrefix: https://localhost:8543/querymetric/v1/id/ diff --git a/configuration/configMapFiles/modification.yml b/configuration/configMapFiles/modification.yml new file mode 100644 index 0000000..0ed3ebb --- /dev/null +++ b/configuration/configMapFiles/modification.yml @@ -0,0 +1,68 @@ +# This file contains all of the configuration required to use the modification service +logging: + level: + root: INFO + datawave.modification: DEBUG + datawave.microservice.modification: DEBUG + datawave.microservice.modification.query: DEBUG + +datawave: + swagger: + title: "Modification (Mutable Metadata) Service" + description: "REST API provided by the Modification (Mutable Metadata) Service" + + modification: + query: + queryURI: https://dwv-web-query:8443/query/v1 + queryPool: pool1 + remoteQueryTimeout: 1 + remoteQueryTimeoutUnit: MINUTES + data: + tableName: ${warehouse.tables.metadata.name} + poolName: "default" + handlers: + authorizedRoles: + - "AuthorizedUser" + eventTableName: ${warehouse.tables.shard.name} + metadataTableName: ${warehouse.tables.metadata.name} + indexTableName: ${warehouse.tables.index.name} + reverseIndexTableName: ${warehouse.tables.reverseIndex.name} + securityMarkingExemptFields: + - "ExampleExemptField" + requiresAudit: false + indexOnlyMap: + "SomeEventField": "SomeIndexField1,SomeIndexField2" + indexOnlySuffixes: + - "ExampleSuffix" + contentFields: + - "ExampleContentField" + + table: + cache: + zookeepers: '${accumulo.zookeepers}' + tableNames: + - '${warehouse.tables.metadata.name}' + poolName: 'default' + reloadInterval: 360000 + evictionReaperIntervalInSeconds: 360 + numLocks: 3 + maxRetries: 3 + reload-crontab: '* * * * * ?' + connection: + factory: + defaultPool: "default" + pools: + "default": + zookeepers: '${accumulo.zookeepers}' + instance: '${accumulo.instanceName}' + username: '${accumulo.username}' + password: '${accumulo.password}' + lowPriorityPoolSize: 40 + normalPriorityPoolSize: 40 + highPriorityPoolSize: 40 + adminPriorityPoolSize: 40 + + security: + util: + subjectDnPattern: "(?:^|,)\\s*OU\\s*=\\s*My Department\\s*(?:,|$)" + npeOuList: "EXAMPLE_SERVER_OU1,EXAMPLE_SERVER_OU2" \ No newline at end of file diff --git a/configuration/configMapFiles/mrquery.yml b/configuration/configMapFiles/mrquery.yml new file mode 100755 index 0000000..2e3a573 --- /dev/null +++ b/configuration/configMapFiles/mrquery.yml @@ -0,0 +1,31 @@ +logging: + level: + root: INFO + org.springframework.cloud.bootstrap.config: DEBUG + datawave.microservice.query: DEBUG + +datawave: + table: + cache: + zookeepers: '${accumulo.zookeepers}' + tableNames: + - '${warehouse.tables.metadata.name}' + poolName: 'default' + reloadInterval: 360000 + evictionReaperIntervalInSeconds: 360 + numLocks: 3 + maxRetries: 3 + reload-crontab: '* * * * * ?' + connection: + factory: + defaultPool: "default" + pools: + "default": + zookeepers: '${accumulo.zookeepers}' + instance: '${accumulo.instanceName}' + username: '${accumulo.username}' + password: '${accumulo.password}' + lowPriorityPoolSize: 40 + normalPriorityPoolSize: 40 + highPriorityPoolSize: 40 + adminPriorityPoolSize: 40 \ No newline at end of file diff --git a/configuration/configMapFiles/query.yml b/configuration/configMapFiles/query.yml new file mode 100755 index 0000000..c8ee1de --- /dev/null +++ b/configuration/configMapFiles/query.yml @@ -0,0 +1,74 @@ +spring: + lifecycle: + # Set the shutdown grace period + timeout-per-shutdown-phase: 5s + +management: + endpoint: + # Enable the shutdown endpoint for the query service + shutdown: + enabled: true + +# Query requires a client certificate +server: + ssl: + client-auth: NEED + # Enable graceful shutdown + shutdown: "graceful" + +logging: + level: + root: DEBUG + org.springframework.cloud.bootstrap.config: DEBUG + datawave.microservice.query: DEBUG + org.apache.kafka: ERROR + datawave.microservice.query.storage: WARN + +datawave: + swagger: + title: "Query Service" + description: "REST API provided by the Query Service" + query: + nextCall: + resultPollInterval: 500 + statusUpdateInterval: 500 + expiration: + callTimeout: 1 + callTimeoutUnit: HOURS + shortCircuitCheckTime: 60 + shortCircuitCheckTimeUnit: MINUTES + shortCircuitTimeout: 55 + shortCircuitTimeoutUnit: MINUTES + longRunningQueryTimeout: 24 + longRunningQueryTimeoutUnit: HOURS + monitor: + monitorInterval: 30 + monitorIntervalUnit: SECONDS + doc: + menu: + extras: '' + table: + cache: + enabled: false + web: + accumulo: + uri: 'https://accumulo:9143/accumulo' + cache: + uri: 'https://cache:8843/cache' + config: + uri: 'https://configuration:8888/configserver' + authorization: + uri: 'https://authorization:8343/authorization' + audit: + uri: 'https://audit-service:9043/audit' + metrics: + uri: 'https://querymetric:8543/querymetric' + dictionary: + uri: 'https://dictionary:8643/dictionary' + executor: + uri: 'https://executor:8743/executor' + +audit-client: + discovery: + enabled: false + uri: '${AUDIT_SERVER_URL:http://localhost:11111/audit}' diff --git a/configuration/configMapFiles/querymetric.yml b/configuration/configMapFiles/querymetric.yml new file mode 100755 index 0000000..325380f --- /dev/null +++ b/configuration/configMapFiles/querymetric.yml @@ -0,0 +1,124 @@ +# Query Metrics requires a client certificate +server: + ssl: + client-auth: NEED + +spring: + cloud: + stream: + bindings: + queryMetricSource-out-0: + destination: queryMetricChannel + producer: + errorChannelEnabled: true + queryMetricSink-in-0: + destination: queryMetricChannel + group: queryMetricService + # NOTE: When defining your functions, be sure to include busConsumer, or else spring cloud bus will not work + function: + definition: queryMetricSource;queryMetricSink;busConsumer + +warehouse-cluster: + accumulo: + zookeepers: '${accumulo.zookeepers}' + instanceName: '${accumulo.instanceName}' + username: '${accumulo.username}' + password: '${accumulo.password}' + +logging: + level: + ROOT: DEBUG + datawave: + microservice.querymetric: DEBUG + iterators: error + query: error + ingest: error + security: error + +datawave: + swagger: + title: "Query Metric Service" + description: "REST API provided by the Query Metric Service" + query: + metric: + handler: + zookeepers: ${warehouse-cluster.accumulo.zookeepers} + instanceName: ${warehouse-cluster.accumulo.instanceName} + username: ${warehouse-cluster.accumulo.username} + password: ${warehouse-cluster.accumulo.password} + accumuloClientPoolSize: 16 + mapStoreWriteThreads: 1 + numShards: 10 + fieldLengthThreshold: 4049 + shardTableName: datawave.queryMetrics_s + indexTableName: datawave.queryMetrics_i + dateIndexTableName: datawave.queryMetrics_di + reverseIndexTableName: datawave.queryMetrics_r + metadataTableName: datawave.queryMetrics_m + metadataDefaultAuths: PUBLIC + recordWriterMaxMemory: 10 + recordWriterMaxLatency: 16 + recordWriterNumThreads: 4 + enableBloomFilter: false + queryVisibility: PUBLIC + defaultMetricVisibility: PUBLIC + defaultMetricMarkings: + columnVisibility: PUBLIC + baseMaps: "{}" + queryPool: "pool1" + timely: + enabled: false + confirmAckTimeoutMillis: 30000 + + # this should be consolidated into a metadata application profile + metadata: + all-metadata-auths: + - PRIVATE + - PUBLIC + type-substitutions: + "[datawave.data.type.DateType]": "datawave.data.type.RawDateType" + +hazelcast: + client.enabled: false + server: + enabled: true + xml-config: | + + + + 1 + + 600 + + 3600 + com.hazelcast.spi.merge.LatestUpdateMergePolicy + true + + + + datawave.microservice.querymetric.persistence.AccumuloMapStore$Factory + 1 + 1000 + + + + + 1 + + 600 + + 3600 + com.hazelcast.spi.merge.LatestUpdateMergePolicy + true + + + + datawave.microservice.querymetric.persistence.AccumuloMapLoader$Factory + + + + clusterName: '${spring.application.name}' diff --git a/configuration/values.yaml b/configuration/values.yaml index fd3a866..c736a0d 100644 --- a/configuration/values.yaml +++ b/configuration/values.yaml @@ -1,4 +1,17 @@ global: + mysql: + user: datawave + minIdle: 10 + maxSize: 10 + configMap: + name: mysql-init-config + init: + - name: init-db + fileName: init-db.sql + fileContents: |- + create database cachedresults; + use cachedresults; + GRANT ALL PRIVILEGES ON *.* TO 'datawave'@'%' WITH GRANT OPTION; dockerRegistry: url: ghcr.io/nationalsecurityagency volumes: @@ -49,7 +62,17 @@ global: endpoint: authorization/v1/authorize rabbitmq: name: rabbitmq - + kafka: + name: kafka + port: 9092 + mysql: + name: mysql + query: + name: query + port: 8080 + metrics: + name: query-metrics + port: 8080 image: name: datawave-config-service pullPolicy: IfNotPresent diff --git a/datawave-driver.sh b/datawave-driver.sh index d53b87e..a3a238d 100755 --- a/datawave-driver.sh +++ b/datawave-driver.sh @@ -55,6 +55,8 @@ package_helm_dependencies() { local base_dir="$1" local chart_file="$base_dir"/Chart.yaml + echo "Processing $chart_file" + local dependencies=$(yq eval '.dependencies[]' "$chart_file") if [ -z "$dependencies" ]; then return diff --git a/datawave-qms-stack/.helmignore b/datawave-qms-stack/.helmignore deleted file mode 100644 index 1c1043d..0000000 --- a/datawave-qms-stack/.helmignore +++ /dev/null @@ -1,19 +0,0 @@ -########################################### -# Ignores All File or Path Related to Git # -########################################### - -.git - -##################################### -# Ignores All Development Resources # -##################################### - -development/ -setup.sh - -######################## -# Ignores All Archives # -######################## - -*.tar.gz -datawave-system-*.tgz diff --git a/datawave-qms-stack/.schema.yaml b/datawave-qms-stack/.schema.yaml deleted file mode 100644 index 546b749..0000000 --- a/datawave-qms-stack/.schema.yaml +++ /dev/null @@ -1,13 +0,0 @@ -# Required -input: - - values.yaml - -draft: 2020 -indent: 4 -output: values.schema.json - -schemaRoot: - id: https://code.nsa.org/datawave/schema - title: Helm Values Schema - description: Schema for DataWave Helm values - additionalProperties: true diff --git a/datawave-qms-stack/Chart.lock b/datawave-qms-stack/Chart.lock deleted file mode 100644 index 2e6bde4..0000000 --- a/datawave-qms-stack/Chart.lock +++ /dev/null @@ -1,21 +0,0 @@ -dependencies: -- name: dwv-ingest - repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts - version: 1.0.0 -- name: dwv-hadoop - repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts - version: 1.0.0 -- name: dwv-hadoop-config - repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts - version: 1.0.0 -- name: dwv-zookeeper - repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts - version: 1.0.0 -- name: dwv-accumulo - repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts - version: 1.0.0 -- name: datawave-qms-umbrella - repository: file://../datawave-qms-umbrella - version: 1.0.0-SNAPSHOT -digest: sha256:425b773c0ee3abf3d311df05c0213f9ba5af887792be8f8edaaf628c4ac3207a -generated: "2024-10-08T11:06:21.957957643Z" diff --git a/datawave-qms-stack/Chart.yaml b/datawave-qms-stack/Chart.yaml deleted file mode 100644 index 0c1b7a6..0000000 --- a/datawave-qms-stack/Chart.yaml +++ /dev/null @@ -1,38 +0,0 @@ -##################################### -# DataWave Helm Chart Configuration # -##################################### - -apiVersion: v2 -name: datawave-qms -type: application -version: 1.0.0-SNAPSHOT - -################################# -# Basic Metadata for this Chart # -################################# - -appVersion: 1.0.0 -description: Deploys an Entire DataWave Stack w/ Dependencies using Query Microservices -icon: https://code.nsa.gov/datawave/images/datawave-logo.png - -dependencies: - - name: dwv-ingest - repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts - version: 1.0.0 - - name: dwv-hadoop - repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts - version: 1.0.0 - condition: charts.hadoop.enabled - - name: dwv-hadoop-config - repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts - version: 1.0.0 - - name: dwv-zookeeper - repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts - version: 1.0.0 - condition: charts.zookeeper.enabled - - name: dwv-accumulo - repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts - version: 1.0.0 - - name: datawave-qms-umbrella - repository: file://../datawave-qms-umbrella - version: 1.0.0-SNAPSHOT diff --git a/datawave-qms-stack/README.md b/datawave-qms-stack/README.md deleted file mode 100644 index 19d864d..0000000 --- a/datawave-qms-stack/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# DataWave Web Helm Chart - -Manages All Helm Resources Required to Support a Deployment of DataWave Web diff --git a/datawave-qms-stack/certificates/keystore.p12 b/datawave-qms-stack/certificates/keystore.p12 deleted file mode 100644 index ee6ca90def7f6a8888e37560a8a0f1d0aed6a9d7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3586 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 WLMG(VGG1zJH>f(sOX)Tk@&5rX1>|@D diff --git a/datawave-qms-stack/templates/_helpers.tpl b/datawave-qms-stack/templates/_helpers.tpl deleted file mode 100644 index 9713615..0000000 --- a/datawave-qms-stack/templates/_helpers.tpl +++ /dev/null @@ -1,23 +0,0 @@ -{{/* vim: set filetype=mustache: */}} -{{/* -Expand the name of the chart. -*/}} -{{- define "datawave.stack.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). -*/}} -{{- define "datawave.stack.fullname" -}} -{{- $name := default .Chart.Name .Values.nameOverride -}} -{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} -{{- end -}} - -{{/* -Create chart name and version as used by the chart label. -*/}} -{{- define "datawave.stack.chart" -}} -{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} -{{- end -}} diff --git a/datawave-qms-stack/templates/hdfs.yaml b/datawave-qms-stack/templates/hdfs.yaml deleted file mode 100644 index 2c78769..0000000 --- a/datawave-qms-stack/templates/hdfs.yaml +++ /dev/null @@ -1,19 +0,0 @@ -{{- if not .Values.charts.hadoop.enabled }} -{{- with .Values.external.hdfs.hosts }} -{{- range . }} ---- -apiVersion: v1 -kind: Service -metadata: - name: {{ . }} - labels: - app: hdfs - chart: {{ include "datawave.stack.chart" $ }} - release: {{ $.Release.Name }} - app.kubernetes.io/component: {{ . }} -spec: - externalName: {{ . }} - type: ExternalName -{{- end }} -{{- end }} -{{- end }} \ No newline at end of file diff --git a/datawave-qms-stack/templates/yarn.yaml b/datawave-qms-stack/templates/yarn.yaml deleted file mode 100644 index 15a15fb..0000000 --- a/datawave-qms-stack/templates/yarn.yaml +++ /dev/null @@ -1,19 +0,0 @@ -{{- if not .Values.charts.hadoop.enabled }} -{{- with .Values.external.yarn.hosts }} -{{- range . }} ---- -apiVersion: v1 -kind: Service -metadata: - name: {{ . }} - labels: - app: yarn - chart: {{ include "datawave.stack.chart" $ }} - release: {{ $.Release.Name }} - app.kubernetes.io/component: {{ . }} -spec: - externalName: {{ . }} - type: ExternalName -{{- end }} -{{- end }} -{{- end }} diff --git a/datawave-qms-stack/templates/zookeeper.yaml b/datawave-qms-stack/templates/zookeeper.yaml deleted file mode 100644 index 83bf769..0000000 --- a/datawave-qms-stack/templates/zookeeper.yaml +++ /dev/null @@ -1,24 +0,0 @@ -{{- if not .Values.charts.zookeeper.enabled }} -{{- with .Values.external.zookeeper.hosts }} -{{- range . }} ---- -apiVersion: v1 -kind: Service -metadata: - name: {{ . }} - labels: - app: zookeeper - chart: {{ include "datawave.stack.chart" $ }} - release: {{ $.Release.Name }} - app.kubernetes.io/component: zookeeper -spec: - externalName: {{ . }} - ports: - - name: zk - port: 2181 - protocol: TCP - targetPort: 2181 - type: ExternalName -{{- end }} -{{- end }} -{{- end }} \ No newline at end of file diff --git a/datawave-qms-stack/values-testing.yaml b/datawave-qms-stack/values-testing.yaml deleted file mode 100644 index 9e9294b..0000000 --- a/datawave-qms-stack/values-testing.yaml +++ /dev/null @@ -1,8 +0,0 @@ -dwv-accumulo: - image: - tag: 2.1.3 - initContainer: - tag: 3.3.6 -dwv-hadoop: - image: - tag: 3.3.6 diff --git a/datawave-qms-stack/values.schema.json b/datawave-qms-stack/values.schema.json deleted file mode 100644 index 161c3c1..0000000 --- a/datawave-qms-stack/values.schema.json +++ /dev/null @@ -1,88 +0,0 @@ -{ - "$id": "https://code.nsa.org/datawave/schema", - "$schema": "https://json-schema.org/draft/2020-12/schema", - "additionalProperties": true, - "description": "Schema for DataWave Helm values", - "properties": { - "charts": { - "properties": { - "hadoop": { - "properties": { - "enabled": { - "type": "boolean" - } - }, - "type": "object" - }, - "zookeeper": { - "properties": { - "enabled": { - "type": "boolean" - } - }, - "type": "object" - } - }, - "type": "object" - }, - "dockerRegistry": { - "properties": { - "url": { - "type": "string" - } - }, - "type": "object" - }, - "external": { - "properties": { - "hdfs": { - "properties": { - "hosts": { - "items": { - "type": "string" - }, - "type": "array" - } - }, - "type": "object" - }, - "yarn": { - "properties": { - "hosts": { - "items": { - "type": "string" - }, - "type": "array" - } - }, - "type": "object" - }, - "zookeeper": { - "properties": { - "hosts": { - "items": { - "type": "string" - }, - "type": "array" - } - }, - "type": "object" - } - }, - "type": "object" - }, - "global": { - "properties": { - "accumuloConfigMap": { - "type": "string" - }, - "hadoopConfigMap": { - "type": "string" - } - }, - "type": "object" - } - }, - "title": "Helm Values Schema", - "type": "object" -} diff --git a/datawave-qms-stack/values.yaml b/datawave-qms-stack/values.yaml deleted file mode 100644 index dfb8f9c..0000000 --- a/datawave-qms-stack/values.yaml +++ /dev/null @@ -1,27 +0,0 @@ -###################################### -# Default Values for Docker Registry # -###################################### - -global: - hadoopConfigMap: dwv-hadoop-config - accumuloConfigMap: dwv-accumulo-config - -dockerRegistry: - url: ghcr.io/nationalsecurityagency/ -charts: - zookeeper: - enabled: true - hadoop: - enabled: true -external: - zookeeper: - hosts: - - zookeeper - hdfs: - hosts: - - hdfs-nn - - hdfs-dn - yarn: - hosts: - - yarn-rm - - yarn-nm \ No newline at end of file diff --git a/datawave-qms-umbrella/.schema.yaml b/datawave-qms-umbrella/.schema.yaml deleted file mode 100644 index 546b749..0000000 --- a/datawave-qms-umbrella/.schema.yaml +++ /dev/null @@ -1,13 +0,0 @@ -# Required -input: - - values.yaml - -draft: 2020 -indent: 4 -output: values.schema.json - -schemaRoot: - id: https://code.nsa.org/datawave/schema - title: Helm Values Schema - description: Schema for DataWave Helm values - additionalProperties: true diff --git a/datawave-qms-umbrella/Chart.lock b/datawave-qms-umbrella/Chart.lock deleted file mode 100644 index 03b34c0..0000000 --- a/datawave-qms-umbrella/Chart.lock +++ /dev/null @@ -1,42 +0,0 @@ -dependencies: -- name: dwv-audit - repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts - version: 1.0.0 -- name: dwv-authorization - repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts - version: 1.0.0 -- name: dwv-cache - repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts - version: 1.0.0 -- name: dwv-configuration - repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts - version: 1.0.0 -- name: dwv-dictionary - repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts - version: 1.0.0 -- name: dwv-executor - repository: file://../executor/ - version: 1.0.0-SNAPSHOT -- name: dwv-kafdrop - repository: file://../kafdrop - version: 1.0.0-SNAPSHOT -- name: dwv-kafka - repository: file://../kafka - version: 1.0.0-SNAPSHOT -- name: dwv-modification - repository: file://../modification - version: 1.0.0-SNAPSHOT -- name: dwv-mr-query - repository: file://../mr-query - version: 1.0.0-SNAPSHOT -- name: dwv-query - repository: file://../query - version: 1.0.0-SNAPSHOT -- name: dwv-query-metrics - repository: file://../query-metrics - version: 1.0.0-SNAPSHOT -- name: dwv-rabbitmq - repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts - version: 1.0.0 -digest: sha256:00d0cd83713ad19d971fd74c64b57032c24250c05f5ae25df1f6549261a99e4f -generated: "2024-10-08T10:51:03.152002577Z" diff --git a/datawave-qms-umbrella/Chart.yaml b/datawave-qms-umbrella/Chart.yaml deleted file mode 100644 index 4810478..0000000 --- a/datawave-qms-umbrella/Chart.yaml +++ /dev/null @@ -1,57 +0,0 @@ -##################################### -# DataWave Helm Chart Configuration # -##################################### - -apiVersion: v2 -name: datawave-qms-umbrella -type: application -version: 1.0.0-SNAPSHOT - -################################# -# Basic Metadata for this Chart # -################################# - -appVersion: 1.0.0 -description: Deploys The web stack of DataWave using Query Microservices -icon: https://code.nsa.gov/datawave/images/datawave-logo.png - -dependencies: - - name: dwv-audit - repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts - version: 1.0.0 - - name: dwv-authorization - repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts - version: 1.0.0 - - name: dwv-cache - repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts - version: 1.0.0 - - name: dwv-configuration - repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts - version: 1.0.0 - - name: dwv-dictionary - repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts - version: 1.0.0 - - name: dwv-executor - repository: file://../executor/ - version: 1.0.0-SNAPSHOT - - name: dwv-kafdrop - repository: file://../kafdrop - version: 1.0.0-SNAPSHOT - - name: dwv-kafka - repository: file://../kafka - version: 1.0.0-SNAPSHOT - - name: dwv-modification - repository: file://../modification - version: 1.0.0-SNAPSHOT - - name: dwv-mr-query - repository: file://../mr-query - version: 1.0.0-SNAPSHOT - - name: dwv-query - repository: file://../query - version: 1.0.0-SNAPSHOT - - name: dwv-query-metrics - repository: file://../query-metrics - version: 1.0.0-SNAPSHOT - - name: dwv-rabbitmq - repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts - version: 1.0.0 \ No newline at end of file diff --git a/datawave-qms-umbrella/README.md b/datawave-qms-umbrella/README.md deleted file mode 100644 index 19d864d..0000000 --- a/datawave-qms-umbrella/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# DataWave Web Helm Chart - -Manages All Helm Resources Required to Support a Deployment of DataWave Web diff --git a/datawave-qms-umbrella/values.schema.json b/datawave-qms-umbrella/values.schema.json deleted file mode 100644 index 0fde354..0000000 --- a/datawave-qms-umbrella/values.schema.json +++ /dev/null @@ -1,74 +0,0 @@ -{ - "$id": "https://code.nsa.org/datawave/schema", - "$schema": "https://json-schema.org/draft/2020-12/schema", - "additionalProperties": true, - "description": "Schema for DataWave Helm values", - "properties": { - "dockerRegistry": { - "properties": { - "url": { - "type": "string" - } - }, - "type": "object" - }, - "global": { - "properties": { - "serviceDns": { - "properties": { - "accumuloManager": { - "properties": { - "name": { - "type": "string" - } - }, - "type": "object" - }, - "authorization": { - "properties": { - "name": { - "type": "string" - } - }, - "type": "object" - }, - "cache": { - "properties": { - "name": { - "type": "string" - }, - "port": { - "type": "integer" - } - }, - "type": "object" - }, - "configuration": { - "properties": { - "name": { - "type": "string" - }, - "port": { - "type": "integer" - } - }, - "type": "object" - }, - "rabbitmq": { - "properties": { - "name": { - "type": "string" - } - }, - "type": "object" - } - }, - "type": "object" - } - }, - "type": "object" - } - }, - "title": "Helm Values Schema", - "type": "object" -} diff --git a/datawave-qms-umbrella/values.yaml b/datawave-qms-umbrella/values.yaml deleted file mode 100644 index 7d7d890..0000000 --- a/datawave-qms-umbrella/values.yaml +++ /dev/null @@ -1,22 +0,0 @@ -global: - serviceDns: - accumuloManager: - name: accumulo-manager - authorization: - name: authorization - cache: - name: cache - port: 8080 - configuration: - name: configuration - port: 8888 - rabbitmq: - name: rabbitmq - - -###################################### -# Default Values for Docker Registry # -###################################### - -dockerRegistry: - url: ghcr.io/nationalsecurityagency/ diff --git a/datawave-stack/Chart.yaml b/datawave-stack/Chart.yaml index 5cad822..52078a2 100644 --- a/datawave-stack/Chart.yaml +++ b/datawave-stack/Chart.yaml @@ -42,3 +42,38 @@ dependencies: repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts version: 1.0.0 path: ../datawave-monolith-umbrella + - name: dwv-executor + repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts + version: 1.0.0-SNAPSHOT + path: ../executor + condition: charts.qms.enabled + - name: dwv-kafdrop + repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts + version: 1.0.0-SNAPSHOT + path: ../kafdrop + condition: charts.qms.enabled + - name: dwv-kafka + repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts + version: 1.0.0-SNAPSHOT + path: ../kafka + condition: charts.qms.enabled + - name: dwv-modification + repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts + version: 1.0.0-SNAPSHOT + path: ../modification + condition: charts.qms.enabled + - name: dwv-mr-query + repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts + version: 1.0.0-SNAPSHOT + path: ../mr-query + condition: charts.qms.enabled + - name: dwv-query-metrics + repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts + version: 1.0.0-SNAPSHOT + path: ../query-metrics + condition: charts.qms.enabled + - name: dwv-query + repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts + version: 1.0.0-SNAPSHOT + path: ../query + condition: charts.qms.enabled diff --git a/datawave-stack/values.yaml b/datawave-stack/values.yaml index dfb8f9c..1861cf7 100644 --- a/datawave-stack/values.yaml +++ b/datawave-stack/values.yaml @@ -13,6 +13,8 @@ charts: enabled: true hadoop: enabled: true + qms: + enabled: true external: zookeeper: hosts: diff --git a/executor/Chart.yaml b/executor/Chart.yaml index 6356828..2d55c77 100644 --- a/executor/Chart.yaml +++ b/executor/Chart.yaml @@ -19,4 +19,5 @@ dependencies: - name: common-service-library repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts version: 0.0.2 + path: ../common-service-library diff --git a/executor/templates/accumulo-microservice-deployment.yaml b/executor/templates/accumulo-microservice-deployment.yaml index 194eb3e..afb20a8 100644 --- a/executor/templates/accumulo-microservice-deployment.yaml +++ b/executor/templates/accumulo-microservice-deployment.yaml @@ -1,5 +1,5 @@ -{{- include "common-service-library.deployment" (list . "accumuloMicroservice.deployment") -}} -{{- define "accumuloMicroservice.deployment" -}} +{{- include "common-service-library.deployment" (list . "executorService.deployment") -}} +{{- define "executorService.deployment" -}} #overrides go here spec: template: diff --git a/executor/templates/accumulo-microservice-service.yaml b/executor/templates/accumulo-microservice-service.yaml index 2bcedaa..5ca7728 100644 --- a/executor/templates/accumulo-microservice-service.yaml +++ b/executor/templates/accumulo-microservice-service.yaml @@ -1,4 +1,4 @@ -{{- include "common-service-library.service" (list . "accumuloMicroservice.service") -}} -{{- define "accumuloMicroservice.service" -}} +{{- include "common-service-library.service" (list . "executorService.service") -}} +{{- define "executorService.service" -}} #overrides go here {{- end -}} \ No newline at end of file diff --git a/executor/values.yaml b/executor/values.yaml index e71e1b7..28b9b4b 100644 --- a/executor/values.yaml +++ b/executor/values.yaml @@ -18,6 +18,7 @@ global: port: 8888 authorization: name: authorization + port: 8080 cache: name: cache port: 8080 diff --git a/hadoop-config/.helmignore b/hadoop-config/.helmignore index f0c1319..c8c5fc0 100644 --- a/hadoop-config/.helmignore +++ b/hadoop-config/.helmignore @@ -19,3 +19,5 @@ .project .idea/ *.tmproj + +dwv-*.tgz diff --git a/hadoop/.helmignore b/hadoop/.helmignore index f0c1319..001d084 100644 --- a/hadoop/.helmignore +++ b/hadoop/.helmignore @@ -19,3 +19,5 @@ .project .idea/ *.tmproj + +dwv-hadoop*.tgz \ No newline at end of file diff --git a/modification/Chart.yaml b/modification/Chart.yaml index ee1adf4..12f2eba 100644 --- a/modification/Chart.yaml +++ b/modification/Chart.yaml @@ -19,4 +19,5 @@ dependencies: - name: common-service-library repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts version: 0.0.2 + path: ../common-service-library diff --git a/modification/values.yaml b/modification/values.yaml index 3550ed8..e0413a0 100644 --- a/modification/values.yaml +++ b/modification/values.yaml @@ -18,6 +18,7 @@ global: port: 8888 authorization: name: authorization + port: 8080 cache: name: cache port: 8080 @@ -29,7 +30,7 @@ global: image: name: datawave-modification-service pullPolicy: IfNotPresent - tag: 1.0.2 + tag: latest args: - "--spring.output.ansi.enabled=ALWAYS" - "--spring.profiles.active=default,k8s,remoteauth,query" diff --git a/mr-query/Chart.yaml b/mr-query/Chart.yaml index a9ebe00..832af4c 100644 --- a/mr-query/Chart.yaml +++ b/mr-query/Chart.yaml @@ -19,4 +19,5 @@ dependencies: - name: common-service-library repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts version: 0.0.2 + path: ../common-service-library diff --git a/mr-query/values.yaml b/mr-query/values.yaml index d6931d5..d3aa5ea 100644 --- a/mr-query/values.yaml +++ b/mr-query/values.yaml @@ -18,6 +18,7 @@ global: port: 8888 authorization: name: authorization + port: 8080 cache: name: cache port: 8080 @@ -29,7 +30,7 @@ global: image: name: datawave-mapreduce-query-service pullPolicy: IfNotPresent - tag: 1.0.4 + tag: latest args: - "--spring.output.ansi.enabled=ALWAYS" - "--spring.profiles.active=default,k8s,remoteauth,query" diff --git a/query-metrics/Chart.yaml b/query-metrics/Chart.yaml index 9c41707..1018bea 100644 --- a/query-metrics/Chart.yaml +++ b/query-metrics/Chart.yaml @@ -19,4 +19,5 @@ dependencies: - name: common-service-library repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts version: 0.0.2 + path: ../common-service-library diff --git a/query-metrics/values.yaml b/query-metrics/values.yaml index 4e11960..eb16cef 100644 --- a/query-metrics/values.yaml +++ b/query-metrics/values.yaml @@ -18,6 +18,7 @@ global: port: 8888 authorization: name: authorization + port: 8080 cache: name: cache port: 8080 @@ -27,9 +28,9 @@ global: # Default Values for Audit Deployment # ####################################### image: - name: datawave-mapreduce-query-service - pullPolicy: IfNotPresent - tag: 4.0.8 + name: datawave-query-metric-service + pullPolicy: Always + tag: latest args: - "--spring.output.ansi.enabled=ALWAYS" - "--spring.profiles.active=default,k8s,remoteauth" diff --git a/query/Chart.yaml b/query/Chart.yaml index 2c3dce3..5407622 100644 --- a/query/Chart.yaml +++ b/query/Chart.yaml @@ -19,4 +19,5 @@ dependencies: - name: common-service-library repository: oci://ghcr.io/nationalsecurityagency/datawave-helm-charts/charts version: 0.0.2 + path: ../common-service-library diff --git a/query/values.yaml b/query/values.yaml index 6e930c4..50c6c30 100644 --- a/query/values.yaml +++ b/query/values.yaml @@ -18,6 +18,7 @@ global: port: 8888 authorization: name: authorization + port: 8080 cache: name: cache port: 8080 @@ -27,9 +28,9 @@ global: # Default Values for Audit Deployment # ####################################### image: - name: datawave-mapreduce-query-service + name: datawave-query-service pullPolicy: IfNotPresent - tag: 1.0.10 + tag: 1.0.11 args: - "--spring.output.ansi.enabled=ALWAYS" - "--spring.profiles.active=default,k8s,remoteauth,querymessaging,metricssource,query,mrquery,cachedresults,federation" From 18989b9b5858ab2a728df5ae185498b9617dbdc4 Mon Sep 17 00:00:00 2001 From: Adam Lerman Date: Wed, 13 Nov 2024 15:39:17 +0000 Subject: [PATCH 11/16] Intermediate commit --- configuration/configMapFiles/application.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configuration/configMapFiles/application.yml b/configuration/configMapFiles/application.yml index b2befe5..20457ce 100644 --- a/configuration/configMapFiles/application.yml +++ b/configuration/configMapFiles/application.yml @@ -51,5 +51,5 @@ spring: enforce-allowed-callers: false issuers-required: true jwt.ttl: 86400 - manager-roles: Administator,JBossAdministrator + manager-roles: Administrator,JBossAdministrator user.password: passwordNotUsed \ No newline at end of file From ca93d06f8af9d0ceeba4c52e2d0f311b335bf8eb Mon Sep 17 00:00:00 2001 From: Adam Lerman Date: Tue, 19 Nov 2024 17:26:48 +0000 Subject: [PATCH 12/16] Fix ingest if no claim --- ingest/templates/post-start-cmds_secret.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ingest/templates/post-start-cmds_secret.yaml b/ingest/templates/post-start-cmds_secret.yaml index a3cf287..61f80b9 100644 --- a/ingest/templates/post-start-cmds_secret.yaml +++ b/ingest/templates/post-start-cmds_secret.yaml @@ -32,13 +32,14 @@ echo "Create datawave tables" echo "loading job cache" /opt/datawave-ingest/current/bin/ingest/load-job-cache.sh - +{{- if (.Values.config.sharedConfig).claim }} if [[ {{ (.Values.config.sharedConfig).claim }} != "" ]]; then echo "synchronizing shared config to pvc {{ .Values.config.sharedConfig.claim }} at {{ .Values.config.sharedConfig.path }}" cp -Lr /opt/datawave-ingest/current/config/* {{ .Values.config.sharedConfig.path }} else echo "skipping shared config pvc sync" fi +{{- end }} echo "Starting datawave ingest" /opt/datawave-ingest/current/bin/system/start-all.sh From 2c2255e6db17dc15740f71a4131d25e5b91a9a05 Mon Sep 17 00:00:00 2001 From: Adam Lerman Date: Tue, 19 Nov 2024 17:27:08 +0000 Subject: [PATCH 13/16] Microservices all deploy --- audit/values.yaml | 2 ++ authorization/values.yaml | 2 ++ cache/values.yaml | 2 ++ common-service-library/templates/_deployment.yaml | 2 +- dictionary/values.yaml | 2 ++ executor/values.yaml | 4 +++- ingest/values.yaml | 7 ++----- kafdrop/templates/kafdrop-deployment.yaml | 4 ++-- kafdrop/values.yaml | 3 +++ kafka/templates/kafka-statefulset.yaml | 4 ++-- kafka/values.yaml | 5 +++++ modification/values.yaml | 2 ++ mr-query/values.yaml | 4 +++- mysql/templates/mysql-deployment.yaml | 2 +- mysql/values.yaml | 2 ++ query-metrics/values.yaml | 2 ++ query/values.yaml | 2 ++ rabbitmq/templates/rabbitmq-deployment.yaml | 2 +- rabbitmq/values.yaml | 2 ++ 19 files changed, 41 insertions(+), 14 deletions(-) diff --git a/audit/values.yaml b/audit/values.yaml index 561854d..0572668 100644 --- a/audit/values.yaml +++ b/audit/values.yaml @@ -1,4 +1,6 @@ global: + security: + userid: 1000 dockerRegistry: url: ghcr.io/nationalsecurityagency volumes: diff --git a/authorization/values.yaml b/authorization/values.yaml index f07a19b..74525d5 100644 --- a/authorization/values.yaml +++ b/authorization/values.yaml @@ -1,4 +1,6 @@ global: + security: + userid: 1000 dockerRegistry: url: ghcr.io/nationalsecurityagency volumes: diff --git a/cache/values.yaml b/cache/values.yaml index 1e22f07..fbce288 100644 --- a/cache/values.yaml +++ b/cache/values.yaml @@ -1,4 +1,6 @@ global: + security: + userid: 1000 dockerRegistry: url: ghcr.io/nationalsecurityagency volumes: diff --git a/common-service-library/templates/_deployment.yaml b/common-service-library/templates/_deployment.yaml index c2ec61e..4a751a5 100644 --- a/common-service-library/templates/_deployment.yaml +++ b/common-service-library/templates/_deployment.yaml @@ -78,7 +78,7 @@ spec: # Containers Associated with this Deployment # ############################################## securityContext: - runAsUser: 1000 + runAsUser: "{{ .Values.global.security.userid }}" containers: - name: "{{ .Values.meta.name }}" args: diff --git a/dictionary/values.yaml b/dictionary/values.yaml index 74da389..3be2905 100644 --- a/dictionary/values.yaml +++ b/dictionary/values.yaml @@ -1,4 +1,6 @@ global: + security: + userid: 1000 dockerRegistry: url: ghcr.io/nationalsecurityagency volumes: diff --git a/executor/values.yaml b/executor/values.yaml index 28b9b4b..fb54eb2 100644 --- a/executor/values.yaml +++ b/executor/values.yaml @@ -1,4 +1,6 @@ global: + security: + userid: 1000 dockerRegistry: url: ghcr.io/nationalsecurityagency volumes: @@ -30,7 +32,7 @@ global: image: name: datawave-query-executor-service pullPolicy: IfNotPresent - tag: 1.0.9 + tag: latest args: - "--spring.output.ansi.enabled=ALWAYS" - "--spring.profiles.active= default,k8s,remoteauth,querymessaging,metricssource,federation,query,pool1" diff --git a/ingest/values.yaml b/ingest/values.yaml index eeae6df..3368de0 100644 --- a/ingest/values.yaml +++ b/ingest/values.yaml @@ -35,11 +35,8 @@ config: bulkDataTypes: shardStats liveDataTypes: wikipedia,mycsv,myjson,openlib sharedConfig: - create: true - claim: datawave-ingest-config-pvc - path: /opt/datawave-ingest/current/shared-config - size: 1Gi - storageClass: "csi-hostpath-sc" + create: false + files: - name: all-config.xml diff --git a/kafdrop/templates/kafdrop-deployment.yaml b/kafdrop/templates/kafdrop-deployment.yaml index fd6e139..c93f16b 100644 --- a/kafdrop/templates/kafdrop-deployment.yaml +++ b/kafdrop/templates/kafdrop-deployment.yaml @@ -70,8 +70,8 @@ spec: {{- end }} {{- end }} securityContext: - runAsUser: 1000 - fsGroup: 1000 + runAsUser: {{ .Values.global.security.userid }} + fsGroup: {{ .Values.global.security.fsgroupid }} restartPolicy: "{{ .Values.restartPolicy }}" ############################################## # Containers Associated with this Deployment # diff --git a/kafdrop/values.yaml b/kafdrop/values.yaml index 67b46c3..f6f3a21 100644 --- a/kafdrop/values.yaml +++ b/kafdrop/values.yaml @@ -1,4 +1,7 @@ global: + security: + userid: 1000 + fsgroupid: 1000 dockerRegistry: url: ghcr.io/nationalsecurityagency volumes: diff --git a/kafka/templates/kafka-statefulset.yaml b/kafka/templates/kafka-statefulset.yaml index 22c9d97..954c554 100644 --- a/kafka/templates/kafka-statefulset.yaml +++ b/kafka/templates/kafka-statefulset.yaml @@ -65,8 +65,8 @@ spec: {{- end }} {{- end }} securityContext: - runAsUser: 1000 - fsGroup: 1000 + runAsUser: {{ .Values.global.security.userid }} + fsGroup: {{ .Values.global.security.fsgroupid }} restartPolicy: "{{ .Values.restartPolicy }}" ############################################## # Containers Associated with this Deployment # diff --git a/kafka/values.yaml b/kafka/values.yaml index 3bd8527..66bff28 100644 --- a/kafka/values.yaml +++ b/kafka/values.yaml @@ -1,3 +1,8 @@ +global: + security: + userid: 1000 + fsgroupid: 1000 + ####################################### # Default Values for Kafka Deployment # ####################################### diff --git a/modification/values.yaml b/modification/values.yaml index e0413a0..b8a59b4 100644 --- a/modification/values.yaml +++ b/modification/values.yaml @@ -1,4 +1,6 @@ global: + security: + userid: 1000 dockerRegistry: url: ghcr.io/nationalsecurityagency volumes: diff --git a/mr-query/values.yaml b/mr-query/values.yaml index d3aa5ea..20d0116 100644 --- a/mr-query/values.yaml +++ b/mr-query/values.yaml @@ -1,4 +1,6 @@ global: + security: + userid: 1000 dockerRegistry: url: ghcr.io/nationalsecurityagency volumes: @@ -33,7 +35,7 @@ image: tag: latest args: - "--spring.output.ansi.enabled=ALWAYS" -- "--spring.profiles.active=default,k8s,remoteauth,query" +- "--spring.profiles.active=default,k8s,remoteauth,query,federation" livenessProbe: delaySeconds: 20 periodSeconds: 5 diff --git a/mysql/templates/mysql-deployment.yaml b/mysql/templates/mysql-deployment.yaml index 7c48fe0..2337d80 100644 --- a/mysql/templates/mysql-deployment.yaml +++ b/mysql/templates/mysql-deployment.yaml @@ -70,7 +70,7 @@ spec: {{- end }} {{- end }} securityContext: - runAsUser: 1000 + runAsUser: {{ .Values.global.security.userid }} restartPolicy: "{{ .Values.restartPolicy }}" {{- with .Values.configMap.init }} volumes: diff --git a/mysql/values.yaml b/mysql/values.yaml index ba7d48b..78e86e8 100644 --- a/mysql/values.yaml +++ b/mysql/values.yaml @@ -1,4 +1,6 @@ global: + security: + userid: 1000 pullSecrets: - dockerconfigjson-ghcr ############################################ diff --git a/query-metrics/values.yaml b/query-metrics/values.yaml index eb16cef..df1c7cd 100644 --- a/query-metrics/values.yaml +++ b/query-metrics/values.yaml @@ -1,4 +1,6 @@ global: + security: + userid: 1000 dockerRegistry: url: ghcr.io/nationalsecurityagency volumes: diff --git a/query/values.yaml b/query/values.yaml index 50c6c30..e4916f3 100644 --- a/query/values.yaml +++ b/query/values.yaml @@ -1,4 +1,6 @@ global: + security: + userid: 1000 dockerRegistry: url: ghcr.io/nationalsecurityagency volumes: diff --git a/rabbitmq/templates/rabbitmq-deployment.yaml b/rabbitmq/templates/rabbitmq-deployment.yaml index 14d71e6..a8fe8c1 100644 --- a/rabbitmq/templates/rabbitmq-deployment.yaml +++ b/rabbitmq/templates/rabbitmq-deployment.yaml @@ -70,7 +70,7 @@ spec: {{- end }} {{- end }} securityContext: - runAsUser: 1000 + runAsUser: {{ .Values.global.security.userid }} restartPolicy: "{{ .Values.restartPolicy }}" ############################################## # Containers Associated with this Deployment # diff --git a/rabbitmq/values.yaml b/rabbitmq/values.yaml index 3b6d2ed..26e4fc1 100644 --- a/rabbitmq/values.yaml +++ b/rabbitmq/values.yaml @@ -1,4 +1,6 @@ global: + security: + userid: 1000 volumes: rabbitmq: name: rabbitmq From 41261e5f2ded06d588a8dfc0cb275e2fccb9c81d Mon Sep 17 00:00:00 2001 From: Adam Lerman Date: Tue, 26 Nov 2024 10:54:01 +0000 Subject: [PATCH 14/16] Make user ids values configurable --- common-service-library/templates/_deployment.yaml | 2 +- datawave-driver.sh | 2 +- datawave-monolith/values.yaml | 5 +++-- datawave-stack/values.yaml | 2 +- ingest/values.yaml | 2 +- kafdrop/templates/kafdrop-deployment.yaml | 4 ++-- kafka/templates/kafka-statefulset.yaml | 4 ++-- mysql/templates/mysql-deployment.yaml | 2 +- rabbitmq/templates/rabbitmq-deployment.yaml | 2 +- 9 files changed, 13 insertions(+), 12 deletions(-) diff --git a/common-service-library/templates/_deployment.yaml b/common-service-library/templates/_deployment.yaml index 4a751a5..abedecd 100644 --- a/common-service-library/templates/_deployment.yaml +++ b/common-service-library/templates/_deployment.yaml @@ -78,7 +78,7 @@ spec: # Containers Associated with this Deployment # ############################################## securityContext: - runAsUser: "{{ .Values.global.security.userid }}" + runAsUser: {{ .Values.global.security.userid }} containers: - name: "{{ .Values.meta.name }}" args: diff --git a/datawave-driver.sh b/datawave-driver.sh index a3a238d..f9608b8 100755 --- a/datawave-driver.sh +++ b/datawave-driver.sh @@ -296,7 +296,7 @@ function helm_install() { echo "Starting Helm Deployment" # shellcheck disable=SC2086 - helm -n $NAMESPACE upgrade --install dwv ${HELM_CHART} -f ${values_file:-$DATAWAVE_STACK/values.yaml} ${EXTRA_HELM_ARGS} --wait --timeout 15m0s + helm -n $NAMESPACE upgrade --install dwv ${HELM_CHART} -f ${values_file:-$DATAWAVE_STACK/values.yaml} ${EXTRA_HELM_ARGS} --wait --timeout 15m0s if [ $? -eq 0 ]; then echo "Helm install successful." else diff --git a/datawave-monolith/values.yaml b/datawave-monolith/values.yaml index a4c7b73..37d80bf 100644 --- a/datawave-monolith/values.yaml +++ b/datawave-monolith/values.yaml @@ -32,7 +32,7 @@ datawaveDeployment: image: name: datawave/webservice-kubernetes pullPolicy: Always - tag: 7.8.1 + tag: 7.10.0 livenessProbe: delaySeconds: 60 periodSeconds: 5 @@ -54,7 +54,8 @@ datawaveDeployment: revisionHistoryLimit: 10 restartPolicy: Always datawaveRuntimeConfig: - additions: "" + additions: | + /subsystem=ee/managed-executor-service=default:write-attribute(name=max-threads,value=${jboss.managed.executor.service.default.max.threads}) ####################################### # Default Values for DataWave Service # diff --git a/datawave-stack/values.yaml b/datawave-stack/values.yaml index 1861cf7..c3d9233 100644 --- a/datawave-stack/values.yaml +++ b/datawave-stack/values.yaml @@ -14,7 +14,7 @@ charts: hadoop: enabled: true qms: - enabled: true + enabled: false external: zookeeper: hosts: diff --git a/ingest/values.yaml b/ingest/values.yaml index 3368de0..fb2c367 100644 --- a/ingest/values.yaml +++ b/ingest/values.yaml @@ -8,7 +8,7 @@ fullnameOverride: "" labels: {} image: repository: ghcr.io/nationalsecurityagency/datawave/ingest-kubernetes - tag: 7.8.1 + tag: 7.10.0 pullPolicy: IfNotPresent deployment: replicaCount: 1 diff --git a/kafdrop/templates/kafdrop-deployment.yaml b/kafdrop/templates/kafdrop-deployment.yaml index c93f16b..4f9353e 100644 --- a/kafdrop/templates/kafdrop-deployment.yaml +++ b/kafdrop/templates/kafdrop-deployment.yaml @@ -70,8 +70,8 @@ spec: {{- end }} {{- end }} securityContext: - runAsUser: {{ .Values.global.security.userid }} - fsGroup: {{ .Values.global.security.fsgroupid }} + runAsUser: {{ .Values.global.security.userid | int64 }} + fsGroup: {{ .Values.global.security.fsgroupid | int64 }} restartPolicy: "{{ .Values.restartPolicy }}" ############################################## # Containers Associated with this Deployment # diff --git a/kafka/templates/kafka-statefulset.yaml b/kafka/templates/kafka-statefulset.yaml index 954c554..25b4aa6 100644 --- a/kafka/templates/kafka-statefulset.yaml +++ b/kafka/templates/kafka-statefulset.yaml @@ -65,8 +65,8 @@ spec: {{- end }} {{- end }} securityContext: - runAsUser: {{ .Values.global.security.userid }} - fsGroup: {{ .Values.global.security.fsgroupid }} + runAsUser: {{ .Values.global.security.userid | int64 }} + fsGroup: {{ .Values.global.security.fsgroupid | int64 }} restartPolicy: "{{ .Values.restartPolicy }}" ############################################## # Containers Associated with this Deployment # diff --git a/mysql/templates/mysql-deployment.yaml b/mysql/templates/mysql-deployment.yaml index 2337d80..1231b41 100644 --- a/mysql/templates/mysql-deployment.yaml +++ b/mysql/templates/mysql-deployment.yaml @@ -70,7 +70,7 @@ spec: {{- end }} {{- end }} securityContext: - runAsUser: {{ .Values.global.security.userid }} + runAsUser: {{ .Values.global.security.userid | int64 }} restartPolicy: "{{ .Values.restartPolicy }}" {{- with .Values.configMap.init }} volumes: diff --git a/rabbitmq/templates/rabbitmq-deployment.yaml b/rabbitmq/templates/rabbitmq-deployment.yaml index a8fe8c1..06bbe95 100644 --- a/rabbitmq/templates/rabbitmq-deployment.yaml +++ b/rabbitmq/templates/rabbitmq-deployment.yaml @@ -70,7 +70,7 @@ spec: {{- end }} {{- end }} securityContext: - runAsUser: {{ .Values.global.security.userid }} + runAsUser: {{ .Values.global.security.userid | int64 }} restartPolicy: "{{ .Values.restartPolicy }}" ############################################## # Containers Associated with this Deployment # From 1a5c93676c7c5905ce97fe13b574ea55efbf6882 Mon Sep 17 00:00:00 2001 From: Adam Lerman Date: Tue, 26 Nov 2024 19:18:24 +0000 Subject: [PATCH 15/16] Update items --- datawave-monolith/values.yaml | 4 ++-- datawave-stack/values.yaml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/datawave-monolith/values.yaml b/datawave-monolith/values.yaml index 37d80bf..0721d4e 100644 --- a/datawave-monolith/values.yaml +++ b/datawave-monolith/values.yaml @@ -36,7 +36,7 @@ datawaveDeployment: livenessProbe: delaySeconds: 60 periodSeconds: 5 - port: 8080 + port: 8080 scheme: HTTP uri: DataWave/Common/Health/health readinessProbe: @@ -55,7 +55,7 @@ datawaveDeployment: restartPolicy: Always datawaveRuntimeConfig: additions: | - /subsystem=ee/managed-executor-service=default:write-attribute(name=max-threads,value=${jboss.managed.executor.service.default.max.threads}) + /subsystem=ee/managed-executor-service=default:write-attribute(name=max-threads,value=64) ####################################### # Default Values for DataWave Service # diff --git a/datawave-stack/values.yaml b/datawave-stack/values.yaml index c3d9233..3e2f6c5 100644 --- a/datawave-stack/values.yaml +++ b/datawave-stack/values.yaml @@ -26,4 +26,4 @@ external: yarn: hosts: - yarn-rm - - yarn-nm \ No newline at end of file + - yarn-nm From 48da888cf0db210998050464d673a9ccf222a18f Mon Sep 17 00:00:00 2001 From: Adam Lerman Date: Fri, 6 Dec 2024 12:00:45 +0000 Subject: [PATCH 16/16] Various MS changes. Enable debug --- .../templates/_deployment.yaml | 6 +++ configuration/configMapFiles/accumulo.yml | 2 +- configuration/configMapFiles/query.yml | 2 +- datawave-driver.sh | 2 + datawave-stack/values-testing.yaml | 1 + datawave-stack/values.yaml | 12 +++++ kafdrop/templates/kafdrop-deployment.yaml | 3 ++ kafdrop/values.yaml | 4 ++ query/templates/query-ingress.yaml | 45 +++++++++++++++++++ query/values.yaml | 6 +++ 10 files changed, 81 insertions(+), 2 deletions(-) create mode 100644 query/templates/query-ingress.yaml diff --git a/common-service-library/templates/_deployment.yaml b/common-service-library/templates/_deployment.yaml index abedecd..7868ebc 100644 --- a/common-service-library/templates/_deployment.yaml +++ b/common-service-library/templates/_deployment.yaml @@ -81,6 +81,12 @@ spec: runAsUser: {{ .Values.global.security.userid }} containers: - name: "{{ .Values.meta.name }}" + command: + {{ if .Values.command }} + {{- range $i, $value := .Values.command }} + - {{ $value }} + {{- end }} + {{- end }} args: {{- range $i, $value := .Values.args }} - {{ $value }} diff --git a/configuration/configMapFiles/accumulo.yml b/configuration/configMapFiles/accumulo.yml index 3a1f087..4d01c5f 100644 --- a/configuration/configMapFiles/accumulo.yml +++ b/configuration/configMapFiles/accumulo.yml @@ -15,7 +15,7 @@ accumulo: audit-client: discovery: enabled: false - uri: '${AUDIT_SERVER_URL:http://localhost:11111/audit}' + uri: '${AUDIT_SERVER_URL:http://audit-service:8080/audit}' datawave: swagger: diff --git a/configuration/configMapFiles/query.yml b/configuration/configMapFiles/query.yml index c8ee1de..edb086f 100755 --- a/configuration/configMapFiles/query.yml +++ b/configuration/configMapFiles/query.yml @@ -71,4 +71,4 @@ datawave: audit-client: discovery: enabled: false - uri: '${AUDIT_SERVER_URL:http://localhost:11111/audit}' + uri: '${AUDIT_SERVER_URL:http://audit-service:8080/audit}' diff --git a/datawave-driver.sh b/datawave-driver.sh index f9608b8..20d1f96 100755 --- a/datawave-driver.sh +++ b/datawave-driver.sh @@ -262,11 +262,13 @@ function update_hosts_file_for_hadoop() { function configure_etc_hosts(){ sudo sed -i "/^$/d" /etc/hosts sudo sed -i "/.*datawave\.org.*/d" /etc/hosts + sudo sed -i "/.*microwave\.org.*/d" /etc/hosts sudo sed -i "/.*zookeeper.*/d" /etc/hosts sudo sed -i "/.*hdfs.*/d" /etc/hosts sudo sed -i "/.*yarn.*/d" /etc/hosts echo "$(minikube ip) accumulo.datawave.org" | sudo tee -a /etc/hosts echo "$(minikube ip) web.datawave.org" | sudo tee -a /etc/hosts + echo "$(minikube ip) query.microwave.org" | sudo tee -a /etc/hosts echo "$(minikube ip) dictionary.datawave.org" | sudo tee -a /etc/hosts if ${USE_EXISTING_ZOOKEEPER}; then diff --git a/datawave-stack/values-testing.yaml b/datawave-stack/values-testing.yaml index 9e9294b..05f4aab 100644 --- a/datawave-stack/values-testing.yaml +++ b/datawave-stack/values-testing.yaml @@ -6,3 +6,4 @@ dwv-accumulo: dwv-hadoop: image: tag: 3.3.6 + diff --git a/datawave-stack/values.yaml b/datawave-stack/values.yaml index 3e2f6c5..aed7479 100644 --- a/datawave-stack/values.yaml +++ b/datawave-stack/values.yaml @@ -27,3 +27,15 @@ external: hosts: - yarn-rm - yarn-nm +dwv-query: + command: + - java + - -agentlib:jdwp=transport=dt_socket,server=y,address=5005,suspend=n + - -jar + - app.jar +dwv-executor: + command: + - java + - -agentlib:jdwp=transport=dt_socket,server=y,address=5005,suspend=n + - -jar + - app.jar diff --git a/kafdrop/templates/kafdrop-deployment.yaml b/kafdrop/templates/kafdrop-deployment.yaml index 4f9353e..6616004 100644 --- a/kafdrop/templates/kafdrop-deployment.yaml +++ b/kafdrop/templates/kafdrop-deployment.yaml @@ -83,3 +83,6 @@ spec: image: "{{ .Values.image.name }}:{{ .Values.image.tag }}" imagePullPolicy: "{{ .Values.image.pullPolicy }}" resources: {} + env: + - name: KAFKA_BROKERCONNECT + value: {{.Values.global.serviceDns.kafka.name }}:{{.Values.global.serviceDns.kafka.port }} diff --git a/kafdrop/values.yaml b/kafdrop/values.yaml index f6f3a21..e78f658 100644 --- a/kafdrop/values.yaml +++ b/kafdrop/values.yaml @@ -15,6 +15,10 @@ global: certSecretName: certificates-secret pullSecrets: - dockerconfigjson-ghcr + serviceDns: + kafka: + name: kafka + port: 9092 ####################################### # Default Values for Audit Deployment # diff --git a/query/templates/query-ingress.yaml b/query/templates/query-ingress.yaml new file mode 100644 index 0000000..a523e1a --- /dev/null +++ b/query/templates/query-ingress.yaml @@ -0,0 +1,45 @@ +#################################### +# Core Helm Template Configuration # +#################################### +{{- if .Values.global.ingress.enabled }} +apiVersion: networking.k8s.io/v1 +kind: Ingress + +###################################### +# Basic Metadata for this Deployment # +###################################### + +metadata: + name: "{{ .Chart.Name }}-qms-ingress" + annotations: + {{- with .Values.global.ingress.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + +#################################### +# Ingress Controller Specification # +#################################### + +spec: + + ################################################ + # Transport-Layer Security (TLS) Configuration # + ################################################ + + + ######################################### + # Ingress Controller Rule Configuration # + ######################################### + ingressClassName: "{{ .Values.global.ingress.ingressClassName }}" + rules: + - host: "{{ .Values.global.ingress.domain }}" + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: "{{ .Values.service.name }}" + port: + number: {{ .Values.ports.https }} +{{- end }} diff --git a/query/values.yaml b/query/values.yaml index e4916f3..44fa85c 100644 --- a/query/values.yaml +++ b/query/values.yaml @@ -1,4 +1,10 @@ global: + ingress: + enabled: true + annotations: + nginx.ingress.kubernetes.io/ssl-passthrough: "true" + ingressClassName: nginx + domain: "query.microwave.org" security: userid: 1000 dockerRegistry:
  • Accumulo
  • Accumulo