From df3c757141636528889180d1ea7f82d8aada834f Mon Sep 17 00:00:00 2001 From: subhamkrai Date: Thu, 27 Feb 2025 09:44:29 +0530 Subject: [PATCH 01/16] ci: push rook image to other oci like quay,ghcr currently rook images are only available in docker, let's start pushing rook images to quay.io and ghcr.io as well. Signed-off-by: subhamkrai --- .github/workflows/push-build.yaml | 14 ++++++++++++++ build/release/Makefile | 10 ++++++++-- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/.github/workflows/push-build.yaml b/.github/workflows/push-build.yaml index f850b4512f33..feca831b672a 100644 --- a/.github/workflows/push-build.yaml +++ b/.github/workflows/push-build.yaml @@ -41,6 +41,20 @@ jobs: username: ${{ secrets.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_PASSWORD }} + - name: Login to Quay.io + uses: docker/login-action@v3 + with: + registry: quay.io + username: ${{ secrets.QUAY_USERNAME }} + password: ${{ secrets.QUAY_ROBOT_TOKEN }} + + - name: Login to GitHub Container Registry + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GIT_API_TOKEN }} + - name: Configure AWS Credentials uses: aws-actions/configure-aws-credentials@4fc4975a852c8cd99761e2de1f4ba73402e44dd9 # v4.0.3 with: diff --git a/build/release/Makefile b/build/release/Makefile index e8b592306935..efb068736c18 100644 --- a/build/release/Makefile +++ b/build/release/Makefile @@ -66,8 +66,10 @@ FLAVORS ?= output override BRANCH_NAME := pr/$(BRANCH_NAME) endif -DOCKER_REGISTRY ?= rook -REGISTRIES ?= $(DOCKER_REGISTRY) +DOCKER_REGISTRY ?= docker.io/rook +QUAY_REGISTRY ?= quay.io/rook +GHCR_REGISTRY ?= ghcr.io/rook +REGISTRIES ?= $(DOCKER_REGISTRY) $(QUAY_REGISTRY) $(GHCR_REGISTRY) IMAGE_ARCHS := $(subst linux_,,$(filter linux_%,$(PLATFORMS))) IMAGE_PLATFORMS := $(subst _,/,$(subst $(SPACE),$(COMMA),$(filter linux_%,$(PLATFORMS)))) IMAGE_PLATFORMS_COMMA := $(shell echo "$(IMAGE_PLATFORMS)" | sed 's/ /,/g' | sed 's/.$$//') @@ -191,10 +193,14 @@ $(foreach r,$(REGISTRIES), $(foreach i,$(IMAGES), $(foreach a,$(IMAGE_ARCHS),$(e publish.manifest.image.%: publish.all.images $(MANIFEST_TOOL) $(MANIFEST_TOOL) push from-args --platforms $(IMAGE_PLATFORMS_COMMA) --template $(DOCKER_REGISTRY)/$*-ARCH:$(VERSION) --target $(DOCKER_REGISTRY)/$*:$(VERSION) + $(MANIFEST_TOOL) push from-args --platforms $(IMAGE_PLATFORMS_COMMA) --template $(QUAY_REGISTRY)/$*-ARCH:$(VERSION) --target $(QUAY_REGISTRY)/$*:$(VERSION) + $(MANIFEST_TOOL) push from-args --platforms $(IMAGE_PLATFORMS_COMMA) --template $(GHCR_REGISTRY)/$*-ARCH:$(VERSION) --target $(GHCR_REGISTRY)/$*:$(VERSION) # add the "master" tag to the master image, but do not add the "release" tag for the release channel promote.manifest.image.%: promote.all.images $(MANIFEST_TOOL) [ "$(CHANNEL)" = "release" ] || $(MANIFEST_TOOL) push from-args --platforms $(IMAGE_PLATFORMS_COMMA) --template $(DOCKER_REGISTRY)/$*-ARCH:$(VERSION) --target $(DOCKER_REGISTRY)/$*:$(CHANNEL) + [ "$(CHANNEL)" = "release" ] || $(MANIFEST_TOOL) push from-args --platforms $(IMAGE_PLATFORMS_COMMA) --template $(QUAY_REGISTRY)/$*-ARCH:$(VERSION) --target $(QUAY_REGISTRY)/$*:$(CHANNEL) + [ "$(CHANNEL)" = "release" ] || $(MANIFEST_TOOL) push from-args --platforms $(IMAGE_PLATFORMS_COMMA) --template $(GHCR_REGISTRY)/$*-ARCH:$(VERSION) --target $(GHCR_REGISTRY)/$*:$(CHANNEL) build.images: build.all.images publish.images: $(addprefix publish.manifest.image.,$(IMAGES)) From 3f1d0b192a79629cc4a81870c9c3777da488091c Mon Sep 17 00:00:00 2001 From: subhamkrai Date: Fri, 28 Feb 2025 17:13:38 +0530 Subject: [PATCH 02/16] ci: update python version in push build runner currently push-build runner is having python version 3.9 and some of the dependencies are failing when trying to install with pip upgrading to 3.13(latest) fixed the issue. Signed-off-by: subhamkrai --- .github/workflows/push-build.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/push-build.yaml b/.github/workflows/push-build.yaml index 25c9dc10c3d2..eaf30d2110e1 100644 --- a/.github/workflows/push-build.yaml +++ b/.github/workflows/push-build.yaml @@ -54,6 +54,10 @@ jobs: echo "BRANCH_NAME=${GITHUB_REF##*/}" >> $GITHUB_ENV echo "GITHUB_REF"=${GITHUB_REF} >> $GITHUB_ENV + - uses: actions/setup-python@42375524e23c412d93fb67b49958b491fce71c38 # v5.4.0 + with: + python-version: 3.13 + - name: Install dependencies run: | python3 -m pip install --upgrade pip setuptools wheel From 3017a7e736f7fa4f0baf13bdbb89557fe5ed9c99 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Mar 2025 12:50:43 +0000 Subject: [PATCH 03/16] build(deps): bump docker/setup-qemu-action from 3.4.0 to 3.6.0 Bumps [docker/setup-qemu-action](https://github.com/docker/setup-qemu-action) from 3.4.0 to 3.6.0. - [Release notes](https://github.com/docker/setup-qemu-action/releases) - [Commits](https://github.com/docker/setup-qemu-action/compare/4574d27a4764455b42196d70a065bc6853246a25...29109295f81e9208d7d86ff1c6c12d2833863392) --- updated-dependencies: - dependency-name: docker/setup-qemu-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- .github/workflows/build.yml | 2 +- .github/workflows/push-build.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index b83cca11828a..6b3a05bff36b 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -84,7 +84,7 @@ jobs: go-version: ${{ matrix.go-version }} - name: set up QEMU - uses: docker/setup-qemu-action@4574d27a4764455b42196d70a065bc6853246a25 # master + uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 # master with: platforms: all diff --git a/.github/workflows/push-build.yaml b/.github/workflows/push-build.yaml index 25c9dc10c3d2..c63ed90901c8 100644 --- a/.github/workflows/push-build.yaml +++ b/.github/workflows/push-build.yaml @@ -31,7 +31,7 @@ jobs: # docker/setup-qemu action installs QEMU static binaries, which are used to run builders for architectures other than the host. - name: set up QEMU - uses: docker/setup-qemu-action@4574d27a4764455b42196d70a065bc6853246a25 # master + uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 # master with: platforms: all From a3bde46ad36e3ee595e1f9b6c9efc4e978af2d0a Mon Sep 17 00:00:00 2001 From: parth-gr Date: Mon, 3 Mar 2025 18:34:27 +0530 Subject: [PATCH 04/16] ci: update the python black package in the ci lint file, we use a dependency from a 3rd party lint, which updates the black package, The underlined python script file was not updated to the latest formatting, so re-format the file and update the 3rd party dependency version Signed-off-by: parth-gr --- .github/workflows/linters.yaml | 2 +- deploy/examples/create-external-cluster-resources-tests.py | 2 +- deploy/examples/create-external-cluster-resources.py | 2 +- tests/scripts/pythonwebserver/server.py | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/linters.yaml b/.github/workflows/linters.yaml index db72d3c18224..970163609ce5 100644 --- a/.github/workflows/linters.yaml +++ b/.github/workflows/linters.yaml @@ -61,4 +61,4 @@ jobs: run: make pylint - name: Setup black for py - uses: psf/black@1b2427a2b785cc4aac97c19bb4b9a0de063f9547 # stable + uses: psf/black@8a737e727ac5ab2f1d4cf5876720ed276dc8dc4b # stable diff --git a/deploy/examples/create-external-cluster-resources-tests.py b/deploy/examples/create-external-cluster-resources-tests.py index b3a5196c7493..8c1feecf9f28 100644 --- a/deploy/examples/create-external-cluster-resources-tests.py +++ b/deploy/examples/create-external-cluster-resources-tests.py @@ -3,7 +3,7 @@ Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at - http://www.apache.org/licenses/LICENSE-2.0 + http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. diff --git a/deploy/examples/create-external-cluster-resources.py b/deploy/examples/create-external-cluster-resources.py index 38a567d8d4eb..a2f84eb50e5f 100644 --- a/deploy/examples/create-external-cluster-resources.py +++ b/deploy/examples/create-external-cluster-resources.py @@ -5,7 +5,7 @@ you may not use this file except in compliance with the License. You may obtain a copy of the License at - http://www.apache.org/licenses/LICENSE-2.0 + http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, diff --git a/tests/scripts/pythonwebserver/server.py b/tests/scripts/pythonwebserver/server.py index eb2c841b0c69..6f0960310915 100644 --- a/tests/scripts/pythonwebserver/server.py +++ b/tests/scripts/pythonwebserver/server.py @@ -5,7 +5,7 @@ you may not use this file except in compliance with the License. You may obtain a copy of the License at - http://www.apache.org/licenses/LICENSE-2.0 + http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, From 3b2e6f5bf629283d51d8a309474aef9e020b9b1c Mon Sep 17 00:00:00 2001 From: Artem Torubarov Date: Wed, 19 Feb 2025 12:29:13 +0100 Subject: [PATCH 05/16] object: allow overriding rgw config value from secret Implements #15422 Extends existing ObjectStore configuration options with rgwConfigFromSecret allowing to refer config value from kubernetes secret. Signed-off-by: Artem Torubarov --- .../Object-Storage/ceph-object-store-crd.md | 37 +++++++++++++- Documentation/CRDs/specification.md | 17 +++++++ .../charts/rook-ceph/templates/resources.yaml | 30 ++++++++++++ deploy/examples/crds.yaml | 30 ++++++++++++ pkg/apis/ceph.rook.io/v1/types.go | 8 +++ .../ceph.rook.io/v1/zz_generated.deepcopy.go | 7 +++ pkg/operator/ceph/object/config.go | 30 +++++++++++- pkg/operator/ceph/object/config_test.go | 49 +++++++++++++++++++ 8 files changed, 205 insertions(+), 3 deletions(-) diff --git a/Documentation/CRDs/Object-Storage/ceph-object-store-crd.md b/Documentation/CRDs/Object-Storage/ceph-object-store-crd.md index cd883983621e..542579d165ab 100644 --- a/Documentation/CRDs/Object-Storage/ceph-object-store-crd.md +++ b/Documentation/CRDs/Object-Storage/ceph-object-store-crd.md @@ -390,6 +390,10 @@ spec: debug_rgw: "10" # int # debug-rgw: "20" # equivalent config keys can have dashes or underscores rgw_s3_auth_use_ldap: "true" # bool + rgwConfigFromSecret: + rgw_keystone_barbican_password: # name of rgw option with secret value + name: "barbican-secret" # name of K8s secret + key: "password" # key of secret value in K8s secret.Data map[string]string rgwCommandFlags: rgw_dmclock_auth_res: "100.0" # float rgw_d4n_l1_datacache_persistent_path: /var/log/rook/rgwd4ncache # string @@ -397,12 +401,13 @@ spec: ``` * `rgwConfig` - These configurations are applied and modified at runtime, without RGW restart. +* `rgwConfigFromSecret` - same as `rgwConfig` but config value is referenced from k8s secret. * `rgwCommandFlags` - These configurations are applied as CLI arguments and result in RGW daemons restarting when updates are applied. Restarts are desired behavior for some RGW configs. !!! note - Once an `rgwConfig` is set, it will not be removed from Ceph's central config store when removed - from the `rgwConfig` spec. Be sure to specifically set values back to their defaults once done. + Once an `rgwConfig` or `rgwConfigFromSecret` is set, it will not be removed from Ceph's central config store when removed + from the `rgwConfig` or `rgwConfigFromSecret` spec. Be sure to specifically set values back to their defaults once done. With this in mind, `rgwCommandFlags` may be a better choice for temporary config values like debug levels. @@ -455,6 +460,34 @@ data: "bindpass.secret": aGVsbG8ud29ybGQK # hello.world ``` +### Example - usage with `rgwConfigFromSecret` + +The sample configuration below demonstrates how to securely handle secret configuration parameters when setting up RGW for [Barbican integration](https://docs.ceph.com/en/reef/radosgw/config-ref/#barbican-settings). + +```yaml + # ... + gateway: + # ... + rgwConfig: + rgw_barbican_url: "http://barbican.example.com:9311" + rgw_keystone_barbican_domain: "domain" + rgw_keystone_barbican_project: "project" + rgw_keystone_barbican_user: "user" + rgwConfigFromSecret: + rgw_keystone_barbican_password: + name: "barbican-secret" + key: "password" +--- +apiVersion: v1 +kind: Secret +metadata: + name: barbican-secret + namespace: rook-ceph +type: Opaque +data: + "password": aGVsbG8ud29ybGQK # hello.world +``` + ## Deleting a CephObjectStore During deletion of a CephObjectStore resource, Rook protects against accidental or premature diff --git a/Documentation/CRDs/specification.md b/Documentation/CRDs/specification.md index 99e2000fda64..deeee089b417 100644 --- a/Documentation/CRDs/specification.md +++ b/Documentation/CRDs/specification.md @@ -7203,6 +7203,23 @@ applied. Use with caution.

+rgwConfigFromSecret
+ + +map[string]k8s.io/api/core/v1.SecretKeySelector + + + + +(Optional) +

RgwConfigFromSecret works exactly like RgwConfig but takes config value from Secret Key reference. +Values are modified at runtime without RGW restart. +This feature is intended for advanced users. It allows breaking configurations to be easily +applied. Use with caution.

+ + + + rgwCommandFlags
map[string]string diff --git a/deploy/charts/rook-ceph/templates/resources.yaml b/deploy/charts/rook-ceph/templates/resources.yaml index 53a806f02161..5deee93f9b64 100644 --- a/deploy/charts/rook-ceph/templates/resources.yaml +++ b/deploy/charts/rook-ceph/templates/resources.yaml @@ -11953,6 +11953,36 @@ spec: applied. Use with caution. nullable: true type: object + rgwConfigFromSecret: + additionalProperties: + description: SecretKeySelector selects a key of a Secret. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + description: |- + RgwConfigFromSecret works exactly like RgwConfig but takes config value from Secret Key reference. + Values are modified at runtime without RGW restart. + This feature is intended for advanced users. It allows breaking configurations to be easily + applied. Use with caution. + nullable: true + type: object securePort: description: The port the rgw service will be listening on (https) format: int32 diff --git a/deploy/examples/crds.yaml b/deploy/examples/crds.yaml index 25b576af41a1..327b8e363ff0 100644 --- a/deploy/examples/crds.yaml +++ b/deploy/examples/crds.yaml @@ -11944,6 +11944,36 @@ spec: applied. Use with caution. nullable: true type: object + rgwConfigFromSecret: + additionalProperties: + description: SecretKeySelector selects a key of a Secret. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + description: |- + RgwConfigFromSecret works exactly like RgwConfig but takes config value from Secret Key reference. + Values are modified at runtime without RGW restart. + This feature is intended for advanced users. It allows breaking configurations to be easily + applied. Use with caution. + nullable: true + type: object securePort: description: The port the rgw service will be listening on (https) format: int32 diff --git a/pkg/apis/ceph.rook.io/v1/types.go b/pkg/apis/ceph.rook.io/v1/types.go index de8c70cceac9..586a3fe077c0 100755 --- a/pkg/apis/ceph.rook.io/v1/types.go +++ b/pkg/apis/ceph.rook.io/v1/types.go @@ -1748,6 +1748,14 @@ type GatewaySpec struct { // +optional RgwConfig map[string]string `json:"rgwConfig,omitempty"` + // RgwConfigFromSecret works exactly like RgwConfig but takes config value from Secret Key reference. + // Values are modified at runtime without RGW restart. + // This feature is intended for advanced users. It allows breaking configurations to be easily + // applied. Use with caution. + // +nullable + // +optional + RgwConfigFromSecret map[string]v1.SecretKeySelector `json:"rgwConfigFromSecret,omitempty"` + // RgwCommandFlags sets Ceph RGW config values for the gateway clients that serve this object // store. Values are modified at RGW startup, resulting in RGW pod restarts. // This feature is intended for advanced users. It allows breaking configurations to be easily diff --git a/pkg/apis/ceph.rook.io/v1/zz_generated.deepcopy.go b/pkg/apis/ceph.rook.io/v1/zz_generated.deepcopy.go index 90d36b973859..7065861a7a05 100644 --- a/pkg/apis/ceph.rook.io/v1/zz_generated.deepcopy.go +++ b/pkg/apis/ceph.rook.io/v1/zz_generated.deepcopy.go @@ -2743,6 +2743,13 @@ func (in *GatewaySpec) DeepCopyInto(out *GatewaySpec) { (*out)[key] = val } } + if in.RgwConfigFromSecret != nil { + in, out := &in.RgwConfigFromSecret, &out.RgwConfigFromSecret + *out = make(map[string]corev1.SecretKeySelector, len(*in)) + for key, val := range *in { + (*out)[key] = *val.DeepCopy() + } + } if in.RgwCommandFlags != nil { in, out := &in.RgwCommandFlags, &out.RgwCommandFlags *out = make(map[string]string, len(*in)) diff --git a/pkg/operator/ceph/object/config.go b/pkg/operator/ceph/object/config.go index 8c3608f2bf98..73044203c194 100644 --- a/pkg/operator/ceph/object/config.go +++ b/pkg/operator/ceph/object/config.go @@ -27,6 +27,7 @@ import ( cephconfig "github.com/rook/rook/pkg/operator/ceph/config" "github.com/rook/rook/pkg/operator/ceph/config/keyring" v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) const ( @@ -215,12 +216,39 @@ func (c *clusterConfig) generateMonConfigOptions(rgwConfig *rgwConfig) (map[stri for flag, val := range c.store.Spec.Gateway.RgwConfig { if currVal, ok := configOptions[flag]; ok { // RGW might break with some user-specified config overrides; log clearly to help triage - logger.Infof("overriding object store %q RGW config option %q (current value %q) with user-specified rgwConfig %q", + logger.Infof("overriding object store %q RGW config option %q with user-specified rgwConfig", + fmt.Sprintf("%s/%s", c.store.Namespace, c.store.Name), flag) + logger.Debugf("overriding object store %q RGW config option %q (current value %q) with user-specified rgwConfig %q", fmt.Sprintf("%s/%s", c.store.Namespace, c.store.Name), flag, currVal, val) } configOptions[flag] = val } + for flag, val := range c.store.Spec.Gateway.RgwConfigFromSecret { + if val.Key == "" || val.Name == "" { + logger.Warningf("invalid object store %q rgwConfigFromSecret value %q=%+v", fmt.Sprintf("%s/%s", c.store.Namespace, c.store.Name), flag, val) + continue + } + secret, err := c.context.Clientset.CoreV1().Secrets(c.clusterInfo.Namespace).Get(c.clusterInfo.Context, val.Name, metav1.GetOptions{}) + if err != nil { + return nil, fmt.Errorf("unable to lookup secret for object store %q rgwConfigFromSecret %q=%+v", fmt.Sprintf("%s/%s", c.store.Namespace, c.store.Name), flag, val) + } + secretVal, ok := secret.Data[val.Key] + if !ok { + return nil, fmt.Errorf("unable to lookup secret for object store %q rgwConfigFromSecret %q: key %q not found in secret %q", + fmt.Sprintf("%s/%s", c.store.Namespace, c.store.Name), flag, val.Key, val.Name) + } + + if currVal, ok := configOptions[flag]; ok { + // RGW might break with some user-specified config overrides; log clearly to help triage + logger.Infof("overriding object store %q RGW config option %q with user-specified rgwConfigFromSecret", + fmt.Sprintf("%s/%s", c.store.Namespace, c.store.Name), flag) + logger.Debugf("overriding object store %q RGW config option %q (current value %q) with user-specified rgwConfigFromSecret %q", + fmt.Sprintf("%s/%s", c.store.Namespace, c.store.Name), flag, currVal, secretVal) + } + configOptions[flag] = string(secretVal) + } + return configOptions, nil } diff --git a/pkg/operator/ceph/object/config_test.go b/pkg/operator/ceph/object/config_test.go index f146ce6175c8..21ae599c6a27 100644 --- a/pkg/operator/ceph/object/config_test.go +++ b/pkg/operator/ceph/object/config_test.go @@ -17,6 +17,7 @@ limitations under the License. package object import ( + "context" "testing" cephv1 "github.com/rook/rook/pkg/apis/ceph.rook.io/v1" @@ -25,6 +26,8 @@ import ( cephver "github.com/rook/rook/pkg/operator/ceph/version" "github.com/rook/rook/pkg/operator/test" "github.com/stretchr/testify/assert" + v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) func newConfig(t *testing.T) *clusterConfig { @@ -182,3 +185,49 @@ func Test_clusterConfig_generateMonConfigOptions(t *testing.T) { }) } } + +func TestRgwConfigFromSecret(t *testing.T) { + objContext := &Context{ + Context: &clusterd.Context{ + Clientset: test.New(t, 3), + }, + clusterInfo: cephclient.AdminTestClusterInfo("rook-ceph"), + } + + objectStore := simpleStore() + objectStore.Spec.Gateway.RgwConfigFromSecret = map[string]v1.SecretKeySelector{ + "rgw_secret_conf_name": { + LocalObjectReference: v1.LocalObjectReference{ + Name: "my-secret", + }, + Key: "secKey", + }, + } + + c := &clusterConfig{ + store: objectStore, + context: objContext.Context, + clusterInfo: objContext.clusterInfo, + } + + rgwConfig := &rgwConfig{} + + _, err := c.generateMonConfigOptions(rgwConfig) + assert.Error(t, err, "error if secret not exists") + + s := &v1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: "my-secret", + Namespace: "rook-ceph", + }, + Data: map[string][]byte{ + "secKey": []byte("secVal"), + }, + } + _, err = objContext.Context.Clientset.CoreV1().Secrets(objContext.clusterInfo.Namespace).Create(context.TODO(), s, metav1.CreateOptions{}) + assert.NoError(t, err, "create secret") + + got, err := c.generateMonConfigOptions(rgwConfig) + assert.NoError(t, err) + assert.EqualValues(t, "secVal", got["rgw_secret_conf_name"]) +} From 81d0f69aaec8410ff9ad7c13e72070337bc9dd97 Mon Sep 17 00:00:00 2001 From: Artem Torubarov Date: Tue, 25 Feb 2025 14:17:49 +0100 Subject: [PATCH 06/16] object: change log level for config from secret Signed-off-by: Artem Torubarov --- .../CRDs/Object-Storage/ceph-object-store-crd.md | 8 ++++---- pkg/operator/ceph/object/config.go | 7 +++---- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/Documentation/CRDs/Object-Storage/ceph-object-store-crd.md b/Documentation/CRDs/Object-Storage/ceph-object-store-crd.md index 542579d165ab..f04c71013028 100644 --- a/Documentation/CRDs/Object-Storage/ceph-object-store-crd.md +++ b/Documentation/CRDs/Object-Storage/ceph-object-store-crd.md @@ -462,7 +462,7 @@ data: ### Example - usage with `rgwConfigFromSecret` -The sample configuration below demonstrates how to securely handle secret configuration parameters when setting up RGW for [Barbican integration](https://docs.ceph.com/en/reef/radosgw/config-ref/#barbican-settings). +The sample configuration below demonstrates how to securely handle secret configuration parameters when setting up RGW for [Barbican integration](https://docs.ceph.com/en/latest/radosgw/config-ref/#barbican-settings). ```yaml # ... @@ -481,11 +481,11 @@ The sample configuration below demonstrates how to securely handle secret config apiVersion: v1 kind: Secret metadata: - name: barbican-secret - namespace: rook-ceph + name: barbican-secret + namespace: rook-ceph type: Opaque data: - "password": aGVsbG8ud29ybGQK # hello.world + "password": aGVsbG8ud29ybGQK # hello.world ``` ## Deleting a CephObjectStore diff --git a/pkg/operator/ceph/object/config.go b/pkg/operator/ceph/object/config.go index 73044203c194..dad9879c63e3 100644 --- a/pkg/operator/ceph/object/config.go +++ b/pkg/operator/ceph/object/config.go @@ -218,7 +218,7 @@ func (c *clusterConfig) generateMonConfigOptions(rgwConfig *rgwConfig) (map[stri // RGW might break with some user-specified config overrides; log clearly to help triage logger.Infof("overriding object store %q RGW config option %q with user-specified rgwConfig", fmt.Sprintf("%s/%s", c.store.Namespace, c.store.Name), flag) - logger.Debugf("overriding object store %q RGW config option %q (current value %q) with user-specified rgwConfig %q", + logger.Tracef("overriding object store %q RGW config option %q (current value %q) with user-specified rgwConfig %q", fmt.Sprintf("%s/%s", c.store.Namespace, c.store.Name), flag, currVal, val) } configOptions[flag] = val @@ -226,8 +226,7 @@ func (c *clusterConfig) generateMonConfigOptions(rgwConfig *rgwConfig) (map[stri for flag, val := range c.store.Spec.Gateway.RgwConfigFromSecret { if val.Key == "" || val.Name == "" { - logger.Warningf("invalid object store %q rgwConfigFromSecret value %q=%+v", fmt.Sprintf("%s/%s", c.store.Namespace, c.store.Name), flag, val) - continue + return nil, fmt.Errorf("invalid object store %q rgwConfigFromSecret value %q=%+v", fmt.Sprintf("%s/%s", c.store.Namespace, c.store.Name), flag, val) } secret, err := c.context.Clientset.CoreV1().Secrets(c.clusterInfo.Namespace).Get(c.clusterInfo.Context, val.Name, metav1.GetOptions{}) if err != nil { @@ -243,7 +242,7 @@ func (c *clusterConfig) generateMonConfigOptions(rgwConfig *rgwConfig) (map[stri // RGW might break with some user-specified config overrides; log clearly to help triage logger.Infof("overriding object store %q RGW config option %q with user-specified rgwConfigFromSecret", fmt.Sprintf("%s/%s", c.store.Namespace, c.store.Name), flag) - logger.Debugf("overriding object store %q RGW config option %q (current value %q) with user-specified rgwConfigFromSecret %q", + logger.Tracef("overriding object store %q RGW config option %q (current value %q) with user-specified rgwConfigFromSecret %q", fmt.Sprintf("%s/%s", c.store.Namespace, c.store.Name), flag, currVal, secretVal) } configOptions[flag] = string(secretVal) From 0b2e830111fc6cacf193f5c6fd16758e67e546d1 Mon Sep 17 00:00:00 2001 From: Artem Torubarov Date: Mon, 3 Mar 2025 14:11:48 +0100 Subject: [PATCH 07/16] mon: support external mons in local rook cluster Implements #14733. Allows to set IDs of external mons to Cluster CRD. Rook will not remove external mons from quorum and will add external mon addresses to mon endpoints. Use-case for external mon is to maintain quorum for 2-AZ k8s cluster in case of zone outage. Signed-off-by: Artem Torubarov --- .../CRDs/Cluster/ceph-cluster-crd.md | 7 + Documentation/CRDs/specification.md | 16 + .../Advanced/ceph-mon-health.md | 40 ++ cmd/rook/ceph/mgr.go | 2 +- cmd/rook/ceph/osd.go | 2 +- .../charts/rook-ceph/templates/resources.yaml | 10 + deploy/examples/crds.yaml | 10 + pkg/apis/ceph.rook.io/v1/types.go | 7 + .../ceph.rook.io/v1/zz_generated.deepcopy.go | 5 + pkg/daemon/ceph/client/config.go | 2 +- pkg/daemon/ceph/client/config_test.go | 8 +- pkg/daemon/ceph/client/info.go | 25 +- pkg/daemon/ceph/client/mirror.go | 2 +- pkg/daemon/ceph/client/test/info.go | 9 +- pkg/operator/ceph/cluster/cluster_external.go | 4 +- pkg/operator/ceph/cluster/mon/health.go | 159 ++++- pkg/operator/ceph/cluster/mon/health_test.go | 560 +++++++++++++++++- pkg/operator/ceph/cluster/mon/mon.go | 32 +- pkg/operator/ceph/cluster/mon/mon_test.go | 6 +- pkg/operator/ceph/cluster/mon/util.go | 12 + pkg/operator/ceph/config/store_test.go | 16 +- pkg/operator/ceph/controller/cluster_info.go | 40 +- pkg/operator/ceph/csi/ceph_connection.go | 2 +- .../ceph/file/subvolumegroup/controller.go | 2 +- .../ceph/pool/radosnamespace/controller.go | 2 +- 25 files changed, 874 insertions(+), 106 deletions(-) diff --git a/Documentation/CRDs/Cluster/ceph-cluster-crd.md b/Documentation/CRDs/Cluster/ceph-cluster-crd.md index 51b4e4fc1e63..eea150e38145 100755 --- a/Documentation/CRDs/Cluster/ceph-cluster-crd.md +++ b/Documentation/CRDs/Cluster/ceph-cluster-crd.md @@ -150,6 +150,13 @@ A specific will contain a specific release of Ceph as well as security fixes fro * `failureDomainLabel`: The label that is expected on each node where the mons are expected to be deployed. The labels must be found in the list of well-known [topology labels](#osd-topology). +* `externalMonIDs`: ID list of external mons deployed outside of Rook cluster + and not managed by Rook. If set, Rook will not remove external mons from quorum + and populate external mons addresses to mon endpoints for CSI. + This parameter is supported only for local Rook cluster running in normal mode, + meaning that it will be ignored for external cluster (`spec.external.enabled: true`) + or for `stretchedCluster`. + For more details see [external mons](../../Storage-Configuration/Advanced/ceph-mon-health.md#external-monitors). * `zones`: The failure domain names where the Mons are expected to be deployed. There must be **at least three zones** specified in the list. Each zone can be backed by a different storage class by specifying the `volumeClaimTemplate`. diff --git a/Documentation/CRDs/specification.md b/Documentation/CRDs/specification.md index 99e2000fda64..ca91f6d29321 100644 --- a/Documentation/CRDs/specification.md +++ b/Documentation/CRDs/specification.md @@ -8777,6 +8777,22 @@ VolumeClaimTemplate

VolumeClaimTemplate is the PVC definition

+ + +externalMonIDs
+ +[]string + + + +(Optional) +

ExternalMonIDs - optional list of monitor IDs which are deployed externally and not managed by Rook. +If set, Rook will not remove mons with given IDs from quorum. +This parameter is used only for local Rook cluster running in normal mode +and will be ignored if external or stretched mode is used. +leading

+ +

MonZoneSpec diff --git a/Documentation/Storage-Configuration/Advanced/ceph-mon-health.md b/Documentation/Storage-Configuration/Advanced/ceph-mon-health.md index f39c931b3c11..5e69b9ac21b7 100644 --- a/Documentation/Storage-Configuration/Advanced/ceph-mon-health.md +++ b/Documentation/Storage-Configuration/Advanced/ceph-mon-health.md @@ -124,3 +124,43 @@ CephCluster CR: - `spec.network.hostNetwork`: When enabled or disabled, Rook fails over all monitors, configuring them to enable or disable host networking. - `spec.network.Provider` : When updated from being empty to "host", Rook fails over all monitors, configuring them to enable or disable host networking. - `spec.network.multiClusterService`: When enabled or disabled, Rook fails over all monitors, configuring them to start (or stop) using service IPs compatible with the multi-cluster service. + +## External Monitors + +!!! attention + This feature is experimental. + +It is possible to have both Rook-managed and external monitors in the same Rook cluster. +One use case for this is 2 datacenter aka 2-AZ (Availability Zone) setup. For 2-AZ setup, Zone outage will lead to loss of the k8s control plane and half of the worker nodes hosting Rook mons. +In this case remaining half of the Rook cluster will not be able to form quorum and will be in a stuck state even if the other half of worker nodes are still up. +To avoid this situation, external mons can be used to form quorum and keep the cluster running. + +If there are external monitors, Rook must be aware of them, otherwise Rook will remove the unknown mons from the quorum. This is done by setting the `mon.externalMonIDs` field in the CephCluster CR. The `mon.count` ignores the number of `mon.externalMonIDs`. For example, if `mon.count = 2`, Rook will create two internal mons no matter how many external mons are in the cluster and no matter what their health state might be. External monitors are supported only for the local Rook cluster running in normal mode. The external mons will be ignored for external clusters and stretch clusters. + +Here is a step-by-step guide on how to add external monitors to a Rook cluster: + +1. Create a CephCluster CR with the `mon.externalMonIDs` field set to the external monitor IDs. For example: + + ```yaml + spec: + mon: + # Spawn 2 Mons - one Mon in each AZ managed by Rook + count: 2 + allowMultiplePerNode: false + # ID of external Mon + externalMonIDs: + - ext-mon-1 + ``` + + This will tell Rook to create two internal monitors in the cluster and to keep the external monitor with the ID `ext-mon-1` if it is found in the quorum. + It is also possible to add `externalMonIDs` to an existing Cluster. +2. Wait until the Rook cluster and internal mons are up and running. +3. Manually deploy an external monitor with the ID `ext-mon-1` outside of the Rook cluster and its availability zones. See [ceph guide](https://docs.ceph.com/en/latest/rados/operations/add-or-rm-mons/#adding-removing-monitors) on deploying monitors. +4. Move the external Mon to [disallow-mode](https://docs.ceph.com/en/reef/rados/operations/change-mon-elections/#rados-operations-disallow-mode) to make sure that it won't be elected as a leader. The purpose of external mode is maintaining quorum to elect a new leader in case of a zone outage. The external Mon will likely have higher latency to the cluster so it should not be elected. +5. Check that the external monitor is in the quorum by running `ceph status` or `ceph quorum_status` from the toolbox. +6. Check that the external mon is added to the Rook mon endpoints: + + ```console + $ kubectl -n rook-ceph get cm rook-ceph-mon-endpoints -o jsonpath='{.data.data}' + a=10.100.68.61:6789,b=10.103.201.172:6789,ext-mon-1=10.102.136.102:6789 + ``` diff --git a/cmd/rook/ceph/mgr.go b/cmd/rook/ceph/mgr.go index 372beb449e60..8b8834de1e55 100644 --- a/cmd/rook/ceph/mgr.go +++ b/cmd/rook/ceph/mgr.go @@ -79,7 +79,7 @@ func runMgrSidecar(cmd *cobra.Command, args []string) error { } context := createContext() - clusterInfo.Monitors = opcontroller.ParseMonEndpoints(cfg.monEndpoints) + clusterInfo.InternalMonitors = opcontroller.ParseMonEndpoints(cfg.monEndpoints) rook.LogStartupInfo(mgrSidecarCmd.Flags()) ownerRef := opcontroller.ClusterOwnerRef(clusterName, ownerRefID) diff --git a/cmd/rook/ceph/osd.go b/cmd/rook/ceph/osd.go index d4f0caf5f597..c231c4b9513e 100644 --- a/cmd/rook/ceph/osd.go +++ b/cmd/rook/ceph/osd.go @@ -344,7 +344,7 @@ func commonOSDInit(cmd *cobra.Command) { rook.SetLogLevel() rook.LogStartupInfo(cmd.Flags()) - clusterInfo.Monitors = opcontroller.ParseMonEndpoints(cfg.monEndpoints) + clusterInfo.InternalMonitors = opcontroller.ParseMonEndpoints(cfg.monEndpoints) } // use zone/region/hostname labels in the crushmap diff --git a/deploy/charts/rook-ceph/templates/resources.yaml b/deploy/charts/rook-ceph/templates/resources.yaml index 53a806f02161..1eda882a4396 100644 --- a/deploy/charts/rook-ceph/templates/resources.yaml +++ b/deploy/charts/rook-ceph/templates/resources.yaml @@ -1789,6 +1789,16 @@ spec: maximum: 9 minimum: 0 type: integer + externalMonIDs: + description: |- + ExternalMonIDs - optional list of monitor IDs which are deployed externally and not managed by Rook. + If set, Rook will not remove mons with given IDs from quorum. + This parameter is used only for local Rook cluster running in normal mode + and will be ignored if external or stretched mode is used. + leading + items: + type: string + type: array failureDomainLabel: type: string stretchCluster: diff --git a/deploy/examples/crds.yaml b/deploy/examples/crds.yaml index 25b576af41a1..9446d8900061 100644 --- a/deploy/examples/crds.yaml +++ b/deploy/examples/crds.yaml @@ -1787,6 +1787,16 @@ spec: maximum: 9 minimum: 0 type: integer + externalMonIDs: + description: |- + ExternalMonIDs - optional list of monitor IDs which are deployed externally and not managed by Rook. + If set, Rook will not remove mons with given IDs from quorum. + This parameter is used only for local Rook cluster running in normal mode + and will be ignored if external or stretched mode is used. + leading + items: + type: string + type: array failureDomainLabel: type: string stretchCluster: diff --git a/pkg/apis/ceph.rook.io/v1/types.go b/pkg/apis/ceph.rook.io/v1/types.go index de8c70cceac9..c6076056a6a1 100755 --- a/pkg/apis/ceph.rook.io/v1/types.go +++ b/pkg/apis/ceph.rook.io/v1/types.go @@ -626,6 +626,13 @@ type MonSpec struct { // +kubebuilder:pruning:PreserveUnknownFields // +optional VolumeClaimTemplate *VolumeClaimTemplate `json:"volumeClaimTemplate,omitempty"` + // ExternalMonIDs - optional list of monitor IDs which are deployed externally and not managed by Rook. + // If set, Rook will not remove mons with given IDs from quorum. + // This parameter is used only for local Rook cluster running in normal mode + // and will be ignored if external or stretched mode is used. + // leading + // +optional + ExternalMonIDs []string `json:"externalMonIDs,omitempty"` } // VolumeClaimTemplate is a simplified version of K8s corev1's PVC. It has no type meta or status. diff --git a/pkg/apis/ceph.rook.io/v1/zz_generated.deepcopy.go b/pkg/apis/ceph.rook.io/v1/zz_generated.deepcopy.go index 90d36b973859..b71595f86e23 100644 --- a/pkg/apis/ceph.rook.io/v1/zz_generated.deepcopy.go +++ b/pkg/apis/ceph.rook.io/v1/zz_generated.deepcopy.go @@ -3346,6 +3346,11 @@ func (in *MonSpec) DeepCopyInto(out *MonSpec) { *out = new(VolumeClaimTemplate) (*in).DeepCopyInto(*out) } + if in.ExternalMonIDs != nil { + in, out := &in.ExternalMonIDs, &out.ExternalMonIDs + *out = make([]string, len(*in)) + copy(*out, *in) + } return } diff --git a/pkg/daemon/ceph/client/config.go b/pkg/daemon/ceph/client/config.go index f2cc6119ba1c..278c3744586d 100644 --- a/pkg/daemon/ceph/client/config.go +++ b/pkg/daemon/ceph/client/config.go @@ -249,7 +249,7 @@ func PopulateMonHostMembers(clusterInfo *ClusterInfo) ([]string, []string) { var monMembers []string var monHosts []string - for _, monitor := range clusterInfo.Monitors { + for _, monitor := range clusterInfo.AllMonitors() { if monitor.OutOfQuorum { logger.Warningf("skipping adding mon %q to config file, detected out of quorum", monitor.Name) continue diff --git a/pkg/daemon/ceph/client/config_test.go b/pkg/daemon/ceph/client/config_test.go index cfb2afa20a6a..cf7810312523 100644 --- a/pkg/daemon/ceph/client/config_test.go +++ b/pkg/daemon/ceph/client/config_test.go @@ -37,7 +37,7 @@ func TestCreateDefaultCephConfig(t *testing.T) { FSID: "id", MonitorSecret: "monsecret", Namespace: "foo-cluster", - Monitors: map[string]*MonInfo{ + InternalMonitors: map[string]*MonInfo{ "node0": {Name: "mon0", Endpoint: "10.0.0.1:6789"}, "node1": {Name: "mon1", Endpoint: "10.0.0.2:6789"}, }, @@ -89,7 +89,7 @@ func TestGenerateConfigFile(t *testing.T) { FSID: "myfsid", MonitorSecret: "monsecret", Namespace: ns, - Monitors: map[string]*MonInfo{ + InternalMonitors: map[string]*MonInfo{ "node0": {Name: "mon0", Endpoint: "10.0.0.1:6789"}, }, CephCred: CephCred{Username: "admin", Secret: "mysecret"}, @@ -112,9 +112,9 @@ func TestGenerateConfigFile(t *testing.T) { } func verifyConfig(t *testing.T, cephConfig *CephConfig, cluster *ClusterInfo, loggingLevel int) { - monMembers := make([]string, len(cluster.Monitors)) + monMembers := make([]string, len(cluster.InternalMonitors)) i := 0 - for _, expectedMon := range cluster.Monitors { + for _, expectedMon := range cluster.InternalMonitors { contained := false monMembers[i] = expectedMon.Name for _, actualMon := range strings.Split(cephConfig.MonMembers, " ") { diff --git a/pkg/daemon/ceph/client/info.go b/pkg/daemon/ceph/client/info.go index 70e49bc48b34..79d2734718c1 100644 --- a/pkg/daemon/ceph/client/info.go +++ b/pkg/daemon/ceph/client/info.go @@ -39,10 +39,13 @@ type ClusterInfo struct { FSID string MonitorSecret string CephCred CephCred - Monitors map[string]*MonInfo - CephVersion cephver.CephVersion - Namespace string - OwnerInfo *k8sutil.OwnerInfo + // InternalMonitors - montiros managed by Rook or external monitors when Rook manages external cluster. + InternalMonitors map[string]*MonInfo + // ExternalMons - external montiros listed in CephCluster.spec.mon.externalMonIDs when Rook managing local cluster. + ExternalMons map[string]*MonInfo + CephVersion cephver.CephVersion + Namespace string + OwnerInfo *k8sutil.OwnerInfo // Hide the name of the cluster since in 99% of uses we want to use the cluster namespace. // If the CR name is needed, access it through the NamespacedName() method. name string @@ -59,6 +62,20 @@ type ClusterInfo struct { Context context.Context } +func (c *ClusterInfo) AllMonitors() map[string]*MonInfo { + if len(c.ExternalMons) == 0 { + return c.InternalMonitors + } + res := make(map[string]*MonInfo, len(c.InternalMonitors)+len(c.ExternalMons)) + for id, mon := range c.InternalMonitors { + res[id] = mon + } + for id, mon := range c.ExternalMons { + res[id] = mon + } + return res +} + // MonInfo is a collection of information about a Ceph mon. type MonInfo struct { Name string `json:"name"` diff --git a/pkg/daemon/ceph/client/mirror.go b/pkg/daemon/ceph/client/mirror.go index d9c2dc8a870c..a0795c89205d 100644 --- a/pkg/daemon/ceph/client/mirror.go +++ b/pkg/daemon/ceph/client/mirror.go @@ -441,7 +441,7 @@ func CreateRBDMirrorBootstrapPeerWithoutPool(context *clusterd.Context, clusterI logger.Infof("successfully created rbd-mirror bootstrap peer token for cluster %q", clusterInfo.NamespacedName().Name) mons := sets.New[string]() - for _, mon := range clusterInfo.Monitors { + for _, mon := range clusterInfo.AllMonitors() { mons.Insert(mon.Endpoint) } diff --git a/pkg/daemon/ceph/client/test/info.go b/pkg/daemon/ceph/client/test/info.go index 4aaa57ac3f84..c5081e243fe5 100644 --- a/pkg/daemon/ceph/client/test/info.go +++ b/pkg/daemon/ceph/client/test/info.go @@ -51,14 +51,15 @@ func CreateTestClusterInfo(monCount int) *client.ClusterInfo { Username: client.AdminUsername, Secret: "adminkey", }, - Monitors: map[string]*client.MonInfo{}, - OwnerInfo: ownerInfo, - Context: context.TODO(), + InternalMonitors: map[string]*client.MonInfo{}, + ExternalMons: map[string]*client.MonInfo{}, + OwnerInfo: ownerInfo, + Context: context.TODO(), } mons := []string{"a", "b", "c", "d", "e"} for i := 0; i < monCount; i++ { id := mons[i] - c.Monitors[id] = &client.MonInfo{ + c.InternalMonitors[id] = &client.MonInfo{ Name: id, Endpoint: fmt.Sprintf("1.2.3.%d:3300", (i + 1)), } diff --git a/pkg/operator/ceph/cluster/cluster_external.go b/pkg/operator/ceph/cluster/cluster_external.go index 37f82526399d..b9b14121b920 100644 --- a/pkg/operator/ceph/cluster/cluster_external.go +++ b/pkg/operator/ceph/cluster/cluster_external.go @@ -109,7 +109,7 @@ func (c *ClusterController) configureExternalCephCluster(cluster *cluster) error } // update the msgr2 flag - for _, m := range cluster.ClusterInfo.Monitors { + for _, m := range cluster.ClusterInfo.InternalMonitors { // m.Endpoint=10.1.115.104:3300 monPort := util.GetPortFromEndpoint(m.Endpoint) if monPort == client.Msgr2port { @@ -123,7 +123,7 @@ func (c *ClusterController) configureExternalCephCluster(cluster *cluster) error } // Save CSI configmap - monEndpoints := csi.MonEndpoints(cluster.ClusterInfo.Monitors, cluster.Spec.RequireMsgr2()) + monEndpoints := csi.MonEndpoints(cluster.ClusterInfo.InternalMonitors, cluster.Spec.RequireMsgr2()) csiConfigEntry := &csi.CSIClusterConfigEntry{ Namespace: cluster.ClusterInfo.Namespace, ClusterInfo: cephcsi.ClusterInfo{ diff --git a/pkg/operator/ceph/cluster/mon/health.go b/pkg/operator/ceph/cluster/mon/health.go index 050d88f43585..fe1042ae815b 100644 --- a/pkg/operator/ceph/cluster/mon/health.go +++ b/pkg/operator/ceph/cluster/mon/health.go @@ -1,5 +1,4 @@ -/* -Copyright 2018 The Rook Authors. All rights reserved. +/* Copyright 2018 The Rook Authors. All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -20,6 +19,7 @@ import ( "context" "fmt" "os" + "slices" "strings" "time" @@ -202,6 +202,12 @@ func (c *Cluster) checkHealth(ctx context.Context) error { } logger.Debugf("Mon quorum status: %+v", quorumStatus) + // handle external Mons + quorumStatus, err = c.reconcileExternalMons(ctx, quorumStatus) + if err != nil { + return errors.Wrap(err, "failed to check external mons health") + } + // Use a local mon count in case the user updates the crd in another goroutine. // We need to complete a health check with a consistent value. desiredMonCount := c.spec.Mon.Count @@ -209,7 +215,7 @@ func (c *Cluster) checkHealth(ctx context.Context) error { // Source of truth of which mons should exist is our *clusterInfo* monsNotFound := map[string]interface{}{} - for _, mon := range c.ClusterInfo.Monitors { + for _, mon := range c.ClusterInfo.InternalMonitors { monsNotFound[mon.Name] = struct{}{} } @@ -314,7 +320,7 @@ func (c *Cluster) checkHealth(ctx context.Context) error { // handle all mons that haven't been in the Ceph mon map for mon := range monsNotFound { logger.Warningf("mon %s NOT found in ceph mon map, failover", mon) - c.failMon(len(c.ClusterInfo.Monitors), desiredMonCount, mon) + c.failMon(len(c.ClusterInfo.InternalMonitors), desiredMonCount, mon) // only deal with one "not found in ceph mon map" mon per health check return nil } @@ -351,24 +357,24 @@ func (c *Cluster) checkHealth(ctx context.Context) error { // failover mon if `multiClusterService` is enabled but mon service is not exported if allMonsInQuorum && c.spec.Network.MultiClusterService.Enabled { - for _, mon := range c.ClusterInfo.Monitors { + for _, mon := range c.ClusterInfo.InternalMonitors { monResourceName := resourceName(mon.Name) isAlreadyExported, err := k8sutil.IsServiceExported(c.ClusterInfo.Context, c.context, monResourceName, c.ClusterInfo.Namespace) if err != nil { return errors.Wrapf(err, "failed to check if the service %q is already exported", mon.Name) } if !isAlreadyExported { - c.failMon(len(c.ClusterInfo.Monitors), desiredMonCount, mon.Name) + c.failMon(len(c.ClusterInfo.InternalMonitors), desiredMonCount, mon.Name) return nil } } } // failover any mons present in the mon fail over list - for _, mon := range c.ClusterInfo.Monitors { + for _, mon := range c.ClusterInfo.InternalMonitors { if c.monsToFailover.Has(mon.Name) { logger.Infof("fail over mon %q from the mon fail over list", mon.Name) - c.failMon(len(c.ClusterInfo.Monitors), desiredMonCount, mon.Name) + c.failMon(len(c.ClusterInfo.InternalMonitors), desiredMonCount, mon.Name) c.monsToFailover.Delete(mon.Name) return nil } @@ -377,12 +383,102 @@ func (c *Cluster) checkHealth(ctx context.Context) error { return nil } +// reconcileExternalMons handling external monitors defined in CephCluster.spec.mon.externalMonIDs when Rook managing local cluster. +func (c *Cluster) reconcileExternalMons(ctx context.Context, quorumStatus cephclient.MonStatusResponse) (cephclient.MonStatusResponse, error) { + if len(c.spec.Mon.ExternalMonIDs) != 0 { + if c.spec.External.Enable { + logger.Warning("ignore external mon IDs in cluster spec: cluster is running in external mode") + return quorumStatus, nil + } + if c.spec.IsStretchCluster() { + logger.Warning("ignore external mon IDs in cluster spec: cluster is running in stretch mode") + return quorumStatus, nil + } + } + + extMonIDs := c.spec.Mon.ExternalMonIDs + if c.ClusterInfo.ExternalMons == nil { + c.ClusterInfo.ExternalMons = make(map[string]*cephclient.MonInfo, len(extMonIDs)) + } + + extMonsChanged := false + for extID := range c.ClusterInfo.ExternalMons { + if slices.Contains(extMonIDs, extID) { + continue + } + // existing external mon was removed from Cluster CRD spec: + // remove it from CLusterInfo + logger.Debugf("existing external mon %q was removed from spec: removing it", extID) + delete(c.ClusterInfo.ExternalMons, extID) + extMonsChanged = true + } + + // handle external monitors if configured in cluster CRD: + logger.Debugf("external mon IDs: %v", extMonIDs) + for _, extID := range extMonIDs { + monStatus, inQuorum := getMonByID(extID, quorumStatus) + if inQuorum { + logger.Debugf("external mon %q in quorum", extID) + } else { + logger.Debugf("external mon %q not in quorum %+v, %+v", extID, quorumStatus.Quorum, quorumStatus.MonMap.Mons) + } + _, inInfo := c.ClusterInfo.ExternalMons[extID] + if inQuorum && !inInfo { + // add newly discovered external mon to cluster info: + monInfo := monStatusToInfo(monStatus) + c.ClusterInfo.ExternalMons[extID] = monInfo + extMonsChanged = true + logger.Infof("new external mon %q found: %s, adding it", extID, monInfo.Endpoint) + } else if !inQuorum && inInfo { + // remove external mon from cluster info if it is out of quorum: + delete(c.ClusterInfo.ExternalMons, extID) + extMonsChanged = true + logger.Infof("new external mon %q not in quorum: removing it", extID) + } + } + if extMonsChanged { + // update config if external mon was removed or added: + if err := c.saveMonConfig(); err != nil { + return cephclient.MonStatusResponse{}, errors.Wrap(err, "failed to save mon config after adding/removing external mon") + } + } + + // now, remove processed external mons from ceph quorum status response + // to not affect existing logic processing internal mons that are within the mon.count + quorumStatus = removeMonsFromQuorumStatusResponse(quorumStatus, extMonIDs) + return quorumStatus, nil +} + +func removeMonsFromQuorumStatusResponse(quorumStatus cephclient.MonStatusResponse, idsToRemove []string) cephclient.MonStatusResponse { + var removeFromQuorum []int + var keepMons []cephclient.MonMapEntry + + for _, mon := range quorumStatus.MonMap.Mons { + if !slices.Contains(idsToRemove, mon.Name) { + keepMons = append(keepMons, mon) + continue + } + removeFromQuorum = append(removeFromQuorum, mon.Rank) + } + + var keepQuorum []int + for _, rank := range quorumStatus.Quorum { + if slices.Contains(removeFromQuorum, rank) { + continue + } + keepQuorum = append(keepQuorum, rank) + } + quorumStatus.MonMap.Mons = keepMons + quorumStatus.Quorum = keepQuorum + return quorumStatus +} + func (c *Cluster) trackMonInOrOutOfQuorum(monName string, inQuorum bool) (bool, error) { updateNeeded := false var monsOutOfQuorum []string if monName == "" { // All mons are in quorum, so make sure no mons are marked out of quorum - for monName, mon := range c.ClusterInfo.Monitors { + for monName, mon := range c.ClusterInfo.InternalMonitors { if mon.OutOfQuorum { logger.Infof("resetting mon %q to be back in quorum", monName) mon.OutOfQuorum = false @@ -390,7 +486,7 @@ func (c *Cluster) trackMonInOrOutOfQuorum(monName string, inQuorum bool) (bool, } } } else { - mon, ok := c.ClusterInfo.Monitors[monName] + mon, ok := c.ClusterInfo.InternalMonitors[monName] if !ok { logger.Infof("mon %q not found to keep track of being out of quorum", monName) return false, nil @@ -675,7 +771,7 @@ func (c *Cluster) failoverMon(name string) error { m.PublicIP = monService.Spec.ClusterIP } } - c.ClusterInfo.Monitors[m.DaemonName] = cephclient.NewMonInfo(m.DaemonName, m.PublicIP, m.Port) + c.ClusterInfo.InternalMonitors[m.DaemonName] = cephclient.NewMonInfo(m.DaemonName, m.PublicIP, m.Port) // Start the deployment newMonMightBeInQuorum = true @@ -717,7 +813,7 @@ func (c *Cluster) removeMonWithOptionalQuorum(daemonName string, shouldRemoveFro logger.Errorf("failed to remove mon %q from quorum. %v", daemonName, err) } } - delete(c.ClusterInfo.Monitors, daemonName) + delete(c.ClusterInfo.InternalMonitors, daemonName) delete(c.mapping.Schedule, daemonName) if err := c.saveMonConfig(); err != nil { @@ -813,9 +909,9 @@ func (c *Cluster) addOrRemoveExternalMonitor(status cephclient.MonStatusResponse // clearing the content of clusterinfo monitors // and populate oldClusterInfoMonitors with monitors from clusterinfo // later c.ClusterInfo.Monitors get populated again - for monName, mon := range c.ClusterInfo.Monitors { + for monName, mon := range c.ClusterInfo.InternalMonitors { oldClusterInfoMonitors[mon.Name] = mon - delete(c.ClusterInfo.Monitors, monName) + delete(c.ClusterInfo.InternalMonitors, monName) } logger.Debugf("ClusterInfo is now Empty, refilling it from status.MonMap.Mons") @@ -831,17 +927,9 @@ func (c *Cluster) addOrRemoveExternalMonitor(status cephclient.MonStatusResponse if _, ok := oldClusterInfoMonitors[mon.Name]; !ok { // If the mon is part of the quorum if inQuorum { - // let's add it to ClusterInfo - // FYI mon.PublicAddr is "10.97.171.131:6789/0" - // so we need to remove '/0' - endpointSlash := strings.Split(mon.PublicAddr, "/") - endpoint := endpointSlash[0] - - // find IP and Port of that Mon - monIP := cephutil.GetIPFromEndpoint(endpoint) - monPort := cephutil.GetPortFromEndpoint(endpoint) - logger.Infof("new external mon %q found: %s, adding it", mon.Name, endpoint) - c.ClusterInfo.Monitors[mon.Name] = cephclient.NewMonInfo(mon.Name, monIP, monPort) + info := monStatusToInfo(mon) + logger.Infof("new external mon %q found: %s, adding it", mon.Name, info.Endpoint) + c.ClusterInfo.InternalMonitors[mon.Name] = info } else { logger.Debugf("mon %q is not in quorum and not in ClusterInfo", mon.Name) } @@ -857,7 +945,7 @@ func (c *Cluster) addOrRemoveExternalMonitor(status cephclient.MonStatusResponse } else { // this mon was in clusterInfo and is still in the quorum // add it again - c.ClusterInfo.Monitors[mon.Name] = oldClusterInfoMonitors[mon.Name] + c.ClusterInfo.InternalMonitors[mon.Name] = oldClusterInfoMonitors[mon.Name] logger.Debugf("everything is fine mon %q in the clusterInfo and its quorum status is %v", mon.Name, inQuorum) } } @@ -865,20 +953,33 @@ func (c *Cluster) addOrRemoveExternalMonitor(status cephclient.MonStatusResponse // compare old clusterInfo with new ClusterInfo // if length differ -> the are different // then check if all elements are the same - if len(oldClusterInfoMonitors) != len(c.ClusterInfo.Monitors) { + if len(oldClusterInfoMonitors) != len(c.ClusterInfo.InternalMonitors) { changed = true } else { - for _, mon := range c.ClusterInfo.Monitors { + for _, mon := range c.ClusterInfo.InternalMonitors { if old, ok := oldClusterInfoMonitors[mon.Name]; !ok || *old != *mon { changed = true } } } - logger.Debugf("ClusterInfo.Monitors is %+v", c.ClusterInfo.Monitors) + logger.Debugf("ClusterInfo.Monitors is %+v", c.ClusterInfo.InternalMonitors) return changed, nil } +func monStatusToInfo(mon cephclient.MonMapEntry) *cephclient.MonInfo { + // let's add it to ClusterInfo + // FYI mon.PublicAddr is "10.97.171.131:6789/0" + // so we need to remove '/0' + endpointSlash := strings.Split(mon.PublicAddr, "/") + endpoint := endpointSlash[0] + + // find IP and Port of that Mon + monIP := cephutil.GetIPFromEndpoint(endpoint) + monPort := cephutil.GetPortFromEndpoint(endpoint) + return cephclient.NewMonInfo(mon.Name, monIP, monPort) +} + func (c *Cluster) evictMonIfMultipleOnSameNode() error { if c.spec.Mon.AllowMultiplePerNode { logger.Debug("skipping check for multiple mons on same node since multiple mons are allowed") diff --git a/pkg/operator/ceph/cluster/mon/health_test.go b/pkg/operator/ceph/cluster/mon/health_test.go index 90a778dbcc92..5a9452a755df 100644 --- a/pkg/operator/ceph/cluster/mon/health_test.go +++ b/pkg/operator/ceph/cluster/mon/health_test.go @@ -29,6 +29,7 @@ import ( cephclient "github.com/rook/rook/pkg/daemon/ceph/client" clienttest "github.com/rook/rook/pkg/daemon/ceph/client/test" "github.com/rook/rook/pkg/operator/ceph/config" + "github.com/rook/rook/pkg/operator/ceph/controller" opcontroller "github.com/rook/rook/pkg/operator/ceph/controller" testopk8s "github.com/rook/rook/pkg/operator/k8sutil/test" "github.com/rook/rook/pkg/operator/test" @@ -74,7 +75,7 @@ func TestCheckHealth(t *testing.T) { assert.NotNil(t, err) c.spec.Mon.Count = 3 - logger.Infof("initial mons: %v", c.ClusterInfo.Monitors) + logger.Infof("initial mons: %v", c.ClusterInfo.InternalMonitors) c.waitForStart = false c.mapping.Schedule["f"] = &opcontroller.MonScheduleInfo{ @@ -92,7 +93,7 @@ func TestCheckHealth(t *testing.T) { c.ClusterInfo.Context = ctx err = c.checkHealth(ctx) assert.Nil(t, err) - logger.Infof("mons after checkHealth: %v", c.ClusterInfo.Monitors) + logger.Infof("mons after checkHealth: %v", c.ClusterInfo.InternalMonitors) assert.ElementsMatch(t, []string{"rook-ceph-mon-a", "rook-ceph-mon-f"}, testopk8s.DeploymentNamesUpdated(deploymentsUpdated)) testopk8s.ClearDeploymentsUpdated(deploymentsUpdated) @@ -105,8 +106,8 @@ func TestCheckHealth(t *testing.T) { "g", } for _, monName := range newMons { - _, ok := c.ClusterInfo.Monitors[monName] - assert.True(t, ok, fmt.Sprintf("mon %s not found in monitor list. %v", monName, c.ClusterInfo.Monitors)) + _, ok := c.ClusterInfo.InternalMonitors[monName] + assert.True(t, ok, fmt.Sprintf("mon %s not found in monitor list. %v", monName, c.ClusterInfo.InternalMonitors)) } deployments, err := clientset.AppsV1().Deployments(c.Namespace).List(ctx, metav1.ListOptions{}) @@ -153,7 +154,7 @@ func TestCheckHealth(t *testing.T) { func TestRemoveExtraMon(t *testing.T) { endpoint := "1.2.3.4:6789" c := &Cluster{mapping: &opcontroller.Mapping{}} - c.ClusterInfo = &cephclient.ClusterInfo{Monitors: map[string]*cephclient.MonInfo{ + c.ClusterInfo = &cephclient.ClusterInfo{InternalMonitors: map[string]*cephclient.MonInfo{ "a": {Name: "a", Endpoint: endpoint}, "b": {Name: "b", Endpoint: endpoint}, "c": {Name: "c", Endpoint: endpoint}, @@ -182,7 +183,7 @@ func TestRemoveExtraMon(t *testing.T) { {Name: "y"}, {Name: "z"}, }} - c.ClusterInfo.Monitors["e"] = &cephclient.MonInfo{Name: "e", Endpoint: endpoint} + c.ClusterInfo.InternalMonitors["e"] = &cephclient.MonInfo{Name: "e", Endpoint: endpoint} c.mapping.Schedule["a"].Zone = "x" c.mapping.Schedule["b"].Zone = "y" c.mapping.Schedule["c"].Zone = "y" @@ -218,7 +219,7 @@ func TestTrackMonsOutOfQuorum(t *testing.T) { context: &clusterd.Context{Clientset: clientset, ConfigDir: tempDir}, ownerInfo: ownerInfo, Namespace: "ns"} - c.ClusterInfo = &cephclient.ClusterInfo{Monitors: map[string]*cephclient.MonInfo{ + c.ClusterInfo = &cephclient.ClusterInfo{InternalMonitors: map[string]*cephclient.MonInfo{ "a": {Name: "a", Endpoint: endpoint}, "b": {Name: "b", Endpoint: endpoint}, "c": {Name: "c", Endpoint: endpoint}, @@ -323,7 +324,7 @@ func TestScaleMonDeployment(t *testing.T) { name := "a" c.spec.Mon.Count = 3 - logger.Infof("initial mons: %v", c.ClusterInfo.Monitors[name]) + logger.Infof("initial mons: %v", c.ClusterInfo.InternalMonitors[name]) monConfig := &monConfig{ResourceName: resourceName(name), DaemonName: name, DataPathMap: &config.DataPathMap{}} d, err := c.makeDeployment(monConfig, false) require.NoError(t, err) @@ -437,7 +438,7 @@ func TestAddRemoveMons(t *testing.T) { // checking the health will increase the mons as desired all in one go err := c.checkHealth(ctx) assert.Nil(t, err) - assert.Equal(t, 5, len(c.ClusterInfo.Monitors), fmt.Sprintf("mons: %v", c.ClusterInfo.Monitors)) + assert.Equal(t, 5, len(c.ClusterInfo.InternalMonitors), fmt.Sprintf("mons: %v", c.ClusterInfo.InternalMonitors)) assert.ElementsMatch(t, []string{ // b is created first, no updates "rook-ceph-mon-b", // b updated when c created @@ -448,39 +449,39 @@ func TestAddRemoveMons(t *testing.T) { testopk8s.ClearDeploymentsUpdated(deploymentsUpdated) // reducing the mon count to 3 will reduce the mon count once each time we call checkHealth - monQuorumResponse = clienttest.MonInQuorumResponseFromMons(c.ClusterInfo.Monitors) + monQuorumResponse = clienttest.MonInQuorumResponseFromMons(c.ClusterInfo.InternalMonitors) c.spec.Mon.Count = 3 err = c.checkHealth(ctx) assert.Nil(t, err) - assert.Equal(t, 4, len(c.ClusterInfo.Monitors)) + assert.Equal(t, 4, len(c.ClusterInfo.InternalMonitors)) // No updates in unit tests w/ workaround assert.ElementsMatch(t, []string{}, testopk8s.DeploymentNamesUpdated(deploymentsUpdated)) testopk8s.ClearDeploymentsUpdated(deploymentsUpdated) // after the second call we will be down to the expected count of 3 - monQuorumResponse = clienttest.MonInQuorumResponseFromMons(c.ClusterInfo.Monitors) + monQuorumResponse = clienttest.MonInQuorumResponseFromMons(c.ClusterInfo.InternalMonitors) err = c.checkHealth(ctx) assert.Nil(t, err) - assert.Equal(t, 3, len(c.ClusterInfo.Monitors)) + assert.Equal(t, 3, len(c.ClusterInfo.InternalMonitors)) // No updates in unit tests w/ workaround assert.ElementsMatch(t, []string{}, testopk8s.DeploymentNamesUpdated(deploymentsUpdated)) testopk8s.ClearDeploymentsUpdated(deploymentsUpdated) // now attempt to reduce the mons down to quorum size 1 - monQuorumResponse = clienttest.MonInQuorumResponseFromMons(c.ClusterInfo.Monitors) + monQuorumResponse = clienttest.MonInQuorumResponseFromMons(c.ClusterInfo.InternalMonitors) c.spec.Mon.Count = 1 err = c.checkHealth(ctx) assert.Nil(t, err) - assert.Equal(t, 2, len(c.ClusterInfo.Monitors)) + assert.Equal(t, 2, len(c.ClusterInfo.InternalMonitors)) // No updates in unit tests w/ workaround assert.ElementsMatch(t, []string{}, testopk8s.DeploymentNamesUpdated(deploymentsUpdated)) testopk8s.ClearDeploymentsUpdated(deploymentsUpdated) // cannot reduce from quorum size of 2 to 1 - monQuorumResponse = clienttest.MonInQuorumResponseFromMons(c.ClusterInfo.Monitors) + monQuorumResponse = clienttest.MonInQuorumResponseFromMons(c.ClusterInfo.InternalMonitors) err = c.checkHealth(ctx) assert.Nil(t, err) - assert.Equal(t, 2, len(c.ClusterInfo.Monitors)) + assert.Equal(t, 2, len(c.ClusterInfo.InternalMonitors)) // No updates in unit tests w/ workaround assert.ElementsMatch(t, []string{}, testopk8s.DeploymentNamesUpdated(deploymentsUpdated)) testopk8s.ClearDeploymentsUpdated(deploymentsUpdated) @@ -511,7 +512,7 @@ func TestAddOrRemoveExternalMonitor(t *testing.T) { changed, err = c.addOrRemoveExternalMonitor(fakeResp) assert.NoError(t, err) assert.False(t, changed) - assert.Equal(t, 1, len(c.ClusterInfo.Monitors)) + assert.Equal(t, 1, len(c.ClusterInfo.InternalMonitors)) // // TEST 2 @@ -524,7 +525,7 @@ func TestAddOrRemoveExternalMonitor(t *testing.T) { assert.NoError(t, err) assert.True(t, changed) // ClusterInfo should shrink to 1 - assert.Equal(t, 1, len(c.ClusterInfo.Monitors)) + assert.Equal(t, 1, len(c.ClusterInfo.InternalMonitors)) // // TEST 3 @@ -545,7 +546,7 @@ func TestAddOrRemoveExternalMonitor(t *testing.T) { assert.NoError(t, err) assert.True(t, changed) // ClusterInfo should now have 2 monitors - assert.Equal(t, 2, len(c.ClusterInfo.Monitors)) + assert.Equal(t, 2, len(c.ClusterInfo.InternalMonitors)) } func TestNewHealthChecker(t *testing.T) { @@ -610,3 +611,522 @@ func TestUpdateMonInterval(t *testing.T) { assert.Equal(t, time.Minute, h.interval) }) } + +func Test_removeMonsFromQuorumStatusResponse(t *testing.T) { + type args struct { + quorumStatus cephclient.MonStatusResponse + idsToRemove []string + } + tests := []struct { + name string + args args + want cephclient.MonStatusResponse + }{ + { + name: "remove one mon", + args: args{ + quorumStatus: cephclient.MonStatusResponse{ + Quorum: []int{0, 1, 2}, + MonMap: struct { + Mons []cephclient.MonMapEntry `json:"mons"` + }{ + Mons: []cephclient.MonMapEntry{ + { + Name: "a", + Rank: 0, + }, + { + Name: "b", + Rank: 1, + }, + { + Name: "c", + Rank: 2, + }, + }, + }, + }, + idsToRemove: []string{"b"}, + }, + want: cephclient.MonStatusResponse{ + Quorum: []int{0, 2}, + MonMap: struct { + Mons []cephclient.MonMapEntry `json:"mons"` + }{ + Mons: []cephclient.MonMapEntry{ + { + Name: "a", + Rank: 0, + }, + { + Name: "c", + Rank: 2, + }, + }, + }, + }, + }, + { + name: "not remove if not present", + args: args{ + quorumStatus: cephclient.MonStatusResponse{ + Quorum: []int{0, 1, 2}, + MonMap: struct { + Mons []cephclient.MonMapEntry `json:"mons"` + }{ + Mons: []cephclient.MonMapEntry{ + { + Name: "a", + Rank: 0, + }, + { + Name: "b", + Rank: 1, + }, + { + Name: "c", + Rank: 2, + }, + }, + }, + }, + idsToRemove: []string{"e"}, + }, + want: cephclient.MonStatusResponse{ + Quorum: []int{0, 1, 2}, + MonMap: struct { + Mons []cephclient.MonMapEntry `json:"mons"` + }{ + Mons: []cephclient.MonMapEntry{ + { + Name: "a", + Rank: 0, + }, + { + Name: "b", + Rank: 1, + }, + { + Name: "c", + Rank: 2, + }, + }, + }, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := removeMonsFromQuorumStatusResponse(tt.args.quorumStatus, tt.args.idsToRemove); !reflect.DeepEqual(got, tt.want) { + t.Errorf("removeMonsFromQuorumStatusResponse() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestExternalMons_notInSpec_InQuorum(t *testing.T) { + // 1. setup test + ctx := context.TODO() + var deploymentsUpdated *[]*apps.Deployment + updateDeploymentAndWait, deploymentsUpdated = testopk8s.UpdateDeploymentAndWaitStub() + + monQuorumResponse := clienttest.MonInQuorumResponse() + executor := &exectest.MockExecutor{ + MockExecuteCommandWithOutput: func(command string, args ...string) (string, error) { + logger.Infof("executing command: %s %+v", command, args) + if args[0] == "auth" && args[1] == "get-or-create-key" { + return "{\"key\":\"mysecurekey\"}", nil + } + return monQuorumResponse, nil + }, + } + clientset := test.New(t, 1) + configDir := t.TempDir() + context := &clusterd.Context{ + Clientset: clientset, + ConfigDir: configDir, + Executor: executor, + } + ownerInfo := cephclient.NewMinimumOwnerInfoWithOwnerRef() + c := New(ctx, context, "ns", cephv1.ClusterSpec{}, ownerInfo) + setCommonMonProperties(c, 0, cephv1.MonSpec{Count: 5, AllowMultiplePerNode: true}, "myversion") + c.maxMonID = 0 // "a" is max mon id + c.waitForStart = false + + // checking the health will increase the mons as desired all in one go + err := c.checkHealth(ctx) + assert.Nil(t, err) + assert.Equal(t, 5, len(c.ClusterInfo.InternalMonitors), fmt.Sprintf("mons: %v", c.ClusterInfo.InternalMonitors)) + assert.ElementsMatch(t, []string{ + // b is created first, no updates + "rook-ceph-mon-b", // b updated when c created + "rook-ceph-mon-b", "rook-ceph-mon-c", // b and c updated when d created + "rook-ceph-mon-b", "rook-ceph-mon-c", "rook-ceph-mon-d", // etc. + "rook-ceph-mon-b", "rook-ceph-mon-c", "rook-ceph-mon-d", "rook-ceph-mon-e"}, + testopk8s.DeploymentNamesUpdated(deploymentsUpdated)) + testopk8s.ClearDeploymentsUpdated(deploymentsUpdated) + + inital5Mons := make(map[string]*cephclient.MonInfo) + for k, v := range c.ClusterInfo.InternalMonitors { + inital5Mons[k] = v + } + + // 2. add external mon to quorum but not in spec: + + mons := make(map[string]*cephclient.MonInfo) + for k, v := range inital5Mons { + mons[k] = v + } + // add unknown mon to quorum: + mons["ext-mon-id"] = &cephclient.MonInfo{Name: "ext-mon-id", Endpoint: "0.0.0.0:6789"} + monQuorumResponse = clienttest.MonInQuorumResponseFromMons(mons) + + // internal mons and deployments has not changed + // and unknown mon was removed from quorum + err = c.checkHealth(ctx) + assert.Nil(t, err) + assert.Equal(t, 5, len(c.ClusterInfo.InternalMonitors)) + assert.Empty(t, c.ClusterInfo.ExternalMons) + + // No updates in unit tests w/ workaround + assert.ElementsMatch(t, []string{}, testopk8s.DeploymentNamesUpdated(deploymentsUpdated)) + testopk8s.ClearDeploymentsUpdated(deploymentsUpdated) + + // check that unknown mon is not in endpoint configmap + cm, err := c.context.Clientset.CoreV1().ConfigMaps(c.Namespace).Get(ctx, EndpointConfigMapName, metav1.GetOptions{}) + assert.Nil(t, err) + assert.Empty(t, cm.Data[EndpointExternalMonsKey]) + monsFromCM := controller.ParseMonEndpoints(cm.Data[EndpointDataKey]) + assert.Len(t, monsFromCM, 5) + for id, mon := range monsFromCM { + assert.Equal(t, inital5Mons[id].Name, mon.Name) + assert.Equal(t, inital5Mons[id].Endpoint, mon.Endpoint) + assert.Equal(t, inital5Mons[id].OutOfQuorum, mon.OutOfQuorum) + } + + // 3. downscale mons to 4: + c.spec.Mon.Count = 4 + monQuorumResponse = clienttest.MonInQuorumResponseFromMons(c.ClusterInfo.InternalMonitors) + + err = c.checkHealth(ctx) + assert.Nil(t, err) + // todo fix + assert.Equal(t, 4, len(c.ClusterInfo.InternalMonitors)) + assert.Empty(t, c.ClusterInfo.ExternalMons) + // No updates in unit tests w/ workaround + assert.ElementsMatch(t, []string{}, testopk8s.DeploymentNamesUpdated(deploymentsUpdated)) + testopk8s.ClearDeploymentsUpdated(deploymentsUpdated) + + // check that unknown mon is not in endpoint configmap + cm, err = c.context.Clientset.CoreV1().ConfigMaps(c.Namespace).Get(ctx, EndpointConfigMapName, metav1.GetOptions{}) + assert.Nil(t, err) + assert.Empty(t, cm.Data[EndpointExternalMonsKey]) + monsFromCM = controller.ParseMonEndpoints(cm.Data[EndpointDataKey]) + assert.Len(t, monsFromCM, 4) + for id, mon := range monsFromCM { + assert.Equal(t, inital5Mons[id].Name, mon.Name) + assert.Equal(t, inital5Mons[id].Endpoint, mon.Endpoint) + assert.Equal(t, inital5Mons[id].OutOfQuorum, mon.OutOfQuorum) + } + + // 4. upscale back to 5: + c.spec.Mon.Count = 5 + monQuorumResponse = clienttest.MonInQuorumResponseFromMons(c.ClusterInfo.InternalMonitors) + + err = c.checkHealth(ctx) + assert.Nil(t, err) + assert.Equal(t, 5, len(c.ClusterInfo.InternalMonitors)) + assert.Empty(t, c.ClusterInfo.ExternalMons) + // No updates in unit tests w/ workaround + assert.Len(t, testopk8s.DeploymentNamesUpdated(deploymentsUpdated), 4) + testopk8s.ClearDeploymentsUpdated(deploymentsUpdated) + + // check that unknown mon is not in endpoint configmap + cm, err = c.context.Clientset.CoreV1().ConfigMaps(c.Namespace).Get(ctx, EndpointConfigMapName, metav1.GetOptions{}) + assert.Nil(t, err) + assert.Empty(t, cm.Data[EndpointExternalMonsKey]) + monsFromCM = controller.ParseMonEndpoints(cm.Data[EndpointDataKey]) + assert.Len(t, monsFromCM, 5) + for id, mon := range monsFromCM { + assert.Equal(t, c.ClusterInfo.InternalMonitors[id].Name, mon.Name) + assert.Equal(t, c.ClusterInfo.InternalMonitors[id].Endpoint, mon.Endpoint) + assert.Equal(t, c.ClusterInfo.InternalMonitors[id].OutOfQuorum, mon.OutOfQuorum) + } + +} + +func TestExternalMons_inSpec_notInQuorum(t *testing.T) { + // 1. setup test + ctx := context.TODO() + var deploymentsUpdated *[]*apps.Deployment + updateDeploymentAndWait, deploymentsUpdated = testopk8s.UpdateDeploymentAndWaitStub() + + monQuorumResponse := clienttest.MonInQuorumResponse() + executor := &exectest.MockExecutor{ + MockExecuteCommandWithOutput: func(command string, args ...string) (string, error) { + logger.Infof("executing command: %s %+v", command, args) + if args[0] == "auth" && args[1] == "get-or-create-key" { + return "{\"key\":\"mysecurekey\"}", nil + } + return monQuorumResponse, nil + }, + } + clientset := test.New(t, 1) + configDir := t.TempDir() + context := &clusterd.Context{ + Clientset: clientset, + ConfigDir: configDir, + Executor: executor, + } + ownerInfo := cephclient.NewMinimumOwnerInfoWithOwnerRef() + c := New(ctx, context, "ns", cephv1.ClusterSpec{}, ownerInfo) + setCommonMonProperties(c, 0, cephv1.MonSpec{Count: 5, AllowMultiplePerNode: true}, "myversion") + c.maxMonID = 0 // "a" is max mon id + c.waitForStart = false + + // checking the health will increase the mons as desired all in one go + err := c.checkHealth(ctx) + assert.Nil(t, err) + assert.Equal(t, 5, len(c.ClusterInfo.InternalMonitors), fmt.Sprintf("mons: %v", c.ClusterInfo.InternalMonitors)) + assert.ElementsMatch(t, []string{ + // b is created first, no updates + "rook-ceph-mon-b", // b updated when c created + "rook-ceph-mon-b", "rook-ceph-mon-c", // b and c updated when d created + "rook-ceph-mon-b", "rook-ceph-mon-c", "rook-ceph-mon-d", // etc. + "rook-ceph-mon-b", "rook-ceph-mon-c", "rook-ceph-mon-d", "rook-ceph-mon-e"}, + testopk8s.DeploymentNamesUpdated(deploymentsUpdated)) + testopk8s.ClearDeploymentsUpdated(deploymentsUpdated) + + inital5Mons := make(map[string]*cephclient.MonInfo) + for k, v := range c.ClusterInfo.InternalMonitors { + inital5Mons[k] = v + } + + // 2. add external mon id to spec but not to quorum + c.spec.Mon.ExternalMonIDs = []string{"ext-mon-id"} + + // don't add ext mon to quorum: + monQuorumResponse = clienttest.MonInQuorumResponseFromMons(inital5Mons) + + err = c.checkHealth(ctx) + assert.Nil(t, err) + assert.Equal(t, 5, len(c.ClusterInfo.InternalMonitors)) + assert.Empty(t, c.ClusterInfo.ExternalMons) + + // No updates in unit tests w/ workaround + assert.ElementsMatch(t, []string{}, testopk8s.DeploymentNamesUpdated(deploymentsUpdated)) + testopk8s.ClearDeploymentsUpdated(deploymentsUpdated) + + // check that unknown mon is not in endpoint configmap + cm, err := c.context.Clientset.CoreV1().ConfigMaps(c.Namespace).Get(ctx, EndpointConfigMapName, metav1.GetOptions{}) + assert.Nil(t, err) + assert.Empty(t, cm.Data[EndpointExternalMonsKey]) + monsFromCM := controller.ParseMonEndpoints(cm.Data[EndpointDataKey]) + assert.Len(t, monsFromCM, 5) + for id, mon := range monsFromCM { + assert.Equal(t, inital5Mons[id].Name, mon.Name) + assert.Equal(t, inital5Mons[id].Endpoint, mon.Endpoint) + assert.Equal(t, inital5Mons[id].OutOfQuorum, mon.OutOfQuorum) + } + + // 3. downscale mons to 4: + c.spec.Mon.Count = 4 + + err = c.checkHealth(ctx) + assert.Nil(t, err) + assert.Equal(t, 4, len(c.ClusterInfo.InternalMonitors)) + assert.Empty(t, c.ClusterInfo.ExternalMons) + // No updates in unit tests w/ workaround + assert.ElementsMatch(t, []string{}, testopk8s.DeploymentNamesUpdated(deploymentsUpdated)) + testopk8s.ClearDeploymentsUpdated(deploymentsUpdated) + + // check that unknown mon is not in endpoint configmap + cm, err = c.context.Clientset.CoreV1().ConfigMaps(c.Namespace).Get(ctx, EndpointConfigMapName, metav1.GetOptions{}) + assert.Nil(t, err) + assert.Empty(t, cm.Data[EndpointExternalMonsKey]) + monsFromCM = controller.ParseMonEndpoints(cm.Data[EndpointDataKey]) + assert.Len(t, monsFromCM, 4) + for id, mon := range monsFromCM { + assert.Equal(t, inital5Mons[id].Name, mon.Name) + assert.Equal(t, inital5Mons[id].Endpoint, mon.Endpoint) + assert.Equal(t, inital5Mons[id].OutOfQuorum, mon.OutOfQuorum) + } + + // 4. upscale back to 5: + c.spec.Mon.Count = 5 + monQuorumResponse = clienttest.MonInQuorumResponseFromMons(c.ClusterInfo.InternalMonitors) + + err = c.checkHealth(ctx) + assert.Nil(t, err) + assert.Equal(t, 5, len(c.ClusterInfo.InternalMonitors)) + assert.Empty(t, c.ClusterInfo.ExternalMons) + // No updates in unit tests w/ workaround + assert.Len(t, testopk8s.DeploymentNamesUpdated(deploymentsUpdated), 4) + testopk8s.ClearDeploymentsUpdated(deploymentsUpdated) + + // check that unknown mon is not in endpoint configmap + cm, err = c.context.Clientset.CoreV1().ConfigMaps(c.Namespace).Get(ctx, EndpointConfigMapName, metav1.GetOptions{}) + assert.Nil(t, err) + assert.Empty(t, cm.Data[EndpointExternalMonsKey]) + monsFromCM = controller.ParseMonEndpoints(cm.Data[EndpointDataKey]) + assert.Len(t, monsFromCM, 5) + for id, mon := range monsFromCM { + assert.Equal(t, c.ClusterInfo.InternalMonitors[id].Name, mon.Name) + assert.Equal(t, c.ClusterInfo.InternalMonitors[id].Endpoint, mon.Endpoint) + assert.Equal(t, c.ClusterInfo.InternalMonitors[id].OutOfQuorum, mon.OutOfQuorum) + } + +} + +func TestExternalMons_inSpec_inQuorum(t *testing.T) { + // 1. setup test + ctx := context.TODO() + var deploymentsUpdated *[]*apps.Deployment + updateDeploymentAndWait, deploymentsUpdated = testopk8s.UpdateDeploymentAndWaitStub() + + monQuorumResponse := clienttest.MonInQuorumResponse() + executor := &exectest.MockExecutor{ + MockExecuteCommandWithOutput: func(command string, args ...string) (string, error) { + logger.Infof("executing command: %s %+v", command, args) + if args[0] == "auth" && args[1] == "get-or-create-key" { + return "{\"key\":\"mysecurekey\"}", nil + } + return monQuorumResponse, nil + }, + } + clientset := test.New(t, 1) + configDir := t.TempDir() + context := &clusterd.Context{ + Clientset: clientset, + ConfigDir: configDir, + Executor: executor, + } + ownerInfo := cephclient.NewMinimumOwnerInfoWithOwnerRef() + c := New(ctx, context, "ns", cephv1.ClusterSpec{}, ownerInfo) + setCommonMonProperties(c, 0, cephv1.MonSpec{Count: 5, AllowMultiplePerNode: true}, "myversion") + c.maxMonID = 0 // "a" is max mon id + c.waitForStart = false + + // checking the health will increase the mons as desired all in one go + err := c.checkHealth(ctx) + assert.Nil(t, err) + assert.Equal(t, 5, len(c.ClusterInfo.InternalMonitors), fmt.Sprintf("mons: %v", c.ClusterInfo.InternalMonitors)) + assert.ElementsMatch(t, []string{ + // b is created first, no updates + "rook-ceph-mon-b", // b updated when c created + "rook-ceph-mon-b", "rook-ceph-mon-c", // b and c updated when d created + "rook-ceph-mon-b", "rook-ceph-mon-c", "rook-ceph-mon-d", // etc. + "rook-ceph-mon-b", "rook-ceph-mon-c", "rook-ceph-mon-d", "rook-ceph-mon-e"}, + testopk8s.DeploymentNamesUpdated(deploymentsUpdated)) + testopk8s.ClearDeploymentsUpdated(deploymentsUpdated) + + inital5Mons := make(map[string]*cephclient.MonInfo) + for k, v := range c.ClusterInfo.InternalMonitors { + inital5Mons[k] = v + } + + // 2. add external mon id to spec + c.spec.Mon.ExternalMonIDs = []string{"ext-mon-id"} + + // add ext mon to quorum: + mons := make(map[string]*cephclient.MonInfo) + for k, v := range inital5Mons { + mons[k] = v + } + mons["ext-mon-id"] = &cephclient.MonInfo{Name: "ext-mon-id", Endpoint: "0.0.0.0:6789"} + monQuorumResponse = clienttest.MonInQuorumResponseFromMons(mons) + + // internal mons and deployments has not changed + err = c.checkHealth(ctx) + assert.Nil(t, err) + assert.Equal(t, 5, len(c.ClusterInfo.InternalMonitors)) + // external mon is in quorum + assert.Len(t, c.ClusterInfo.ExternalMons, 1) + assert.Equal(t, "ext-mon-id", c.ClusterInfo.ExternalMons["ext-mon-id"].Name) + + // No updates in unit tests w/ workaround + assert.ElementsMatch(t, []string{}, testopk8s.DeploymentNamesUpdated(deploymentsUpdated)) + testopk8s.ClearDeploymentsUpdated(deploymentsUpdated) + + // check that ext mon is in endpoint configmap + cm, err := c.context.Clientset.CoreV1().ConfigMaps(c.Namespace).Get(ctx, EndpointConfigMapName, metav1.GetOptions{}) + assert.Nil(t, err) + assert.Equal(t, "ext-mon-id", cm.Data[EndpointExternalMonsKey]) + monsFromCM := controller.ParseMonEndpoints(cm.Data[EndpointDataKey]) + assert.Len(t, monsFromCM, 6) + for id, mon := range monsFromCM { + if id == "ext-mon-id" { + assert.Equal(t, c.ClusterInfo.ExternalMons[id].Name, mon.Name) + assert.Equal(t, c.ClusterInfo.ExternalMons[id].Endpoint, mon.Endpoint) + assert.Equal(t, c.ClusterInfo.ExternalMons[id].OutOfQuorum, mon.OutOfQuorum) + } else { + assert.Equal(t, inital5Mons[id].Name, mon.Name) + assert.Equal(t, inital5Mons[id].Endpoint, mon.Endpoint) + assert.Equal(t, inital5Mons[id].OutOfQuorum, mon.OutOfQuorum) + } + } + + // 3. downscale mons to 4: + c.spec.Mon.Count = 4 + + err = c.checkHealth(ctx) + assert.Nil(t, err) + assert.Equal(t, 4, len(c.ClusterInfo.InternalMonitors)) + assert.Len(t, c.ClusterInfo.ExternalMons, 1) + // No updates in unit tests w/ workaround + assert.ElementsMatch(t, []string{}, testopk8s.DeploymentNamesUpdated(deploymentsUpdated)) + testopk8s.ClearDeploymentsUpdated(deploymentsUpdated) + + // check that unknown mon is not in endpoint configmap + cm, err = c.context.Clientset.CoreV1().ConfigMaps(c.Namespace).Get(ctx, EndpointConfigMapName, metav1.GetOptions{}) + assert.Nil(t, err) + assert.Equal(t, "ext-mon-id", cm.Data[EndpointExternalMonsKey]) + monsFromCM = controller.ParseMonEndpoints(cm.Data[EndpointDataKey]) + assert.Len(t, monsFromCM, 5) + for id, mon := range monsFromCM { + if id == "ext-mon-id" { + assert.Equal(t, c.ClusterInfo.ExternalMons[id].Name, mon.Name) + assert.Equal(t, c.ClusterInfo.ExternalMons[id].Endpoint, mon.Endpoint) + assert.Equal(t, c.ClusterInfo.ExternalMons[id].OutOfQuorum, mon.OutOfQuorum) + } else { + assert.Equal(t, inital5Mons[id].Name, mon.Name) + assert.Equal(t, inital5Mons[id].Endpoint, mon.Endpoint) + assert.Equal(t, inital5Mons[id].OutOfQuorum, mon.OutOfQuorum) + } + } + + // 4. upscale back to 5: + c.spec.Mon.Count = 5 + mons = make(map[string]*cephclient.MonInfo) + for k, v := range c.ClusterInfo.InternalMonitors { + mons[k] = v + } + mons["ext-mon-id"] = &cephclient.MonInfo{Name: "ext-mon-id", Endpoint: "0.0.0.0:6789"} + monQuorumResponse = clienttest.MonInQuorumResponseFromMons(mons) + + err = c.checkHealth(ctx) + assert.Nil(t, err) + assert.Equal(t, 5, len(c.ClusterInfo.InternalMonitors)) + assert.Len(t, c.ClusterInfo.ExternalMons, 1) + // No updates in unit tests w/ workaround + assert.Len(t, testopk8s.DeploymentNamesUpdated(deploymentsUpdated), 4) + testopk8s.ClearDeploymentsUpdated(deploymentsUpdated) + + // check that unknown mon is not in endpoint configmap + cm, err = c.context.Clientset.CoreV1().ConfigMaps(c.Namespace).Get(ctx, EndpointConfigMapName, metav1.GetOptions{}) + assert.Nil(t, err) + assert.Equal(t, "ext-mon-id", cm.Data[EndpointExternalMonsKey]) + monsFromCM = controller.ParseMonEndpoints(cm.Data[EndpointDataKey]) + assert.Len(t, monsFromCM, 6) + for id, mon := range monsFromCM { + if id == "ext-mon-id" { + assert.Equal(t, c.ClusterInfo.ExternalMons[id].Name, mon.Name) + assert.Equal(t, c.ClusterInfo.ExternalMons[id].Endpoint, mon.Endpoint) + assert.Equal(t, c.ClusterInfo.ExternalMons[id].OutOfQuorum, mon.OutOfQuorum) + } else { + assert.Equal(t, c.ClusterInfo.InternalMonitors[id].Name, mon.Name) + assert.Equal(t, c.ClusterInfo.InternalMonitors[id].Endpoint, mon.Endpoint) + assert.Equal(t, c.ClusterInfo.InternalMonitors[id].OutOfQuorum, mon.OutOfQuorum) + } + } +} diff --git a/pkg/operator/ceph/cluster/mon/mon.go b/pkg/operator/ceph/cluster/mon/mon.go index df8fc7ff3e20..4d059b39cc72 100644 --- a/pkg/operator/ceph/cluster/mon/mon.go +++ b/pkg/operator/ceph/cluster/mon/mon.go @@ -58,6 +58,8 @@ const ( EndpointConfigMapName = "rook-ceph-mon-endpoints" // EndpointDataKey is the name of the key inside the mon configmap to get the endpoints EndpointDataKey = "data" + // EndpointExternalMonsKey key in EndpointConfigMapName configmap containing IDs of external mons + EndpointExternalMonsKey = "externalMons" // AppName is the name of the secret storing cluster mon.admin key, fsid and name AppName = "rook-ceph-mon" //nolint:gosec // OperatorCreds is the name of the secret @@ -303,7 +305,7 @@ func (c *Cluster) startMons(targetCount int) error { } } - logger.Debugf("mon endpoints used are: %s", flattenMonEndpoints(c.ClusterInfo.Monitors)) + logger.Debugf("mon endpoints used are: %s", flattenMonEndpoints(c.ClusterInfo.AllMonitors())) // reconcile mon PDB if err := c.reconcileMonPDB(); err != nil { @@ -484,7 +486,7 @@ func (c *Cluster) ensureMonsRunning(mons []*monConfig, i, targetCount int, requi // Calculate how many mons we expected to exist after this method is completed. // If we are adding a new mon, we expect one more than currently exist. // If we haven't created all the desired mons already, we will be adding a new one with this iteration - expectedMonCount := len(c.ClusterInfo.Monitors) + expectedMonCount := len(c.ClusterInfo.InternalMonitors) if expectedMonCount < targetCount { expectedMonCount++ } @@ -548,13 +550,12 @@ func (c *Cluster) initClusterInfo(cephVersion cephver.CephVersion, clusterName s } func (c *Cluster) initMonConfig(size int) (int, []*monConfig, error) { - // initialize the mon pod info for mons that have been previously created mons := c.clusterInfoToMonConfig() // initialize mon info if we don't have enough mons (at first startup) - existingCount := len(c.ClusterInfo.Monitors) - for i := len(c.ClusterInfo.Monitors); i < size; i++ { + existingCount := len(c.ClusterInfo.InternalMonitors) + for i := len(c.ClusterInfo.InternalMonitors); i < size; i++ { c.maxMonID++ zone, err := c.findAvailableZone(mons) if err != nil { @@ -572,7 +573,7 @@ func (c *Cluster) clusterInfoToMonConfig() []*monConfig { func (c *Cluster) clusterInfoToMonConfigWithExclude(excludedMon string) []*monConfig { mons := []*monConfig{} - for _, monitor := range c.ClusterInfo.Monitors { + for _, monitor := range c.ClusterInfo.InternalMonitors { if monitor.Name == excludedMon { // Skip a mon if it is being failed over continue @@ -851,7 +852,7 @@ func (c *Cluster) initMonIPs(mons []*monConfig) error { } } } - c.ClusterInfo.Monitors[m.DaemonName] = cephclient.NewMonInfo(m.DaemonName, m.PublicIP, m.Port) + c.ClusterInfo.InternalMonitors[m.DaemonName] = cephclient.NewMonInfo(m.DaemonName, m.PublicIP, m.Port) } return nil @@ -1160,7 +1161,7 @@ func (c *Cluster) saveMonConfig() error { return errors.Wrap(err, "failed to write connection config for new mons") } - monEndpoints := csi.MonEndpoints(c.ClusterInfo.Monitors, c.spec.RequireMsgr2()) + monEndpoints := csi.MonEndpoints(c.ClusterInfo.AllMonitors(), c.spec.RequireMsgr2()) csiConfigEntry := &csi.CSIClusterConfigEntry{ Namespace: c.ClusterInfo.Namespace, ClusterInfo: cephcsi.ClusterInfo{ @@ -1173,7 +1174,7 @@ func (c *Cluster) saveMonConfig() error { return errors.Wrap(err, "failed to update csi cluster config") } - if csi.EnableCSIOperator() && len(c.ClusterInfo.Monitors) > 0 { + if csi.EnableCSIOperator() && len(c.ClusterInfo.AllMonitors()) > 0 { err := csi.CreateUpdateCephConnection(c.context.Client, c.ClusterInfo, c.spec) if err != nil { return errors.Wrap(err, "failed to create/update cephConnection") @@ -1207,7 +1208,7 @@ func (c *Cluster) persistExpectedMonDaemons() error { } csiConfigValue, err := csi.FormatCsiClusterConfig( - c.Namespace, c.ClusterInfo.Monitors) + c.Namespace, c.ClusterInfo.AllMonitors()) if err != nil { return errors.Wrap(err, "failed to format csi config") } @@ -1219,14 +1220,21 @@ func (c *Cluster) persistExpectedMonDaemons() error { // preserve the mons detected out of quorum var monsOutOfQuorum []string - for monName, mon := range c.ClusterInfo.Monitors { + for monName, mon := range c.ClusterInfo.InternalMonitors { if mon.OutOfQuorum { monsOutOfQuorum = append(monsOutOfQuorum, monName) } } + extMonIDs := make([]string, 0, len(c.ClusterInfo.ExternalMons)) + if c.ClusterInfo.ExternalMons != nil { + for monID := range c.ClusterInfo.ExternalMons { + extMonIDs = append(extMonIDs, monID) + } + } configMap.Data = map[string]string{ - EndpointDataKey: flattenMonEndpoints(c.ClusterInfo.Monitors), + EndpointDataKey: flattenMonEndpoints(c.ClusterInfo.AllMonitors()), + EndpointExternalMonsKey: strings.Join(extMonIDs, ","), // persist the maxMonID that was previously stored in the configmap. We are likely saving info // about scheduling of the mons, but we only want to update the maxMonID once a new mon has // actually been started. If the operator is restarted or the reconcile is otherwise restarted, diff --git a/pkg/operator/ceph/cluster/mon/mon_test.go b/pkg/operator/ceph/cluster/mon/mon_test.go index b4c5e0f5b06b..a481ec4d7452 100644 --- a/pkg/operator/ceph/cluster/mon/mon_test.go +++ b/pkg/operator/ceph/cluster/mon/mon_test.go @@ -288,8 +288,8 @@ func TestPersistMons(t *testing.T) { assert.Equal(t, map[string]string{"key": "value"}, cm.Annotations) // Persist mon b, and remove mon a for simply testing the configmap is updated - c.ClusterInfo.Monitors["b"] = &cephclient.MonInfo{Name: "b", Endpoint: "4.5.6.7:3300"} - delete(c.ClusterInfo.Monitors, "a") + c.ClusterInfo.InternalMonitors["b"] = &cephclient.MonInfo{Name: "b", Endpoint: "4.5.6.7:3300"} + delete(c.ClusterInfo.InternalMonitors, "a") err = c.persistExpectedMonDaemons() assert.NoError(t, err) @@ -317,7 +317,7 @@ func TestSaveMonEndpoints(t *testing.T) { assert.Equal(t, "-1", cm.Data[opcontroller.MaxMonIDKey]) // update the config map - c.ClusterInfo.Monitors["a"].Endpoint = "2.3.4.5:6789" + c.ClusterInfo.InternalMonitors["a"].Endpoint = "2.3.4.5:6789" c.maxMonID = 2 c.mapping.Schedule["a"] = &opcontroller.MonScheduleInfo{ Name: "node0", diff --git a/pkg/operator/ceph/cluster/mon/util.go b/pkg/operator/ceph/cluster/mon/util.go index f688a37944c7..39b20e5828b9 100644 --- a/pkg/operator/ceph/cluster/mon/util.go +++ b/pkg/operator/ceph/cluster/mon/util.go @@ -17,6 +17,7 @@ limitations under the License. package mon import ( + "slices" "strings" "github.com/rook/rook/pkg/daemon/ceph/client" @@ -34,6 +35,17 @@ func monInQuorum(monitor client.MonMapEntry, quorum []int) bool { return false } +func getMonByID(monID string, monMap client.MonStatusResponse) (info client.MonMapEntry, inQuorum bool) { + for _, mon := range monMap.MonMap.Mons { + if mon.Name != monID { + continue + } + monRank := mon.Rank + return mon, slices.Contains(monMap.Quorum, monRank) + } + return client.MonMapEntry{}, false +} + // convert the mon name to the numeric mon ID func fullNameToIndex(name string) (int, error) { // remove the "rook-ceph-mon" prefix diff --git a/pkg/operator/ceph/config/store_test.go b/pkg/operator/ceph/config/store_test.go index 902a72e4c7da..e9a2962b74ec 100644 --- a/pkg/operator/ceph/config/store_test.go +++ b/pkg/operator/ceph/config/store_test.go @@ -45,25 +45,25 @@ func TestStore(t *testing.T) { sec, e := clientset.CoreV1().Secrets(ns).Get(ctxt, StoreName, metav1.GetOptions{}) assert.NoError(t, e) mh := strings.Split(sec.StringData["mon_host"], ",") // list of mon ip:port pairs in cluster - expectedEndpoints := len(ci.Monitors) + expectedEndpoints := len(ci.InternalMonitors) if mon1EndpointsEnabled { expectedEndpoints *= 2 } - assert.Equal(t, expectedEndpoints, len(mh), ci.Monitors["a"].Endpoint) // we need to pass x2 since we split on "," above and that returns msgr1 and msgr2 addresses - mim := strings.Split(sec.StringData["mon_initial_members"], ",") // list of mon ids in cluster - assert.Equal(t, len(ci.Monitors), len(mim)) + assert.Equal(t, expectedEndpoints, len(mh), ci.InternalMonitors["a"].Endpoint) // we need to pass x2 since we split on "," above and that returns msgr1 and msgr2 addresses + mim := strings.Split(sec.StringData["mon_initial_members"], ",") // list of mon ids in cluster + assert.Equal(t, len(ci.InternalMonitors), len(mim)) // make sure every mon has its id/ip:port in mon_initial_members/mon_host for _, id := range mim { // cannot use "assert.Contains(t, mh, ci.Monitors[id].Endpoint)" // it looks like the value is not found but if present, it might be confused by the brackets contains := false for _, c := range mh { - if strings.Contains(c, ci.Monitors[id].Endpoint) { + if strings.Contains(c, ci.InternalMonitors[id].Endpoint) { contains = true } } assert.True(t, contains) - assert.Contains(t, mim, ci.Monitors[id].Name) + assert.Contains(t, mim, ci.InternalMonitors[id].Name) } } @@ -80,14 +80,14 @@ func TestStore(t *testing.T) { // Now run the same test for v1 endpoints mon1EndpointsEnabled = true - for _, mon := range i1.Monitors { + for _, mon := range i1.InternalMonitors { mon.Endpoint = "1.2.3.4:6789" } err = s.CreateOrUpdate(i1) assert.NoError(t, err) assertConfigStore(i1) - for _, mon := range i3.Monitors { + for _, mon := range i3.InternalMonitors { mon.Endpoint = "1.2.3.4:6789" } err = s.CreateOrUpdate(i3) diff --git a/pkg/operator/ceph/controller/cluster_info.go b/pkg/operator/ceph/controller/cluster_info.go index 2da3191ca431..7a4d3851dce3 100644 --- a/pkg/operator/ceph/controller/cluster_info.go +++ b/pkg/operator/ceph/controller/cluster_info.go @@ -23,6 +23,7 @@ import ( "os" "path" "path/filepath" + "slices" "strconv" "strings" "time" @@ -56,6 +57,8 @@ const ( EndpointConfigMapName = "rook-ceph-mon-endpoints" // EndpointDataKey is the name of the key inside the mon configmap to get the endpoints EndpointDataKey = "data" + // EndpointExternalMonsKey key in EndpointConfigMapName configmap containing IDs of external mons + EndpointExternalMonsKey = "externalMons" // OutOfQuorumKey is the name of the key for tracking mons detected out of quorum OutOfQuorumKey = "outOfQuorum" // MaxMonIDKey is the name of the max mon id used @@ -148,7 +151,7 @@ func CreateOrLoadClusterInfo(clusterdContext *clusterd.Context, context context. } // get the existing monitor config - clusterInfo.Monitors, maxMonID, monMapping, err = loadMonConfig(clusterdContext.Clientset, namespace) + clusterInfo.ExternalMons, clusterInfo.InternalMonitors, maxMonID, monMapping, err = loadMonConfig(clusterdContext.Clientset, namespace) if err != nil { return nil, maxMonID, monMapping, errors.Wrap(err, "failed to get mon config") } @@ -276,33 +279,34 @@ func UpdateMonsOutOfQuorum(clientset kubernetes.Interface, namespace string, mon } // loadMonConfig returns the monitor endpoints and maxMonID -func loadMonConfig(clientset kubernetes.Interface, namespace string) (map[string]*cephclient.MonInfo, int, *Mapping, error) { +func loadMonConfig(clientset kubernetes.Interface, namespace string) (extMons map[string]*cephclient.MonInfo, internalMons map[string]*cephclient.MonInfo, maxMonID int, monMapping *Mapping, err error) { ctx := context.TODO() - monEndpointMap := map[string]*cephclient.MonInfo{} - maxMonID := -1 - monMapping := &Mapping{ + extMons = map[string]*cephclient.MonInfo{} + internalMons = map[string]*cephclient.MonInfo{} + maxMonID = -1 + monMapping = &Mapping{ Schedule: map[string]*MonScheduleInfo{}, } cm, err := clientset.CoreV1().ConfigMaps(namespace).Get(ctx, EndpointConfigMapName, metav1.GetOptions{}) if err != nil { if !kerrors.IsNotFound(err) { - return nil, maxMonID, monMapping, err + return nil, nil, maxMonID, monMapping, err } // If the config map was not found, initialize the empty set of monitors - return monEndpointMap, maxMonID, monMapping, nil + return extMons, internalMons, maxMonID, monMapping, nil } // Parse the monitor List if info, ok := cm.Data[EndpointDataKey]; ok { - monEndpointMap = ParseMonEndpoints(info) + internalMons = ParseMonEndpoints(info) } // Parse the mons that were detected out of quorum if outOfQuorum, ok := cm.Data[OutOfQuorumKey]; ok && len(outOfQuorum) > 0 { monNames := strings.Split(outOfQuorum, ",") for _, monName := range monNames { - if monInfo, ok := monEndpointMap[monName]; ok { + if monInfo, ok := internalMons[monName]; ok { monInfo.OutOfQuorum = true } else { logger.Warningf("did not find mon %q to set it out of quorum in the cluster info", monName) @@ -322,7 +326,7 @@ func loadMonConfig(clientset kubernetes.Interface, namespace string) (map[string } // Make sure the max id is consistent with the current monitors - for _, m := range monEndpointMap { + for _, m := range internalMons { id, _ := fullNameToIndex(m.Name) if maxMonID < id { maxMonID = id @@ -336,9 +340,19 @@ func loadMonConfig(clientset kubernetes.Interface, namespace string) (map[string if err != nil { logger.Errorf("invalid JSON in mon mapping. %v", err) } + // filter external mons: + if extMonIDsStr, ok := cm.Data[EndpointExternalMonsKey]; ok && extMonIDsStr != "" { + extMonIDs := strings.Split(extMonIDsStr, ",") + for monID, mon := range internalMons { + if slices.Contains(extMonIDs, monID) { + extMons[monID] = mon + delete(internalMons, monID) + } + } + } - logger.Debugf("loaded: maxMonID=%d, mons=%+v, assignment=%+v", maxMonID, monEndpointMap, monMapping) - return monEndpointMap, maxMonID, monMapping, nil + logger.Debugf("loaded: maxMonID=%d, extMons=%+v, mons=%+v, assignment=%+v", maxMonID, extMons, internalMons, monMapping) + return extMons, internalMons, maxMonID, monMapping, nil } // convert the mon name to the numeric mon ID @@ -413,7 +427,7 @@ func PopulateExternalClusterInfo(cephClusterSpec *cephv1.ClusterSpec, context *c time.Sleep(externalConnectionRetry) continue } - logger.Infof("found the cluster info to connect to the external cluster. will use %q to check health and monitor status. mons=%+v", clusterInfo.CephCred.Username, clusterInfo.Monitors) + logger.Infof("found the cluster info to connect to the external cluster. will use %q to check health and monitor status. mons=%+v", clusterInfo.CephCred.Username, clusterInfo.AllMonitors()) clusterInfo.OwnerInfo = ownerInfo return clusterInfo, nil diff --git a/pkg/operator/ceph/csi/ceph_connection.go b/pkg/operator/ceph/csi/ceph_connection.go index 518b09d2f573..61d89c57b8ee 100644 --- a/pkg/operator/ceph/csi/ceph_connection.go +++ b/pkg/operator/ceph/csi/ceph_connection.go @@ -91,7 +91,7 @@ func generateCephConnSpec(c client.Client, clusterInfo *cephclient.ClusterInfo, csiClusterConnSpec.RbdMirrorDaemonCount = cephRBDMirrorList.Items[0].Spec.Count } - for _, mon := range clusterInfo.Monitors { + for _, mon := range clusterInfo.AllMonitors() { csiClusterConnSpec.Monitors = append(csiClusterConnSpec.Monitors, mon.Endpoint) } diff --git a/pkg/operator/ceph/file/subvolumegroup/controller.go b/pkg/operator/ceph/file/subvolumegroup/controller.go index e5605785af32..2969f00b791f 100644 --- a/pkg/operator/ceph/file/subvolumegroup/controller.go +++ b/pkg/operator/ceph/file/subvolumegroup/controller.go @@ -298,7 +298,7 @@ func (r *ReconcileCephFilesystemSubVolumeGroup) updateClusterConfig(cephFilesyst csiClusterConfigEntry := csi.CSIClusterConfigEntry{ Namespace: r.clusterInfo.Namespace, ClusterInfo: cephcsi.ClusterInfo{ - Monitors: csi.MonEndpoints(r.clusterInfo.Monitors, cephCluster.Spec.RequireMsgr2()), + Monitors: csi.MonEndpoints(r.clusterInfo.AllMonitors(), cephCluster.Spec.RequireMsgr2()), CephFS: cephcsi.CephFS{ SubvolumeGroup: getSubvolumeGroupName(cephFilesystemSubVolumeGroup), KernelMountOptions: r.clusterInfo.CSIDriverSpec.CephFS.KernelMountOptions, diff --git a/pkg/operator/ceph/pool/radosnamespace/controller.go b/pkg/operator/ceph/pool/radosnamespace/controller.go index bbac0c9cc11f..14974bdf6b99 100644 --- a/pkg/operator/ceph/pool/radosnamespace/controller.go +++ b/pkg/operator/ceph/pool/radosnamespace/controller.go @@ -323,7 +323,7 @@ func (r *ReconcileCephBlockPoolRadosNamespace) updateClusterConfig(cephBlockPool csiClusterConfigEntry := csi.CSIClusterConfigEntry{ Namespace: r.clusterInfo.Namespace, ClusterInfo: cephcsi.ClusterInfo{ - Monitors: csi.MonEndpoints(r.clusterInfo.Monitors, cephCluster.Spec.RequireMsgr2()), + Monitors: csi.MonEndpoints(r.clusterInfo.AllMonitors(), cephCluster.Spec.RequireMsgr2()), RBD: cephcsi.RBD{ RadosNamespace: getRadosNamespaceName(cephBlockPoolRadosNamespace), }, From 1ba567a39e06e5d8fd72676e9fbb95f6e594a140 Mon Sep 17 00:00:00 2001 From: subhamkrai Date: Mon, 3 Mar 2025 22:11:01 +0530 Subject: [PATCH 08/16] ci: use github token instead of api token github token should be used intead of api token for ghcr Signed-off-by: subhamkrai --- .github/workflows/push-build.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/push-build.yaml b/.github/workflows/push-build.yaml index 99cf72b890db..36da1fdb28ce 100644 --- a/.github/workflows/push-build.yaml +++ b/.github/workflows/push-build.yaml @@ -53,7 +53,7 @@ jobs: with: registry: ghcr.io username: ${{ github.actor }} - password: ${{ secrets.GIT_API_TOKEN }} + password: ${{ secrets.GITHUB_TOKEN }} - name: Configure AWS Credentials uses: aws-actions/configure-aws-credentials@ececac1a45f3b08a01d2dd070d28d111c5fe6722 # v4.1.0 From 62ee784ae31b734f2af7704f0de1271ea8f419a8 Mon Sep 17 00:00:00 2001 From: Travis Nielsen Date: Mon, 3 Mar 2025 10:29:58 -0700 Subject: [PATCH 09/16] ci: add packages write permission for ghcr Publishing packages to ghcr requires the packages write permission Signed-off-by: Travis Nielsen --- .github/workflows/push-build.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/push-build.yaml b/.github/workflows/push-build.yaml index 36da1fdb28ce..af40e27ac1bf 100644 --- a/.github/workflows/push-build.yaml +++ b/.github/workflows/push-build.yaml @@ -14,6 +14,7 @@ defaults: permissions: contents: read + packages: write jobs: push-image-to-container-registry: From c79d28669b5a6330eb890cdeebd2aa014d0d51d4 Mon Sep 17 00:00:00 2001 From: Artem Torubarov Date: Mon, 3 Mar 2025 18:53:58 +0100 Subject: [PATCH 10/16] ci: add external mon to pending release notes Signed-off-by: Artem Torubarov --- PendingReleaseNotes.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/PendingReleaseNotes.md b/PendingReleaseNotes.md index 252f70b28a7c..faf45c2b662a 100644 --- a/PendingReleaseNotes.md +++ b/PendingReleaseNotes.md @@ -13,3 +13,5 @@ Object: See https://github.com/rook/rook/pull/15376 for more information. ## Features + +- Support external mons for local Rook cluster (see [#14733](https://github.com/rook/rook/issues/14733)). From fda1189dbf644a9a95bc015bac387d28af20f985 Mon Sep 17 00:00:00 2001 From: Patryk Rostkowski Date: Mon, 3 Mar 2025 13:07:25 +0100 Subject: [PATCH 11/16] exporter: add missing rook-ceph-exporter container port definition Adds the missing exporter container port to enable proper Prometheus scraping and filtering. Signed-off-by: Patryk Rostkowski --- pkg/operator/ceph/cluster/nodedaemon/exporter.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/pkg/operator/ceph/cluster/nodedaemon/exporter.go b/pkg/operator/ceph/cluster/nodedaemon/exporter.go index cbd0495e50e3..8fb73b6212e2 100644 --- a/pkg/operator/ceph/cluster/nodedaemon/exporter.go +++ b/pkg/operator/ceph/cluster/nodedaemon/exporter.go @@ -198,6 +198,11 @@ func getCephExporterDaemonContainer(cephCluster cephv1.CephCluster, cephVersion args = append(args, "--addrs", "::") } + containerPort := corev1.ContainerPort{ + ContainerPort: int32(DefaultMetricsPort), + Protocol: corev1.ProtocolTCP, + } + container := corev1.Container{ Name: "ceph-exporter", Command: []string{"ceph-exporter"}, @@ -205,6 +210,7 @@ func getCephExporterDaemonContainer(cephCluster cephv1.CephCluster, cephVersion Image: cephImage, ImagePullPolicy: controller.GetContainerImagePullPolicy(cephCluster.Spec.CephVersion.ImagePullPolicy), Env: envVars, + Ports: []corev1.ContainerPort{containerPort}, VolumeMounts: volumeMounts, Resources: cephv1.GetCephExporterResources(cephCluster.Spec.Resources), SecurityContext: controller.PodSecurityContext(), From 25d3b6d5fc8dd7199eecad7a97d9fcd783bbca57 Mon Sep 17 00:00:00 2001 From: Niels de Vos Date: Wed, 5 Mar 2025 09:35:41 +0100 Subject: [PATCH 12/16] csi: update csi-addons to v0.12.0 The csi-addons v0.12.0 release is now available. See-also: https://github.com/csi-addons/kubernetes-csi-addons/releases/tag/v0.12.0 Signed-off-by: Niels de Vos --- Documentation/Helm-Charts/operator-chart.md | 2 +- .../Ceph-CSI/ceph-csi-drivers.md | 32 +++++++++---------- .../Ceph-CSI/custom-images.md | 2 +- deploy/charts/rook-ceph/values.yaml | 2 +- deploy/examples/images.txt | 2 +- deploy/examples/operator-openshift.yaml | 2 +- deploy/examples/operator.yaml | 2 +- pkg/operator/ceph/csi/spec.go | 2 +- tests/scripts/csiaddons.sh | 2 +- 9 files changed, 24 insertions(+), 24 deletions(-) diff --git a/Documentation/Helm-Charts/operator-chart.md b/Documentation/Helm-Charts/operator-chart.md index 4307fc083af1..d9a5fa281525 100644 --- a/Documentation/Helm-Charts/operator-chart.md +++ b/Documentation/Helm-Charts/operator-chart.md @@ -66,7 +66,7 @@ The following table lists the configurable parameters of the rook-operator chart | `csi.clusterName` | Cluster name identifier to set as metadata on the CephFS subvolume and RBD images. This will be useful in cases like for example, when two container orchestrator clusters (Kubernetes/OCP) are using a single ceph cluster | `nil` | | `csi.csiAddons.enabled` | Enable CSIAddons | `false` | | `csi.csiAddons.repository` | CSIAddons sidecar image repository | `"quay.io/csiaddons/k8s-sidecar"` | -| `csi.csiAddons.tag` | CSIAddons sidecar image tag | `"v0.11.0"` | +| `csi.csiAddons.tag` | CSIAddons sidecar image tag | `"v0.12.0"` | | `csi.csiAddonsCephFSProvisionerPort` | CSI Addons server port for the Ceph FS provisioner | `9070` | | `csi.csiAddonsPort` | CSI Addons server port | `9070` | | `csi.csiAddonsRBDProvisionerPort` | CSI Addons server port for the RBD provisioner | `9070` | diff --git a/Documentation/Storage-Configuration/Ceph-CSI/ceph-csi-drivers.md b/Documentation/Storage-Configuration/Ceph-CSI/ceph-csi-drivers.md index 17ca0d0ac3d8..75f43859cd73 100644 --- a/Documentation/Storage-Configuration/Ceph-CSI/ceph-csi-drivers.md +++ b/Documentation/Storage-Configuration/Ceph-CSI/ceph-csi-drivers.md @@ -166,9 +166,9 @@ that the controller inspects and forwards to one or more CSI-Addons sidecars for Deploy the controller by running the following commands: ```console -kubectl create -f https://github.com/csi-addons/kubernetes-csi-addons/releases/download/v0.11.0/crds.yaml -kubectl create -f https://github.com/csi-addons/kubernetes-csi-addons/releases/download/v0.11.0/rbac.yaml -kubectl create -f https://github.com/csi-addons/kubernetes-csi-addons/releases/download/v0.11.0/setup-controller.yaml +kubectl create -f https://github.com/csi-addons/kubernetes-csi-addons/releases/download/v0.12.0/crds.yaml +kubectl create -f https://github.com/csi-addons/kubernetes-csi-addons/releases/download/v0.12.0/rbac.yaml +kubectl create -f https://github.com/csi-addons/kubernetes-csi-addons/releases/download/v0.12.0/setup-controller.yaml ``` This creates the required CRDs and configures permissions. @@ -196,22 +196,22 @@ Execute the following to enable the CSI-Addons sidecars: CSI-Addons supports the following operations: * Reclaim Space - * [Creating a ReclaimSpaceJob](https://github.com/csi-addons/kubernetes-csi-addons/blob/v0.11.0/docs/reclaimspace.md#reclaimspacejob) - * [Creating a ReclaimSpaceCronJob](https://github.com/csi-addons/kubernetes-csi-addons/blob/v0.11.0/docs/reclaimspace.md#reclaimspacecronjob) - * [Annotating PersistentVolumeClaims](https://github.com/csi-addons/kubernetes-csi-addons/blob/v0.11.0/docs/reclaimspace.md#annotating-perstentvolumeclaims) - * [Annotating Namespace](https://github.com/csi-addons/kubernetes-csi-addons/blob/v0.11.0/docs/reclaimspace.md#annotating-namespace) - * [Annotating StorageClass](https://github.com/csi-addons/kubernetes-csi-addons/blob/v0.11.0/docs/reclaimspace.md#annotating-storageclass) + * [Creating a ReclaimSpaceJob](https://github.com/csi-addons/kubernetes-csi-addons/blob/v0.12.0/docs/reclaimspace.md#reclaimspacejob) + * [Creating a ReclaimSpaceCronJob](https://github.com/csi-addons/kubernetes-csi-addons/blob/v0.12.0/docs/reclaimspace.md#reclaimspacecronjob) + * [Annotating PersistentVolumeClaims](https://github.com/csi-addons/kubernetes-csi-addons/blob/v0.12.0/docs/reclaimspace.md#annotating-perstentvolumeclaims) + * [Annotating Namespace](https://github.com/csi-addons/kubernetes-csi-addons/blob/v0.12.0/docs/reclaimspace.md#annotating-namespace) + * [Annotating StorageClass](https://github.com/csi-addons/kubernetes-csi-addons/blob/v0.12.0/docs/reclaimspace.md#annotating-storageclass) * Network Fencing - * [Creating a NetworkFence](https://github.com/csi-addons/kubernetes-csi-addons/blob/v0.11.0/docs/networkfence.md) + * [Creating a NetworkFence](https://github.com/csi-addons/kubernetes-csi-addons/blob/v0.12.0/docs/networkfence.md) * Volume Replication - * [Creating VolumeReplicationClass](https://github.com/csi-addons/kubernetes-csi-addons/blob/v0.11.0/docs/volumereplicationclass.md) - * [Creating VolumeReplication CR](https://github.com/csi-addons/kubernetes-csi-addons/blob/v0.11.0/docs/volumereplication.md) + * [Creating VolumeReplicationClass](https://github.com/csi-addons/kubernetes-csi-addons/blob/v0.12.0/docs/volumereplicationclass.md) + * [Creating VolumeReplication CR](https://github.com/csi-addons/kubernetes-csi-addons/blob/v0.12.0/docs/volumereplication.md) * Key Rotation Job for PV encryption - * [Creating EncryptionKeyRotationJob](https://github.com/csi-addons/kubernetes-csi-addons/blob/v0.11.0/docs/encryptionkeyrotation.md#encryptionkeyrotationjob) - * [Creating EncryptionKeyRotationCronJob](https://github.com/csi-addons/kubernetes-csi-addons/blob/v0.11.0/docs/encryptionkeyrotation.md#encryptionkeyrotationcronjob) - * [Annotating PersistentVolumeClaims](https://github.com/csi-addons/kubernetes-csi-addons/blob/v0.11.0/docs/encryptionkeyrotation.md#annotating-persistentvolumeclaims) - * [Annotating Namespace](https://github.com/csi-addons/kubernetes-csi-addons/blob/v0.11.0/docs/encryptionkeyrotation.md#annotating-namespace) - * [Annotating StorageClass](https://github.com/csi-addons/kubernetes-csi-addons/blob/v0.11.0/docs/encryptionkeyrotation.md#annotating-storageclass) + * [Creating EncryptionKeyRotationJob](https://github.com/csi-addons/kubernetes-csi-addons/blob/v0.12.0/docs/encryptionkeyrotation.md#encryptionkeyrotationjob) + * [Creating EncryptionKeyRotationCronJob](https://github.com/csi-addons/kubernetes-csi-addons/blob/v0.12.0/docs/encryptionkeyrotation.md#encryptionkeyrotationcronjob) + * [Annotating PersistentVolumeClaims](https://github.com/csi-addons/kubernetes-csi-addons/blob/v0.12.0/docs/encryptionkeyrotation.md#annotating-persistentvolumeclaims) + * [Annotating Namespace](https://github.com/csi-addons/kubernetes-csi-addons/blob/v0.12.0/docs/encryptionkeyrotation.md#annotating-namespace) + * [Annotating StorageClass](https://github.com/csi-addons/kubernetes-csi-addons/blob/v0.12.0/docs/encryptionkeyrotation.md#annotating-storageclass) ## Enable RBD and CephFS Encryption Support diff --git a/Documentation/Storage-Configuration/Ceph-CSI/custom-images.md b/Documentation/Storage-Configuration/Ceph-CSI/custom-images.md index 88b5b68403ca..3e0fffd6012a 100644 --- a/Documentation/Storage-Configuration/Ceph-CSI/custom-images.md +++ b/Documentation/Storage-Configuration/Ceph-CSI/custom-images.md @@ -24,7 +24,7 @@ ROOK_CSI_PROVISIONER_IMAGE: "registry.k8s.io/sig-storage/csi-provisioner:v5.1.0" ROOK_CSI_ATTACHER_IMAGE: "registry.k8s.io/sig-storage/csi-attacher:v4.8.0" ROOK_CSI_RESIZER_IMAGE: "registry.k8s.io/sig-storage/csi-resizer:v1.13.1" ROOK_CSI_SNAPSHOTTER_IMAGE: "registry.k8s.io/sig-storage/csi-snapshotter:v8.2.0" -ROOK_CSIADDONS_IMAGE: "quay.io/csiaddons/k8s-sidecar:v0.11.0" +ROOK_CSIADDONS_IMAGE: "quay.io/csiaddons/k8s-sidecar:v0.12.0" ``` ### **Use private repository** diff --git a/deploy/charts/rook-ceph/values.yaml b/deploy/charts/rook-ceph/values.yaml index 4ce764357778..19a3729b5af4 100644 --- a/deploy/charts/rook-ceph/values.yaml +++ b/deploy/charts/rook-ceph/values.yaml @@ -539,7 +539,7 @@ csi: # -- CSIAddons sidecar image repository repository: quay.io/csiaddons/k8s-sidecar # -- CSIAddons sidecar image tag - tag: v0.11.0 + tag: v0.12.0 nfs: # -- Enable the nfs csi driver diff --git a/deploy/examples/images.txt b/deploy/examples/images.txt index 53cf473bf27c..8e3006e387f7 100644 --- a/deploy/examples/images.txt +++ b/deploy/examples/images.txt @@ -3,7 +3,7 @@ quay.io/ceph/ceph:v19.2.1 quay.io/ceph/cosi:v0.1.2 quay.io/cephcsi/cephcsi:v3.13.0 - quay.io/csiaddons/k8s-sidecar:v0.11.0 + quay.io/csiaddons/k8s-sidecar:v0.12.0 registry.k8s.io/sig-storage/csi-attacher:v4.8.0 registry.k8s.io/sig-storage/csi-node-driver-registrar:v2.13.0 registry.k8s.io/sig-storage/csi-provisioner:v5.1.0 diff --git a/deploy/examples/operator-openshift.yaml b/deploy/examples/operator-openshift.yaml index 26eead857ca6..27acb6a8a781 100644 --- a/deploy/examples/operator-openshift.yaml +++ b/deploy/examples/operator-openshift.yaml @@ -556,7 +556,7 @@ data: CSI_ENABLE_CSIADDONS: "false" # Enable watch for faster recovery from rbd rwo node loss ROOK_WATCH_FOR_NODE_FAILURE: "true" - # ROOK_CSIADDONS_IMAGE: "quay.io/csiaddons/k8s-sidecar:v0.11.0" + # ROOK_CSIADDONS_IMAGE: "quay.io/csiaddons/k8s-sidecar:v0.12.0" # The GCSI RPC timeout value (in seconds). It should be >= 120. If this variable is not set or is an invalid value, it's default to 150. CSI_GRPC_TIMEOUT_SECONDS: "150" diff --git a/deploy/examples/operator.yaml b/deploy/examples/operator.yaml index b1fcd62b3a3f..960e94b159e4 100644 --- a/deploy/examples/operator.yaml +++ b/deploy/examples/operator.yaml @@ -511,7 +511,7 @@ data: CSI_ENABLE_CSIADDONS: "false" # Enable watch for faster recovery from rbd rwo node loss ROOK_WATCH_FOR_NODE_FAILURE: "true" - # ROOK_CSIADDONS_IMAGE: "quay.io/csiaddons/k8s-sidecar:v0.11.0" + # ROOK_CSIADDONS_IMAGE: "quay.io/csiaddons/k8s-sidecar:v0.12.0" # The CSI GRPC timeout value (in seconds). It should be >= 120. If this variable is not set or is an invalid value, it's default to 150. CSI_GRPC_TIMEOUT_SECONDS: "150" diff --git a/pkg/operator/ceph/csi/spec.go b/pkg/operator/ceph/csi/spec.go index 5b968453fba6..3bdde58e5841 100644 --- a/pkg/operator/ceph/csi/spec.go +++ b/pkg/operator/ceph/csi/spec.go @@ -139,7 +139,7 @@ var ( DefaultAttacherImage = "registry.k8s.io/sig-storage/csi-attacher:v4.8.0" DefaultSnapshotterImage = "registry.k8s.io/sig-storage/csi-snapshotter:v8.2.0" DefaultResizerImage = "registry.k8s.io/sig-storage/csi-resizer:v1.13.1" - DefaultCSIAddonsImage = "quay.io/csiaddons/k8s-sidecar:v0.11.0" + DefaultCSIAddonsImage = "quay.io/csiaddons/k8s-sidecar:v0.12.0" // image pull policy DefaultCSIImagePullPolicy = string(corev1.PullIfNotPresent) diff --git a/tests/scripts/csiaddons.sh b/tests/scripts/csiaddons.sh index 2b048b80761f..c577b6dff3ba 100755 --- a/tests/scripts/csiaddons.sh +++ b/tests/scripts/csiaddons.sh @@ -16,7 +16,7 @@ set -xEo pipefail -CSIADDONS_VERSION="v0.11.0" +CSIADDONS_VERSION="v0.12.0" CSIADDONS_CRD_NAME="csiaddonsnodes.csiaddons.openshift.io" CSIADDONS_CONTAINER_NAME="csi-addons" From e56dda36c239e7e5be8b3a0f1fd5630d52578250 Mon Sep 17 00:00:00 2001 From: "Bryan J." <132493975+chkpwd@users.noreply.github.com> Date: Tue, 4 Mar 2025 20:14:53 -0500 Subject: [PATCH 13/16] docs: unsupported kubectl exec params Signed-off-by: Bryan Jones --- Documentation/Storage-Configuration/Advanced/ceph-osd-mgmt.md | 2 +- Documentation/Troubleshooting/ceph-common-issues.md | 2 +- Documentation/Troubleshooting/direct-tools.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Documentation/Storage-Configuration/Advanced/ceph-osd-mgmt.md b/Documentation/Storage-Configuration/Advanced/ceph-osd-mgmt.md index 25a7abf7df46..668e5567436e 100644 --- a/Documentation/Storage-Configuration/Advanced/ceph-osd-mgmt.md +++ b/Documentation/Storage-Configuration/Advanced/ceph-osd-mgmt.md @@ -24,7 +24,7 @@ ceph osd utilization ``` ```console -kubectl -n rook-ceph exec -it $(kubectl -n rook-ceph get pod -l "app=rook-ceph-tools" -o jsonpath='{.items[0].metadata.name}') bash +kubectl -n rook-ceph exec -it $(kubectl -n rook-ceph get pod -l "app=rook-ceph-tools" -o jsonpath='{.items[0].metadata.name}') -- bash ``` ## Add an OSD diff --git a/Documentation/Troubleshooting/ceph-common-issues.md b/Documentation/Troubleshooting/ceph-common-issues.md index 8cca5195b43f..599002ef0cd7 100644 --- a/Documentation/Troubleshooting/ceph-common-issues.md +++ b/Documentation/Troubleshooting/ceph-common-issues.md @@ -99,7 +99,7 @@ After you verify the basic health of the running pods, next you will want to run The [rook-ceph-tools pod](ceph-toolbox.md) provides a simple environment to run Ceph tools. Once the pod is up and running, connect to the pod to execute Ceph commands to evaluate that current state of the cluster. ```console -kubectl -n rook-ceph exec -it $(kubectl -n rook-ceph get pod -l "app=rook-ceph-tools" -o jsonpath='{.items[*].metadata.name}') bash +kubectl -n rook-ceph exec -it $(kubectl -n rook-ceph get pod -l "app=rook-ceph-tools" -o jsonpath='{.items[*].metadata.name}') -- bash ``` #### Ceph Commands diff --git a/Documentation/Troubleshooting/direct-tools.md b/Documentation/Troubleshooting/direct-tools.md index 1ff3a92c2872..0053b5e29ae3 100644 --- a/Documentation/Troubleshooting/direct-tools.md +++ b/Documentation/Troubleshooting/direct-tools.md @@ -19,7 +19,7 @@ After the pod is started, connect to it like this: ```console kubectl -n rook-ceph get pod -l app=rook-direct-mount -$ kubectl -n rook-ceph exec -it bash +$ kubectl -n rook-ceph exec -it -- bash ``` ## Block Storage Tools From 5dcc6af9e898bc4eecba10dbefe7270e202f2f81 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Mar 2025 12:24:31 +0000 Subject: [PATCH 14/16] build(deps): bump the k8s-dependencies group with 7 updates Bumps the k8s-dependencies group with 7 updates: | Package | From | To | | --- | --- | --- | | [k8s.io/api](https://github.com/kubernetes/api) | `0.32.1` | `0.32.2` | | [k8s.io/apiextensions-apiserver](https://github.com/kubernetes/apiextensions-apiserver) | `0.32.1` | `0.32.2` | | [k8s.io/apimachinery](https://github.com/kubernetes/apimachinery) | `0.32.1` | `0.32.2` | | [k8s.io/cli-runtime](https://github.com/kubernetes/cli-runtime) | `0.32.1` | `0.32.2` | | [k8s.io/client-go](https://github.com/kubernetes/client-go) | `0.32.1` | `0.32.2` | | [k8s.io/cloud-provider](https://github.com/kubernetes/cloud-provider) | `0.32.1` | `0.32.2` | | [sigs.k8s.io/controller-runtime](https://github.com/kubernetes-sigs/controller-runtime) | `0.20.1` | `0.20.2` | Updates `k8s.io/api` from 0.32.1 to 0.32.2 - [Commits](https://github.com/kubernetes/api/compare/v0.32.1...v0.32.2) Updates `k8s.io/apiextensions-apiserver` from 0.32.1 to 0.32.2 - [Release notes](https://github.com/kubernetes/apiextensions-apiserver/releases) - [Commits](https://github.com/kubernetes/apiextensions-apiserver/compare/v0.32.1...v0.32.2) Updates `k8s.io/apimachinery` from 0.32.1 to 0.32.2 - [Commits](https://github.com/kubernetes/apimachinery/compare/v0.32.1...v0.32.2) Updates `k8s.io/cli-runtime` from 0.32.1 to 0.32.2 - [Commits](https://github.com/kubernetes/cli-runtime/compare/v0.32.1...v0.32.2) Updates `k8s.io/client-go` from 0.32.1 to 0.32.2 - [Changelog](https://github.com/kubernetes/client-go/blob/master/CHANGELOG.md) - [Commits](https://github.com/kubernetes/client-go/compare/v0.32.1...v0.32.2) Updates `k8s.io/cloud-provider` from 0.32.1 to 0.32.2 - [Commits](https://github.com/kubernetes/cloud-provider/compare/v0.32.1...v0.32.2) Updates `sigs.k8s.io/controller-runtime` from 0.20.1 to 0.20.2 - [Release notes](https://github.com/kubernetes-sigs/controller-runtime/releases) - [Changelog](https://github.com/kubernetes-sigs/controller-runtime/blob/main/RELEASE.md) - [Commits](https://github.com/kubernetes-sigs/controller-runtime/compare/v0.20.1...v0.20.2) --- updated-dependencies: - dependency-name: k8s.io/api dependency-type: direct:production update-type: version-update:semver-patch dependency-group: k8s-dependencies - dependency-name: k8s.io/apiextensions-apiserver dependency-type: direct:production update-type: version-update:semver-patch dependency-group: k8s-dependencies - dependency-name: k8s.io/apimachinery dependency-type: direct:production update-type: version-update:semver-patch dependency-group: k8s-dependencies - dependency-name: k8s.io/cli-runtime dependency-type: direct:production update-type: version-update:semver-patch dependency-group: k8s-dependencies - dependency-name: k8s.io/client-go dependency-type: direct:production update-type: version-update:semver-patch dependency-group: k8s-dependencies - dependency-name: k8s.io/cloud-provider dependency-type: direct:production update-type: version-update:semver-patch dependency-group: k8s-dependencies - dependency-name: sigs.k8s.io/controller-runtime dependency-type: direct:production update-type: version-update:semver-patch dependency-group: k8s-dependencies ... Signed-off-by: dependabot[bot] --- go.mod | 16 ++++++++-------- go.sum | 40 ++++++++++++++++++++-------------------- pkg/apis/go.mod | 8 +++++--- pkg/apis/go.sum | 20 ++++++++++---------- 4 files changed, 43 insertions(+), 41 deletions(-) diff --git a/go.mod b/go.mod index 9f0e2076ba3c..50d847c20eb7 100644 --- a/go.mod +++ b/go.mod @@ -45,14 +45,14 @@ require ( golang.org/x/sync v0.11.0 gopkg.in/ini.v1 v1.67.0 gopkg.in/yaml.v2 v2.4.0 - k8s.io/api v0.32.1 - k8s.io/apiextensions-apiserver v0.32.1 - k8s.io/apimachinery v0.32.1 - k8s.io/cli-runtime v0.32.1 - k8s.io/client-go v0.32.1 - k8s.io/cloud-provider v0.32.1 + k8s.io/api v0.32.2 + k8s.io/apiextensions-apiserver v0.32.2 + k8s.io/apimachinery v0.32.2 + k8s.io/cli-runtime v0.32.2 + k8s.io/client-go v0.32.2 + k8s.io/cloud-provider v0.32.2 k8s.io/utils v0.0.0-20241210054802-24370beab758 - sigs.k8s.io/controller-runtime v0.20.1 + sigs.k8s.io/controller-runtime v0.20.2 sigs.k8s.io/mcs-api v0.1.0 sigs.k8s.io/yaml v1.4.0 ) @@ -80,7 +80,7 @@ require ( github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/emicklei/go-restful/v3 v3.12.1 // indirect github.com/evanphx/json-patch v5.9.0+incompatible // indirect - github.com/evanphx/json-patch/v5 v5.9.0 // indirect + github.com/evanphx/json-patch/v5 v5.9.11 // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/fxamacker/cbor/v2 v2.7.0 // indirect github.com/gemalto/flume v0.13.1 // indirect diff --git a/go.sum b/go.sum index f92a4e581de0..e0cc9991c45a 100644 --- a/go.sum +++ b/go.sum @@ -297,8 +297,8 @@ github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQL github.com/evanphx/json-patch v5.9.0+incompatible h1:fBXyNpNMuTTDdquAq/uisOr2lShz4oaXpDTX2bLe7ls= github.com/evanphx/json-patch v5.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch/v5 v5.0.0/go.mod h1:G79N1coSVB93tBe7j6PhzjmR3/2VvlbKOFpnXhI9Bw4= -github.com/evanphx/json-patch/v5 v5.9.0 h1:kcBlZQbplgElYIlo/n1hJbls2z/1awpXxpRi0/FOJfg= -github.com/evanphx/json-patch/v5 v5.9.0/go.mod h1:VNkHZ/282BpEyt/tObQO8s5CMPmYYq14uClGH4abBuQ= +github.com/evanphx/json-patch/v5 v5.9.11 h1:/8HVnzMq13/3x9TPvjG08wUGqBTmZBsCWzjTM0wiaDU= +github.com/evanphx/json-patch/v5 v5.9.11/go.mod h1:3j+LviiESTElxA4p3EMKAB9HXj3/XEtnUf6OZxqIQTM= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= @@ -764,8 +764,8 @@ github.com/onsi/ginkgo/v2 v2.3.0/go.mod h1:Eew0uilEqZmIEZr8JrvYlvOM7Rr6xzTmMV8Ay github.com/onsi/ginkgo/v2 v2.4.0/go.mod h1:iHkDK1fKGcBoEHT5W7YBq4RFWaQulw+caOMkAt4OrFo= github.com/onsi/ginkgo/v2 v2.5.0/go.mod h1:Luc4sArBICYCS8THh8v3i3i5CuSZO+RaQRaJoeNwomw= github.com/onsi/ginkgo/v2 v2.6.0/go.mod h1:63DOGlLAH8+REH8jUGdL3YpCpu7JODesutUjdENfUAc= -github.com/onsi/ginkgo/v2 v2.21.0 h1:7rg/4f3rB88pb5obDgNZrNHrQ4e6WpjonchcpuBRnZM= -github.com/onsi/ginkgo/v2 v2.21.0/go.mod h1:7Du3c42kxCUegi0IImZ1wUQzMBVecgIHjR1C+NkhLQo= +github.com/onsi/ginkgo/v2 v2.22.0 h1:Yed107/8DjTr0lKCNt7Dn8yQ6ybuDRQoMGrNFKzMfHg= +github.com/onsi/ginkgo/v2 v2.22.0/go.mod h1:7Du3c42kxCUegi0IImZ1wUQzMBVecgIHjR1C+NkhLQo= github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v1.4.2/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= @@ -780,8 +780,8 @@ github.com/onsi/gomega v1.22.1/go.mod h1:x6n7VNe4hw0vkyYUM4mjIXx3JbLiPaBPNgB7PRQ github.com/onsi/gomega v1.23.0/go.mod h1:Z/NWtiqwBrwUt4/2loMmHL63EDLnYHmVbuBpDr2vQAg= github.com/onsi/gomega v1.24.0/go.mod h1:Z/NWtiqwBrwUt4/2loMmHL63EDLnYHmVbuBpDr2vQAg= github.com/onsi/gomega v1.24.1/go.mod h1:3AOiACssS3/MajrniINInwbfOOtfZvplPzuRSmvt1jM= -github.com/onsi/gomega v1.35.1 h1:Cwbd75ZBPxFSuZ6T+rN/WCb/gOc6YgFBXLlZLhC7Ds4= -github.com/onsi/gomega v1.35.1/go.mod h1:PvZbdDc8J6XJEpDK4HCuRBm8a6Fzp9/DmhC9C7yFlog= +github.com/onsi/gomega v1.36.1 h1:bJDPBO7ibjxcbHMgSCoo4Yj18UWbKDlLwX1x9sybDcw= +github.com/onsi/gomega v1.36.1/go.mod h1:PvZbdDc8J6XJEpDK4HCuRBm8a6Fzp9/DmhC9C7yFlog= github.com/openshift/api v0.0.0-20210105115604-44119421ec6b/go.mod h1:aqU5Cq+kqKKPbDMqxo9FojgDeSpNJI7iuskjXjtojDg= github.com/openshift/api v0.0.0-20241216151652-de9de05a8e43 h1:3lcB5nqOOfsJzY4JD12AMKyg3+yQhAdJzNDenbmbMQg= github.com/openshift/api v0.0.0-20241216151652-de9de05a8e43/go.mod h1:Shkl4HanLwDiiBzakv+con/aMGnVE2MAGvoKp5oyYUo= @@ -1645,15 +1645,15 @@ k8s.io/api v0.20.1/go.mod h1:KqwcCVogGxQY3nBlRpwt+wpAMF/KjaCc7RpywacvqUo= k8s.io/api v0.20.4/go.mod h1:++lNL1AJMkDymriNniQsWRkMDzRaX2Y/POTUi8yvqYQ= k8s.io/api v0.23.5/go.mod h1:Na4XuKng8PXJ2JsploYYrivXrINeTaycCGcYgF91Xm8= k8s.io/api v0.26.0/go.mod h1:k6HDTaIFC8yn1i6pSClSqIwLABIcLV9l5Q4EcngKnQg= -k8s.io/api v0.32.1 h1:f562zw9cy+GvXzXf0CKlVQ7yHJVYzLfL6JAS4kOAaOc= -k8s.io/api v0.32.1/go.mod h1:/Yi/BqkuueW1BgpoePYBRdDYfjPF5sgTr5+YqDZra5k= +k8s.io/api v0.32.2 h1:bZrMLEkgizC24G9eViHGOPbW+aRo9duEISRIJKfdJuw= +k8s.io/api v0.32.2/go.mod h1:hKlhk4x1sJyYnHENsrdCWw31FEmCijNGPJO5WzHiJ6Y= k8s.io/apiextensions-apiserver v0.0.0-20190409022649-727a075fdec8/go.mod h1:IxkesAMoaCRoLrPJdZNZUQp9NfZnzqaVzLhb2VEQzXE= k8s.io/apiextensions-apiserver v0.18.2/go.mod h1:q3faSnRGmYimiocj6cHQ1I3WpLqmDgJFlKL37fC4ZvY= k8s.io/apiextensions-apiserver v0.18.3/go.mod h1:TMsNGs7DYpMXd+8MOCX8KzPOCx8fnZMoIGB24m03+JE= k8s.io/apiextensions-apiserver v0.18.4/go.mod h1:NYeyeYq4SIpFlPxSAB6jHPIdvu3hL0pc36wuRChybio= k8s.io/apiextensions-apiserver v0.20.1/go.mod h1:ntnrZV+6a3dB504qwC5PN/Yg9PBiDNt1EVqbW2kORVk= -k8s.io/apiextensions-apiserver v0.32.1 h1:hjkALhRUeCariC8DiVmb5jj0VjIc1N0DREP32+6UXZw= -k8s.io/apiextensions-apiserver v0.32.1/go.mod h1:sxWIGuGiYov7Io1fAS2X06NjMIk5CbRHc2StSmbaQto= +k8s.io/apiextensions-apiserver v0.32.2 h1:2YMk285jWMk2188V2AERy5yDwBYrjgWYggscghPCvV4= +k8s.io/apiextensions-apiserver v0.32.2/go.mod h1:GPwf8sph7YlJT3H6aKUWtd0E+oyShk/YHWQHf/OOgCA= k8s.io/apimachinery v0.0.0-20190404173353-6a84e37a896d/go.mod h1:ccL7Eh7zubPUSh9A3USN90/OzHNSVN6zxzde07TDCL0= k8s.io/apimachinery v0.18.2/go.mod h1:9SnR/e11v5IbyPCGbvJViimtJ0SwHG4nfZFjU77ftcA= k8s.io/apimachinery v0.18.3/go.mod h1:OaXp26zu/5J7p0f92ASynJa1pZo06YlV9fG7BoWbCko= @@ -1665,14 +1665,14 @@ k8s.io/apimachinery v0.20.1/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRp k8s.io/apimachinery v0.20.4/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU= k8s.io/apimachinery v0.23.5/go.mod h1:BEuFMMBaIbcOqVIJqNZJXGFTP4W6AycEpb5+m/97hrM= k8s.io/apimachinery v0.26.0/go.mod h1:tnPmbONNJ7ByJNz9+n9kMjNP8ON+1qoAIIC70lztu74= -k8s.io/apimachinery v0.32.1 h1:683ENpaCBjma4CYqsmZyhEzrGz6cjn1MY/X2jB2hkZs= -k8s.io/apimachinery v0.32.1/go.mod h1:GpHVgxoKlTxClKcteaeuF1Ul/lDVb74KpZcxcmLDElE= +k8s.io/apimachinery v0.32.2 h1:yoQBR9ZGkA6Rgmhbp/yuT9/g+4lxtsGYwW6dR6BDPLQ= +k8s.io/apimachinery v0.32.2/go.mod h1:GpHVgxoKlTxClKcteaeuF1Ul/lDVb74KpZcxcmLDElE= k8s.io/apiserver v0.18.2/go.mod h1:Xbh066NqrZO8cbsoenCwyDJ1OSi8Ag8I2lezeHxzwzw= k8s.io/apiserver v0.18.3/go.mod h1:tHQRmthRPLUtwqsOnJJMoI8SW3lnoReZeE861lH8vUw= k8s.io/apiserver v0.18.4/go.mod h1:q+zoFct5ABNnYkGIaGQ3bcbUNdmPyOCoEBcg51LChY8= k8s.io/apiserver v0.20.1/go.mod h1:ro5QHeQkgMS7ZGpvf4tSMx6bBOgPfE+f52KwvXfScaU= -k8s.io/cli-runtime v0.32.1 h1:19nwZPlYGJPUDbhAxDIS2/oydCikvKMHsxroKNGA2mM= -k8s.io/cli-runtime v0.32.1/go.mod h1:NJPbeadVFnV2E7B7vF+FvU09mpwYlZCu8PqjzfuOnkY= +k8s.io/cli-runtime v0.32.2 h1:aKQR4foh9qeyckKRkNXUccP9moxzffyndZAvr+IXMks= +k8s.io/cli-runtime v0.32.2/go.mod h1:a/JpeMztz3xDa7GCyyShcwe55p8pbcCVQxvqZnIwXN8= k8s.io/client-go v0.18.2/go.mod h1:Xcm5wVGXX9HAA2JJ2sSBUn3tCJ+4SVlCbl2MNNv+CIU= k8s.io/client-go v0.18.3/go.mod h1:4a/dpQEvzAhT1BbuWW09qvIaGw6Gbu1gZYiQZIi1DMw= k8s.io/client-go v0.18.4/go.mod h1:f5sXwL4yAZRkAtzOxRWUhA/N8XzGCb+nPZI8PfobZ9g= @@ -1681,10 +1681,10 @@ k8s.io/client-go v0.19.2/go.mod h1:S5wPhCqyDNAlzM9CnEdgTGV4OqhsW3jGO1UM1epwfJA= k8s.io/client-go v0.20.0/go.mod h1:4KWh/g+Ocd8KkCwKF8vUNnmqgv+EVnQDK4MBF4oB5tY= k8s.io/client-go v0.20.1/go.mod h1:/zcHdt1TeWSd5HoUe6elJmHSQ6uLLgp4bIJHVEuy+/Y= k8s.io/client-go v0.23.5/go.mod h1:flkeinTO1CirYgzMPRWxUCnV0G4Fbu2vLhYCObnt/r4= -k8s.io/client-go v0.32.1 h1:otM0AxdhdBIaQh7l1Q0jQpmo7WOFIk5FFa4bg6YMdUU= -k8s.io/client-go v0.32.1/go.mod h1:aTTKZY7MdxUaJ/KiUs8D+GssR9zJZi77ZqtzcGXIiDg= -k8s.io/cloud-provider v0.32.1 h1:74rRhnfca3o4CsjjnIp/C3ARVuSmyNsxgWPtH0yc9Z0= -k8s.io/cloud-provider v0.32.1/go.mod h1:GECSanFT+EeZ/ToX3xlasjETzMUI+VFu92zHUDUsGHw= +k8s.io/client-go v0.32.2 h1:4dYCD4Nz+9RApM2b/3BtVvBHw54QjMFUl1OLcJG5yOA= +k8s.io/client-go v0.32.2/go.mod h1:fpZ4oJXclZ3r2nDOv+Ux3XcJutfrwjKTCHz2H3sww94= +k8s.io/cloud-provider v0.32.2 h1:8EC+fCYo0r0REczSjOZcVuQPCMxXxCKlgxDbYMrzC30= +k8s.io/cloud-provider v0.32.2/go.mod h1:2s8TeAXhVezp5VISaTxM6vW3yDonOZXoN4Aryz1p1PQ= k8s.io/code-generator v0.18.2/go.mod h1:+UHX5rSbxmR8kzS+FAv7um6dtYrZokQvjHpDSYRVkTc= k8s.io/code-generator v0.18.3/go.mod h1:TgNEVx9hCyPGpdtCWA34olQYLkh3ok9ar7XfSsr8b6c= k8s.io/code-generator v0.18.4/go.mod h1:TgNEVx9hCyPGpdtCWA34olQYLkh3ok9ar7XfSsr8b6c= @@ -1739,8 +1739,8 @@ sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.7/go.mod h1:PHgbrJT sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.14/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg= sigs.k8s.io/controller-runtime v0.2.2/go.mod h1:9dyohw3ZtoXQuV1e766PHUn+cmrRCIcBh6XIMFNMZ+I= sigs.k8s.io/controller-runtime v0.6.1/go.mod h1:XRYBPdbf5XJu9kpS84VJiZ7h/u1hF3gEORz0efEja7A= -sigs.k8s.io/controller-runtime v0.20.1 h1:JbGMAG/X94NeM3xvjenVUaBjy6Ui4Ogd/J5ZtjZnHaE= -sigs.k8s.io/controller-runtime v0.20.1/go.mod h1:BrP3w158MwvB3ZbNpaAcIKkHQ7YGpYnzpoSTZ8E14WU= +sigs.k8s.io/controller-runtime v0.20.2 h1:/439OZVxoEc02psi1h4QO3bHzTgu49bb347Xp4gW1pc= +sigs.k8s.io/controller-runtime v0.20.2/go.mod h1:xg2XB0K5ShQzAgsoujxuKN4LNXR2LfwwHsPj7Iaw+XY= sigs.k8s.io/controller-tools v0.3.0/go.mod h1:enhtKGfxZD1GFEoMgP8Fdbu+uKQ/cq1/WGJhdVChfvI= sigs.k8s.io/json v0.0.0-20211020170558-c049b76a60c6/go.mod h1:p4QtZmO4uMYipTQNzagwnNoseA6OxSUutVw05NhYDRs= sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= diff --git a/pkg/apis/go.mod b/pkg/apis/go.mod index 93888c7e09b8..a56a5ca9c1c9 100644 --- a/pkg/apis/go.mod +++ b/pkg/apis/go.mod @@ -22,8 +22,8 @@ require ( github.com/openshift/api v0.0.0-20241216151652-de9de05a8e43 github.com/pkg/errors v0.9.1 github.com/stretchr/testify v1.10.0 - k8s.io/api v0.32.1 - k8s.io/apimachinery v0.32.1 + k8s.io/api v0.32.2 + k8s.io/apimachinery v0.32.2 ) require ( @@ -63,6 +63,8 @@ require ( github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect + github.com/onsi/ginkgo/v2 v2.22.0 // indirect + github.com/onsi/gomega v1.36.1 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/ryanuber/go-glob v1.0.0 // indirect github.com/sirupsen/logrus v1.9.3 // indirect @@ -79,7 +81,7 @@ require ( gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - k8s.io/client-go v0.32.1 // indirect + k8s.io/client-go v0.32.2 // indirect k8s.io/klog/v2 v2.130.1 // indirect k8s.io/kube-openapi v0.0.0-20241212222426-2c72e554b1e7 // indirect k8s.io/utils v0.0.0-20241210054802-24370beab758 // indirect diff --git a/pkg/apis/go.sum b/pkg/apis/go.sum index a9c792c875cc..c774f55b6614 100644 --- a/pkg/apis/go.sum +++ b/pkg/apis/go.sum @@ -607,8 +607,8 @@ github.com/onsi/ginkgo/v2 v2.3.0/go.mod h1:Eew0uilEqZmIEZr8JrvYlvOM7Rr6xzTmMV8Ay github.com/onsi/ginkgo/v2 v2.4.0/go.mod h1:iHkDK1fKGcBoEHT5W7YBq4RFWaQulw+caOMkAt4OrFo= github.com/onsi/ginkgo/v2 v2.5.0/go.mod h1:Luc4sArBICYCS8THh8v3i3i5CuSZO+RaQRaJoeNwomw= github.com/onsi/ginkgo/v2 v2.6.0/go.mod h1:63DOGlLAH8+REH8jUGdL3YpCpu7JODesutUjdENfUAc= -github.com/onsi/ginkgo/v2 v2.21.0 h1:7rg/4f3rB88pb5obDgNZrNHrQ4e6WpjonchcpuBRnZM= -github.com/onsi/ginkgo/v2 v2.21.0/go.mod h1:7Du3c42kxCUegi0IImZ1wUQzMBVecgIHjR1C+NkhLQo= +github.com/onsi/ginkgo/v2 v2.22.0 h1:Yed107/8DjTr0lKCNt7Dn8yQ6ybuDRQoMGrNFKzMfHg= +github.com/onsi/ginkgo/v2 v2.22.0/go.mod h1:7Du3c42kxCUegi0IImZ1wUQzMBVecgIHjR1C+NkhLQo= github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v1.4.2/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= @@ -622,8 +622,8 @@ github.com/onsi/gomega v1.22.1/go.mod h1:x6n7VNe4hw0vkyYUM4mjIXx3JbLiPaBPNgB7PRQ github.com/onsi/gomega v1.23.0/go.mod h1:Z/NWtiqwBrwUt4/2loMmHL63EDLnYHmVbuBpDr2vQAg= github.com/onsi/gomega v1.24.0/go.mod h1:Z/NWtiqwBrwUt4/2loMmHL63EDLnYHmVbuBpDr2vQAg= github.com/onsi/gomega v1.24.1/go.mod h1:3AOiACssS3/MajrniINInwbfOOtfZvplPzuRSmvt1jM= -github.com/onsi/gomega v1.35.1 h1:Cwbd75ZBPxFSuZ6T+rN/WCb/gOc6YgFBXLlZLhC7Ds4= -github.com/onsi/gomega v1.35.1/go.mod h1:PvZbdDc8J6XJEpDK4HCuRBm8a6Fzp9/DmhC9C7yFlog= +github.com/onsi/gomega v1.36.1 h1:bJDPBO7ibjxcbHMgSCoo4Yj18UWbKDlLwX1x9sybDcw= +github.com/onsi/gomega v1.36.1/go.mod h1:PvZbdDc8J6XJEpDK4HCuRBm8a6Fzp9/DmhC9C7yFlog= github.com/openshift/api v0.0.0-20210105115604-44119421ec6b/go.mod h1:aqU5Cq+kqKKPbDMqxo9FojgDeSpNJI7iuskjXjtojDg= github.com/openshift/api v0.0.0-20241216151652-de9de05a8e43 h1:3lcB5nqOOfsJzY4JD12AMKyg3+yQhAdJzNDenbmbMQg= github.com/openshift/api v0.0.0-20241216151652-de9de05a8e43/go.mod h1:Shkl4HanLwDiiBzakv+con/aMGnVE2MAGvoKp5oyYUo= @@ -1405,8 +1405,8 @@ k8s.io/api v0.20.1/go.mod h1:KqwcCVogGxQY3nBlRpwt+wpAMF/KjaCc7RpywacvqUo= k8s.io/api v0.20.4/go.mod h1:++lNL1AJMkDymriNniQsWRkMDzRaX2Y/POTUi8yvqYQ= k8s.io/api v0.23.5/go.mod h1:Na4XuKng8PXJ2JsploYYrivXrINeTaycCGcYgF91Xm8= k8s.io/api v0.26.0/go.mod h1:k6HDTaIFC8yn1i6pSClSqIwLABIcLV9l5Q4EcngKnQg= -k8s.io/api v0.32.1 h1:f562zw9cy+GvXzXf0CKlVQ7yHJVYzLfL6JAS4kOAaOc= -k8s.io/api v0.32.1/go.mod h1:/Yi/BqkuueW1BgpoePYBRdDYfjPF5sgTr5+YqDZra5k= +k8s.io/api v0.32.2 h1:bZrMLEkgizC24G9eViHGOPbW+aRo9duEISRIJKfdJuw= +k8s.io/api v0.32.2/go.mod h1:hKlhk4x1sJyYnHENsrdCWw31FEmCijNGPJO5WzHiJ6Y= k8s.io/apiextensions-apiserver v0.0.0-20190409022649-727a075fdec8/go.mod h1:IxkesAMoaCRoLrPJdZNZUQp9NfZnzqaVzLhb2VEQzXE= k8s.io/apiextensions-apiserver v0.18.3/go.mod h1:TMsNGs7DYpMXd+8MOCX8KzPOCx8fnZMoIGB24m03+JE= k8s.io/apiextensions-apiserver v0.20.1/go.mod h1:ntnrZV+6a3dB504qwC5PN/Yg9PBiDNt1EVqbW2kORVk= @@ -1419,8 +1419,8 @@ k8s.io/apimachinery v0.20.1/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRp k8s.io/apimachinery v0.20.4/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU= k8s.io/apimachinery v0.23.5/go.mod h1:BEuFMMBaIbcOqVIJqNZJXGFTP4W6AycEpb5+m/97hrM= k8s.io/apimachinery v0.26.0/go.mod h1:tnPmbONNJ7ByJNz9+n9kMjNP8ON+1qoAIIC70lztu74= -k8s.io/apimachinery v0.32.1 h1:683ENpaCBjma4CYqsmZyhEzrGz6cjn1MY/X2jB2hkZs= -k8s.io/apimachinery v0.32.1/go.mod h1:GpHVgxoKlTxClKcteaeuF1Ul/lDVb74KpZcxcmLDElE= +k8s.io/apimachinery v0.32.2 h1:yoQBR9ZGkA6Rgmhbp/yuT9/g+4lxtsGYwW6dR6BDPLQ= +k8s.io/apimachinery v0.32.2/go.mod h1:GpHVgxoKlTxClKcteaeuF1Ul/lDVb74KpZcxcmLDElE= k8s.io/apiserver v0.18.3/go.mod h1:tHQRmthRPLUtwqsOnJJMoI8SW3lnoReZeE861lH8vUw= k8s.io/apiserver v0.20.1/go.mod h1:ro5QHeQkgMS7ZGpvf4tSMx6bBOgPfE+f52KwvXfScaU= k8s.io/client-go v0.18.3/go.mod h1:4a/dpQEvzAhT1BbuWW09qvIaGw6Gbu1gZYiQZIi1DMw= @@ -1429,8 +1429,8 @@ k8s.io/client-go v0.19.2/go.mod h1:S5wPhCqyDNAlzM9CnEdgTGV4OqhsW3jGO1UM1epwfJA= k8s.io/client-go v0.20.0/go.mod h1:4KWh/g+Ocd8KkCwKF8vUNnmqgv+EVnQDK4MBF4oB5tY= k8s.io/client-go v0.20.1/go.mod h1:/zcHdt1TeWSd5HoUe6elJmHSQ6uLLgp4bIJHVEuy+/Y= k8s.io/client-go v0.23.5/go.mod h1:flkeinTO1CirYgzMPRWxUCnV0G4Fbu2vLhYCObnt/r4= -k8s.io/client-go v0.32.1 h1:otM0AxdhdBIaQh7l1Q0jQpmo7WOFIk5FFa4bg6YMdUU= -k8s.io/client-go v0.32.1/go.mod h1:aTTKZY7MdxUaJ/KiUs8D+GssR9zJZi77ZqtzcGXIiDg= +k8s.io/client-go v0.32.2 h1:4dYCD4Nz+9RApM2b/3BtVvBHw54QjMFUl1OLcJG5yOA= +k8s.io/client-go v0.32.2/go.mod h1:fpZ4oJXclZ3r2nDOv+Ux3XcJutfrwjKTCHz2H3sww94= k8s.io/code-generator v0.18.3/go.mod h1:TgNEVx9hCyPGpdtCWA34olQYLkh3ok9ar7XfSsr8b6c= k8s.io/code-generator v0.19.0/go.mod h1:moqLn7w0t9cMs4+5CQyxnfA/HV8MF6aAVENF+WZZhgk= k8s.io/code-generator v0.20.0/go.mod h1:UsqdF+VX4PU2g46NC2JRs4gc+IfrctnwHb76RNbWHJg= From 95a911f8c38c166de5f3bf92f34c5b36e380ec1d Mon Sep 17 00:00:00 2001 From: Tarun Gupta Akirala Date: Fri, 14 Feb 2025 00:05:54 -0800 Subject: [PATCH 15/16] operator: formatting issue in cosi log statement updates the debug log line to ensure the formatting is applied correctly. Signed-off-by: Tarun Gupta Akirala --- pkg/operator/ceph/controller/predicate.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/operator/ceph/controller/predicate.go b/pkg/operator/ceph/controller/predicate.go index 631c68120c48..55acff4e406d 100644 --- a/pkg/operator/ceph/controller/predicate.go +++ b/pkg/operator/ceph/controller/predicate.go @@ -440,7 +440,7 @@ func WatchControllerPredicate() predicate.Funcs { case *cephv1.CephCOSIDriver: objNew := e.ObjectNew.(*cephv1.CephCOSIDriver) namespacedName := fmt.Sprintf("%s/%s", objNew.Namespace, objNew.Name) - logger.Debug("update event on CephCOSIDriver %q CR", namespacedName) + logger.Debugf("update event on CephCOSIDriver %q CR", namespacedName) // If the labels "do_not_reconcile" is set on the object, let's not reconcile that request IsDoNotReconcile := IsDoNotReconcile(objNew.GetLabels()) if IsDoNotReconcile { From db9bec358a14df0a8d28151f6a3619fce57f468c Mon Sep 17 00:00:00 2001 From: DF Build Team Date: Sun, 9 Mar 2025 04:07:54 -0400 Subject: [PATCH 16/16] csv: add additional csv changes that other commits bring add generated csv changes Signed-off-by: DF Build Team --- build/csv/ceph/ceph.rook.io_cephclusters.yaml | 4 + .../ceph/ceph.rook.io_cephobjectstores.yaml | 16 + ...al-cluster-script-config_v1_configmap.yaml | 3356 ++++++++--------- 3 files changed, 1698 insertions(+), 1678 deletions(-) diff --git a/build/csv/ceph/ceph.rook.io_cephclusters.yaml b/build/csv/ceph/ceph.rook.io_cephclusters.yaml index 522401ee6ad6..5c1032bef430 100644 --- a/build/csv/ceph/ceph.rook.io_cephclusters.yaml +++ b/build/csv/ceph/ceph.rook.io_cephclusters.yaml @@ -468,6 +468,10 @@ spec: maximum: 9 minimum: 0 type: integer + externalMonIDs: + items: + type: string + type: array failureDomainLabel: type: string stretchCluster: diff --git a/build/csv/ceph/ceph.rook.io_cephobjectstores.yaml b/build/csv/ceph/ceph.rook.io_cephobjectstores.yaml index 3883f780bd34..1aa730fbb9e8 100644 --- a/build/csv/ceph/ceph.rook.io_cephobjectstores.yaml +++ b/build/csv/ceph/ceph.rook.io_cephobjectstores.yaml @@ -1094,6 +1094,22 @@ spec: type: string nullable: true type: object + rgwConfigFromSecret: + additionalProperties: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + nullable: true + type: object securePort: format: int32 maximum: 65535 diff --git a/build/csv/ceph/rook-ceph-external-cluster-script-config_v1_configmap.yaml b/build/csv/ceph/rook-ceph-external-cluster-script-config_v1_configmap.yaml index 7008388e461a..63e85dd0500a 100644 --- a/build/csv/ceph/rook-ceph-external-cluster-script-config_v1_configmap.yaml +++ b/build/csv/ceph/rook-ceph-external-cluster-script-config_v1_configmap.yaml @@ -5,1693 +5,1693 @@ data: CgpMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxp Y2Vuc2UiKTsKeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3 aXRoIHRoZSBMaWNlbnNlLgpZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQK - CglodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKClVubGVzcyByZXF1 - aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUK - ZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElT - IiBCQVNJUywKV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVp - dGhlciBleHByZXNzIG9yIGltcGxpZWQuClNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmlj - IGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKbGltaXRhdGlvbnMgdW5kZXIgdGhl - IExpY2Vuc2UuCiIiIgoKaW1wb3J0IGVycm5vCmltcG9ydCBzeXMKaW1wb3J0IGpzb24KaW1wb3J0 - IGFyZ3BhcnNlCmltcG9ydCByZQppbXBvcnQgc3VicHJvY2VzcwppbXBvcnQgaG1hYwppbXBvcnQg - Y29uZmlncGFyc2VyCmZyb20gaGFzaGxpYiBpbXBvcnQgc2hhMSBhcyBzaGEKZnJvbSBvcyBpbXBv - cnQgbGluZXNlcCBhcyBMSU5FU0VQCmZyb20gb3MgaW1wb3J0IHBhdGgKZnJvbSBlbWFpbC51dGls - cyBpbXBvcnQgZm9ybWF0ZGF0ZQppbXBvcnQgcmVxdWVzdHMKZnJvbSByZXF1ZXN0cy5hdXRoIGlt - cG9ydCBBdXRoQmFzZQpmcm9tIGlvIGltcG9ydCBTdHJpbmdJTwpmcm9tIHVybGxpYi5wYXJzZSBp - bXBvcnQgdXJscGFyc2UKZnJvbSB1cmxsaWIucGFyc2UgaW1wb3J0IHVybGVuY29kZSBhcyB1cmxl - bmNvZGUKZnJvbSBpcGFkZHJlc3MgaW1wb3J0IGlwX2FkZHJlc3MKZnJvbSBpcGFkZHJlc3MgaW1w - b3J0IElQdjRBZGRyZXNzCmZyb20gYmFzZTY0IGltcG9ydCBlbmNvZGVieXRlcyBhcyBlbmNvZGVz - dHJpbmcKCk1vZHVsZU5vdEZvdW5kRXJyb3IgPSBJbXBvcnRFcnJvcgoKdHJ5OgogICAgaW1wb3J0 - IHJhZG9zCmV4Y2VwdCBNb2R1bGVOb3RGb3VuZEVycm9yIGFzIG5vTW9kRXJyOgogICAgcHJpbnQo - ZiJFcnJvcjoge25vTW9kRXJyfVxuRXhpdGluZyB0aGUgc2NyaXB0Li4uIikKICAgIHN5cy5leGl0 - KDEpCgp0cnk6CiAgICBpbXBvcnQgcmJkCmV4Y2VwdCBNb2R1bGVOb3RGb3VuZEVycm9yIGFzIG5v - TW9kRXJyOgogICAgcHJpbnQoZiJFcnJvcjoge25vTW9kRXJyfVxuRXhpdGluZyB0aGUgc2NyaXB0 - Li4uIikKICAgIHN5cy5leGl0KDEpCgoKY2xhc3MgRXhlY3V0aW9uRmFpbHVyZUV4Y2VwdGlvbihF - eGNlcHRpb24pOgogICAgcGFzcwoKCiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMj - IyMjIyMjIyMjIyMjIwojIyMjIyMjIyMjIyMjIyMjIyMgRHVtbXlSYWRvcyAjIyMjIyMjIyMjIyMj - IyMjIyMKIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCiMg - dGhpcyBpcyBtYWlubHkgZm9yIHRlc3RpbmcgYW5kIGNvdWxkIGJlIHVzZWQgd2hlcmUgJ3JhZG9z - JyBpcyBub3QgYXZhaWxhYmxlCgoKY2xhc3MgRHVtbXlSYWRvcyhvYmplY3QpOgogICAgZGVmIF9f - aW5pdF9fKHNlbGYpOgogICAgICAgIHNlbGYucmV0dXJuX3ZhbCA9IDAKICAgICAgICBzZWxmLmVy - cl9tZXNzYWdlID0gIiIKICAgICAgICBzZWxmLnN0YXRlID0gImNvbm5lY3RlZCIKICAgICAgICBz - ZWxmLmNtZF9vdXRwdXRfbWFwID0ge30KICAgICAgICBzZWxmLmNtZF9uYW1lcyA9IHt9CiAgICAg - ICAgc2VsZi5faW5pdF9jbWRfb3V0cHV0X21hcCgpCiAgICAgICAgc2VsZi5kdW1teV9ob3N0X2lw - X21hcCA9IHt9CgogICAgZGVmIF9pbml0X2NtZF9vdXRwdXRfbWFwKHNlbGYpOgogICAgICAgIGpz - b25fZmlsZV9uYW1lID0gInRlc3QtZGF0YS9jZXBoLXN0YXR1cy1vdXQiCiAgICAgICAgc2NyaXB0 - X2RpciA9IHBhdGguYWJzcGF0aChwYXRoLmRpcm5hbWUoX19maWxlX18pKQogICAgICAgIGNlcGhf - c3RhdHVzX3N0ciA9ICIiCiAgICAgICAgd2l0aCBvcGVuKAogICAgICAgICAgICBwYXRoLmpvaW4o - c2NyaXB0X2RpciwganNvbl9maWxlX25hbWUpLCBtb2RlPSJyIiwgZW5jb2Rpbmc9IlVURi04Igog - ICAgICAgICkgYXMganNvbl9maWxlOgogICAgICAgICAgICBjZXBoX3N0YXR1c19zdHIgPSBqc29u - X2ZpbGUucmVhZCgpCiAgICAgICAgc2VsZi5jbWRfbmFtZXNbImZzIGxzIl0gPSAiIiJ7ImZvcm1h - dCI6ICJqc29uIiwgInByZWZpeCI6ICJmcyBscyJ9IiIiCiAgICAgICAgc2VsZi5jbWRfbmFtZXNb - InF1b3J1bV9zdGF0dXMiXSA9ICgKICAgICAgICAgICAgIiIieyJmb3JtYXQiOiAianNvbiIsICJw - cmVmaXgiOiAicXVvcnVtX3N0YXR1cyJ9IiIiCiAgICAgICAgKQogICAgICAgIHNlbGYuY21kX25h - bWVzWyJtZ3Igc2VydmljZXMiXSA9ICgKICAgICAgICAgICAgIiIieyJmb3JtYXQiOiAianNvbiIs - ICJwcmVmaXgiOiAibWdyIHNlcnZpY2VzIn0iIiIKICAgICAgICApCiAgICAgICAgIyBhbGwgdGhl - IGNvbW1hbmRzIGFuZCB0aGVpciBvdXRwdXQKICAgICAgICBzZWxmLmNtZF9vdXRwdXRfbWFwW3Nl - bGYuY21kX25hbWVzWyJmcyBscyJdXSA9ICgKICAgICAgICAgICAgIiIiW3sibmFtZSI6Im15ZnMi - LCJtZXRhZGF0YV9wb29sIjoibXlmcy1tZXRhZGF0YSIsIm1ldGFkYXRhX3Bvb2xfaWQiOjIsImRh - dGFfcG9vbF9pZHMiOlszXSwiZGF0YV9wb29scyI6WyJteWZzLXJlcGxpY2F0ZWQiXX1dIiIiCiAg - ICAgICAgKQogICAgICAgIHNlbGYuY21kX291dHB1dF9tYXBbc2VsZi5jbWRfbmFtZXNbInF1b3J1 - bV9zdGF0dXMiXV0gPSAoCiAgICAgICAgICAgICIiInsiZWxlY3Rpb25fZXBvY2giOjMsInF1b3J1 - bSI6WzBdLCJxdW9ydW1fbmFtZXMiOlsiYSJdLCJxdW9ydW1fbGVhZGVyX25hbWUiOiJhIiwicXVv - cnVtX2FnZSI6MTQzODUsImZlYXR1cmVzIjp7InF1b3J1bV9jb24iOiI0NTQwMTM4MjkyODM2Njk2 - MDYzIiwicXVvcnVtX21vbiI6WyJrcmFrZW4iLCJsdW1pbm91cyIsIm1pbWljIiwib3NkbWFwLXBy - dW5lIiwibmF1dGlsdXMiLCJvY3RvcHVzIl19LCJtb25tYXAiOnsiZXBvY2giOjEsImZzaWQiOiJh - ZjRlMTY3My0wYjcyLTQwMmQtOTkwYS0yMmQyOTE5ZDBmMWMiLCJtb2RpZmllZCI6IjIwMjAtMDUt - MDdUMDM6MzY6MzkuOTE4MDM1WiIsImNyZWF0ZWQiOiIyMDIwLTA1LTA3VDAzOjM2OjM5LjkxODAz - NVoiLCJtaW5fbW9uX3JlbGVhc2UiOjE1LCJtaW5fbW9uX3JlbGVhc2VfbmFtZSI6Im9jdG9wdXMi - LCJmZWF0dXJlcyI6eyJwZXJzaXN0ZW50IjpbImtyYWtlbiIsImx1bWlub3VzIiwibWltaWMiLCJv - c2RtYXAtcHJ1bmUiLCJuYXV0aWx1cyIsIm9jdG9wdXMiXSwib3B0aW9uYWwiOltdfSwibW9ucyI6 - W3sicmFuayI6MCwibmFtZSI6ImEiLCJwdWJsaWNfYWRkcnMiOnsiYWRkcnZlYyI6W3sidHlwZSI6 - InYyIiwiYWRkciI6IjEwLjExMC4yMDUuMTc0OjMzMDAiLCJub25jZSI6MH0seyJ0eXBlIjoidjEi - LCJhZGRyIjoiMTAuMTEwLjIwNS4xNzQ6Njc4OSIsIm5vbmNlIjowfV19LCJhZGRyIjoiMTAuMTEw - LjIwNS4xNzQ6Njc4OS8wIiwicHVibGljX2FkZHIiOiIxMC4xMTAuMjA1LjE3NDo2Nzg5LzAiLCJw - cmlvcml0eSI6MCwid2VpZ2h0IjowfV19fSIiIgogICAgICAgICkKICAgICAgICBzZWxmLmNtZF9v - dXRwdXRfbWFwW3NlbGYuY21kX25hbWVzWyJtZ3Igc2VydmljZXMiXV0gPSAoCiAgICAgICAgICAg - ICIiInsiZGFzaGJvYXJkIjoiaHR0cHM6Ly9jZXBoLWRhc2hib2FyZDo4NDQzLyIsInByb21ldGhl - dXMiOiJodHRwOi8vY2VwaC1kYXNoYm9hcmQtZGI6OTI4My8ifSIiIgogICAgICAgICkKICAgICAg - ICBzZWxmLmNtZF9vdXRwdXRfbWFwWwogICAgICAgICAgICAiIiJ7ImNhcHMiOiBbIm1vbiIsICJh - bGxvdyByLCBhbGxvdyBjb21tYW5kIHF1b3J1bV9zdGF0dXMiLCAib3NkIiwgInByb2ZpbGUgcmJk - LXJlYWQtb25seSwgYWxsb3cgcnd4IHBvb2w9ZGVmYXVsdC5yZ3cubWV0YSwgYWxsb3cgciBwb29s - PS5yZ3cucm9vdCwgYWxsb3cgcncgcG9vbD1kZWZhdWx0LnJndy5jb250cm9sLCBhbGxvdyB4IHBv - b2w9ZGVmYXVsdC5yZ3cuYnVja2V0cy5pbmRleCIsICJtZHMiLCAiYWxsb3cgKiJdLCAiZW50aXR5 - IjogImNsaWVudC5oZWFsdGhjaGVja2VyIiwgImZvcm1hdCI6ICJqc29uIiwgInByZWZpeCI6ICJh - dXRoIGdldC1vci1jcmVhdGUifSIiIgogICAgICAgIF0gPSAiIiJbeyJlbnRpdHkiOiJjbGllbnQu - aGVhbHRoY2hlY2tlciIsImtleSI6IkFRREZrYk5lZnQ1YkZSQUFUbmRMTlVTRUtydW96eGlaaTNs - cmRBPT0iLCJjYXBzIjp7Im1vbiI6ImFsbG93IHIsIGFsbG93IGNvbW1hbmQgcXVvcnVtX3N0YXR1 - cyIsIm9zZCI6InByb2ZpbGUgcmJkLXJlYWQtb25seSwgYWxsb3cgcnd4IHBvb2w9ZGVmYXVsdC5y - Z3cubWV0YSwgYWxsb3cgciBwb29sPS5yZ3cucm9vdCwgYWxsb3cgcncgcG9vbD1kZWZhdWx0LnJn - dy5jb250cm9sLCBhbGxvdyB4IHBvb2w9ZGVmYXVsdC5yZ3cuYnVja2V0cy5pbmRleCIsIm1kcyI6 - ImFsbG93ICoifX1dIiIiCiAgICAgICAgc2VsZi5jbWRfb3V0cHV0X21hcFsKICAgICAgICAgICAg - IiIieyJjYXBzIjogWyJtb24iLCAicHJvZmlsZSByYmQsIGFsbG93IGNvbW1hbmQgJ29zZCBibG9j - a2xpc3QnIiwgIm9zZCIsICJwcm9maWxlIHJiZCJdLCAiZW50aXR5IjogImNsaWVudC5jc2ktcmJk - LW5vZGUiLCAiZm9ybWF0IjogImpzb24iLCAicHJlZml4IjogImF1dGggZ2V0LW9yLWNyZWF0ZSJ9 - IiIiCiAgICAgICAgXSA9ICIiIlt7ImVudGl0eSI6ImNsaWVudC5jc2ktcmJkLW5vZGUiLCJrZXki - OiJBUUJPZ3JOZUhiSzFBeEFBdWJZQmVWOFMxVS9HUHpxNVNWZXE2Zz09IiwiY2FwcyI6eyJtb24i - OiJwcm9maWxlIHJiZCwgYWxsb3cgY29tbWFuZCAnb3NkIGJsb2NrbGlzdCciLCJvc2QiOiJwcm9m - aWxlIHJiZCJ9fV0iIiIKICAgICAgICBzZWxmLmNtZF9vdXRwdXRfbWFwWwogICAgICAgICAgICAi - IiJ7ImNhcHMiOiBbIm1vbiIsICJwcm9maWxlIHJiZCwgYWxsb3cgY29tbWFuZCAnb3NkIGJsb2Nr - bGlzdCciLCAibWdyIiwgImFsbG93IHJ3IiwgIm9zZCIsICJwcm9maWxlIHJiZCJdLCAiZW50aXR5 - IjogImNsaWVudC5jc2ktcmJkLXByb3Zpc2lvbmVyIiwgImZvcm1hdCI6ICJqc29uIiwgInByZWZp - eCI6ICJhdXRoIGdldC1vci1jcmVhdGUifSIiIgogICAgICAgIF0gPSAiIiJbeyJlbnRpdHkiOiJj - bGllbnQuY3NpLXJiZC1wcm92aXNpb25lciIsImtleSI6IkFRQk5nck5lMWdleUt4QUE4ZWtWaVJk - RStoc3M1T3dlWUJrd05nPT0iLCJjYXBzIjp7Im1nciI6ImFsbG93IHJ3IiwibW9uIjoicHJvZmls - ZSByYmQsIGFsbG93IGNvbW1hbmQgJ29zZCBibG9ja2xpc3QnIiwib3NkIjoicHJvZmlsZSByYmQi - fX1dIiIiCiAgICAgICAgc2VsZi5jbWRfb3V0cHV0X21hcFsKICAgICAgICAgICAgIiIieyJjYXBz - IjogWyJtb24iLCAiYWxsb3cgciwgYWxsb3cgY29tbWFuZCAnb3NkIGJsb2NrbGlzdCciLCAibWdy - IiwgImFsbG93IHJ3IiwgIm9zZCIsICJhbGxvdyBydyB0YWcgY2VwaGZzICo9KiIsICJtZHMiLCAi - YWxsb3cgcnciXSwgImVudGl0eSI6ICJjbGllbnQuY3NpLWNlcGhmcy1ub2RlIiwgImZvcm1hdCI6 - ICJqc29uIiwgInByZWZpeCI6ICJhdXRoIGdldC1vci1jcmVhdGUifSIiIgogICAgICAgIF0gPSAi - IiJbeyJlbnRpdHkiOiJjbGllbnQuY3NpLWNlcGhmcy1ub2RlIiwia2V5IjoiQVFCT2dyTmVFTnVu - S3hBQVBDbWdFN1I2RzhEY1huYUoxRjMycWc9PSIsImNhcHMiOnsibWRzIjoiYWxsb3cgcnciLCJt - Z3IiOiJhbGxvdyBydyIsIm1vbiI6ImFsbG93IHIsIGFsbG93IGNvbW1hbmQgJ29zZCBibG9ja2xp - c3QnIiwib3NkIjoiYWxsb3cgcncgdGFnIGNlcGhmcyAqPSoifX1dIiIiCiAgICAgICAgc2VsZi5j - bWRfb3V0cHV0X21hcFsKICAgICAgICAgICAgIiIieyJjYXBzIjogWyJtb24iLCAiYWxsb3cgciwg - YWxsb3cgY29tbWFuZCAnb3NkIGJsb2NrbGlzdCciLCAibWdyIiwgImFsbG93IHJ3IiwgIm9zZCIs - ICJhbGxvdyBydyB0YWcgY2VwaGZzIG1ldGFkYXRhPSoiLCAibWRzIiwgImFsbG93ICoiXSwgImVu - dGl0eSI6ICJjbGllbnQuY3NpLWNlcGhmcy1wcm92aXNpb25lciIsICJmb3JtYXQiOiAianNvbiIs + CiAgICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCgpVbmxl + c3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNv + ZnR3YXJlCmRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFu + ICJBUyBJUyIgQkFTSVMsCldJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBL + SU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgpTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBz + cGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCmxpbWl0YXRpb25zIHVu + ZGVyIHRoZSBMaWNlbnNlLgoiIiIKCmltcG9ydCBlcnJubwppbXBvcnQgc3lzCmltcG9ydCBqc29u + CmltcG9ydCBhcmdwYXJzZQppbXBvcnQgcmUKaW1wb3J0IHN1YnByb2Nlc3MKaW1wb3J0IGhtYWMK + aW1wb3J0IGNvbmZpZ3BhcnNlcgpmcm9tIGhhc2hsaWIgaW1wb3J0IHNoYTEgYXMgc2hhCmZyb20g + b3MgaW1wb3J0IGxpbmVzZXAgYXMgTElORVNFUApmcm9tIG9zIGltcG9ydCBwYXRoCmZyb20gZW1h + aWwudXRpbHMgaW1wb3J0IGZvcm1hdGRhdGUKaW1wb3J0IHJlcXVlc3RzCmZyb20gcmVxdWVzdHMu + YXV0aCBpbXBvcnQgQXV0aEJhc2UKZnJvbSBpbyBpbXBvcnQgU3RyaW5nSU8KZnJvbSB1cmxsaWIu + cGFyc2UgaW1wb3J0IHVybHBhcnNlCmZyb20gdXJsbGliLnBhcnNlIGltcG9ydCB1cmxlbmNvZGUg + YXMgdXJsZW5jb2RlCmZyb20gaXBhZGRyZXNzIGltcG9ydCBpcF9hZGRyZXNzCmZyb20gaXBhZGRy + ZXNzIGltcG9ydCBJUHY0QWRkcmVzcwpmcm9tIGJhc2U2NCBpbXBvcnQgZW5jb2RlYnl0ZXMgYXMg + ZW5jb2Rlc3RyaW5nCgpNb2R1bGVOb3RGb3VuZEVycm9yID0gSW1wb3J0RXJyb3IKCnRyeToKICAg + IGltcG9ydCByYWRvcwpleGNlcHQgTW9kdWxlTm90Rm91bmRFcnJvciBhcyBub01vZEVycjoKICAg + IHByaW50KGYiRXJyb3I6IHtub01vZEVycn1cbkV4aXRpbmcgdGhlIHNjcmlwdC4uLiIpCiAgICBz + eXMuZXhpdCgxKQoKdHJ5OgogICAgaW1wb3J0IHJiZApleGNlcHQgTW9kdWxlTm90Rm91bmRFcnJv + ciBhcyBub01vZEVycjoKICAgIHByaW50KGYiRXJyb3I6IHtub01vZEVycn1cbkV4aXRpbmcgdGhl + IHNjcmlwdC4uLiIpCiAgICBzeXMuZXhpdCgxKQoKCmNsYXNzIEV4ZWN1dGlvbkZhaWx1cmVFeGNl + cHRpb24oRXhjZXB0aW9uKToKICAgIHBhc3MKCgojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMj + IyMjIyMjIyMjIyMjIyMjIyMjIyMKIyMjIyMjIyMjIyMjIyMjIyMjIER1bW15UmFkb3MgIyMjIyMj + IyMjIyMjIyMjIyMjCiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMj + IyMjIwojIHRoaXMgaXMgbWFpbmx5IGZvciB0ZXN0aW5nIGFuZCBjb3VsZCBiZSB1c2VkIHdoZXJl + ICdyYWRvcycgaXMgbm90IGF2YWlsYWJsZQoKCmNsYXNzIER1bW15UmFkb3Mob2JqZWN0KToKICAg + IGRlZiBfX2luaXRfXyhzZWxmKToKICAgICAgICBzZWxmLnJldHVybl92YWwgPSAwCiAgICAgICAg + c2VsZi5lcnJfbWVzc2FnZSA9ICIiCiAgICAgICAgc2VsZi5zdGF0ZSA9ICJjb25uZWN0ZWQiCiAg + ICAgICAgc2VsZi5jbWRfb3V0cHV0X21hcCA9IHt9CiAgICAgICAgc2VsZi5jbWRfbmFtZXMgPSB7 + fQogICAgICAgIHNlbGYuX2luaXRfY21kX291dHB1dF9tYXAoKQogICAgICAgIHNlbGYuZHVtbXlf + aG9zdF9pcF9tYXAgPSB7fQoKICAgIGRlZiBfaW5pdF9jbWRfb3V0cHV0X21hcChzZWxmKToKICAg + ICAgICBqc29uX2ZpbGVfbmFtZSA9ICJ0ZXN0LWRhdGEvY2VwaC1zdGF0dXMtb3V0IgogICAgICAg + IHNjcmlwdF9kaXIgPSBwYXRoLmFic3BhdGgocGF0aC5kaXJuYW1lKF9fZmlsZV9fKSkKICAgICAg + ICBjZXBoX3N0YXR1c19zdHIgPSAiIgogICAgICAgIHdpdGggb3BlbigKICAgICAgICAgICAgcGF0 + aC5qb2luKHNjcmlwdF9kaXIsIGpzb25fZmlsZV9uYW1lKSwgbW9kZT0iciIsIGVuY29kaW5nPSJV + VEYtOCIKICAgICAgICApIGFzIGpzb25fZmlsZToKICAgICAgICAgICAgY2VwaF9zdGF0dXNfc3Ry + ID0ganNvbl9maWxlLnJlYWQoKQogICAgICAgIHNlbGYuY21kX25hbWVzWyJmcyBscyJdID0gIiIi + eyJmb3JtYXQiOiAianNvbiIsICJwcmVmaXgiOiAiZnMgbHMifSIiIgogICAgICAgIHNlbGYuY21k + X25hbWVzWyJxdW9ydW1fc3RhdHVzIl0gPSAoCiAgICAgICAgICAgICIiInsiZm9ybWF0IjogImpz + b24iLCAicHJlZml4IjogInF1b3J1bV9zdGF0dXMifSIiIgogICAgICAgICkKICAgICAgICBzZWxm + LmNtZF9uYW1lc1sibWdyIHNlcnZpY2VzIl0gPSAoCiAgICAgICAgICAgICIiInsiZm9ybWF0Ijog + Impzb24iLCAicHJlZml4IjogIm1nciBzZXJ2aWNlcyJ9IiIiCiAgICAgICAgKQogICAgICAgICMg + YWxsIHRoZSBjb21tYW5kcyBhbmQgdGhlaXIgb3V0cHV0CiAgICAgICAgc2VsZi5jbWRfb3V0cHV0 + X21hcFtzZWxmLmNtZF9uYW1lc1siZnMgbHMiXV0gPSAoCiAgICAgICAgICAgICIiIlt7Im5hbWUi + OiJteWZzIiwibWV0YWRhdGFfcG9vbCI6Im15ZnMtbWV0YWRhdGEiLCJtZXRhZGF0YV9wb29sX2lk + IjoyLCJkYXRhX3Bvb2xfaWRzIjpbM10sImRhdGFfcG9vbHMiOlsibXlmcy1yZXBsaWNhdGVkIl19 + XSIiIgogICAgICAgICkKICAgICAgICBzZWxmLmNtZF9vdXRwdXRfbWFwW3NlbGYuY21kX25hbWVz + WyJxdW9ydW1fc3RhdHVzIl1dID0gKAogICAgICAgICAgICAiIiJ7ImVsZWN0aW9uX2Vwb2NoIjoz + LCJxdW9ydW0iOlswXSwicXVvcnVtX25hbWVzIjpbImEiXSwicXVvcnVtX2xlYWRlcl9uYW1lIjoi + YSIsInF1b3J1bV9hZ2UiOjE0Mzg1LCJmZWF0dXJlcyI6eyJxdW9ydW1fY29uIjoiNDU0MDEzODI5 + MjgzNjY5NjA2MyIsInF1b3J1bV9tb24iOlsia3Jha2VuIiwibHVtaW5vdXMiLCJtaW1pYyIsIm9z + ZG1hcC1wcnVuZSIsIm5hdXRpbHVzIiwib2N0b3B1cyJdfSwibW9ubWFwIjp7ImVwb2NoIjoxLCJm + c2lkIjoiYWY0ZTE2NzMtMGI3Mi00MDJkLTk5MGEtMjJkMjkxOWQwZjFjIiwibW9kaWZpZWQiOiIy + MDIwLTA1LTA3VDAzOjM2OjM5LjkxODAzNVoiLCJjcmVhdGVkIjoiMjAyMC0wNS0wN1QwMzozNjoz + OS45MTgwMzVaIiwibWluX21vbl9yZWxlYXNlIjoxNSwibWluX21vbl9yZWxlYXNlX25hbWUiOiJv + Y3RvcHVzIiwiZmVhdHVyZXMiOnsicGVyc2lzdGVudCI6WyJrcmFrZW4iLCJsdW1pbm91cyIsIm1p + bWljIiwib3NkbWFwLXBydW5lIiwibmF1dGlsdXMiLCJvY3RvcHVzIl0sIm9wdGlvbmFsIjpbXX0s + Im1vbnMiOlt7InJhbmsiOjAsIm5hbWUiOiJhIiwicHVibGljX2FkZHJzIjp7ImFkZHJ2ZWMiOlt7 + InR5cGUiOiJ2MiIsImFkZHIiOiIxMC4xMTAuMjA1LjE3NDozMzAwIiwibm9uY2UiOjB9LHsidHlw + ZSI6InYxIiwiYWRkciI6IjEwLjExMC4yMDUuMTc0OjY3ODkiLCJub25jZSI6MH1dfSwiYWRkciI6 + IjEwLjExMC4yMDUuMTc0OjY3ODkvMCIsInB1YmxpY19hZGRyIjoiMTAuMTEwLjIwNS4xNzQ6Njc4 + OS8wIiwicHJpb3JpdHkiOjAsIndlaWdodCI6MH1dfX0iIiIKICAgICAgICApCiAgICAgICAgc2Vs + Zi5jbWRfb3V0cHV0X21hcFtzZWxmLmNtZF9uYW1lc1sibWdyIHNlcnZpY2VzIl1dID0gKAogICAg + ICAgICAgICAiIiJ7ImRhc2hib2FyZCI6Imh0dHBzOi8vY2VwaC1kYXNoYm9hcmQ6ODQ0My8iLCJw + cm9tZXRoZXVzIjoiaHR0cDovL2NlcGgtZGFzaGJvYXJkLWRiOjkyODMvIn0iIiIKICAgICAgICAp + CiAgICAgICAgc2VsZi5jbWRfb3V0cHV0X21hcFsKICAgICAgICAgICAgIiIieyJjYXBzIjogWyJt + b24iLCAiYWxsb3cgciwgYWxsb3cgY29tbWFuZCBxdW9ydW1fc3RhdHVzIiwgIm9zZCIsICJwcm9m + aWxlIHJiZC1yZWFkLW9ubHksIGFsbG93IHJ3eCBwb29sPWRlZmF1bHQucmd3Lm1ldGEsIGFsbG93 + IHIgcG9vbD0ucmd3LnJvb3QsIGFsbG93IHJ3IHBvb2w9ZGVmYXVsdC5yZ3cuY29udHJvbCwgYWxs + b3cgeCBwb29sPWRlZmF1bHQucmd3LmJ1Y2tldHMuaW5kZXgiLCAibWRzIiwgImFsbG93ICoiXSwg + ImVudGl0eSI6ICJjbGllbnQuaGVhbHRoY2hlY2tlciIsICJmb3JtYXQiOiAianNvbiIsICJwcmVm + aXgiOiAiYXV0aCBnZXQtb3ItY3JlYXRlIn0iIiIKICAgICAgICBdID0gIiIiW3siZW50aXR5Ijoi + Y2xpZW50LmhlYWx0aGNoZWNrZXIiLCJrZXkiOiJBUURGa2JOZWZ0NWJGUkFBVG5kTE5VU0VLcnVv + enhpWmkzbHJkQT09IiwiY2FwcyI6eyJtb24iOiJhbGxvdyByLCBhbGxvdyBjb21tYW5kIHF1b3J1 + bV9zdGF0dXMiLCJvc2QiOiJwcm9maWxlIHJiZC1yZWFkLW9ubHksIGFsbG93IHJ3eCBwb29sPWRl + ZmF1bHQucmd3Lm1ldGEsIGFsbG93IHIgcG9vbD0ucmd3LnJvb3QsIGFsbG93IHJ3IHBvb2w9ZGVm + YXVsdC5yZ3cuY29udHJvbCwgYWxsb3cgeCBwb29sPWRlZmF1bHQucmd3LmJ1Y2tldHMuaW5kZXgi + LCJtZHMiOiJhbGxvdyAqIn19XSIiIgogICAgICAgIHNlbGYuY21kX291dHB1dF9tYXBbCiAgICAg + ICAgICAgICIiInsiY2FwcyI6IFsibW9uIiwgInByb2ZpbGUgcmJkLCBhbGxvdyBjb21tYW5kICdv + c2QgYmxvY2tsaXN0JyIsICJvc2QiLCAicHJvZmlsZSByYmQiXSwgImVudGl0eSI6ICJjbGllbnQu + Y3NpLXJiZC1ub2RlIiwgImZvcm1hdCI6ICJqc29uIiwgInByZWZpeCI6ICJhdXRoIGdldC1vci1j + cmVhdGUifSIiIgogICAgICAgIF0gPSAiIiJbeyJlbnRpdHkiOiJjbGllbnQuY3NpLXJiZC1ub2Rl + Iiwia2V5IjoiQVFCT2dyTmVIYksxQXhBQXViWUJlVjhTMVUvR1B6cTVTVmVxNmc9PSIsImNhcHMi + OnsibW9uIjoicHJvZmlsZSByYmQsIGFsbG93IGNvbW1hbmQgJ29zZCBibG9ja2xpc3QnIiwib3Nk + IjoicHJvZmlsZSByYmQifX1dIiIiCiAgICAgICAgc2VsZi5jbWRfb3V0cHV0X21hcFsKICAgICAg + ICAgICAgIiIieyJjYXBzIjogWyJtb24iLCAicHJvZmlsZSByYmQsIGFsbG93IGNvbW1hbmQgJ29z + ZCBibG9ja2xpc3QnIiwgIm1nciIsICJhbGxvdyBydyIsICJvc2QiLCAicHJvZmlsZSByYmQiXSwg + ImVudGl0eSI6ICJjbGllbnQuY3NpLXJiZC1wcm92aXNpb25lciIsICJmb3JtYXQiOiAianNvbiIs ICJwcmVmaXgiOiAiYXV0aCBnZXQtb3ItY3JlYXRlIn0iIiIKICAgICAgICBdID0gIiIiW3siZW50 - aXR5IjoiY2xpZW50LmNzaS1jZXBoZnMtcHJvdmlzaW9uZXIiLCJrZXkiOiJBUUJPZ3JOZUFGZ2NH - QkFBdkdxS09BRDBEM3h4bVZZMFI5MTJkZz09IiwiY2FwcyI6eyJtZ3IiOiJhbGxvdyBydyIsIm1v - biI6ImFsbG93IHIsIGFsbG93IGNvbW1hbmQgJ29zZCBibG9ja2xpc3QnIiwib3NkIjoiYWxsb3cg - cncgdGFnIGNlcGhmcyBtZXRhZGF0YT0qIiwibWRzIjoiYWxsb3cgKiJ9fV0iIiIKICAgICAgICBz - ZWxmLmNtZF9vdXRwdXRfbWFwWwogICAgICAgICAgICAiIiJ7ImNhcHMiOiBbIm1vbiIsICJhbGxv - dyByLCBhbGxvdyBjb21tYW5kICdvc2QgYmxvY2tsaXN0JyIsICJtZ3IiLCAiYWxsb3cgcnciLCAi - b3NkIiwgImFsbG93IHJ3IHRhZyBjZXBoZnMgbWV0YWRhdGE9KiIsICJtZHMiLCAiYWxsb3cgKiJd - LCAiZW50aXR5IjogImNsaWVudC5jc2ktY2VwaGZzLXByb3Zpc2lvbmVyLW9wZW5zaGlmdC1zdG9y - YWdlIiwgImZvcm1hdCI6ICJqc29uIiwgInByZWZpeCI6ICJhdXRoIGdldC1vci1jcmVhdGUifSIi + aXR5IjoiY2xpZW50LmNzaS1yYmQtcHJvdmlzaW9uZXIiLCJrZXkiOiJBUUJOZ3JOZTFnZXlLeEFB + OGVrVmlSZEUraHNzNU93ZVlCa3dOZz09IiwiY2FwcyI6eyJtZ3IiOiJhbGxvdyBydyIsIm1vbiI6 + InByb2ZpbGUgcmJkLCBhbGxvdyBjb21tYW5kICdvc2QgYmxvY2tsaXN0JyIsIm9zZCI6InByb2Zp + bGUgcmJkIn19XSIiIgogICAgICAgIHNlbGYuY21kX291dHB1dF9tYXBbCiAgICAgICAgICAgICIi + InsiY2FwcyI6IFsibW9uIiwgImFsbG93IHIsIGFsbG93IGNvbW1hbmQgJ29zZCBibG9ja2xpc3Qn + IiwgIm1nciIsICJhbGxvdyBydyIsICJvc2QiLCAiYWxsb3cgcncgdGFnIGNlcGhmcyAqPSoiLCAi + bWRzIiwgImFsbG93IHJ3Il0sICJlbnRpdHkiOiAiY2xpZW50LmNzaS1jZXBoZnMtbm9kZSIsICJm + b3JtYXQiOiAianNvbiIsICJwcmVmaXgiOiAiYXV0aCBnZXQtb3ItY3JlYXRlIn0iIiIKICAgICAg + ICBdID0gIiIiW3siZW50aXR5IjoiY2xpZW50LmNzaS1jZXBoZnMtbm9kZSIsImtleSI6IkFRQk9n + ck5lRU51bkt4QUFQQ21nRTdSNkc4RGNYbmFKMUYzMnFnPT0iLCJjYXBzIjp7Im1kcyI6ImFsbG93 + IHJ3IiwibWdyIjoiYWxsb3cgcnciLCJtb24iOiJhbGxvdyByLCBhbGxvdyBjb21tYW5kICdvc2Qg + YmxvY2tsaXN0JyIsIm9zZCI6ImFsbG93IHJ3IHRhZyBjZXBoZnMgKj0qIn19XSIiIgogICAgICAg + IHNlbGYuY21kX291dHB1dF9tYXBbCiAgICAgICAgICAgICIiInsiY2FwcyI6IFsibW9uIiwgImFs + bG93IHIsIGFsbG93IGNvbW1hbmQgJ29zZCBibG9ja2xpc3QnIiwgIm1nciIsICJhbGxvdyBydyIs + ICJvc2QiLCAiYWxsb3cgcncgdGFnIGNlcGhmcyBtZXRhZGF0YT0qIiwgIm1kcyIsICJhbGxvdyAq + Il0sICJlbnRpdHkiOiAiY2xpZW50LmNzaS1jZXBoZnMtcHJvdmlzaW9uZXIiLCAiZm9ybWF0Ijog + Impzb24iLCAicHJlZml4IjogImF1dGggZ2V0LW9yLWNyZWF0ZSJ9IiIiCiAgICAgICAgXSA9ICIi + Ilt7ImVudGl0eSI6ImNsaWVudC5jc2ktY2VwaGZzLXByb3Zpc2lvbmVyIiwia2V5IjoiQVFCT2dy + TmVBRmdjR0JBQXZHcUtPQUQwRDN4eG1WWTBSOTEyZGc9PSIsImNhcHMiOnsibWdyIjoiYWxsb3cg + cnciLCJtb24iOiJhbGxvdyByLCBhbGxvdyBjb21tYW5kICdvc2QgYmxvY2tsaXN0JyIsIm9zZCI6 + ImFsbG93IHJ3IHRhZyBjZXBoZnMgbWV0YWRhdGE9KiIsIm1kcyI6ImFsbG93ICoifX1dIiIiCiAg + ICAgICAgc2VsZi5jbWRfb3V0cHV0X21hcFsKICAgICAgICAgICAgIiIieyJjYXBzIjogWyJtb24i + LCAiYWxsb3cgciwgYWxsb3cgY29tbWFuZCAnb3NkIGJsb2NrbGlzdCciLCAibWdyIiwgImFsbG93 + IHJ3IiwgIm9zZCIsICJhbGxvdyBydyB0YWcgY2VwaGZzIG1ldGFkYXRhPSoiLCAibWRzIiwgImFs + bG93ICoiXSwgImVudGl0eSI6ICJjbGllbnQuY3NpLWNlcGhmcy1wcm92aXNpb25lci1vcGVuc2hp + ZnQtc3RvcmFnZSIsICJmb3JtYXQiOiAianNvbiIsICJwcmVmaXgiOiAiYXV0aCBnZXQtb3ItY3Jl + YXRlIn0iIiIKICAgICAgICBdID0gIiIiW3siZW50aXR5IjoiY2xpZW50LmNzaS1jZXBoZnMtcHJv + dmlzaW9uZXItb3BlbnNoaWZ0LXN0b3JhZ2UiLCJrZXkiOiJCUUJPZ3JOZUFGZ2NHQkFBdkdxS09B + RDBEM3h4bVZZMFI5MTJkZz09IiwiY2FwcyI6eyJtZ3IiOiJhbGxvdyBydyIsIm1vbiI6ImFsbG93 + IHIsIGFsbG93IGNvbW1hbmQgJ29zZCBibG9ja2xpc3QnIiwib3NkIjoiYWxsb3cgcncgdGFnIGNl + cGhmcyBtZXRhZGF0YT0qIiwgIm1kcyI6ImFsbG93ICoifX1dIiIiCiAgICAgICAgc2VsZi5jbWRf + b3V0cHV0X21hcFsKICAgICAgICAgICAgIiIieyJjYXBzIjogWyJtb24iLCAiYWxsb3cgciwgYWxs + b3cgY29tbWFuZCAnb3NkIGJsb2NrbGlzdCciLCAibWdyIiwgImFsbG93IHJ3IiwgIm9zZCIsICJh + bGxvdyBydyB0YWcgY2VwaGZzIG1ldGFkYXRhPW15ZnMiLCAibWRzIiwgImFsbG93ICoiXSwgImVu + dGl0eSI6ICJjbGllbnQuY3NpLWNlcGhmcy1wcm92aXNpb25lci1vcGVuc2hpZnQtc3RvcmFnZS1t + eWZzIiwgImZvcm1hdCI6ICJqc29uIiwgInByZWZpeCI6ICJhdXRoIGdldC1vci1jcmVhdGUifSIi IgogICAgICAgIF0gPSAiIiJbeyJlbnRpdHkiOiJjbGllbnQuY3NpLWNlcGhmcy1wcm92aXNpb25l - ci1vcGVuc2hpZnQtc3RvcmFnZSIsImtleSI6IkJRQk9nck5lQUZnY0dCQUF2R3FLT0FEMEQzeHht - VlkwUjkxMmRnPT0iLCJjYXBzIjp7Im1nciI6ImFsbG93IHJ3IiwibW9uIjoiYWxsb3cgciwgYWxs - b3cgY29tbWFuZCAnb3NkIGJsb2NrbGlzdCciLCJvc2QiOiJhbGxvdyBydyB0YWcgY2VwaGZzIG1l - dGFkYXRhPSoiLCAibWRzIjoiYWxsb3cgKiJ9fV0iIiIKICAgICAgICBzZWxmLmNtZF9vdXRwdXRf - bWFwWwogICAgICAgICAgICAiIiJ7ImNhcHMiOiBbIm1vbiIsICJhbGxvdyByLCBhbGxvdyBjb21t - YW5kICdvc2QgYmxvY2tsaXN0JyIsICJtZ3IiLCAiYWxsb3cgcnciLCAib3NkIiwgImFsbG93IHJ3 - IHRhZyBjZXBoZnMgbWV0YWRhdGE9bXlmcyIsICJtZHMiLCAiYWxsb3cgKiJdLCAiZW50aXR5Ijog - ImNsaWVudC5jc2ktY2VwaGZzLXByb3Zpc2lvbmVyLW9wZW5zaGlmdC1zdG9yYWdlLW15ZnMiLCAi - Zm9ybWF0IjogImpzb24iLCAicHJlZml4IjogImF1dGggZ2V0LW9yLWNyZWF0ZSJ9IiIiCiAgICAg - ICAgXSA9ICIiIlt7ImVudGl0eSI6ImNsaWVudC5jc2ktY2VwaGZzLXByb3Zpc2lvbmVyLW9wZW5z - aGlmdC1zdG9yYWdlLW15ZnMiLCJrZXkiOiJDUUJPZ3JOZUFGZ2NHQkFBdkdxS09BRDBEM3h4bVZZ - MFI5MTJkZz09IiwiY2FwcyI6eyJtZ3IiOiJhbGxvdyBydyIsIm1vbiI6ImFsbG93IHIsIGFsbG93 - IGNvbW1hbmQgJ29zZCBibG9ja2xpc3QnIiwib3NkIjoiYWxsb3cgcncgdGFnIGNlcGhmcyBtZXRh - ZGF0YT1teWZzIiwibWRzIjoiYWxsb3cgKiJ9fV0iIiIKICAgICAgICBzZWxmLmNtZF9vdXRwdXRf - bWFwWwogICAgICAgICAgICAiIiJ7ImNhcHMiOiBbIm1vbiIsICJhbGxvdyByLCBhbGxvdyBjb21t - YW5kIHF1b3J1bV9zdGF0dXMsIGFsbG93IGNvbW1hbmQgdmVyc2lvbiIsICJtZ3IiLCAiYWxsb3cg - Y29tbWFuZCBjb25maWciLCAib3NkIiwgInByb2ZpbGUgcmJkLXJlYWQtb25seSwgYWxsb3cgcnd4 - IHBvb2w9ZGVmYXVsdC5yZ3cubWV0YSwgYWxsb3cgciBwb29sPS5yZ3cucm9vdCwgYWxsb3cgcncg - cG9vbD1kZWZhdWx0LnJndy5jb250cm9sLCBhbGxvdyByeCBwb29sPWRlZmF1bHQucmd3LmxvZywg - YWxsb3cgeCBwb29sPWRlZmF1bHQucmd3LmJ1Y2tldHMuaW5kZXgiLCAibWRzIiwgImFsbG93ICoi - XSwgImVudGl0eSI6ICJjbGllbnQuaGVhbHRoY2hlY2tlciIsICJmb3JtYXQiOiAianNvbiIsICJw - cmVmaXgiOiAiYXV0aCBnZXQtb3ItY3JlYXRlIn0iIiIKICAgICAgICBdID0gIiIiW3siZW50aXR5 - IjoiY2xpZW50LmhlYWx0aGNoZWNrZXIiLCJrZXkiOiJBUURGa2JOZWZ0NWJGUkFBVG5kTE5VU0VL - cnVvenhpWmkzbHJkQT09IiwiY2FwcyI6eyJtb24iOiAiYWxsb3cgciwgYWxsb3cgY29tbWFuZCBx - dW9ydW1fc3RhdHVzLCBhbGxvdyBjb21tYW5kIHZlcnNpb24iLCAibWdyIjogImFsbG93IGNvbW1h - bmQgY29uZmlnIiwgIm9zZCI6ICJwcm9maWxlIHJiZC1yZWFkLW9ubHksIGFsbG93IHJ3eCBwb29s - PWRlZmF1bHQucmd3Lm1ldGEsIGFsbG93IHIgcG9vbD0ucmd3LnJvb3QsIGFsbG93IHJ3IHBvb2w9 - ZGVmYXVsdC5yZ3cuY29udHJvbCwgYWxsb3cgcnggcG9vbD1kZWZhdWx0LnJndy5sb2csIGFsbG93 - IHggcG9vbD1kZWZhdWx0LnJndy5idWNrZXRzLmluZGV4IiwibWRzIjoiYWxsb3cgKiJ9fV0iIiIK - ICAgICAgICBzZWxmLmNtZF9vdXRwdXRfbWFwWwogICAgICAgICAgICAiIiJ7ImNhcHMiOiBbIm1v - biIsICJhbGxvdyByLCBhbGxvdyBjb21tYW5kIHF1b3J1bV9zdGF0dXMsIGFsbG93IGNvbW1hbmQg - dmVyc2lvbiIsICJtZ3IiLCAiYWxsb3cgY29tbWFuZCBjb25maWciLCAib3NkIiwgInByb2ZpbGUg - cmJkLXJlYWQtb25seSwgYWxsb3cgcnd4IHBvb2w9ZGVmYXVsdC5yZ3cubWV0YSwgYWxsb3cgciBw - b29sPS5yZ3cucm9vdCwgYWxsb3cgcncgcG9vbD1kZWZhdWx0LnJndy5jb250cm9sLCBhbGxvdyBy - eCBwb29sPWRlZmF1bHQucmd3LmxvZywgYWxsb3cgeCBwb29sPWRlZmF1bHQucmd3LmJ1Y2tldHMu - aW5kZXgiLCAibWRzIiwgImFsbG93ICoiXSwgImVudGl0eSI6ICJjbGllbnQuaGVhbHRoY2hlY2tl - ciIsICJmb3JtYXQiOiAianNvbiIsICJwcmVmaXgiOiAiYXV0aCBjYXBzIn0iIiIKICAgICAgICBd - ID0gIiIiW3siZW50aXR5IjoiY2xpZW50LmhlYWx0aGNoZWNrZXIiLCJrZXkiOiJBUURGa2JOZWZ0 - NWJGUkFBVG5kTE5VU1JLcnVvenhpWmkzbHJkQT09IiwiY2FwcyI6eyJtb24iOiAiYWxsb3cgciwg - YWxsb3cgY29tbWFuZCBxdW9ydW1fc3RhdHVzLCBhbGxvdyBjb21tYW5kIHZlcnNpb24iLCAibWdy - IjogImFsbG93IGNvbW1hbmQgY29uZmlnIiwgIm9zZCI6ICJwcm9maWxlIHJiZC1yZWFkLW9ubHks - IGFsbG93IHJ3eCBwb29sPWRlZmF1bHQucmd3Lm1ldGEsIGFsbG93IHIgcG9vbD0ucmd3LnJvb3Qs - IGFsbG93IHJ3IHBvb2w9ZGVmYXVsdC5yZ3cuY29udHJvbCwgYWxsb3cgcnggcG9vbD1kZWZhdWx0 - LnJndy5sb2csIGFsbG93IHggcG9vbD1kZWZhdWx0LnJndy5idWNrZXRzLmluZGV4IiwibWRzIjoi - YWxsb3cgKiJ9fV0iIiIKICAgICAgICBzZWxmLmNtZF9vdXRwdXRfbWFwWyIiInsiZm9ybWF0Ijog - Impzb24iLCAicHJlZml4IjogIm1nciBzZXJ2aWNlcyJ9IiIiXSA9ICgKICAgICAgICAgICAgIiIi - eyJkYXNoYm9hcmQiOiAiaHR0cDovL3Jvb2stY2VwaC1tZ3ItYS01N2NmOWY4NGJjLWY0am5sOjcw - MDAvIiwgInByb21ldGhldXMiOiAiaHR0cDovL3Jvb2stY2VwaC1tZ3ItYS01N2NmOWY4NGJjLWY0 - am5sOjkyODMvIn0iIiIKICAgICAgICApCiAgICAgICAgc2VsZi5jbWRfb3V0cHV0X21hcFsKICAg - ICAgICAgICAgIiIieyJlbnRpdHkiOiAiY2xpZW50LmhlYWx0aGNoZWNrZXIiLCAiZm9ybWF0Ijog - Impzb24iLCAicHJlZml4IjogImF1dGggZ2V0In0iIiIKICAgICAgICBdID0gIiIieyJkYXNoYm9h - cmQiOiAiaHR0cDovL3Jvb2stY2VwaC1tZ3ItYS01N2NmOWY4NGJjLWY0am5sOjcwMDAvIiwgInBy - b21ldGhldXMiOiAiaHR0cDovL3Jvb2stY2VwaC1tZ3ItYS01N2NmOWY4NGJjLWY0am5sOjkyODMv - In0iIiIKICAgICAgICBzZWxmLmNtZF9vdXRwdXRfbWFwWwogICAgICAgICAgICAiIiJ7ImVudGl0 - eSI6ICJjbGllbnQuaGVhbHRoY2hlY2tlciIsICJmb3JtYXQiOiAianNvbiIsICJwcmVmaXgiOiAi - YXV0aCBnZXQifSIiIgogICAgICAgIF0gPSAiIiJbeyJlbnRpdHkiOiJjbGllbnQuaGVhbHRoY2hl - Y2tlciIsImtleSI6IkFRREZrYk5lZnQ1YkZSQUFUbmRMTlVTRUtydW96eGlaaTNscmRBPT0iLCJj - YXBzIjp7Im1vbiI6ICJhbGxvdyByLCBhbGxvdyBjb21tYW5kIHF1b3J1bV9zdGF0dXMsIGFsbG93 - IGNvbW1hbmQgdmVyc2lvbiIsICJtZ3IiOiAiYWxsb3cgY29tbWFuZCBjb25maWciLCAib3NkIjog - InByb2ZpbGUgcmJkLXJlYWQtb25seSwgYWxsb3cgcnd4IHBvb2w9ZGVmYXVsdC5yZ3cubWV0YSwg - YWxsb3cgciBwb29sPS5yZ3cucm9vdCwgYWxsb3cgcncgcG9vbD1kZWZhdWx0LnJndy5jb250cm9s - LCBhbGxvdyByeCBwb29sPWRlZmF1bHQucmd3LmxvZywgYWxsb3cgeCBwb29sPWRlZmF1bHQucmd3 - LmJ1Y2tldHMuaW5kZXgiLCJtZHMiOiJhbGxvdyAqIn19XSIiIgogICAgICAgIHNlbGYuY21kX291 - dHB1dF9tYXBbCiAgICAgICAgICAgICIiInsiZW50aXR5IjogImNsaWVudC5jc2ktY2VwaGZzLW5v - ZGUiLCAiZm9ybWF0IjogImpzb24iLCAicHJlZml4IjogImF1dGggZ2V0In0iIiIKICAgICAgICBd - ID0gIiIiW10iIiIKICAgICAgICBzZWxmLmNtZF9vdXRwdXRfbWFwWwogICAgICAgICAgICAiIiJ7 - ImVudGl0eSI6ICJjbGllbnQuY3NpLXJiZC1ub2RlIiwgImZvcm1hdCI6ICJqc29uIiwgInByZWZp - eCI6ICJhdXRoIGdldCJ9IiIiCiAgICAgICAgXSA9ICIiIltdIiIiCiAgICAgICAgc2VsZi5jbWRf - b3V0cHV0X21hcFsKICAgICAgICAgICAgIiIieyJlbnRpdHkiOiAiY2xpZW50LmNzaS1yYmQtcHJv - dmlzaW9uZXIiLCAiZm9ybWF0IjogImpzb24iLCAicHJlZml4IjogImF1dGggZ2V0In0iIiIKICAg - ICAgICBdID0gIiIiW10iIiIKICAgICAgICBzZWxmLmNtZF9vdXRwdXRfbWFwWwogICAgICAgICAg - ICAiIiJ7ImVudGl0eSI6ICJjbGllbnQuY3NpLWNlcGhmcy1wcm92aXNpb25lciIsICJmb3JtYXQi - OiAianNvbiIsICJwcmVmaXgiOiAiYXV0aCBnZXQifSIiIgogICAgICAgIF0gPSAiIiJbXSIiIgog - ICAgICAgIHNlbGYuY21kX291dHB1dF9tYXBbCiAgICAgICAgICAgICIiInsiZW50aXR5IjogImNs - aWVudC5jc2ktY2VwaGZzLXByb3Zpc2lvbmVyLW9wZW5zaGlmdC1zdG9yYWdlIiwgImZvcm1hdCI6 - ICJqc29uIiwgInByZWZpeCI6ICJhdXRoIGdldCJ9IiIiCiAgICAgICAgXSA9ICIiIltdIiIiCiAg - ICAgICAgc2VsZi5jbWRfb3V0cHV0X21hcFsKICAgICAgICAgICAgIiIieyJlbnRpdHkiOiAiY2xp - ZW50LmNzaS1jZXBoZnMtcHJvdmlzaW9uZXItb3BlbnNoaWZ0LXN0b3JhZ2UtbXlmcyIsICJmb3Jt - YXQiOiAianNvbiIsICJwcmVmaXgiOiAiYXV0aCBnZXQifSIiIgogICAgICAgIF0gPSAiIiJbXSIi - IgogICAgICAgIHNlbGYuY21kX291dHB1dF9tYXBbCiAgICAgICAgICAgICIiInsiZW50aXR5Ijog - ImNsaWVudC5jc2ktY2VwaGZzLXByb3Zpc2lvbmVyIiwgImZvcm1hdCI6ICJqc29uIiwgInByZWZp - eCI6ICJhdXRoIGdldCJ9IiIiCiAgICAgICAgXSA9ICIiIlt7ImVudGl0eSI6ImNsaWVudC5jc2kt - Y2VwaGZzLXByb3Zpc2lvbmVyIiwia2V5IjoiQVFERmtiTmVmdDViRlJBQVRuZExOVVNFS3J1b3p4 - aVppM2xyZEE9PSIsImNhcHMiOnsibW9uIjoiYWxsb3cgciIsICJtZ3IiOiJhbGxvdyBydyIsICJv - c2QiOiJhbGxvdyBydyB0YWcgY2VwaGZzIG1ldGFkYXRhPSoiLCJtZHMiOiJhbGxvdyAqIn19XSIi - IgogICAgICAgIHNlbGYuY21kX291dHB1dF9tYXBbCiAgICAgICAgICAgICIiInsiY2FwcyI6IFsi - bW9uIiwgImFsbG93IHIsIGFsbG93IGNvbW1hbmQgJ29zZCBibG9ja2xpc3QnIiwgIm1nciIsICJh - bGxvdyBydyIsICJvc2QiLCAiYWxsb3cgcncgdGFnIGNlcGhmcyBtZXRhZGF0YT0qIiwgIm1kcyIs - ICJhbGxvdyAqIl0sICJlbnRpdHkiOiAiY2xpZW50LmNzaS1jZXBoZnMtcHJvdmlzaW9uZXIiLCAi - Zm9ybWF0IjogImpzb24iLCAicHJlZml4IjogImF1dGggY2FwcyJ9IiIiCiAgICAgICAgXSA9ICIi - Ilt7ImVudGl0eSI6ImNsaWVudC5jc2ktY2VwaGZzLXByb3Zpc2lvbmVyIiwia2V5IjoiQVFERmti - TmVmdDViRlJBQVRuZExOVVNFS3J1b3p4aVppM2xyZEE9PSIsImNhcHMiOnsibW9uIjoiYWxsb3cg - ciwgIGFsbG93IGNvbW1hbmQgJ29zZCBibG9ja2xpc3QnIiwgIm1nciI6ImFsbG93IHJ3IiwgIm9z - ZCI6ImFsbG93IHJ3IHRhZyBjZXBoZnMgbWV0YWRhdGE9KiIsIm1kcyI6ImFsbG93ICoifX1dIiIi - CiAgICAgICAgc2VsZi5jbWRfb3V0cHV0X21hcFsneyJmb3JtYXQiOiAianNvbiIsICJwcmVmaXgi - OiAic3RhdHVzIn0nXSA9IGNlcGhfc3RhdHVzX3N0cgoKICAgIGRlZiBzaHV0ZG93bihzZWxmKToK - ICAgICAgICBwYXNzCgogICAgZGVmIGdldF9mc2lkKHNlbGYpOgogICAgICAgIHJldHVybiAiYWY0 - ZTE2NzMtMGI3Mi00MDJkLTk5MGEtMjJkMjkxOWQwZjFjIgoKICAgIGRlZiBjb25mX3JlYWRfZmls - ZShzZWxmKToKICAgICAgICBwYXNzCgogICAgZGVmIGNvbm5lY3Qoc2VsZik6CiAgICAgICAgcGFz - cwoKICAgIGRlZiBwb29sX2V4aXN0cyhzZWxmLCBwb29sX25hbWUpOgogICAgICAgIHJldHVybiBU - cnVlCgogICAgZGVmIG1vbl9jb21tYW5kKHNlbGYsIGNtZCwgb3V0KToKICAgICAgICBqc29uX2Nt - ZCA9IGpzb24ubG9hZHMoY21kKQogICAgICAgIGpzb25fY21kX3N0ciA9IGpzb24uZHVtcHMoanNv - bl9jbWQsIHNvcnRfa2V5cz1UcnVlKQogICAgICAgIGNtZF9vdXRwdXQgPSBzZWxmLmNtZF9vdXRw - dXRfbWFwW2pzb25fY21kX3N0cl0KICAgICAgICByZXR1cm4gc2VsZi5yZXR1cm5fdmFsLCBjbWRf - b3V0cHV0LCBzdHIoc2VsZi5lcnJfbWVzc2FnZS5lbmNvZGUoInV0Zi04IikpCgogICAgZGVmIF9j - b252ZXJ0X2hvc3RuYW1lX3RvX2lwKHNlbGYsIGhvc3RfbmFtZSk6CiAgICAgICAgaXBfcmVnX3gg - PSByZS5jb21waWxlKHIiXGR7MSwzfS5cZHsxLDN9LlxkezEsM30uXGR7MSwzfSIpCiAgICAgICAg - IyBpZiBwcm92aWRlZCBob3N0IGlzIGRpcmVjdGx5IGFuIElQIGFkZHJlc3MsIHJldHVybiB0aGUg - c2FtZQogICAgICAgIGlmIGlwX3JlZ194Lm1hdGNoKGhvc3RfbmFtZSk6CiAgICAgICAgICAgIHJl - dHVybiBob3N0X25hbWUKICAgICAgICBpbXBvcnQgcmFuZG9tCgogICAgICAgIGhvc3RfaXAgPSBz - ZWxmLmR1bW15X2hvc3RfaXBfbWFwLmdldChob3N0X25hbWUsICIiKQogICAgICAgIGlmIG5vdCBo - b3N0X2lwOgogICAgICAgICAgICBob3N0X2lwID0gZiIxNzIuOS57cmFuZG9tLnJhbmRpbnQoMCwg - MjU0KX0ue3JhbmRvbS5yYW5kaW50KDAsIDI1NCl9IgogICAgICAgICAgICBzZWxmLmR1bW15X2hv - c3RfaXBfbWFwW2hvc3RfbmFtZV0gPSBob3N0X2lwCiAgICAgICAgZGVsIHJhbmRvbQogICAgICAg - IHJldHVybiBob3N0X2lwCgogICAgQGNsYXNzbWV0aG9kCiAgICBkZWYgUmFkb3MoY29uZmZpbGU9 - Tm9uZSk6CiAgICAgICAgcmV0dXJuIER1bW15UmFkb3MoKQoKCmNsYXNzIFMzQXV0aChBdXRoQmFz - ZSk6CiAgICAiIiJBdHRhY2hlcyBBV1MgQXV0aGVudGljYXRpb24gdG8gdGhlIGdpdmVuIFJlcXVl - c3Qgb2JqZWN0LiIiIgoKICAgIHNlcnZpY2VfYmFzZV91cmwgPSAiczMuYW1hem9uYXdzLmNvbSIK - CiAgICBkZWYgX19pbml0X18oc2VsZiwgYWNjZXNzX2tleSwgc2VjcmV0X2tleSwgc2VydmljZV91 - cmw9Tm9uZSk6CiAgICAgICAgaWYgc2VydmljZV91cmw6CiAgICAgICAgICAgIHNlbGYuc2Vydmlj - ZV9iYXNlX3VybCA9IHNlcnZpY2VfdXJsCiAgICAgICAgc2VsZi5hY2Nlc3Nfa2V5ID0gc3RyKGFj - Y2Vzc19rZXkpCiAgICAgICAgc2VsZi5zZWNyZXRfa2V5ID0gc3RyKHNlY3JldF9rZXkpCgogICAg - ZGVmIF9fY2FsbF9fKHNlbGYsIHIpOgogICAgICAgICMgQ3JlYXRlIGRhdGUgaGVhZGVyIGlmIGl0 - IGlzIG5vdCBjcmVhdGVkIHlldC4KICAgICAgICBpZiAiZGF0ZSIgbm90IGluIHIuaGVhZGVycyBh - bmQgIngtYW16LWRhdGUiIG5vdCBpbiByLmhlYWRlcnM6CiAgICAgICAgICAgIHIuaGVhZGVyc1si - ZGF0ZSJdID0gZm9ybWF0ZGF0ZSh0aW1ldmFsPU5vbmUsIGxvY2FsdGltZT1GYWxzZSwgdXNlZ210 - PVRydWUpCiAgICAgICAgc2lnbmF0dXJlID0gc2VsZi5nZXRfc2lnbmF0dXJlKHIpCiAgICAgICAg - c2lnbmF0dXJlID0gc2lnbmF0dXJlLmRlY29kZSgidXRmLTgiKQogICAgICAgIHIuaGVhZGVyc1si - QXV0aG9yaXphdGlvbiJdID0gZiJBV1Mge3NlbGYuYWNjZXNzX2tleX06e3NpZ25hdHVyZX0iCiAg - ICAgICAgcmV0dXJuIHIKCiAgICBkZWYgZ2V0X3NpZ25hdHVyZShzZWxmLCByKToKICAgICAgICBj - YW5vbmljYWxfc3RyaW5nID0gc2VsZi5nZXRfY2Fub25pY2FsX3N0cmluZyhyLnVybCwgci5oZWFk - ZXJzLCByLm1ldGhvZCkKICAgICAgICBrZXkgPSBzZWxmLnNlY3JldF9rZXkuZW5jb2RlKCJ1dGYt - OCIpCiAgICAgICAgbXNnID0gY2Fub25pY2FsX3N0cmluZy5lbmNvZGUoInV0Zi04IikKICAgICAg - ICBoID0gaG1hYy5uZXcoa2V5LCBtc2csIGRpZ2VzdG1vZD1zaGEpCiAgICAgICAgcmV0dXJuIGVu - Y29kZXN0cmluZyhoLmRpZ2VzdCgpKS5zdHJpcCgpCgogICAgZGVmIGdldF9jYW5vbmljYWxfc3Ry - aW5nKHNlbGYsIHVybCwgaGVhZGVycywgbWV0aG9kKToKICAgICAgICBwYXJzZWR1cmwgPSB1cmxw - YXJzZSh1cmwpCiAgICAgICAgb2JqZWN0a2V5ID0gcGFyc2VkdXJsLnBhdGhbMTpdCgogICAgICAg - IGJ1Y2tldCA9IHBhcnNlZHVybC5uZXRsb2NbOiAtbGVuKHNlbGYuc2VydmljZV9iYXNlX3VybCld - CiAgICAgICAgaWYgbGVuKGJ1Y2tldCkgPiAxOgogICAgICAgICAgICAjIHJlbW92ZSBsYXN0IGRv - dAogICAgICAgICAgICBidWNrZXQgPSBidWNrZXRbOi0xXQoKICAgICAgICBpbnRlcmVzdGluZ19o - ZWFkZXJzID0geyJjb250ZW50LW1kNSI6ICIiLCAiY29udGVudC10eXBlIjogIiIsICJkYXRlIjog - IiJ9CiAgICAgICAgZm9yIGtleSBpbiBoZWFkZXJzOgogICAgICAgICAgICBsayA9IGtleS5sb3dl - cigpCiAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgIGxrID0gbGsuZGVjb2RlKCJ1dGYt - OCIpCiAgICAgICAgICAgIGV4Y2VwdDoKICAgICAgICAgICAgICAgIHBhc3MKICAgICAgICAgICAg - aWYgaGVhZGVyc1trZXldIGFuZCAoCiAgICAgICAgICAgICAgICBsayBpbiBpbnRlcmVzdGluZ19o - ZWFkZXJzLmtleXMoKSBvciBsay5zdGFydHN3aXRoKCJ4LWFtei0iKQogICAgICAgICAgICApOgog - ICAgICAgICAgICAgICAgaW50ZXJlc3RpbmdfaGVhZGVyc1tsa10gPSBoZWFkZXJzW2tleV0uc3Ry - aXAoKQoKICAgICAgICAjIElmIHgtYW16LWRhdGUgaXMgdXNlZCBpdCBzdXBlcnNlZGVzIHRoZSBk - YXRlIGhlYWRlci4KICAgICAgICBpZiAieC1hbXotZGF0ZSIgaW4gaW50ZXJlc3RpbmdfaGVhZGVy - czoKICAgICAgICAgICAgaW50ZXJlc3RpbmdfaGVhZGVyc1siZGF0ZSJdID0gIiIKCiAgICAgICAg - YnVmID0gZiJ7bWV0aG9kfVxuIgogICAgICAgIGZvciBrZXkgaW4gc29ydGVkKGludGVyZXN0aW5n - X2hlYWRlcnMua2V5cygpKToKICAgICAgICAgICAgdmFsID0gaW50ZXJlc3RpbmdfaGVhZGVyc1tr - ZXldCiAgICAgICAgICAgIGlmIGtleS5zdGFydHN3aXRoKCJ4LWFtei0iKToKICAgICAgICAgICAg - ICAgIGJ1ZiArPSBmIntrZXl9Ont2YWx9XG4iCiAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAg - ICAgICBidWYgKz0gZiJ7dmFsfVxuIgoKICAgICAgICAjIGFwcGVuZCB0aGUgYnVja2V0IGlmIGl0 - IGV4aXN0cwogICAgICAgIGlmIGJ1Y2tldCAhPSAiIjoKICAgICAgICAgICAgYnVmICs9IGYiL3ti - dWNrZXR9IgoKICAgICAgICAjIGFkZCB0aGUgb2JqZWN0a2V5LiBldmVuIGlmIGl0IGRvZXNuJ3Qg - ZXhpc3QsIGFkZCB0aGUgc2xhc2gKICAgICAgICBidWYgKz0gZiIve29iamVjdGtleX0iCgogICAg - ICAgIHJldHVybiBidWYKCgpjbGFzcyBSYWRvc0pTT046CiAgICBFWFRFUk5BTF9VU0VSX05BTUUg - PSAiY2xpZW50LmhlYWx0aGNoZWNrZXIiCiAgICBFWFRFUk5BTF9SR1dfQURNSU5fT1BTX1VTRVJf - TkFNRSA9ICJyZ3ctYWRtaW4tb3BzLXVzZXIiCiAgICBFTVBUWV9PVVRQVVRfTElTVCA9ICJFbXB0 - eSBvdXRwdXQgbGlzdCIKICAgIERFRkFVTFRfUkdXX1BPT0xfUFJFRklYID0gImRlZmF1bHQiCiAg - ICBERUZBVUxUX01PTklUT1JJTkdfRU5EUE9JTlRfUE9SVCA9ICI5MjgzIgoKICAgIEBjbGFzc21l - dGhvZAogICAgZGVmIGdlbl9hcmdfcGFyc2VyKGNscywgYXJnc190b19wYXJzZT1Ob25lKToKICAg - ICAgICBhcmdQID0gYXJncGFyc2UuQXJndW1lbnRQYXJzZXIoKQoKICAgICAgICBjb21tb25fZ3Jv - dXAgPSBhcmdQLmFkZF9hcmd1bWVudF9ncm91cCgiY29tbW9uIikKICAgICAgICBjb21tb25fZ3Jv - dXAuYWRkX2FyZ3VtZW50KCItLXZlcmJvc2UiLCAiLXYiLCBhY3Rpb249InN0b3JlX3RydWUiLCBk - ZWZhdWx0PUZhbHNlKQogICAgICAgIGNvbW1vbl9ncm91cC5hZGRfYXJndW1lbnQoCiAgICAgICAg - ICAgICItLWNlcGgtY29uZiIsICItYyIsIGhlbHA9IlByb3ZpZGUgYSBjZXBoIGNvbmYgZmlsZS4i - LCB0eXBlPXN0ciwgZGVmYXVsdD0iIgogICAgICAgICkKICAgICAgICBjb21tb25fZ3JvdXAuYWRk - X2FyZ3VtZW50KAogICAgICAgICAgICAiLS1rZXlyaW5nIiwgIi1rIiwgaGVscD0iUGF0aCB0byBj - ZXBoIGtleXJpbmcgZmlsZS4iLCB0eXBlPXN0ciwgZGVmYXVsdD0iIgogICAgICAgICkKICAgICAg - ICBjb21tb25fZ3JvdXAuYWRkX2FyZ3VtZW50KAogICAgICAgICAgICAiLS1ydW4tYXMtdXNlciIs - CiAgICAgICAgICAgICItdSIsCiAgICAgICAgICAgIGRlZmF1bHQ9IiIsCiAgICAgICAgICAgIHR5 - cGU9c3RyLAogICAgICAgICAgICBoZWxwPSJQcm92aWRlcyBhIHVzZXIgbmFtZSB0byBjaGVjayB0 - aGUgY2x1c3RlcidzIGhlYWx0aCBzdGF0dXMsIG11c3QgYmUgcHJlZml4ZWQgYnkgJ2NsaWVudC4n - IiwKICAgICAgICApCiAgICAgICAgY29tbW9uX2dyb3VwLmFkZF9hcmd1bWVudCgKICAgICAgICAg - ICAgIi0tY2x1c3Rlci1uYW1lIiwKICAgICAgICAgICAgZGVmYXVsdD0iIiwKICAgICAgICAgICAg - aGVscD0iS3ViZXJuZXRlcyBjbHVzdGVyIG5hbWUobGVnYWN5IGZsYWcpLCBOb3RlOiBFaXRoZXIg - dXNlIHRoaXMgb3IgLS1rOHMtY2x1c3Rlci1uYW1lIiwKICAgICAgICApCiAgICAgICAgY29tbW9u - X2dyb3VwLmFkZF9hcmd1bWVudCgKICAgICAgICAgICAgIi0tazhzLWNsdXN0ZXItbmFtZSIsIGRl - ZmF1bHQ9IiIsIGhlbHA9Ikt1YmVybmV0ZXMgY2x1c3RlciBuYW1lIgogICAgICAgICkKICAgICAg - ICBjb21tb25fZ3JvdXAuYWRkX2FyZ3VtZW50KAogICAgICAgICAgICAiLS1uYW1lc3BhY2UiLAog - ICAgICAgICAgICBkZWZhdWx0PSIiLAogICAgICAgICAgICBoZWxwPSJOYW1lc3BhY2Ugd2hlcmUg - Q2VwaENsdXN0ZXIgaXMgcnVubmluZyIsCiAgICAgICAgKQogICAgICAgIGNvbW1vbl9ncm91cC5h - ZGRfYXJndW1lbnQoCiAgICAgICAgICAgICItLXJndy1wb29sLXByZWZpeCIsIGRlZmF1bHQ9IiIs - IGhlbHA9IlJHVyBQb29sIHByZWZpeCIKICAgICAgICApCiAgICAgICAgY29tbW9uX2dyb3VwLmFk - ZF9hcmd1bWVudCgKICAgICAgICAgICAgIi0tcmVzdHJpY3RlZC1hdXRoLXBlcm1pc3Npb24iLAog - ICAgICAgICAgICBkZWZhdWx0PUZhbHNlLAogICAgICAgICAgICBoZWxwPSJSZXN0cmljdCBjZXBo - Q1NJS2V5cmluZ3MgYXV0aCBwZXJtaXNzaW9ucyB0byBzcGVjaWZpYyBwb29scywgY2x1c3Rlci4i - CiAgICAgICAgICAgICsgIk1hbmRhdG9yeSBmbGFncyB0aGF0IG5lZWQgdG8gYmUgc2V0IGFyZSAt - LXJiZC1kYXRhLXBvb2wtbmFtZSwgYW5kIC0tazhzLWNsdXN0ZXItbmFtZS4iCiAgICAgICAgICAg - ICsgIi0tY2VwaGZzLWZpbGVzeXN0ZW0tbmFtZSBmbGFnIGNhbiBhbHNvIGJlIHBhc3NlZCBpbiBj - YXNlIG9mIGNlcGhmcyB1c2VyIHJlc3RyaWN0aW9uLCBzbyBpdCBjYW4gcmVzdHJpY3QgdXNlciB0 - byBwYXJ0aWN1bGFyIGNlcGhmcyBmaWxlc3lzdGVtIgogICAgICAgICAgICArICJzYW1wbGUgcnVu - OiBgcHl0aG9uMyAvZXRjL2NlcGgvY3JlYXRlLWV4dGVybmFsLWNsdXN0ZXItcmVzb3VyY2VzLnB5 - IC0tY2VwaGZzLWZpbGVzeXN0ZW0tbmFtZSBteWZzIC0tcmJkLWRhdGEtcG9vbC1uYW1lIHJlcGxp - Y2Fwb29sIC0tazhzLWNsdXN0ZXItbmFtZSByb29rc3RvcmFnZSAtLXJlc3RyaWN0ZWQtYXV0aC1w - ZXJtaXNzaW9uIHRydWVgIgogICAgICAgICAgICArICJOb3RlOiBSZXN0cmljdGluZyB0aGUgY3Np - LXVzZXJzIHBlciBwb29sLCBhbmQgcGVyIGNsdXN0ZXIgd2lsbCByZXF1aXJlIGNyZWF0aW5nIG5l - dyBjc2ktdXNlcnMgYW5kIG5ldyBzZWNyZXRzIGZvciB0aGF0IGNzaS11c2Vycy4iCiAgICAgICAg - ICAgICsgIlNvIGFwcGx5IHRoZXNlIHNlY3JldHMgb25seSB0byBuZXcgYENvbnN1bWVyIGNsdXN0 - ZXJgIGRlcGxveW1lbnQgd2hpbGUgdXNpbmcgdGhlIHNhbWUgYFNvdXJjZSBjbHVzdGVyYC4iLAog - ICAgICAgICkKICAgICAgICBjb21tb25fZ3JvdXAuYWRkX2FyZ3VtZW50KAogICAgICAgICAgICAi - LS12Mi1wb3J0LWVuYWJsZSIsCiAgICAgICAgICAgIGFjdGlvbj0ic3RvcmVfdHJ1ZSIsCiAgICAg - ICAgICAgIGRlZmF1bHQ9VHJ1ZSwgICMgZGVmYXVsdCBpcyBUcnVlIHRvIGVuYWJsZSB2MiBtb24g - cG9ydCBpbiBkb3duc3RyZWFtCiAgICAgICAgICAgIGhlbHA9IkVuYWJsZSB2MiBtb24gcG9ydCgz - MzAwKSBmb3IgbW9ucyIsCiAgICAgICAgKQoKICAgICAgICBvdXRwdXRfZ3JvdXAgPSBhcmdQLmFk - ZF9hcmd1bWVudF9ncm91cCgib3V0cHV0IikKICAgICAgICBvdXRwdXRfZ3JvdXAuYWRkX2FyZ3Vt - ZW50KAogICAgICAgICAgICAiLS1mb3JtYXQiLAogICAgICAgICAgICAiLXQiLAogICAgICAgICAg - ICBjaG9pY2VzPVsianNvbiIsICJiYXNoIl0sCiAgICAgICAgICAgIGRlZmF1bHQ9Impzb24iLAog - ICAgICAgICAgICBoZWxwPSJQcm92aWRlcyB0aGUgb3V0cHV0IGZvcm1hdCAoanNvbiB8IGJhc2gp - IiwKICAgICAgICApCiAgICAgICAgb3V0cHV0X2dyb3VwLmFkZF9hcmd1bWVudCgKICAgICAgICAg - ICAgIi0tb3V0cHV0IiwKICAgICAgICAgICAgIi1vIiwKICAgICAgICAgICAgZGVmYXVsdD0iIiwK - ICAgICAgICAgICAgaGVscD0iT3V0cHV0IHdpbGwgYmUgc3RvcmVkIGludG8gdGhlIHByb3ZpZGVk - IGZpbGUiLAogICAgICAgICkKICAgICAgICBvdXRwdXRfZ3JvdXAuYWRkX2FyZ3VtZW50KAogICAg - ICAgICAgICAiLS1jZXBoZnMtZmlsZXN5c3RlbS1uYW1lIiwKICAgICAgICAgICAgZGVmYXVsdD0i - IiwKICAgICAgICAgICAgaGVscD0iUHJvdmlkZXMgdGhlIG5hbWUgb2YgdGhlIENlcGggZmlsZXN5 - c3RlbSIsCiAgICAgICAgKQogICAgICAgIG91dHB1dF9ncm91cC5hZGRfYXJndW1lbnQoCiAgICAg - ICAgICAgICItLWNlcGhmcy1tZXRhZGF0YS1wb29sLW5hbWUiLAogICAgICAgICAgICBkZWZhdWx0 - PSIiLAogICAgICAgICAgICBoZWxwPSJQcm92aWRlcyB0aGUgbmFtZSBvZiB0aGUgY2VwaGZzIG1l - dGFkYXRhIHBvb2wiLAogICAgICAgICkKICAgICAgICBvdXRwdXRfZ3JvdXAuYWRkX2FyZ3VtZW50 - KAogICAgICAgICAgICAiLS1jZXBoZnMtZGF0YS1wb29sLW5hbWUiLAogICAgICAgICAgICBkZWZh - dWx0PSIiLAogICAgICAgICAgICBoZWxwPSJQcm92aWRlcyB0aGUgbmFtZSBvZiB0aGUgY2VwaGZz - IGRhdGEgcG9vbCIsCiAgICAgICAgKQogICAgICAgIG91dHB1dF9ncm91cC5hZGRfYXJndW1lbnQo - CiAgICAgICAgICAgICItLXJiZC1kYXRhLXBvb2wtbmFtZSIsCiAgICAgICAgICAgIGRlZmF1bHQ9 - IiIsCiAgICAgICAgICAgIHJlcXVpcmVkPUZhbHNlLAogICAgICAgICAgICBoZWxwPSJQcm92aWRl - cyB0aGUgbmFtZSBvZiB0aGUgUkJEIGRhdGFwb29sIiwKICAgICAgICApCiAgICAgICAgb3V0cHV0 - X2dyb3VwLmFkZF9hcmd1bWVudCgKICAgICAgICAgICAgIi0tYWxpYXMtcmJkLWRhdGEtcG9vbC1u - YW1lIiwKICAgICAgICAgICAgZGVmYXVsdD0iIiwKICAgICAgICAgICAgcmVxdWlyZWQ9RmFsc2Us - CiAgICAgICAgICAgIGhlbHA9IlByb3ZpZGVzIGFuIGFsaWFzIGZvciB0aGUgIFJCRCBkYXRhIHBv - b2wgbmFtZSwgbmVjZXNzYXJ5IGlmIGEgc3BlY2lhbCBjaGFyYWN0ZXIgaXMgcHJlc2VudCBpbiB0 - aGUgcG9vbCBuYW1lIHN1Y2ggYXMgYSBwZXJpb2Qgb3IgdW5kZXJzY29yZSIsCiAgICAgICAgKQog - ICAgICAgIG91dHB1dF9ncm91cC5hZGRfYXJndW1lbnQoCiAgICAgICAgICAgICItLXJndy1lbmRw - b2ludCIsCiAgICAgICAgICAgIGRlZmF1bHQ9IiIsCiAgICAgICAgICAgIHJlcXVpcmVkPUZhbHNl - LAogICAgICAgICAgICBoZWxwPSJSQURPUyBHYXRld2F5IGVuZHBvaW50IChpbiBgPElQdjQ+OjxQ - T1JUPmAgb3IgYDxbSVB2Nl0+OjxQT1JUPmAgb3IgYDxGUUROPjo8UE9SVD5gIGZvcm1hdCkiLAog - ICAgICAgICkKICAgICAgICBvdXRwdXRfZ3JvdXAuYWRkX2FyZ3VtZW50KAogICAgICAgICAgICAi - LS1yZ3ctdGxzLWNlcnQtcGF0aCIsCiAgICAgICAgICAgIGRlZmF1bHQ9IiIsCiAgICAgICAgICAg - IHJlcXVpcmVkPUZhbHNlLAogICAgICAgICAgICBoZWxwPSJSQURPUyBHYXRld2F5IGVuZHBvaW50 - IFRMUyBjZXJ0aWZpY2F0ZSAob3IgaW50ZXJtZWRpYXRlIHNpZ25pbmcgY2VydGlmaWNhdGUpIiwK - ICAgICAgICApCiAgICAgICAgb3V0cHV0X2dyb3VwLmFkZF9hcmd1bWVudCgKICAgICAgICAgICAg - Ii0tcmd3LXNraXAtdGxzIiwKICAgICAgICAgICAgcmVxdWlyZWQ9RmFsc2UsCiAgICAgICAgICAg - IGRlZmF1bHQ9RmFsc2UsCiAgICAgICAgICAgIGhlbHA9Iklnbm9yZSBUTFMgY2VydGlmaWNhdGlv - biB2YWxpZGF0aW9uIHdoZW4gYSBzZWxmLXNpZ25lZCBjZXJ0aWZpY2F0ZSBpcyBwcm92aWRlZCAo - Tk9UIFJFQ09NTUVOREVEIiwKICAgICAgICApCiAgICAgICAgb3V0cHV0X2dyb3VwLmFkZF9hcmd1 - bWVudCgKICAgICAgICAgICAgIi0tbW9uaXRvcmluZy1lbmRwb2ludCIsCiAgICAgICAgICAgIGRl - ZmF1bHQ9IiIsCiAgICAgICAgICAgIHJlcXVpcmVkPUZhbHNlLAogICAgICAgICAgICBoZWxwPSJD - ZXBoIE1hbmFnZXIgcHJvbWV0aGV1cyBleHBvcnRlciBlbmRwb2ludHMgKGNvbW1hIHNlcGFyYXRl - ZCBsaXN0IG9mIChmb3JtYXQgYDxJUHY0PmAgb3IgYDxbSVB2Nl0+YCBvciBgPEZRRE4+YCkgZW50 - cmllcyBvZiBhY3RpdmUgYW5kIHN0YW5kYnkgbWdycykiLAogICAgICAgICkKICAgICAgICBvdXRw - dXRfZ3JvdXAuYWRkX2FyZ3VtZW50KAogICAgICAgICAgICAiLS1tb25pdG9yaW5nLWVuZHBvaW50 - LXBvcnQiLAogICAgICAgICAgICBkZWZhdWx0PSIiLAogICAgICAgICAgICByZXF1aXJlZD1GYWxz - ZSwKICAgICAgICAgICAgaGVscD0iQ2VwaCBNYW5hZ2VyIHByb21ldGhldXMgZXhwb3J0ZXIgcG9y - dCIsCiAgICAgICAgKQogICAgICAgIG91dHB1dF9ncm91cC5hZGRfYXJndW1lbnQoCiAgICAgICAg - ICAgICItLXNraXAtbW9uaXRvcmluZy1lbmRwb2ludCIsCiAgICAgICAgICAgIGRlZmF1bHQ9RmFs - c2UsCiAgICAgICAgICAgIGFjdGlvbj0ic3RvcmVfdHJ1ZSIsCiAgICAgICAgICAgIGhlbHA9IkRv - IG5vdCBjaGVjayBmb3IgYSBtb25pdG9yaW5nIGVuZHBvaW50IGZvciB0aGUgQ2VwaCBjbHVzdGVy - IiwKICAgICAgICApCiAgICAgICAgb3V0cHV0X2dyb3VwLmFkZF9hcmd1bWVudCgKICAgICAgICAg - ICAgIi0tcmJkLW1ldGFkYXRhLWVjLXBvb2wtbmFtZSIsCiAgICAgICAgICAgIGRlZmF1bHQ9IiIs - CiAgICAgICAgICAgIHJlcXVpcmVkPUZhbHNlLAogICAgICAgICAgICBoZWxwPSJQcm92aWRlcyB0 - aGUgbmFtZSBvZiBlcmFzdXJlIGNvZGVkIFJCRCBtZXRhZGF0YSBwb29sIiwKICAgICAgICApCiAg - ICAgICAgb3V0cHV0X2dyb3VwLmFkZF9hcmd1bWVudCgKICAgICAgICAgICAgIi0tZHJ5LXJ1biIs - CiAgICAgICAgICAgIGRlZmF1bHQ9RmFsc2UsCiAgICAgICAgICAgIGFjdGlvbj0ic3RvcmVfdHJ1 - ZSIsCiAgICAgICAgICAgIGhlbHA9IkRyeSBydW4gcHJpbnRzIHRoZSBleGVjdXRlZCBjb21tYW5k - cyB3aXRob3V0IHJ1bm5pbmcgdGhlbSIsCiAgICAgICAgKQogICAgICAgIG91dHB1dF9ncm91cC5h - ZGRfYXJndW1lbnQoCiAgICAgICAgICAgICItLXJhZG9zLW5hbWVzcGFjZSIsCiAgICAgICAgICAg - IGRlZmF1bHQ9IiIsCiAgICAgICAgICAgIHJlcXVpcmVkPUZhbHNlLAogICAgICAgICAgICBoZWxw - PSJEaXZpZGVzIGEgcG9vbCBpbnRvIHNlcGFyYXRlIGxvZ2ljYWwgbmFtZXNwYWNlcywgdXNlZCBm - b3IgY3JlYXRpbmcgUkJEIFBWQyBpbiBhIENlcGhCbG9ja1Bvb2xSYWRvc05hbWVzcGFjZSAoc2hv - dWxkIGJlIGxvd2VyIGNhc2UpIiwKICAgICAgICApCiAgICAgICAgb3V0cHV0X2dyb3VwLmFkZF9h - cmd1bWVudCgKICAgICAgICAgICAgIi0tc3Vidm9sdW1lLWdyb3VwIiwKICAgICAgICAgICAgZGVm - YXVsdD0iIiwKICAgICAgICAgICAgcmVxdWlyZWQ9RmFsc2UsCiAgICAgICAgICAgIGhlbHA9InBy - b3ZpZGVzIHRoZSBuYW1lIG9mIHRoZSBzdWJ2b2x1bWUgZ3JvdXAiLAogICAgICAgICkKICAgICAg - ICBvdXRwdXRfZ3JvdXAuYWRkX2FyZ3VtZW50KAogICAgICAgICAgICAiLS1yZ3ctcmVhbG0tbmFt - ZSIsCiAgICAgICAgICAgIGRlZmF1bHQ9IiIsCiAgICAgICAgICAgIHJlcXVpcmVkPUZhbHNlLAog - ICAgICAgICAgICBoZWxwPSJwcm92aWRlcyB0aGUgbmFtZSBvZiB0aGUgcmd3LXJlYWxtIiwKICAg - ICAgICApCiAgICAgICAgb3V0cHV0X2dyb3VwLmFkZF9hcmd1bWVudCgKICAgICAgICAgICAgIi0t - cmd3LXpvbmUtbmFtZSIsCiAgICAgICAgICAgIGRlZmF1bHQ9IiIsCiAgICAgICAgICAgIHJlcXVp - cmVkPUZhbHNlLAogICAgICAgICAgICBoZWxwPSJwcm92aWRlcyB0aGUgbmFtZSBvZiB0aGUgcmd3 - LXpvbmUiLAogICAgICAgICkKICAgICAgICBvdXRwdXRfZ3JvdXAuYWRkX2FyZ3VtZW50KAogICAg - ICAgICAgICAiLS1yZ3ctem9uZWdyb3VwLW5hbWUiLAogICAgICAgICAgICBkZWZhdWx0PSIiLAog - ICAgICAgICAgICByZXF1aXJlZD1GYWxzZSwKICAgICAgICAgICAgaGVscD0icHJvdmlkZXMgdGhl - IG5hbWUgb2YgdGhlIHJndy16b25lZ3JvdXAiLAogICAgICAgICkKICAgICAgICBvdXRwdXRfZ3Jv - dXAuYWRkX2FyZ3VtZW50KAogICAgICAgICAgICAiLS10b3BvbG9neS1wb29scyIsCiAgICAgICAg + ci1vcGVuc2hpZnQtc3RvcmFnZS1teWZzIiwia2V5IjoiQ1FCT2dyTmVBRmdjR0JBQXZHcUtPQUQw + RDN4eG1WWTBSOTEyZGc9PSIsImNhcHMiOnsibWdyIjoiYWxsb3cgcnciLCJtb24iOiJhbGxvdyBy + LCBhbGxvdyBjb21tYW5kICdvc2QgYmxvY2tsaXN0JyIsIm9zZCI6ImFsbG93IHJ3IHRhZyBjZXBo + ZnMgbWV0YWRhdGE9bXlmcyIsIm1kcyI6ImFsbG93ICoifX1dIiIiCiAgICAgICAgc2VsZi5jbWRf + b3V0cHV0X21hcFsKICAgICAgICAgICAgIiIieyJjYXBzIjogWyJtb24iLCAiYWxsb3cgciwgYWxs + b3cgY29tbWFuZCBxdW9ydW1fc3RhdHVzLCBhbGxvdyBjb21tYW5kIHZlcnNpb24iLCAibWdyIiwg + ImFsbG93IGNvbW1hbmQgY29uZmlnIiwgIm9zZCIsICJwcm9maWxlIHJiZC1yZWFkLW9ubHksIGFs + bG93IHJ3eCBwb29sPWRlZmF1bHQucmd3Lm1ldGEsIGFsbG93IHIgcG9vbD0ucmd3LnJvb3QsIGFs + bG93IHJ3IHBvb2w9ZGVmYXVsdC5yZ3cuY29udHJvbCwgYWxsb3cgcnggcG9vbD1kZWZhdWx0LnJn + dy5sb2csIGFsbG93IHggcG9vbD1kZWZhdWx0LnJndy5idWNrZXRzLmluZGV4IiwgIm1kcyIsICJh + bGxvdyAqIl0sICJlbnRpdHkiOiAiY2xpZW50LmhlYWx0aGNoZWNrZXIiLCAiZm9ybWF0IjogImpz + b24iLCAicHJlZml4IjogImF1dGggZ2V0LW9yLWNyZWF0ZSJ9IiIiCiAgICAgICAgXSA9ICIiIlt7 + ImVudGl0eSI6ImNsaWVudC5oZWFsdGhjaGVja2VyIiwia2V5IjoiQVFERmtiTmVmdDViRlJBQVRu + ZExOVVNFS3J1b3p4aVppM2xyZEE9PSIsImNhcHMiOnsibW9uIjogImFsbG93IHIsIGFsbG93IGNv + bW1hbmQgcXVvcnVtX3N0YXR1cywgYWxsb3cgY29tbWFuZCB2ZXJzaW9uIiwgIm1nciI6ICJhbGxv + dyBjb21tYW5kIGNvbmZpZyIsICJvc2QiOiAicHJvZmlsZSByYmQtcmVhZC1vbmx5LCBhbGxvdyBy + d3ggcG9vbD1kZWZhdWx0LnJndy5tZXRhLCBhbGxvdyByIHBvb2w9LnJndy5yb290LCBhbGxvdyBy + dyBwb29sPWRlZmF1bHQucmd3LmNvbnRyb2wsIGFsbG93IHJ4IHBvb2w9ZGVmYXVsdC5yZ3cubG9n + LCBhbGxvdyB4IHBvb2w9ZGVmYXVsdC5yZ3cuYnVja2V0cy5pbmRleCIsIm1kcyI6ImFsbG93ICoi + fX1dIiIiCiAgICAgICAgc2VsZi5jbWRfb3V0cHV0X21hcFsKICAgICAgICAgICAgIiIieyJjYXBz + IjogWyJtb24iLCAiYWxsb3cgciwgYWxsb3cgY29tbWFuZCBxdW9ydW1fc3RhdHVzLCBhbGxvdyBj + b21tYW5kIHZlcnNpb24iLCAibWdyIiwgImFsbG93IGNvbW1hbmQgY29uZmlnIiwgIm9zZCIsICJw + cm9maWxlIHJiZC1yZWFkLW9ubHksIGFsbG93IHJ3eCBwb29sPWRlZmF1bHQucmd3Lm1ldGEsIGFs + bG93IHIgcG9vbD0ucmd3LnJvb3QsIGFsbG93IHJ3IHBvb2w9ZGVmYXVsdC5yZ3cuY29udHJvbCwg + YWxsb3cgcnggcG9vbD1kZWZhdWx0LnJndy5sb2csIGFsbG93IHggcG9vbD1kZWZhdWx0LnJndy5i + dWNrZXRzLmluZGV4IiwgIm1kcyIsICJhbGxvdyAqIl0sICJlbnRpdHkiOiAiY2xpZW50LmhlYWx0 + aGNoZWNrZXIiLCAiZm9ybWF0IjogImpzb24iLCAicHJlZml4IjogImF1dGggY2FwcyJ9IiIiCiAg + ICAgICAgXSA9ICIiIlt7ImVudGl0eSI6ImNsaWVudC5oZWFsdGhjaGVja2VyIiwia2V5IjoiQVFE + RmtiTmVmdDViRlJBQVRuZExOVVNSS3J1b3p4aVppM2xyZEE9PSIsImNhcHMiOnsibW9uIjogImFs + bG93IHIsIGFsbG93IGNvbW1hbmQgcXVvcnVtX3N0YXR1cywgYWxsb3cgY29tbWFuZCB2ZXJzaW9u + IiwgIm1nciI6ICJhbGxvdyBjb21tYW5kIGNvbmZpZyIsICJvc2QiOiAicHJvZmlsZSByYmQtcmVh + ZC1vbmx5LCBhbGxvdyByd3ggcG9vbD1kZWZhdWx0LnJndy5tZXRhLCBhbGxvdyByIHBvb2w9LnJn + dy5yb290LCBhbGxvdyBydyBwb29sPWRlZmF1bHQucmd3LmNvbnRyb2wsIGFsbG93IHJ4IHBvb2w9 + ZGVmYXVsdC5yZ3cubG9nLCBhbGxvdyB4IHBvb2w9ZGVmYXVsdC5yZ3cuYnVja2V0cy5pbmRleCIs + Im1kcyI6ImFsbG93ICoifX1dIiIiCiAgICAgICAgc2VsZi5jbWRfb3V0cHV0X21hcFsiIiJ7ImZv + cm1hdCI6ICJqc29uIiwgInByZWZpeCI6ICJtZ3Igc2VydmljZXMifSIiIl0gPSAoCiAgICAgICAg + ICAgICIiInsiZGFzaGJvYXJkIjogImh0dHA6Ly9yb29rLWNlcGgtbWdyLWEtNTdjZjlmODRiYy1m + NGpubDo3MDAwLyIsICJwcm9tZXRoZXVzIjogImh0dHA6Ly9yb29rLWNlcGgtbWdyLWEtNTdjZjlm + ODRiYy1mNGpubDo5MjgzLyJ9IiIiCiAgICAgICAgKQogICAgICAgIHNlbGYuY21kX291dHB1dF9t + YXBbCiAgICAgICAgICAgICIiInsiZW50aXR5IjogImNsaWVudC5oZWFsdGhjaGVja2VyIiwgImZv + cm1hdCI6ICJqc29uIiwgInByZWZpeCI6ICJhdXRoIGdldCJ9IiIiCiAgICAgICAgXSA9ICIiInsi + ZGFzaGJvYXJkIjogImh0dHA6Ly9yb29rLWNlcGgtbWdyLWEtNTdjZjlmODRiYy1mNGpubDo3MDAw + LyIsICJwcm9tZXRoZXVzIjogImh0dHA6Ly9yb29rLWNlcGgtbWdyLWEtNTdjZjlmODRiYy1mNGpu + bDo5MjgzLyJ9IiIiCiAgICAgICAgc2VsZi5jbWRfb3V0cHV0X21hcFsKICAgICAgICAgICAgIiIi + eyJlbnRpdHkiOiAiY2xpZW50LmhlYWx0aGNoZWNrZXIiLCAiZm9ybWF0IjogImpzb24iLCAicHJl + Zml4IjogImF1dGggZ2V0In0iIiIKICAgICAgICBdID0gIiIiW3siZW50aXR5IjoiY2xpZW50Lmhl + YWx0aGNoZWNrZXIiLCJrZXkiOiJBUURGa2JOZWZ0NWJGUkFBVG5kTE5VU0VLcnVvenhpWmkzbHJk + QT09IiwiY2FwcyI6eyJtb24iOiAiYWxsb3cgciwgYWxsb3cgY29tbWFuZCBxdW9ydW1fc3RhdHVz + LCBhbGxvdyBjb21tYW5kIHZlcnNpb24iLCAibWdyIjogImFsbG93IGNvbW1hbmQgY29uZmlnIiwg + Im9zZCI6ICJwcm9maWxlIHJiZC1yZWFkLW9ubHksIGFsbG93IHJ3eCBwb29sPWRlZmF1bHQucmd3 + Lm1ldGEsIGFsbG93IHIgcG9vbD0ucmd3LnJvb3QsIGFsbG93IHJ3IHBvb2w9ZGVmYXVsdC5yZ3cu + Y29udHJvbCwgYWxsb3cgcnggcG9vbD1kZWZhdWx0LnJndy5sb2csIGFsbG93IHggcG9vbD1kZWZh + dWx0LnJndy5idWNrZXRzLmluZGV4IiwibWRzIjoiYWxsb3cgKiJ9fV0iIiIKICAgICAgICBzZWxm + LmNtZF9vdXRwdXRfbWFwWwogICAgICAgICAgICAiIiJ7ImVudGl0eSI6ICJjbGllbnQuY3NpLWNl + cGhmcy1ub2RlIiwgImZvcm1hdCI6ICJqc29uIiwgInByZWZpeCI6ICJhdXRoIGdldCJ9IiIiCiAg + ICAgICAgXSA9ICIiIltdIiIiCiAgICAgICAgc2VsZi5jbWRfb3V0cHV0X21hcFsKICAgICAgICAg + ICAgIiIieyJlbnRpdHkiOiAiY2xpZW50LmNzaS1yYmQtbm9kZSIsICJmb3JtYXQiOiAianNvbiIs + ICJwcmVmaXgiOiAiYXV0aCBnZXQifSIiIgogICAgICAgIF0gPSAiIiJbXSIiIgogICAgICAgIHNl + bGYuY21kX291dHB1dF9tYXBbCiAgICAgICAgICAgICIiInsiZW50aXR5IjogImNsaWVudC5jc2kt + cmJkLXByb3Zpc2lvbmVyIiwgImZvcm1hdCI6ICJqc29uIiwgInByZWZpeCI6ICJhdXRoIGdldCJ9 + IiIiCiAgICAgICAgXSA9ICIiIltdIiIiCiAgICAgICAgc2VsZi5jbWRfb3V0cHV0X21hcFsKICAg + ICAgICAgICAgIiIieyJlbnRpdHkiOiAiY2xpZW50LmNzaS1jZXBoZnMtcHJvdmlzaW9uZXIiLCAi + Zm9ybWF0IjogImpzb24iLCAicHJlZml4IjogImF1dGggZ2V0In0iIiIKICAgICAgICBdID0gIiIi + W10iIiIKICAgICAgICBzZWxmLmNtZF9vdXRwdXRfbWFwWwogICAgICAgICAgICAiIiJ7ImVudGl0 + eSI6ICJjbGllbnQuY3NpLWNlcGhmcy1wcm92aXNpb25lci1vcGVuc2hpZnQtc3RvcmFnZSIsICJm + b3JtYXQiOiAianNvbiIsICJwcmVmaXgiOiAiYXV0aCBnZXQifSIiIgogICAgICAgIF0gPSAiIiJb + XSIiIgogICAgICAgIHNlbGYuY21kX291dHB1dF9tYXBbCiAgICAgICAgICAgICIiInsiZW50aXR5 + IjogImNsaWVudC5jc2ktY2VwaGZzLXByb3Zpc2lvbmVyLW9wZW5zaGlmdC1zdG9yYWdlLW15ZnMi + LCAiZm9ybWF0IjogImpzb24iLCAicHJlZml4IjogImF1dGggZ2V0In0iIiIKICAgICAgICBdID0g + IiIiW10iIiIKICAgICAgICBzZWxmLmNtZF9vdXRwdXRfbWFwWwogICAgICAgICAgICAiIiJ7ImVu + dGl0eSI6ICJjbGllbnQuY3NpLWNlcGhmcy1wcm92aXNpb25lciIsICJmb3JtYXQiOiAianNvbiIs + ICJwcmVmaXgiOiAiYXV0aCBnZXQifSIiIgogICAgICAgIF0gPSAiIiJbeyJlbnRpdHkiOiJjbGll + bnQuY3NpLWNlcGhmcy1wcm92aXNpb25lciIsImtleSI6IkFRREZrYk5lZnQ1YkZSQUFUbmRMTlVT + RUtydW96eGlaaTNscmRBPT0iLCJjYXBzIjp7Im1vbiI6ImFsbG93IHIiLCAibWdyIjoiYWxsb3cg + cnciLCAib3NkIjoiYWxsb3cgcncgdGFnIGNlcGhmcyBtZXRhZGF0YT0qIiwibWRzIjoiYWxsb3cg + KiJ9fV0iIiIKICAgICAgICBzZWxmLmNtZF9vdXRwdXRfbWFwWwogICAgICAgICAgICAiIiJ7ImNh + cHMiOiBbIm1vbiIsICJhbGxvdyByLCBhbGxvdyBjb21tYW5kICdvc2QgYmxvY2tsaXN0JyIsICJt + Z3IiLCAiYWxsb3cgcnciLCAib3NkIiwgImFsbG93IHJ3IHRhZyBjZXBoZnMgbWV0YWRhdGE9KiIs + ICJtZHMiLCAiYWxsb3cgKiJdLCAiZW50aXR5IjogImNsaWVudC5jc2ktY2VwaGZzLXByb3Zpc2lv + bmVyIiwgImZvcm1hdCI6ICJqc29uIiwgInByZWZpeCI6ICJhdXRoIGNhcHMifSIiIgogICAgICAg + IF0gPSAiIiJbeyJlbnRpdHkiOiJjbGllbnQuY3NpLWNlcGhmcy1wcm92aXNpb25lciIsImtleSI6 + IkFRREZrYk5lZnQ1YkZSQUFUbmRMTlVTRUtydW96eGlaaTNscmRBPT0iLCJjYXBzIjp7Im1vbiI6 + ImFsbG93IHIsICBhbGxvdyBjb21tYW5kICdvc2QgYmxvY2tsaXN0JyIsICJtZ3IiOiJhbGxvdyBy + dyIsICJvc2QiOiJhbGxvdyBydyB0YWcgY2VwaGZzIG1ldGFkYXRhPSoiLCJtZHMiOiJhbGxvdyAq + In19XSIiIgogICAgICAgIHNlbGYuY21kX291dHB1dF9tYXBbJ3siZm9ybWF0IjogImpzb24iLCAi + cHJlZml4IjogInN0YXR1cyJ9J10gPSBjZXBoX3N0YXR1c19zdHIKCiAgICBkZWYgc2h1dGRvd24o + c2VsZik6CiAgICAgICAgcGFzcwoKICAgIGRlZiBnZXRfZnNpZChzZWxmKToKICAgICAgICByZXR1 + cm4gImFmNGUxNjczLTBiNzItNDAyZC05OTBhLTIyZDI5MTlkMGYxYyIKCiAgICBkZWYgY29uZl9y + ZWFkX2ZpbGUoc2VsZik6CiAgICAgICAgcGFzcwoKICAgIGRlZiBjb25uZWN0KHNlbGYpOgogICAg + ICAgIHBhc3MKCiAgICBkZWYgcG9vbF9leGlzdHMoc2VsZiwgcG9vbF9uYW1lKToKICAgICAgICBy + ZXR1cm4gVHJ1ZQoKICAgIGRlZiBtb25fY29tbWFuZChzZWxmLCBjbWQsIG91dCk6CiAgICAgICAg + anNvbl9jbWQgPSBqc29uLmxvYWRzKGNtZCkKICAgICAgICBqc29uX2NtZF9zdHIgPSBqc29uLmR1 + bXBzKGpzb25fY21kLCBzb3J0X2tleXM9VHJ1ZSkKICAgICAgICBjbWRfb3V0cHV0ID0gc2VsZi5j + bWRfb3V0cHV0X21hcFtqc29uX2NtZF9zdHJdCiAgICAgICAgcmV0dXJuIHNlbGYucmV0dXJuX3Zh + bCwgY21kX291dHB1dCwgc3RyKHNlbGYuZXJyX21lc3NhZ2UuZW5jb2RlKCJ1dGYtOCIpKQoKICAg + IGRlZiBfY29udmVydF9ob3N0bmFtZV90b19pcChzZWxmLCBob3N0X25hbWUpOgogICAgICAgIGlw + X3JlZ194ID0gcmUuY29tcGlsZShyIlxkezEsM30uXGR7MSwzfS5cZHsxLDN9LlxkezEsM30iKQog + ICAgICAgICMgaWYgcHJvdmlkZWQgaG9zdCBpcyBkaXJlY3RseSBhbiBJUCBhZGRyZXNzLCByZXR1 + cm4gdGhlIHNhbWUKICAgICAgICBpZiBpcF9yZWdfeC5tYXRjaChob3N0X25hbWUpOgogICAgICAg + ICAgICByZXR1cm4gaG9zdF9uYW1lCiAgICAgICAgaW1wb3J0IHJhbmRvbQoKICAgICAgICBob3N0 + X2lwID0gc2VsZi5kdW1teV9ob3N0X2lwX21hcC5nZXQoaG9zdF9uYW1lLCAiIikKICAgICAgICBp + ZiBub3QgaG9zdF9pcDoKICAgICAgICAgICAgaG9zdF9pcCA9IGYiMTcyLjkue3JhbmRvbS5yYW5k + aW50KDAsIDI1NCl9LntyYW5kb20ucmFuZGludCgwLCAyNTQpfSIKICAgICAgICAgICAgc2VsZi5k + dW1teV9ob3N0X2lwX21hcFtob3N0X25hbWVdID0gaG9zdF9pcAogICAgICAgIGRlbCByYW5kb20K + ICAgICAgICByZXR1cm4gaG9zdF9pcAoKICAgIEBjbGFzc21ldGhvZAogICAgZGVmIFJhZG9zKGNv + bmZmaWxlPU5vbmUpOgogICAgICAgIHJldHVybiBEdW1teVJhZG9zKCkKCgpjbGFzcyBTM0F1dGgo + QXV0aEJhc2UpOgogICAgIiIiQXR0YWNoZXMgQVdTIEF1dGhlbnRpY2F0aW9uIHRvIHRoZSBnaXZl + biBSZXF1ZXN0IG9iamVjdC4iIiIKCiAgICBzZXJ2aWNlX2Jhc2VfdXJsID0gInMzLmFtYXpvbmF3 + cy5jb20iCgogICAgZGVmIF9faW5pdF9fKHNlbGYsIGFjY2Vzc19rZXksIHNlY3JldF9rZXksIHNl + cnZpY2VfdXJsPU5vbmUpOgogICAgICAgIGlmIHNlcnZpY2VfdXJsOgogICAgICAgICAgICBzZWxm + LnNlcnZpY2VfYmFzZV91cmwgPSBzZXJ2aWNlX3VybAogICAgICAgIHNlbGYuYWNjZXNzX2tleSA9 + IHN0cihhY2Nlc3Nfa2V5KQogICAgICAgIHNlbGYuc2VjcmV0X2tleSA9IHN0cihzZWNyZXRfa2V5 + KQoKICAgIGRlZiBfX2NhbGxfXyhzZWxmLCByKToKICAgICAgICAjIENyZWF0ZSBkYXRlIGhlYWRl + ciBpZiBpdCBpcyBub3QgY3JlYXRlZCB5ZXQuCiAgICAgICAgaWYgImRhdGUiIG5vdCBpbiByLmhl + YWRlcnMgYW5kICJ4LWFtei1kYXRlIiBub3QgaW4gci5oZWFkZXJzOgogICAgICAgICAgICByLmhl + YWRlcnNbImRhdGUiXSA9IGZvcm1hdGRhdGUodGltZXZhbD1Ob25lLCBsb2NhbHRpbWU9RmFsc2Us + IHVzZWdtdD1UcnVlKQogICAgICAgIHNpZ25hdHVyZSA9IHNlbGYuZ2V0X3NpZ25hdHVyZShyKQog + ICAgICAgIHNpZ25hdHVyZSA9IHNpZ25hdHVyZS5kZWNvZGUoInV0Zi04IikKICAgICAgICByLmhl + YWRlcnNbIkF1dGhvcml6YXRpb24iXSA9IGYiQVdTIHtzZWxmLmFjY2Vzc19rZXl9OntzaWduYXR1 + cmV9IgogICAgICAgIHJldHVybiByCgogICAgZGVmIGdldF9zaWduYXR1cmUoc2VsZiwgcik6CiAg + ICAgICAgY2Fub25pY2FsX3N0cmluZyA9IHNlbGYuZ2V0X2Nhbm9uaWNhbF9zdHJpbmcoci51cmws + IHIuaGVhZGVycywgci5tZXRob2QpCiAgICAgICAga2V5ID0gc2VsZi5zZWNyZXRfa2V5LmVuY29k + ZSgidXRmLTgiKQogICAgICAgIG1zZyA9IGNhbm9uaWNhbF9zdHJpbmcuZW5jb2RlKCJ1dGYtOCIp + CiAgICAgICAgaCA9IGhtYWMubmV3KGtleSwgbXNnLCBkaWdlc3Rtb2Q9c2hhKQogICAgICAgIHJl + dHVybiBlbmNvZGVzdHJpbmcoaC5kaWdlc3QoKSkuc3RyaXAoKQoKICAgIGRlZiBnZXRfY2Fub25p + Y2FsX3N0cmluZyhzZWxmLCB1cmwsIGhlYWRlcnMsIG1ldGhvZCk6CiAgICAgICAgcGFyc2VkdXJs + ID0gdXJscGFyc2UodXJsKQogICAgICAgIG9iamVjdGtleSA9IHBhcnNlZHVybC5wYXRoWzE6XQoK + ICAgICAgICBidWNrZXQgPSBwYXJzZWR1cmwubmV0bG9jWzogLWxlbihzZWxmLnNlcnZpY2VfYmFz + ZV91cmwpXQogICAgICAgIGlmIGxlbihidWNrZXQpID4gMToKICAgICAgICAgICAgIyByZW1vdmUg + bGFzdCBkb3QKICAgICAgICAgICAgYnVja2V0ID0gYnVja2V0WzotMV0KCiAgICAgICAgaW50ZXJl + c3RpbmdfaGVhZGVycyA9IHsiY29udGVudC1tZDUiOiAiIiwgImNvbnRlbnQtdHlwZSI6ICIiLCAi + ZGF0ZSI6ICIifQogICAgICAgIGZvciBrZXkgaW4gaGVhZGVyczoKICAgICAgICAgICAgbGsgPSBr + ZXkubG93ZXIoKQogICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICBsayA9IGxrLmRlY29k + ZSgidXRmLTgiKQogICAgICAgICAgICBleGNlcHQ6CiAgICAgICAgICAgICAgICBwYXNzCiAgICAg + ICAgICAgIGlmIGhlYWRlcnNba2V5XSBhbmQgKAogICAgICAgICAgICAgICAgbGsgaW4gaW50ZXJl + c3RpbmdfaGVhZGVycy5rZXlzKCkgb3IgbGsuc3RhcnRzd2l0aCgieC1hbXotIikKICAgICAgICAg + ICAgKToKICAgICAgICAgICAgICAgIGludGVyZXN0aW5nX2hlYWRlcnNbbGtdID0gaGVhZGVyc1tr + ZXldLnN0cmlwKCkKCiAgICAgICAgIyBJZiB4LWFtei1kYXRlIGlzIHVzZWQgaXQgc3VwZXJzZWRl + cyB0aGUgZGF0ZSBoZWFkZXIuCiAgICAgICAgaWYgIngtYW16LWRhdGUiIGluIGludGVyZXN0aW5n + X2hlYWRlcnM6CiAgICAgICAgICAgIGludGVyZXN0aW5nX2hlYWRlcnNbImRhdGUiXSA9ICIiCgog + ICAgICAgIGJ1ZiA9IGYie21ldGhvZH1cbiIKICAgICAgICBmb3Iga2V5IGluIHNvcnRlZChpbnRl + cmVzdGluZ19oZWFkZXJzLmtleXMoKSk6CiAgICAgICAgICAgIHZhbCA9IGludGVyZXN0aW5nX2hl + YWRlcnNba2V5XQogICAgICAgICAgICBpZiBrZXkuc3RhcnRzd2l0aCgieC1hbXotIik6CiAgICAg + ICAgICAgICAgICBidWYgKz0gZiJ7a2V5fTp7dmFsfVxuIgogICAgICAgICAgICBlbHNlOgogICAg + ICAgICAgICAgICAgYnVmICs9IGYie3ZhbH1cbiIKCiAgICAgICAgIyBhcHBlbmQgdGhlIGJ1Y2tl + dCBpZiBpdCBleGlzdHMKICAgICAgICBpZiBidWNrZXQgIT0gIiI6CiAgICAgICAgICAgIGJ1ZiAr + PSBmIi97YnVja2V0fSIKCiAgICAgICAgIyBhZGQgdGhlIG9iamVjdGtleS4gZXZlbiBpZiBpdCBk + b2Vzbid0IGV4aXN0LCBhZGQgdGhlIHNsYXNoCiAgICAgICAgYnVmICs9IGYiL3tvYmplY3RrZXl9 + IgoKICAgICAgICByZXR1cm4gYnVmCgoKY2xhc3MgUmFkb3NKU09OOgogICAgRVhURVJOQUxfVVNF + Ul9OQU1FID0gImNsaWVudC5oZWFsdGhjaGVja2VyIgogICAgRVhURVJOQUxfUkdXX0FETUlOX09Q + U19VU0VSX05BTUUgPSAicmd3LWFkbWluLW9wcy11c2VyIgogICAgRU1QVFlfT1VUUFVUX0xJU1Qg + PSAiRW1wdHkgb3V0cHV0IGxpc3QiCiAgICBERUZBVUxUX1JHV19QT09MX1BSRUZJWCA9ICJkZWZh + dWx0IgogICAgREVGQVVMVF9NT05JVE9SSU5HX0VORFBPSU5UX1BPUlQgPSAiOTI4MyIKCiAgICBA + Y2xhc3NtZXRob2QKICAgIGRlZiBnZW5fYXJnX3BhcnNlcihjbHMsIGFyZ3NfdG9fcGFyc2U9Tm9u + ZSk6CiAgICAgICAgYXJnUCA9IGFyZ3BhcnNlLkFyZ3VtZW50UGFyc2VyKCkKCiAgICAgICAgY29t + bW9uX2dyb3VwID0gYXJnUC5hZGRfYXJndW1lbnRfZ3JvdXAoImNvbW1vbiIpCiAgICAgICAgY29t + bW9uX2dyb3VwLmFkZF9hcmd1bWVudCgiLS12ZXJib3NlIiwgIi12IiwgYWN0aW9uPSJzdG9yZV90 + cnVlIiwgZGVmYXVsdD1GYWxzZSkKICAgICAgICBjb21tb25fZ3JvdXAuYWRkX2FyZ3VtZW50KAog + ICAgICAgICAgICAiLS1jZXBoLWNvbmYiLCAiLWMiLCBoZWxwPSJQcm92aWRlIGEgY2VwaCBjb25m + IGZpbGUuIiwgdHlwZT1zdHIsIGRlZmF1bHQ9IiIKICAgICAgICApCiAgICAgICAgY29tbW9uX2dy + b3VwLmFkZF9hcmd1bWVudCgKICAgICAgICAgICAgIi0ta2V5cmluZyIsICItayIsIGhlbHA9IlBh + dGggdG8gY2VwaCBrZXlyaW5nIGZpbGUuIiwgdHlwZT1zdHIsIGRlZmF1bHQ9IiIKICAgICAgICAp + CiAgICAgICAgY29tbW9uX2dyb3VwLmFkZF9hcmd1bWVudCgKICAgICAgICAgICAgIi0tcnVuLWFz + LXVzZXIiLAogICAgICAgICAgICAiLXUiLAogICAgICAgICAgICBkZWZhdWx0PSIiLAogICAgICAg + ICAgICB0eXBlPXN0ciwKICAgICAgICAgICAgaGVscD0iUHJvdmlkZXMgYSB1c2VyIG5hbWUgdG8g + Y2hlY2sgdGhlIGNsdXN0ZXIncyBoZWFsdGggc3RhdHVzLCBtdXN0IGJlIHByZWZpeGVkIGJ5ICdj + bGllbnQuJyIsCiAgICAgICAgKQogICAgICAgIGNvbW1vbl9ncm91cC5hZGRfYXJndW1lbnQoCiAg + ICAgICAgICAgICItLWNsdXN0ZXItbmFtZSIsCiAgICAgICAgICAgIGRlZmF1bHQ9IiIsCiAgICAg + ICAgICAgIGhlbHA9Ikt1YmVybmV0ZXMgY2x1c3RlciBuYW1lKGxlZ2FjeSBmbGFnKSwgTm90ZTog + RWl0aGVyIHVzZSB0aGlzIG9yIC0tazhzLWNsdXN0ZXItbmFtZSIsCiAgICAgICAgKQogICAgICAg + IGNvbW1vbl9ncm91cC5hZGRfYXJndW1lbnQoCiAgICAgICAgICAgICItLWs4cy1jbHVzdGVyLW5h + bWUiLCBkZWZhdWx0PSIiLCBoZWxwPSJLdWJlcm5ldGVzIGNsdXN0ZXIgbmFtZSIKICAgICAgICAp + CiAgICAgICAgY29tbW9uX2dyb3VwLmFkZF9hcmd1bWVudCgKICAgICAgICAgICAgIi0tbmFtZXNw + YWNlIiwKICAgICAgICAgICAgZGVmYXVsdD0iIiwKICAgICAgICAgICAgaGVscD0iTmFtZXNwYWNl + IHdoZXJlIENlcGhDbHVzdGVyIGlzIHJ1bm5pbmciLAogICAgICAgICkKICAgICAgICBjb21tb25f + Z3JvdXAuYWRkX2FyZ3VtZW50KAogICAgICAgICAgICAiLS1yZ3ctcG9vbC1wcmVmaXgiLCBkZWZh + dWx0PSIiLCBoZWxwPSJSR1cgUG9vbCBwcmVmaXgiCiAgICAgICAgKQogICAgICAgIGNvbW1vbl9n + cm91cC5hZGRfYXJndW1lbnQoCiAgICAgICAgICAgICItLXJlc3RyaWN0ZWQtYXV0aC1wZXJtaXNz + aW9uIiwKICAgICAgICAgICAgZGVmYXVsdD1GYWxzZSwKICAgICAgICAgICAgaGVscD0iUmVzdHJp + Y3QgY2VwaENTSUtleXJpbmdzIGF1dGggcGVybWlzc2lvbnMgdG8gc3BlY2lmaWMgcG9vbHMsIGNs + dXN0ZXIuIgogICAgICAgICAgICArICJNYW5kYXRvcnkgZmxhZ3MgdGhhdCBuZWVkIHRvIGJlIHNl + dCBhcmUgLS1yYmQtZGF0YS1wb29sLW5hbWUsIGFuZCAtLWs4cy1jbHVzdGVyLW5hbWUuIgogICAg + ICAgICAgICArICItLWNlcGhmcy1maWxlc3lzdGVtLW5hbWUgZmxhZyBjYW4gYWxzbyBiZSBwYXNz + ZWQgaW4gY2FzZSBvZiBjZXBoZnMgdXNlciByZXN0cmljdGlvbiwgc28gaXQgY2FuIHJlc3RyaWN0 + IHVzZXIgdG8gcGFydGljdWxhciBjZXBoZnMgZmlsZXN5c3RlbSIKICAgICAgICAgICAgKyAic2Ft + cGxlIHJ1bjogYHB5dGhvbjMgL2V0Yy9jZXBoL2NyZWF0ZS1leHRlcm5hbC1jbHVzdGVyLXJlc291 + cmNlcy5weSAtLWNlcGhmcy1maWxlc3lzdGVtLW5hbWUgbXlmcyAtLXJiZC1kYXRhLXBvb2wtbmFt + ZSByZXBsaWNhcG9vbCAtLWs4cy1jbHVzdGVyLW5hbWUgcm9va3N0b3JhZ2UgLS1yZXN0cmljdGVk + LWF1dGgtcGVybWlzc2lvbiB0cnVlYCIKICAgICAgICAgICAgKyAiTm90ZTogUmVzdHJpY3Rpbmcg + dGhlIGNzaS11c2VycyBwZXIgcG9vbCwgYW5kIHBlciBjbHVzdGVyIHdpbGwgcmVxdWlyZSBjcmVh + dGluZyBuZXcgY3NpLXVzZXJzIGFuZCBuZXcgc2VjcmV0cyBmb3IgdGhhdCBjc2ktdXNlcnMuIgog + ICAgICAgICAgICArICJTbyBhcHBseSB0aGVzZSBzZWNyZXRzIG9ubHkgdG8gbmV3IGBDb25zdW1l + ciBjbHVzdGVyYCBkZXBsb3ltZW50IHdoaWxlIHVzaW5nIHRoZSBzYW1lIGBTb3VyY2UgY2x1c3Rl + cmAuIiwKICAgICAgICApCiAgICAgICAgY29tbW9uX2dyb3VwLmFkZF9hcmd1bWVudCgKICAgICAg + ICAgICAgIi0tdjItcG9ydC1lbmFibGUiLAogICAgICAgICAgICBhY3Rpb249InN0b3JlX3RydWUi + LAogICAgICAgICAgICBkZWZhdWx0PVRydWUsICAjIGRlZmF1bHQgaXMgVHJ1ZSB0byBlbmFibGUg + djIgbW9uIHBvcnQgaW4gZG93bnN0cmVhbQogICAgICAgICAgICBoZWxwPSJFbmFibGUgdjIgbW9u + IHBvcnQoMzMwMCkgZm9yIG1vbnMiLAogICAgICAgICkKCiAgICAgICAgb3V0cHV0X2dyb3VwID0g + YXJnUC5hZGRfYXJndW1lbnRfZ3JvdXAoIm91dHB1dCIpCiAgICAgICAgb3V0cHV0X2dyb3VwLmFk + ZF9hcmd1bWVudCgKICAgICAgICAgICAgIi0tZm9ybWF0IiwKICAgICAgICAgICAgIi10IiwKICAg + ICAgICAgICAgY2hvaWNlcz1bImpzb24iLCAiYmFzaCJdLAogICAgICAgICAgICBkZWZhdWx0PSJq + c29uIiwKICAgICAgICAgICAgaGVscD0iUHJvdmlkZXMgdGhlIG91dHB1dCBmb3JtYXQgKGpzb24g + fCBiYXNoKSIsCiAgICAgICAgKQogICAgICAgIG91dHB1dF9ncm91cC5hZGRfYXJndW1lbnQoCiAg + ICAgICAgICAgICItLW91dHB1dCIsCiAgICAgICAgICAgICItbyIsCiAgICAgICAgICAgIGRlZmF1 + bHQ9IiIsCiAgICAgICAgICAgIGhlbHA9Ik91dHB1dCB3aWxsIGJlIHN0b3JlZCBpbnRvIHRoZSBw + cm92aWRlZCBmaWxlIiwKICAgICAgICApCiAgICAgICAgb3V0cHV0X2dyb3VwLmFkZF9hcmd1bWVu + dCgKICAgICAgICAgICAgIi0tY2VwaGZzLWZpbGVzeXN0ZW0tbmFtZSIsCiAgICAgICAgICAgIGRl + ZmF1bHQ9IiIsCiAgICAgICAgICAgIGhlbHA9IlByb3ZpZGVzIHRoZSBuYW1lIG9mIHRoZSBDZXBo + IGZpbGVzeXN0ZW0iLAogICAgICAgICkKICAgICAgICBvdXRwdXRfZ3JvdXAuYWRkX2FyZ3VtZW50 + KAogICAgICAgICAgICAiLS1jZXBoZnMtbWV0YWRhdGEtcG9vbC1uYW1lIiwKICAgICAgICAgICAg + ZGVmYXVsdD0iIiwKICAgICAgICAgICAgaGVscD0iUHJvdmlkZXMgdGhlIG5hbWUgb2YgdGhlIGNl + cGhmcyBtZXRhZGF0YSBwb29sIiwKICAgICAgICApCiAgICAgICAgb3V0cHV0X2dyb3VwLmFkZF9h + cmd1bWVudCgKICAgICAgICAgICAgIi0tY2VwaGZzLWRhdGEtcG9vbC1uYW1lIiwKICAgICAgICAg + ICAgZGVmYXVsdD0iIiwKICAgICAgICAgICAgaGVscD0iUHJvdmlkZXMgdGhlIG5hbWUgb2YgdGhl + IGNlcGhmcyBkYXRhIHBvb2wiLAogICAgICAgICkKICAgICAgICBvdXRwdXRfZ3JvdXAuYWRkX2Fy + Z3VtZW50KAogICAgICAgICAgICAiLS1yYmQtZGF0YS1wb29sLW5hbWUiLAogICAgICAgICAgICBk + ZWZhdWx0PSIiLAogICAgICAgICAgICByZXF1aXJlZD1GYWxzZSwKICAgICAgICAgICAgaGVscD0i + UHJvdmlkZXMgdGhlIG5hbWUgb2YgdGhlIFJCRCBkYXRhcG9vbCIsCiAgICAgICAgKQogICAgICAg + IG91dHB1dF9ncm91cC5hZGRfYXJndW1lbnQoCiAgICAgICAgICAgICItLWFsaWFzLXJiZC1kYXRh + LXBvb2wtbmFtZSIsCiAgICAgICAgICAgIGRlZmF1bHQ9IiIsCiAgICAgICAgICAgIHJlcXVpcmVk + PUZhbHNlLAogICAgICAgICAgICBoZWxwPSJQcm92aWRlcyBhbiBhbGlhcyBmb3IgdGhlICBSQkQg + ZGF0YSBwb29sIG5hbWUsIG5lY2Vzc2FyeSBpZiBhIHNwZWNpYWwgY2hhcmFjdGVyIGlzIHByZXNl + bnQgaW4gdGhlIHBvb2wgbmFtZSBzdWNoIGFzIGEgcGVyaW9kIG9yIHVuZGVyc2NvcmUiLAogICAg + ICAgICkKICAgICAgICBvdXRwdXRfZ3JvdXAuYWRkX2FyZ3VtZW50KAogICAgICAgICAgICAiLS1y + Z3ctZW5kcG9pbnQiLAogICAgICAgICAgICBkZWZhdWx0PSIiLAogICAgICAgICAgICByZXF1aXJl + ZD1GYWxzZSwKICAgICAgICAgICAgaGVscD0iUkFET1MgR2F0ZXdheSBlbmRwb2ludCAoaW4gYDxJ + UHY0Pjo8UE9SVD5gIG9yIGA8W0lQdjZdPjo8UE9SVD5gIG9yIGA8RlFETj46PFBPUlQ+YCBmb3Jt + YXQpIiwKICAgICAgICApCiAgICAgICAgb3V0cHV0X2dyb3VwLmFkZF9hcmd1bWVudCgKICAgICAg + ICAgICAgIi0tcmd3LXRscy1jZXJ0LXBhdGgiLAogICAgICAgICAgICBkZWZhdWx0PSIiLAogICAg + ICAgICAgICByZXF1aXJlZD1GYWxzZSwKICAgICAgICAgICAgaGVscD0iUkFET1MgR2F0ZXdheSBl + bmRwb2ludCBUTFMgY2VydGlmaWNhdGUgKG9yIGludGVybWVkaWF0ZSBzaWduaW5nIGNlcnRpZmlj + YXRlKSIsCiAgICAgICAgKQogICAgICAgIG91dHB1dF9ncm91cC5hZGRfYXJndW1lbnQoCiAgICAg + ICAgICAgICItLXJndy1za2lwLXRscyIsCiAgICAgICAgICAgIHJlcXVpcmVkPUZhbHNlLAogICAg + ICAgICAgICBkZWZhdWx0PUZhbHNlLAogICAgICAgICAgICBoZWxwPSJJZ25vcmUgVExTIGNlcnRp + ZmljYXRpb24gdmFsaWRhdGlvbiB3aGVuIGEgc2VsZi1zaWduZWQgY2VydGlmaWNhdGUgaXMgcHJv + dmlkZWQgKE5PVCBSRUNPTU1FTkRFRCIsCiAgICAgICAgKQogICAgICAgIG91dHB1dF9ncm91cC5h + ZGRfYXJndW1lbnQoCiAgICAgICAgICAgICItLW1vbml0b3JpbmctZW5kcG9pbnQiLAogICAgICAg + ICAgICBkZWZhdWx0PSIiLAogICAgICAgICAgICByZXF1aXJlZD1GYWxzZSwKICAgICAgICAgICAg + aGVscD0iQ2VwaCBNYW5hZ2VyIHByb21ldGhldXMgZXhwb3J0ZXIgZW5kcG9pbnRzIChjb21tYSBz + ZXBhcmF0ZWQgbGlzdCBvZiAoZm9ybWF0IGA8SVB2ND5gIG9yIGA8W0lQdjZdPmAgb3IgYDxGUURO + PmApIGVudHJpZXMgb2YgYWN0aXZlIGFuZCBzdGFuZGJ5IG1ncnMpIiwKICAgICAgICApCiAgICAg + ICAgb3V0cHV0X2dyb3VwLmFkZF9hcmd1bWVudCgKICAgICAgICAgICAgIi0tbW9uaXRvcmluZy1l + bmRwb2ludC1wb3J0IiwKICAgICAgICAgICAgZGVmYXVsdD0iIiwKICAgICAgICAgICAgcmVxdWly + ZWQ9RmFsc2UsCiAgICAgICAgICAgIGhlbHA9IkNlcGggTWFuYWdlciBwcm9tZXRoZXVzIGV4cG9y + dGVyIHBvcnQiLAogICAgICAgICkKICAgICAgICBvdXRwdXRfZ3JvdXAuYWRkX2FyZ3VtZW50KAog + ICAgICAgICAgICAiLS1za2lwLW1vbml0b3JpbmctZW5kcG9pbnQiLAogICAgICAgICAgICBkZWZh + dWx0PUZhbHNlLAogICAgICAgICAgICBhY3Rpb249InN0b3JlX3RydWUiLAogICAgICAgICAgICBo + ZWxwPSJEbyBub3QgY2hlY2sgZm9yIGEgbW9uaXRvcmluZyBlbmRwb2ludCBmb3IgdGhlIENlcGgg + Y2x1c3RlciIsCiAgICAgICAgKQogICAgICAgIG91dHB1dF9ncm91cC5hZGRfYXJndW1lbnQoCiAg + ICAgICAgICAgICItLXJiZC1tZXRhZGF0YS1lYy1wb29sLW5hbWUiLAogICAgICAgICAgICBkZWZh + dWx0PSIiLAogICAgICAgICAgICByZXF1aXJlZD1GYWxzZSwKICAgICAgICAgICAgaGVscD0iUHJv + dmlkZXMgdGhlIG5hbWUgb2YgZXJhc3VyZSBjb2RlZCBSQkQgbWV0YWRhdGEgcG9vbCIsCiAgICAg + ICAgKQogICAgICAgIG91dHB1dF9ncm91cC5hZGRfYXJndW1lbnQoCiAgICAgICAgICAgICItLWRy + eS1ydW4iLAogICAgICAgICAgICBkZWZhdWx0PUZhbHNlLAogICAgICAgICAgICBhY3Rpb249InN0 + b3JlX3RydWUiLAogICAgICAgICAgICBoZWxwPSJEcnkgcnVuIHByaW50cyB0aGUgZXhlY3V0ZWQg + Y29tbWFuZHMgd2l0aG91dCBydW5uaW5nIHRoZW0iLAogICAgICAgICkKICAgICAgICBvdXRwdXRf + Z3JvdXAuYWRkX2FyZ3VtZW50KAogICAgICAgICAgICAiLS1yYWRvcy1uYW1lc3BhY2UiLAogICAg + ICAgICAgICBkZWZhdWx0PSIiLAogICAgICAgICAgICByZXF1aXJlZD1GYWxzZSwKICAgICAgICAg + ICAgaGVscD0iRGl2aWRlcyBhIHBvb2wgaW50byBzZXBhcmF0ZSBsb2dpY2FsIG5hbWVzcGFjZXMs + IHVzZWQgZm9yIGNyZWF0aW5nIFJCRCBQVkMgaW4gYSBDZXBoQmxvY2tQb29sUmFkb3NOYW1lc3Bh + Y2UgKHNob3VsZCBiZSBsb3dlciBjYXNlKSIsCiAgICAgICAgKQogICAgICAgIG91dHB1dF9ncm91 + cC5hZGRfYXJndW1lbnQoCiAgICAgICAgICAgICItLXN1YnZvbHVtZS1ncm91cCIsCiAgICAgICAg ICAgIGRlZmF1bHQ9IiIsCiAgICAgICAgICAgIHJlcXVpcmVkPUZhbHNlLAogICAgICAgICAgICBo - ZWxwPSJjb21tYS1zZXBhcmF0ZWQgbGlzdCBvZiB0b3BvbG9neS1jb25zdHJhaW5lZCByYmQgcG9v - bHMiLAogICAgICAgICkKICAgICAgICBvdXRwdXRfZ3JvdXAuYWRkX2FyZ3VtZW50KAogICAgICAg - ICAgICAiLS10b3BvbG9neS1mYWlsdXJlLWRvbWFpbi1sYWJlbCIsCiAgICAgICAgICAgIGRlZmF1 - bHQ9IiIsCiAgICAgICAgICAgIHJlcXVpcmVkPUZhbHNlLAogICAgICAgICAgICBoZWxwPSJrOHMg - Y2x1c3RlciBmYWlsdXJlIGRvbWFpbiBsYWJlbCAoZXhhbXBsZTogem9uZSwgcmFjaywgb3IgaG9z - dCkgZm9yIHRoZSB0b3BvbG9neS1wb29scyB0aGF0IG1hdGNoIHRoZSBjZXBoIGRvbWFpbiIsCiAg - ICAgICAgKQogICAgICAgIG91dHB1dF9ncm91cC5hZGRfYXJndW1lbnQoCiAgICAgICAgICAgICIt - LXRvcG9sb2d5LWZhaWx1cmUtZG9tYWluLXZhbHVlcyIsCiAgICAgICAgICAgIGRlZmF1bHQ9IiIs - CiAgICAgICAgICAgIHJlcXVpcmVkPUZhbHNlLAogICAgICAgICAgICBoZWxwPSJjb21tYS1zZXBh - cmF0ZWQgbGlzdCBvZiB0aGUgazhzIGNsdXN0ZXIgZmFpbHVyZSBkb21haW4gdmFsdWVzIGNvcnJl - c3BvbmRpbmcgdG8gZWFjaCBvZiB0aGUgcG9vbHMgaW4gdGhlIGB0b3BvbG9neS1wb29sc2AgbGlz - dCIsCiAgICAgICAgKQoKICAgICAgICB1cGdyYWRlX2dyb3VwID0gYXJnUC5hZGRfYXJndW1lbnRf - Z3JvdXAoInVwZ3JhZGUiKQogICAgICAgIHVwZ3JhZGVfZ3JvdXAuYWRkX2FyZ3VtZW50KAogICAg - ICAgICAgICAiLS11cGdyYWRlIiwKICAgICAgICAgICAgYWN0aW9uPSJzdG9yZV90cnVlIiwKICAg - ICAgICAgICAgZGVmYXVsdD1GYWxzZSwKICAgICAgICAgICAgaGVscD0iVXBncmFkZXMgdGhlIGNl - cGhDU0lLZXlyaW5ncyhGb3IgZXhhbXBsZTogY2xpZW50LmNzaS1jZXBoZnMtcHJvdmlzaW9uZXIp - IGFuZCBjbGllbnQuaGVhbHRoY2hlY2tlciBjZXBoIHVzZXJzIHdpdGggbmV3IHBlcm1pc3Npb25z - IG5lZWRlZCBmb3IgdGhlIG5ldyBjbHVzdGVyIHZlcnNpb24gYW5kIG9sZGVyIHBlcm1pc3Npb24g - d2lsbCBzdGlsbCBiZSBhcHBsaWVkLiIKICAgICAgICAgICAgKyAiU2FtcGxlIHJ1bjogYHB5dGhv - bjMgL2V0Yy9jZXBoL2NyZWF0ZS1leHRlcm5hbC1jbHVzdGVyLXJlc291cmNlcy5weSAtLXVwZ3Jh - ZGVgLCB0aGlzIHdpbGwgdXBncmFkZSBhbGwgdGhlIGRlZmF1bHQgY3NpIHVzZXJzKG5vbi1yZXN0 - cmljdGVkKSIKICAgICAgICAgICAgKyAiRm9yIHJlc3RyaWN0ZWQgdXNlcnMoRm9yIGV4YW1wbGU6 - IGNsaWVudC5jc2ktY2VwaGZzLXByb3Zpc2lvbmVyLW9wZW5zaGlmdC1zdG9yYWdlLW15ZnMpLCB1 - c2VycyBjcmVhdGVkIHVzaW5nIC0tcmVzdHJpY3RlZC1hdXRoLXBlcm1pc3Npb24gZmxhZyBuZWVk - IHRvIHBhc3MgbWFuZGF0b3J5IGZsYWdzIgogICAgICAgICAgICArICJtYW5kYXRvcnkgZmxhZ3M6 - ICctLXJiZC1kYXRhLXBvb2wtbmFtZSwgLS1rOHMtY2x1c3Rlci1uYW1lIGFuZCAtLXJ1bi1hcy11 - c2VyJyBmbGFncyB3aGlsZSB1cGdyYWRpbmciCiAgICAgICAgICAgICsgImluIGNhc2Ugb2YgY2Vw - aGZzIHVzZXJzIGlmIHlvdSBoYXZlIHBhc3NlZCAtLWNlcGhmcy1maWxlc3lzdGVtLW5hbWUgZmxh - ZyB3aGlsZSBjcmVhdGluZyB1c2VyIHRoZW4gd2hpbGUgdXBncmFkaW5nIGl0IHdpbGwgYmUgbWFu - ZGF0b3J5IHRvbyIKICAgICAgICAgICAgKyAiU2FtcGxlIHJ1bjogYHB5dGhvbjMgL2V0Yy9jZXBo - L2NyZWF0ZS1leHRlcm5hbC1jbHVzdGVyLXJlc291cmNlcy5weSAtLXVwZ3JhZGUgLS1yYmQtZGF0 - YS1wb29sLW5hbWUgcmVwbGljYXBvb2wgLS1rOHMtY2x1c3Rlci1uYW1lIHJvb2tzdG9yYWdlICAt - LXJ1bi1hcy11c2VyIGNsaWVudC5jc2ktcmJkLW5vZGUtcm9va3N0b3JhZ2UtcmVwbGljYXBvb2xg - IgogICAgICAgICAgICArICJQUzogQW4gZXhpc3Rpbmcgbm9uLXJlc3RyaWN0ZWQgdXNlciBjYW5u - b3QgYmUgY29udmVydGVkIHRvIGEgcmVzdHJpY3RlZCB1c2VyIGJ5IHVwZ3JhZGluZy4iCiAgICAg - ICAgICAgICsgIlVwZ3JhZGUgZmxhZyBzaG91bGQgb25seSBiZSB1c2VkIHRvIGFwcGVuZCBuZXcg - cGVybWlzc2lvbnMgdG8gdXNlcnMsIGl0IHNob3VsZG4ndCBiZSB1c2VkIGZvciBjaGFuZ2luZyB1 - c2VyIGFscmVhZHkgYXBwbGllZCBwZXJtaXNzaW9uLCBmb3IgZXhhbXBsZSB5b3Ugc2hvdWxkbid0 - IGNoYW5nZSBpbiB3aGljaCBwb29sIHVzZXIgaGFzIGFjY2VzcyIsCiAgICAgICAgKQoKICAgICAg - ICAjIEFkZCBjb21tYW5kLWxpbmUgYXJndW1lbnRzCiAgICAgICAgY29uZmlnX2dyb3VwID0gYXJn - UC5hZGRfYXJndW1lbnRfZ3JvdXAoImNvbmZpZyIpCiAgICAgICAgY29uZmlnX2dyb3VwLmFkZF9h - cmd1bWVudCgKICAgICAgICAgICAgIi0tY29uZmlnLWZpbGUiLAogICAgICAgICAgICB0eXBlPXN0 - ciwKICAgICAgICAgICAgaGVscD0iUGF0aCB0byB0aGUgY29uZmlndXJhdGlvbiBmaWxlLCBQcmlv - cml0eTogY29tbWFuZC1saW5lLWFyZ3MgPiBjb25maWcuaW5pIGZpbGUgdmFsdWVzID4gZGVmYXVs - dCB2YWx1ZXMiLAogICAgICAgICAgICByZXF1aXJlZD1GYWxzZSwKICAgICAgICAgICAgZGVmYXVs - dD0iIiwKICAgICAgICApCgogICAgICAgIGlmIGFyZ3NfdG9fcGFyc2U6CiAgICAgICAgICAgIGFz - c2VydCAoCiAgICAgICAgICAgICAgICB0eXBlKGFyZ3NfdG9fcGFyc2UpID09IGxpc3QKICAgICAg - ICAgICAgKSwgIkFyZ3VtZW50IHRvICdnZW5fYXJnX3BhcnNlcicgc2hvdWxkIGJlIGEgbGlzdCIK - ICAgICAgICBlbHNlOgogICAgICAgICAgICBhcmdzX3RvX3BhcnNlID0gc3lzLmFyZ3ZbMTpdCiAg - ICAgICAgcmV0dXJuIGFyZ1AucGFyc2VfYXJncyhhcmdzX3RvX3BhcnNlKQoKICAgIGRlZiB2YWxp - ZGF0ZV9yYmRfbWV0YWRhdGFfZWNfcG9vbF9uYW1lKHNlbGYpOgogICAgICAgIGlmIHNlbGYuX2Fy - Z19wYXJzZXIucmJkX21ldGFkYXRhX2VjX3Bvb2xfbmFtZToKICAgICAgICAgICAgcmJkX21ldGFk - YXRhX2VjX3Bvb2xfbmFtZSA9IHNlbGYuX2FyZ19wYXJzZXIucmJkX21ldGFkYXRhX2VjX3Bvb2xf - bmFtZQogICAgICAgICAgICByYmRfcG9vbF9uYW1lID0gc2VsZi5fYXJnX3BhcnNlci5yYmRfZGF0 - YV9wb29sX25hbWUKCiAgICAgICAgICAgIGlmIHJiZF9wb29sX25hbWUgPT0gIiI6CiAgICAgICAg - ICAgICAgICByYWlzZSBFeGVjdXRpb25GYWlsdXJlRXhjZXB0aW9uKAogICAgICAgICAgICAgICAg - ICAgICJGbGFnICctLXJiZC1kYXRhLXBvb2wtbmFtZScgc2hvdWxkIG5vdCBiZSBlbXB0eSIKICAg - ICAgICAgICAgICAgICkKCiAgICAgICAgICAgIGlmIHJiZF9tZXRhZGF0YV9lY19wb29sX25hbWUg - PT0gIiI6CiAgICAgICAgICAgICAgICByYWlzZSBFeGVjdXRpb25GYWlsdXJlRXhjZXB0aW9uKAog - ICAgICAgICAgICAgICAgICAgICJGbGFnICctLXJiZC1tZXRhZGF0YS1lYy1wb29sLW5hbWUnIHNo - b3VsZCBub3QgYmUgZW1wdHkiCiAgICAgICAgICAgICAgICApCgogICAgICAgICAgICBjbWRfanNv - biA9IHsicHJlZml4IjogIm9zZCBkdW1wIiwgImZvcm1hdCI6ICJqc29uIn0KICAgICAgICAgICAg - cmV0X3ZhbCwganNvbl9vdXQsIGVycl9tc2cgPSBzZWxmLl9jb21tb25fY21kX2pzb25fZ2VuKGNt - ZF9qc29uKQogICAgICAgICAgICBpZiByZXRfdmFsICE9IDAgb3IgbGVuKGpzb25fb3V0KSA9PSAw - OgogICAgICAgICAgICAgICAgcmFpc2UgRXhlY3V0aW9uRmFpbHVyZUV4Y2VwdGlvbigKICAgICAg - ICAgICAgICAgICAgICBmIntjbWRfanNvblsncHJlZml4J119IGNvbW1hbmQgZmFpbGVkLlxuIgog - ICAgICAgICAgICAgICAgICAgIGYiRXJyb3I6IHtlcnJfbXNnIGlmIHJldF92YWwgIT0gMCBlbHNl - IHNlbGYuRU1QVFlfT1VUUFVUX0xJU1R9IgogICAgICAgICAgICAgICAgKQogICAgICAgICAgICBt - ZXRhZGF0YV9wb29sX2V4aXN0LCBwb29sX2V4aXN0ID0gRmFsc2UsIEZhbHNlCgogICAgICAgICAg - ICBmb3Iga2V5IGluIGpzb25fb3V0WyJwb29scyJdOgogICAgICAgICAgICAgICAgIyBpZiBlcmFz - dXJlX2NvZGVfcHJvZmlsZSBpcyBlbXB0eSBhbmQgcG9vbCBuYW1lIGV4aXN0cyB0aGVuIGl0IHJl - cGxpY2EgcG9vbAogICAgICAgICAgICAgICAgaWYgKAogICAgICAgICAgICAgICAgICAgIGtleVsi - ZXJhc3VyZV9jb2RlX3Byb2ZpbGUiXSA9PSAiIgogICAgICAgICAgICAgICAgICAgIGFuZCBrZXlb - InBvb2xfbmFtZSJdID09IHJiZF9tZXRhZGF0YV9lY19wb29sX25hbWUKICAgICAgICAgICAgICAg - ICk6CiAgICAgICAgICAgICAgICAgICAgbWV0YWRhdGFfcG9vbF9leGlzdCA9IFRydWUKICAgICAg - ICAgICAgICAgICMgaWYgZXJhc3VyZV9jb2RlX3Byb2ZpbGUgaXMgbm90IGVtcHR5IGFuZCBwb29s - IG5hbWUgZXhpc3RzIHRoZW4gaXQgaXMgZWMgcG9vbAogICAgICAgICAgICAgICAgaWYga2V5WyJl - cmFzdXJlX2NvZGVfcHJvZmlsZSJdIGFuZCBrZXlbInBvb2xfbmFtZSJdID09IHJiZF9wb29sX25h - bWU6CiAgICAgICAgICAgICAgICAgICAgcG9vbF9leGlzdCA9IFRydWUKCiAgICAgICAgICAgIGlm - IG5vdCBtZXRhZGF0YV9wb29sX2V4aXN0OgogICAgICAgICAgICAgICAgcmFpc2UgRXhlY3V0aW9u - RmFpbHVyZUV4Y2VwdGlvbigKICAgICAgICAgICAgICAgICAgICAiUHJvdmlkZWQgcmJkX2VjX21l - dGFkYXRhX3Bvb2wgbmFtZSwiCiAgICAgICAgICAgICAgICAgICAgZiIge3JiZF9tZXRhZGF0YV9l - Y19wb29sX25hbWV9LCBkb2VzIG5vdCBleGlzdCIKICAgICAgICAgICAgICAgICkKICAgICAgICAg - ICAgaWYgbm90IHBvb2xfZXhpc3Q6CiAgICAgICAgICAgICAgICByYWlzZSBFeGVjdXRpb25GYWls - dXJlRXhjZXB0aW9uKAogICAgICAgICAgICAgICAgICAgIGYiUHJvdmlkZWQgcmJkX2RhdGFfcG9v - bCBuYW1lLCB7cmJkX3Bvb2xfbmFtZX0sIGRvZXMgbm90IGV4aXN0IgogICAgICAgICAgICAgICAg - KQogICAgICAgICAgICByZXR1cm4gcmJkX21ldGFkYXRhX2VjX3Bvb2xfbmFtZQoKICAgIGRlZiBk - cnlfcnVuKHNlbGYsIG1zZyk6CiAgICAgICAgaWYgc2VsZi5fYXJnX3BhcnNlci5kcnlfcnVuOgog - ICAgICAgICAgICBwcmludCgiRXhlY3V0ZTogIiArICInIiArIG1zZyArICInIikKCiAgICBkZWYg - dmFsaWRhdGVfcmd3X2VuZHBvaW50X3Rsc19jZXJ0KHNlbGYpOgogICAgICAgIGlmIHNlbGYuX2Fy - Z19wYXJzZXIucmd3X3Rsc19jZXJ0X3BhdGg6CiAgICAgICAgICAgIHdpdGggb3BlbihzZWxmLl9h - cmdfcGFyc2VyLnJnd190bHNfY2VydF9wYXRoLCBlbmNvZGluZz0idXRmOCIpIGFzIGY6CiAgICAg - ICAgICAgICAgICBjb250ZW50cyA9IGYucmVhZCgpCiAgICAgICAgICAgICAgICByZXR1cm4gY29u - dGVudHMucnN0cmlwKCkKCiAgICBkZWYgX2ludmFsaWRfZW5kcG9pbnQoc2VsZiwgZW5kcG9pbnRf - c3RyKToKICAgICAgICAjIGV4dHJhY3QgdGhlIHBvcnQgYnkgZ2V0dGluZyB0aGUgbGFzdCBzcGxp - dCBvbiBgOmAgZGVsaW1pdGVyCiAgICAgICAgdHJ5OgogICAgICAgICAgICBlbmRwb2ludF9zdHJf - aXAsIHBvcnQgPSBlbmRwb2ludF9zdHIucnNwbGl0KCI6IiwgMSkKICAgICAgICBleGNlcHQgVmFs - dWVFcnJvcjoKICAgICAgICAgICAgcmFpc2UgRXhlY3V0aW9uRmFpbHVyZUV4Y2VwdGlvbihmIk5v - dCBhIHByb3BlciBlbmRwb2ludDoge2VuZHBvaW50X3N0cn0iKQoKICAgICAgICB0cnk6CiAgICAg - ICAgICAgIGlmIGVuZHBvaW50X3N0cl9pcFswXSA9PSAiWyI6CiAgICAgICAgICAgICAgICBlbmRw - b2ludF9zdHJfaXAgPSBlbmRwb2ludF9zdHJfaXBbMSA6IGxlbihlbmRwb2ludF9zdHJfaXApIC0g - MV0KICAgICAgICAgICAgaXBfdHlwZSA9ICgKICAgICAgICAgICAgICAgICJJUHY0IiBpZiB0eXBl - KGlwX2FkZHJlc3MoZW5kcG9pbnRfc3RyX2lwKSkgaXMgSVB2NEFkZHJlc3MgZWxzZSAiSVB2NiIK - ICAgICAgICAgICAgKQogICAgICAgIGV4Y2VwdCBWYWx1ZUVycm9yOgogICAgICAgICAgICBpcF90 - eXBlID0gIkZRRE4iCiAgICAgICAgaWYgbm90IHBvcnQuaXNkaWdpdCgpOgogICAgICAgICAgICBy - YWlzZSBFeGVjdXRpb25GYWlsdXJlRXhjZXB0aW9uKGYiUG9ydCBub3QgdmFsaWQ6IHtwb3J0fSIp - CiAgICAgICAgaW50UG9ydCA9IGludChwb3J0KQogICAgICAgIGlmIGludFBvcnQgPCAxIG9yIGlu - dFBvcnQgPiAyKioxNiAtIDE6CiAgICAgICAgICAgIHJhaXNlIEV4ZWN1dGlvbkZhaWx1cmVFeGNl - cHRpb24oZiJPdXQgb2YgcmFuZ2UgcG9ydCBudW1iZXI6IHtwb3J0fSIpCgogICAgICAgIHJldHVy - biBpcF90eXBlCgogICAgZGVmIGVuZHBvaW50X2RpYWwoc2VsZiwgZW5kcG9pbnRfc3RyLCBpcF90 - eXBlLCB0aW1lb3V0PTMsIGNlcnQ9Tm9uZSk6CiAgICAgICAgIyBpZiB0aGUgJ2NsdXN0ZXInIGlu - c3RhbmNlIGlzIGEgZHVtbXkgb25lLAogICAgICAgICMgZG9uJ3QgdHJ5IHRvIHJlYWNoIG91dCB0 - byB0aGUgZW5kcG9pbnQKICAgICAgICBpZiBpc2luc3RhbmNlKHNlbGYuY2x1c3RlciwgRHVtbXlS - YWRvcyk6CiAgICAgICAgICAgIHJldHVybiAiIiwgIiIsICIiCiAgICAgICAgaWYgaXBfdHlwZSA9 - PSAiSVB2NiI6CiAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgIGVuZHBvaW50X3N0cl9p - cCwgZW5kcG9pbnRfc3RyX3BvcnQgPSBlbmRwb2ludF9zdHIucnNwbGl0KCI6IiwgMSkKICAgICAg - ICAgICAgZXhjZXB0IFZhbHVlRXJyb3I6CiAgICAgICAgICAgICAgICByYWlzZSBFeGVjdXRpb25G - YWlsdXJlRXhjZXB0aW9uKAogICAgICAgICAgICAgICAgICAgIGYiTm90IGEgcHJvcGVyIGVuZHBv - aW50OiB7ZW5kcG9pbnRfc3RyfSIKICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgaWYgZW5k - cG9pbnRfc3RyX2lwWzBdICE9ICJbIjoKICAgICAgICAgICAgICAgIGVuZHBvaW50X3N0cl9pcCA9 - ICJbIiArIGVuZHBvaW50X3N0cl9pcCArICJdIgogICAgICAgICAgICBlbmRwb2ludF9zdHIgPSAi - OiIuam9pbihbZW5kcG9pbnRfc3RyX2lwLCBlbmRwb2ludF9zdHJfcG9ydF0pCgogICAgICAgIHBy - b3RvY29scyA9IFsiaHR0cCIsICJodHRwcyJdCiAgICAgICAgcmVzcG9uc2VfZXJyb3IgPSBOb25l - CiAgICAgICAgZm9yIHByZWZpeCBpbiBwcm90b2NvbHM6CiAgICAgICAgICAgIHRyeToKICAgICAg - ICAgICAgICAgIGVwID0gZiJ7cHJlZml4fTovL3tlbmRwb2ludF9zdHJ9IgogICAgICAgICAgICAg - ICAgdmVyaWZ5ID0gTm9uZQogICAgICAgICAgICAgICAgIyBJZiB2ZXJpZnkgaXMgc2V0IHRvIGEg - cGF0aCB0byBhIGRpcmVjdG9yeSwKICAgICAgICAgICAgICAgICMgdGhlIGRpcmVjdG9yeSBtdXN0 - IGhhdmUgYmVlbiBwcm9jZXNzZWQgdXNpbmcgdGhlIGNfcmVoYXNoIHV0aWxpdHkgc3VwcGxpZWQg - d2l0aCBPcGVuU1NMLgogICAgICAgICAgICAgICAgaWYgcHJlZml4ID09ICJodHRwcyIgYW5kIHNl - bGYuX2FyZ19wYXJzZXIucmd3X3NraXBfdGxzOgogICAgICAgICAgICAgICAgICAgIHZlcmlmeSA9 - IEZhbHNlCiAgICAgICAgICAgICAgICAgICAgciA9IHJlcXVlc3RzLmhlYWQoZXAsIHRpbWVvdXQ9 - dGltZW91dCwgdmVyaWZ5PUZhbHNlKQogICAgICAgICAgICAgICAgZWxpZiBwcmVmaXggPT0gImh0 - dHBzIiBhbmQgY2VydDoKICAgICAgICAgICAgICAgICAgICB2ZXJpZnkgPSBjZXJ0CiAgICAgICAg - ICAgICAgICAgICAgciA9IHJlcXVlc3RzLmhlYWQoZXAsIHRpbWVvdXQ9dGltZW91dCwgdmVyaWZ5 - PWNlcnQpCiAgICAgICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgICAgIHIgPSByZXF1 - ZXN0cy5oZWFkKGVwLCB0aW1lb3V0PXRpbWVvdXQpCiAgICAgICAgICAgICAgICBpZiByLnN0YXR1 - c19jb2RlID09IDIwMDoKICAgICAgICAgICAgICAgICAgICByZXR1cm4gcHJlZml4LCB2ZXJpZnks - ICIiCiAgICAgICAgICAgIGV4Y2VwdCBFeGNlcHRpb24gYXMgZXJyOgogICAgICAgICAgICAgICAg - cmVzcG9uc2VfZXJyb3IgPSBlcnIKICAgICAgICAgICAgICAgIGNvbnRpbnVlCiAgICAgICAgc3lz - LnN0ZGVyci53cml0ZSgKICAgICAgICAgICAgZiJ1bmFibGUgdG8gY29ubmVjdCB0byBlbmRwb2lu - dDoge2VuZHBvaW50X3N0cn0sIGZhaWxlZCBlcnJvcjoge3Jlc3BvbnNlX2Vycm9yfSIKICAgICAg - ICApCiAgICAgICAgcmV0dXJuICgKICAgICAgICAgICAgIiIsCiAgICAgICAgICAgICIiLAogICAg - ICAgICAgICAoIi0xIiksCiAgICAgICAgKQoKICAgIGRlZiBwYXJzZV9jb25maWdfZmlsZShzZWxm - LCBjb25maWdfZmlsZSk6CiAgICAgICAgY29uZmlnID0gY29uZmlncGFyc2VyLkNvbmZpZ1BhcnNl - cigpCiAgICAgICAgY29uZmlnLnJlYWQoY29uZmlnX2ZpbGUpCiAgICAgICAgZm9yIGFyZyBpbiBs - aXN0KHZhcnMoc2VsZi5fYXJnX3BhcnNlcikpOgogICAgICAgICAgICAjIHB5dGhvbiB0cmVhdHMg - ZmxhZy1uYW1lIGFzIGZsYWdfbmFtZSBpbnRlcm5hbGx5LCBzbyBjb252ZXJ0aW5nIGJhY2sgdG8g - ZmxhZy1uYW1lLAogICAgICAgICAgICAjIHNvIHdlIGNhbiBnZXQgdGhvc2UgdmFsdWVzIGZyb20g - Y29uZmlnIGZpbGUKICAgICAgICAgICAgYXJndW1lbnQgPSBhcmcucmVwbGFjZSgiXyIsICItIikK - ICAgICAgICAgICAgYXJndW1lbnRWYWx1ZSA9IHN0cihnZXRhdHRyKHNlbGYuX2FyZ19wYXJzZXIs - IGFyZykpCiAgICAgICAgICAgIGNvbmZpZ192YWx1ZSA9IGNvbmZpZy5nZXQoIkNvbmZpZ3VyYXRp - b25zIiwgYXJndW1lbnQsIGZhbGxiYWNrPU5vbmUpCiAgICAgICAgICAgICMgZ2l2ZSBwcmlvcml0 - eSB0byBjb21tYW5kIGxpbmUgYXJndW1lbnQsIGlmIGNvbW1hbmQgbGluZSBhcmd1bWVudCBpcyBu - b3QgcHJlc2VudCB1c2UgY29uZmlnLmluaSB2YWx1ZSwKICAgICAgICAgICAgaWYgKHN0cihzeXMu - YXJndikuZmluZChhcmd1bWVudCkgPT0gLTEpIGFuZCAoCiAgICAgICAgICAgICAgICAoY29uZmln - X3ZhbHVlICE9IE5vbmUpIGFuZCAoY29uZmlnX3ZhbHVlICE9ICIiKQogICAgICAgICAgICApOgog - ICAgICAgICAgICAgICAgc2VsZi5fYXJnX3BhcnNlci5fX3NldGF0dHJfXyhhcmcsIGNvbmZpZ192 - YWx1ZSkKCiAgICAgICAgcmV0dXJuIGNvbmZpZwoKICAgIGRlZiBfX2luaXRfXyhzZWxmLCBhcmdf - bGlzdD1Ob25lKToKICAgICAgICBzZWxmLm91dF9tYXAgPSB7fQogICAgICAgIHNlbGYuX2V4Y2x1 - ZGVkX2tleXMgPSBzZXQoKQogICAgICAgIHNlbGYuX2FyZ19wYXJzZXIgPSBzZWxmLmdlbl9hcmdf - cGFyc2VyKGFyZ3NfdG9fcGFyc2U9YXJnX2xpc3QpCiAgICAgICAgaWYgc2VsZi5fYXJnX3BhcnNl - ci5jb25maWdfZmlsZToKICAgICAgICAgICAgc2VsZi5jb25maWcgPSBzZWxmLnBhcnNlX2NvbmZp - Z19maWxlKHNlbGYuX2FyZ19wYXJzZXIuY29uZmlnX2ZpbGUpCiAgICAgICAgc2VsZi5ydW5fYXNf - dXNlciA9IHNlbGYuX2FyZ19wYXJzZXIucnVuX2FzX3VzZXIKICAgICAgICBzZWxmLm91dHB1dF9m - aWxlID0gc2VsZi5fYXJnX3BhcnNlci5vdXRwdXQKICAgICAgICBzZWxmLmNlcGhfY29uZiA9IHNl - bGYuX2FyZ19wYXJzZXIuY2VwaF9jb25mCiAgICAgICAgc2VsZi5jZXBoX2tleXJpbmcgPSBzZWxm - Ll9hcmdfcGFyc2VyLmtleXJpbmcKICAgICAgICAjIGlmIHVzZXIgbm90IHByb3ZpZGVkLCBnaXZl - IGEgZGVmYXVsdCB1c2VyCiAgICAgICAgaWYgbm90IHNlbGYucnVuX2FzX3VzZXIgYW5kIG5vdCBz - ZWxmLl9hcmdfcGFyc2VyLnVwZ3JhZGU6CiAgICAgICAgICAgIHNlbGYucnVuX2FzX3VzZXIgPSBz - ZWxmLkVYVEVSTkFMX1VTRVJfTkFNRQogICAgICAgIGlmIG5vdCBzZWxmLl9hcmdfcGFyc2VyLnJn - d19wb29sX3ByZWZpeCBhbmQgbm90IHNlbGYuX2FyZ19wYXJzZXIudXBncmFkZToKICAgICAgICAg - ICAgc2VsZi5fYXJnX3BhcnNlci5yZ3dfcG9vbF9wcmVmaXggPSBzZWxmLkRFRkFVTFRfUkdXX1BP - T0xfUFJFRklYCiAgICAgICAgaWYgc2VsZi5jZXBoX2NvbmY6CiAgICAgICAgICAgIGt3YXJncyA9 - IHt9CiAgICAgICAgICAgIGlmIHNlbGYuY2VwaF9rZXlyaW5nOgogICAgICAgICAgICAgICAga3dh - cmdzWyJjb25mIl0gPSB7ImtleXJpbmciOiBzZWxmLmNlcGhfa2V5cmluZ30KICAgICAgICAgICAg - c2VsZi5jbHVzdGVyID0gcmFkb3MuUmFkb3MoY29uZmZpbGU9c2VsZi5jZXBoX2NvbmYsICoqa3dh - cmdzKQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHNlbGYuY2x1c3RlciA9IHJhZG9zLlJhZG9z - KCkKICAgICAgICAgICAgc2VsZi5jbHVzdGVyLmNvbmZfcmVhZF9maWxlKCkKICAgICAgICBzZWxm - LmNsdXN0ZXIuY29ubmVjdCgpCgogICAgZGVmIHNodXRkb3duKHNlbGYpOgogICAgICAgIGlmIHNl - bGYuY2x1c3Rlci5zdGF0ZSA9PSAiY29ubmVjdGVkIjoKICAgICAgICAgICAgc2VsZi5jbHVzdGVy - LnNodXRkb3duKCkKCiAgICBkZWYgZ2V0X2ZzaWQoc2VsZik6CiAgICAgICAgaWYgc2VsZi5fYXJn - X3BhcnNlci5kcnlfcnVuOgogICAgICAgICAgICByZXR1cm4gc2VsZi5kcnlfcnVuKCJjZXBoIGZz - aWQiKQogICAgICAgIHJldHVybiBzdHIoc2VsZi5jbHVzdGVyLmdldF9mc2lkKCkpCgogICAgZGVm - IF9jb21tb25fY21kX2pzb25fZ2VuKHNlbGYsIGNtZF9qc29uKToKICAgICAgICBjbWQgPSBqc29u - LmR1bXBzKGNtZF9qc29uLCBzb3J0X2tleXM9VHJ1ZSkKICAgICAgICByZXRfdmFsLCBjbWRfb3V0 - LCBlcnJfbXNnID0gc2VsZi5jbHVzdGVyLm1vbl9jb21tYW5kKGNtZCwgYiIiKQogICAgICAgIGlm - IHNlbGYuX2FyZ19wYXJzZXIudmVyYm9zZToKICAgICAgICAgICAgcHJpbnQoZiJDb21tYW5kIElu - cHV0OiB7Y21kfSIpCiAgICAgICAgICAgIHByaW50KAogICAgICAgICAgICAgICAgZiJSZXR1cm4g - VmFsOiB7cmV0X3ZhbH1cbkNvbW1hbmQgT3V0cHV0OiB7Y21kX291dH1cbiIKICAgICAgICAgICAg - ICAgIGYiRXJyb3IgTWVzc2FnZToge2Vycl9tc2d9XG4tLS0tLS0tLS0tXG4iCiAgICAgICAgICAg - ICkKICAgICAgICBqc29uX291dCA9IHt9CiAgICAgICAgIyBpZiB0aGVyZSBpcyBubyBlcnJvciAo - aS5lOyByZXRfdmFsIGlzIFpFUk8pIGFuZCAnY21kX291dCcgaXMgbm90IGVtcHR5CiAgICAgICAg - IyB0aGVuIGNvbnZlcnQgJ2NtZF9vdXQnIHRvIGEganNvbiBvdXRwdXQKICAgICAgICBpZiByZXRf - dmFsID09IDAgYW5kIGNtZF9vdXQ6CiAgICAgICAgICAgIGpzb25fb3V0ID0ganNvbi5sb2Fkcyhj - bWRfb3V0KQogICAgICAgIHJldHVybiByZXRfdmFsLCBqc29uX291dCwgZXJyX21zZwoKICAgIGRl - ZiBnZXRfY2VwaF9leHRlcm5hbF9tb25fZGF0YShzZWxmKToKICAgICAgICBjbWRfanNvbiA9IHsi - cHJlZml4IjogInF1b3J1bV9zdGF0dXMiLCAiZm9ybWF0IjogImpzb24ifQogICAgICAgIGlmIHNl - bGYuX2FyZ19wYXJzZXIuZHJ5X3J1bjoKICAgICAgICAgICAgcmV0dXJuIHNlbGYuZHJ5X3J1bigi - Y2VwaCAiICsgY21kX2pzb25bInByZWZpeCJdKQogICAgICAgIHJldF92YWwsIGpzb25fb3V0LCBl - cnJfbXNnID0gc2VsZi5fY29tbW9uX2NtZF9qc29uX2dlbihjbWRfanNvbikKICAgICAgICAjIGlm - IHRoZXJlIGlzIGFuIHVuc3VjY2Vzc2Z1bCBhdHRlbXB0LAogICAgICAgIGlmIHJldF92YWwgIT0g - MCBvciBsZW4oanNvbl9vdXQpID09IDA6CiAgICAgICAgICAgIHJhaXNlIEV4ZWN1dGlvbkZhaWx1 - cmVFeGNlcHRpb24oCiAgICAgICAgICAgICAgICAiJ3F1b3J1bV9zdGF0dXMnIGNvbW1hbmQgZmFp - bGVkLlxuIgogICAgICAgICAgICAgICAgZiJFcnJvcjoge2Vycl9tc2cgaWYgcmV0X3ZhbCAhPSAw - IGVsc2Ugc2VsZi5FTVBUWV9PVVRQVVRfTElTVH0iCiAgICAgICAgICAgICkKICAgICAgICBxX2xl - YWRlcl9uYW1lID0ganNvbl9vdXRbInF1b3J1bV9sZWFkZXJfbmFtZSJdCiAgICAgICAgcV9sZWFk - ZXJfZGV0YWlscyA9IHt9CiAgICAgICAgcV9sZWFkZXJfbWF0Y2hpbmdfbGlzdCA9IFsKICAgICAg - ICAgICAgbCBmb3IgbCBpbiBqc29uX291dFsibW9ubWFwIl1bIm1vbnMiXSBpZiBsWyJuYW1lIl0g - PT0gcV9sZWFkZXJfbmFtZQogICAgICAgIF0KICAgICAgICBpZiBsZW4ocV9sZWFkZXJfbWF0Y2hp - bmdfbGlzdCkgPT0gMDoKICAgICAgICAgICAgcmFpc2UgRXhlY3V0aW9uRmFpbHVyZUV4Y2VwdGlv - bigiTm8gbWF0Y2hpbmcgJ21vbicgZGV0YWlscyBmb3VuZCIpCiAgICAgICAgcV9sZWFkZXJfZGV0 - YWlscyA9IHFfbGVhZGVyX21hdGNoaW5nX2xpc3RbMF0KICAgICAgICAjIGdldCB0aGUgYWRkcmVz - cyB2ZWN0b3Igb2YgdGhlIHF1b3J1bS1sZWFkZXIKICAgICAgICBxX2xlYWRlcl9hZGRydmVjID0g - cV9sZWFkZXJfZGV0YWlscy5nZXQoInB1YmxpY19hZGRycyIsIHt9KS5nZXQoImFkZHJ2ZWMiLCBb - XSkKICAgICAgICBpcF9hZGRyID0gc3RyKHFfbGVhZGVyX2RldGFpbHNbInB1YmxpY19hZGRyIl0u - c3BsaXQoIi8iKVswXSkKCiAgICAgICAgaWYgc2VsZi5fYXJnX3BhcnNlci52Ml9wb3J0X2VuYWJs - ZToKICAgICAgICAgICAgaWYgcV9sZWFkZXJfYWRkcnZlY1swXVsidHlwZSJdID09ICJ2MiI6CiAg - ICAgICAgICAgICAgICBpcF9hZGRyID0gcV9sZWFkZXJfYWRkcnZlY1swXVsiYWRkciJdCiAgICAg - ICAgICAgIGVsaWYgbGVuKHFfbGVhZGVyX2FkZHJ2ZWMpID4gMSBhbmQgcV9sZWFkZXJfYWRkcnZl - Y1sxXVsidHlwZSJdID09ICJ2MiI6CiAgICAgICAgICAgICAgICBpcF9hZGRyID0gcV9sZWFkZXJf - YWRkcnZlY1sxXVsiYWRkciJdCiAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICBzeXMu - c3RkZXJyLndyaXRlKAogICAgICAgICAgICAgICAgICAgICIndjInIGFkZHJlc3MgdHlwZSBub3Qg - cHJlc2VudCwgYW5kICd2Mi1wb3J0LWVuYWJsZScgZmxhZyBpcyBwcm92aWRlZCIKICAgICAgICAg - ICAgICAgICkKCiAgICAgICAgcmV0dXJuIGYie3N0cihxX2xlYWRlcl9uYW1lKX09e2lwX2FkZHJ9 - IgoKICAgIGRlZiBfY29udmVydF9ob3N0bmFtZV90b19pcChzZWxmLCBob3N0X25hbWUsIHBvcnQs - IGlwX3R5cGUpOgogICAgICAgICMgaWYgJ2NsdXN0ZXInIGluc3RhbmNlIGlzIGEgZHVtbXkgdHlw - ZSwKICAgICAgICAjIGNhbGwgdGhlIGR1bW15IGluc3RhbmNlJ3MgImNvbnZlcnQiIG1ldGhvZAog - ICAgICAgIGlmIG5vdCBob3N0X25hbWU6CiAgICAgICAgICAgIHJhaXNlIEV4ZWN1dGlvbkZhaWx1 - cmVFeGNlcHRpb24oIkVtcHR5IGhvc3RuYW1lIHByb3ZpZGVkIikKICAgICAgICBpZiBpc2luc3Rh - bmNlKHNlbGYuY2x1c3RlciwgRHVtbXlSYWRvcyk6CiAgICAgICAgICAgIHJldHVybiBzZWxmLmNs - dXN0ZXIuX2NvbnZlcnRfaG9zdG5hbWVfdG9faXAoaG9zdF9uYW1lKQoKICAgICAgICBpZiBpcF90 - eXBlID09ICJGUUROIjoKICAgICAgICAgICAgIyBjaGVjayB3aGljaCBpcCBGUUROIHNob3VsZCBi - ZSBjb252ZXJ0ZWQgdG8sIElQdjQgb3IgSVB2NgogICAgICAgICAgICAjIGNoZWNrIHRoZSBob3N0 - IGlwLCB0aGUgZW5kcG9pbnQgaXAgdHlwZSB3b3VsZCBiZSBzaW1pbGFyIHRvIGhvc3QgaXAKICAg - ICAgICAgICAgY21kX2pzb24gPSB7InByZWZpeCI6ICJvcmNoIGhvc3QgbHMiLCAiZm9ybWF0Ijog - Impzb24ifQogICAgICAgICAgICByZXRfdmFsLCBqc29uX291dCwgZXJyX21zZyA9IHNlbGYuX2Nv - bW1vbl9jbWRfanNvbl9nZW4oY21kX2pzb24pCiAgICAgICAgICAgICMgaWYgdGhlcmUgaXMgYW4g - dW5zdWNjZXNzZnVsIGF0dGVtcHQsCiAgICAgICAgICAgIGlmIHJldF92YWwgIT0gMCBvciBsZW4o - anNvbl9vdXQpID09IDA6CiAgICAgICAgICAgICAgICByYWlzZSBFeGVjdXRpb25GYWlsdXJlRXhj - ZXB0aW9uKAogICAgICAgICAgICAgICAgICAgICInb3JjaCBob3N0IGxzJyBjb21tYW5kIGZhaWxl + ZWxwPSJwcm92aWRlcyB0aGUgbmFtZSBvZiB0aGUgc3Vidm9sdW1lIGdyb3VwIiwKICAgICAgICAp + CiAgICAgICAgb3V0cHV0X2dyb3VwLmFkZF9hcmd1bWVudCgKICAgICAgICAgICAgIi0tcmd3LXJl + YWxtLW5hbWUiLAogICAgICAgICAgICBkZWZhdWx0PSIiLAogICAgICAgICAgICByZXF1aXJlZD1G + YWxzZSwKICAgICAgICAgICAgaGVscD0icHJvdmlkZXMgdGhlIG5hbWUgb2YgdGhlIHJndy1yZWFs + bSIsCiAgICAgICAgKQogICAgICAgIG91dHB1dF9ncm91cC5hZGRfYXJndW1lbnQoCiAgICAgICAg + ICAgICItLXJndy16b25lLW5hbWUiLAogICAgICAgICAgICBkZWZhdWx0PSIiLAogICAgICAgICAg + ICByZXF1aXJlZD1GYWxzZSwKICAgICAgICAgICAgaGVscD0icHJvdmlkZXMgdGhlIG5hbWUgb2Yg + dGhlIHJndy16b25lIiwKICAgICAgICApCiAgICAgICAgb3V0cHV0X2dyb3VwLmFkZF9hcmd1bWVu + dCgKICAgICAgICAgICAgIi0tcmd3LXpvbmVncm91cC1uYW1lIiwKICAgICAgICAgICAgZGVmYXVs + dD0iIiwKICAgICAgICAgICAgcmVxdWlyZWQ9RmFsc2UsCiAgICAgICAgICAgIGhlbHA9InByb3Zp + ZGVzIHRoZSBuYW1lIG9mIHRoZSByZ3ctem9uZWdyb3VwIiwKICAgICAgICApCiAgICAgICAgb3V0 + cHV0X2dyb3VwLmFkZF9hcmd1bWVudCgKICAgICAgICAgICAgIi0tdG9wb2xvZ3ktcG9vbHMiLAog + ICAgICAgICAgICBkZWZhdWx0PSIiLAogICAgICAgICAgICByZXF1aXJlZD1GYWxzZSwKICAgICAg + ICAgICAgaGVscD0iY29tbWEtc2VwYXJhdGVkIGxpc3Qgb2YgdG9wb2xvZ3ktY29uc3RyYWluZWQg + cmJkIHBvb2xzIiwKICAgICAgICApCiAgICAgICAgb3V0cHV0X2dyb3VwLmFkZF9hcmd1bWVudCgK + ICAgICAgICAgICAgIi0tdG9wb2xvZ3ktZmFpbHVyZS1kb21haW4tbGFiZWwiLAogICAgICAgICAg + ICBkZWZhdWx0PSIiLAogICAgICAgICAgICByZXF1aXJlZD1GYWxzZSwKICAgICAgICAgICAgaGVs + cD0iazhzIGNsdXN0ZXIgZmFpbHVyZSBkb21haW4gbGFiZWwgKGV4YW1wbGU6IHpvbmUsIHJhY2ss + IG9yIGhvc3QpIGZvciB0aGUgdG9wb2xvZ3ktcG9vbHMgdGhhdCBtYXRjaCB0aGUgY2VwaCBkb21h + aW4iLAogICAgICAgICkKICAgICAgICBvdXRwdXRfZ3JvdXAuYWRkX2FyZ3VtZW50KAogICAgICAg + ICAgICAiLS10b3BvbG9neS1mYWlsdXJlLWRvbWFpbi12YWx1ZXMiLAogICAgICAgICAgICBkZWZh + dWx0PSIiLAogICAgICAgICAgICByZXF1aXJlZD1GYWxzZSwKICAgICAgICAgICAgaGVscD0iY29t + bWEtc2VwYXJhdGVkIGxpc3Qgb2YgdGhlIGs4cyBjbHVzdGVyIGZhaWx1cmUgZG9tYWluIHZhbHVl + cyBjb3JyZXNwb25kaW5nIHRvIGVhY2ggb2YgdGhlIHBvb2xzIGluIHRoZSBgdG9wb2xvZ3ktcG9v + bHNgIGxpc3QiLAogICAgICAgICkKCiAgICAgICAgdXBncmFkZV9ncm91cCA9IGFyZ1AuYWRkX2Fy + Z3VtZW50X2dyb3VwKCJ1cGdyYWRlIikKICAgICAgICB1cGdyYWRlX2dyb3VwLmFkZF9hcmd1bWVu + dCgKICAgICAgICAgICAgIi0tdXBncmFkZSIsCiAgICAgICAgICAgIGFjdGlvbj0ic3RvcmVfdHJ1 + ZSIsCiAgICAgICAgICAgIGRlZmF1bHQ9RmFsc2UsCiAgICAgICAgICAgIGhlbHA9IlVwZ3JhZGVz + IHRoZSBjZXBoQ1NJS2V5cmluZ3MoRm9yIGV4YW1wbGU6IGNsaWVudC5jc2ktY2VwaGZzLXByb3Zp + c2lvbmVyKSBhbmQgY2xpZW50LmhlYWx0aGNoZWNrZXIgY2VwaCB1c2VycyB3aXRoIG5ldyBwZXJt + aXNzaW9ucyBuZWVkZWQgZm9yIHRoZSBuZXcgY2x1c3RlciB2ZXJzaW9uIGFuZCBvbGRlciBwZXJt + aXNzaW9uIHdpbGwgc3RpbGwgYmUgYXBwbGllZC4iCiAgICAgICAgICAgICsgIlNhbXBsZSBydW46 + IGBweXRob24zIC9ldGMvY2VwaC9jcmVhdGUtZXh0ZXJuYWwtY2x1c3Rlci1yZXNvdXJjZXMucHkg + LS11cGdyYWRlYCwgdGhpcyB3aWxsIHVwZ3JhZGUgYWxsIHRoZSBkZWZhdWx0IGNzaSB1c2Vycyhu + b24tcmVzdHJpY3RlZCkiCiAgICAgICAgICAgICsgIkZvciByZXN0cmljdGVkIHVzZXJzKEZvciBl + eGFtcGxlOiBjbGllbnQuY3NpLWNlcGhmcy1wcm92aXNpb25lci1vcGVuc2hpZnQtc3RvcmFnZS1t + eWZzKSwgdXNlcnMgY3JlYXRlZCB1c2luZyAtLXJlc3RyaWN0ZWQtYXV0aC1wZXJtaXNzaW9uIGZs + YWcgbmVlZCB0byBwYXNzIG1hbmRhdG9yeSBmbGFncyIKICAgICAgICAgICAgKyAibWFuZGF0b3J5 + IGZsYWdzOiAnLS1yYmQtZGF0YS1wb29sLW5hbWUsIC0tazhzLWNsdXN0ZXItbmFtZSBhbmQgLS1y + dW4tYXMtdXNlcicgZmxhZ3Mgd2hpbGUgdXBncmFkaW5nIgogICAgICAgICAgICArICJpbiBjYXNl + IG9mIGNlcGhmcyB1c2VycyBpZiB5b3UgaGF2ZSBwYXNzZWQgLS1jZXBoZnMtZmlsZXN5c3RlbS1u + YW1lIGZsYWcgd2hpbGUgY3JlYXRpbmcgdXNlciB0aGVuIHdoaWxlIHVwZ3JhZGluZyBpdCB3aWxs + IGJlIG1hbmRhdG9yeSB0b28iCiAgICAgICAgICAgICsgIlNhbXBsZSBydW46IGBweXRob24zIC9l + dGMvY2VwaC9jcmVhdGUtZXh0ZXJuYWwtY2x1c3Rlci1yZXNvdXJjZXMucHkgLS11cGdyYWRlIC0t + cmJkLWRhdGEtcG9vbC1uYW1lIHJlcGxpY2Fwb29sIC0tazhzLWNsdXN0ZXItbmFtZSByb29rc3Rv + cmFnZSAgLS1ydW4tYXMtdXNlciBjbGllbnQuY3NpLXJiZC1ub2RlLXJvb2tzdG9yYWdlLXJlcGxp + Y2Fwb29sYCIKICAgICAgICAgICAgKyAiUFM6IEFuIGV4aXN0aW5nIG5vbi1yZXN0cmljdGVkIHVz + ZXIgY2Fubm90IGJlIGNvbnZlcnRlZCB0byBhIHJlc3RyaWN0ZWQgdXNlciBieSB1cGdyYWRpbmcu + IgogICAgICAgICAgICArICJVcGdyYWRlIGZsYWcgc2hvdWxkIG9ubHkgYmUgdXNlZCB0byBhcHBl + bmQgbmV3IHBlcm1pc3Npb25zIHRvIHVzZXJzLCBpdCBzaG91bGRuJ3QgYmUgdXNlZCBmb3IgY2hh + bmdpbmcgdXNlciBhbHJlYWR5IGFwcGxpZWQgcGVybWlzc2lvbiwgZm9yIGV4YW1wbGUgeW91IHNo + b3VsZG4ndCBjaGFuZ2UgaW4gd2hpY2ggcG9vbCB1c2VyIGhhcyBhY2Nlc3MiLAogICAgICAgICkK + CiAgICAgICAgIyBBZGQgY29tbWFuZC1saW5lIGFyZ3VtZW50cwogICAgICAgIGNvbmZpZ19ncm91 + cCA9IGFyZ1AuYWRkX2FyZ3VtZW50X2dyb3VwKCJjb25maWciKQogICAgICAgIGNvbmZpZ19ncm91 + cC5hZGRfYXJndW1lbnQoCiAgICAgICAgICAgICItLWNvbmZpZy1maWxlIiwKICAgICAgICAgICAg + dHlwZT1zdHIsCiAgICAgICAgICAgIGhlbHA9IlBhdGggdG8gdGhlIGNvbmZpZ3VyYXRpb24gZmls + ZSwgUHJpb3JpdHk6IGNvbW1hbmQtbGluZS1hcmdzID4gY29uZmlnLmluaSBmaWxlIHZhbHVlcyA+ + IGRlZmF1bHQgdmFsdWVzIiwKICAgICAgICAgICAgcmVxdWlyZWQ9RmFsc2UsCiAgICAgICAgICAg + IGRlZmF1bHQ9IiIsCiAgICAgICAgKQoKICAgICAgICBpZiBhcmdzX3RvX3BhcnNlOgogICAgICAg + ICAgICBhc3NlcnQgKAogICAgICAgICAgICAgICAgdHlwZShhcmdzX3RvX3BhcnNlKSA9PSBsaXN0 + CiAgICAgICAgICAgICksICJBcmd1bWVudCB0byAnZ2VuX2FyZ19wYXJzZXInIHNob3VsZCBiZSBh + IGxpc3QiCiAgICAgICAgZWxzZToKICAgICAgICAgICAgYXJnc190b19wYXJzZSA9IHN5cy5hcmd2 + WzE6XQogICAgICAgIHJldHVybiBhcmdQLnBhcnNlX2FyZ3MoYXJnc190b19wYXJzZSkKCiAgICBk + ZWYgdmFsaWRhdGVfcmJkX21ldGFkYXRhX2VjX3Bvb2xfbmFtZShzZWxmKToKICAgICAgICBpZiBz + ZWxmLl9hcmdfcGFyc2VyLnJiZF9tZXRhZGF0YV9lY19wb29sX25hbWU6CiAgICAgICAgICAgIHJi + ZF9tZXRhZGF0YV9lY19wb29sX25hbWUgPSBzZWxmLl9hcmdfcGFyc2VyLnJiZF9tZXRhZGF0YV9l + Y19wb29sX25hbWUKICAgICAgICAgICAgcmJkX3Bvb2xfbmFtZSA9IHNlbGYuX2FyZ19wYXJzZXIu + cmJkX2RhdGFfcG9vbF9uYW1lCgogICAgICAgICAgICBpZiByYmRfcG9vbF9uYW1lID09ICIiOgog + ICAgICAgICAgICAgICAgcmFpc2UgRXhlY3V0aW9uRmFpbHVyZUV4Y2VwdGlvbigKICAgICAgICAg + ICAgICAgICAgICAiRmxhZyAnLS1yYmQtZGF0YS1wb29sLW5hbWUnIHNob3VsZCBub3QgYmUgZW1w + dHkiCiAgICAgICAgICAgICAgICApCgogICAgICAgICAgICBpZiByYmRfbWV0YWRhdGFfZWNfcG9v + bF9uYW1lID09ICIiOgogICAgICAgICAgICAgICAgcmFpc2UgRXhlY3V0aW9uRmFpbHVyZUV4Y2Vw + dGlvbigKICAgICAgICAgICAgICAgICAgICAiRmxhZyAnLS1yYmQtbWV0YWRhdGEtZWMtcG9vbC1u + YW1lJyBzaG91bGQgbm90IGJlIGVtcHR5IgogICAgICAgICAgICAgICAgKQoKICAgICAgICAgICAg + Y21kX2pzb24gPSB7InByZWZpeCI6ICJvc2QgZHVtcCIsICJmb3JtYXQiOiAianNvbiJ9CiAgICAg + ICAgICAgIHJldF92YWwsIGpzb25fb3V0LCBlcnJfbXNnID0gc2VsZi5fY29tbW9uX2NtZF9qc29u + X2dlbihjbWRfanNvbikKICAgICAgICAgICAgaWYgcmV0X3ZhbCAhPSAwIG9yIGxlbihqc29uX291 + dCkgPT0gMDoKICAgICAgICAgICAgICAgIHJhaXNlIEV4ZWN1dGlvbkZhaWx1cmVFeGNlcHRpb24o + CiAgICAgICAgICAgICAgICAgICAgZiJ7Y21kX2pzb25bJ3ByZWZpeCddfSBjb21tYW5kIGZhaWxl ZC5cbiIKICAgICAgICAgICAgICAgICAgICBmIkVycm9yOiB7ZXJyX21zZyBpZiByZXRfdmFsICE9 IDAgZWxzZSBzZWxmLkVNUFRZX09VVFBVVF9MSVNUfSIKICAgICAgICAgICAgICAgICkKICAgICAg - ICAgICAgaG9zdF9hZGRyID0ganNvbl9vdXRbMF1bImFkZHIiXQogICAgICAgICAgICAjIGFkZCA6 - ODAgc2FtcGxlIHBvcnQgaW4gaXBfdHlwZSwgYXMgX2ludmFsaWRfZW5kcG9pbnQgYWxzbyB2ZXJp - ZnkgcG9ydAogICAgICAgICAgICBob3N0X2lwX3R5cGUgPSBzZWxmLl9pbnZhbGlkX2VuZHBvaW50 - KGhvc3RfYWRkciArICI6ODAiKQogICAgICAgICAgICBpbXBvcnQgc29ja2V0CgogICAgICAgICAg - ICBpcCA9IFtdCiAgICAgICAgICAgICMgZXhhbXBsZSBvdXRwdXQgWyg8QWRkcmVzc0ZhbWlseS5B - Rl9JTkVUOiAyPiwgPFNvY2tldEtpbmQuU09DS19TVFJFQU06IDE+LCA2LCAnJywgKCc5My4xODQu - MjE2LjM0JywgODApKSwgLi4uXQogICAgICAgICAgICAjIHdlIG5lZWQgdG8gZ2V0IDkzLjE4NC4y - MTYuMzQgc28gaXQgd291bGQgYmUgaXBbMF1bNF1bMF0KICAgICAgICAgICAgaWYgaG9zdF9pcF90 - eXBlID09ICJJUHY2IjoKICAgICAgICAgICAgICAgIGlwID0gc29ja2V0LmdldGFkZHJpbmZvKAog - ICAgICAgICAgICAgICAgICAgIGhvc3RfbmFtZSwgcG9ydCwgZmFtaWx5PXNvY2tldC5BRl9JTkVU - NiwgcHJvdG89c29ja2V0LklQUFJPVE9fVENQCiAgICAgICAgICAgICAgICApCiAgICAgICAgICAg - IGVsaWYgaG9zdF9pcF90eXBlID09ICJJUHY0IjoKICAgICAgICAgICAgICAgIGlwID0gc29ja2V0 - LmdldGFkZHJpbmZvKAogICAgICAgICAgICAgICAgICAgIGhvc3RfbmFtZSwgcG9ydCwgZmFtaWx5 - PXNvY2tldC5BRl9JTkVULCBwcm90bz1zb2NrZXQuSVBQUk9UT19UQ1AKICAgICAgICAgICAgICAg - ICkKICAgICAgICAgICAgZGVsIHNvY2tldAogICAgICAgICAgICByZXR1cm4gaXBbMF1bNF1bMF0K - ICAgICAgICByZXR1cm4gaG9zdF9uYW1lCgogICAgZGVmIGdldF9hY3RpdmVfYW5kX3N0YW5kYnlf - bWdycyhzZWxmKToKICAgICAgICBpZiBzZWxmLl9hcmdfcGFyc2VyLmRyeV9ydW46CiAgICAgICAg - ICAgIHJldHVybiAiIiwgc2VsZi5kcnlfcnVuKCJjZXBoIHN0YXR1cyIpCiAgICAgICAgbW9uaXRv - cmluZ19lbmRwb2ludF9wb3J0ID0gc2VsZi5fYXJnX3BhcnNlci5tb25pdG9yaW5nX2VuZHBvaW50 - X3BvcnQKICAgICAgICBtb25pdG9yaW5nX2VuZHBvaW50X2lwX2xpc3QgPSBzZWxmLl9hcmdfcGFy - c2VyLm1vbml0b3JpbmdfZW5kcG9pbnQKICAgICAgICBzdGFuZGJ5X21ncnMgPSBbXQogICAgICAg - IGlmIG5vdCBtb25pdG9yaW5nX2VuZHBvaW50X2lwX2xpc3Q6CiAgICAgICAgICAgIGNtZF9qc29u - ID0geyJwcmVmaXgiOiAic3RhdHVzIiwgImZvcm1hdCI6ICJqc29uIn0KICAgICAgICAgICAgcmV0 - X3ZhbCwganNvbl9vdXQsIGVycl9tc2cgPSBzZWxmLl9jb21tb25fY21kX2pzb25fZ2VuKGNtZF9q - c29uKQogICAgICAgICAgICAjIGlmIHRoZXJlIGlzIGFuIHVuc3VjY2Vzc2Z1bCBhdHRlbXB0LAog - ICAgICAgICAgICBpZiByZXRfdmFsICE9IDAgb3IgbGVuKGpzb25fb3V0KSA9PSAwOgogICAgICAg - ICAgICAgICAgcmFpc2UgRXhlY3V0aW9uRmFpbHVyZUV4Y2VwdGlvbigKICAgICAgICAgICAgICAg - ICAgICAiJ21nciBzZXJ2aWNlcycgY29tbWFuZCBmYWlsZWQuXG4iCiAgICAgICAgICAgICAgICAg - ICAgZiJFcnJvcjoge2Vycl9tc2cgaWYgcmV0X3ZhbCAhPSAwIGVsc2Ugc2VsZi5FTVBUWV9PVVRQ - VVRfTElTVH0iCiAgICAgICAgICAgICAgICApCiAgICAgICAgICAgIG1vbml0b3JpbmdfZW5kcG9p - bnQgPSAoCiAgICAgICAgICAgICAgICBqc29uX291dC5nZXQoIm1ncm1hcCIsIHt9KS5nZXQoInNl - cnZpY2VzIiwge30pLmdldCgicHJvbWV0aGV1cyIsICIiKQogICAgICAgICAgICApCiAgICAgICAg - ICAgIGlmIG5vdCBtb25pdG9yaW5nX2VuZHBvaW50OgogICAgICAgICAgICAgICAgcmFpc2UgRXhl - Y3V0aW9uRmFpbHVyZUV4Y2VwdGlvbigKICAgICAgICAgICAgICAgICAgICAiY2FuJ3QgZmluZCBt - b25pdG9yaW5nX2VuZHBvaW50LCBwcm9tZXRoZXVzIG1vZHVsZSBtaWdodCBub3QgYmUgZW5hYmxl - ZCwgIgogICAgICAgICAgICAgICAgICAgICJlbmFibGUgdGhlIG1vZHVsZSBieSBydW5uaW5nICdj - ZXBoIG1nciBtb2R1bGUgZW5hYmxlIHByb21ldGhldXMnIgogICAgICAgICAgICAgICAgKQogICAg - ICAgICAgICAjIG5vdyBjaGVjayB0aGUgc3RhbmQtYnkgbWdyLXMKICAgICAgICAgICAgc3RhbmRi - eV9hcnIgPSBqc29uX291dC5nZXQoIm1ncm1hcCIsIHt9KS5nZXQoInN0YW5kYnlzIiwgW10pCiAg - ICAgICAgICAgIGZvciBlYWNoX3N0YW5kYnkgaW4gc3RhbmRieV9hcnI6CiAgICAgICAgICAgICAg - ICBpZiAibmFtZSIgaW4gZWFjaF9zdGFuZGJ5LmtleXMoKToKICAgICAgICAgICAgICAgICAgICBz - dGFuZGJ5X21ncnMuYXBwZW5kKGVhY2hfc3RhbmRieVsibmFtZSJdKQogICAgICAgICAgICB0cnk6 - CiAgICAgICAgICAgICAgICBwYXJzZWRfZW5kcG9pbnQgPSB1cmxwYXJzZShtb25pdG9yaW5nX2Vu - ZHBvaW50KQogICAgICAgICAgICBleGNlcHQgVmFsdWVFcnJvcjoKICAgICAgICAgICAgICAgIHJh - aXNlIEV4ZWN1dGlvbkZhaWx1cmVFeGNlcHRpb24oCiAgICAgICAgICAgICAgICAgICAgZiJpbnZh - bGlkIGVuZHBvaW50OiB7bW9uaXRvcmluZ19lbmRwb2ludH0iCiAgICAgICAgICAgICAgICApCiAg - ICAgICAgICAgIG1vbml0b3JpbmdfZW5kcG9pbnRfaXBfbGlzdCA9IHBhcnNlZF9lbmRwb2ludC5o - b3N0bmFtZQogICAgICAgICAgICBpZiBub3QgbW9uaXRvcmluZ19lbmRwb2ludF9wb3J0OgogICAg - ICAgICAgICAgICAgbW9uaXRvcmluZ19lbmRwb2ludF9wb3J0ID0gc3RyKHBhcnNlZF9lbmRwb2lu - dC5wb3J0KQoKICAgICAgICAjIGlmIG1vbml0b3JpbmcgZW5kcG9pbnQgcG9ydCBpcyBub3Qgc2V0 - LCBwdXQgYSBkZWZhdWx0IG1vbiBwb3J0CiAgICAgICAgaWYgbm90IG1vbml0b3JpbmdfZW5kcG9p - bnRfcG9ydDoKICAgICAgICAgICAgbW9uaXRvcmluZ19lbmRwb2ludF9wb3J0ID0gc2VsZi5ERUZB - VUxUX01PTklUT1JJTkdfRU5EUE9JTlRfUE9SVAoKICAgICAgICAjIHVzZXIgY291bGQgZ2l2ZSBj - b21tYSBhbmQgc3BhY2Ugc2VwYXJhdGVkIGlucHV0cyAobGlrZSAtLW1vbml0b3JpbmctZW5kcG9p - bnQ9IjxpcDE+LCA8aXAyPiIpCiAgICAgICAgbW9uaXRvcmluZ19lbmRwb2ludF9pcF9saXN0ID0g - bW9uaXRvcmluZ19lbmRwb2ludF9pcF9saXN0LnJlcGxhY2UoIiwiLCAiICIpCiAgICAgICAgbW9u - aXRvcmluZ19lbmRwb2ludF9pcF9saXN0X3NwbGl0ID0gbW9uaXRvcmluZ19lbmRwb2ludF9pcF9s - aXN0LnNwbGl0KCkKICAgICAgICAjIGlmIG1vbml0b3JpbmctZW5kcG9pbnQgY291bGQgbm90IGJl - IGZvdW5kLCByYWlzZSBhbiBlcnJvcgogICAgICAgIGlmIGxlbihtb25pdG9yaW5nX2VuZHBvaW50 - X2lwX2xpc3Rfc3BsaXQpID09IDA6CiAgICAgICAgICAgIHJhaXNlIEV4ZWN1dGlvbkZhaWx1cmVF - eGNlcHRpb24oIk5vICdtb25pdG9yaW5nLWVuZHBvaW50JyBmb3VuZCIpCiAgICAgICAgIyBmaXJz - dCBpcCBpcyB0cmVhdGVkIGFzIHRoZSBtYWluIG1vbml0b3JpbmctZW5kcG9pbnQKICAgICAgICBt - b25pdG9yaW5nX2VuZHBvaW50X2lwID0gbW9uaXRvcmluZ19lbmRwb2ludF9pcF9saXN0X3NwbGl0 - WzBdCiAgICAgICAgIyByZXN0IG9mIHRoZSBpcC1zIGFyZSBhZGRlZCB0byB0aGUgJ3N0YW5kYnlf - bWdycycgbGlzdAogICAgICAgIHN0YW5kYnlfbWdycy5leHRlbmQobW9uaXRvcmluZ19lbmRwb2lu - dF9pcF9saXN0X3NwbGl0WzE6XSkKICAgICAgICBmYWlsZWRfaXAgPSBtb25pdG9yaW5nX2VuZHBv - aW50X2lwCgogICAgICAgIG1vbml0b3JpbmdfZW5kcG9pbnQgPSAiOiIuam9pbigKICAgICAgICAg - ICAgW21vbml0b3JpbmdfZW5kcG9pbnRfaXAsIG1vbml0b3JpbmdfZW5kcG9pbnRfcG9ydF0KICAg - ICAgICApCiAgICAgICAgaXBfdHlwZSA9IHNlbGYuX2ludmFsaWRfZW5kcG9pbnQobW9uaXRvcmlu - Z19lbmRwb2ludCkKICAgICAgICB0cnk6CiAgICAgICAgICAgIG1vbml0b3JpbmdfZW5kcG9pbnRf - aXAgPSBzZWxmLl9jb252ZXJ0X2hvc3RuYW1lX3RvX2lwKAogICAgICAgICAgICAgICAgbW9uaXRv - cmluZ19lbmRwb2ludF9pcCwgbW9uaXRvcmluZ19lbmRwb2ludF9wb3J0LCBpcF90eXBlCiAgICAg - ICAgICAgICkKICAgICAgICAgICAgIyBjb2xsZWN0IGFsbCB0aGUgJ3N0YW5kLWJ5JyBtZ3IgaXBz - CiAgICAgICAgICAgIG1ncl9pcHMgPSBbXQogICAgICAgICAgICBmb3IgZWFjaF9zdGFuZGJ5X21n - ciBpbiBzdGFuZGJ5X21ncnM6CiAgICAgICAgICAgICAgICBmYWlsZWRfaXAgPSBlYWNoX3N0YW5k - YnlfbWdyCiAgICAgICAgICAgICAgICBtZ3JfaXBzLmFwcGVuZCgKICAgICAgICAgICAgICAgICAg - ICBzZWxmLl9jb252ZXJ0X2hvc3RuYW1lX3RvX2lwKAogICAgICAgICAgICAgICAgICAgICAgICBl - YWNoX3N0YW5kYnlfbWdyLCBtb25pdG9yaW5nX2VuZHBvaW50X3BvcnQsIGlwX3R5cGUKICAgICAg - ICAgICAgICAgICAgICApCiAgICAgICAgICAgICAgICApCiAgICAgICAgZXhjZXB0OgogICAgICAg - ICAgICByYWlzZSBFeGVjdXRpb25GYWlsdXJlRXhjZXB0aW9uKAogICAgICAgICAgICAgICAgZiJD - b252ZXJzaW9uIG9mIGhvc3Q6IHtmYWlsZWRfaXB9IHRvIElQIGZhaWxlZC4gIgogICAgICAgICAg - ICAgICAgIlBsZWFzZSBlbnRlciB0aGUgSVAgYWRkcmVzc2VzIG9mIGFsbCB0aGUgY2VwaC1tZ3Jz - IHdpdGggdGhlICctLW1vbml0b3JpbmctZW5kcG9pbnQnIGZsYWciCiAgICAgICAgICAgICkKCiAg - ICAgICAgXywgXywgZXJyID0gc2VsZi5lbmRwb2ludF9kaWFsKG1vbml0b3JpbmdfZW5kcG9pbnQs - IGlwX3R5cGUpCiAgICAgICAgaWYgZXJyID09ICItMSI6CiAgICAgICAgICAgIHJhaXNlIEV4ZWN1 - dGlvbkZhaWx1cmVFeGNlcHRpb24oZXJyKQogICAgICAgICMgYWRkIHRoZSB2YWxpZGF0ZWQgYWN0 - aXZlIG1nciBJUCBpbnRvIHRoZSBmaXJzdCBpbmRleAogICAgICAgIG1ncl9pcHMuaW5zZXJ0KDAs - IG1vbml0b3JpbmdfZW5kcG9pbnRfaXApCiAgICAgICAgYWxsX21ncl9pcHNfc3RyID0gIiwiLmpv - aW4obWdyX2lwcykKICAgICAgICByZXR1cm4gYWxsX21ncl9pcHNfc3RyLCBtb25pdG9yaW5nX2Vu - ZHBvaW50X3BvcnQKCiAgICBkZWYgY2hlY2tfdXNlcl9leGlzdChzZWxmLCB1c2VyKToKICAgICAg - ICBjbWRfanNvbiA9IHsicHJlZml4IjogImF1dGggZ2V0IiwgImVudGl0eSI6IGYie3VzZXJ9Iiwg - ImZvcm1hdCI6ICJqc29uIn0KICAgICAgICByZXRfdmFsLCBqc29uX291dCwgXyA9IHNlbGYuX2Nv - bW1vbl9jbWRfanNvbl9nZW4oY21kX2pzb24pCiAgICAgICAgaWYgcmV0X3ZhbCAhPSAwIG9yIGxl - bihqc29uX291dCkgPT0gMDoKICAgICAgICAgICAgcmV0dXJuICIiCiAgICAgICAgcmV0dXJuIHN0 - cihqc29uX291dFswXVsia2V5Il0pCgogICAgZGVmIGdldF9jZXBoZnNfcHJvdmlzaW9uZXJfY2Fw - c19hbmRfZW50aXR5KHNlbGYpOgogICAgICAgIGVudGl0eSA9ICJjbGllbnQuY3NpLWNlcGhmcy1w - cm92aXNpb25lciIKICAgICAgICBjYXBzID0gewogICAgICAgICAgICAibW9uIjogImFsbG93IHIs - IGFsbG93IGNvbW1hbmQgJ29zZCBibG9ja2xpc3QnIiwKICAgICAgICAgICAgIm1nciI6ICJhbGxv - dyBydyIsCiAgICAgICAgICAgICJvc2QiOiAiYWxsb3cgcncgdGFnIGNlcGhmcyBtZXRhZGF0YT0q - IiwKICAgICAgICAgICAgIm1kcyI6ICJhbGxvdyAqIiwKICAgICAgICB9CiAgICAgICAgaWYgc2Vs - Zi5fYXJnX3BhcnNlci5yZXN0cmljdGVkX2F1dGhfcGVybWlzc2lvbjoKICAgICAgICAgICAgazhz - X2NsdXN0ZXJfbmFtZSA9IHNlbGYuX2FyZ19wYXJzZXIuazhzX2NsdXN0ZXJfbmFtZQogICAgICAg - ICAgICBpZiBrOHNfY2x1c3Rlcl9uYW1lID09ICIiOgogICAgICAgICAgICAgICAgcmFpc2UgRXhl - Y3V0aW9uRmFpbHVyZUV4Y2VwdGlvbigKICAgICAgICAgICAgICAgICAgICAiazhzX2NsdXN0ZXJf - bmFtZSBub3QgZm91bmQsIHBsZWFzZSBzZXQgdGhlICctLWs4cy1jbHVzdGVyLW5hbWUnIGZsYWci - CiAgICAgICAgICAgICAgICApCiAgICAgICAgICAgIGNlcGhmc19maWxlc3lzdGVtID0gc2VsZi5f - YXJnX3BhcnNlci5jZXBoZnNfZmlsZXN5c3RlbV9uYW1lCiAgICAgICAgICAgIGlmIGNlcGhmc19m - aWxlc3lzdGVtID09ICIiOgogICAgICAgICAgICAgICAgZW50aXR5ID0gZiJ7ZW50aXR5fS17azhz - X2NsdXN0ZXJfbmFtZX0iCiAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICBlbnRpdHkg - PSBmIntlbnRpdHl9LXtrOHNfY2x1c3Rlcl9uYW1lfS17Y2VwaGZzX2ZpbGVzeXN0ZW19IgogICAg - ICAgICAgICAgICAgY2Fwc1sib3NkIl0gPSBmImFsbG93IHJ3IHRhZyBjZXBoZnMgbWV0YWRhdGE9 - e2NlcGhmc19maWxlc3lzdGVtfSIKCiAgICAgICAgcmV0dXJuIGNhcHMsIGVudGl0eQoKICAgIGRl - ZiBnZXRfY2VwaGZzX25vZGVfY2Fwc19hbmRfZW50aXR5KHNlbGYpOgogICAgICAgIGVudGl0eSA9 - ICJjbGllbnQuY3NpLWNlcGhmcy1ub2RlIgogICAgICAgIGNhcHMgPSB7CiAgICAgICAgICAgICJt - b24iOiAiYWxsb3cgciwgYWxsb3cgY29tbWFuZCAnb3NkIGJsb2NrbGlzdCciLAogICAgICAgICAg - ICAibWdyIjogImFsbG93IHJ3IiwKICAgICAgICAgICAgIm9zZCI6ICJhbGxvdyBydyB0YWcgY2Vw - aGZzICo9KiIsCiAgICAgICAgICAgICJtZHMiOiAiYWxsb3cgcnciLAogICAgICAgIH0KICAgICAg - ICBpZiBzZWxmLl9hcmdfcGFyc2VyLnJlc3RyaWN0ZWRfYXV0aF9wZXJtaXNzaW9uOgogICAgICAg - ICAgICBrOHNfY2x1c3Rlcl9uYW1lID0gc2VsZi5fYXJnX3BhcnNlci5rOHNfY2x1c3Rlcl9uYW1l - CiAgICAgICAgICAgIGlmIGs4c19jbHVzdGVyX25hbWUgPT0gIiI6CiAgICAgICAgICAgICAgICBy - YWlzZSBFeGVjdXRpb25GYWlsdXJlRXhjZXB0aW9uKAogICAgICAgICAgICAgICAgICAgICJrOHNf - Y2x1c3Rlcl9uYW1lIG5vdCBmb3VuZCwgcGxlYXNlIHNldCB0aGUgJy0tazhzLWNsdXN0ZXItbmFt - ZScgZmxhZyIKICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgY2VwaGZzX2ZpbGVzeXN0ZW0g - PSBzZWxmLl9hcmdfcGFyc2VyLmNlcGhmc19maWxlc3lzdGVtX25hbWUKICAgICAgICAgICAgaWYg - Y2VwaGZzX2ZpbGVzeXN0ZW0gPT0gIiI6CiAgICAgICAgICAgICAgICBlbnRpdHkgPSBmIntlbnRp - dHl9LXtrOHNfY2x1c3Rlcl9uYW1lfSIKICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAg - IGVudGl0eSA9IGYie2VudGl0eX0te2s4c19jbHVzdGVyX25hbWV9LXtjZXBoZnNfZmlsZXN5c3Rl - bX0iCiAgICAgICAgICAgICAgICBjYXBzWyJvc2QiXSA9IGYiYWxsb3cgcncgdGFnIGNlcGhmcyAq - PXtjZXBoZnNfZmlsZXN5c3RlbX0iCgogICAgICAgIHJldHVybiBjYXBzLCBlbnRpdHkKCiAgICBk - ZWYgZ2V0X2VudGl0eSgKICAgICAgICBzZWxmLAogICAgICAgIGVudGl0eSwKICAgICAgICByYmRf - cG9vbF9uYW1lLAogICAgICAgIGFsaWFzX3JiZF9wb29sX25hbWUsCiAgICAgICAgazhzX2NsdXN0 - ZXJfbmFtZSwKICAgICAgICByYWRvc19uYW1lc3BhY2UsCiAgICApOgogICAgICAgIGlmICgKICAg - ICAgICAgICAgcmJkX3Bvb2xfbmFtZS5jb3VudCgiLiIpICE9IDAKICAgICAgICAgICAgb3IgcmJk - X3Bvb2xfbmFtZS5jb3VudCgiXyIpICE9IDAKICAgICAgICAgICAgb3IgYWxpYXNfcmJkX3Bvb2xf - bmFtZSAhPSAiIgogICAgICAgICAgICAjIGNoZWNraW5nIGFsaWFzX3JiZF9wb29sX25hbWUgaXMg - bm90IGVtcHR5IGFzIHRoZXJlIG1heWJlIGEgc3BlY2lhbCBjaGFyYWN0ZXIgdXNlZCBvdGhlciB0 - aGFuIC4gb3IgXwogICAgICAgICk6CiAgICAgICAgICAgIGlmIGFsaWFzX3JiZF9wb29sX25hbWUg - PT0gIiI6CiAgICAgICAgICAgICAgICByYWlzZSBFeGVjdXRpb25GYWlsdXJlRXhjZXB0aW9uKAog - ICAgICAgICAgICAgICAgICAgICJwbGVhc2Ugc2V0IHRoZSAnLS1hbGlhcy1yYmQtZGF0YS1wb29s - LW5hbWUnIGZsYWcgYXMgdGhlIHJiZCBkYXRhIHBvb2wgbmFtZSBjb250YWlucyAnLicgb3IgJ18n - IgogICAgICAgICAgICAgICAgKQogICAgICAgICAgICBpZiAoCiAgICAgICAgICAgICAgICBhbGlh - c19yYmRfcG9vbF9uYW1lLmNvdW50KCIuIikgIT0gMAogICAgICAgICAgICAgICAgb3IgYWxpYXNf - cmJkX3Bvb2xfbmFtZS5jb3VudCgiXyIpICE9IDAKICAgICAgICAgICAgKToKICAgICAgICAgICAg - ICAgIHJhaXNlIEV4ZWN1dGlvbkZhaWx1cmVFeGNlcHRpb24oCiAgICAgICAgICAgICAgICAgICAg - IictLWFsaWFzLXJiZC1kYXRhLXBvb2wtbmFtZScgZmxhZyB2YWx1ZSBzaG91bGQgbm90IGNvbnRh - aW4gJy4nIG9yICdfJyIKICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgZW50aXR5ID0gZiJ7 - ZW50aXR5fS17azhzX2NsdXN0ZXJfbmFtZX0te2FsaWFzX3JiZF9wb29sX25hbWV9IgogICAgICAg - IGVsc2U6CiAgICAgICAgICAgIGVudGl0eSA9IGYie2VudGl0eX0te2s4c19jbHVzdGVyX25hbWV9 - LXtyYmRfcG9vbF9uYW1lfSIKCiAgICAgICAgaWYgcmFkb3NfbmFtZXNwYWNlOgogICAgICAgICAg - ICBlbnRpdHkgPSBmIntlbnRpdHl9LXtyYWRvc19uYW1lc3BhY2V9IgogICAgICAgIHJldHVybiBl - bnRpdHkKCiAgICBkZWYgZ2V0X3JiZF9wcm92aXNpb25lcl9jYXBzX2FuZF9lbnRpdHkoc2VsZik6 - CiAgICAgICAgZW50aXR5ID0gImNsaWVudC5jc2ktcmJkLXByb3Zpc2lvbmVyIgogICAgICAgIGNh - cHMgPSB7CiAgICAgICAgICAgICJtb24iOiAicHJvZmlsZSByYmQsIGFsbG93IGNvbW1hbmQgJ29z - ZCBibG9ja2xpc3QnIiwKICAgICAgICAgICAgIm1nciI6ICJhbGxvdyBydyIsCiAgICAgICAgICAg - ICJvc2QiOiAicHJvZmlsZSByYmQiLAogICAgICAgIH0KICAgICAgICBpZiBzZWxmLl9hcmdfcGFy - c2VyLnJlc3RyaWN0ZWRfYXV0aF9wZXJtaXNzaW9uOgogICAgICAgICAgICByYmRfcG9vbF9uYW1l - ID0gc2VsZi5fYXJnX3BhcnNlci5yYmRfZGF0YV9wb29sX25hbWUKICAgICAgICAgICAgYWxpYXNf - cmJkX3Bvb2xfbmFtZSA9IHNlbGYuX2FyZ19wYXJzZXIuYWxpYXNfcmJkX2RhdGFfcG9vbF9uYW1l - CiAgICAgICAgICAgIGs4c19jbHVzdGVyX25hbWUgPSBzZWxmLl9hcmdfcGFyc2VyLms4c19jbHVz - dGVyX25hbWUKICAgICAgICAgICAgcmFkb3NfbmFtZXNwYWNlID0gc2VsZi5fYXJnX3BhcnNlci5y - YWRvc19uYW1lc3BhY2UKICAgICAgICAgICAgaWYgcmJkX3Bvb2xfbmFtZSA9PSAiIjoKICAgICAg - ICAgICAgICAgIHJhaXNlIEV4ZWN1dGlvbkZhaWx1cmVFeGNlcHRpb24oCiAgICAgICAgICAgICAg - ICAgICAgIm1hbmRhdG9yeSBmbGFnIG5vdCBmb3VuZCwgcGxlYXNlIHNldCB0aGUgJy0tcmJkLWRh - dGEtcG9vbC1uYW1lJyBmbGFnIgogICAgICAgICAgICAgICAgKQogICAgICAgICAgICBpZiBrOHNf - Y2x1c3Rlcl9uYW1lID09ICIiOgogICAgICAgICAgICAgICAgcmFpc2UgRXhlY3V0aW9uRmFpbHVy - ZUV4Y2VwdGlvbigKICAgICAgICAgICAgICAgICAgICAibWFuZGF0b3J5IGZsYWcgbm90IGZvdW5k - LCBwbGVhc2Ugc2V0IHRoZSAnLS1rOHMtY2x1c3Rlci1uYW1lJyBmbGFnIgogICAgICAgICAgICAg - ICAgKQogICAgICAgICAgICBlbnRpdHkgPSBzZWxmLmdldF9lbnRpdHkoCiAgICAgICAgICAgICAg - ICBlbnRpdHksCiAgICAgICAgICAgICAgICByYmRfcG9vbF9uYW1lLAogICAgICAgICAgICAgICAg - YWxpYXNfcmJkX3Bvb2xfbmFtZSwKICAgICAgICAgICAgICAgIGs4c19jbHVzdGVyX25hbWUsCiAg - ICAgICAgICAgICAgICByYWRvc19uYW1lc3BhY2UsCiAgICAgICAgICAgICkKICAgICAgICAgICAg - aWYgcmFkb3NfbmFtZXNwYWNlICE9ICIiOgogICAgICAgICAgICAgICAgY2Fwc1sib3NkIl0gPSAo - CiAgICAgICAgICAgICAgICAgICAgZiJwcm9maWxlIHJiZCBwb29sPXtyYmRfcG9vbF9uYW1lfSBu - YW1lc3BhY2U9e3JhZG9zX25hbWVzcGFjZX0iCiAgICAgICAgICAgICAgICApCiAgICAgICAgICAg - IGVsc2U6CiAgICAgICAgICAgICAgICBjYXBzWyJvc2QiXSA9IGYicHJvZmlsZSByYmQgcG9vbD17 - cmJkX3Bvb2xfbmFtZX0iCgogICAgICAgIHJldHVybiBjYXBzLCBlbnRpdHkKCiAgICBkZWYgZ2V0 - X3JiZF9ub2RlX2NhcHNfYW5kX2VudGl0eShzZWxmKToKICAgICAgICBlbnRpdHkgPSAiY2xpZW50 - LmNzaS1yYmQtbm9kZSIKICAgICAgICBjYXBzID0gewogICAgICAgICAgICAibW9uIjogInByb2Zp - bGUgcmJkLCBhbGxvdyBjb21tYW5kICdvc2QgYmxvY2tsaXN0JyIsCiAgICAgICAgICAgICJvc2Qi - OiAicHJvZmlsZSByYmQiLAogICAgICAgIH0KICAgICAgICBpZiBzZWxmLl9hcmdfcGFyc2VyLnJl - c3RyaWN0ZWRfYXV0aF9wZXJtaXNzaW9uOgogICAgICAgICAgICByYmRfcG9vbF9uYW1lID0gc2Vs - Zi5fYXJnX3BhcnNlci5yYmRfZGF0YV9wb29sX25hbWUKICAgICAgICAgICAgYWxpYXNfcmJkX3Bv - b2xfbmFtZSA9IHNlbGYuX2FyZ19wYXJzZXIuYWxpYXNfcmJkX2RhdGFfcG9vbF9uYW1lCiAgICAg - ICAgICAgIGs4c19jbHVzdGVyX25hbWUgPSBzZWxmLl9hcmdfcGFyc2VyLms4c19jbHVzdGVyX25h - bWUKICAgICAgICAgICAgcmFkb3NfbmFtZXNwYWNlID0gc2VsZi5fYXJnX3BhcnNlci5yYWRvc19u - YW1lc3BhY2UKICAgICAgICAgICAgaWYgcmJkX3Bvb2xfbmFtZSA9PSAiIjoKICAgICAgICAgICAg - ICAgIHJhaXNlIEV4ZWN1dGlvbkZhaWx1cmVFeGNlcHRpb24oCiAgICAgICAgICAgICAgICAgICAg - Im1hbmRhdG9yeSBmbGFnIG5vdCBmb3VuZCwgcGxlYXNlIHNldCB0aGUgJy0tcmJkLWRhdGEtcG9v - bC1uYW1lJyBmbGFnIgogICAgICAgICAgICAgICAgKQogICAgICAgICAgICBpZiBrOHNfY2x1c3Rl - cl9uYW1lID09ICIiOgogICAgICAgICAgICAgICAgcmFpc2UgRXhlY3V0aW9uRmFpbHVyZUV4Y2Vw - dGlvbigKICAgICAgICAgICAgICAgICAgICAibWFuZGF0b3J5IGZsYWcgbm90IGZvdW5kLCBwbGVh - c2Ugc2V0IHRoZSAnLS1rOHMtY2x1c3Rlci1uYW1lJyBmbGFnIgogICAgICAgICAgICAgICAgKQog - ICAgICAgICAgICBlbnRpdHkgPSBzZWxmLmdldF9lbnRpdHkoCiAgICAgICAgICAgICAgICBlbnRp - dHksCiAgICAgICAgICAgICAgICByYmRfcG9vbF9uYW1lLAogICAgICAgICAgICAgICAgYWxpYXNf - cmJkX3Bvb2xfbmFtZSwKICAgICAgICAgICAgICAgIGs4c19jbHVzdGVyX25hbWUsCiAgICAgICAg - ICAgICAgICByYWRvc19uYW1lc3BhY2UsCiAgICAgICAgICAgICkKICAgICAgICAgICAgaWYgcmFk - b3NfbmFtZXNwYWNlICE9ICIiOgogICAgICAgICAgICAgICAgY2Fwc1sib3NkIl0gPSAoCiAgICAg - ICAgICAgICAgICAgICAgZiJwcm9maWxlIHJiZCBwb29sPXtyYmRfcG9vbF9uYW1lfSBuYW1lc3Bh - Y2U9e3JhZG9zX25hbWVzcGFjZX0iCiAgICAgICAgICAgICAgICApCiAgICAgICAgICAgIGVsc2U6 - CiAgICAgICAgICAgICAgICBjYXBzWyJvc2QiXSA9IGYicHJvZmlsZSByYmQgcG9vbD17cmJkX3Bv - b2xfbmFtZX0iCgogICAgICAgIHJldHVybiBjYXBzLCBlbnRpdHkKCiAgICBkZWYgZ2V0X2RlZmF1 - bHRVc2VyX2NhcHNfYW5kX2VudGl0eShzZWxmKToKICAgICAgICBlbnRpdHkgPSBzZWxmLnJ1bl9h - c191c2VyCiAgICAgICAgY2FwcyA9IHsKICAgICAgICAgICAgIm1vbiI6ICJhbGxvdyByLCBhbGxv - dyBjb21tYW5kIHF1b3J1bV9zdGF0dXMsIGFsbG93IGNvbW1hbmQgdmVyc2lvbiIsCiAgICAgICAg - ICAgICJtZ3IiOiAiYWxsb3cgY29tbWFuZCBjb25maWciLAogICAgICAgICAgICAib3NkIjogZiJw - cm9maWxlIHJiZC1yZWFkLW9ubHksIGFsbG93IHJ3eCBwb29sPXtzZWxmLl9hcmdfcGFyc2VyLnJn - d19wb29sX3ByZWZpeH0ucmd3Lm1ldGEsIGFsbG93IHIgcG9vbD0ucmd3LnJvb3QsIGFsbG93IHJ3 - IHBvb2w9e3NlbGYuX2FyZ19wYXJzZXIucmd3X3Bvb2xfcHJlZml4fS5yZ3cuY29udHJvbCwgYWxs - b3cgcnggcG9vbD17c2VsZi5fYXJnX3BhcnNlci5yZ3dfcG9vbF9wcmVmaXh9LnJndy5sb2csIGFs - bG93IHggcG9vbD17c2VsZi5fYXJnX3BhcnNlci5yZ3dfcG9vbF9wcmVmaXh9LnJndy5idWNrZXRz - LmluZGV4IiwKICAgICAgICAgICAgIm1kcyI6ICJhbGxvdyAqIiwKICAgICAgICB9CgogICAgICAg - IHJldHVybiBjYXBzLCBlbnRpdHkKCiAgICBkZWYgZ2V0X2NhcHNfYW5kX2VudGl0eShzZWxmLCB1 - c2VyX25hbWUpOgogICAgICAgIGlmICJjbGllbnQuY3NpLWNlcGhmcy1wcm92aXNpb25lciIgaW4g - dXNlcl9uYW1lOgogICAgICAgICAgICBpZiAiY2xpZW50LmNzaS1jZXBoZnMtcHJvdmlzaW9uZXIi - ICE9IHVzZXJfbmFtZToKICAgICAgICAgICAgICAgIHNlbGYuX2FyZ19wYXJzZXIucmVzdHJpY3Rl - ZF9hdXRoX3Blcm1pc3Npb24gPSBUcnVlCiAgICAgICAgICAgIHJldHVybiBzZWxmLmdldF9jZXBo - ZnNfcHJvdmlzaW9uZXJfY2Fwc19hbmRfZW50aXR5KCkKICAgICAgICBpZiAiY2xpZW50LmNzaS1j - ZXBoZnMtbm9kZSIgaW4gdXNlcl9uYW1lOgogICAgICAgICAgICBpZiAiY2xpZW50LmNzaS1jZXBo - ZnMtbm9kZSIgIT0gdXNlcl9uYW1lOgogICAgICAgICAgICAgICAgc2VsZi5fYXJnX3BhcnNlci5y - ZXN0cmljdGVkX2F1dGhfcGVybWlzc2lvbiA9IFRydWUKICAgICAgICAgICAgcmV0dXJuIHNlbGYu - Z2V0X2NlcGhmc19ub2RlX2NhcHNfYW5kX2VudGl0eSgpCiAgICAgICAgaWYgImNsaWVudC5jc2kt - cmJkLXByb3Zpc2lvbmVyIiBpbiB1c2VyX25hbWU6CiAgICAgICAgICAgIGlmICJjbGllbnQuY3Np - LXJiZC1wcm92aXNpb25lciIgIT0gdXNlcl9uYW1lOgogICAgICAgICAgICAgICAgc2VsZi5fYXJn - X3BhcnNlci5yZXN0cmljdGVkX2F1dGhfcGVybWlzc2lvbiA9IFRydWUKICAgICAgICAgICAgcmV0 - dXJuIHNlbGYuZ2V0X3JiZF9wcm92aXNpb25lcl9jYXBzX2FuZF9lbnRpdHkoKQogICAgICAgIGlm - ICJjbGllbnQuY3NpLXJiZC1ub2RlIiBpbiB1c2VyX25hbWU6CiAgICAgICAgICAgIGlmICJjbGll - bnQuY3NpLXJiZC1ub2RlIiAhPSB1c2VyX25hbWU6CiAgICAgICAgICAgICAgICBzZWxmLl9hcmdf - cGFyc2VyLnJlc3RyaWN0ZWRfYXV0aF9wZXJtaXNzaW9uID0gVHJ1ZQogICAgICAgICAgICByZXR1 - cm4gc2VsZi5nZXRfcmJkX25vZGVfY2Fwc19hbmRfZW50aXR5KCkKICAgICAgICBpZiAiY2xpZW50 - LmhlYWx0aGNoZWNrZXIiIGluIHVzZXJfbmFtZToKICAgICAgICAgICAgaWYgImNsaWVudC5oZWFs - dGhjaGVja2VyIiAhPSB1c2VyX25hbWU6CiAgICAgICAgICAgICAgICBzZWxmLl9hcmdfcGFyc2Vy - LnJlc3RyaWN0ZWRfYXV0aF9wZXJtaXNzaW9uID0gVHJ1ZQogICAgICAgICAgICByZXR1cm4gc2Vs - Zi5nZXRfZGVmYXVsdFVzZXJfY2Fwc19hbmRfZW50aXR5KCkKCiAgICAgICAgcmFpc2UgRXhlY3V0 - aW9uRmFpbHVyZUV4Y2VwdGlvbigKICAgICAgICAgICAgZiJubyB1c2VyIGZvdW5kIHdpdGggdXNl - cl9uYW1lOiB7dXNlcl9uYW1lfSwgIgogICAgICAgICAgICAiZ2V0X2NhcHNfYW5kX2VudGl0eSBj - b21tYW5kIGZhaWxlZC5cbiIKICAgICAgICApCgogICAgZGVmIGNyZWF0ZV9jZXBoQ1NJS2V5cmlu - Z191c2VyKHNlbGYsIHVzZXIpOgogICAgICAgICIiIgogICAgICAgIGNvbW1hbmQ6IGNlcGggYXV0 - aCBnZXQtb3ItY3JlYXRlIGNsaWVudC5jc2ktY2VwaGZzLXByb3Zpc2lvbmVyIG1vbiAnYWxsb3cg - cicgbWdyICdhbGxvdyBydycgb3NkICdhbGxvdyBydyB0YWcgY2VwaGZzIG1ldGFkYXRhPSonCiAg - ICAgICAgIiIiCiAgICAgICAgY2FwcywgZW50aXR5ID0gc2VsZi5nZXRfY2Fwc19hbmRfZW50aXR5 - KHVzZXIpCiAgICAgICAgY21kX2pzb24gPSB7CiAgICAgICAgICAgICJwcmVmaXgiOiAiYXV0aCBn - ZXQtb3ItY3JlYXRlIiwKICAgICAgICAgICAgImVudGl0eSI6IGVudGl0eSwKICAgICAgICAgICAg - ImNhcHMiOiBbY2FwIGZvciBjYXBfbGlzdCBpbiBsaXN0KGNhcHMuaXRlbXMoKSkgZm9yIGNhcCBp - biBjYXBfbGlzdF0sCiAgICAgICAgICAgICJmb3JtYXQiOiAianNvbiIsCiAgICAgICAgfQoKICAg - ICAgICBpZiBzZWxmLl9hcmdfcGFyc2VyLmRyeV9ydW46CiAgICAgICAgICAgIHJldHVybiAoCiAg - ICAgICAgICAgICAgICBzZWxmLmRyeV9ydW4oCiAgICAgICAgICAgICAgICAgICAgImNlcGggIgog - ICAgICAgICAgICAgICAgICAgICsgY21kX2pzb25bInByZWZpeCJdCiAgICAgICAgICAgICAgICAg - ICAgKyAiICIKICAgICAgICAgICAgICAgICAgICArIGNtZF9qc29uWyJlbnRpdHkiXQogICAgICAg - ICAgICAgICAgICAgICsgIiAiCiAgICAgICAgICAgICAgICAgICAgKyAiICIuam9pbihjbWRfanNv - blsiY2FwcyJdKQogICAgICAgICAgICAgICAgKSwKICAgICAgICAgICAgICAgICIiLAogICAgICAg - ICAgICApCiAgICAgICAgIyBjaGVjayBpZiB1c2VyIGFscmVhZHkgZXhpc3QKICAgICAgICB1c2Vy - X2tleSA9IHNlbGYuY2hlY2tfdXNlcl9leGlzdChlbnRpdHkpCiAgICAgICAgaWYgdXNlcl9rZXkg - IT0gIiI6CiAgICAgICAgICAgIHJldHVybiB1c2VyX2tleSwgZiJ7ZW50aXR5LnNwbGl0KCcuJywg - MSlbMV19IgogICAgICAgICAgICAjIGVudGl0eS5zcGxpdCgnLicsMSlbMV0gdG8gcmVuYW1lIGVu - dGl0eShjbGllbnQuY3NpLXJiZC1ub2RlKSBhcyBjc2ktcmJkLW5vZGUKCiAgICAgICAgcmV0X3Zh - bCwganNvbl9vdXQsIGVycl9tc2cgPSBzZWxmLl9jb21tb25fY21kX2pzb25fZ2VuKGNtZF9qc29u - KQogICAgICAgICMgaWYgdGhlcmUgaXMgYW4gdW5zdWNjZXNzZnVsIGF0dGVtcHQsCiAgICAgICAg - aWYgcmV0X3ZhbCAhPSAwIG9yIGxlbihqc29uX291dCkgPT0gMDoKICAgICAgICAgICAgcmFpc2Ug - RXhlY3V0aW9uRmFpbHVyZUV4Y2VwdGlvbigKICAgICAgICAgICAgICAgIGYiJ2F1dGggZ2V0LW9y - LWNyZWF0ZSB7dXNlcn0nIGNvbW1hbmQgZmFpbGVkLlxuIgogICAgICAgICAgICAgICAgZiJFcnJv - cjoge2Vycl9tc2cgaWYgcmV0X3ZhbCAhPSAwIGVsc2Ugc2VsZi5FTVBUWV9PVVRQVVRfTElTVH0i - CiAgICAgICAgICAgICkKICAgICAgICByZXR1cm4gc3RyKGpzb25fb3V0WzBdWyJrZXkiXSksIGYi - e2VudGl0eS5zcGxpdCgnLicsIDEpWzFdfSIKICAgICAgICAjIGVudGl0eS5zcGxpdCgnLicsMSlb - MV0gdG8gcmVuYW1lIGVudGl0eShjbGllbnQuY3NpLXJiZC1ub2RlKSBhcyBjc2ktcmJkLW5vZGUK - CiAgICBkZWYgZ2V0X2NlcGhmc19kYXRhX3Bvb2xfZGV0YWlscyhzZWxmKToKICAgICAgICBjbWRf - anNvbiA9IHsicHJlZml4IjogImZzIGxzIiwgImZvcm1hdCI6ICJqc29uIn0KICAgICAgICBpZiBz - ZWxmLl9hcmdfcGFyc2VyLmRyeV9ydW46CiAgICAgICAgICAgIHJldHVybiBzZWxmLmRyeV9ydW4o - ImNlcGggIiArIGNtZF9qc29uWyJwcmVmaXgiXSkKICAgICAgICByZXRfdmFsLCBqc29uX291dCwg - ZXJyX21zZyA9IHNlbGYuX2NvbW1vbl9jbWRfanNvbl9nZW4oY21kX2pzb24pCiAgICAgICAgIyBp - ZiB0aGVyZSBpcyBhbiB1bnN1Y2Nlc3NmdWwgYXR0ZW1wdCwgcmVwb3J0IGFuIGVycm9yCiAgICAg - ICAgaWYgcmV0X3ZhbCAhPSAwOgogICAgICAgICAgICAjIGlmIGZzIGFuZCBkYXRhX3Bvb2wgYXJn - dW1lbnRzIGFyZSBub3Qgc2V0LCBzaWxlbnRseSByZXR1cm4KICAgICAgICAgICAgaWYgKAogICAg - ICAgICAgICAgICAgc2VsZi5fYXJnX3BhcnNlci5jZXBoZnNfZmlsZXN5c3RlbV9uYW1lID09ICIi - CiAgICAgICAgICAgICAgICBhbmQgc2VsZi5fYXJnX3BhcnNlci5jZXBoZnNfZGF0YV9wb29sX25h - bWUgPT0gIiIKICAgICAgICAgICAgKToKICAgICAgICAgICAgICAgIHJldHVybgogICAgICAgICAg - ICAjIGlmIHVzZXIgaGFzIHByb3ZpZGVkIGFueSBvZiB0aGUKICAgICAgICAgICAgIyAnLS1jZXBo - ZnMtZmlsZXN5c3RlbS1uYW1lJyBvciAnLS1jZXBoZnMtZGF0YS1wb29sLW5hbWUnIGFyZ3VtZW50 - cywKICAgICAgICAgICAgIyByYWlzZSBhbiBleGNlcHRpb24gYXMgd2UgYXJlIHVuYWJsZSB0byB2 - ZXJpZnkgdGhlIGFyZ3MKICAgICAgICAgICAgcmFpc2UgRXhlY3V0aW9uRmFpbHVyZUV4Y2VwdGlv - bigKICAgICAgICAgICAgICAgIGYiJ2ZzIGxzJyBjZXBoIGNhbGwgZmFpbGVkIHdpdGggZXJyb3I6 - IHtlcnJfbXNnfSIKICAgICAgICAgICAgKQoKICAgICAgICBtYXRjaGluZ19qc29uX291dCA9IHt9 - CiAgICAgICAgIyBpZiAnLS1jZXBoZnMtZmlsZXN5c3RlbS1uYW1lJyBhcmd1bWVudCBpcyBwcm92 - aWRlZCwKICAgICAgICAjIGNoZWNrIHdoZXRoZXIgdGhlIHByb3ZpZGVkIGZpbGVzeXN0ZW0tbmFt - ZSBleGlzdHMgb3Igbm90CiAgICAgICAgaWYgc2VsZi5fYXJnX3BhcnNlci5jZXBoZnNfZmlsZXN5 - c3RlbV9uYW1lOgogICAgICAgICAgICAjIGdldCB0aGUgbWF0Y2hpbmcgbGlzdAogICAgICAgICAg - ICBtYXRjaGluZ19qc29uX291dF9saXN0ID0gWwogICAgICAgICAgICAgICAgbWF0Y2hlZAogICAg - ICAgICAgICAgICAgZm9yIG1hdGNoZWQgaW4ganNvbl9vdXQKICAgICAgICAgICAgICAgIGlmIHN0 - cihtYXRjaGVkWyJuYW1lIl0pID09IHNlbGYuX2FyZ19wYXJzZXIuY2VwaGZzX2ZpbGVzeXN0ZW1f - bmFtZQogICAgICAgICAgICBdCiAgICAgICAgICAgICMgdW5hYmxlIHRvIGZpbmQgYSBtYXRjaGlu - ZyBmcy1uYW1lLCByYWlzZSBhbiBlcnJvcgogICAgICAgICAgICBpZiBsZW4obWF0Y2hpbmdfanNv - bl9vdXRfbGlzdCkgPT0gMDoKICAgICAgICAgICAgICAgIHJhaXNlIEV4ZWN1dGlvbkZhaWx1cmVF - eGNlcHRpb24oCiAgICAgICAgICAgICAgICAgICAgZiJGaWxlc3lzdGVtIHByb3ZpZGVkLCAne3Nl - bGYuX2FyZ19wYXJzZXIuY2VwaGZzX2ZpbGVzeXN0ZW1fbmFtZX0nLCAiCiAgICAgICAgICAgICAg - ICAgICAgZiJpcyBub3QgZm91bmQgaW4gdGhlIGZzLWxpc3Q6IHtbc3RyKHhbJ25hbWUnXSkgZm9y - IHggaW4ganNvbl9vdXRdfSIKICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgbWF0Y2hpbmdf - anNvbl9vdXQgPSBtYXRjaGluZ19qc29uX291dF9saXN0WzBdCiAgICAgICAgIyBpZiBjZXBoZnMg - ZmlsZXN5c3RlbSBuYW1lIGlzIG5vdCBwcm92aWRlZCwKICAgICAgICAjIHRyeSB0byBnZXQgYSBk - ZWZhdWx0IGZzIG5hbWUgYnkgZG9pbmcgdGhlIGZvbGxvd2luZwogICAgICAgIGVsc2U6CiAgICAg - ICAgICAgICMgYS4gY2hlY2sgaWYgdGhlcmUgaXMgb25seSBvbmUgZmlsZXN5c3RlbSBpcyBwcmVz - ZW50CiAgICAgICAgICAgIGlmIGxlbihqc29uX291dCkgPT0gMToKICAgICAgICAgICAgICAgIG1h - dGNoaW5nX2pzb25fb3V0ID0ganNvbl9vdXRbMF0KICAgICAgICAgICAgIyBiLiBvciBlbHNlLCBj - aGVjayBpZiBkYXRhX3Bvb2wgbmFtZSBpcyBwcm92aWRlZAogICAgICAgICAgICBlbGlmIHNlbGYu - X2FyZ19wYXJzZXIuY2VwaGZzX2RhdGFfcG9vbF9uYW1lOgogICAgICAgICAgICAgICAgIyBhbmQg - aWYgcHJlc2VudCwgY2hlY2sgd2hldGhlciB0aGVyZSBleGlzdHMgYSBmcyB3aGljaCBoYXMgdGhl - IGRhdGFfcG9vbAogICAgICAgICAgICAgICAgZm9yIGVhY2hKIGluIGpzb25fb3V0OgogICAgICAg - ICAgICAgICAgICAgIGlmIHNlbGYuX2FyZ19wYXJzZXIuY2VwaGZzX2RhdGFfcG9vbF9uYW1lIGlu - IGVhY2hKWyJkYXRhX3Bvb2xzIl06CiAgICAgICAgICAgICAgICAgICAgICAgIG1hdGNoaW5nX2pz - b25fb3V0ID0gZWFjaEoKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWsKICAgICAgICAgICAg - ICAgICMgaWYgdGhlcmUgaXMgbm8gbWF0Y2hpbmcgZnMgZXhpc3RzLCB0aGF0IG1lYW5zIHByb3Zp - ZGVkIGRhdGFfcG9vbCBuYW1lIGlzIGludmFsaWQKICAgICAgICAgICAgICAgIGlmIG5vdCBtYXRj - aGluZ19qc29uX291dDoKICAgICAgICAgICAgICAgICAgICByYWlzZSBFeGVjdXRpb25GYWlsdXJl - RXhjZXB0aW9uKAogICAgICAgICAgICAgICAgICAgICAgICBmIlByb3ZpZGVkIGRhdGFfcG9vbCBu - YW1lLCB7c2VsZi5fYXJnX3BhcnNlci5jZXBoZnNfZGF0YV9wb29sX25hbWV9LCIKICAgICAgICAg - ICAgICAgICAgICAgICAgIiBkb2VzIG5vdCBleGlzdHMiCiAgICAgICAgICAgICAgICAgICAgKQog - ICAgICAgICAgICAjIGMuIGlmIG5vdGhpbmcgaXMgc2V0IGFuZCBjb3VsZG4ndCBmaW5kIGEgZGVm - YXVsdCwKICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgICMganVzdCByZXR1cm4gc2ls - ZW50bHkKICAgICAgICAgICAgICAgIHJldHVybgoKICAgICAgICBpZiBtYXRjaGluZ19qc29uX291 - dDoKICAgICAgICAgICAgc2VsZi5fYXJnX3BhcnNlci5jZXBoZnNfZmlsZXN5c3RlbV9uYW1lID0g - c3RyKG1hdGNoaW5nX2pzb25fb3V0WyJuYW1lIl0pCiAgICAgICAgICAgIHNlbGYuX2FyZ19wYXJz - ZXIuY2VwaGZzX21ldGFkYXRhX3Bvb2xfbmFtZSA9IHN0cigKICAgICAgICAgICAgICAgIG1hdGNo - aW5nX2pzb25fb3V0WyJtZXRhZGF0YV9wb29sIl0KICAgICAgICAgICAgKQoKICAgICAgICBpZiBp - c2luc3RhbmNlKG1hdGNoaW5nX2pzb25fb3V0WyJkYXRhX3Bvb2xzIl0sIGxpc3QpOgogICAgICAg - ICAgICAjIGlmIHRoZSB1c2VyIGhhcyBhbHJlYWR5IHByb3ZpZGVkIGRhdGEtcG9vbC1uYW1lLAog - ICAgICAgICAgICAjIHRocm91Z2ggLS1jZXBoZnMtZGF0YS1wb29sLW5hbWUKICAgICAgICAgICAg - aWYgc2VsZi5fYXJnX3BhcnNlci5jZXBoZnNfZGF0YV9wb29sX25hbWU6CiAgICAgICAgICAgICAg - ICAjIGlmIHRoZSBwcm92aWRlZCBuYW1lIGlzIG5vdCBtYXRjaGluZyB3aXRoIHRoZSBvbmUgaW4g - dGhlIGxpc3QKICAgICAgICAgICAgICAgIGlmICgKICAgICAgICAgICAgICAgICAgICBzZWxmLl9h - cmdfcGFyc2VyLmNlcGhmc19kYXRhX3Bvb2xfbmFtZQogICAgICAgICAgICAgICAgICAgIG5vdCBp - biBtYXRjaGluZ19qc29uX291dFsiZGF0YV9wb29scyJdCiAgICAgICAgICAgICAgICApOgogICAg + ICAgICAgbWV0YWRhdGFfcG9vbF9leGlzdCwgcG9vbF9leGlzdCA9IEZhbHNlLCBGYWxzZQoKICAg + ICAgICAgICAgZm9yIGtleSBpbiBqc29uX291dFsicG9vbHMiXToKICAgICAgICAgICAgICAgICMg + aWYgZXJhc3VyZV9jb2RlX3Byb2ZpbGUgaXMgZW1wdHkgYW5kIHBvb2wgbmFtZSBleGlzdHMgdGhl + biBpdCByZXBsaWNhIHBvb2wKICAgICAgICAgICAgICAgIGlmICgKICAgICAgICAgICAgICAgICAg + ICBrZXlbImVyYXN1cmVfY29kZV9wcm9maWxlIl0gPT0gIiIKICAgICAgICAgICAgICAgICAgICBh + bmQga2V5WyJwb29sX25hbWUiXSA9PSByYmRfbWV0YWRhdGFfZWNfcG9vbF9uYW1lCiAgICAgICAg + ICAgICAgICApOgogICAgICAgICAgICAgICAgICAgIG1ldGFkYXRhX3Bvb2xfZXhpc3QgPSBUcnVl + CiAgICAgICAgICAgICAgICAjIGlmIGVyYXN1cmVfY29kZV9wcm9maWxlIGlzIG5vdCBlbXB0eSBh + bmQgcG9vbCBuYW1lIGV4aXN0cyB0aGVuIGl0IGlzIGVjIHBvb2wKICAgICAgICAgICAgICAgIGlm + IGtleVsiZXJhc3VyZV9jb2RlX3Byb2ZpbGUiXSBhbmQga2V5WyJwb29sX25hbWUiXSA9PSByYmRf + cG9vbF9uYW1lOgogICAgICAgICAgICAgICAgICAgIHBvb2xfZXhpc3QgPSBUcnVlCgogICAgICAg + ICAgICBpZiBub3QgbWV0YWRhdGFfcG9vbF9leGlzdDoKICAgICAgICAgICAgICAgIHJhaXNlIEV4 + ZWN1dGlvbkZhaWx1cmVFeGNlcHRpb24oCiAgICAgICAgICAgICAgICAgICAgIlByb3ZpZGVkIHJi + ZF9lY19tZXRhZGF0YV9wb29sIG5hbWUsIgogICAgICAgICAgICAgICAgICAgIGYiIHtyYmRfbWV0 + YWRhdGFfZWNfcG9vbF9uYW1lfSwgZG9lcyBub3QgZXhpc3QiCiAgICAgICAgICAgICAgICApCiAg + ICAgICAgICAgIGlmIG5vdCBwb29sX2V4aXN0OgogICAgICAgICAgICAgICAgcmFpc2UgRXhlY3V0 + aW9uRmFpbHVyZUV4Y2VwdGlvbigKICAgICAgICAgICAgICAgICAgICBmIlByb3ZpZGVkIHJiZF9k + YXRhX3Bvb2wgbmFtZSwge3JiZF9wb29sX25hbWV9LCBkb2VzIG5vdCBleGlzdCIKICAgICAgICAg + ICAgICAgICkKICAgICAgICAgICAgcmV0dXJuIHJiZF9tZXRhZGF0YV9lY19wb29sX25hbWUKCiAg + ICBkZWYgZHJ5X3J1bihzZWxmLCBtc2cpOgogICAgICAgIGlmIHNlbGYuX2FyZ19wYXJzZXIuZHJ5 + X3J1bjoKICAgICAgICAgICAgcHJpbnQoIkV4ZWN1dGU6ICIgKyAiJyIgKyBtc2cgKyAiJyIpCgog + ICAgZGVmIHZhbGlkYXRlX3Jnd19lbmRwb2ludF90bHNfY2VydChzZWxmKToKICAgICAgICBpZiBz + ZWxmLl9hcmdfcGFyc2VyLnJnd190bHNfY2VydF9wYXRoOgogICAgICAgICAgICB3aXRoIG9wZW4o + c2VsZi5fYXJnX3BhcnNlci5yZ3dfdGxzX2NlcnRfcGF0aCwgZW5jb2Rpbmc9InV0ZjgiKSBhcyBm + OgogICAgICAgICAgICAgICAgY29udGVudHMgPSBmLnJlYWQoKQogICAgICAgICAgICAgICAgcmV0 + dXJuIGNvbnRlbnRzLnJzdHJpcCgpCgogICAgZGVmIF9pbnZhbGlkX2VuZHBvaW50KHNlbGYsIGVu + ZHBvaW50X3N0cik6CiAgICAgICAgIyBleHRyYWN0IHRoZSBwb3J0IGJ5IGdldHRpbmcgdGhlIGxh + c3Qgc3BsaXQgb24gYDpgIGRlbGltaXRlcgogICAgICAgIHRyeToKICAgICAgICAgICAgZW5kcG9p + bnRfc3RyX2lwLCBwb3J0ID0gZW5kcG9pbnRfc3RyLnJzcGxpdCgiOiIsIDEpCiAgICAgICAgZXhj + ZXB0IFZhbHVlRXJyb3I6CiAgICAgICAgICAgIHJhaXNlIEV4ZWN1dGlvbkZhaWx1cmVFeGNlcHRp + b24oZiJOb3QgYSBwcm9wZXIgZW5kcG9pbnQ6IHtlbmRwb2ludF9zdHJ9IikKCiAgICAgICAgdHJ5 + OgogICAgICAgICAgICBpZiBlbmRwb2ludF9zdHJfaXBbMF0gPT0gIlsiOgogICAgICAgICAgICAg + ICAgZW5kcG9pbnRfc3RyX2lwID0gZW5kcG9pbnRfc3RyX2lwWzEgOiBsZW4oZW5kcG9pbnRfc3Ry + X2lwKSAtIDFdCiAgICAgICAgICAgIGlwX3R5cGUgPSAoCiAgICAgICAgICAgICAgICAiSVB2NCIg + aWYgdHlwZShpcF9hZGRyZXNzKGVuZHBvaW50X3N0cl9pcCkpIGlzIElQdjRBZGRyZXNzIGVsc2Ug + IklQdjYiCiAgICAgICAgICAgICkKICAgICAgICBleGNlcHQgVmFsdWVFcnJvcjoKICAgICAgICAg + ICAgaXBfdHlwZSA9ICJGUUROIgogICAgICAgIGlmIG5vdCBwb3J0LmlzZGlnaXQoKToKICAgICAg + ICAgICAgcmFpc2UgRXhlY3V0aW9uRmFpbHVyZUV4Y2VwdGlvbihmIlBvcnQgbm90IHZhbGlkOiB7 + cG9ydH0iKQogICAgICAgIGludFBvcnQgPSBpbnQocG9ydCkKICAgICAgICBpZiBpbnRQb3J0IDwg + MSBvciBpbnRQb3J0ID4gMioqMTYgLSAxOgogICAgICAgICAgICByYWlzZSBFeGVjdXRpb25GYWls + dXJlRXhjZXB0aW9uKGYiT3V0IG9mIHJhbmdlIHBvcnQgbnVtYmVyOiB7cG9ydH0iKQoKICAgICAg + ICByZXR1cm4gaXBfdHlwZQoKICAgIGRlZiBlbmRwb2ludF9kaWFsKHNlbGYsIGVuZHBvaW50X3N0 + ciwgaXBfdHlwZSwgdGltZW91dD0zLCBjZXJ0PU5vbmUpOgogICAgICAgICMgaWYgdGhlICdjbHVz + dGVyJyBpbnN0YW5jZSBpcyBhIGR1bW15IG9uZSwKICAgICAgICAjIGRvbid0IHRyeSB0byByZWFj + aCBvdXQgdG8gdGhlIGVuZHBvaW50CiAgICAgICAgaWYgaXNpbnN0YW5jZShzZWxmLmNsdXN0ZXIs + IER1bW15UmFkb3MpOgogICAgICAgICAgICByZXR1cm4gIiIsICIiLCAiIgogICAgICAgIGlmIGlw + X3R5cGUgPT0gIklQdjYiOgogICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICBlbmRwb2lu + dF9zdHJfaXAsIGVuZHBvaW50X3N0cl9wb3J0ID0gZW5kcG9pbnRfc3RyLnJzcGxpdCgiOiIsIDEp + CiAgICAgICAgICAgIGV4Y2VwdCBWYWx1ZUVycm9yOgogICAgICAgICAgICAgICAgcmFpc2UgRXhl + Y3V0aW9uRmFpbHVyZUV4Y2VwdGlvbigKICAgICAgICAgICAgICAgICAgICBmIk5vdCBhIHByb3Bl + ciBlbmRwb2ludDoge2VuZHBvaW50X3N0cn0iCiAgICAgICAgICAgICAgICApCiAgICAgICAgICAg + IGlmIGVuZHBvaW50X3N0cl9pcFswXSAhPSAiWyI6CiAgICAgICAgICAgICAgICBlbmRwb2ludF9z + dHJfaXAgPSAiWyIgKyBlbmRwb2ludF9zdHJfaXAgKyAiXSIKICAgICAgICAgICAgZW5kcG9pbnRf + c3RyID0gIjoiLmpvaW4oW2VuZHBvaW50X3N0cl9pcCwgZW5kcG9pbnRfc3RyX3BvcnRdKQoKICAg + ICAgICBwcm90b2NvbHMgPSBbImh0dHAiLCAiaHR0cHMiXQogICAgICAgIHJlc3BvbnNlX2Vycm9y + ID0gTm9uZQogICAgICAgIGZvciBwcmVmaXggaW4gcHJvdG9jb2xzOgogICAgICAgICAgICB0cnk6 + CiAgICAgICAgICAgICAgICBlcCA9IGYie3ByZWZpeH06Ly97ZW5kcG9pbnRfc3RyfSIKICAgICAg + ICAgICAgICAgIHZlcmlmeSA9IE5vbmUKICAgICAgICAgICAgICAgICMgSWYgdmVyaWZ5IGlzIHNl + dCB0byBhIHBhdGggdG8gYSBkaXJlY3RvcnksCiAgICAgICAgICAgICAgICAjIHRoZSBkaXJlY3Rv + cnkgbXVzdCBoYXZlIGJlZW4gcHJvY2Vzc2VkIHVzaW5nIHRoZSBjX3JlaGFzaCB1dGlsaXR5IHN1 + cHBsaWVkIHdpdGggT3BlblNTTC4KICAgICAgICAgICAgICAgIGlmIHByZWZpeCA9PSAiaHR0cHMi + IGFuZCBzZWxmLl9hcmdfcGFyc2VyLnJnd19za2lwX3RsczoKICAgICAgICAgICAgICAgICAgICB2 + ZXJpZnkgPSBGYWxzZQogICAgICAgICAgICAgICAgICAgIHIgPSByZXF1ZXN0cy5oZWFkKGVwLCB0 + aW1lb3V0PXRpbWVvdXQsIHZlcmlmeT1GYWxzZSkKICAgICAgICAgICAgICAgIGVsaWYgcHJlZml4 + ID09ICJodHRwcyIgYW5kIGNlcnQ6CiAgICAgICAgICAgICAgICAgICAgdmVyaWZ5ID0gY2VydAog + ICAgICAgICAgICAgICAgICAgIHIgPSByZXF1ZXN0cy5oZWFkKGVwLCB0aW1lb3V0PXRpbWVvdXQs + IHZlcmlmeT1jZXJ0KQogICAgICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgICAgICBy + ID0gcmVxdWVzdHMuaGVhZChlcCwgdGltZW91dD10aW1lb3V0KQogICAgICAgICAgICAgICAgaWYg + ci5zdGF0dXNfY29kZSA9PSAyMDA6CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHByZWZpeCwg + dmVyaWZ5LCAiIgogICAgICAgICAgICBleGNlcHQgRXhjZXB0aW9uIGFzIGVycjoKICAgICAgICAg + ICAgICAgIHJlc3BvbnNlX2Vycm9yID0gZXJyCiAgICAgICAgICAgICAgICBjb250aW51ZQogICAg + ICAgIHN5cy5zdGRlcnIud3JpdGUoCiAgICAgICAgICAgIGYidW5hYmxlIHRvIGNvbm5lY3QgdG8g + ZW5kcG9pbnQ6IHtlbmRwb2ludF9zdHJ9LCBmYWlsZWQgZXJyb3I6IHtyZXNwb25zZV9lcnJvcn0i + CiAgICAgICAgKQogICAgICAgIHJldHVybiAoCiAgICAgICAgICAgICIiLAogICAgICAgICAgICAi + IiwKICAgICAgICAgICAgKCItMSIpLAogICAgICAgICkKCiAgICBkZWYgcGFyc2VfY29uZmlnX2Zp + bGUoc2VsZiwgY29uZmlnX2ZpbGUpOgogICAgICAgIGNvbmZpZyA9IGNvbmZpZ3BhcnNlci5Db25m + aWdQYXJzZXIoKQogICAgICAgIGNvbmZpZy5yZWFkKGNvbmZpZ19maWxlKQogICAgICAgIGZvciBh + cmcgaW4gbGlzdCh2YXJzKHNlbGYuX2FyZ19wYXJzZXIpKToKICAgICAgICAgICAgIyBweXRob24g + dHJlYXRzIGZsYWctbmFtZSBhcyBmbGFnX25hbWUgaW50ZXJuYWxseSwgc28gY29udmVydGluZyBi + YWNrIHRvIGZsYWctbmFtZSwKICAgICAgICAgICAgIyBzbyB3ZSBjYW4gZ2V0IHRob3NlIHZhbHVl + cyBmcm9tIGNvbmZpZyBmaWxlCiAgICAgICAgICAgIGFyZ3VtZW50ID0gYXJnLnJlcGxhY2UoIl8i + LCAiLSIpCiAgICAgICAgICAgIGFyZ3VtZW50VmFsdWUgPSBzdHIoZ2V0YXR0cihzZWxmLl9hcmdf + cGFyc2VyLCBhcmcpKQogICAgICAgICAgICBjb25maWdfdmFsdWUgPSBjb25maWcuZ2V0KCJDb25m + aWd1cmF0aW9ucyIsIGFyZ3VtZW50LCBmYWxsYmFjaz1Ob25lKQogICAgICAgICAgICAjIGdpdmUg + cHJpb3JpdHkgdG8gY29tbWFuZCBsaW5lIGFyZ3VtZW50LCBpZiBjb21tYW5kIGxpbmUgYXJndW1l + bnQgaXMgbm90IHByZXNlbnQgdXNlIGNvbmZpZy5pbmkgdmFsdWUsCiAgICAgICAgICAgIGlmIChz + dHIoc3lzLmFyZ3YpLmZpbmQoYXJndW1lbnQpID09IC0xKSBhbmQgKAogICAgICAgICAgICAgICAg + KGNvbmZpZ192YWx1ZSAhPSBOb25lKSBhbmQgKGNvbmZpZ192YWx1ZSAhPSAiIikKICAgICAgICAg + ICAgKToKICAgICAgICAgICAgICAgIHNlbGYuX2FyZ19wYXJzZXIuX19zZXRhdHRyX18oYXJnLCBj + b25maWdfdmFsdWUpCgogICAgICAgIHJldHVybiBjb25maWcKCiAgICBkZWYgX19pbml0X18oc2Vs + ZiwgYXJnX2xpc3Q9Tm9uZSk6CiAgICAgICAgc2VsZi5vdXRfbWFwID0ge30KICAgICAgICBzZWxm + Ll9leGNsdWRlZF9rZXlzID0gc2V0KCkKICAgICAgICBzZWxmLl9hcmdfcGFyc2VyID0gc2VsZi5n + ZW5fYXJnX3BhcnNlcihhcmdzX3RvX3BhcnNlPWFyZ19saXN0KQogICAgICAgIGlmIHNlbGYuX2Fy + Z19wYXJzZXIuY29uZmlnX2ZpbGU6CiAgICAgICAgICAgIHNlbGYuY29uZmlnID0gc2VsZi5wYXJz + ZV9jb25maWdfZmlsZShzZWxmLl9hcmdfcGFyc2VyLmNvbmZpZ19maWxlKQogICAgICAgIHNlbGYu + cnVuX2FzX3VzZXIgPSBzZWxmLl9hcmdfcGFyc2VyLnJ1bl9hc191c2VyCiAgICAgICAgc2VsZi5v + dXRwdXRfZmlsZSA9IHNlbGYuX2FyZ19wYXJzZXIub3V0cHV0CiAgICAgICAgc2VsZi5jZXBoX2Nv + bmYgPSBzZWxmLl9hcmdfcGFyc2VyLmNlcGhfY29uZgogICAgICAgIHNlbGYuY2VwaF9rZXlyaW5n + ID0gc2VsZi5fYXJnX3BhcnNlci5rZXlyaW5nCiAgICAgICAgIyBpZiB1c2VyIG5vdCBwcm92aWRl + ZCwgZ2l2ZSBhIGRlZmF1bHQgdXNlcgogICAgICAgIGlmIG5vdCBzZWxmLnJ1bl9hc191c2VyIGFu + ZCBub3Qgc2VsZi5fYXJnX3BhcnNlci51cGdyYWRlOgogICAgICAgICAgICBzZWxmLnJ1bl9hc191 + c2VyID0gc2VsZi5FWFRFUk5BTF9VU0VSX05BTUUKICAgICAgICBpZiBub3Qgc2VsZi5fYXJnX3Bh + cnNlci5yZ3dfcG9vbF9wcmVmaXggYW5kIG5vdCBzZWxmLl9hcmdfcGFyc2VyLnVwZ3JhZGU6CiAg + ICAgICAgICAgIHNlbGYuX2FyZ19wYXJzZXIucmd3X3Bvb2xfcHJlZml4ID0gc2VsZi5ERUZBVUxU + X1JHV19QT09MX1BSRUZJWAogICAgICAgIGlmIHNlbGYuY2VwaF9jb25mOgogICAgICAgICAgICBr + d2FyZ3MgPSB7fQogICAgICAgICAgICBpZiBzZWxmLmNlcGhfa2V5cmluZzoKICAgICAgICAgICAg + ICAgIGt3YXJnc1siY29uZiJdID0geyJrZXlyaW5nIjogc2VsZi5jZXBoX2tleXJpbmd9CiAgICAg + ICAgICAgIHNlbGYuY2x1c3RlciA9IHJhZG9zLlJhZG9zKGNvbmZmaWxlPXNlbGYuY2VwaF9jb25m + LCAqKmt3YXJncykKICAgICAgICBlbHNlOgogICAgICAgICAgICBzZWxmLmNsdXN0ZXIgPSByYWRv + cy5SYWRvcygpCiAgICAgICAgICAgIHNlbGYuY2x1c3Rlci5jb25mX3JlYWRfZmlsZSgpCiAgICAg + ICAgc2VsZi5jbHVzdGVyLmNvbm5lY3QoKQoKICAgIGRlZiBzaHV0ZG93bihzZWxmKToKICAgICAg + ICBpZiBzZWxmLmNsdXN0ZXIuc3RhdGUgPT0gImNvbm5lY3RlZCI6CiAgICAgICAgICAgIHNlbGYu + Y2x1c3Rlci5zaHV0ZG93bigpCgogICAgZGVmIGdldF9mc2lkKHNlbGYpOgogICAgICAgIGlmIHNl + bGYuX2FyZ19wYXJzZXIuZHJ5X3J1bjoKICAgICAgICAgICAgcmV0dXJuIHNlbGYuZHJ5X3J1bigi + Y2VwaCBmc2lkIikKICAgICAgICByZXR1cm4gc3RyKHNlbGYuY2x1c3Rlci5nZXRfZnNpZCgpKQoK + ICAgIGRlZiBfY29tbW9uX2NtZF9qc29uX2dlbihzZWxmLCBjbWRfanNvbik6CiAgICAgICAgY21k + ID0ganNvbi5kdW1wcyhjbWRfanNvbiwgc29ydF9rZXlzPVRydWUpCiAgICAgICAgcmV0X3ZhbCwg + Y21kX291dCwgZXJyX21zZyA9IHNlbGYuY2x1c3Rlci5tb25fY29tbWFuZChjbWQsIGIiIikKICAg + ICAgICBpZiBzZWxmLl9hcmdfcGFyc2VyLnZlcmJvc2U6CiAgICAgICAgICAgIHByaW50KGYiQ29t + bWFuZCBJbnB1dDoge2NtZH0iKQogICAgICAgICAgICBwcmludCgKICAgICAgICAgICAgICAgIGYi + UmV0dXJuIFZhbDoge3JldF92YWx9XG5Db21tYW5kIE91dHB1dDoge2NtZF9vdXR9XG4iCiAgICAg + ICAgICAgICAgICBmIkVycm9yIE1lc3NhZ2U6IHtlcnJfbXNnfVxuLS0tLS0tLS0tLVxuIgogICAg + ICAgICAgICApCiAgICAgICAganNvbl9vdXQgPSB7fQogICAgICAgICMgaWYgdGhlcmUgaXMgbm8g + ZXJyb3IgKGkuZTsgcmV0X3ZhbCBpcyBaRVJPKSBhbmQgJ2NtZF9vdXQnIGlzIG5vdCBlbXB0eQog + ICAgICAgICMgdGhlbiBjb252ZXJ0ICdjbWRfb3V0JyB0byBhIGpzb24gb3V0cHV0CiAgICAgICAg + aWYgcmV0X3ZhbCA9PSAwIGFuZCBjbWRfb3V0OgogICAgICAgICAgICBqc29uX291dCA9IGpzb24u + bG9hZHMoY21kX291dCkKICAgICAgICByZXR1cm4gcmV0X3ZhbCwganNvbl9vdXQsIGVycl9tc2cK + CiAgICBkZWYgZ2V0X2NlcGhfZXh0ZXJuYWxfbW9uX2RhdGEoc2VsZik6CiAgICAgICAgY21kX2pz + b24gPSB7InByZWZpeCI6ICJxdW9ydW1fc3RhdHVzIiwgImZvcm1hdCI6ICJqc29uIn0KICAgICAg + ICBpZiBzZWxmLl9hcmdfcGFyc2VyLmRyeV9ydW46CiAgICAgICAgICAgIHJldHVybiBzZWxmLmRy + eV9ydW4oImNlcGggIiArIGNtZF9qc29uWyJwcmVmaXgiXSkKICAgICAgICByZXRfdmFsLCBqc29u + X291dCwgZXJyX21zZyA9IHNlbGYuX2NvbW1vbl9jbWRfanNvbl9nZW4oY21kX2pzb24pCiAgICAg + ICAgIyBpZiB0aGVyZSBpcyBhbiB1bnN1Y2Nlc3NmdWwgYXR0ZW1wdCwKICAgICAgICBpZiByZXRf + dmFsICE9IDAgb3IgbGVuKGpzb25fb3V0KSA9PSAwOgogICAgICAgICAgICByYWlzZSBFeGVjdXRp + b25GYWlsdXJlRXhjZXB0aW9uKAogICAgICAgICAgICAgICAgIidxdW9ydW1fc3RhdHVzJyBjb21t + YW5kIGZhaWxlZC5cbiIKICAgICAgICAgICAgICAgIGYiRXJyb3I6IHtlcnJfbXNnIGlmIHJldF92 + YWwgIT0gMCBlbHNlIHNlbGYuRU1QVFlfT1VUUFVUX0xJU1R9IgogICAgICAgICAgICApCiAgICAg + ICAgcV9sZWFkZXJfbmFtZSA9IGpzb25fb3V0WyJxdW9ydW1fbGVhZGVyX25hbWUiXQogICAgICAg + IHFfbGVhZGVyX2RldGFpbHMgPSB7fQogICAgICAgIHFfbGVhZGVyX21hdGNoaW5nX2xpc3QgPSBb + CiAgICAgICAgICAgIGwgZm9yIGwgaW4ganNvbl9vdXRbIm1vbm1hcCJdWyJtb25zIl0gaWYgbFsi + bmFtZSJdID09IHFfbGVhZGVyX25hbWUKICAgICAgICBdCiAgICAgICAgaWYgbGVuKHFfbGVhZGVy + X21hdGNoaW5nX2xpc3QpID09IDA6CiAgICAgICAgICAgIHJhaXNlIEV4ZWN1dGlvbkZhaWx1cmVF + eGNlcHRpb24oIk5vIG1hdGNoaW5nICdtb24nIGRldGFpbHMgZm91bmQiKQogICAgICAgIHFfbGVh + ZGVyX2RldGFpbHMgPSBxX2xlYWRlcl9tYXRjaGluZ19saXN0WzBdCiAgICAgICAgIyBnZXQgdGhl + IGFkZHJlc3MgdmVjdG9yIG9mIHRoZSBxdW9ydW0tbGVhZGVyCiAgICAgICAgcV9sZWFkZXJfYWRk + cnZlYyA9IHFfbGVhZGVyX2RldGFpbHMuZ2V0KCJwdWJsaWNfYWRkcnMiLCB7fSkuZ2V0KCJhZGRy + dmVjIiwgW10pCiAgICAgICAgaXBfYWRkciA9IHN0cihxX2xlYWRlcl9kZXRhaWxzWyJwdWJsaWNf + YWRkciJdLnNwbGl0KCIvIilbMF0pCgogICAgICAgIGlmIHNlbGYuX2FyZ19wYXJzZXIudjJfcG9y + dF9lbmFibGU6CiAgICAgICAgICAgIGlmIHFfbGVhZGVyX2FkZHJ2ZWNbMF1bInR5cGUiXSA9PSAi + djIiOgogICAgICAgICAgICAgICAgaXBfYWRkciA9IHFfbGVhZGVyX2FkZHJ2ZWNbMF1bImFkZHIi + XQogICAgICAgICAgICBlbGlmIGxlbihxX2xlYWRlcl9hZGRydmVjKSA+IDEgYW5kIHFfbGVhZGVy + X2FkZHJ2ZWNbMV1bInR5cGUiXSA9PSAidjIiOgogICAgICAgICAgICAgICAgaXBfYWRkciA9IHFf + bGVhZGVyX2FkZHJ2ZWNbMV1bImFkZHIiXQogICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAg + ICAgc3lzLnN0ZGVyci53cml0ZSgKICAgICAgICAgICAgICAgICAgICAiJ3YyJyBhZGRyZXNzIHR5 + cGUgbm90IHByZXNlbnQsIGFuZCAndjItcG9ydC1lbmFibGUnIGZsYWcgaXMgcHJvdmlkZWQiCiAg + ICAgICAgICAgICAgICApCgogICAgICAgIHJldHVybiBmIntzdHIocV9sZWFkZXJfbmFtZSl9PXtp + cF9hZGRyfSIKCiAgICBkZWYgX2NvbnZlcnRfaG9zdG5hbWVfdG9faXAoc2VsZiwgaG9zdF9uYW1l + LCBwb3J0LCBpcF90eXBlKToKICAgICAgICAjIGlmICdjbHVzdGVyJyBpbnN0YW5jZSBpcyBhIGR1 + bW15IHR5cGUsCiAgICAgICAgIyBjYWxsIHRoZSBkdW1teSBpbnN0YW5jZSdzICJjb252ZXJ0IiBt + ZXRob2QKICAgICAgICBpZiBub3QgaG9zdF9uYW1lOgogICAgICAgICAgICByYWlzZSBFeGVjdXRp + b25GYWlsdXJlRXhjZXB0aW9uKCJFbXB0eSBob3N0bmFtZSBwcm92aWRlZCIpCiAgICAgICAgaWYg + aXNpbnN0YW5jZShzZWxmLmNsdXN0ZXIsIER1bW15UmFkb3MpOgogICAgICAgICAgICByZXR1cm4g + c2VsZi5jbHVzdGVyLl9jb252ZXJ0X2hvc3RuYW1lX3RvX2lwKGhvc3RfbmFtZSkKCiAgICAgICAg + aWYgaXBfdHlwZSA9PSAiRlFETiI6CiAgICAgICAgICAgICMgY2hlY2sgd2hpY2ggaXAgRlFETiBz + aG91bGQgYmUgY29udmVydGVkIHRvLCBJUHY0IG9yIElQdjYKICAgICAgICAgICAgIyBjaGVjayB0 + aGUgaG9zdCBpcCwgdGhlIGVuZHBvaW50IGlwIHR5cGUgd291bGQgYmUgc2ltaWxhciB0byBob3N0 + IGlwCiAgICAgICAgICAgIGNtZF9qc29uID0geyJwcmVmaXgiOiAib3JjaCBob3N0IGxzIiwgImZv + cm1hdCI6ICJqc29uIn0KICAgICAgICAgICAgcmV0X3ZhbCwganNvbl9vdXQsIGVycl9tc2cgPSBz + ZWxmLl9jb21tb25fY21kX2pzb25fZ2VuKGNtZF9qc29uKQogICAgICAgICAgICAjIGlmIHRoZXJl + IGlzIGFuIHVuc3VjY2Vzc2Z1bCBhdHRlbXB0LAogICAgICAgICAgICBpZiByZXRfdmFsICE9IDAg + b3IgbGVuKGpzb25fb3V0KSA9PSAwOgogICAgICAgICAgICAgICAgcmFpc2UgRXhlY3V0aW9uRmFp + bHVyZUV4Y2VwdGlvbigKICAgICAgICAgICAgICAgICAgICAiJ29yY2ggaG9zdCBscycgY29tbWFu + ZCBmYWlsZWQuXG4iCiAgICAgICAgICAgICAgICAgICAgZiJFcnJvcjoge2Vycl9tc2cgaWYgcmV0 + X3ZhbCAhPSAwIGVsc2Ugc2VsZi5FTVBUWV9PVVRQVVRfTElTVH0iCiAgICAgICAgICAgICAgICAp + CiAgICAgICAgICAgIGhvc3RfYWRkciA9IGpzb25fb3V0WzBdWyJhZGRyIl0KICAgICAgICAgICAg + IyBhZGQgOjgwIHNhbXBsZSBwb3J0IGluIGlwX3R5cGUsIGFzIF9pbnZhbGlkX2VuZHBvaW50IGFs + c28gdmVyaWZ5IHBvcnQKICAgICAgICAgICAgaG9zdF9pcF90eXBlID0gc2VsZi5faW52YWxpZF9l + bmRwb2ludChob3N0X2FkZHIgKyAiOjgwIikKICAgICAgICAgICAgaW1wb3J0IHNvY2tldAoKICAg + ICAgICAgICAgaXAgPSBbXQogICAgICAgICAgICAjIGV4YW1wbGUgb3V0cHV0IFsoPEFkZHJlc3NG + YW1pbHkuQUZfSU5FVDogMj4sIDxTb2NrZXRLaW5kLlNPQ0tfU1RSRUFNOiAxPiwgNiwgJycsICgn + OTMuMTg0LjIxNi4zNCcsIDgwKSksIC4uLl0KICAgICAgICAgICAgIyB3ZSBuZWVkIHRvIGdldCA5 + My4xODQuMjE2LjM0IHNvIGl0IHdvdWxkIGJlIGlwWzBdWzRdWzBdCiAgICAgICAgICAgIGlmIGhv + c3RfaXBfdHlwZSA9PSAiSVB2NiI6CiAgICAgICAgICAgICAgICBpcCA9IHNvY2tldC5nZXRhZGRy + aW5mbygKICAgICAgICAgICAgICAgICAgICBob3N0X25hbWUsIHBvcnQsIGZhbWlseT1zb2NrZXQu + QUZfSU5FVDYsIHByb3RvPXNvY2tldC5JUFBST1RPX1RDUAogICAgICAgICAgICAgICAgKQogICAg + ICAgICAgICBlbGlmIGhvc3RfaXBfdHlwZSA9PSAiSVB2NCI6CiAgICAgICAgICAgICAgICBpcCA9 + IHNvY2tldC5nZXRhZGRyaW5mbygKICAgICAgICAgICAgICAgICAgICBob3N0X25hbWUsIHBvcnQs + IGZhbWlseT1zb2NrZXQuQUZfSU5FVCwgcHJvdG89c29ja2V0LklQUFJPVE9fVENQCiAgICAgICAg + ICAgICAgICApCiAgICAgICAgICAgIGRlbCBzb2NrZXQKICAgICAgICAgICAgcmV0dXJuIGlwWzBd + WzRdWzBdCiAgICAgICAgcmV0dXJuIGhvc3RfbmFtZQoKICAgIGRlZiBnZXRfYWN0aXZlX2FuZF9z + dGFuZGJ5X21ncnMoc2VsZik6CiAgICAgICAgaWYgc2VsZi5fYXJnX3BhcnNlci5kcnlfcnVuOgog + ICAgICAgICAgICByZXR1cm4gIiIsIHNlbGYuZHJ5X3J1bigiY2VwaCBzdGF0dXMiKQogICAgICAg + IG1vbml0b3JpbmdfZW5kcG9pbnRfcG9ydCA9IHNlbGYuX2FyZ19wYXJzZXIubW9uaXRvcmluZ19l + bmRwb2ludF9wb3J0CiAgICAgICAgbW9uaXRvcmluZ19lbmRwb2ludF9pcF9saXN0ID0gc2VsZi5f + YXJnX3BhcnNlci5tb25pdG9yaW5nX2VuZHBvaW50CiAgICAgICAgc3RhbmRieV9tZ3JzID0gW10K + ICAgICAgICBpZiBub3QgbW9uaXRvcmluZ19lbmRwb2ludF9pcF9saXN0OgogICAgICAgICAgICBj + bWRfanNvbiA9IHsicHJlZml4IjogInN0YXR1cyIsICJmb3JtYXQiOiAianNvbiJ9CiAgICAgICAg + ICAgIHJldF92YWwsIGpzb25fb3V0LCBlcnJfbXNnID0gc2VsZi5fY29tbW9uX2NtZF9qc29uX2dl + bihjbWRfanNvbikKICAgICAgICAgICAgIyBpZiB0aGVyZSBpcyBhbiB1bnN1Y2Nlc3NmdWwgYXR0 + ZW1wdCwKICAgICAgICAgICAgaWYgcmV0X3ZhbCAhPSAwIG9yIGxlbihqc29uX291dCkgPT0gMDoK ICAgICAgICAgICAgICAgIHJhaXNlIEV4ZWN1dGlvbkZhaWx1cmVFeGNlcHRpb24oCiAgICAgICAg - ICAgICAgICAgICAgICAgIGYiUHJvdmlkZWQgZGF0YS1wb29sLW5hbWU6ICd7c2VsZi5fYXJnX3Bh - cnNlci5jZXBoZnNfZGF0YV9wb29sX25hbWV9JywgIgogICAgICAgICAgICAgICAgICAgICAgICAi - ZG9lc24ndCBtYXRjaCBmcm9tIHRoZSBkYXRhLXBvb2xzIGxpc3Q6ICIKICAgICAgICAgICAgICAg - ICAgICAgICAgZiJ7W3N0cih4KSBmb3IgeCBpbiBtYXRjaGluZ19qc29uX291dFsnZGF0YV9wb29s - cyddXX0iCiAgICAgICAgICAgICAgICAgICAgKQogICAgICAgICAgICAjIGlmIGRhdGFfcG9vbCBu - YW1lIGlzIG5vdCBwcm92aWRlZCwKICAgICAgICAgICAgIyB0aGVuIHRyeSB0byBmaW5kIGEgZGVm - YXVsdCBkYXRhIHBvb2wgbmFtZQogICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgIyBp - ZiBubyBkYXRhX3Bvb2xzIGV4aXN0LCBzaWxlbnRseSByZXR1cm4KICAgICAgICAgICAgICAgIGlm - IGxlbihtYXRjaGluZ19qc29uX291dFsiZGF0YV9wb29scyJdKSA9PSAwOgogICAgICAgICAgICAg - ICAgICAgIHJldHVybgogICAgICAgICAgICAgICAgc2VsZi5fYXJnX3BhcnNlci5jZXBoZnNfZGF0 - YV9wb29sX25hbWUgPSBzdHIoCiAgICAgICAgICAgICAgICAgICAgbWF0Y2hpbmdfanNvbl9vdXRb - ImRhdGFfcG9vbHMiXVswXQogICAgICAgICAgICAgICAgKQogICAgICAgICAgICAjIGlmIHRoZXJl - IGFyZSBtb3JlIHRoYW4gb25lICdkYXRhX3Bvb2xzJyBleGlzdCwKICAgICAgICAgICAgIyB0aGVu - IHdhcm4gdGhlIHVzZXIgdGhhdCB3ZSBhcmUgdXNpbmcgdGhlIHNlbGVjdGVkIG5hbWUKICAgICAg - ICAgICAgaWYgbGVuKG1hdGNoaW5nX2pzb25fb3V0WyJkYXRhX3Bvb2xzIl0pID4gMToKICAgICAg - ICAgICAgICAgIHByaW50KAogICAgICAgICAgICAgICAgICAgICJXQVJOSU5HOiBNdWx0aXBsZSBk - YXRhIHBvb2xzIGRldGVjdGVkOiAiCiAgICAgICAgICAgICAgICAgICAgZiJ7W3N0cih4KSBmb3Ig - eCBpbiBtYXRjaGluZ19qc29uX291dFsnZGF0YV9wb29scyddXX1cbiIKICAgICAgICAgICAgICAg - ICAgICBmIlVzaW5nIHRoZSBkYXRhLXBvb2w6ICd7c2VsZi5fYXJnX3BhcnNlci5jZXBoZnNfZGF0 - YV9wb29sX25hbWV9J1xuIgogICAgICAgICAgICAgICAgKQoKICAgIGRlZiBjcmVhdGVfY2hlY2tl - cktleShzZWxmLCB1c2VyKToKICAgICAgICBjYXBzLCBlbnRpdHkgPSBzZWxmLmdldF9jYXBzX2Fu - ZF9lbnRpdHkodXNlcikKICAgICAgICBjbWRfanNvbiA9IHsKICAgICAgICAgICAgInByZWZpeCI6 - ICJhdXRoIGdldC1vci1jcmVhdGUiLAogICAgICAgICAgICAiZW50aXR5IjogZW50aXR5LAogICAg - ICAgICAgICAiY2FwcyI6IFtjYXAgZm9yIGNhcF9saXN0IGluIGxpc3QoY2Fwcy5pdGVtcygpKSBm - b3IgY2FwIGluIGNhcF9saXN0XSwKICAgICAgICAgICAgImZvcm1hdCI6ICJqc29uIiwKICAgICAg - ICB9CgogICAgICAgIGlmIHNlbGYuX2FyZ19wYXJzZXIuZHJ5X3J1bjoKICAgICAgICAgICAgcmV0 - dXJuIHNlbGYuZHJ5X3J1bigKICAgICAgICAgICAgICAgICJjZXBoICIKICAgICAgICAgICAgICAg - ICsgY21kX2pzb25bInByZWZpeCJdCiAgICAgICAgICAgICAgICArICIgIgogICAgICAgICAgICAg - ICAgKyBjbWRfanNvblsiZW50aXR5Il0KICAgICAgICAgICAgICAgICsgIiAiCiAgICAgICAgICAg - ICAgICArICIgIi5qb2luKGNtZF9qc29uWyJjYXBzIl0pCiAgICAgICAgICAgICkKICAgICAgICAj - IGNoZWNrIGlmIHVzZXIgYWxyZWFkeSBleGlzdAogICAgICAgIHVzZXJfa2V5ID0gc2VsZi5jaGVj - a191c2VyX2V4aXN0KGVudGl0eSkKICAgICAgICBpZiB1c2VyX2tleSAhPSAiIjoKICAgICAgICAg - ICAgcmV0dXJuIHVzZXJfa2V5CgogICAgICAgIHJldF92YWwsIGpzb25fb3V0LCBlcnJfbXNnID0g - c2VsZi5fY29tbW9uX2NtZF9qc29uX2dlbihjbWRfanNvbikKICAgICAgICAjIGlmIHRoZXJlIGlz - IGFuIHVuc3VjY2Vzc2Z1bCBhdHRlbXB0LAogICAgICAgIGlmIHJldF92YWwgIT0gMCBvciBsZW4o - anNvbl9vdXQpID09IDA6CiAgICAgICAgICAgIHJhaXNlIEV4ZWN1dGlvbkZhaWx1cmVFeGNlcHRp - b24oCiAgICAgICAgICAgICAgICBmIidhdXRoIGdldC1vci1jcmVhdGUge3NlbGYucnVuX2FzX3Vz - ZXJ9JyBjb21tYW5kIGZhaWxlZFxuIgogICAgICAgICAgICAgICAgZiJFcnJvcjoge2Vycl9tc2cg - aWYgcmV0X3ZhbCAhPSAwIGVsc2Ugc2VsZi5FTVBUWV9PVVRQVVRfTElTVH0iCiAgICAgICAgICAg - ICkKICAgICAgICByZXR1cm4gc3RyKGpzb25fb3V0WzBdWyJrZXkiXSkKCiAgICBkZWYgZ2V0X2Nl - cGhfZGFzaGJvYXJkX2xpbmsoc2VsZik6CiAgICAgICAgY21kX2pzb24gPSB7InByZWZpeCI6ICJt - Z3Igc2VydmljZXMiLCAiZm9ybWF0IjogImpzb24ifQogICAgICAgIGlmIHNlbGYuX2FyZ19wYXJz - ZXIuZHJ5X3J1bjoKICAgICAgICAgICAgcmV0dXJuIHNlbGYuZHJ5X3J1bigiY2VwaCAiICsgY21k - X2pzb25bInByZWZpeCJdKQogICAgICAgIHJldF92YWwsIGpzb25fb3V0LCBfID0gc2VsZi5fY29t - bW9uX2NtZF9qc29uX2dlbihjbWRfanNvbikKICAgICAgICAjIGlmIHRoZXJlIGlzIGFuIHVuc3Vj - Y2Vzc2Z1bCBhdHRlbXB0LAogICAgICAgIGlmIHJldF92YWwgIT0gMCBvciBsZW4oanNvbl9vdXQp - ID09IDA6CiAgICAgICAgICAgIHJldHVybiBOb25lCiAgICAgICAgaWYgImRhc2hib2FyZCIgbm90 - IGluIGpzb25fb3V0OgogICAgICAgICAgICByZXR1cm4gTm9uZQogICAgICAgIHJldHVybiBqc29u - X291dFsiZGFzaGJvYXJkIl0KCiAgICBkZWYgY3JlYXRlX3Jnd19hZG1pbl9vcHNfdXNlcihzZWxm - KToKICAgICAgICBjbWQgPSBbCiAgICAgICAgICAgICJyYWRvc2d3LWFkbWluIiwKICAgICAgICAg - ICAgInVzZXIiLAogICAgICAgICAgICAiY3JlYXRlIiwKICAgICAgICAgICAgIi0tdWlkIiwKICAg - ICAgICAgICAgc2VsZi5FWFRFUk5BTF9SR1dfQURNSU5fT1BTX1VTRVJfTkFNRSwKICAgICAgICAg - ICAgIi0tZGlzcGxheS1uYW1lIiwKICAgICAgICAgICAgIlJvb2sgUkdXIEFkbWluIE9wcyB1c2Vy - IiwKICAgICAgICAgICAgIi0tY2FwcyIsCiAgICAgICAgICAgICJidWNrZXRzPSo7dXNlcnM9Kjt1 - c2FnZT1yZWFkO21ldGFkYXRhPXJlYWQ7em9uZT1yZWFkIiwKICAgICAgICAgICAgIi0tcmd3LXJl - YWxtIiwKICAgICAgICAgICAgc2VsZi5fYXJnX3BhcnNlci5yZ3dfcmVhbG1fbmFtZSwKICAgICAg - ICAgICAgIi0tcmd3LXpvbmVncm91cCIsCiAgICAgICAgICAgIHNlbGYuX2FyZ19wYXJzZXIucmd3 - X3pvbmVncm91cF9uYW1lLAogICAgICAgICAgICAiLS1yZ3ctem9uZSIsCiAgICAgICAgICAgIHNl - bGYuX2FyZ19wYXJzZXIucmd3X3pvbmVfbmFtZSwKICAgICAgICBdCiAgICAgICAgaWYgc2VsZi5f - YXJnX3BhcnNlci5kcnlfcnVuOgogICAgICAgICAgICByZXR1cm4gc2VsZi5kcnlfcnVuKCJjZXBo - ICIgKyAiICIuam9pbihjbWQpKQogICAgICAgIHRyeToKICAgICAgICAgICAgb3V0cHV0ID0gc3Vi - cHJvY2Vzcy5jaGVja19vdXRwdXQoY21kLCBzdGRlcnI9c3VicHJvY2Vzcy5QSVBFKQogICAgICAg - IGV4Y2VwdCBzdWJwcm9jZXNzLkNhbGxlZFByb2Nlc3NFcnJvciBhcyBleGVjRXJyOgogICAgICAg - ICAgICAjIGlmIHRoZSB1c2VyIGFscmVhZHkgZXhpc3RzLCB3ZSBqdXN0IHF1ZXJ5IGl0CiAgICAg - ICAgICAgIGlmIGV4ZWNFcnIucmV0dXJuY29kZSA9PSBlcnJuby5FRVhJU1Q6CiAgICAgICAgICAg - ICAgICBjbWQgPSBbCiAgICAgICAgICAgICAgICAgICAgInJhZG9zZ3ctYWRtaW4iLAogICAgICAg - ICAgICAgICAgICAgICJ1c2VyIiwKICAgICAgICAgICAgICAgICAgICAiaW5mbyIsCiAgICAgICAg - ICAgICAgICAgICAgIi0tdWlkIiwKICAgICAgICAgICAgICAgICAgICBzZWxmLkVYVEVSTkFMX1JH - V19BRE1JTl9PUFNfVVNFUl9OQU1FLAogICAgICAgICAgICAgICAgICAgICItLXJndy1yZWFsbSIs - CiAgICAgICAgICAgICAgICAgICAgc2VsZi5fYXJnX3BhcnNlci5yZ3dfcmVhbG1fbmFtZSwKICAg - ICAgICAgICAgICAgICAgICAiLS1yZ3ctem9uZWdyb3VwIiwKICAgICAgICAgICAgICAgICAgICBz - ZWxmLl9hcmdfcGFyc2VyLnJnd196b25lZ3JvdXBfbmFtZSwKICAgICAgICAgICAgICAgICAgICAi - LS1yZ3ctem9uZSIsCiAgICAgICAgICAgICAgICAgICAgc2VsZi5fYXJnX3BhcnNlci5yZ3dfem9u - ZV9uYW1lLAogICAgICAgICAgICAgICAgXQogICAgICAgICAgICAgICAgdHJ5OgogICAgICAgICAg - ICAgICAgICAgIG91dHB1dCA9IHN1YnByb2Nlc3MuY2hlY2tfb3V0cHV0KGNtZCwgc3RkZXJyPXN1 - YnByb2Nlc3MuUElQRSkKICAgICAgICAgICAgICAgIGV4Y2VwdCBzdWJwcm9jZXNzLkNhbGxlZFBy - b2Nlc3NFcnJvciBhcyBleGVjRXJyOgogICAgICAgICAgICAgICAgICAgIGVycl9tc2cgPSAoCiAg - ICAgICAgICAgICAgICAgICAgICAgIGYiZmFpbGVkIHRvIGV4ZWN1dGUgY29tbWFuZCB7Y21kfS4g - T3V0cHV0OiB7ZXhlY0Vyci5vdXRwdXR9LiAiCiAgICAgICAgICAgICAgICAgICAgICAgIGYiQ29k - ZToge2V4ZWNFcnIucmV0dXJuY29kZX0uIEVycm9yOiB7ZXhlY0Vyci5zdGRlcnJ9IgogICAgICAg - ICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgICAgICBzeXMuc3RkZXJyLndyaXRlKGVycl9t - c2cpCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIE5vbmUsIE5vbmUsIEZhbHNlLCAiLTEiCiAg - ICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICBlcnJfbXNnID0gKAogICAgICAgICAgICAg - ICAgICAgIGYiZmFpbGVkIHRvIGV4ZWN1dGUgY29tbWFuZCB7Y21kfS4gT3V0cHV0OiB7ZXhlY0Vy - ci5vdXRwdXR9LiAiCiAgICAgICAgICAgICAgICAgICAgZiJDb2RlOiB7ZXhlY0Vyci5yZXR1cm5j - b2RlfS4gRXJyb3I6IHtleGVjRXJyLnN0ZGVycn0iCiAgICAgICAgICAgICAgICApCiAgICAgICAg - ICAgICAgICBzeXMuc3RkZXJyLndyaXRlKGVycl9tc2cpCiAgICAgICAgICAgICAgICByZXR1cm4g - Tm9uZSwgTm9uZSwgRmFsc2UsICItMSIKCiAgICAgICAgIyBzZXBhcmF0ZWx5IGFkZCBpbmZvPXJl - YWQgY2FwcyBmb3Igcmd3LWVuZHBvaW50IGlwIHZhbGlkYXRpb24KICAgICAgICBpbmZvX2NhcF9z - dXBwb3J0ZWQgPSBUcnVlCiAgICAgICAgY21kID0gWwogICAgICAgICAgICAicmFkb3Nndy1hZG1p - biIsCiAgICAgICAgICAgICJjYXBzIiwKICAgICAgICAgICAgImFkZCIsCiAgICAgICAgICAgICIt - LXVpZCIsCiAgICAgICAgICAgIHNlbGYuRVhURVJOQUxfUkdXX0FETUlOX09QU19VU0VSX05BTUUs - CiAgICAgICAgICAgICItLWNhcHMiLAogICAgICAgICAgICAiaW5mbz1yZWFkIiwKICAgICAgICAg - ICAgIi0tcmd3LXJlYWxtIiwKICAgICAgICAgICAgc2VsZi5fYXJnX3BhcnNlci5yZ3dfcmVhbG1f - bmFtZSwKICAgICAgICAgICAgIi0tcmd3LXpvbmVncm91cCIsCiAgICAgICAgICAgIHNlbGYuX2Fy - Z19wYXJzZXIucmd3X3pvbmVncm91cF9uYW1lLAogICAgICAgICAgICAiLS1yZ3ctem9uZSIsCiAg - ICAgICAgICAgIHNlbGYuX2FyZ19wYXJzZXIucmd3X3pvbmVfbmFtZSwKICAgICAgICBdCiAgICAg - ICAgdHJ5OgogICAgICAgICAgICBvdXRwdXQgPSBzdWJwcm9jZXNzLmNoZWNrX291dHB1dChjbWQs - IHN0ZGVycj1zdWJwcm9jZXNzLlBJUEUpCiAgICAgICAgZXhjZXB0IHN1YnByb2Nlc3MuQ2FsbGVk - UHJvY2Vzc0Vycm9yIGFzIGV4ZWNFcnI6CiAgICAgICAgICAgICMgaWYgdGhlIGNlcGggdmVyc2lv - biBub3Qgc3VwcG9ydGVkIGZvciBhZGRpbmcgYGluZm89cmVhZGAgY2FwKHJnd192YWxpZGF0aW9u - KQogICAgICAgICAgICBpZiAoCiAgICAgICAgICAgICAgICAiY291bGQgbm90IGFkZCBjYXBzOiB1 - bmFibGUgdG8gYWRkIGNhcHM6IGluZm89cmVhZFxuIgogICAgICAgICAgICAgICAgaW4gZXhlY0Vy - ci5zdGRlcnIuZGVjb2RlKCJ1dGYtOCIpCiAgICAgICAgICAgICAgICBhbmQgZXhlY0Vyci5yZXR1 - cm5jb2RlID09IDI0NAogICAgICAgICAgICApOgogICAgICAgICAgICAgICAgaW5mb19jYXBfc3Vw - cG9ydGVkID0gRmFsc2UKICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgIGVycl9tc2cg - PSAoCiAgICAgICAgICAgICAgICAgICAgZiJmYWlsZWQgdG8gZXhlY3V0ZSBjb21tYW5kIHtjbWR9 - LiBPdXRwdXQ6IHtleGVjRXJyLm91dHB1dH0uICIKICAgICAgICAgICAgICAgICAgICBmIkNvZGU6 - IHtleGVjRXJyLnJldHVybmNvZGV9LiBFcnJvcjoge2V4ZWNFcnIuc3RkZXJyfSIKICAgICAgICAg - ICAgICAgICkKICAgICAgICAgICAgICAgIHN5cy5zdGRlcnIud3JpdGUoZXJyX21zZykKICAgICAg - ICAgICAgICAgIHJldHVybiBOb25lLCBOb25lLCBGYWxzZSwgIi0xIgoKICAgICAgICBqc29ub3V0 - cHV0ID0ganNvbi5sb2FkcyhvdXRwdXQpCiAgICAgICAgcmV0dXJuICgKICAgICAgICAgICAganNv - bm91dHB1dFsia2V5cyJdWzBdWyJhY2Nlc3Nfa2V5Il0sCiAgICAgICAgICAgIGpzb25vdXRwdXRb - ImtleXMiXVswXVsic2VjcmV0X2tleSJdLAogICAgICAgICAgICBpbmZvX2NhcF9zdXBwb3J0ZWQs - CiAgICAgICAgICAgICIiLAogICAgICAgICkKCiAgICBkZWYgdmFsaWRhdGVfcmJkX3Bvb2woc2Vs - ZiwgcG9vbF9uYW1lKToKICAgICAgICBpZiBub3Qgc2VsZi5jbHVzdGVyLnBvb2xfZXhpc3RzKHBv - b2xfbmFtZSk6CiAgICAgICAgICAgIHJhaXNlIEV4ZWN1dGlvbkZhaWx1cmVFeGNlcHRpb24oCiAg - ICAgICAgICAgICAgICBmIlRoZSBwcm92aWRlZCBwb29sLCAne3Bvb2xfbmFtZX0nLCBkb2VzIG5v - dCBleGlzdCIKICAgICAgICAgICAgKQoKICAgIGRlZiBpbml0X3JiZF9wb29sKHNlbGYsIHJiZF9w - b29sX25hbWUpOgogICAgICAgIGlmIGlzaW5zdGFuY2Uoc2VsZi5jbHVzdGVyLCBEdW1teVJhZG9z - KToKICAgICAgICAgICAgcmV0dXJuCiAgICAgICAgaW9jdHggPSBzZWxmLmNsdXN0ZXIub3Blbl9p - b2N0eChyYmRfcG9vbF9uYW1lKQogICAgICAgIHJiZF9pbnN0ID0gcmJkLlJCRCgpCiAgICAgICAg - cmJkX2luc3QucG9vbF9pbml0KGlvY3R4LCBUcnVlKQoKICAgIGRlZiB2YWxpZGF0ZV9yYWRvc19u - YW1lc3BhY2Uoc2VsZik6CiAgICAgICAgcmJkX3Bvb2xfbmFtZSA9IHNlbGYuX2FyZ19wYXJzZXIu - cmJkX2RhdGFfcG9vbF9uYW1lCiAgICAgICAgaWYgc2VsZi5fYXJnX3BhcnNlci5yYmRfbWV0YWRh - dGFfZWNfcG9vbF9uYW1lOgogICAgICAgICAgICByYmRfcG9vbF9uYW1lID0gc2VsZi5fYXJnX3Bh - cnNlci5yYmRfbWV0YWRhdGFfZWNfcG9vbF9uYW1lCiAgICAgICAgcmFkb3NfbmFtZXNwYWNlID0g - c2VsZi5fYXJnX3BhcnNlci5yYWRvc19uYW1lc3BhY2UKICAgICAgICBpZiByYWRvc19uYW1lc3Bh - Y2UgPT0gIiI6CiAgICAgICAgICAgIHJldHVybgogICAgICAgIGlmIHJhZG9zX25hbWVzcGFjZS5p - c2xvd2VyKCkgPT0gRmFsc2U6CiAgICAgICAgICAgIHJhaXNlIEV4ZWN1dGlvbkZhaWx1cmVFeGNl - cHRpb24oCiAgICAgICAgICAgICAgICBmIlRoZSBwcm92aWRlZCByYWRvcyBOYW1lc3BhY2UsICd7 - cmFkb3NfbmFtZXNwYWNlfScsICIKICAgICAgICAgICAgICAgIGYiY29udGFpbnMgdXBwZXIgY2Fz - ZSIKICAgICAgICAgICAgKQogICAgICAgIHJiZF9pbnN0ID0gcmJkLlJCRCgpCiAgICAgICAgaW9j - dHggPSBzZWxmLmNsdXN0ZXIub3Blbl9pb2N0eChyYmRfcG9vbF9uYW1lKQogICAgICAgIGlmIHJi - ZF9pbnN0Lm5hbWVzcGFjZV9leGlzdHMoaW9jdHgsIHJhZG9zX25hbWVzcGFjZSkgaXMgRmFsc2U6 - CiAgICAgICAgICAgIHJhaXNlIEV4ZWN1dGlvbkZhaWx1cmVFeGNlcHRpb24oCiAgICAgICAgICAg - ICAgICBmIlRoZSBwcm92aWRlZCByYWRvcyBOYW1lc3BhY2UsICd7cmFkb3NfbmFtZXNwYWNlfScs - ICIKICAgICAgICAgICAgICAgIGYiaXMgbm90IGZvdW5kIGluIHRoZSBwb29sICd7cmJkX3Bvb2xf - bmFtZX0nIgogICAgICAgICAgICApCgogICAgZGVmIGdldF9vcl9jcmVhdGVfc3Vidm9sdW1lX2dy - b3VwKHNlbGYsIHN1YnZvbHVtZV9ncm91cCwgY2VwaGZzX2ZpbGVzeXN0ZW1fbmFtZSk6CiAgICAg - ICAgY21kID0gWwogICAgICAgICAgICAiY2VwaCIsCiAgICAgICAgICAgICJmcyIsCiAgICAgICAg - ICAgICJzdWJ2b2x1bWVncm91cCIsCiAgICAgICAgICAgICJnZXRwYXRoIiwKICAgICAgICAgICAg - Y2VwaGZzX2ZpbGVzeXN0ZW1fbmFtZSwKICAgICAgICAgICAgc3Vidm9sdW1lX2dyb3VwLAogICAg - ICAgIF0KICAgICAgICB0cnk6CiAgICAgICAgICAgIF8gPSBzdWJwcm9jZXNzLmNoZWNrX291dHB1 - dChjbWQsIHN0ZGVycj1zdWJwcm9jZXNzLlBJUEUpCiAgICAgICAgZXhjZXB0IHN1YnByb2Nlc3Mu - Q2FsbGVkUHJvY2Vzc0Vycm9yOgogICAgICAgICAgICBjbWQgPSBbCiAgICAgICAgICAgICAgICAi - Y2VwaCIsCiAgICAgICAgICAgICAgICAiZnMiLAogICAgICAgICAgICAgICAgInN1YnZvbHVtZWdy - b3VwIiwKICAgICAgICAgICAgICAgICJjcmVhdGUiLAogICAgICAgICAgICAgICAgY2VwaGZzX2Zp - bGVzeXN0ZW1fbmFtZSwKICAgICAgICAgICAgICAgIHN1YnZvbHVtZV9ncm91cCwKICAgICAgICAg - ICAgXQogICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICBfID0gc3VicHJvY2Vzcy5jaGVj - a19vdXRwdXQoY21kLCBzdGRlcnI9c3VicHJvY2Vzcy5QSVBFKQogICAgICAgICAgICBleGNlcHQg - c3VicHJvY2Vzcy5DYWxsZWRQcm9jZXNzRXJyb3I6CiAgICAgICAgICAgICAgICByYWlzZSBFeGVj - dXRpb25GYWlsdXJlRXhjZXB0aW9uKAogICAgICAgICAgICAgICAgICAgIGYic3Vidm9sdW1lIGdy - b3VwIHtzdWJ2b2x1bWVfZ3JvdXB9IGlzIG5vdCBhYmxlIHRvIGdldCBjcmVhdGVkIgogICAgICAg - ICAgICAgICAgKQoKICAgIGRlZiBwaW5fc3Vidm9sdW1lKAogICAgICAgIHNlbGYsIHN1YnZvbHVt - ZV9ncm91cCwgY2VwaGZzX2ZpbGVzeXN0ZW1fbmFtZSwgcGluX3R5cGUsIHBpbl9zZXR0aW5nCiAg - ICApOgogICAgICAgIGNtZCA9IFsKICAgICAgICAgICAgImNlcGgiLAogICAgICAgICAgICAiZnMi - LAogICAgICAgICAgICAic3Vidm9sdW1lZ3JvdXAiLAogICAgICAgICAgICAicGluIiwKICAgICAg - ICAgICAgY2VwaGZzX2ZpbGVzeXN0ZW1fbmFtZSwKICAgICAgICAgICAgc3Vidm9sdW1lX2dyb3Vw - LAogICAgICAgICAgICBwaW5fdHlwZSwKICAgICAgICAgICAgcGluX3NldHRpbmcsCiAgICAgICAg - XQogICAgICAgIHRyeToKICAgICAgICAgICAgXyA9IHN1YnByb2Nlc3MuY2hlY2tfb3V0cHV0KGNt - ZCwgc3RkZXJyPXN1YnByb2Nlc3MuUElQRSkKICAgICAgICBleGNlcHQgc3VicHJvY2Vzcy5DYWxs - ZWRQcm9jZXNzRXJyb3I6CiAgICAgICAgICAgIHJhaXNlIEV4ZWN1dGlvbkZhaWx1cmVFeGNlcHRp - b24oCiAgICAgICAgICAgICAgICBmInN1YnZvbHVtZSBncm91cCB7c3Vidm9sdW1lX2dyb3VwfSBp - cyBub3QgYWJsZSB0byBnZXQgcGlubmVkIgogICAgICAgICAgICApCgogICAgZGVmIGdldF9yZ3df - ZnNpZChzZWxmLCBiYXNlX3VybCwgdmVyaWZ5KToKICAgICAgICBhY2Nlc3Nfa2V5ID0gc2VsZi5v - dXRfbWFwWyJSR1dfQURNSU5fT1BTX1VTRVJfQUNDRVNTX0tFWSJdCiAgICAgICAgc2VjcmV0X2tl - eSA9IHNlbGYub3V0X21hcFsiUkdXX0FETUlOX09QU19VU0VSX1NFQ1JFVF9LRVkiXQogICAgICAg - IHJnd19lbmRwb2ludCA9IHNlbGYuX2FyZ19wYXJzZXIucmd3X2VuZHBvaW50CiAgICAgICAgYmFz - ZV91cmwgPSBiYXNlX3VybCArICI6Ly8iICsgcmd3X2VuZHBvaW50ICsgIi9hZG1pbi9pbmZvPyIK - ICAgICAgICBwYXJhbXMgPSB7ImZvcm1hdCI6ICJqc29uIn0KICAgICAgICByZXF1ZXN0X3VybCA9 - IGJhc2VfdXJsICsgdXJsZW5jb2RlKHBhcmFtcykKCiAgICAgICAgdHJ5OgogICAgICAgICAgICBy - ID0gcmVxdWVzdHMuZ2V0KAogICAgICAgICAgICAgICAgcmVxdWVzdF91cmwsCiAgICAgICAgICAg - ICAgICBhdXRoPVMzQXV0aChhY2Nlc3Nfa2V5LCBzZWNyZXRfa2V5LCByZ3dfZW5kcG9pbnQpLAog - ICAgICAgICAgICAgICAgdmVyaWZ5PXZlcmlmeSwKICAgICAgICAgICAgKQogICAgICAgIGV4Y2Vw - dCByZXF1ZXN0cy5leGNlcHRpb25zLlRpbWVvdXQ6CiAgICAgICAgICAgIHN5cy5zdGRlcnIud3Jp - dGUoCiAgICAgICAgICAgICAgICBmImludmFsaWQgZW5kcG9pbnQ6LCBub3QgYWJsZSB0byBjYWxs - IGFkbWluLW9wcyBhcGl7cmd3X2VuZHBvaW50fSIKICAgICAgICAgICAgKQogICAgICAgICAgICBy - ZXR1cm4gIiIsICItMSIKICAgICAgICByMSA9IHIuanNvbigpCiAgICAgICAgaWYgcjEgaXMgTm9u - ZSBvciByMS5nZXQoImluZm8iKSBpcyBOb25lOgogICAgICAgICAgICBzeXMuc3RkZXJyLndyaXRl - KAogICAgICAgICAgICAgICAgZiJUaGUgcHJvdmlkZWQgcmd3IEVuZHBvaW50LCAne3NlbGYuX2Fy - Z19wYXJzZXIucmd3X2VuZHBvaW50fScsIGlzIGludmFsaWQuIgogICAgICAgICAgICApCiAgICAg - ICAgICAgIHJldHVybiAoCiAgICAgICAgICAgICAgICAiIiwKICAgICAgICAgICAgICAgICItMSIs - CiAgICAgICAgICAgICkKCiAgICAgICAgcmV0dXJuIHIxWyJpbmZvIl1bInN0b3JhZ2VfYmFja2Vu - ZHMiXVswXVsiY2x1c3Rlcl9pZCJdLCAiIgoKICAgIGRlZiB2YWxpZGF0ZV9yZ3dfZW5kcG9pbnQo - c2VsZiwgaW5mb19jYXBfc3VwcG9ydGVkKToKICAgICAgICAjIGlmIHRoZSAnY2x1c3RlcicgaW5z - dGFuY2UgaXMgYSBkdW1teSBvbmUsCiAgICAgICAgIyBkb24ndCB0cnkgdG8gcmVhY2ggb3V0IHRv - IHRoZSBlbmRwb2ludAogICAgICAgIGlmIGlzaW5zdGFuY2Uoc2VsZi5jbHVzdGVyLCBEdW1teVJh - ZG9zKToKICAgICAgICAgICAgcmV0dXJuCgogICAgICAgIHJnd19lbmRwb2ludCA9IHNlbGYuX2Fy - Z19wYXJzZXIucmd3X2VuZHBvaW50CgogICAgICAgICMgdmFsaWRhdGUgcmd3IGVuZHBvaW50IG9u - bHkgaWYgaXAgYWRkcmVzcyBpcyBwYXNzZWQKICAgICAgICBpcF90eXBlID0gc2VsZi5faW52YWxp - ZF9lbmRwb2ludChyZ3dfZW5kcG9pbnQpCgogICAgICAgICMgY2hlY2sgaWYgdGhlIHJndyBlbmRw - b2ludCBpcyByZWFjaGFibGUKICAgICAgICBjZXJ0ID0gTm9uZQogICAgICAgIGlmIG5vdCBzZWxm - Ll9hcmdfcGFyc2VyLnJnd19za2lwX3RscyBhbmQgc2VsZi52YWxpZGF0ZV9yZ3dfZW5kcG9pbnRf - dGxzX2NlcnQoKToKICAgICAgICAgICAgY2VydCA9IHNlbGYuX2FyZ19wYXJzZXIucmd3X3Rsc19j - ZXJ0X3BhdGgKICAgICAgICBiYXNlX3VybCwgdmVyaWZ5LCBlcnIgPSBzZWxmLmVuZHBvaW50X2Rp - YWwocmd3X2VuZHBvaW50LCBpcF90eXBlLCBjZXJ0PWNlcnQpCiAgICAgICAgaWYgZXJyICE9ICIi - OgogICAgICAgICAgICByZXR1cm4gIi0xIgoKICAgICAgICAjIGNoZWNrIGlmIHRoZSByZ3cgZW5k - cG9pbnQgYmVsb25ncyB0byB0aGUgc2FtZSBjbHVzdGVyCiAgICAgICAgIyBvbmx5IGNoZWNrIGlm - IGBpbmZvYCBjYXAgaXMgc3VwcG9ydGVkCiAgICAgICAgaWYgaW5mb19jYXBfc3VwcG9ydGVkOgog - ICAgICAgICAgICBmc2lkID0gc2VsZi5nZXRfZnNpZCgpCiAgICAgICAgICAgIHJnd19mc2lkLCBl - cnIgPSBzZWxmLmdldF9yZ3dfZnNpZChiYXNlX3VybCwgdmVyaWZ5KQogICAgICAgICAgICBpZiBl - cnIgPT0gIi0xIjoKICAgICAgICAgICAgICAgIHJldHVybiAiLTEiCiAgICAgICAgICAgIGlmIGZz - aWQgIT0gcmd3X2ZzaWQ6CiAgICAgICAgICAgICAgICBzeXMuc3RkZXJyLndyaXRlKAogICAgICAg - ICAgICAgICAgICAgIGYiVGhlIHByb3ZpZGVkIHJndyBFbmRwb2ludCwgJ3tzZWxmLl9hcmdfcGFy - c2VyLnJnd19lbmRwb2ludH0nLCBpcyBpbnZhbGlkLiBXZSBhcmUgdmFsaWRhdGluZyBieSBjYWxs - aW5nIHRoZSBhZG1pbm9wcyBhcGkgdGhyb3VnaCByZ3ctZW5kcG9pbnQgYW5kIHZhbGlkYXRpbmcg - dGhlIGNsdXN0ZXJfaWQgJ3tyZ3dfZnNpZH0nIGlzIGVxdWFsIHRvIHRoZSBjZXBoIGNsdXN0ZXIg - ZnNpZCAne2ZzaWR9JyIKICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgIHJldHVybiAi - LTEiCgogICAgICAgICMgY2hlY2sgaWYgdGhlIHJndyBlbmRwb2ludCBwb29sIGV4aXN0CiAgICAg - ICAgIyBvbmx5IHZhbGlkYXRlIGlmIHJnd19wb29sX3ByZWZpeCBpcyBwYXNzZWQgZWxzZSBpdCB3 - aWxsIHRha2UgZGVmYXVsdCB2YWx1ZSBhbmQgd2UgZG9uJ3QgY3JlYXRlIHRoZXNlIGRlZmF1bHQg - cG9vbHMKICAgICAgICBpZiBzZWxmLl9hcmdfcGFyc2VyLnJnd19wb29sX3ByZWZpeCAhPSAiZGVm - YXVsdCI6CiAgICAgICAgICAgIHJnd19wb29sc190b192YWxpZGF0ZSA9IFsKICAgICAgICAgICAg - ICAgIGYie3NlbGYuX2FyZ19wYXJzZXIucmd3X3Bvb2xfcHJlZml4fS5yZ3cubWV0YSIsCiAgICAg - ICAgICAgICAgICAiLnJndy5yb290IiwKICAgICAgICAgICAgICAgIGYie3NlbGYuX2FyZ19wYXJz - ZXIucmd3X3Bvb2xfcHJlZml4fS5yZ3cuY29udHJvbCIsCiAgICAgICAgICAgICAgICBmIntzZWxm - Ll9hcmdfcGFyc2VyLnJnd19wb29sX3ByZWZpeH0ucmd3LmxvZyIsCiAgICAgICAgICAgIF0KICAg - ICAgICAgICAgZm9yIF9yZ3dfcG9vbF90b192YWxpZGF0ZSBpbiByZ3dfcG9vbHNfdG9fdmFsaWRh - dGU6CiAgICAgICAgICAgICAgICBpZiBub3Qgc2VsZi5jbHVzdGVyLnBvb2xfZXhpc3RzKF9yZ3df - cG9vbF90b192YWxpZGF0ZSk6CiAgICAgICAgICAgICAgICAgICAgc3lzLnN0ZGVyci53cml0ZSgK - ICAgICAgICAgICAgICAgICAgICAgICAgZiJUaGUgcHJvdmlkZWQgcG9vbCwgJ3tfcmd3X3Bvb2xf - dG9fdmFsaWRhdGV9JywgZG9lcyBub3QgZXhpc3QiCiAgICAgICAgICAgICAgICAgICAgKQogICAg - ICAgICAgICAgICAgICAgIHJldHVybiAiLTEiCgogICAgICAgIHJldHVybiAiIgoKICAgIGRlZiB2 - YWxpZGF0ZV9yZ3dfbXVsdGlzaXRlKHNlbGYsIHJnd19tdWx0aXNpdGVfY29uZmlnX25hbWUsIHJn - d19tdWx0aXNpdGVfY29uZmlnKToKICAgICAgICBpZiByZ3dfbXVsdGlzaXRlX2NvbmZpZyAhPSAi - IjoKICAgICAgICAgICAgY21kID0gWwogICAgICAgICAgICAgICAgInJhZG9zZ3ctYWRtaW4iLAog - ICAgICAgICAgICAgICAgcmd3X211bHRpc2l0ZV9jb25maWcsCiAgICAgICAgICAgICAgICAiZ2V0 - IiwKICAgICAgICAgICAgICAgICItLXJndy0iICsgcmd3X211bHRpc2l0ZV9jb25maWcsCiAgICAg - ICAgICAgICAgICByZ3dfbXVsdGlzaXRlX2NvbmZpZ19uYW1lLAogICAgICAgICAgICBdCiAgICAg - ICAgICAgIHRyeToKICAgICAgICAgICAgICAgIF8gPSBzdWJwcm9jZXNzLmNoZWNrX291dHB1dChj - bWQsIHN0ZGVycj1zdWJwcm9jZXNzLlBJUEUpCiAgICAgICAgICAgIGV4Y2VwdCBzdWJwcm9jZXNz - LkNhbGxlZFByb2Nlc3NFcnJvciBhcyBleGVjRXJyOgogICAgICAgICAgICAgICAgZXJyX21zZyA9 - ICgKICAgICAgICAgICAgICAgICAgICBmImZhaWxlZCB0byBleGVjdXRlIGNvbW1hbmQge2NtZH0u - IE91dHB1dDoge2V4ZWNFcnIub3V0cHV0fS4gIgogICAgICAgICAgICAgICAgICAgIGYiQ29kZTog - e2V4ZWNFcnIucmV0dXJuY29kZX0uIEVycm9yOiB7ZXhlY0Vyci5zdGRlcnJ9IgogICAgICAgICAg - ICAgICAgKQogICAgICAgICAgICAgICAgc3lzLnN0ZGVyci53cml0ZShlcnJfbXNnKQogICAgICAg - ICAgICAgICAgcmV0dXJuICItMSIKICAgICAgICByZXR1cm4gIiIKCiAgICBkZWYgY29udmVydF9j - b21tYV9zZXBhcmF0ZWRfdG9fYXJyYXkoc2VsZiwgdmFsdWUpOgogICAgICAgIHJldHVybiB2YWx1 - ZS5zcGxpdCgiLCIpCgogICAgZGVmIHJhaXNlX2V4Y2VwdGlvbl9pZl9hbnlfdG9wb2xvZ3lfZmxh - Z19pc19taXNzaW5nKHNlbGYpOgogICAgICAgIGlmICgKICAgICAgICAgICAgKAogICAgICAgICAg - ICAgICAgc2VsZi5fYXJnX3BhcnNlci50b3BvbG9neV9wb29scyAhPSAiIgogICAgICAgICAgICAg - ICAgYW5kICgKICAgICAgICAgICAgICAgICAgICBzZWxmLl9hcmdfcGFyc2VyLnRvcG9sb2d5X2Zh - aWx1cmVfZG9tYWluX2xhYmVsID09ICIiCiAgICAgICAgICAgICAgICAgICAgb3Igc2VsZi5fYXJn - X3BhcnNlci50b3BvbG9neV9mYWlsdXJlX2RvbWFpbl92YWx1ZXMgPT0gIiIKICAgICAgICAgICAg - ICAgICkKICAgICAgICAgICAgKQogICAgICAgICAgICBvciAoCiAgICAgICAgICAgICAgICBzZWxm - Ll9hcmdfcGFyc2VyLnRvcG9sb2d5X2ZhaWx1cmVfZG9tYWluX2xhYmVsICE9ICIiCiAgICAgICAg - ICAgICAgICBhbmQgKAogICAgICAgICAgICAgICAgICAgIHNlbGYuX2FyZ19wYXJzZXIudG9wb2xv - Z3lfcG9vbHMgPT0gIiIKICAgICAgICAgICAgICAgICAgICBvciBzZWxmLl9hcmdfcGFyc2VyLnRv - cG9sb2d5X2ZhaWx1cmVfZG9tYWluX3ZhbHVlcyA9PSAiIgogICAgICAgICAgICAgICAgKQogICAg - ICAgICAgICApCiAgICAgICAgICAgIG9yICgKICAgICAgICAgICAgICAgIHNlbGYuX2FyZ19wYXJz - ZXIudG9wb2xvZ3lfZmFpbHVyZV9kb21haW5fdmFsdWVzICE9ICIiCiAgICAgICAgICAgICAgICBh - bmQgKAogICAgICAgICAgICAgICAgICAgIHNlbGYuX2FyZ19wYXJzZXIudG9wb2xvZ3lfcG9vbHMg - PT0gIiIKICAgICAgICAgICAgICAgICAgICBvciBzZWxmLl9hcmdfcGFyc2VyLnRvcG9sb2d5X2Zh - aWx1cmVfZG9tYWluX2xhYmVsID09ICIiCiAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICkK - ICAgICAgICApOgogICAgICAgICAgICByYWlzZSBFeGVjdXRpb25GYWlsdXJlRXhjZXB0aW9uKAog - ICAgICAgICAgICAgICAgInByb3ZpZGUgYWxsIHRoZSB0b3BvbG9neSBmbGFncyAtLXRvcG9sb2d5 - LXBvb2xzLCAtLXRvcG9sb2d5LWZhaWx1cmUtZG9tYWluLWxhYmVsLCAtLXRvcG9sb2d5LWZhaWx1 - cmUtZG9tYWluLXZhbHVlcyIKICAgICAgICAgICAgKQoKICAgIGRlZiB2YWxpZGF0ZV90b3BvbG9n - eV92YWx1ZXMoc2VsZiwgdG9wb2xvZ3lfcG9vbHMsIHRvcG9sb2d5X2ZkKToKICAgICAgICBpZiBs - ZW4odG9wb2xvZ3lfcG9vbHMpICE9IGxlbih0b3BvbG9neV9mZCk6CiAgICAgICAgICAgIHJhaXNl - IEV4ZWN1dGlvbkZhaWx1cmVFeGNlcHRpb24oCiAgICAgICAgICAgICAgICBmIlRoZSBwcm92aWRl - ZCB0b3BvbG9neSBwb29scywgJ3t0b3BvbG9neV9wb29sc30nLCBhbmQgIgogICAgICAgICAgICAg - ICAgZiJ0b3BvbG9neSBmYWlsdXJlIGRvbWFpbiwgJ3t0b3BvbG9neV9mZH0nLCIKICAgICAgICAg - ICAgICAgIGYiYXJlIG9mIGRpZmZlcmVudCBsZW5ndGgsICd7bGVuKHRvcG9sb2d5X3Bvb2xzKX0n - IGFuZCAne2xlbih0b3BvbG9neV9mZCl9JyByZXNwY3RpdmVseSIKICAgICAgICAgICAgKQogICAg - ICAgIHJldHVybgoKICAgIGRlZiB2YWxpZGF0ZV90b3BvbG9neV9yYmRfcG9vbHMoc2VsZiwgdG9w - b2xvZ3lfcmJkX3Bvb2xzKToKICAgICAgICBmb3IgcG9vbCBpbiB0b3BvbG9neV9yYmRfcG9vbHM6 - CiAgICAgICAgICAgIHNlbGYudmFsaWRhdGVfcmJkX3Bvb2wocG9vbCkKCiAgICBkZWYgaW5pdF90 - b3BvbG9neV9yYmRfcG9vbHMoc2VsZiwgdG9wb2xvZ3lfcmJkX3Bvb2xzKToKICAgICAgICBmb3Ig - cG9vbCBpbiB0b3BvbG9neV9yYmRfcG9vbHM6CiAgICAgICAgICAgIHNlbGYuaW5pdF9yYmRfcG9v - bChwb29sKQoKICAgICMgdGhpcyB3aWxsIHJldHVybiB0aGUgZmluYWwgYXJncyB0aGF0IHNjcmlw - dCB1c2VzIHRvIHByb2Nlc3MKICAgICMgdGhlIHByaW9yaXR5IHRvIHNldCBhIHBhcnRpY3VsYXIg - dmFsdWUgaXMsCiAgICAjIGNvbW1hbmQtbGluZS1hcmdzID4gY29uZmlnLmluaSBmaWxlIHZhbHVl - cyA+IGRlZmF1bHQgdmFsdWVzCiAgICBkZWYgZ2V0RmluYWxVc2VkQXJncyhzZWxmKToKICAgICAg - ICBhcmd1bWVudCA9IGYiW0NvbmZpZ3VyYXRpb25zXVxuIgogICAgICAgIGZvciBhcmcgaW4gdmFy - cyhzZWxmLl9hcmdfcGFyc2VyKToKICAgICAgICAgICAgaWYgc3RyKGdldGF0dHIoc2VsZi5fYXJn - X3BhcnNlciwgYXJnKSk6CiAgICAgICAgICAgICAgICAjIHB5dGhvbiB0cmVhdHMgZmxhZy1uYW1l - IGFzIGZsYWdfbmFtZSBpbnRlcm5hbGx5LCBzbyBjb252ZXJ0aW5nIGJhY2sgdG8gZmxhZy1uYW1l - LAogICAgICAgICAgICAgICAgIyBzbyB3ZSBjYW4gZ2V0IHRob3NlIHZhbHVlcyBmcm9tIGNvbmZp - ZyBmaWxlCiAgICAgICAgICAgICAgICBhcmdWYWx1ZSA9IGFyZy5yZXBsYWNlKCJfIiwgIi0iKQog - ICAgICAgICAgICAgICAgIyBkbyBub3QgYWRkIHRoZSBjb25maWctZmlsZSBmbGFnIGFuZCBhbHNv - IG5vdCBhZGQgdGhlIGJvb2xlYW4gZmxhZ3Mgd2hpY2ggYXJlIHNldCB0byBGYWxzZQogICAgICAg - ICAgICAgICAgIyBiZWNhdXNlIGNvbmZpZy5pbmkgZmlsZSB0cmVhdHMgYm9vbGVhbiBmbGFncyBh - cyBUcnVlIGFsd2F5cwogICAgICAgICAgICAgICAgaWYgKAogICAgICAgICAgICAgICAgICAgIGFy - Z1ZhbHVlICE9ICJjb25maWctZmlsZSIKICAgICAgICAgICAgICAgICAgICBhbmQgZ2V0YXR0cihz - ZWxmLl9hcmdfcGFyc2VyLCBhcmcpICE9IEZhbHNlCiAgICAgICAgICAgICAgICApOgogICAgICAg - ICAgICAgICAgICAgIGFyZ3VtZW50ICs9IGYie2FyZ1ZhbHVlfSA9IHtzdHIoZ2V0YXR0cihzZWxm - Ll9hcmdfcGFyc2VyLCBhcmcpKX1cbiIKICAgICAgICByZXR1cm4gYXJndW1lbnQKCiAgICBkZWYg - X2dlbl9vdXRwdXRfbWFwKHNlbGYpOgogICAgICAgIGlmIHNlbGYub3V0X21hcDoKICAgICAgICAg - ICAgcmV0dXJuCiAgICAgICAgIyBzdXBwb3J0IGxlZ2FjeSBmbGFnIHdpdGggdXBncmFkZXMKICAg - ICAgICBpZiBzZWxmLl9hcmdfcGFyc2VyLmNsdXN0ZXJfbmFtZToKICAgICAgICAgICAgc2VsZi5f - YXJnX3BhcnNlci5rOHNfY2x1c3Rlcl9uYW1lID0gc2VsZi5fYXJnX3BhcnNlci5jbHVzdGVyX25h - bWUKICAgICAgICBzZWxmLl9hcmdfcGFyc2VyLms4c19jbHVzdGVyX25hbWUgPSAoCiAgICAgICAg - ICAgIHNlbGYuX2FyZ19wYXJzZXIuazhzX2NsdXN0ZXJfbmFtZS5sb3dlcigpCiAgICAgICAgKSAg - IyBhbHdheXMgY29udmVydCBjbHVzdGVyIG5hbWUgdG8gbG93ZXJjYXNlIGNoYXJhY3RlcnMKICAg - ICAgICBzZWxmLnZhbGlkYXRlX3JiZF9wb29sKHNlbGYuX2FyZ19wYXJzZXIucmJkX2RhdGFfcG9v - bF9uYW1lKQogICAgICAgIHNlbGYuaW5pdF9yYmRfcG9vbChzZWxmLl9hcmdfcGFyc2VyLnJiZF9k - YXRhX3Bvb2xfbmFtZSkKICAgICAgICBzZWxmLnZhbGlkYXRlX3JhZG9zX25hbWVzcGFjZSgpCiAg - ICAgICAgc2VsZi5fZXhjbHVkZWRfa2V5cy5hZGQoIks4U19DTFVTVEVSX05BTUUiKQogICAgICAg - IHNlbGYuZ2V0X2NlcGhmc19kYXRhX3Bvb2xfZGV0YWlscygpCiAgICAgICAgIyBkb3VibGUgc3Ry - aW5nIG5lZWRlZCBmb3IgdXBzdHJlYW0gZXhwb3J0cyBvZiBmbGFncwogICAgICAgIHNlbGYub3V0 - X21hcFsiQVJHUyJdID0gZicie3NlbGYuZ2V0RmluYWxVc2VkQXJncygpfSInCiAgICAgICAgc2Vs - Zi5vdXRfbWFwWyJOQU1FU1BBQ0UiXSA9IHNlbGYuX2FyZ19wYXJzZXIubmFtZXNwYWNlCiAgICAg - ICAgc2VsZi5vdXRfbWFwWyJLOFNfQ0xVU1RFUl9OQU1FIl0gPSBzZWxmLl9hcmdfcGFyc2VyLms4 - c19jbHVzdGVyX25hbWUKICAgICAgICBzZWxmLm91dF9tYXBbIlJPT0tfRVhURVJOQUxfRlNJRCJd - ID0gc2VsZi5nZXRfZnNpZCgpCiAgICAgICAgc2VsZi5vdXRfbWFwWyJST09LX0VYVEVSTkFMX1VT - RVJOQU1FIl0gPSBzZWxmLnJ1bl9hc191c2VyCiAgICAgICAgc2VsZi5vdXRfbWFwWyJST09LX0VY - VEVSTkFMX0NFUEhfTU9OX0RBVEEiXSA9IHNlbGYuZ2V0X2NlcGhfZXh0ZXJuYWxfbW9uX2RhdGEo - KQogICAgICAgIHNlbGYub3V0X21hcFsiUk9PS19FWFRFUk5BTF9VU0VSX1NFQ1JFVCJdID0gc2Vs - Zi5jcmVhdGVfY2hlY2tlcktleSgKICAgICAgICAgICAgImNsaWVudC5oZWFsdGhjaGVja2VyIgog - ICAgICAgICkKICAgICAgICBzZWxmLm91dF9tYXBbIlJPT0tfRVhURVJOQUxfREFTSEJPQVJEX0xJ - TksiXSA9IHNlbGYuZ2V0X2NlcGhfZGFzaGJvYXJkX2xpbmsoKQogICAgICAgICgKICAgICAgICAg - ICAgc2VsZi5vdXRfbWFwWyJDU0lfUkJEX05PREVfU0VDUkVUIl0sCiAgICAgICAgICAgIHNlbGYu - b3V0X21hcFsiQ1NJX1JCRF9OT0RFX1NFQ1JFVF9OQU1FIl0sCiAgICAgICAgKSA9IHNlbGYuY3Jl - YXRlX2NlcGhDU0lLZXlyaW5nX3VzZXIoImNsaWVudC5jc2ktcmJkLW5vZGUiKQogICAgICAgICgK - ICAgICAgICAgICAgc2VsZi5vdXRfbWFwWyJDU0lfUkJEX1BST1ZJU0lPTkVSX1NFQ1JFVCJdLAog - ICAgICAgICAgICBzZWxmLm91dF9tYXBbIkNTSV9SQkRfUFJPVklTSU9ORVJfU0VDUkVUX05BTUUi - XSwKICAgICAgICApID0gc2VsZi5jcmVhdGVfY2VwaENTSUtleXJpbmdfdXNlcigiY2xpZW50LmNz - aS1yYmQtcHJvdmlzaW9uZXIiKQogICAgICAgIHNlbGYub3V0X21hcFsiQ0VQSEZTX1BPT0xfTkFN - RSJdID0gc2VsZi5fYXJnX3BhcnNlci5jZXBoZnNfZGF0YV9wb29sX25hbWUKICAgICAgICBzZWxm - Lm91dF9tYXBbIkNFUEhGU19NRVRBREFUQV9QT09MX05BTUUiXSA9ICgKICAgICAgICAgICAgc2Vs - Zi5fYXJnX3BhcnNlci5jZXBoZnNfbWV0YWRhdGFfcG9vbF9uYW1lCiAgICAgICAgKQogICAgICAg - IHNlbGYub3V0X21hcFsiQ0VQSEZTX0ZTX05BTUUiXSA9IHNlbGYuX2FyZ19wYXJzZXIuY2VwaGZz - X2ZpbGVzeXN0ZW1fbmFtZQogICAgICAgIHNlbGYub3V0X21hcFsiUkVTVFJJQ1RFRF9BVVRIX1BF - Uk1JU1NJT04iXSA9ICgKICAgICAgICAgICAgc2VsZi5fYXJnX3BhcnNlci5yZXN0cmljdGVkX2F1 - dGhfcGVybWlzc2lvbgogICAgICAgICkKICAgICAgICBzZWxmLm91dF9tYXBbIlJBRE9TX05BTUVT - UEFDRSJdID0gc2VsZi5fYXJnX3BhcnNlci5yYWRvc19uYW1lc3BhY2UKICAgICAgICBzZWxmLm91 - dF9tYXBbIlNVQlZPTFVNRV9HUk9VUCJdID0gc2VsZi5fYXJnX3BhcnNlci5zdWJ2b2x1bWVfZ3Jv - dXAKICAgICAgICBzZWxmLm91dF9tYXBbIkNTSV9DRVBIRlNfTk9ERV9TRUNSRVQiXSA9ICIiCiAg - ICAgICAgc2VsZi5vdXRfbWFwWyJDU0lfQ0VQSEZTX1BST1ZJU0lPTkVSX1NFQ1JFVCJdID0gIiIK - ICAgICAgICAjIGNyZWF0ZSBDZXBoRlMgbm9kZSBhbmQgcHJvdmlzaW9uZXIga2V5cmluZyBvbmx5 - IHdoZW4gTURTIGV4aXN0cwogICAgICAgIGlmIHNlbGYub3V0X21hcFsiQ0VQSEZTX0ZTX05BTUUi - XSBhbmQgc2VsZi5vdXRfbWFwWyJDRVBIRlNfUE9PTF9OQU1FIl06CiAgICAgICAgICAgICgKICAg - ICAgICAgICAgICAgIHNlbGYub3V0X21hcFsiQ1NJX0NFUEhGU19OT0RFX1NFQ1JFVCJdLAogICAg - ICAgICAgICAgICAgc2VsZi5vdXRfbWFwWyJDU0lfQ0VQSEZTX05PREVfU0VDUkVUX05BTUUiXSwK - ICAgICAgICAgICAgKSA9IHNlbGYuY3JlYXRlX2NlcGhDU0lLZXlyaW5nX3VzZXIoImNsaWVudC5j - c2ktY2VwaGZzLW5vZGUiKQogICAgICAgICAgICAoCiAgICAgICAgICAgICAgICBzZWxmLm91dF9t - YXBbIkNTSV9DRVBIRlNfUFJPVklTSU9ORVJfU0VDUkVUIl0sCiAgICAgICAgICAgICAgICBzZWxm - Lm91dF9tYXBbIkNTSV9DRVBIRlNfUFJPVklTSU9ORVJfU0VDUkVUX05BTUUiXSwKICAgICAgICAg - ICAgKSA9IHNlbGYuY3JlYXRlX2NlcGhDU0lLZXlyaW5nX3VzZXIoImNsaWVudC5jc2ktY2VwaGZz - LXByb3Zpc2lvbmVyIikKICAgICAgICAgICAgIyBjcmVhdGUgdGhlIGRlZmF1bHQgImNzaSIgc3Vi - dm9sdW1lZ3JvdXAKICAgICAgICAgICAgc2VsZi5nZXRfb3JfY3JlYXRlX3N1YnZvbHVtZV9ncm91 - cCgKICAgICAgICAgICAgICAgICJjc2kiLCBzZWxmLl9hcmdfcGFyc2VyLmNlcGhmc19maWxlc3lz - dGVtX25hbWUKICAgICAgICAgICAgKQogICAgICAgICAgICAjIHBpbiB0aGUgZGVmYXVsdCAiY3Np - IiBzdWJ2b2x1bWVncm91cAogICAgICAgICAgICBzZWxmLnBpbl9zdWJ2b2x1bWUoCiAgICAgICAg - ICAgICAgICAiY3NpIiwgc2VsZi5fYXJnX3BhcnNlci5jZXBoZnNfZmlsZXN5c3RlbV9uYW1lLCAi - ZGlzdHJpYnV0ZWQiLCAiMSIKICAgICAgICAgICAgKQogICAgICAgICAgICBpZiBzZWxmLm91dF9t - YXBbIlNVQlZPTFVNRV9HUk9VUCJdOgogICAgICAgICAgICAgICAgc2VsZi5nZXRfb3JfY3JlYXRl - X3N1YnZvbHVtZV9ncm91cCgKICAgICAgICAgICAgICAgICAgICBzZWxmLl9hcmdfcGFyc2VyLnN1 - YnZvbHVtZV9ncm91cCwKICAgICAgICAgICAgICAgICAgICBzZWxmLl9hcmdfcGFyc2VyLmNlcGhm - c19maWxlc3lzdGVtX25hbWUsCiAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICAgICBzZWxm - LnBpbl9zdWJ2b2x1bWUoCiAgICAgICAgICAgICAgICAgICAgc2VsZi5fYXJnX3BhcnNlci5zdWJ2 - b2x1bWVfZ3JvdXAsCiAgICAgICAgICAgICAgICAgICAgc2VsZi5fYXJnX3BhcnNlci5jZXBoZnNf - ZmlsZXN5c3RlbV9uYW1lLAogICAgICAgICAgICAgICAgICAgICJkaXN0cmlidXRlZCIsCiAgICAg - ICAgICAgICAgICAgICAgIjEiLAogICAgICAgICAgICAgICAgKQogICAgICAgIHNlbGYub3V0X21h - cFsiUkdXX1RMU19DRVJUIl0gPSAiIgogICAgICAgIHNlbGYub3V0X21hcFsiTU9OSVRPUklOR19F - TkRQT0lOVCJdID0gIiIKICAgICAgICBzZWxmLm91dF9tYXBbIk1PTklUT1JJTkdfRU5EUE9JTlRf - UE9SVCJdID0gIiIKICAgICAgICBpZiBub3Qgc2VsZi5fYXJnX3BhcnNlci5za2lwX21vbml0b3Jp - bmdfZW5kcG9pbnQ6CiAgICAgICAgICAgICgKICAgICAgICAgICAgICAgIHNlbGYub3V0X21hcFsi - TU9OSVRPUklOR19FTkRQT0lOVCJdLAogICAgICAgICAgICAgICAgc2VsZi5vdXRfbWFwWyJNT05J - VE9SSU5HX0VORFBPSU5UX1BPUlQiXSwKICAgICAgICAgICAgKSA9IHNlbGYuZ2V0X2FjdGl2ZV9h - bmRfc3RhbmRieV9tZ3JzKCkKICAgICAgICBzZWxmLm91dF9tYXBbIlJCRF9QT09MX05BTUUiXSA9 - IHNlbGYuX2FyZ19wYXJzZXIucmJkX2RhdGFfcG9vbF9uYW1lCiAgICAgICAgc2VsZi5vdXRfbWFw - WyJSQkRfTUVUQURBVEFfRUNfUE9PTF9OQU1FIl0gPSAoCiAgICAgICAgICAgIHNlbGYudmFsaWRh - dGVfcmJkX21ldGFkYXRhX2VjX3Bvb2xfbmFtZSgpCiAgICAgICAgKQogICAgICAgIHNlbGYub3V0 - X21hcFsiVE9QT0xPR1lfUE9PTFMiXSA9IHNlbGYuX2FyZ19wYXJzZXIudG9wb2xvZ3lfcG9vbHMK - ICAgICAgICBzZWxmLm91dF9tYXBbIlRPUE9MT0dZX0ZBSUxVUkVfRE9NQUlOX0xBQkVMIl0gPSAo - CiAgICAgICAgICAgIHNlbGYuX2FyZ19wYXJzZXIudG9wb2xvZ3lfZmFpbHVyZV9kb21haW5fbGFi - ZWwKICAgICAgICApCiAgICAgICAgc2VsZi5vdXRfbWFwWyJUT1BPTE9HWV9GQUlMVVJFX0RPTUFJ - Tl9WQUxVRVMiXSA9ICgKICAgICAgICAgICAgc2VsZi5fYXJnX3BhcnNlci50b3BvbG9neV9mYWls - dXJlX2RvbWFpbl92YWx1ZXMKICAgICAgICApCiAgICAgICAgaWYgKAogICAgICAgICAgICBzZWxm - Ll9hcmdfcGFyc2VyLnRvcG9sb2d5X3Bvb2xzICE9ICIiCiAgICAgICAgICAgIGFuZCBzZWxmLl9h - cmdfcGFyc2VyLnRvcG9sb2d5X2ZhaWx1cmVfZG9tYWluX2xhYmVsICE9ICIiCiAgICAgICAgICAg - IGFuZCBzZWxmLl9hcmdfcGFyc2VyLnRvcG9sb2d5X2ZhaWx1cmVfZG9tYWluX3ZhbHVlcyAhPSAi - IgogICAgICAgICk6CiAgICAgICAgICAgIHNlbGYudmFsaWRhdGVfdG9wb2xvZ3lfdmFsdWVzKAog - ICAgICAgICAgICAgICAgc2VsZi5jb252ZXJ0X2NvbW1hX3NlcGFyYXRlZF90b19hcnJheShzZWxm - Lm91dF9tYXBbIlRPUE9MT0dZX1BPT0xTIl0pLAogICAgICAgICAgICAgICAgc2VsZi5jb252ZXJ0 - X2NvbW1hX3NlcGFyYXRlZF90b19hcnJheSgKICAgICAgICAgICAgICAgICAgICBzZWxmLm91dF9t - YXBbIlRPUE9MT0dZX0ZBSUxVUkVfRE9NQUlOX1ZBTFVFUyJdCiAgICAgICAgICAgICAgICApLAog - ICAgICAgICAgICApCiAgICAgICAgICAgIHNlbGYudmFsaWRhdGVfdG9wb2xvZ3lfcmJkX3Bvb2xz - KAogICAgICAgICAgICAgICAgc2VsZi5jb252ZXJ0X2NvbW1hX3NlcGFyYXRlZF90b19hcnJheShz - ZWxmLm91dF9tYXBbIlRPUE9MT0dZX1BPT0xTIl0pCiAgICAgICAgICAgICkKICAgICAgICAgICAg - c2VsZi5pbml0X3RvcG9sb2d5X3JiZF9wb29scygKICAgICAgICAgICAgICAgIHNlbGYuY29udmVy - dF9jb21tYV9zZXBhcmF0ZWRfdG9fYXJyYXkoc2VsZi5vdXRfbWFwWyJUT1BPTE9HWV9QT09MUyJd - KQogICAgICAgICAgICApCiAgICAgICAgZWxzZToKICAgICAgICAgICAgc2VsZi5yYWlzZV9leGNl - cHRpb25faWZfYW55X3RvcG9sb2d5X2ZsYWdfaXNfbWlzc2luZygpCgogICAgICAgIHNlbGYub3V0 - X21hcFsiUkdXX1BPT0xfUFJFRklYIl0gPSBzZWxmLl9hcmdfcGFyc2VyLnJnd19wb29sX3ByZWZp - eAogICAgICAgIHNlbGYub3V0X21hcFsiUkdXX0VORFBPSU5UIl0gPSAiIgogICAgICAgIGlmIHNl - bGYuX2FyZ19wYXJzZXIucmd3X2VuZHBvaW50OgogICAgICAgICAgICBpZiBzZWxmLl9hcmdfcGFy - c2VyLmRyeV9ydW46CiAgICAgICAgICAgICAgICBzZWxmLmNyZWF0ZV9yZ3dfYWRtaW5fb3BzX3Vz - ZXIoKQogICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgaWYgKAogICAgICAgICAgICAg - ICAgICAgIHNlbGYuX2FyZ19wYXJzZXIucmd3X3JlYWxtX25hbWUgIT0gIiIKICAgICAgICAgICAg - ICAgICAgICBhbmQgc2VsZi5fYXJnX3BhcnNlci5yZ3dfem9uZWdyb3VwX25hbWUgIT0gIiIKICAg - ICAgICAgICAgICAgICAgICBhbmQgc2VsZi5fYXJnX3BhcnNlci5yZ3dfem9uZV9uYW1lICE9ICIi - CiAgICAgICAgICAgICAgICApOgogICAgICAgICAgICAgICAgICAgIGVyciA9IHNlbGYudmFsaWRh - dGVfcmd3X211bHRpc2l0ZSgKICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5fYXJnX3BhcnNl - ci5yZ3dfcmVhbG1fbmFtZSwgInJlYWxtIgogICAgICAgICAgICAgICAgICAgICkKICAgICAgICAg - ICAgICAgICAgICBlcnIgPSBzZWxmLnZhbGlkYXRlX3Jnd19tdWx0aXNpdGUoCiAgICAgICAgICAg - ICAgICAgICAgICAgIHNlbGYuX2FyZ19wYXJzZXIucmd3X3pvbmVncm91cF9uYW1lLCAiem9uZWdy - b3VwIgogICAgICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgICAgICBlcnIgPSBzZWxm + ICAgICAgICAgICAgIidtZ3Igc2VydmljZXMnIGNvbW1hbmQgZmFpbGVkLlxuIgogICAgICAgICAg + ICAgICAgICAgIGYiRXJyb3I6IHtlcnJfbXNnIGlmIHJldF92YWwgIT0gMCBlbHNlIHNlbGYuRU1Q + VFlfT1VUUFVUX0xJU1R9IgogICAgICAgICAgICAgICAgKQogICAgICAgICAgICBtb25pdG9yaW5n + X2VuZHBvaW50ID0gKAogICAgICAgICAgICAgICAganNvbl9vdXQuZ2V0KCJtZ3JtYXAiLCB7fSku + Z2V0KCJzZXJ2aWNlcyIsIHt9KS5nZXQoInByb21ldGhldXMiLCAiIikKICAgICAgICAgICAgKQog + ICAgICAgICAgICBpZiBub3QgbW9uaXRvcmluZ19lbmRwb2ludDoKICAgICAgICAgICAgICAgIHJh + aXNlIEV4ZWN1dGlvbkZhaWx1cmVFeGNlcHRpb24oCiAgICAgICAgICAgICAgICAgICAgImNhbid0 + IGZpbmQgbW9uaXRvcmluZ19lbmRwb2ludCwgcHJvbWV0aGV1cyBtb2R1bGUgbWlnaHQgbm90IGJl + IGVuYWJsZWQsICIKICAgICAgICAgICAgICAgICAgICAiZW5hYmxlIHRoZSBtb2R1bGUgYnkgcnVu + bmluZyAnY2VwaCBtZ3IgbW9kdWxlIGVuYWJsZSBwcm9tZXRoZXVzJyIKICAgICAgICAgICAgICAg + ICkKICAgICAgICAgICAgIyBub3cgY2hlY2sgdGhlIHN0YW5kLWJ5IG1nci1zCiAgICAgICAgICAg + IHN0YW5kYnlfYXJyID0ganNvbl9vdXQuZ2V0KCJtZ3JtYXAiLCB7fSkuZ2V0KCJzdGFuZGJ5cyIs + IFtdKQogICAgICAgICAgICBmb3IgZWFjaF9zdGFuZGJ5IGluIHN0YW5kYnlfYXJyOgogICAgICAg + ICAgICAgICAgaWYgIm5hbWUiIGluIGVhY2hfc3RhbmRieS5rZXlzKCk6CiAgICAgICAgICAgICAg + ICAgICAgc3RhbmRieV9tZ3JzLmFwcGVuZChlYWNoX3N0YW5kYnlbIm5hbWUiXSkKICAgICAgICAg + ICAgdHJ5OgogICAgICAgICAgICAgICAgcGFyc2VkX2VuZHBvaW50ID0gdXJscGFyc2UobW9uaXRv + cmluZ19lbmRwb2ludCkKICAgICAgICAgICAgZXhjZXB0IFZhbHVlRXJyb3I6CiAgICAgICAgICAg + ICAgICByYWlzZSBFeGVjdXRpb25GYWlsdXJlRXhjZXB0aW9uKAogICAgICAgICAgICAgICAgICAg + IGYiaW52YWxpZCBlbmRwb2ludDoge21vbml0b3JpbmdfZW5kcG9pbnR9IgogICAgICAgICAgICAg + ICAgKQogICAgICAgICAgICBtb25pdG9yaW5nX2VuZHBvaW50X2lwX2xpc3QgPSBwYXJzZWRfZW5k + cG9pbnQuaG9zdG5hbWUKICAgICAgICAgICAgaWYgbm90IG1vbml0b3JpbmdfZW5kcG9pbnRfcG9y + dDoKICAgICAgICAgICAgICAgIG1vbml0b3JpbmdfZW5kcG9pbnRfcG9ydCA9IHN0cihwYXJzZWRf + ZW5kcG9pbnQucG9ydCkKCiAgICAgICAgIyBpZiBtb25pdG9yaW5nIGVuZHBvaW50IHBvcnQgaXMg + bm90IHNldCwgcHV0IGEgZGVmYXVsdCBtb24gcG9ydAogICAgICAgIGlmIG5vdCBtb25pdG9yaW5n + X2VuZHBvaW50X3BvcnQ6CiAgICAgICAgICAgIG1vbml0b3JpbmdfZW5kcG9pbnRfcG9ydCA9IHNl + bGYuREVGQVVMVF9NT05JVE9SSU5HX0VORFBPSU5UX1BPUlQKCiAgICAgICAgIyB1c2VyIGNvdWxk + IGdpdmUgY29tbWEgYW5kIHNwYWNlIHNlcGFyYXRlZCBpbnB1dHMgKGxpa2UgLS1tb25pdG9yaW5n + LWVuZHBvaW50PSI8aXAxPiwgPGlwMj4iKQogICAgICAgIG1vbml0b3JpbmdfZW5kcG9pbnRfaXBf + bGlzdCA9IG1vbml0b3JpbmdfZW5kcG9pbnRfaXBfbGlzdC5yZXBsYWNlKCIsIiwgIiAiKQogICAg + ICAgIG1vbml0b3JpbmdfZW5kcG9pbnRfaXBfbGlzdF9zcGxpdCA9IG1vbml0b3JpbmdfZW5kcG9p + bnRfaXBfbGlzdC5zcGxpdCgpCiAgICAgICAgIyBpZiBtb25pdG9yaW5nLWVuZHBvaW50IGNvdWxk + IG5vdCBiZSBmb3VuZCwgcmFpc2UgYW4gZXJyb3IKICAgICAgICBpZiBsZW4obW9uaXRvcmluZ19l + bmRwb2ludF9pcF9saXN0X3NwbGl0KSA9PSAwOgogICAgICAgICAgICByYWlzZSBFeGVjdXRpb25G + YWlsdXJlRXhjZXB0aW9uKCJObyAnbW9uaXRvcmluZy1lbmRwb2ludCcgZm91bmQiKQogICAgICAg + ICMgZmlyc3QgaXAgaXMgdHJlYXRlZCBhcyB0aGUgbWFpbiBtb25pdG9yaW5nLWVuZHBvaW50CiAg + ICAgICAgbW9uaXRvcmluZ19lbmRwb2ludF9pcCA9IG1vbml0b3JpbmdfZW5kcG9pbnRfaXBfbGlz + dF9zcGxpdFswXQogICAgICAgICMgcmVzdCBvZiB0aGUgaXAtcyBhcmUgYWRkZWQgdG8gdGhlICdz + dGFuZGJ5X21ncnMnIGxpc3QKICAgICAgICBzdGFuZGJ5X21ncnMuZXh0ZW5kKG1vbml0b3Jpbmdf + ZW5kcG9pbnRfaXBfbGlzdF9zcGxpdFsxOl0pCiAgICAgICAgZmFpbGVkX2lwID0gbW9uaXRvcmlu + Z19lbmRwb2ludF9pcAoKICAgICAgICBtb25pdG9yaW5nX2VuZHBvaW50ID0gIjoiLmpvaW4oCiAg + ICAgICAgICAgIFttb25pdG9yaW5nX2VuZHBvaW50X2lwLCBtb25pdG9yaW5nX2VuZHBvaW50X3Bv + cnRdCiAgICAgICAgKQogICAgICAgIGlwX3R5cGUgPSBzZWxmLl9pbnZhbGlkX2VuZHBvaW50KG1v + bml0b3JpbmdfZW5kcG9pbnQpCiAgICAgICAgdHJ5OgogICAgICAgICAgICBtb25pdG9yaW5nX2Vu + ZHBvaW50X2lwID0gc2VsZi5fY29udmVydF9ob3N0bmFtZV90b19pcCgKICAgICAgICAgICAgICAg + IG1vbml0b3JpbmdfZW5kcG9pbnRfaXAsIG1vbml0b3JpbmdfZW5kcG9pbnRfcG9ydCwgaXBfdHlw + ZQogICAgICAgICAgICApCiAgICAgICAgICAgICMgY29sbGVjdCBhbGwgdGhlICdzdGFuZC1ieScg + bWdyIGlwcwogICAgICAgICAgICBtZ3JfaXBzID0gW10KICAgICAgICAgICAgZm9yIGVhY2hfc3Rh + bmRieV9tZ3IgaW4gc3RhbmRieV9tZ3JzOgogICAgICAgICAgICAgICAgZmFpbGVkX2lwID0gZWFj + aF9zdGFuZGJ5X21ncgogICAgICAgICAgICAgICAgbWdyX2lwcy5hcHBlbmQoCiAgICAgICAgICAg + ICAgICAgICAgc2VsZi5fY29udmVydF9ob3N0bmFtZV90b19pcCgKICAgICAgICAgICAgICAgICAg + ICAgICAgZWFjaF9zdGFuZGJ5X21nciwgbW9uaXRvcmluZ19lbmRwb2ludF9wb3J0LCBpcF90eXBl + CiAgICAgICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgKQogICAgICAgIGV4Y2VwdDoK + ICAgICAgICAgICAgcmFpc2UgRXhlY3V0aW9uRmFpbHVyZUV4Y2VwdGlvbigKICAgICAgICAgICAg + ICAgIGYiQ29udmVyc2lvbiBvZiBob3N0OiB7ZmFpbGVkX2lwfSB0byBJUCBmYWlsZWQuICIKICAg + ICAgICAgICAgICAgICJQbGVhc2UgZW50ZXIgdGhlIElQIGFkZHJlc3NlcyBvZiBhbGwgdGhlIGNl + cGgtbWdycyB3aXRoIHRoZSAnLS1tb25pdG9yaW5nLWVuZHBvaW50JyBmbGFnIgogICAgICAgICAg + ICApCgogICAgICAgIF8sIF8sIGVyciA9IHNlbGYuZW5kcG9pbnRfZGlhbChtb25pdG9yaW5nX2Vu + ZHBvaW50LCBpcF90eXBlKQogICAgICAgIGlmIGVyciA9PSAiLTEiOgogICAgICAgICAgICByYWlz + ZSBFeGVjdXRpb25GYWlsdXJlRXhjZXB0aW9uKGVycikKICAgICAgICAjIGFkZCB0aGUgdmFsaWRh + dGVkIGFjdGl2ZSBtZ3IgSVAgaW50byB0aGUgZmlyc3QgaW5kZXgKICAgICAgICBtZ3JfaXBzLmlu + c2VydCgwLCBtb25pdG9yaW5nX2VuZHBvaW50X2lwKQogICAgICAgIGFsbF9tZ3JfaXBzX3N0ciA9 + ICIsIi5qb2luKG1ncl9pcHMpCiAgICAgICAgcmV0dXJuIGFsbF9tZ3JfaXBzX3N0ciwgbW9uaXRv + cmluZ19lbmRwb2ludF9wb3J0CgogICAgZGVmIGNoZWNrX3VzZXJfZXhpc3Qoc2VsZiwgdXNlcik6 + CiAgICAgICAgY21kX2pzb24gPSB7InByZWZpeCI6ICJhdXRoIGdldCIsICJlbnRpdHkiOiBmInt1 + c2VyfSIsICJmb3JtYXQiOiAianNvbiJ9CiAgICAgICAgcmV0X3ZhbCwganNvbl9vdXQsIF8gPSBz + ZWxmLl9jb21tb25fY21kX2pzb25fZ2VuKGNtZF9qc29uKQogICAgICAgIGlmIHJldF92YWwgIT0g + MCBvciBsZW4oanNvbl9vdXQpID09IDA6CiAgICAgICAgICAgIHJldHVybiAiIgogICAgICAgIHJl + dHVybiBzdHIoanNvbl9vdXRbMF1bImtleSJdKQoKICAgIGRlZiBnZXRfY2VwaGZzX3Byb3Zpc2lv + bmVyX2NhcHNfYW5kX2VudGl0eShzZWxmKToKICAgICAgICBlbnRpdHkgPSAiY2xpZW50LmNzaS1j + ZXBoZnMtcHJvdmlzaW9uZXIiCiAgICAgICAgY2FwcyA9IHsKICAgICAgICAgICAgIm1vbiI6ICJh + bGxvdyByLCBhbGxvdyBjb21tYW5kICdvc2QgYmxvY2tsaXN0JyIsCiAgICAgICAgICAgICJtZ3Ii + OiAiYWxsb3cgcnciLAogICAgICAgICAgICAib3NkIjogImFsbG93IHJ3IHRhZyBjZXBoZnMgbWV0 + YWRhdGE9KiIsCiAgICAgICAgICAgICJtZHMiOiAiYWxsb3cgKiIsCiAgICAgICAgfQogICAgICAg + IGlmIHNlbGYuX2FyZ19wYXJzZXIucmVzdHJpY3RlZF9hdXRoX3Blcm1pc3Npb246CiAgICAgICAg + ICAgIGs4c19jbHVzdGVyX25hbWUgPSBzZWxmLl9hcmdfcGFyc2VyLms4c19jbHVzdGVyX25hbWUK + ICAgICAgICAgICAgaWYgazhzX2NsdXN0ZXJfbmFtZSA9PSAiIjoKICAgICAgICAgICAgICAgIHJh + aXNlIEV4ZWN1dGlvbkZhaWx1cmVFeGNlcHRpb24oCiAgICAgICAgICAgICAgICAgICAgIms4c19j + bHVzdGVyX25hbWUgbm90IGZvdW5kLCBwbGVhc2Ugc2V0IHRoZSAnLS1rOHMtY2x1c3Rlci1uYW1l + JyBmbGFnIgogICAgICAgICAgICAgICAgKQogICAgICAgICAgICBjZXBoZnNfZmlsZXN5c3RlbSA9 + IHNlbGYuX2FyZ19wYXJzZXIuY2VwaGZzX2ZpbGVzeXN0ZW1fbmFtZQogICAgICAgICAgICBpZiBj + ZXBoZnNfZmlsZXN5c3RlbSA9PSAiIjoKICAgICAgICAgICAgICAgIGVudGl0eSA9IGYie2VudGl0 + eX0te2s4c19jbHVzdGVyX25hbWV9IgogICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAg + ZW50aXR5ID0gZiJ7ZW50aXR5fS17azhzX2NsdXN0ZXJfbmFtZX0te2NlcGhmc19maWxlc3lzdGVt + fSIKICAgICAgICAgICAgICAgIGNhcHNbIm9zZCJdID0gZiJhbGxvdyBydyB0YWcgY2VwaGZzIG1l + dGFkYXRhPXtjZXBoZnNfZmlsZXN5c3RlbX0iCgogICAgICAgIHJldHVybiBjYXBzLCBlbnRpdHkK + CiAgICBkZWYgZ2V0X2NlcGhmc19ub2RlX2NhcHNfYW5kX2VudGl0eShzZWxmKToKICAgICAgICBl + bnRpdHkgPSAiY2xpZW50LmNzaS1jZXBoZnMtbm9kZSIKICAgICAgICBjYXBzID0gewogICAgICAg + ICAgICAibW9uIjogImFsbG93IHIsIGFsbG93IGNvbW1hbmQgJ29zZCBibG9ja2xpc3QnIiwKICAg + ICAgICAgICAgIm1nciI6ICJhbGxvdyBydyIsCiAgICAgICAgICAgICJvc2QiOiAiYWxsb3cgcncg + dGFnIGNlcGhmcyAqPSoiLAogICAgICAgICAgICAibWRzIjogImFsbG93IHJ3IiwKICAgICAgICB9 + CiAgICAgICAgaWYgc2VsZi5fYXJnX3BhcnNlci5yZXN0cmljdGVkX2F1dGhfcGVybWlzc2lvbjoK + ICAgICAgICAgICAgazhzX2NsdXN0ZXJfbmFtZSA9IHNlbGYuX2FyZ19wYXJzZXIuazhzX2NsdXN0 + ZXJfbmFtZQogICAgICAgICAgICBpZiBrOHNfY2x1c3Rlcl9uYW1lID09ICIiOgogICAgICAgICAg + ICAgICAgcmFpc2UgRXhlY3V0aW9uRmFpbHVyZUV4Y2VwdGlvbigKICAgICAgICAgICAgICAgICAg + ICAiazhzX2NsdXN0ZXJfbmFtZSBub3QgZm91bmQsIHBsZWFzZSBzZXQgdGhlICctLWs4cy1jbHVz + dGVyLW5hbWUnIGZsYWciCiAgICAgICAgICAgICAgICApCiAgICAgICAgICAgIGNlcGhmc19maWxl + c3lzdGVtID0gc2VsZi5fYXJnX3BhcnNlci5jZXBoZnNfZmlsZXN5c3RlbV9uYW1lCiAgICAgICAg + ICAgIGlmIGNlcGhmc19maWxlc3lzdGVtID09ICIiOgogICAgICAgICAgICAgICAgZW50aXR5ID0g + ZiJ7ZW50aXR5fS17azhzX2NsdXN0ZXJfbmFtZX0iCiAgICAgICAgICAgIGVsc2U6CiAgICAgICAg + ICAgICAgICBlbnRpdHkgPSBmIntlbnRpdHl9LXtrOHNfY2x1c3Rlcl9uYW1lfS17Y2VwaGZzX2Zp + bGVzeXN0ZW19IgogICAgICAgICAgICAgICAgY2Fwc1sib3NkIl0gPSBmImFsbG93IHJ3IHRhZyBj + ZXBoZnMgKj17Y2VwaGZzX2ZpbGVzeXN0ZW19IgoKICAgICAgICByZXR1cm4gY2FwcywgZW50aXR5 + CgogICAgZGVmIGdldF9lbnRpdHkoCiAgICAgICAgc2VsZiwKICAgICAgICBlbnRpdHksCiAgICAg + ICAgcmJkX3Bvb2xfbmFtZSwKICAgICAgICBhbGlhc19yYmRfcG9vbF9uYW1lLAogICAgICAgIGs4 + c19jbHVzdGVyX25hbWUsCiAgICAgICAgcmFkb3NfbmFtZXNwYWNlLAogICAgKToKICAgICAgICBp + ZiAoCiAgICAgICAgICAgIHJiZF9wb29sX25hbWUuY291bnQoIi4iKSAhPSAwCiAgICAgICAgICAg + IG9yIHJiZF9wb29sX25hbWUuY291bnQoIl8iKSAhPSAwCiAgICAgICAgICAgIG9yIGFsaWFzX3Ji + ZF9wb29sX25hbWUgIT0gIiIKICAgICAgICAgICAgIyBjaGVja2luZyBhbGlhc19yYmRfcG9vbF9u + YW1lIGlzIG5vdCBlbXB0eSBhcyB0aGVyZSBtYXliZSBhIHNwZWNpYWwgY2hhcmFjdGVyIHVzZWQg + b3RoZXIgdGhhbiAuIG9yIF8KICAgICAgICApOgogICAgICAgICAgICBpZiBhbGlhc19yYmRfcG9v + bF9uYW1lID09ICIiOgogICAgICAgICAgICAgICAgcmFpc2UgRXhlY3V0aW9uRmFpbHVyZUV4Y2Vw + dGlvbigKICAgICAgICAgICAgICAgICAgICAicGxlYXNlIHNldCB0aGUgJy0tYWxpYXMtcmJkLWRh + dGEtcG9vbC1uYW1lJyBmbGFnIGFzIHRoZSByYmQgZGF0YSBwb29sIG5hbWUgY29udGFpbnMgJy4n + IG9yICdfJyIKICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgaWYgKAogICAgICAgICAgICAg + ICAgYWxpYXNfcmJkX3Bvb2xfbmFtZS5jb3VudCgiLiIpICE9IDAKICAgICAgICAgICAgICAgIG9y + IGFsaWFzX3JiZF9wb29sX25hbWUuY291bnQoIl8iKSAhPSAwCiAgICAgICAgICAgICk6CiAgICAg + ICAgICAgICAgICByYWlzZSBFeGVjdXRpb25GYWlsdXJlRXhjZXB0aW9uKAogICAgICAgICAgICAg + ICAgICAgICInLS1hbGlhcy1yYmQtZGF0YS1wb29sLW5hbWUnIGZsYWcgdmFsdWUgc2hvdWxkIG5v + dCBjb250YWluICcuJyBvciAnXyciCiAgICAgICAgICAgICAgICApCiAgICAgICAgICAgIGVudGl0 + eSA9IGYie2VudGl0eX0te2s4c19jbHVzdGVyX25hbWV9LXthbGlhc19yYmRfcG9vbF9uYW1lfSIK + ICAgICAgICBlbHNlOgogICAgICAgICAgICBlbnRpdHkgPSBmIntlbnRpdHl9LXtrOHNfY2x1c3Rl + cl9uYW1lfS17cmJkX3Bvb2xfbmFtZX0iCgogICAgICAgIGlmIHJhZG9zX25hbWVzcGFjZToKICAg + ICAgICAgICAgZW50aXR5ID0gZiJ7ZW50aXR5fS17cmFkb3NfbmFtZXNwYWNlfSIKICAgICAgICBy + ZXR1cm4gZW50aXR5CgogICAgZGVmIGdldF9yYmRfcHJvdmlzaW9uZXJfY2Fwc19hbmRfZW50aXR5 + KHNlbGYpOgogICAgICAgIGVudGl0eSA9ICJjbGllbnQuY3NpLXJiZC1wcm92aXNpb25lciIKICAg + ICAgICBjYXBzID0gewogICAgICAgICAgICAibW9uIjogInByb2ZpbGUgcmJkLCBhbGxvdyBjb21t + YW5kICdvc2QgYmxvY2tsaXN0JyIsCiAgICAgICAgICAgICJtZ3IiOiAiYWxsb3cgcnciLAogICAg + ICAgICAgICAib3NkIjogInByb2ZpbGUgcmJkIiwKICAgICAgICB9CiAgICAgICAgaWYgc2VsZi5f + YXJnX3BhcnNlci5yZXN0cmljdGVkX2F1dGhfcGVybWlzc2lvbjoKICAgICAgICAgICAgcmJkX3Bv + b2xfbmFtZSA9IHNlbGYuX2FyZ19wYXJzZXIucmJkX2RhdGFfcG9vbF9uYW1lCiAgICAgICAgICAg + IGFsaWFzX3JiZF9wb29sX25hbWUgPSBzZWxmLl9hcmdfcGFyc2VyLmFsaWFzX3JiZF9kYXRhX3Bv + b2xfbmFtZQogICAgICAgICAgICBrOHNfY2x1c3Rlcl9uYW1lID0gc2VsZi5fYXJnX3BhcnNlci5r + OHNfY2x1c3Rlcl9uYW1lCiAgICAgICAgICAgIHJhZG9zX25hbWVzcGFjZSA9IHNlbGYuX2FyZ19w + YXJzZXIucmFkb3NfbmFtZXNwYWNlCiAgICAgICAgICAgIGlmIHJiZF9wb29sX25hbWUgPT0gIiI6 + CiAgICAgICAgICAgICAgICByYWlzZSBFeGVjdXRpb25GYWlsdXJlRXhjZXB0aW9uKAogICAgICAg + ICAgICAgICAgICAgICJtYW5kYXRvcnkgZmxhZyBub3QgZm91bmQsIHBsZWFzZSBzZXQgdGhlICct + LXJiZC1kYXRhLXBvb2wtbmFtZScgZmxhZyIKICAgICAgICAgICAgICAgICkKICAgICAgICAgICAg + aWYgazhzX2NsdXN0ZXJfbmFtZSA9PSAiIjoKICAgICAgICAgICAgICAgIHJhaXNlIEV4ZWN1dGlv + bkZhaWx1cmVFeGNlcHRpb24oCiAgICAgICAgICAgICAgICAgICAgIm1hbmRhdG9yeSBmbGFnIG5v + dCBmb3VuZCwgcGxlYXNlIHNldCB0aGUgJy0tazhzLWNsdXN0ZXItbmFtZScgZmxhZyIKICAgICAg + ICAgICAgICAgICkKICAgICAgICAgICAgZW50aXR5ID0gc2VsZi5nZXRfZW50aXR5KAogICAgICAg + ICAgICAgICAgZW50aXR5LAogICAgICAgICAgICAgICAgcmJkX3Bvb2xfbmFtZSwKICAgICAgICAg + ICAgICAgIGFsaWFzX3JiZF9wb29sX25hbWUsCiAgICAgICAgICAgICAgICBrOHNfY2x1c3Rlcl9u + YW1lLAogICAgICAgICAgICAgICAgcmFkb3NfbmFtZXNwYWNlLAogICAgICAgICAgICApCiAgICAg + ICAgICAgIGlmIHJhZG9zX25hbWVzcGFjZSAhPSAiIjoKICAgICAgICAgICAgICAgIGNhcHNbIm9z + ZCJdID0gKAogICAgICAgICAgICAgICAgICAgIGYicHJvZmlsZSByYmQgcG9vbD17cmJkX3Bvb2xf + bmFtZX0gbmFtZXNwYWNlPXtyYWRvc19uYW1lc3BhY2V9IgogICAgICAgICAgICAgICAgKQogICAg + ICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgY2Fwc1sib3NkIl0gPSBmInByb2ZpbGUgcmJk + IHBvb2w9e3JiZF9wb29sX25hbWV9IgoKICAgICAgICByZXR1cm4gY2FwcywgZW50aXR5CgogICAg + ZGVmIGdldF9yYmRfbm9kZV9jYXBzX2FuZF9lbnRpdHkoc2VsZik6CiAgICAgICAgZW50aXR5ID0g + ImNsaWVudC5jc2ktcmJkLW5vZGUiCiAgICAgICAgY2FwcyA9IHsKICAgICAgICAgICAgIm1vbiI6 + ICJwcm9maWxlIHJiZCwgYWxsb3cgY29tbWFuZCAnb3NkIGJsb2NrbGlzdCciLAogICAgICAgICAg + ICAib3NkIjogInByb2ZpbGUgcmJkIiwKICAgICAgICB9CiAgICAgICAgaWYgc2VsZi5fYXJnX3Bh + cnNlci5yZXN0cmljdGVkX2F1dGhfcGVybWlzc2lvbjoKICAgICAgICAgICAgcmJkX3Bvb2xfbmFt + ZSA9IHNlbGYuX2FyZ19wYXJzZXIucmJkX2RhdGFfcG9vbF9uYW1lCiAgICAgICAgICAgIGFsaWFz + X3JiZF9wb29sX25hbWUgPSBzZWxmLl9hcmdfcGFyc2VyLmFsaWFzX3JiZF9kYXRhX3Bvb2xfbmFt + ZQogICAgICAgICAgICBrOHNfY2x1c3Rlcl9uYW1lID0gc2VsZi5fYXJnX3BhcnNlci5rOHNfY2x1 + c3Rlcl9uYW1lCiAgICAgICAgICAgIHJhZG9zX25hbWVzcGFjZSA9IHNlbGYuX2FyZ19wYXJzZXIu + cmFkb3NfbmFtZXNwYWNlCiAgICAgICAgICAgIGlmIHJiZF9wb29sX25hbWUgPT0gIiI6CiAgICAg + ICAgICAgICAgICByYWlzZSBFeGVjdXRpb25GYWlsdXJlRXhjZXB0aW9uKAogICAgICAgICAgICAg + ICAgICAgICJtYW5kYXRvcnkgZmxhZyBub3QgZm91bmQsIHBsZWFzZSBzZXQgdGhlICctLXJiZC1k + YXRhLXBvb2wtbmFtZScgZmxhZyIKICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgaWYgazhz + X2NsdXN0ZXJfbmFtZSA9PSAiIjoKICAgICAgICAgICAgICAgIHJhaXNlIEV4ZWN1dGlvbkZhaWx1 + cmVFeGNlcHRpb24oCiAgICAgICAgICAgICAgICAgICAgIm1hbmRhdG9yeSBmbGFnIG5vdCBmb3Vu + ZCwgcGxlYXNlIHNldCB0aGUgJy0tazhzLWNsdXN0ZXItbmFtZScgZmxhZyIKICAgICAgICAgICAg + ICAgICkKICAgICAgICAgICAgZW50aXR5ID0gc2VsZi5nZXRfZW50aXR5KAogICAgICAgICAgICAg + ICAgZW50aXR5LAogICAgICAgICAgICAgICAgcmJkX3Bvb2xfbmFtZSwKICAgICAgICAgICAgICAg + IGFsaWFzX3JiZF9wb29sX25hbWUsCiAgICAgICAgICAgICAgICBrOHNfY2x1c3Rlcl9uYW1lLAog + ICAgICAgICAgICAgICAgcmFkb3NfbmFtZXNwYWNlLAogICAgICAgICAgICApCiAgICAgICAgICAg + IGlmIHJhZG9zX25hbWVzcGFjZSAhPSAiIjoKICAgICAgICAgICAgICAgIGNhcHNbIm9zZCJdID0g + KAogICAgICAgICAgICAgICAgICAgIGYicHJvZmlsZSByYmQgcG9vbD17cmJkX3Bvb2xfbmFtZX0g + bmFtZXNwYWNlPXtyYWRvc19uYW1lc3BhY2V9IgogICAgICAgICAgICAgICAgKQogICAgICAgICAg + ICBlbHNlOgogICAgICAgICAgICAgICAgY2Fwc1sib3NkIl0gPSBmInByb2ZpbGUgcmJkIHBvb2w9 + e3JiZF9wb29sX25hbWV9IgoKICAgICAgICByZXR1cm4gY2FwcywgZW50aXR5CgogICAgZGVmIGdl + dF9kZWZhdWx0VXNlcl9jYXBzX2FuZF9lbnRpdHkoc2VsZik6CiAgICAgICAgZW50aXR5ID0gc2Vs + Zi5ydW5fYXNfdXNlcgogICAgICAgIGNhcHMgPSB7CiAgICAgICAgICAgICJtb24iOiAiYWxsb3cg + ciwgYWxsb3cgY29tbWFuZCBxdW9ydW1fc3RhdHVzLCBhbGxvdyBjb21tYW5kIHZlcnNpb24iLAog + ICAgICAgICAgICAibWdyIjogImFsbG93IGNvbW1hbmQgY29uZmlnIiwKICAgICAgICAgICAgIm9z + ZCI6IGYicHJvZmlsZSByYmQtcmVhZC1vbmx5LCBhbGxvdyByd3ggcG9vbD17c2VsZi5fYXJnX3Bh + cnNlci5yZ3dfcG9vbF9wcmVmaXh9LnJndy5tZXRhLCBhbGxvdyByIHBvb2w9LnJndy5yb290LCBh + bGxvdyBydyBwb29sPXtzZWxmLl9hcmdfcGFyc2VyLnJnd19wb29sX3ByZWZpeH0ucmd3LmNvbnRy + b2wsIGFsbG93IHJ4IHBvb2w9e3NlbGYuX2FyZ19wYXJzZXIucmd3X3Bvb2xfcHJlZml4fS5yZ3cu + bG9nLCBhbGxvdyB4IHBvb2w9e3NlbGYuX2FyZ19wYXJzZXIucmd3X3Bvb2xfcHJlZml4fS5yZ3cu + YnVja2V0cy5pbmRleCIsCiAgICAgICAgICAgICJtZHMiOiAiYWxsb3cgKiIsCiAgICAgICAgfQoK + ICAgICAgICByZXR1cm4gY2FwcywgZW50aXR5CgogICAgZGVmIGdldF9jYXBzX2FuZF9lbnRpdHko + c2VsZiwgdXNlcl9uYW1lKToKICAgICAgICBpZiAiY2xpZW50LmNzaS1jZXBoZnMtcHJvdmlzaW9u + ZXIiIGluIHVzZXJfbmFtZToKICAgICAgICAgICAgaWYgImNsaWVudC5jc2ktY2VwaGZzLXByb3Zp + c2lvbmVyIiAhPSB1c2VyX25hbWU6CiAgICAgICAgICAgICAgICBzZWxmLl9hcmdfcGFyc2VyLnJl + c3RyaWN0ZWRfYXV0aF9wZXJtaXNzaW9uID0gVHJ1ZQogICAgICAgICAgICByZXR1cm4gc2VsZi5n + ZXRfY2VwaGZzX3Byb3Zpc2lvbmVyX2NhcHNfYW5kX2VudGl0eSgpCiAgICAgICAgaWYgImNsaWVu + dC5jc2ktY2VwaGZzLW5vZGUiIGluIHVzZXJfbmFtZToKICAgICAgICAgICAgaWYgImNsaWVudC5j + c2ktY2VwaGZzLW5vZGUiICE9IHVzZXJfbmFtZToKICAgICAgICAgICAgICAgIHNlbGYuX2FyZ19w + YXJzZXIucmVzdHJpY3RlZF9hdXRoX3Blcm1pc3Npb24gPSBUcnVlCiAgICAgICAgICAgIHJldHVy + biBzZWxmLmdldF9jZXBoZnNfbm9kZV9jYXBzX2FuZF9lbnRpdHkoKQogICAgICAgIGlmICJjbGll + bnQuY3NpLXJiZC1wcm92aXNpb25lciIgaW4gdXNlcl9uYW1lOgogICAgICAgICAgICBpZiAiY2xp + ZW50LmNzaS1yYmQtcHJvdmlzaW9uZXIiICE9IHVzZXJfbmFtZToKICAgICAgICAgICAgICAgIHNl + bGYuX2FyZ19wYXJzZXIucmVzdHJpY3RlZF9hdXRoX3Blcm1pc3Npb24gPSBUcnVlCiAgICAgICAg + ICAgIHJldHVybiBzZWxmLmdldF9yYmRfcHJvdmlzaW9uZXJfY2Fwc19hbmRfZW50aXR5KCkKICAg + ICAgICBpZiAiY2xpZW50LmNzaS1yYmQtbm9kZSIgaW4gdXNlcl9uYW1lOgogICAgICAgICAgICBp + ZiAiY2xpZW50LmNzaS1yYmQtbm9kZSIgIT0gdXNlcl9uYW1lOgogICAgICAgICAgICAgICAgc2Vs + Zi5fYXJnX3BhcnNlci5yZXN0cmljdGVkX2F1dGhfcGVybWlzc2lvbiA9IFRydWUKICAgICAgICAg + ICAgcmV0dXJuIHNlbGYuZ2V0X3JiZF9ub2RlX2NhcHNfYW5kX2VudGl0eSgpCiAgICAgICAgaWYg + ImNsaWVudC5oZWFsdGhjaGVja2VyIiBpbiB1c2VyX25hbWU6CiAgICAgICAgICAgIGlmICJjbGll + bnQuaGVhbHRoY2hlY2tlciIgIT0gdXNlcl9uYW1lOgogICAgICAgICAgICAgICAgc2VsZi5fYXJn + X3BhcnNlci5yZXN0cmljdGVkX2F1dGhfcGVybWlzc2lvbiA9IFRydWUKICAgICAgICAgICAgcmV0 + dXJuIHNlbGYuZ2V0X2RlZmF1bHRVc2VyX2NhcHNfYW5kX2VudGl0eSgpCgogICAgICAgIHJhaXNl + IEV4ZWN1dGlvbkZhaWx1cmVFeGNlcHRpb24oCiAgICAgICAgICAgIGYibm8gdXNlciBmb3VuZCB3 + aXRoIHVzZXJfbmFtZToge3VzZXJfbmFtZX0sICIKICAgICAgICAgICAgImdldF9jYXBzX2FuZF9l + bnRpdHkgY29tbWFuZCBmYWlsZWQuXG4iCiAgICAgICAgKQoKICAgIGRlZiBjcmVhdGVfY2VwaENT + SUtleXJpbmdfdXNlcihzZWxmLCB1c2VyKToKICAgICAgICAiIiIKICAgICAgICBjb21tYW5kOiBj + ZXBoIGF1dGggZ2V0LW9yLWNyZWF0ZSBjbGllbnQuY3NpLWNlcGhmcy1wcm92aXNpb25lciBtb24g + J2FsbG93IHInIG1nciAnYWxsb3cgcncnIG9zZCAnYWxsb3cgcncgdGFnIGNlcGhmcyBtZXRhZGF0 + YT0qJwogICAgICAgICIiIgogICAgICAgIGNhcHMsIGVudGl0eSA9IHNlbGYuZ2V0X2NhcHNfYW5k + X2VudGl0eSh1c2VyKQogICAgICAgIGNtZF9qc29uID0gewogICAgICAgICAgICAicHJlZml4Ijog + ImF1dGggZ2V0LW9yLWNyZWF0ZSIsCiAgICAgICAgICAgICJlbnRpdHkiOiBlbnRpdHksCiAgICAg + ICAgICAgICJjYXBzIjogW2NhcCBmb3IgY2FwX2xpc3QgaW4gbGlzdChjYXBzLml0ZW1zKCkpIGZv + ciBjYXAgaW4gY2FwX2xpc3RdLAogICAgICAgICAgICAiZm9ybWF0IjogImpzb24iLAogICAgICAg + IH0KCiAgICAgICAgaWYgc2VsZi5fYXJnX3BhcnNlci5kcnlfcnVuOgogICAgICAgICAgICByZXR1 + cm4gKAogICAgICAgICAgICAgICAgc2VsZi5kcnlfcnVuKAogICAgICAgICAgICAgICAgICAgICJj + ZXBoICIKICAgICAgICAgICAgICAgICAgICArIGNtZF9qc29uWyJwcmVmaXgiXQogICAgICAgICAg + ICAgICAgICAgICsgIiAiCiAgICAgICAgICAgICAgICAgICAgKyBjbWRfanNvblsiZW50aXR5Il0K + ICAgICAgICAgICAgICAgICAgICArICIgIgogICAgICAgICAgICAgICAgICAgICsgIiAiLmpvaW4o + Y21kX2pzb25bImNhcHMiXSkKICAgICAgICAgICAgICAgICksCiAgICAgICAgICAgICAgICAiIiwK + ICAgICAgICAgICAgKQogICAgICAgICMgY2hlY2sgaWYgdXNlciBhbHJlYWR5IGV4aXN0CiAgICAg + ICAgdXNlcl9rZXkgPSBzZWxmLmNoZWNrX3VzZXJfZXhpc3QoZW50aXR5KQogICAgICAgIGlmIHVz + ZXJfa2V5ICE9ICIiOgogICAgICAgICAgICByZXR1cm4gdXNlcl9rZXksIGYie2VudGl0eS5zcGxp + dCgnLicsIDEpWzFdfSIKICAgICAgICAgICAgIyBlbnRpdHkuc3BsaXQoJy4nLDEpWzFdIHRvIHJl + bmFtZSBlbnRpdHkoY2xpZW50LmNzaS1yYmQtbm9kZSkgYXMgY3NpLXJiZC1ub2RlCgogICAgICAg + IHJldF92YWwsIGpzb25fb3V0LCBlcnJfbXNnID0gc2VsZi5fY29tbW9uX2NtZF9qc29uX2dlbihj + bWRfanNvbikKICAgICAgICAjIGlmIHRoZXJlIGlzIGFuIHVuc3VjY2Vzc2Z1bCBhdHRlbXB0LAog + ICAgICAgIGlmIHJldF92YWwgIT0gMCBvciBsZW4oanNvbl9vdXQpID09IDA6CiAgICAgICAgICAg + IHJhaXNlIEV4ZWN1dGlvbkZhaWx1cmVFeGNlcHRpb24oCiAgICAgICAgICAgICAgICBmIidhdXRo + IGdldC1vci1jcmVhdGUge3VzZXJ9JyBjb21tYW5kIGZhaWxlZC5cbiIKICAgICAgICAgICAgICAg + IGYiRXJyb3I6IHtlcnJfbXNnIGlmIHJldF92YWwgIT0gMCBlbHNlIHNlbGYuRU1QVFlfT1VUUFVU + X0xJU1R9IgogICAgICAgICAgICApCiAgICAgICAgcmV0dXJuIHN0cihqc29uX291dFswXVsia2V5 + Il0pLCBmIntlbnRpdHkuc3BsaXQoJy4nLCAxKVsxXX0iCiAgICAgICAgIyBlbnRpdHkuc3BsaXQo + Jy4nLDEpWzFdIHRvIHJlbmFtZSBlbnRpdHkoY2xpZW50LmNzaS1yYmQtbm9kZSkgYXMgY3NpLXJi + ZC1ub2RlCgogICAgZGVmIGdldF9jZXBoZnNfZGF0YV9wb29sX2RldGFpbHMoc2VsZik6CiAgICAg + ICAgY21kX2pzb24gPSB7InByZWZpeCI6ICJmcyBscyIsICJmb3JtYXQiOiAianNvbiJ9CiAgICAg + ICAgaWYgc2VsZi5fYXJnX3BhcnNlci5kcnlfcnVuOgogICAgICAgICAgICByZXR1cm4gc2VsZi5k + cnlfcnVuKCJjZXBoICIgKyBjbWRfanNvblsicHJlZml4Il0pCiAgICAgICAgcmV0X3ZhbCwganNv + bl9vdXQsIGVycl9tc2cgPSBzZWxmLl9jb21tb25fY21kX2pzb25fZ2VuKGNtZF9qc29uKQogICAg + ICAgICMgaWYgdGhlcmUgaXMgYW4gdW5zdWNjZXNzZnVsIGF0dGVtcHQsIHJlcG9ydCBhbiBlcnJv + cgogICAgICAgIGlmIHJldF92YWwgIT0gMDoKICAgICAgICAgICAgIyBpZiBmcyBhbmQgZGF0YV9w + b29sIGFyZ3VtZW50cyBhcmUgbm90IHNldCwgc2lsZW50bHkgcmV0dXJuCiAgICAgICAgICAgIGlm + ICgKICAgICAgICAgICAgICAgIHNlbGYuX2FyZ19wYXJzZXIuY2VwaGZzX2ZpbGVzeXN0ZW1fbmFt + ZSA9PSAiIgogICAgICAgICAgICAgICAgYW5kIHNlbGYuX2FyZ19wYXJzZXIuY2VwaGZzX2RhdGFf + cG9vbF9uYW1lID09ICIiCiAgICAgICAgICAgICk6CiAgICAgICAgICAgICAgICByZXR1cm4KICAg + ICAgICAgICAgIyBpZiB1c2VyIGhhcyBwcm92aWRlZCBhbnkgb2YgdGhlCiAgICAgICAgICAgICMg + Jy0tY2VwaGZzLWZpbGVzeXN0ZW0tbmFtZScgb3IgJy0tY2VwaGZzLWRhdGEtcG9vbC1uYW1lJyBh + cmd1bWVudHMsCiAgICAgICAgICAgICMgcmFpc2UgYW4gZXhjZXB0aW9uIGFzIHdlIGFyZSB1bmFi + bGUgdG8gdmVyaWZ5IHRoZSBhcmdzCiAgICAgICAgICAgIHJhaXNlIEV4ZWN1dGlvbkZhaWx1cmVF + eGNlcHRpb24oCiAgICAgICAgICAgICAgICBmIidmcyBscycgY2VwaCBjYWxsIGZhaWxlZCB3aXRo + IGVycm9yOiB7ZXJyX21zZ30iCiAgICAgICAgICAgICkKCiAgICAgICAgbWF0Y2hpbmdfanNvbl9v + dXQgPSB7fQogICAgICAgICMgaWYgJy0tY2VwaGZzLWZpbGVzeXN0ZW0tbmFtZScgYXJndW1lbnQg + aXMgcHJvdmlkZWQsCiAgICAgICAgIyBjaGVjayB3aGV0aGVyIHRoZSBwcm92aWRlZCBmaWxlc3lz + dGVtLW5hbWUgZXhpc3RzIG9yIG5vdAogICAgICAgIGlmIHNlbGYuX2FyZ19wYXJzZXIuY2VwaGZz + X2ZpbGVzeXN0ZW1fbmFtZToKICAgICAgICAgICAgIyBnZXQgdGhlIG1hdGNoaW5nIGxpc3QKICAg + ICAgICAgICAgbWF0Y2hpbmdfanNvbl9vdXRfbGlzdCA9IFsKICAgICAgICAgICAgICAgIG1hdGNo + ZWQKICAgICAgICAgICAgICAgIGZvciBtYXRjaGVkIGluIGpzb25fb3V0CiAgICAgICAgICAgICAg + ICBpZiBzdHIobWF0Y2hlZFsibmFtZSJdKSA9PSBzZWxmLl9hcmdfcGFyc2VyLmNlcGhmc19maWxl + c3lzdGVtX25hbWUKICAgICAgICAgICAgXQogICAgICAgICAgICAjIHVuYWJsZSB0byBmaW5kIGEg + bWF0Y2hpbmcgZnMtbmFtZSwgcmFpc2UgYW4gZXJyb3IKICAgICAgICAgICAgaWYgbGVuKG1hdGNo + aW5nX2pzb25fb3V0X2xpc3QpID09IDA6CiAgICAgICAgICAgICAgICByYWlzZSBFeGVjdXRpb25G + YWlsdXJlRXhjZXB0aW9uKAogICAgICAgICAgICAgICAgICAgIGYiRmlsZXN5c3RlbSBwcm92aWRl + ZCwgJ3tzZWxmLl9hcmdfcGFyc2VyLmNlcGhmc19maWxlc3lzdGVtX25hbWV9JywgIgogICAgICAg + ICAgICAgICAgICAgIGYiaXMgbm90IGZvdW5kIGluIHRoZSBmcy1saXN0OiB7W3N0cih4WyduYW1l + J10pIGZvciB4IGluIGpzb25fb3V0XX0iCiAgICAgICAgICAgICAgICApCiAgICAgICAgICAgIG1h + dGNoaW5nX2pzb25fb3V0ID0gbWF0Y2hpbmdfanNvbl9vdXRfbGlzdFswXQogICAgICAgICMgaWYg + Y2VwaGZzIGZpbGVzeXN0ZW0gbmFtZSBpcyBub3QgcHJvdmlkZWQsCiAgICAgICAgIyB0cnkgdG8g + Z2V0IGEgZGVmYXVsdCBmcyBuYW1lIGJ5IGRvaW5nIHRoZSBmb2xsb3dpbmcKICAgICAgICBlbHNl + OgogICAgICAgICAgICAjIGEuIGNoZWNrIGlmIHRoZXJlIGlzIG9ubHkgb25lIGZpbGVzeXN0ZW0g + aXMgcHJlc2VudAogICAgICAgICAgICBpZiBsZW4oanNvbl9vdXQpID09IDE6CiAgICAgICAgICAg + ICAgICBtYXRjaGluZ19qc29uX291dCA9IGpzb25fb3V0WzBdCiAgICAgICAgICAgICMgYi4gb3Ig + ZWxzZSwgY2hlY2sgaWYgZGF0YV9wb29sIG5hbWUgaXMgcHJvdmlkZWQKICAgICAgICAgICAgZWxp + ZiBzZWxmLl9hcmdfcGFyc2VyLmNlcGhmc19kYXRhX3Bvb2xfbmFtZToKICAgICAgICAgICAgICAg + ICMgYW5kIGlmIHByZXNlbnQsIGNoZWNrIHdoZXRoZXIgdGhlcmUgZXhpc3RzIGEgZnMgd2hpY2gg + aGFzIHRoZSBkYXRhX3Bvb2wKICAgICAgICAgICAgICAgIGZvciBlYWNoSiBpbiBqc29uX291dDoK + ICAgICAgICAgICAgICAgICAgICBpZiBzZWxmLl9hcmdfcGFyc2VyLmNlcGhmc19kYXRhX3Bvb2xf + bmFtZSBpbiBlYWNoSlsiZGF0YV9wb29scyJdOgogICAgICAgICAgICAgICAgICAgICAgICBtYXRj + aGluZ19qc29uX291dCA9IGVhY2hKCiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrCiAgICAg + ICAgICAgICAgICAjIGlmIHRoZXJlIGlzIG5vIG1hdGNoaW5nIGZzIGV4aXN0cywgdGhhdCBtZWFu + cyBwcm92aWRlZCBkYXRhX3Bvb2wgbmFtZSBpcyBpbnZhbGlkCiAgICAgICAgICAgICAgICBpZiBu + b3QgbWF0Y2hpbmdfanNvbl9vdXQ6CiAgICAgICAgICAgICAgICAgICAgcmFpc2UgRXhlY3V0aW9u + RmFpbHVyZUV4Y2VwdGlvbigKICAgICAgICAgICAgICAgICAgICAgICAgZiJQcm92aWRlZCBkYXRh + X3Bvb2wgbmFtZSwge3NlbGYuX2FyZ19wYXJzZXIuY2VwaGZzX2RhdGFfcG9vbF9uYW1lfSwiCiAg + ICAgICAgICAgICAgICAgICAgICAgICIgZG9lcyBub3QgZXhpc3RzIgogICAgICAgICAgICAgICAg + ICAgICkKICAgICAgICAgICAgIyBjLiBpZiBub3RoaW5nIGlzIHNldCBhbmQgY291bGRuJ3QgZmlu + ZCBhIGRlZmF1bHQsCiAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICAjIGp1c3QgcmV0 + dXJuIHNpbGVudGx5CiAgICAgICAgICAgICAgICByZXR1cm4KCiAgICAgICAgaWYgbWF0Y2hpbmdf + anNvbl9vdXQ6CiAgICAgICAgICAgIHNlbGYuX2FyZ19wYXJzZXIuY2VwaGZzX2ZpbGVzeXN0ZW1f + bmFtZSA9IHN0cihtYXRjaGluZ19qc29uX291dFsibmFtZSJdKQogICAgICAgICAgICBzZWxmLl9h + cmdfcGFyc2VyLmNlcGhmc19tZXRhZGF0YV9wb29sX25hbWUgPSBzdHIoCiAgICAgICAgICAgICAg + ICBtYXRjaGluZ19qc29uX291dFsibWV0YWRhdGFfcG9vbCJdCiAgICAgICAgICAgICkKCiAgICAg + ICAgaWYgaXNpbnN0YW5jZShtYXRjaGluZ19qc29uX291dFsiZGF0YV9wb29scyJdLCBsaXN0KToK + ICAgICAgICAgICAgIyBpZiB0aGUgdXNlciBoYXMgYWxyZWFkeSBwcm92aWRlZCBkYXRhLXBvb2wt + bmFtZSwKICAgICAgICAgICAgIyB0aHJvdWdoIC0tY2VwaGZzLWRhdGEtcG9vbC1uYW1lCiAgICAg + ICAgICAgIGlmIHNlbGYuX2FyZ19wYXJzZXIuY2VwaGZzX2RhdGFfcG9vbF9uYW1lOgogICAgICAg + ICAgICAgICAgIyBpZiB0aGUgcHJvdmlkZWQgbmFtZSBpcyBub3QgbWF0Y2hpbmcgd2l0aCB0aGUg + b25lIGluIHRoZSBsaXN0CiAgICAgICAgICAgICAgICBpZiAoCiAgICAgICAgICAgICAgICAgICAg + c2VsZi5fYXJnX3BhcnNlci5jZXBoZnNfZGF0YV9wb29sX25hbWUKICAgICAgICAgICAgICAgICAg + ICBub3QgaW4gbWF0Y2hpbmdfanNvbl9vdXRbImRhdGFfcG9vbHMiXQogICAgICAgICAgICAgICAg + KToKICAgICAgICAgICAgICAgICAgICByYWlzZSBFeGVjdXRpb25GYWlsdXJlRXhjZXB0aW9uKAog + ICAgICAgICAgICAgICAgICAgICAgICBmIlByb3ZpZGVkIGRhdGEtcG9vbC1uYW1lOiAne3NlbGYu + X2FyZ19wYXJzZXIuY2VwaGZzX2RhdGFfcG9vbF9uYW1lfScsICIKICAgICAgICAgICAgICAgICAg + ICAgICAgImRvZXNuJ3QgbWF0Y2ggZnJvbSB0aGUgZGF0YS1wb29scyBsaXN0OiAiCiAgICAgICAg + ICAgICAgICAgICAgICAgIGYie1tzdHIoeCkgZm9yIHggaW4gbWF0Y2hpbmdfanNvbl9vdXRbJ2Rh + dGFfcG9vbHMnXV19IgogICAgICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgIyBpZiBkYXRh + X3Bvb2wgbmFtZSBpcyBub3QgcHJvdmlkZWQsCiAgICAgICAgICAgICMgdGhlbiB0cnkgdG8gZmlu + ZCBhIGRlZmF1bHQgZGF0YSBwb29sIG5hbWUKICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAg + ICAgICMgaWYgbm8gZGF0YV9wb29scyBleGlzdCwgc2lsZW50bHkgcmV0dXJuCiAgICAgICAgICAg + ICAgICBpZiBsZW4obWF0Y2hpbmdfanNvbl9vdXRbImRhdGFfcG9vbHMiXSkgPT0gMDoKICAgICAg + ICAgICAgICAgICAgICByZXR1cm4KICAgICAgICAgICAgICAgIHNlbGYuX2FyZ19wYXJzZXIuY2Vw + aGZzX2RhdGFfcG9vbF9uYW1lID0gc3RyKAogICAgICAgICAgICAgICAgICAgIG1hdGNoaW5nX2pz + b25fb3V0WyJkYXRhX3Bvb2xzIl1bMF0KICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgIyBp + ZiB0aGVyZSBhcmUgbW9yZSB0aGFuIG9uZSAnZGF0YV9wb29scycgZXhpc3QsCiAgICAgICAgICAg + ICMgdGhlbiB3YXJuIHRoZSB1c2VyIHRoYXQgd2UgYXJlIHVzaW5nIHRoZSBzZWxlY3RlZCBuYW1l + CiAgICAgICAgICAgIGlmIGxlbihtYXRjaGluZ19qc29uX291dFsiZGF0YV9wb29scyJdKSA+IDE6 + CiAgICAgICAgICAgICAgICBwcmludCgKICAgICAgICAgICAgICAgICAgICAiV0FSTklORzogTXVs + dGlwbGUgZGF0YSBwb29scyBkZXRlY3RlZDogIgogICAgICAgICAgICAgICAgICAgIGYie1tzdHIo + eCkgZm9yIHggaW4gbWF0Y2hpbmdfanNvbl9vdXRbJ2RhdGFfcG9vbHMnXV19XG4iCiAgICAgICAg + ICAgICAgICAgICAgZiJVc2luZyB0aGUgZGF0YS1wb29sOiAne3NlbGYuX2FyZ19wYXJzZXIuY2Vw + aGZzX2RhdGFfcG9vbF9uYW1lfSdcbiIKICAgICAgICAgICAgICAgICkKCiAgICBkZWYgY3JlYXRl + X2NoZWNrZXJLZXkoc2VsZiwgdXNlcik6CiAgICAgICAgY2FwcywgZW50aXR5ID0gc2VsZi5nZXRf + Y2Fwc19hbmRfZW50aXR5KHVzZXIpCiAgICAgICAgY21kX2pzb24gPSB7CiAgICAgICAgICAgICJw + cmVmaXgiOiAiYXV0aCBnZXQtb3ItY3JlYXRlIiwKICAgICAgICAgICAgImVudGl0eSI6IGVudGl0 + eSwKICAgICAgICAgICAgImNhcHMiOiBbY2FwIGZvciBjYXBfbGlzdCBpbiBsaXN0KGNhcHMuaXRl + bXMoKSkgZm9yIGNhcCBpbiBjYXBfbGlzdF0sCiAgICAgICAgICAgICJmb3JtYXQiOiAianNvbiIs + CiAgICAgICAgfQoKICAgICAgICBpZiBzZWxmLl9hcmdfcGFyc2VyLmRyeV9ydW46CiAgICAgICAg + ICAgIHJldHVybiBzZWxmLmRyeV9ydW4oCiAgICAgICAgICAgICAgICAiY2VwaCAiCiAgICAgICAg + ICAgICAgICArIGNtZF9qc29uWyJwcmVmaXgiXQogICAgICAgICAgICAgICAgKyAiICIKICAgICAg + ICAgICAgICAgICsgY21kX2pzb25bImVudGl0eSJdCiAgICAgICAgICAgICAgICArICIgIgogICAg + ICAgICAgICAgICAgKyAiICIuam9pbihjbWRfanNvblsiY2FwcyJdKQogICAgICAgICAgICApCiAg + ICAgICAgIyBjaGVjayBpZiB1c2VyIGFscmVhZHkgZXhpc3QKICAgICAgICB1c2VyX2tleSA9IHNl + bGYuY2hlY2tfdXNlcl9leGlzdChlbnRpdHkpCiAgICAgICAgaWYgdXNlcl9rZXkgIT0gIiI6CiAg + ICAgICAgICAgIHJldHVybiB1c2VyX2tleQoKICAgICAgICByZXRfdmFsLCBqc29uX291dCwgZXJy + X21zZyA9IHNlbGYuX2NvbW1vbl9jbWRfanNvbl9nZW4oY21kX2pzb24pCiAgICAgICAgIyBpZiB0 + aGVyZSBpcyBhbiB1bnN1Y2Nlc3NmdWwgYXR0ZW1wdCwKICAgICAgICBpZiByZXRfdmFsICE9IDAg + b3IgbGVuKGpzb25fb3V0KSA9PSAwOgogICAgICAgICAgICByYWlzZSBFeGVjdXRpb25GYWlsdXJl + RXhjZXB0aW9uKAogICAgICAgICAgICAgICAgZiInYXV0aCBnZXQtb3ItY3JlYXRlIHtzZWxmLnJ1 + bl9hc191c2VyfScgY29tbWFuZCBmYWlsZWRcbiIKICAgICAgICAgICAgICAgIGYiRXJyb3I6IHtl + cnJfbXNnIGlmIHJldF92YWwgIT0gMCBlbHNlIHNlbGYuRU1QVFlfT1VUUFVUX0xJU1R9IgogICAg + ICAgICAgICApCiAgICAgICAgcmV0dXJuIHN0cihqc29uX291dFswXVsia2V5Il0pCgogICAgZGVm + IGdldF9jZXBoX2Rhc2hib2FyZF9saW5rKHNlbGYpOgogICAgICAgIGNtZF9qc29uID0geyJwcmVm + aXgiOiAibWdyIHNlcnZpY2VzIiwgImZvcm1hdCI6ICJqc29uIn0KICAgICAgICBpZiBzZWxmLl9h + cmdfcGFyc2VyLmRyeV9ydW46CiAgICAgICAgICAgIHJldHVybiBzZWxmLmRyeV9ydW4oImNlcGgg + IiArIGNtZF9qc29uWyJwcmVmaXgiXSkKICAgICAgICByZXRfdmFsLCBqc29uX291dCwgXyA9IHNl + bGYuX2NvbW1vbl9jbWRfanNvbl9nZW4oY21kX2pzb24pCiAgICAgICAgIyBpZiB0aGVyZSBpcyBh + biB1bnN1Y2Nlc3NmdWwgYXR0ZW1wdCwKICAgICAgICBpZiByZXRfdmFsICE9IDAgb3IgbGVuKGpz + b25fb3V0KSA9PSAwOgogICAgICAgICAgICByZXR1cm4gTm9uZQogICAgICAgIGlmICJkYXNoYm9h + cmQiIG5vdCBpbiBqc29uX291dDoKICAgICAgICAgICAgcmV0dXJuIE5vbmUKICAgICAgICByZXR1 + cm4ganNvbl9vdXRbImRhc2hib2FyZCJdCgogICAgZGVmIGNyZWF0ZV9yZ3dfYWRtaW5fb3BzX3Vz + ZXIoc2VsZik6CiAgICAgICAgY21kID0gWwogICAgICAgICAgICAicmFkb3Nndy1hZG1pbiIsCiAg + ICAgICAgICAgICJ1c2VyIiwKICAgICAgICAgICAgImNyZWF0ZSIsCiAgICAgICAgICAgICItLXVp + ZCIsCiAgICAgICAgICAgIHNlbGYuRVhURVJOQUxfUkdXX0FETUlOX09QU19VU0VSX05BTUUsCiAg + ICAgICAgICAgICItLWRpc3BsYXktbmFtZSIsCiAgICAgICAgICAgICJSb29rIFJHVyBBZG1pbiBP + cHMgdXNlciIsCiAgICAgICAgICAgICItLWNhcHMiLAogICAgICAgICAgICAiYnVja2V0cz0qO3Vz + ZXJzPSo7dXNhZ2U9cmVhZDttZXRhZGF0YT1yZWFkO3pvbmU9cmVhZCIsCiAgICAgICAgICAgICIt + LXJndy1yZWFsbSIsCiAgICAgICAgICAgIHNlbGYuX2FyZ19wYXJzZXIucmd3X3JlYWxtX25hbWUs + CiAgICAgICAgICAgICItLXJndy16b25lZ3JvdXAiLAogICAgICAgICAgICBzZWxmLl9hcmdfcGFy + c2VyLnJnd196b25lZ3JvdXBfbmFtZSwKICAgICAgICAgICAgIi0tcmd3LXpvbmUiLAogICAgICAg + ICAgICBzZWxmLl9hcmdfcGFyc2VyLnJnd196b25lX25hbWUsCiAgICAgICAgXQogICAgICAgIGlm + IHNlbGYuX2FyZ19wYXJzZXIuZHJ5X3J1bjoKICAgICAgICAgICAgcmV0dXJuIHNlbGYuZHJ5X3J1 + bigiY2VwaCAiICsgIiAiLmpvaW4oY21kKSkKICAgICAgICB0cnk6CiAgICAgICAgICAgIG91dHB1 + dCA9IHN1YnByb2Nlc3MuY2hlY2tfb3V0cHV0KGNtZCwgc3RkZXJyPXN1YnByb2Nlc3MuUElQRSkK + ICAgICAgICBleGNlcHQgc3VicHJvY2Vzcy5DYWxsZWRQcm9jZXNzRXJyb3IgYXMgZXhlY0VycjoK + ICAgICAgICAgICAgIyBpZiB0aGUgdXNlciBhbHJlYWR5IGV4aXN0cywgd2UganVzdCBxdWVyeSBp + dAogICAgICAgICAgICBpZiBleGVjRXJyLnJldHVybmNvZGUgPT0gZXJybm8uRUVYSVNUOgogICAg + ICAgICAgICAgICAgY21kID0gWwogICAgICAgICAgICAgICAgICAgICJyYWRvc2d3LWFkbWluIiwK + ICAgICAgICAgICAgICAgICAgICAidXNlciIsCiAgICAgICAgICAgICAgICAgICAgImluZm8iLAog + ICAgICAgICAgICAgICAgICAgICItLXVpZCIsCiAgICAgICAgICAgICAgICAgICAgc2VsZi5FWFRF + Uk5BTF9SR1dfQURNSU5fT1BTX1VTRVJfTkFNRSwKICAgICAgICAgICAgICAgICAgICAiLS1yZ3ct + cmVhbG0iLAogICAgICAgICAgICAgICAgICAgIHNlbGYuX2FyZ19wYXJzZXIucmd3X3JlYWxtX25h + bWUsCiAgICAgICAgICAgICAgICAgICAgIi0tcmd3LXpvbmVncm91cCIsCiAgICAgICAgICAgICAg + ICAgICAgc2VsZi5fYXJnX3BhcnNlci5yZ3dfem9uZWdyb3VwX25hbWUsCiAgICAgICAgICAgICAg + ICAgICAgIi0tcmd3LXpvbmUiLAogICAgICAgICAgICAgICAgICAgIHNlbGYuX2FyZ19wYXJzZXIu + cmd3X3pvbmVfbmFtZSwKICAgICAgICAgICAgICAgIF0KICAgICAgICAgICAgICAgIHRyeToKICAg + ICAgICAgICAgICAgICAgICBvdXRwdXQgPSBzdWJwcm9jZXNzLmNoZWNrX291dHB1dChjbWQsIHN0 + ZGVycj1zdWJwcm9jZXNzLlBJUEUpCiAgICAgICAgICAgICAgICBleGNlcHQgc3VicHJvY2Vzcy5D + YWxsZWRQcm9jZXNzRXJyb3IgYXMgZXhlY0VycjoKICAgICAgICAgICAgICAgICAgICBlcnJfbXNn + ID0gKAogICAgICAgICAgICAgICAgICAgICAgICBmImZhaWxlZCB0byBleGVjdXRlIGNvbW1hbmQg + e2NtZH0uIE91dHB1dDoge2V4ZWNFcnIub3V0cHV0fS4gIgogICAgICAgICAgICAgICAgICAgICAg + ICBmIkNvZGU6IHtleGVjRXJyLnJldHVybmNvZGV9LiBFcnJvcjoge2V4ZWNFcnIuc3RkZXJyfSIK + ICAgICAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICAgICAgICAgc3lzLnN0ZGVyci53cml0 + ZShlcnJfbXNnKQogICAgICAgICAgICAgICAgICAgIHJldHVybiBOb25lLCBOb25lLCBGYWxzZSwg + Ii0xIgogICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgZXJyX21zZyA9ICgKICAgICAg + ICAgICAgICAgICAgICBmImZhaWxlZCB0byBleGVjdXRlIGNvbW1hbmQge2NtZH0uIE91dHB1dDog + e2V4ZWNFcnIub3V0cHV0fS4gIgogICAgICAgICAgICAgICAgICAgIGYiQ29kZToge2V4ZWNFcnIu + cmV0dXJuY29kZX0uIEVycm9yOiB7ZXhlY0Vyci5zdGRlcnJ9IgogICAgICAgICAgICAgICAgKQog + ICAgICAgICAgICAgICAgc3lzLnN0ZGVyci53cml0ZShlcnJfbXNnKQogICAgICAgICAgICAgICAg + cmV0dXJuIE5vbmUsIE5vbmUsIEZhbHNlLCAiLTEiCgogICAgICAgICMgc2VwYXJhdGVseSBhZGQg + aW5mbz1yZWFkIGNhcHMgZm9yIHJndy1lbmRwb2ludCBpcCB2YWxpZGF0aW9uCiAgICAgICAgaW5m + b19jYXBfc3VwcG9ydGVkID0gVHJ1ZQogICAgICAgIGNtZCA9IFsKICAgICAgICAgICAgInJhZG9z + Z3ctYWRtaW4iLAogICAgICAgICAgICAiY2FwcyIsCiAgICAgICAgICAgICJhZGQiLAogICAgICAg + ICAgICAiLS11aWQiLAogICAgICAgICAgICBzZWxmLkVYVEVSTkFMX1JHV19BRE1JTl9PUFNfVVNF + Ul9OQU1FLAogICAgICAgICAgICAiLS1jYXBzIiwKICAgICAgICAgICAgImluZm89cmVhZCIsCiAg + ICAgICAgICAgICItLXJndy1yZWFsbSIsCiAgICAgICAgICAgIHNlbGYuX2FyZ19wYXJzZXIucmd3 + X3JlYWxtX25hbWUsCiAgICAgICAgICAgICItLXJndy16b25lZ3JvdXAiLAogICAgICAgICAgICBz + ZWxmLl9hcmdfcGFyc2VyLnJnd196b25lZ3JvdXBfbmFtZSwKICAgICAgICAgICAgIi0tcmd3LXpv + bmUiLAogICAgICAgICAgICBzZWxmLl9hcmdfcGFyc2VyLnJnd196b25lX25hbWUsCiAgICAgICAg + XQogICAgICAgIHRyeToKICAgICAgICAgICAgb3V0cHV0ID0gc3VicHJvY2Vzcy5jaGVja19vdXRw + dXQoY21kLCBzdGRlcnI9c3VicHJvY2Vzcy5QSVBFKQogICAgICAgIGV4Y2VwdCBzdWJwcm9jZXNz + LkNhbGxlZFByb2Nlc3NFcnJvciBhcyBleGVjRXJyOgogICAgICAgICAgICAjIGlmIHRoZSBjZXBo + IHZlcnNpb24gbm90IHN1cHBvcnRlZCBmb3IgYWRkaW5nIGBpbmZvPXJlYWRgIGNhcChyZ3dfdmFs + aWRhdGlvbikKICAgICAgICAgICAgaWYgKAogICAgICAgICAgICAgICAgImNvdWxkIG5vdCBhZGQg + Y2FwczogdW5hYmxlIHRvIGFkZCBjYXBzOiBpbmZvPXJlYWRcbiIKICAgICAgICAgICAgICAgIGlu + IGV4ZWNFcnIuc3RkZXJyLmRlY29kZSgidXRmLTgiKQogICAgICAgICAgICAgICAgYW5kIGV4ZWNF + cnIucmV0dXJuY29kZSA9PSAyNDQKICAgICAgICAgICAgKToKICAgICAgICAgICAgICAgIGluZm9f + Y2FwX3N1cHBvcnRlZCA9IEZhbHNlCiAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICBl + cnJfbXNnID0gKAogICAgICAgICAgICAgICAgICAgIGYiZmFpbGVkIHRvIGV4ZWN1dGUgY29tbWFu + ZCB7Y21kfS4gT3V0cHV0OiB7ZXhlY0Vyci5vdXRwdXR9LiAiCiAgICAgICAgICAgICAgICAgICAg + ZiJDb2RlOiB7ZXhlY0Vyci5yZXR1cm5jb2RlfS4gRXJyb3I6IHtleGVjRXJyLnN0ZGVycn0iCiAg + ICAgICAgICAgICAgICApCiAgICAgICAgICAgICAgICBzeXMuc3RkZXJyLndyaXRlKGVycl9tc2cp + CiAgICAgICAgICAgICAgICByZXR1cm4gTm9uZSwgTm9uZSwgRmFsc2UsICItMSIKCiAgICAgICAg + anNvbm91dHB1dCA9IGpzb24ubG9hZHMob3V0cHV0KQogICAgICAgIHJldHVybiAoCiAgICAgICAg + ICAgIGpzb25vdXRwdXRbImtleXMiXVswXVsiYWNjZXNzX2tleSJdLAogICAgICAgICAgICBqc29u + b3V0cHV0WyJrZXlzIl1bMF1bInNlY3JldF9rZXkiXSwKICAgICAgICAgICAgaW5mb19jYXBfc3Vw + cG9ydGVkLAogICAgICAgICAgICAiIiwKICAgICAgICApCgogICAgZGVmIHZhbGlkYXRlX3JiZF9w + b29sKHNlbGYsIHBvb2xfbmFtZSk6CiAgICAgICAgaWYgbm90IHNlbGYuY2x1c3Rlci5wb29sX2V4 + aXN0cyhwb29sX25hbWUpOgogICAgICAgICAgICByYWlzZSBFeGVjdXRpb25GYWlsdXJlRXhjZXB0 + aW9uKAogICAgICAgICAgICAgICAgZiJUaGUgcHJvdmlkZWQgcG9vbCwgJ3twb29sX25hbWV9Jywg + ZG9lcyBub3QgZXhpc3QiCiAgICAgICAgICAgICkKCiAgICBkZWYgaW5pdF9yYmRfcG9vbChzZWxm + LCByYmRfcG9vbF9uYW1lKToKICAgICAgICBpZiBpc2luc3RhbmNlKHNlbGYuY2x1c3RlciwgRHVt + bXlSYWRvcyk6CiAgICAgICAgICAgIHJldHVybgogICAgICAgIGlvY3R4ID0gc2VsZi5jbHVzdGVy + Lm9wZW5faW9jdHgocmJkX3Bvb2xfbmFtZSkKICAgICAgICByYmRfaW5zdCA9IHJiZC5SQkQoKQog + ICAgICAgIHJiZF9pbnN0LnBvb2xfaW5pdChpb2N0eCwgVHJ1ZSkKCiAgICBkZWYgdmFsaWRhdGVf + cmFkb3NfbmFtZXNwYWNlKHNlbGYpOgogICAgICAgIHJiZF9wb29sX25hbWUgPSBzZWxmLl9hcmdf + cGFyc2VyLnJiZF9kYXRhX3Bvb2xfbmFtZQogICAgICAgIGlmIHNlbGYuX2FyZ19wYXJzZXIucmJk + X21ldGFkYXRhX2VjX3Bvb2xfbmFtZToKICAgICAgICAgICAgcmJkX3Bvb2xfbmFtZSA9IHNlbGYu + X2FyZ19wYXJzZXIucmJkX21ldGFkYXRhX2VjX3Bvb2xfbmFtZQogICAgICAgIHJhZG9zX25hbWVz + cGFjZSA9IHNlbGYuX2FyZ19wYXJzZXIucmFkb3NfbmFtZXNwYWNlCiAgICAgICAgaWYgcmFkb3Nf + bmFtZXNwYWNlID09ICIiOgogICAgICAgICAgICByZXR1cm4KICAgICAgICBpZiByYWRvc19uYW1l + c3BhY2UuaXNsb3dlcigpID09IEZhbHNlOgogICAgICAgICAgICByYWlzZSBFeGVjdXRpb25GYWls + dXJlRXhjZXB0aW9uKAogICAgICAgICAgICAgICAgZiJUaGUgcHJvdmlkZWQgcmFkb3MgTmFtZXNw + YWNlLCAne3JhZG9zX25hbWVzcGFjZX0nLCAiCiAgICAgICAgICAgICAgICBmImNvbnRhaW5zIHVw + cGVyIGNhc2UiCiAgICAgICAgICAgICkKICAgICAgICByYmRfaW5zdCA9IHJiZC5SQkQoKQogICAg + ICAgIGlvY3R4ID0gc2VsZi5jbHVzdGVyLm9wZW5faW9jdHgocmJkX3Bvb2xfbmFtZSkKICAgICAg + ICBpZiByYmRfaW5zdC5uYW1lc3BhY2VfZXhpc3RzKGlvY3R4LCByYWRvc19uYW1lc3BhY2UpIGlz + IEZhbHNlOgogICAgICAgICAgICByYWlzZSBFeGVjdXRpb25GYWlsdXJlRXhjZXB0aW9uKAogICAg + ICAgICAgICAgICAgZiJUaGUgcHJvdmlkZWQgcmFkb3MgTmFtZXNwYWNlLCAne3JhZG9zX25hbWVz + cGFjZX0nLCAiCiAgICAgICAgICAgICAgICBmImlzIG5vdCBmb3VuZCBpbiB0aGUgcG9vbCAne3Ji + ZF9wb29sX25hbWV9JyIKICAgICAgICAgICAgKQoKICAgIGRlZiBnZXRfb3JfY3JlYXRlX3N1YnZv + bHVtZV9ncm91cChzZWxmLCBzdWJ2b2x1bWVfZ3JvdXAsIGNlcGhmc19maWxlc3lzdGVtX25hbWUp + OgogICAgICAgIGNtZCA9IFsKICAgICAgICAgICAgImNlcGgiLAogICAgICAgICAgICAiZnMiLAog + ICAgICAgICAgICAic3Vidm9sdW1lZ3JvdXAiLAogICAgICAgICAgICAiZ2V0cGF0aCIsCiAgICAg + ICAgICAgIGNlcGhmc19maWxlc3lzdGVtX25hbWUsCiAgICAgICAgICAgIHN1YnZvbHVtZV9ncm91 + cCwKICAgICAgICBdCiAgICAgICAgdHJ5OgogICAgICAgICAgICBfID0gc3VicHJvY2Vzcy5jaGVj + a19vdXRwdXQoY21kLCBzdGRlcnI9c3VicHJvY2Vzcy5QSVBFKQogICAgICAgIGV4Y2VwdCBzdWJw + cm9jZXNzLkNhbGxlZFByb2Nlc3NFcnJvcjoKICAgICAgICAgICAgY21kID0gWwogICAgICAgICAg + ICAgICAgImNlcGgiLAogICAgICAgICAgICAgICAgImZzIiwKICAgICAgICAgICAgICAgICJzdWJ2 + b2x1bWVncm91cCIsCiAgICAgICAgICAgICAgICAiY3JlYXRlIiwKICAgICAgICAgICAgICAgIGNl + cGhmc19maWxlc3lzdGVtX25hbWUsCiAgICAgICAgICAgICAgICBzdWJ2b2x1bWVfZ3JvdXAsCiAg + ICAgICAgICAgIF0KICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgXyA9IHN1YnByb2Nl + c3MuY2hlY2tfb3V0cHV0KGNtZCwgc3RkZXJyPXN1YnByb2Nlc3MuUElQRSkKICAgICAgICAgICAg + ZXhjZXB0IHN1YnByb2Nlc3MuQ2FsbGVkUHJvY2Vzc0Vycm9yOgogICAgICAgICAgICAgICAgcmFp + c2UgRXhlY3V0aW9uRmFpbHVyZUV4Y2VwdGlvbigKICAgICAgICAgICAgICAgICAgICBmInN1YnZv + bHVtZSBncm91cCB7c3Vidm9sdW1lX2dyb3VwfSBpcyBub3QgYWJsZSB0byBnZXQgY3JlYXRlZCIK + ICAgICAgICAgICAgICAgICkKCiAgICBkZWYgcGluX3N1YnZvbHVtZSgKICAgICAgICBzZWxmLCBz + dWJ2b2x1bWVfZ3JvdXAsIGNlcGhmc19maWxlc3lzdGVtX25hbWUsIHBpbl90eXBlLCBwaW5fc2V0 + dGluZwogICAgKToKICAgICAgICBjbWQgPSBbCiAgICAgICAgICAgICJjZXBoIiwKICAgICAgICAg + ICAgImZzIiwKICAgICAgICAgICAgInN1YnZvbHVtZWdyb3VwIiwKICAgICAgICAgICAgInBpbiIs + CiAgICAgICAgICAgIGNlcGhmc19maWxlc3lzdGVtX25hbWUsCiAgICAgICAgICAgIHN1YnZvbHVt + ZV9ncm91cCwKICAgICAgICAgICAgcGluX3R5cGUsCiAgICAgICAgICAgIHBpbl9zZXR0aW5nLAog + ICAgICAgIF0KICAgICAgICB0cnk6CiAgICAgICAgICAgIF8gPSBzdWJwcm9jZXNzLmNoZWNrX291 + dHB1dChjbWQsIHN0ZGVycj1zdWJwcm9jZXNzLlBJUEUpCiAgICAgICAgZXhjZXB0IHN1YnByb2Nl + c3MuQ2FsbGVkUHJvY2Vzc0Vycm9yOgogICAgICAgICAgICByYWlzZSBFeGVjdXRpb25GYWlsdXJl + RXhjZXB0aW9uKAogICAgICAgICAgICAgICAgZiJzdWJ2b2x1bWUgZ3JvdXAge3N1YnZvbHVtZV9n + cm91cH0gaXMgbm90IGFibGUgdG8gZ2V0IHBpbm5lZCIKICAgICAgICAgICAgKQoKICAgIGRlZiBn + ZXRfcmd3X2ZzaWQoc2VsZiwgYmFzZV91cmwsIHZlcmlmeSk6CiAgICAgICAgYWNjZXNzX2tleSA9 + IHNlbGYub3V0X21hcFsiUkdXX0FETUlOX09QU19VU0VSX0FDQ0VTU19LRVkiXQogICAgICAgIHNl + Y3JldF9rZXkgPSBzZWxmLm91dF9tYXBbIlJHV19BRE1JTl9PUFNfVVNFUl9TRUNSRVRfS0VZIl0K + ICAgICAgICByZ3dfZW5kcG9pbnQgPSBzZWxmLl9hcmdfcGFyc2VyLnJnd19lbmRwb2ludAogICAg + ICAgIGJhc2VfdXJsID0gYmFzZV91cmwgKyAiOi8vIiArIHJnd19lbmRwb2ludCArICIvYWRtaW4v + aW5mbz8iCiAgICAgICAgcGFyYW1zID0geyJmb3JtYXQiOiAianNvbiJ9CiAgICAgICAgcmVxdWVz + dF91cmwgPSBiYXNlX3VybCArIHVybGVuY29kZShwYXJhbXMpCgogICAgICAgIHRyeToKICAgICAg + ICAgICAgciA9IHJlcXVlc3RzLmdldCgKICAgICAgICAgICAgICAgIHJlcXVlc3RfdXJsLAogICAg + ICAgICAgICAgICAgYXV0aD1TM0F1dGgoYWNjZXNzX2tleSwgc2VjcmV0X2tleSwgcmd3X2VuZHBv + aW50KSwKICAgICAgICAgICAgICAgIHZlcmlmeT12ZXJpZnksCiAgICAgICAgICAgICkKICAgICAg + ICBleGNlcHQgcmVxdWVzdHMuZXhjZXB0aW9ucy5UaW1lb3V0OgogICAgICAgICAgICBzeXMuc3Rk + ZXJyLndyaXRlKAogICAgICAgICAgICAgICAgZiJpbnZhbGlkIGVuZHBvaW50Oiwgbm90IGFibGUg + dG8gY2FsbCBhZG1pbi1vcHMgYXBpe3Jnd19lbmRwb2ludH0iCiAgICAgICAgICAgICkKICAgICAg + ICAgICAgcmV0dXJuICIiLCAiLTEiCiAgICAgICAgcjEgPSByLmpzb24oKQogICAgICAgIGlmIHIx + IGlzIE5vbmUgb3IgcjEuZ2V0KCJpbmZvIikgaXMgTm9uZToKICAgICAgICAgICAgc3lzLnN0ZGVy + ci53cml0ZSgKICAgICAgICAgICAgICAgIGYiVGhlIHByb3ZpZGVkIHJndyBFbmRwb2ludCwgJ3tz + ZWxmLl9hcmdfcGFyc2VyLnJnd19lbmRwb2ludH0nLCBpcyBpbnZhbGlkLiIKICAgICAgICAgICAg + KQogICAgICAgICAgICByZXR1cm4gKAogICAgICAgICAgICAgICAgIiIsCiAgICAgICAgICAgICAg + ICAiLTEiLAogICAgICAgICAgICApCgogICAgICAgIHJldHVybiByMVsiaW5mbyJdWyJzdG9yYWdl + X2JhY2tlbmRzIl1bMF1bImNsdXN0ZXJfaWQiXSwgIiIKCiAgICBkZWYgdmFsaWRhdGVfcmd3X2Vu + ZHBvaW50KHNlbGYsIGluZm9fY2FwX3N1cHBvcnRlZCk6CiAgICAgICAgIyBpZiB0aGUgJ2NsdXN0 + ZXInIGluc3RhbmNlIGlzIGEgZHVtbXkgb25lLAogICAgICAgICMgZG9uJ3QgdHJ5IHRvIHJlYWNo + IG91dCB0byB0aGUgZW5kcG9pbnQKICAgICAgICBpZiBpc2luc3RhbmNlKHNlbGYuY2x1c3Rlciwg + RHVtbXlSYWRvcyk6CiAgICAgICAgICAgIHJldHVybgoKICAgICAgICByZ3dfZW5kcG9pbnQgPSBz + ZWxmLl9hcmdfcGFyc2VyLnJnd19lbmRwb2ludAoKICAgICAgICAjIHZhbGlkYXRlIHJndyBlbmRw + b2ludCBvbmx5IGlmIGlwIGFkZHJlc3MgaXMgcGFzc2VkCiAgICAgICAgaXBfdHlwZSA9IHNlbGYu + X2ludmFsaWRfZW5kcG9pbnQocmd3X2VuZHBvaW50KQoKICAgICAgICAjIGNoZWNrIGlmIHRoZSBy + Z3cgZW5kcG9pbnQgaXMgcmVhY2hhYmxlCiAgICAgICAgY2VydCA9IE5vbmUKICAgICAgICBpZiBu + b3Qgc2VsZi5fYXJnX3BhcnNlci5yZ3dfc2tpcF90bHMgYW5kIHNlbGYudmFsaWRhdGVfcmd3X2Vu + ZHBvaW50X3Rsc19jZXJ0KCk6CiAgICAgICAgICAgIGNlcnQgPSBzZWxmLl9hcmdfcGFyc2VyLnJn + d190bHNfY2VydF9wYXRoCiAgICAgICAgYmFzZV91cmwsIHZlcmlmeSwgZXJyID0gc2VsZi5lbmRw + b2ludF9kaWFsKHJnd19lbmRwb2ludCwgaXBfdHlwZSwgY2VydD1jZXJ0KQogICAgICAgIGlmIGVy + ciAhPSAiIjoKICAgICAgICAgICAgcmV0dXJuICItMSIKCiAgICAgICAgIyBjaGVjayBpZiB0aGUg + cmd3IGVuZHBvaW50IGJlbG9uZ3MgdG8gdGhlIHNhbWUgY2x1c3RlcgogICAgICAgICMgb25seSBj + aGVjayBpZiBgaW5mb2AgY2FwIGlzIHN1cHBvcnRlZAogICAgICAgIGlmIGluZm9fY2FwX3N1cHBv + cnRlZDoKICAgICAgICAgICAgZnNpZCA9IHNlbGYuZ2V0X2ZzaWQoKQogICAgICAgICAgICByZ3df + ZnNpZCwgZXJyID0gc2VsZi5nZXRfcmd3X2ZzaWQoYmFzZV91cmwsIHZlcmlmeSkKICAgICAgICAg + ICAgaWYgZXJyID09ICItMSI6CiAgICAgICAgICAgICAgICByZXR1cm4gIi0xIgogICAgICAgICAg + ICBpZiBmc2lkICE9IHJnd19mc2lkOgogICAgICAgICAgICAgICAgc3lzLnN0ZGVyci53cml0ZSgK + ICAgICAgICAgICAgICAgICAgICBmIlRoZSBwcm92aWRlZCByZ3cgRW5kcG9pbnQsICd7c2VsZi5f + YXJnX3BhcnNlci5yZ3dfZW5kcG9pbnR9JywgaXMgaW52YWxpZC4gV2UgYXJlIHZhbGlkYXRpbmcg + YnkgY2FsbGluZyB0aGUgYWRtaW5vcHMgYXBpIHRocm91Z2ggcmd3LWVuZHBvaW50IGFuZCB2YWxp + ZGF0aW5nIHRoZSBjbHVzdGVyX2lkICd7cmd3X2ZzaWR9JyBpcyBlcXVhbCB0byB0aGUgY2VwaCBj + bHVzdGVyIGZzaWQgJ3tmc2lkfSciCiAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICAgICBy + ZXR1cm4gIi0xIgoKICAgICAgICAjIGNoZWNrIGlmIHRoZSByZ3cgZW5kcG9pbnQgcG9vbCBleGlz + dAogICAgICAgICMgb25seSB2YWxpZGF0ZSBpZiByZ3dfcG9vbF9wcmVmaXggaXMgcGFzc2VkIGVs + c2UgaXQgd2lsbCB0YWtlIGRlZmF1bHQgdmFsdWUgYW5kIHdlIGRvbid0IGNyZWF0ZSB0aGVzZSBk + ZWZhdWx0IHBvb2xzCiAgICAgICAgaWYgc2VsZi5fYXJnX3BhcnNlci5yZ3dfcG9vbF9wcmVmaXgg + IT0gImRlZmF1bHQiOgogICAgICAgICAgICByZ3dfcG9vbHNfdG9fdmFsaWRhdGUgPSBbCiAgICAg + ICAgICAgICAgICBmIntzZWxmLl9hcmdfcGFyc2VyLnJnd19wb29sX3ByZWZpeH0ucmd3Lm1ldGEi + LAogICAgICAgICAgICAgICAgIi5yZ3cucm9vdCIsCiAgICAgICAgICAgICAgICBmIntzZWxmLl9h + cmdfcGFyc2VyLnJnd19wb29sX3ByZWZpeH0ucmd3LmNvbnRyb2wiLAogICAgICAgICAgICAgICAg + ZiJ7c2VsZi5fYXJnX3BhcnNlci5yZ3dfcG9vbF9wcmVmaXh9LnJndy5sb2ciLAogICAgICAgICAg + ICBdCiAgICAgICAgICAgIGZvciBfcmd3X3Bvb2xfdG9fdmFsaWRhdGUgaW4gcmd3X3Bvb2xzX3Rv + X3ZhbGlkYXRlOgogICAgICAgICAgICAgICAgaWYgbm90IHNlbGYuY2x1c3Rlci5wb29sX2V4aXN0 + cyhfcmd3X3Bvb2xfdG9fdmFsaWRhdGUpOgogICAgICAgICAgICAgICAgICAgIHN5cy5zdGRlcnIu + d3JpdGUoCiAgICAgICAgICAgICAgICAgICAgICAgIGYiVGhlIHByb3ZpZGVkIHBvb2wsICd7X3Jn + d19wb29sX3RvX3ZhbGlkYXRlfScsIGRvZXMgbm90IGV4aXN0IgogICAgICAgICAgICAgICAgICAg + ICkKICAgICAgICAgICAgICAgICAgICByZXR1cm4gIi0xIgoKICAgICAgICByZXR1cm4gIiIKCiAg + ICBkZWYgdmFsaWRhdGVfcmd3X211bHRpc2l0ZShzZWxmLCByZ3dfbXVsdGlzaXRlX2NvbmZpZ19u + YW1lLCByZ3dfbXVsdGlzaXRlX2NvbmZpZyk6CiAgICAgICAgaWYgcmd3X211bHRpc2l0ZV9jb25m + aWcgIT0gIiI6CiAgICAgICAgICAgIGNtZCA9IFsKICAgICAgICAgICAgICAgICJyYWRvc2d3LWFk + bWluIiwKICAgICAgICAgICAgICAgIHJnd19tdWx0aXNpdGVfY29uZmlnLAogICAgICAgICAgICAg + ICAgImdldCIsCiAgICAgICAgICAgICAgICAiLS1yZ3ctIiArIHJnd19tdWx0aXNpdGVfY29uZmln + LAogICAgICAgICAgICAgICAgcmd3X211bHRpc2l0ZV9jb25maWdfbmFtZSwKICAgICAgICAgICAg + XQogICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICBfID0gc3VicHJvY2Vzcy5jaGVja19v + dXRwdXQoY21kLCBzdGRlcnI9c3VicHJvY2Vzcy5QSVBFKQogICAgICAgICAgICBleGNlcHQgc3Vi + cHJvY2Vzcy5DYWxsZWRQcm9jZXNzRXJyb3IgYXMgZXhlY0VycjoKICAgICAgICAgICAgICAgIGVy + cl9tc2cgPSAoCiAgICAgICAgICAgICAgICAgICAgZiJmYWlsZWQgdG8gZXhlY3V0ZSBjb21tYW5k + IHtjbWR9LiBPdXRwdXQ6IHtleGVjRXJyLm91dHB1dH0uICIKICAgICAgICAgICAgICAgICAgICBm + IkNvZGU6IHtleGVjRXJyLnJldHVybmNvZGV9LiBFcnJvcjoge2V4ZWNFcnIuc3RkZXJyfSIKICAg + ICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgIHN5cy5zdGRlcnIud3JpdGUoZXJyX21zZykK + ICAgICAgICAgICAgICAgIHJldHVybiAiLTEiCiAgICAgICAgcmV0dXJuICIiCgogICAgZGVmIGNv + bnZlcnRfY29tbWFfc2VwYXJhdGVkX3RvX2FycmF5KHNlbGYsIHZhbHVlKToKICAgICAgICByZXR1 + cm4gdmFsdWUuc3BsaXQoIiwiKQoKICAgIGRlZiByYWlzZV9leGNlcHRpb25faWZfYW55X3RvcG9s + b2d5X2ZsYWdfaXNfbWlzc2luZyhzZWxmKToKICAgICAgICBpZiAoCiAgICAgICAgICAgICgKICAg + ICAgICAgICAgICAgIHNlbGYuX2FyZ19wYXJzZXIudG9wb2xvZ3lfcG9vbHMgIT0gIiIKICAgICAg + ICAgICAgICAgIGFuZCAoCiAgICAgICAgICAgICAgICAgICAgc2VsZi5fYXJnX3BhcnNlci50b3Bv + bG9neV9mYWlsdXJlX2RvbWFpbl9sYWJlbCA9PSAiIgogICAgICAgICAgICAgICAgICAgIG9yIHNl + bGYuX2FyZ19wYXJzZXIudG9wb2xvZ3lfZmFpbHVyZV9kb21haW5fdmFsdWVzID09ICIiCiAgICAg + ICAgICAgICAgICApCiAgICAgICAgICAgICkKICAgICAgICAgICAgb3IgKAogICAgICAgICAgICAg + ICAgc2VsZi5fYXJnX3BhcnNlci50b3BvbG9neV9mYWlsdXJlX2RvbWFpbl9sYWJlbCAhPSAiIgog + ICAgICAgICAgICAgICAgYW5kICgKICAgICAgICAgICAgICAgICAgICBzZWxmLl9hcmdfcGFyc2Vy + LnRvcG9sb2d5X3Bvb2xzID09ICIiCiAgICAgICAgICAgICAgICAgICAgb3Igc2VsZi5fYXJnX3Bh + cnNlci50b3BvbG9neV9mYWlsdXJlX2RvbWFpbl92YWx1ZXMgPT0gIiIKICAgICAgICAgICAgICAg + ICkKICAgICAgICAgICAgKQogICAgICAgICAgICBvciAoCiAgICAgICAgICAgICAgICBzZWxmLl9h + cmdfcGFyc2VyLnRvcG9sb2d5X2ZhaWx1cmVfZG9tYWluX3ZhbHVlcyAhPSAiIgogICAgICAgICAg + ICAgICAgYW5kICgKICAgICAgICAgICAgICAgICAgICBzZWxmLl9hcmdfcGFyc2VyLnRvcG9sb2d5 + X3Bvb2xzID09ICIiCiAgICAgICAgICAgICAgICAgICAgb3Igc2VsZi5fYXJnX3BhcnNlci50b3Bv + bG9neV9mYWlsdXJlX2RvbWFpbl9sYWJlbCA9PSAiIgogICAgICAgICAgICAgICAgKQogICAgICAg + ICAgICApCiAgICAgICAgKToKICAgICAgICAgICAgcmFpc2UgRXhlY3V0aW9uRmFpbHVyZUV4Y2Vw + dGlvbigKICAgICAgICAgICAgICAgICJwcm92aWRlIGFsbCB0aGUgdG9wb2xvZ3kgZmxhZ3MgLS10 + b3BvbG9neS1wb29scywgLS10b3BvbG9neS1mYWlsdXJlLWRvbWFpbi1sYWJlbCwgLS10b3BvbG9n + eS1mYWlsdXJlLWRvbWFpbi12YWx1ZXMiCiAgICAgICAgICAgICkKCiAgICBkZWYgdmFsaWRhdGVf + dG9wb2xvZ3lfdmFsdWVzKHNlbGYsIHRvcG9sb2d5X3Bvb2xzLCB0b3BvbG9neV9mZCk6CiAgICAg + ICAgaWYgbGVuKHRvcG9sb2d5X3Bvb2xzKSAhPSBsZW4odG9wb2xvZ3lfZmQpOgogICAgICAgICAg + ICByYWlzZSBFeGVjdXRpb25GYWlsdXJlRXhjZXB0aW9uKAogICAgICAgICAgICAgICAgZiJUaGUg + cHJvdmlkZWQgdG9wb2xvZ3kgcG9vbHMsICd7dG9wb2xvZ3lfcG9vbHN9JywgYW5kICIKICAgICAg + ICAgICAgICAgIGYidG9wb2xvZ3kgZmFpbHVyZSBkb21haW4sICd7dG9wb2xvZ3lfZmR9JywiCiAg + ICAgICAgICAgICAgICBmImFyZSBvZiBkaWZmZXJlbnQgbGVuZ3RoLCAne2xlbih0b3BvbG9neV9w + b29scyl9JyBhbmQgJ3tsZW4odG9wb2xvZ3lfZmQpfScgcmVzcGN0aXZlbHkiCiAgICAgICAgICAg + ICkKICAgICAgICByZXR1cm4KCiAgICBkZWYgdmFsaWRhdGVfdG9wb2xvZ3lfcmJkX3Bvb2xzKHNl + bGYsIHRvcG9sb2d5X3JiZF9wb29scyk6CiAgICAgICAgZm9yIHBvb2wgaW4gdG9wb2xvZ3lfcmJk + X3Bvb2xzOgogICAgICAgICAgICBzZWxmLnZhbGlkYXRlX3JiZF9wb29sKHBvb2wpCgogICAgZGVm + IGluaXRfdG9wb2xvZ3lfcmJkX3Bvb2xzKHNlbGYsIHRvcG9sb2d5X3JiZF9wb29scyk6CiAgICAg + ICAgZm9yIHBvb2wgaW4gdG9wb2xvZ3lfcmJkX3Bvb2xzOgogICAgICAgICAgICBzZWxmLmluaXRf + cmJkX3Bvb2wocG9vbCkKCiAgICAjIHRoaXMgd2lsbCByZXR1cm4gdGhlIGZpbmFsIGFyZ3MgdGhh + dCBzY3JpcHQgdXNlcyB0byBwcm9jZXNzCiAgICAjIHRoZSBwcmlvcml0eSB0byBzZXQgYSBwYXJ0 + aWN1bGFyIHZhbHVlIGlzLAogICAgIyBjb21tYW5kLWxpbmUtYXJncyA+IGNvbmZpZy5pbmkgZmls + ZSB2YWx1ZXMgPiBkZWZhdWx0IHZhbHVlcwogICAgZGVmIGdldEZpbmFsVXNlZEFyZ3Moc2VsZik6 + CiAgICAgICAgYXJndW1lbnQgPSBmIltDb25maWd1cmF0aW9uc11cbiIKICAgICAgICBmb3IgYXJn + IGluIHZhcnMoc2VsZi5fYXJnX3BhcnNlcik6CiAgICAgICAgICAgIGlmIHN0cihnZXRhdHRyKHNl + bGYuX2FyZ19wYXJzZXIsIGFyZykpOgogICAgICAgICAgICAgICAgIyBweXRob24gdHJlYXRzIGZs + YWctbmFtZSBhcyBmbGFnX25hbWUgaW50ZXJuYWxseSwgc28gY29udmVydGluZyBiYWNrIHRvIGZs + YWctbmFtZSwKICAgICAgICAgICAgICAgICMgc28gd2UgY2FuIGdldCB0aG9zZSB2YWx1ZXMgZnJv + bSBjb25maWcgZmlsZQogICAgICAgICAgICAgICAgYXJnVmFsdWUgPSBhcmcucmVwbGFjZSgiXyIs + ICItIikKICAgICAgICAgICAgICAgICMgZG8gbm90IGFkZCB0aGUgY29uZmlnLWZpbGUgZmxhZyBh + bmQgYWxzbyBub3QgYWRkIHRoZSBib29sZWFuIGZsYWdzIHdoaWNoIGFyZSBzZXQgdG8gRmFsc2UK + ICAgICAgICAgICAgICAgICMgYmVjYXVzZSBjb25maWcuaW5pIGZpbGUgdHJlYXRzIGJvb2xlYW4g + ZmxhZ3MgYXMgVHJ1ZSBhbHdheXMKICAgICAgICAgICAgICAgIGlmICgKICAgICAgICAgICAgICAg + ICAgICBhcmdWYWx1ZSAhPSAiY29uZmlnLWZpbGUiCiAgICAgICAgICAgICAgICAgICAgYW5kIGdl + dGF0dHIoc2VsZi5fYXJnX3BhcnNlciwgYXJnKSAhPSBGYWxzZQogICAgICAgICAgICAgICAgKToK + ICAgICAgICAgICAgICAgICAgICBhcmd1bWVudCArPSBmInthcmdWYWx1ZX0gPSB7c3RyKGdldGF0 + dHIoc2VsZi5fYXJnX3BhcnNlciwgYXJnKSl9XG4iCiAgICAgICAgcmV0dXJuIGFyZ3VtZW50Cgog + ICAgZGVmIF9nZW5fb3V0cHV0X21hcChzZWxmKToKICAgICAgICBpZiBzZWxmLm91dF9tYXA6CiAg + ICAgICAgICAgIHJldHVybgogICAgICAgICMgc3VwcG9ydCBsZWdhY3kgZmxhZyB3aXRoIHVwZ3Jh + ZGVzCiAgICAgICAgaWYgc2VsZi5fYXJnX3BhcnNlci5jbHVzdGVyX25hbWU6CiAgICAgICAgICAg + IHNlbGYuX2FyZ19wYXJzZXIuazhzX2NsdXN0ZXJfbmFtZSA9IHNlbGYuX2FyZ19wYXJzZXIuY2x1 + c3Rlcl9uYW1lCiAgICAgICAgc2VsZi5fYXJnX3BhcnNlci5rOHNfY2x1c3Rlcl9uYW1lID0gKAog + ICAgICAgICAgICBzZWxmLl9hcmdfcGFyc2VyLms4c19jbHVzdGVyX25hbWUubG93ZXIoKQogICAg + ICAgICkgICMgYWx3YXlzIGNvbnZlcnQgY2x1c3RlciBuYW1lIHRvIGxvd2VyY2FzZSBjaGFyYWN0 + ZXJzCiAgICAgICAgc2VsZi52YWxpZGF0ZV9yYmRfcG9vbChzZWxmLl9hcmdfcGFyc2VyLnJiZF9k + YXRhX3Bvb2xfbmFtZSkKICAgICAgICBzZWxmLmluaXRfcmJkX3Bvb2woc2VsZi5fYXJnX3BhcnNl + ci5yYmRfZGF0YV9wb29sX25hbWUpCiAgICAgICAgc2VsZi52YWxpZGF0ZV9yYWRvc19uYW1lc3Bh + Y2UoKQogICAgICAgIHNlbGYuX2V4Y2x1ZGVkX2tleXMuYWRkKCJLOFNfQ0xVU1RFUl9OQU1FIikK + ICAgICAgICBzZWxmLmdldF9jZXBoZnNfZGF0YV9wb29sX2RldGFpbHMoKQogICAgICAgICMgZG91 + YmxlIHN0cmluZyBuZWVkZWQgZm9yIHVwc3RyZWFtIGV4cG9ydHMgb2YgZmxhZ3MKICAgICAgICBz + ZWxmLm91dF9tYXBbIkFSR1MiXSA9IGYnIntzZWxmLmdldEZpbmFsVXNlZEFyZ3MoKX0iJwogICAg + ICAgIHNlbGYub3V0X21hcFsiTkFNRVNQQUNFIl0gPSBzZWxmLl9hcmdfcGFyc2VyLm5hbWVzcGFj + ZQogICAgICAgIHNlbGYub3V0X21hcFsiSzhTX0NMVVNURVJfTkFNRSJdID0gc2VsZi5fYXJnX3Bh + cnNlci5rOHNfY2x1c3Rlcl9uYW1lCiAgICAgICAgc2VsZi5vdXRfbWFwWyJST09LX0VYVEVSTkFM + X0ZTSUQiXSA9IHNlbGYuZ2V0X2ZzaWQoKQogICAgICAgIHNlbGYub3V0X21hcFsiUk9PS19FWFRF + Uk5BTF9VU0VSTkFNRSJdID0gc2VsZi5ydW5fYXNfdXNlcgogICAgICAgIHNlbGYub3V0X21hcFsi + Uk9PS19FWFRFUk5BTF9DRVBIX01PTl9EQVRBIl0gPSBzZWxmLmdldF9jZXBoX2V4dGVybmFsX21v + bl9kYXRhKCkKICAgICAgICBzZWxmLm91dF9tYXBbIlJPT0tfRVhURVJOQUxfVVNFUl9TRUNSRVQi + XSA9IHNlbGYuY3JlYXRlX2NoZWNrZXJLZXkoCiAgICAgICAgICAgICJjbGllbnQuaGVhbHRoY2hl + Y2tlciIKICAgICAgICApCiAgICAgICAgc2VsZi5vdXRfbWFwWyJST09LX0VYVEVSTkFMX0RBU0hC + T0FSRF9MSU5LIl0gPSBzZWxmLmdldF9jZXBoX2Rhc2hib2FyZF9saW5rKCkKICAgICAgICAoCiAg + ICAgICAgICAgIHNlbGYub3V0X21hcFsiQ1NJX1JCRF9OT0RFX1NFQ1JFVCJdLAogICAgICAgICAg + ICBzZWxmLm91dF9tYXBbIkNTSV9SQkRfTk9ERV9TRUNSRVRfTkFNRSJdLAogICAgICAgICkgPSBz + ZWxmLmNyZWF0ZV9jZXBoQ1NJS2V5cmluZ191c2VyKCJjbGllbnQuY3NpLXJiZC1ub2RlIikKICAg + ICAgICAoCiAgICAgICAgICAgIHNlbGYub3V0X21hcFsiQ1NJX1JCRF9QUk9WSVNJT05FUl9TRUNS + RVQiXSwKICAgICAgICAgICAgc2VsZi5vdXRfbWFwWyJDU0lfUkJEX1BST1ZJU0lPTkVSX1NFQ1JF + VF9OQU1FIl0sCiAgICAgICAgKSA9IHNlbGYuY3JlYXRlX2NlcGhDU0lLZXlyaW5nX3VzZXIoImNs + aWVudC5jc2ktcmJkLXByb3Zpc2lvbmVyIikKICAgICAgICBzZWxmLm91dF9tYXBbIkNFUEhGU19Q + T09MX05BTUUiXSA9IHNlbGYuX2FyZ19wYXJzZXIuY2VwaGZzX2RhdGFfcG9vbF9uYW1lCiAgICAg + ICAgc2VsZi5vdXRfbWFwWyJDRVBIRlNfTUVUQURBVEFfUE9PTF9OQU1FIl0gPSAoCiAgICAgICAg + ICAgIHNlbGYuX2FyZ19wYXJzZXIuY2VwaGZzX21ldGFkYXRhX3Bvb2xfbmFtZQogICAgICAgICkK + ICAgICAgICBzZWxmLm91dF9tYXBbIkNFUEhGU19GU19OQU1FIl0gPSBzZWxmLl9hcmdfcGFyc2Vy + LmNlcGhmc19maWxlc3lzdGVtX25hbWUKICAgICAgICBzZWxmLm91dF9tYXBbIlJFU1RSSUNURURf + QVVUSF9QRVJNSVNTSU9OIl0gPSAoCiAgICAgICAgICAgIHNlbGYuX2FyZ19wYXJzZXIucmVzdHJp + Y3RlZF9hdXRoX3Blcm1pc3Npb24KICAgICAgICApCiAgICAgICAgc2VsZi5vdXRfbWFwWyJSQURP + U19OQU1FU1BBQ0UiXSA9IHNlbGYuX2FyZ19wYXJzZXIucmFkb3NfbmFtZXNwYWNlCiAgICAgICAg + c2VsZi5vdXRfbWFwWyJTVUJWT0xVTUVfR1JPVVAiXSA9IHNlbGYuX2FyZ19wYXJzZXIuc3Vidm9s + dW1lX2dyb3VwCiAgICAgICAgc2VsZi5vdXRfbWFwWyJDU0lfQ0VQSEZTX05PREVfU0VDUkVUIl0g + PSAiIgogICAgICAgIHNlbGYub3V0X21hcFsiQ1NJX0NFUEhGU19QUk9WSVNJT05FUl9TRUNSRVQi + XSA9ICIiCiAgICAgICAgIyBjcmVhdGUgQ2VwaEZTIG5vZGUgYW5kIHByb3Zpc2lvbmVyIGtleXJp + bmcgb25seSB3aGVuIE1EUyBleGlzdHMKICAgICAgICBpZiBzZWxmLm91dF9tYXBbIkNFUEhGU19G + U19OQU1FIl0gYW5kIHNlbGYub3V0X21hcFsiQ0VQSEZTX1BPT0xfTkFNRSJdOgogICAgICAgICAg + ICAoCiAgICAgICAgICAgICAgICBzZWxmLm91dF9tYXBbIkNTSV9DRVBIRlNfTk9ERV9TRUNSRVQi + XSwKICAgICAgICAgICAgICAgIHNlbGYub3V0X21hcFsiQ1NJX0NFUEhGU19OT0RFX1NFQ1JFVF9O + QU1FIl0sCiAgICAgICAgICAgICkgPSBzZWxmLmNyZWF0ZV9jZXBoQ1NJS2V5cmluZ191c2VyKCJj + bGllbnQuY3NpLWNlcGhmcy1ub2RlIikKICAgICAgICAgICAgKAogICAgICAgICAgICAgICAgc2Vs + Zi5vdXRfbWFwWyJDU0lfQ0VQSEZTX1BST1ZJU0lPTkVSX1NFQ1JFVCJdLAogICAgICAgICAgICAg + ICAgc2VsZi5vdXRfbWFwWyJDU0lfQ0VQSEZTX1BST1ZJU0lPTkVSX1NFQ1JFVF9OQU1FIl0sCiAg + ICAgICAgICAgICkgPSBzZWxmLmNyZWF0ZV9jZXBoQ1NJS2V5cmluZ191c2VyKCJjbGllbnQuY3Np + LWNlcGhmcy1wcm92aXNpb25lciIpCiAgICAgICAgICAgICMgY3JlYXRlIHRoZSBkZWZhdWx0ICJj + c2kiIHN1YnZvbHVtZWdyb3VwCiAgICAgICAgICAgIHNlbGYuZ2V0X29yX2NyZWF0ZV9zdWJ2b2x1 + bWVfZ3JvdXAoCiAgICAgICAgICAgICAgICAiY3NpIiwgc2VsZi5fYXJnX3BhcnNlci5jZXBoZnNf + ZmlsZXN5c3RlbV9uYW1lCiAgICAgICAgICAgICkKICAgICAgICAgICAgIyBwaW4gdGhlIGRlZmF1 + bHQgImNzaSIgc3Vidm9sdW1lZ3JvdXAKICAgICAgICAgICAgc2VsZi5waW5fc3Vidm9sdW1lKAog + ICAgICAgICAgICAgICAgImNzaSIsIHNlbGYuX2FyZ19wYXJzZXIuY2VwaGZzX2ZpbGVzeXN0ZW1f + bmFtZSwgImRpc3RyaWJ1dGVkIiwgIjEiCiAgICAgICAgICAgICkKICAgICAgICAgICAgaWYgc2Vs + Zi5vdXRfbWFwWyJTVUJWT0xVTUVfR1JPVVAiXToKICAgICAgICAgICAgICAgIHNlbGYuZ2V0X29y + X2NyZWF0ZV9zdWJ2b2x1bWVfZ3JvdXAoCiAgICAgICAgICAgICAgICAgICAgc2VsZi5fYXJnX3Bh + cnNlci5zdWJ2b2x1bWVfZ3JvdXAsCiAgICAgICAgICAgICAgICAgICAgc2VsZi5fYXJnX3BhcnNl + ci5jZXBoZnNfZmlsZXN5c3RlbV9uYW1lLAogICAgICAgICAgICAgICAgKQogICAgICAgICAgICAg + ICAgc2VsZi5waW5fc3Vidm9sdW1lKAogICAgICAgICAgICAgICAgICAgIHNlbGYuX2FyZ19wYXJz + ZXIuc3Vidm9sdW1lX2dyb3VwLAogICAgICAgICAgICAgICAgICAgIHNlbGYuX2FyZ19wYXJzZXIu + Y2VwaGZzX2ZpbGVzeXN0ZW1fbmFtZSwKICAgICAgICAgICAgICAgICAgICAiZGlzdHJpYnV0ZWQi + LAogICAgICAgICAgICAgICAgICAgICIxIiwKICAgICAgICAgICAgICAgICkKICAgICAgICBzZWxm + Lm91dF9tYXBbIlJHV19UTFNfQ0VSVCJdID0gIiIKICAgICAgICBzZWxmLm91dF9tYXBbIk1PTklU + T1JJTkdfRU5EUE9JTlQiXSA9ICIiCiAgICAgICAgc2VsZi5vdXRfbWFwWyJNT05JVE9SSU5HX0VO + RFBPSU5UX1BPUlQiXSA9ICIiCiAgICAgICAgaWYgbm90IHNlbGYuX2FyZ19wYXJzZXIuc2tpcF9t + b25pdG9yaW5nX2VuZHBvaW50OgogICAgICAgICAgICAoCiAgICAgICAgICAgICAgICBzZWxmLm91 + dF9tYXBbIk1PTklUT1JJTkdfRU5EUE9JTlQiXSwKICAgICAgICAgICAgICAgIHNlbGYub3V0X21h + cFsiTU9OSVRPUklOR19FTkRQT0lOVF9QT1JUIl0sCiAgICAgICAgICAgICkgPSBzZWxmLmdldF9h + Y3RpdmVfYW5kX3N0YW5kYnlfbWdycygpCiAgICAgICAgc2VsZi5vdXRfbWFwWyJSQkRfUE9PTF9O + QU1FIl0gPSBzZWxmLl9hcmdfcGFyc2VyLnJiZF9kYXRhX3Bvb2xfbmFtZQogICAgICAgIHNlbGYu + b3V0X21hcFsiUkJEX01FVEFEQVRBX0VDX1BPT0xfTkFNRSJdID0gKAogICAgICAgICAgICBzZWxm + LnZhbGlkYXRlX3JiZF9tZXRhZGF0YV9lY19wb29sX25hbWUoKQogICAgICAgICkKICAgICAgICBz + ZWxmLm91dF9tYXBbIlRPUE9MT0dZX1BPT0xTIl0gPSBzZWxmLl9hcmdfcGFyc2VyLnRvcG9sb2d5 + X3Bvb2xzCiAgICAgICAgc2VsZi5vdXRfbWFwWyJUT1BPTE9HWV9GQUlMVVJFX0RPTUFJTl9MQUJF + TCJdID0gKAogICAgICAgICAgICBzZWxmLl9hcmdfcGFyc2VyLnRvcG9sb2d5X2ZhaWx1cmVfZG9t + YWluX2xhYmVsCiAgICAgICAgKQogICAgICAgIHNlbGYub3V0X21hcFsiVE9QT0xPR1lfRkFJTFVS + RV9ET01BSU5fVkFMVUVTIl0gPSAoCiAgICAgICAgICAgIHNlbGYuX2FyZ19wYXJzZXIudG9wb2xv + Z3lfZmFpbHVyZV9kb21haW5fdmFsdWVzCiAgICAgICAgKQogICAgICAgIGlmICgKICAgICAgICAg + ICAgc2VsZi5fYXJnX3BhcnNlci50b3BvbG9neV9wb29scyAhPSAiIgogICAgICAgICAgICBhbmQg + c2VsZi5fYXJnX3BhcnNlci50b3BvbG9neV9mYWlsdXJlX2RvbWFpbl9sYWJlbCAhPSAiIgogICAg + ICAgICAgICBhbmQgc2VsZi5fYXJnX3BhcnNlci50b3BvbG9neV9mYWlsdXJlX2RvbWFpbl92YWx1 + ZXMgIT0gIiIKICAgICAgICApOgogICAgICAgICAgICBzZWxmLnZhbGlkYXRlX3RvcG9sb2d5X3Zh + bHVlcygKICAgICAgICAgICAgICAgIHNlbGYuY29udmVydF9jb21tYV9zZXBhcmF0ZWRfdG9fYXJy + YXkoc2VsZi5vdXRfbWFwWyJUT1BPTE9HWV9QT09MUyJdKSwKICAgICAgICAgICAgICAgIHNlbGYu + Y29udmVydF9jb21tYV9zZXBhcmF0ZWRfdG9fYXJyYXkoCiAgICAgICAgICAgICAgICAgICAgc2Vs + Zi5vdXRfbWFwWyJUT1BPTE9HWV9GQUlMVVJFX0RPTUFJTl9WQUxVRVMiXQogICAgICAgICAgICAg + ICAgKSwKICAgICAgICAgICAgKQogICAgICAgICAgICBzZWxmLnZhbGlkYXRlX3RvcG9sb2d5X3Ji + ZF9wb29scygKICAgICAgICAgICAgICAgIHNlbGYuY29udmVydF9jb21tYV9zZXBhcmF0ZWRfdG9f + YXJyYXkoc2VsZi5vdXRfbWFwWyJUT1BPTE9HWV9QT09MUyJdKQogICAgICAgICAgICApCiAgICAg + ICAgICAgIHNlbGYuaW5pdF90b3BvbG9neV9yYmRfcG9vbHMoCiAgICAgICAgICAgICAgICBzZWxm + LmNvbnZlcnRfY29tbWFfc2VwYXJhdGVkX3RvX2FycmF5KHNlbGYub3V0X21hcFsiVE9QT0xPR1lf + UE9PTFMiXSkKICAgICAgICAgICAgKQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHNlbGYucmFp + c2VfZXhjZXB0aW9uX2lmX2FueV90b3BvbG9neV9mbGFnX2lzX21pc3NpbmcoKQoKICAgICAgICBz + ZWxmLm91dF9tYXBbIlJHV19QT09MX1BSRUZJWCJdID0gc2VsZi5fYXJnX3BhcnNlci5yZ3dfcG9v + bF9wcmVmaXgKICAgICAgICBzZWxmLm91dF9tYXBbIlJHV19FTkRQT0lOVCJdID0gIiIKICAgICAg + ICBpZiBzZWxmLl9hcmdfcGFyc2VyLnJnd19lbmRwb2ludDoKICAgICAgICAgICAgaWYgc2VsZi5f + YXJnX3BhcnNlci5kcnlfcnVuOgogICAgICAgICAgICAgICAgc2VsZi5jcmVhdGVfcmd3X2FkbWlu + X29wc191c2VyKCkKICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgIGlmICgKICAgICAg + ICAgICAgICAgICAgICBzZWxmLl9hcmdfcGFyc2VyLnJnd19yZWFsbV9uYW1lICE9ICIiCiAgICAg + ICAgICAgICAgICAgICAgYW5kIHNlbGYuX2FyZ19wYXJzZXIucmd3X3pvbmVncm91cF9uYW1lICE9 + ICIiCiAgICAgICAgICAgICAgICAgICAgYW5kIHNlbGYuX2FyZ19wYXJzZXIucmd3X3pvbmVfbmFt + ZSAhPSAiIgogICAgICAgICAgICAgICAgKToKICAgICAgICAgICAgICAgICAgICBlcnIgPSBzZWxm LnZhbGlkYXRlX3Jnd19tdWx0aXNpdGUoCiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuX2Fy - Z19wYXJzZXIucmd3X3pvbmVfbmFtZSwgInpvbmUiCiAgICAgICAgICAgICAgICAgICAgKQoKICAg - ICAgICAgICAgICAgIGlmICgKICAgICAgICAgICAgICAgICAgICBzZWxmLl9hcmdfcGFyc2VyLnJn - d19yZWFsbV9uYW1lID09ICIiCiAgICAgICAgICAgICAgICAgICAgYW5kIHNlbGYuX2FyZ19wYXJz - ZXIucmd3X3pvbmVncm91cF9uYW1lID09ICIiCiAgICAgICAgICAgICAgICAgICAgYW5kIHNlbGYu - X2FyZ19wYXJzZXIucmd3X3pvbmVfbmFtZSA9PSAiIgogICAgICAgICAgICAgICAgKSBvciAoCiAg - ICAgICAgICAgICAgICAgICAgc2VsZi5fYXJnX3BhcnNlci5yZ3dfcmVhbG1fbmFtZSAhPSAiIgog - ICAgICAgICAgICAgICAgICAgIGFuZCBzZWxmLl9hcmdfcGFyc2VyLnJnd196b25lZ3JvdXBfbmFt - ZSAhPSAiIgogICAgICAgICAgICAgICAgICAgIGFuZCBzZWxmLl9hcmdfcGFyc2VyLnJnd196b25l - X25hbWUgIT0gIiIKICAgICAgICAgICAgICAgICk6CiAgICAgICAgICAgICAgICAgICAgKAogICAg - ICAgICAgICAgICAgICAgICAgICBzZWxmLm91dF9tYXBbIlJHV19BRE1JTl9PUFNfVVNFUl9BQ0NF - U1NfS0VZIl0sCiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYub3V0X21hcFsiUkdXX0FETUlO - X09QU19VU0VSX1NFQ1JFVF9LRVkiXSwKICAgICAgICAgICAgICAgICAgICAgICAgaW5mb19jYXBf - c3VwcG9ydGVkLAogICAgICAgICAgICAgICAgICAgICAgICBlcnIsCiAgICAgICAgICAgICAgICAg - ICAgKSA9IHNlbGYuY3JlYXRlX3Jnd19hZG1pbl9vcHNfdXNlcigpCiAgICAgICAgICAgICAgICAg - ICAgZXJyID0gc2VsZi52YWxpZGF0ZV9yZ3dfZW5kcG9pbnQoaW5mb19jYXBfc3VwcG9ydGVkKQog - ICAgICAgICAgICAgICAgICAgIGlmIHNlbGYuX2FyZ19wYXJzZXIucmd3X3Rsc19jZXJ0X3BhdGg6 - CiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYub3V0X21hcFsiUkdXX1RMU19DRVJUIl0gPSAo - CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLnZhbGlkYXRlX3Jnd19lbmRwb2ludF90 - bHNfY2VydCgpCiAgICAgICAgICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgICAgICAj - IGlmIHRoZXJlIGlzIG5vIGVycm9yLCBzZXQgdGhlIFJHV19FTkRQT0lOVAogICAgICAgICAgICAg - ICAgICAgIGlmIGVyciAhPSAiLTEiOgogICAgICAgICAgICAgICAgICAgICAgICBzZWxmLm91dF9t - YXBbIlJHV19FTkRQT0lOVCJdID0gc2VsZi5fYXJnX3BhcnNlci5yZ3dfZW5kcG9pbnQKICAgICAg - ICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICAgICAgZXJyID0gIlBsZWFzZSBwcm92aWRl - IGFsbCB0aGUgUkdXIG11bHRpc2l0ZSBwYXJhbWV0ZXJzIG9yIG5vbmUgb2YgdGhlbSIKICAgICAg - ICAgICAgICAgICAgICBzeXMuc3RkZXJyLndyaXRlKGVycikKCiAgICBkZWYgZ2VuX3NoZWxsX291 - dChzZWxmKToKICAgICAgICBzZWxmLl9nZW5fb3V0cHV0X21hcCgpCiAgICAgICAgc2hPdXRJTyA9 - IFN0cmluZ0lPKCkKICAgICAgICBmb3IgaywgdiBpbiBzZWxmLm91dF9tYXAuaXRlbXMoKToKICAg - ICAgICAgICAgaWYgdiBhbmQgayBub3QgaW4gc2VsZi5fZXhjbHVkZWRfa2V5czoKICAgICAgICAg - ICAgICAgIHNoT3V0SU8ud3JpdGUoZiJleHBvcnQge2t9PXt2fXtMSU5FU0VQfSIpCiAgICAgICAg - c2hPdXQgPSBzaE91dElPLmdldHZhbHVlKCkKICAgICAgICBzaE91dElPLmNsb3NlKCkKICAgICAg - ICByZXR1cm4gc2hPdXQKCiAgICBkZWYgZ2VuX2pzb25fb3V0KHNlbGYpOgogICAgICAgIHNlbGYu - X2dlbl9vdXRwdXRfbWFwKCkKICAgICAgICBpZiBzZWxmLl9hcmdfcGFyc2VyLmRyeV9ydW46CiAg - ICAgICAgICAgIHJldHVybiAiIgogICAgICAgIGpzb25fb3V0ID0gWwogICAgICAgICAgICB7CiAg - ICAgICAgICAgICAgICAibmFtZSI6ICJleHRlcm5hbC1jbHVzdGVyLXVzZXItY29tbWFuZCIsCiAg - ICAgICAgICAgICAgICAia2luZCI6ICJDb25maWdNYXAiLAogICAgICAgICAgICAgICAgImRhdGEi - OiB7CiAgICAgICAgICAgICAgICAgICAgImFyZ3MiOiBzZWxmLm91dF9tYXBbIkFSR1MiXSwKICAg - ICAgICAgICAgICAgIH0sCiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHsKICAgICAgICAgICAg - ICAgICJuYW1lIjogInJvb2stY2VwaC1tb24tZW5kcG9pbnRzIiwKICAgICAgICAgICAgICAgICJr - aW5kIjogIkNvbmZpZ01hcCIsCiAgICAgICAgICAgICAgICAiZGF0YSI6IHsKICAgICAgICAgICAg - ICAgICAgICAiZGF0YSI6IHNlbGYub3V0X21hcFsiUk9PS19FWFRFUk5BTF9DRVBIX01PTl9EQVRB - Il0sCiAgICAgICAgICAgICAgICAgICAgIm1heE1vbklkIjogIjAiLAogICAgICAgICAgICAgICAg - ICAgICJtYXBwaW5nIjogInt9IiwKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgIH0sCiAg - ICAgICAgICAgIHsKICAgICAgICAgICAgICAgICJuYW1lIjogInJvb2stY2VwaC1tb24iLAogICAg - ICAgICAgICAgICAgImtpbmQiOiAiU2VjcmV0IiwKICAgICAgICAgICAgICAgICJkYXRhIjogewog - ICAgICAgICAgICAgICAgICAgICJhZG1pbi1zZWNyZXQiOiAiYWRtaW4tc2VjcmV0IiwKICAgICAg - ICAgICAgICAgICAgICAiZnNpZCI6IHNlbGYub3V0X21hcFsiUk9PS19FWFRFUk5BTF9GU0lEIl0s - CiAgICAgICAgICAgICAgICAgICAgIm1vbi1zZWNyZXQiOiAibW9uLXNlY3JldCIsCiAgICAgICAg - ICAgICAgICB9LAogICAgICAgICAgICB9LAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAi - bmFtZSI6ICJyb29rLWNlcGgtb3BlcmF0b3ItY3JlZHMiLAogICAgICAgICAgICAgICAgImtpbmQi - OiAiU2VjcmV0IiwKICAgICAgICAgICAgICAgICJkYXRhIjogewogICAgICAgICAgICAgICAgICAg - ICJ1c2VySUQiOiBzZWxmLm91dF9tYXBbIlJPT0tfRVhURVJOQUxfVVNFUk5BTUUiXSwKICAgICAg - ICAgICAgICAgICAgICAidXNlcktleSI6IHNlbGYub3V0X21hcFsiUk9PS19FWFRFUk5BTF9VU0VS - X1NFQ1JFVCJdLAogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgfSwKICAgICAgICBdCgog - ICAgICAgICMgaWYgJ01PTklUT1JJTkdfRU5EUE9JTlQnIGV4aXN0cywgdGhlbiBvbmx5IGFkZCAn - bW9uaXRvcmluZy1lbmRwb2ludCcgdG8gQ2x1c3RlcgogICAgICAgIGlmICgKICAgICAgICAgICAg - c2VsZi5vdXRfbWFwWyJNT05JVE9SSU5HX0VORFBPSU5UIl0KICAgICAgICAgICAgYW5kIHNlbGYu - b3V0X21hcFsiTU9OSVRPUklOR19FTkRQT0lOVF9QT1JUIl0KICAgICAgICApOgogICAgICAgICAg - ICBqc29uX291dC5hcHBlbmQoCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAg - Im5hbWUiOiAibW9uaXRvcmluZy1lbmRwb2ludCIsCiAgICAgICAgICAgICAgICAgICAgImtpbmQi - OiAiQ2VwaENsdXN0ZXIiLAogICAgICAgICAgICAgICAgICAgICJkYXRhIjogewogICAgICAgICAg - ICAgICAgICAgICAgICAiTW9uaXRvcmluZ0VuZHBvaW50Ijogc2VsZi5vdXRfbWFwWyJNT05JVE9S - SU5HX0VORFBPSU5UIl0sCiAgICAgICAgICAgICAgICAgICAgICAgICJNb25pdG9yaW5nUG9ydCI6 - IHNlbGYub3V0X21hcFsiTU9OSVRPUklOR19FTkRQT0lOVF9QT1JUIl0sCiAgICAgICAgICAgICAg - ICAgICAgfSwKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgKQoKICAgICAgICAjIGlmICdD - U0lfUkJEX05PREVfU0VDUkVUJyBleGlzdHMsIHRoZW4gb25seSBhZGQgJ3Jvb2stY3NpLXJiZC1w - cm92aXNpb25lcicgU2VjcmV0CiAgICAgICAgaWYgKAogICAgICAgICAgICBzZWxmLm91dF9tYXBb - IkNTSV9SQkRfTk9ERV9TRUNSRVQiXQogICAgICAgICAgICBhbmQgc2VsZi5vdXRfbWFwWyJDU0lf - UkJEX05PREVfU0VDUkVUX05BTUUiXQogICAgICAgICk6CiAgICAgICAgICAgIGpzb25fb3V0LmFw - cGVuZCgKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAibmFtZSI6IGYicm9v - ay17c2VsZi5vdXRfbWFwWydDU0lfUkJEX05PREVfU0VDUkVUX05BTUUnXX0iLAogICAgICAgICAg - ICAgICAgICAgICJraW5kIjogIlNlY3JldCIsCiAgICAgICAgICAgICAgICAgICAgImRhdGEiOiB7 - CiAgICAgICAgICAgICAgICAgICAgICAgICJ1c2VySUQiOiBzZWxmLm91dF9tYXBbIkNTSV9SQkRf - Tk9ERV9TRUNSRVRfTkFNRSJdLAogICAgICAgICAgICAgICAgICAgICAgICAidXNlcktleSI6IHNl - bGYub3V0X21hcFsiQ1NJX1JCRF9OT0RFX1NFQ1JFVCJdLAogICAgICAgICAgICAgICAgICAgIH0s - CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICkKICAgICAgICAjIGlmICdDU0lfUkJEX1BS - T1ZJU0lPTkVSX1NFQ1JFVCcgZXhpc3RzLCB0aGVuIG9ubHkgYWRkICdyb29rLWNzaS1yYmQtcHJv - dmlzaW9uZXInIFNlY3JldAogICAgICAgIGlmICgKICAgICAgICAgICAgc2VsZi5vdXRfbWFwWyJD - U0lfUkJEX1BST1ZJU0lPTkVSX1NFQ1JFVCJdCiAgICAgICAgICAgIGFuZCBzZWxmLm91dF9tYXBb - IkNTSV9SQkRfUFJPVklTSU9ORVJfU0VDUkVUX05BTUUiXQogICAgICAgICk6CiAgICAgICAgICAg - IGpzb25fb3V0LmFwcGVuZCgKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAi - bmFtZSI6IGYicm9vay17c2VsZi5vdXRfbWFwWydDU0lfUkJEX1BST1ZJU0lPTkVSX1NFQ1JFVF9O - QU1FJ119IiwKICAgICAgICAgICAgICAgICAgICAia2luZCI6ICJTZWNyZXQiLAogICAgICAgICAg - ICAgICAgICAgICJkYXRhIjogewogICAgICAgICAgICAgICAgICAgICAgICAidXNlcklEIjogc2Vs - Zi5vdXRfbWFwWyJDU0lfUkJEX1BST1ZJU0lPTkVSX1NFQ1JFVF9OQU1FIl0sCiAgICAgICAgICAg - ICAgICAgICAgICAgICJ1c2VyS2V5Ijogc2VsZi5vdXRfbWFwWyJDU0lfUkJEX1BST1ZJU0lPTkVS - X1NFQ1JFVCJdLAogICAgICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICB9CiAgICAg - ICAgICAgICkKICAgICAgICAjIGlmICdDU0lfQ0VQSEZTX1BST1ZJU0lPTkVSX1NFQ1JFVCcgZXhp - c3RzLCB0aGVuIG9ubHkgYWRkICdyb29rLWNzaS1jZXBoZnMtcHJvdmlzaW9uZXInIFNlY3JldAog - ICAgICAgIGlmICgKICAgICAgICAgICAgc2VsZi5vdXRfbWFwWyJDU0lfQ0VQSEZTX1BST1ZJU0lP - TkVSX1NFQ1JFVCJdCiAgICAgICAgICAgIGFuZCBzZWxmLm91dF9tYXBbIkNTSV9DRVBIRlNfUFJP - VklTSU9ORVJfU0VDUkVUX05BTUUiXQogICAgICAgICk6CiAgICAgICAgICAgIGpzb25fb3V0LmFw - cGVuZCgKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAibmFtZSI6IGYicm9v - ay17c2VsZi5vdXRfbWFwWydDU0lfQ0VQSEZTX1BST1ZJU0lPTkVSX1NFQ1JFVF9OQU1FJ119IiwK - ICAgICAgICAgICAgICAgICAgICAia2luZCI6ICJTZWNyZXQiLAogICAgICAgICAgICAgICAgICAg - ICJkYXRhIjogewogICAgICAgICAgICAgICAgICAgICAgICAiYWRtaW5JRCI6IHNlbGYub3V0X21h - cFsiQ1NJX0NFUEhGU19QUk9WSVNJT05FUl9TRUNSRVRfTkFNRSJdLAogICAgICAgICAgICAgICAg - ICAgICAgICAiYWRtaW5LZXkiOiBzZWxmLm91dF9tYXBbIkNTSV9DRVBIRlNfUFJPVklTSU9ORVJf - U0VDUkVUIl0sCiAgICAgICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgIH0KICAgICAg - ICAgICAgKQogICAgICAgICMgaWYgJ0NTSV9DRVBIRlNfTk9ERV9TRUNSRVQnIGV4aXN0cywgdGhl - biBvbmx5IGFkZCAncm9vay1jc2ktY2VwaGZzLW5vZGUnIFNlY3JldAogICAgICAgIGlmICgKICAg - ICAgICAgICAgc2VsZi5vdXRfbWFwWyJDU0lfQ0VQSEZTX05PREVfU0VDUkVUIl0KICAgICAgICAg - ICAgYW5kIHNlbGYub3V0X21hcFsiQ1NJX0NFUEhGU19OT0RFX1NFQ1JFVF9OQU1FIl0KICAgICAg - ICApOgogICAgICAgICAgICBqc29uX291dC5hcHBlbmQoCiAgICAgICAgICAgICAgICB7CiAgICAg - ICAgICAgICAgICAgICAgIm5hbWUiOiBmInJvb2ste3NlbGYub3V0X21hcFsnQ1NJX0NFUEhGU19O - T0RFX1NFQ1JFVF9OQU1FJ119IiwKICAgICAgICAgICAgICAgICAgICAia2luZCI6ICJTZWNyZXQi - LAogICAgICAgICAgICAgICAgICAgICJkYXRhIjogewogICAgICAgICAgICAgICAgICAgICAgICAi - YWRtaW5JRCI6IHNlbGYub3V0X21hcFsiQ1NJX0NFUEhGU19OT0RFX1NFQ1JFVF9OQU1FIl0sCiAg - ICAgICAgICAgICAgICAgICAgICAgICJhZG1pbktleSI6IHNlbGYub3V0X21hcFsiQ1NJX0NFUEhG - U19OT0RFX1NFQ1JFVCJdLAogICAgICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICB9 - CiAgICAgICAgICAgICkKICAgICAgICAjIGlmICdST09LX0VYVEVSTkFMX0RBU0hCT0FSRF9MSU5L - JyBleGlzdHMsIHRoZW4gb25seSBhZGQgJ3Jvb2stY2VwaC1kYXNoYm9hcmQtbGluaycgU2VjcmV0 - CiAgICAgICAgaWYgc2VsZi5vdXRfbWFwWyJST09LX0VYVEVSTkFMX0RBU0hCT0FSRF9MSU5LIl06 - CiAgICAgICAgICAgIGpzb25fb3V0LmFwcGVuZCgKICAgICAgICAgICAgICAgIHsKICAgICAgICAg - ICAgICAgICAgICAibmFtZSI6ICJyb29rLWNlcGgtZGFzaGJvYXJkLWxpbmsiLAogICAgICAgICAg - ICAgICAgICAgICJraW5kIjogIlNlY3JldCIsCiAgICAgICAgICAgICAgICAgICAgImRhdGEiOiB7 - CiAgICAgICAgICAgICAgICAgICAgICAgICJ1c2VySUQiOiAiY2VwaC1kYXNoYm9hcmQtbGluayIs - CiAgICAgICAgICAgICAgICAgICAgICAgICJ1c2VyS2V5Ijogc2VsZi5vdXRfbWFwWyJST09LX0VY - VEVSTkFMX0RBU0hCT0FSRF9MSU5LIl0sCiAgICAgICAgICAgICAgICAgICAgfSwKICAgICAgICAg - ICAgICAgIH0KICAgICAgICAgICAgKQogICAgICAgICMgaWYgJ1JBRE9TX05BTUVTUEFDRScgZXhp - c3RzLCB0aGVuIG9ubHkgYWRkIHRoZSAiUkFET1NfTkFNRVNQQUNFIiBuYW1lc3BhY2UKICAgICAg - ICBpZiAoCiAgICAgICAgICAgIHNlbGYub3V0X21hcFsiUkFET1NfTkFNRVNQQUNFIl0KICAgICAg - ICAgICAgYW5kIHNlbGYub3V0X21hcFsiUkVTVFJJQ1RFRF9BVVRIX1BFUk1JU1NJT04iXQogICAg - ICAgICAgICBhbmQgbm90IHNlbGYub3V0X21hcFsiUkJEX01FVEFEQVRBX0VDX1BPT0xfTkFNRSJd + Z19wYXJzZXIucmd3X3JlYWxtX25hbWUsICJyZWFsbSIKICAgICAgICAgICAgICAgICAgICApCiAg + ICAgICAgICAgICAgICAgICAgZXJyID0gc2VsZi52YWxpZGF0ZV9yZ3dfbXVsdGlzaXRlKAogICAg + ICAgICAgICAgICAgICAgICAgICBzZWxmLl9hcmdfcGFyc2VyLnJnd196b25lZ3JvdXBfbmFtZSwg + InpvbmVncm91cCIKICAgICAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICAgICAgICAgZXJy + ID0gc2VsZi52YWxpZGF0ZV9yZ3dfbXVsdGlzaXRlKAogICAgICAgICAgICAgICAgICAgICAgICBz + ZWxmLl9hcmdfcGFyc2VyLnJnd196b25lX25hbWUsICJ6b25lIgogICAgICAgICAgICAgICAgICAg + ICkKCiAgICAgICAgICAgICAgICBpZiAoCiAgICAgICAgICAgICAgICAgICAgc2VsZi5fYXJnX3Bh + cnNlci5yZ3dfcmVhbG1fbmFtZSA9PSAiIgogICAgICAgICAgICAgICAgICAgIGFuZCBzZWxmLl9h + cmdfcGFyc2VyLnJnd196b25lZ3JvdXBfbmFtZSA9PSAiIgogICAgICAgICAgICAgICAgICAgIGFu + ZCBzZWxmLl9hcmdfcGFyc2VyLnJnd196b25lX25hbWUgPT0gIiIKICAgICAgICAgICAgICAgICkg + b3IgKAogICAgICAgICAgICAgICAgICAgIHNlbGYuX2FyZ19wYXJzZXIucmd3X3JlYWxtX25hbWUg + IT0gIiIKICAgICAgICAgICAgICAgICAgICBhbmQgc2VsZi5fYXJnX3BhcnNlci5yZ3dfem9uZWdy + b3VwX25hbWUgIT0gIiIKICAgICAgICAgICAgICAgICAgICBhbmQgc2VsZi5fYXJnX3BhcnNlci5y + Z3dfem9uZV9uYW1lICE9ICIiCiAgICAgICAgICAgICAgICApOgogICAgICAgICAgICAgICAgICAg + ICgKICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5vdXRfbWFwWyJSR1dfQURNSU5fT1BTX1VT + RVJfQUNDRVNTX0tFWSJdLAogICAgICAgICAgICAgICAgICAgICAgICBzZWxmLm91dF9tYXBbIlJH + V19BRE1JTl9PUFNfVVNFUl9TRUNSRVRfS0VZIl0sCiAgICAgICAgICAgICAgICAgICAgICAgIGlu + Zm9fY2FwX3N1cHBvcnRlZCwKICAgICAgICAgICAgICAgICAgICAgICAgZXJyLAogICAgICAgICAg + ICAgICAgICAgICkgPSBzZWxmLmNyZWF0ZV9yZ3dfYWRtaW5fb3BzX3VzZXIoKQogICAgICAgICAg + ICAgICAgICAgIGVyciA9IHNlbGYudmFsaWRhdGVfcmd3X2VuZHBvaW50KGluZm9fY2FwX3N1cHBv + cnRlZCkKICAgICAgICAgICAgICAgICAgICBpZiBzZWxmLl9hcmdfcGFyc2VyLnJnd190bHNfY2Vy + dF9wYXRoOgogICAgICAgICAgICAgICAgICAgICAgICBzZWxmLm91dF9tYXBbIlJHV19UTFNfQ0VS + VCJdID0gKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi52YWxpZGF0ZV9yZ3dfZW5k + cG9pbnRfdGxzX2NlcnQoKQogICAgICAgICAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICAg + ICAgICAgIyBpZiB0aGVyZSBpcyBubyBlcnJvciwgc2V0IHRoZSBSR1dfRU5EUE9JTlQKICAgICAg + ICAgICAgICAgICAgICBpZiBlcnIgIT0gIi0xIjoKICAgICAgICAgICAgICAgICAgICAgICAgc2Vs + Zi5vdXRfbWFwWyJSR1dfRU5EUE9JTlQiXSA9IHNlbGYuX2FyZ19wYXJzZXIucmd3X2VuZHBvaW50 + CiAgICAgICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgICAgIGVyciA9ICJQbGVhc2Ug + cHJvdmlkZSBhbGwgdGhlIFJHVyBtdWx0aXNpdGUgcGFyYW1ldGVycyBvciBub25lIG9mIHRoZW0i + CiAgICAgICAgICAgICAgICAgICAgc3lzLnN0ZGVyci53cml0ZShlcnIpCgogICAgZGVmIGdlbl9z + aGVsbF9vdXQoc2VsZik6CiAgICAgICAgc2VsZi5fZ2VuX291dHB1dF9tYXAoKQogICAgICAgIHNo + T3V0SU8gPSBTdHJpbmdJTygpCiAgICAgICAgZm9yIGssIHYgaW4gc2VsZi5vdXRfbWFwLml0ZW1z + KCk6CiAgICAgICAgICAgIGlmIHYgYW5kIGsgbm90IGluIHNlbGYuX2V4Y2x1ZGVkX2tleXM6CiAg + ICAgICAgICAgICAgICBzaE91dElPLndyaXRlKGYiZXhwb3J0IHtrfT17dn17TElORVNFUH0iKQog + ICAgICAgIHNoT3V0ID0gc2hPdXRJTy5nZXR2YWx1ZSgpCiAgICAgICAgc2hPdXRJTy5jbG9zZSgp + CiAgICAgICAgcmV0dXJuIHNoT3V0CgogICAgZGVmIGdlbl9qc29uX291dChzZWxmKToKICAgICAg + ICBzZWxmLl9nZW5fb3V0cHV0X21hcCgpCiAgICAgICAgaWYgc2VsZi5fYXJnX3BhcnNlci5kcnlf + cnVuOgogICAgICAgICAgICByZXR1cm4gIiIKICAgICAgICBqc29uX291dCA9IFsKICAgICAgICAg + ICAgewogICAgICAgICAgICAgICAgIm5hbWUiOiAiZXh0ZXJuYWwtY2x1c3Rlci11c2VyLWNvbW1h + bmQiLAogICAgICAgICAgICAgICAgImtpbmQiOiAiQ29uZmlnTWFwIiwKICAgICAgICAgICAgICAg + ICJkYXRhIjogewogICAgICAgICAgICAgICAgICAgICJhcmdzIjogc2VsZi5vdXRfbWFwWyJBUkdT + Il0sCiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICB9LAogICAgICAgICAgICB7CiAgICAg + ICAgICAgICAgICAibmFtZSI6ICJyb29rLWNlcGgtbW9uLWVuZHBvaW50cyIsCiAgICAgICAgICAg + ICAgICAia2luZCI6ICJDb25maWdNYXAiLAogICAgICAgICAgICAgICAgImRhdGEiOiB7CiAgICAg + ICAgICAgICAgICAgICAgImRhdGEiOiBzZWxmLm91dF9tYXBbIlJPT0tfRVhURVJOQUxfQ0VQSF9N + T05fREFUQSJdLAogICAgICAgICAgICAgICAgICAgICJtYXhNb25JZCI6ICIwIiwKICAgICAgICAg + ICAgICAgICAgICAibWFwcGluZyI6ICJ7fSIsCiAgICAgICAgICAgICAgICB9LAogICAgICAgICAg + ICB9LAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAibmFtZSI6ICJyb29rLWNlcGgtbW9u + IiwKICAgICAgICAgICAgICAgICJraW5kIjogIlNlY3JldCIsCiAgICAgICAgICAgICAgICAiZGF0 + YSI6IHsKICAgICAgICAgICAgICAgICAgICAiYWRtaW4tc2VjcmV0IjogImFkbWluLXNlY3JldCIs + CiAgICAgICAgICAgICAgICAgICAgImZzaWQiOiBzZWxmLm91dF9tYXBbIlJPT0tfRVhURVJOQUxf + RlNJRCJdLAogICAgICAgICAgICAgICAgICAgICJtb24tc2VjcmV0IjogIm1vbi1zZWNyZXQiLAog + ICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgfSwKICAgICAgICAgICAgewogICAgICAgICAg + ICAgICAgIm5hbWUiOiAicm9vay1jZXBoLW9wZXJhdG9yLWNyZWRzIiwKICAgICAgICAgICAgICAg + ICJraW5kIjogIlNlY3JldCIsCiAgICAgICAgICAgICAgICAiZGF0YSI6IHsKICAgICAgICAgICAg + ICAgICAgICAidXNlcklEIjogc2VsZi5vdXRfbWFwWyJST09LX0VYVEVSTkFMX1VTRVJOQU1FIl0s + CiAgICAgICAgICAgICAgICAgICAgInVzZXJLZXkiOiBzZWxmLm91dF9tYXBbIlJPT0tfRVhURVJO + QUxfVVNFUl9TRUNSRVQiXSwKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgIH0sCiAgICAg + ICAgXQoKICAgICAgICAjIGlmICdNT05JVE9SSU5HX0VORFBPSU5UJyBleGlzdHMsIHRoZW4gb25s + eSBhZGQgJ21vbml0b3JpbmctZW5kcG9pbnQnIHRvIENsdXN0ZXIKICAgICAgICBpZiAoCiAgICAg + ICAgICAgIHNlbGYub3V0X21hcFsiTU9OSVRPUklOR19FTkRQT0lOVCJdCiAgICAgICAgICAgIGFu + ZCBzZWxmLm91dF9tYXBbIk1PTklUT1JJTkdfRU5EUE9JTlRfUE9SVCJdCiAgICAgICAgKToKICAg + ICAgICAgICAganNvbl9vdXQuYXBwZW5kKAogICAgICAgICAgICAgICAgewogICAgICAgICAgICAg + ICAgICAgICJuYW1lIjogIm1vbml0b3JpbmctZW5kcG9pbnQiLAogICAgICAgICAgICAgICAgICAg + ICJraW5kIjogIkNlcGhDbHVzdGVyIiwKICAgICAgICAgICAgICAgICAgICAiZGF0YSI6IHsKICAg + ICAgICAgICAgICAgICAgICAgICAgIk1vbml0b3JpbmdFbmRwb2ludCI6IHNlbGYub3V0X21hcFsi + TU9OSVRPUklOR19FTkRQT0lOVCJdLAogICAgICAgICAgICAgICAgICAgICAgICAiTW9uaXRvcmlu + Z1BvcnQiOiBzZWxmLm91dF9tYXBbIk1PTklUT1JJTkdfRU5EUE9JTlRfUE9SVCJdLAogICAgICAg + ICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICkKCiAgICAgICAg + IyBpZiAnQ1NJX1JCRF9OT0RFX1NFQ1JFVCcgZXhpc3RzLCB0aGVuIG9ubHkgYWRkICdyb29rLWNz + aS1yYmQtcHJvdmlzaW9uZXInIFNlY3JldAogICAgICAgIGlmICgKICAgICAgICAgICAgc2VsZi5v + dXRfbWFwWyJDU0lfUkJEX05PREVfU0VDUkVUIl0KICAgICAgICAgICAgYW5kIHNlbGYub3V0X21h + cFsiQ1NJX1JCRF9OT0RFX1NFQ1JFVF9OQU1FIl0KICAgICAgICApOgogICAgICAgICAgICBqc29u + X291dC5hcHBlbmQoCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgIm5hbWUi + OiBmInJvb2ste3NlbGYub3V0X21hcFsnQ1NJX1JCRF9OT0RFX1NFQ1JFVF9OQU1FJ119IiwKICAg + ICAgICAgICAgICAgICAgICAia2luZCI6ICJTZWNyZXQiLAogICAgICAgICAgICAgICAgICAgICJk + YXRhIjogewogICAgICAgICAgICAgICAgICAgICAgICAidXNlcklEIjogc2VsZi5vdXRfbWFwWyJD + U0lfUkJEX05PREVfU0VDUkVUX05BTUUiXSwKICAgICAgICAgICAgICAgICAgICAgICAgInVzZXJL + ZXkiOiBzZWxmLm91dF9tYXBbIkNTSV9SQkRfTk9ERV9TRUNSRVQiXSwKICAgICAgICAgICAgICAg + ICAgICB9LAogICAgICAgICAgICAgICAgfQogICAgICAgICAgICApCiAgICAgICAgIyBpZiAnQ1NJ + X1JCRF9QUk9WSVNJT05FUl9TRUNSRVQnIGV4aXN0cywgdGhlbiBvbmx5IGFkZCAncm9vay1jc2kt + cmJkLXByb3Zpc2lvbmVyJyBTZWNyZXQKICAgICAgICBpZiAoCiAgICAgICAgICAgIHNlbGYub3V0 + X21hcFsiQ1NJX1JCRF9QUk9WSVNJT05FUl9TRUNSRVQiXQogICAgICAgICAgICBhbmQgc2VsZi5v + dXRfbWFwWyJDU0lfUkJEX1BST1ZJU0lPTkVSX1NFQ1JFVF9OQU1FIl0KICAgICAgICApOgogICAg + ICAgICAgICBqc29uX291dC5hcHBlbmQoCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAg + ICAgICAgIm5hbWUiOiBmInJvb2ste3NlbGYub3V0X21hcFsnQ1NJX1JCRF9QUk9WSVNJT05FUl9T + RUNSRVRfTkFNRSddfSIsCiAgICAgICAgICAgICAgICAgICAgImtpbmQiOiAiU2VjcmV0IiwKICAg + ICAgICAgICAgICAgICAgICAiZGF0YSI6IHsKICAgICAgICAgICAgICAgICAgICAgICAgInVzZXJJ + RCI6IHNlbGYub3V0X21hcFsiQ1NJX1JCRF9QUk9WSVNJT05FUl9TRUNSRVRfTkFNRSJdLAogICAg + ICAgICAgICAgICAgICAgICAgICAidXNlcktleSI6IHNlbGYub3V0X21hcFsiQ1NJX1JCRF9QUk9W + SVNJT05FUl9TRUNSRVQiXSwKICAgICAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAg + fQogICAgICAgICAgICApCiAgICAgICAgIyBpZiAnQ1NJX0NFUEhGU19QUk9WSVNJT05FUl9TRUNS + RVQnIGV4aXN0cywgdGhlbiBvbmx5IGFkZCAncm9vay1jc2ktY2VwaGZzLXByb3Zpc2lvbmVyJyBT + ZWNyZXQKICAgICAgICBpZiAoCiAgICAgICAgICAgIHNlbGYub3V0X21hcFsiQ1NJX0NFUEhGU19Q + Uk9WSVNJT05FUl9TRUNSRVQiXQogICAgICAgICAgICBhbmQgc2VsZi5vdXRfbWFwWyJDU0lfQ0VQ + SEZTX1BST1ZJU0lPTkVSX1NFQ1JFVF9OQU1FIl0KICAgICAgICApOgogICAgICAgICAgICBqc29u + X291dC5hcHBlbmQoCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgIm5hbWUi + OiBmInJvb2ste3NlbGYub3V0X21hcFsnQ1NJX0NFUEhGU19QUk9WSVNJT05FUl9TRUNSRVRfTkFN + RSddfSIsCiAgICAgICAgICAgICAgICAgICAgImtpbmQiOiAiU2VjcmV0IiwKICAgICAgICAgICAg + ICAgICAgICAiZGF0YSI6IHsKICAgICAgICAgICAgICAgICAgICAgICAgImFkbWluSUQiOiBzZWxm + Lm91dF9tYXBbIkNTSV9DRVBIRlNfUFJPVklTSU9ORVJfU0VDUkVUX05BTUUiXSwKICAgICAgICAg + ICAgICAgICAgICAgICAgImFkbWluS2V5Ijogc2VsZi5vdXRfbWFwWyJDU0lfQ0VQSEZTX1BST1ZJ + U0lPTkVSX1NFQ1JFVCJdLAogICAgICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICB9 + CiAgICAgICAgICAgICkKICAgICAgICAjIGlmICdDU0lfQ0VQSEZTX05PREVfU0VDUkVUJyBleGlz + dHMsIHRoZW4gb25seSBhZGQgJ3Jvb2stY3NpLWNlcGhmcy1ub2RlJyBTZWNyZXQKICAgICAgICBp + ZiAoCiAgICAgICAgICAgIHNlbGYub3V0X21hcFsiQ1NJX0NFUEhGU19OT0RFX1NFQ1JFVCJdCiAg + ICAgICAgICAgIGFuZCBzZWxmLm91dF9tYXBbIkNTSV9DRVBIRlNfTk9ERV9TRUNSRVRfTkFNRSJd CiAgICAgICAgKToKICAgICAgICAgICAganNvbl9vdXQuYXBwZW5kKAogICAgICAgICAgICAgICAg - ewogICAgICAgICAgICAgICAgICAgICJuYW1lIjogInJhZG9zLW5hbWVzcGFjZSIsCiAgICAgICAg - ICAgICAgICAgICAgImtpbmQiOiAiQ2VwaEJsb2NrUG9vbFJhZG9zTmFtZXNwYWNlIiwKICAgICAg - ICAgICAgICAgICAgICAiZGF0YSI6IHsKICAgICAgICAgICAgICAgICAgICAgICAgInJhZG9zTmFt - ZXNwYWNlTmFtZSI6IHNlbGYub3V0X21hcFsiUkFET1NfTkFNRVNQQUNFIl0sCiAgICAgICAgICAg - ICAgICAgICAgICAgICJwb29sIjogc2VsZi5vdXRfbWFwWyJSQkRfUE9PTF9OQU1FIl0sCiAgICAg - ICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgKQogICAgICAg - ICAgICBqc29uX291dC5hcHBlbmQoCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAg - ICAgIm5hbWUiOiBmImNlcGgtcmJkLXJhZG9zLW5hbWVzcGFjZS17c2VsZi5vdXRfbWFwWydSQURP - U19OQU1FU1BBQ0UnXX0iLAogICAgICAgICAgICAgICAgICAgICJraW5kIjogIlN0b3JhZ2VDbGFz - cyIsCiAgICAgICAgICAgICAgICAgICAgImRhdGEiOiB7CiAgICAgICAgICAgICAgICAgICAgICAg - ICJwb29sIjogc2VsZi5vdXRfbWFwWyJSQkRfUE9PTF9OQU1FIl0sCiAgICAgICAgICAgICAgICAg - ICAgICAgICJjc2kuc3RvcmFnZS5rOHMuaW8vcHJvdmlzaW9uZXItc2VjcmV0LW5hbWUiOiBmInJv - b2ste3NlbGYub3V0X21hcFsnQ1NJX1JCRF9QUk9WSVNJT05FUl9TRUNSRVRfTkFNRSddfSIsCiAg - ICAgICAgICAgICAgICAgICAgICAgICJjc2kuc3RvcmFnZS5rOHMuaW8vY29udHJvbGxlci1leHBh - bmQtc2VjcmV0LW5hbWUiOiBmInJvb2ste3NlbGYub3V0X21hcFsnQ1NJX1JCRF9QUk9WSVNJT05F - Ul9TRUNSRVRfTkFNRSddfSIsCiAgICAgICAgICAgICAgICAgICAgICAgICJjc2kuc3RvcmFnZS5r - OHMuaW8vbm9kZS1zdGFnZS1zZWNyZXQtbmFtZSI6IGYicm9vay17c2VsZi5vdXRfbWFwWydDU0lf - UkJEX05PREVfU0VDUkVUX05BTUUnXX0iLAogICAgICAgICAgICAgICAgICAgIH0sCiAgICAgICAg - ICAgICAgICB9CiAgICAgICAgICAgICkKICAgICAgICBlbHNlOgogICAgICAgICAgICBpZiBzZWxm - Lm91dF9tYXBbIlJCRF9NRVRBREFUQV9FQ19QT09MX05BTUUiXToKICAgICAgICAgICAgICAgIGpz - b25fb3V0LmFwcGVuZCgKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAg - ICAgICJuYW1lIjogImNlcGgtcmJkIiwKICAgICAgICAgICAgICAgICAgICAgICAgImtpbmQiOiAi - U3RvcmFnZUNsYXNzIiwKICAgICAgICAgICAgICAgICAgICAgICAgImRhdGEiOiB7CiAgICAgICAg - ICAgICAgICAgICAgICAgICAgICAiZGF0YVBvb2wiOiBzZWxmLm91dF9tYXBbIlJCRF9QT09MX05B - TUUiXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJwb29sIjogc2VsZi5vdXRfbWFwWyJS - QkRfTUVUQURBVEFfRUNfUE9PTF9OQU1FIl0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAi - Y3NpLnN0b3JhZ2UuazhzLmlvL3Byb3Zpc2lvbmVyLXNlY3JldC1uYW1lIjogZiJyb29rLXtzZWxm - Lm91dF9tYXBbJ0NTSV9SQkRfUFJPVklTSU9ORVJfU0VDUkVUX05BTUUnXX0iLAogICAgICAgICAg - ICAgICAgICAgICAgICAgICAgImNzaS5zdG9yYWdlLms4cy5pby9jb250cm9sbGVyLWV4cGFuZC1z - ZWNyZXQtbmFtZSI6IGYicm9vay17c2VsZi5vdXRfbWFwWydDU0lfUkJEX1BST1ZJU0lPTkVSX1NF - Q1JFVF9OQU1FJ119IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJjc2kuc3RvcmFnZS5r - OHMuaW8vbm9kZS1zdGFnZS1zZWNyZXQtbmFtZSI6IGYicm9vay17c2VsZi5vdXRfbWFwWydDU0lf - UkJEX05PREVfU0VDUkVUX05BTUUnXX0iLAogICAgICAgICAgICAgICAgICAgICAgICB9LAogICAg - ICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgZWxzZToKICAg - ICAgICAgICAgICAgIGpzb25fb3V0LmFwcGVuZCgKICAgICAgICAgICAgICAgICAgICB7CiAgICAg - ICAgICAgICAgICAgICAgICAgICJuYW1lIjogImNlcGgtcmJkIiwKICAgICAgICAgICAgICAgICAg - ICAgICAgImtpbmQiOiAiU3RvcmFnZUNsYXNzIiwKICAgICAgICAgICAgICAgICAgICAgICAgImRh - dGEiOiB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAicG9vbCI6IHNlbGYub3V0X21hcFsi - UkJEX1BPT0xfTkFNRSJdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgImNzaS5zdG9yYWdl - Lms4cy5pby9wcm92aXNpb25lci1zZWNyZXQtbmFtZSI6IGYicm9vay17c2VsZi5vdXRfbWFwWydD - U0lfUkJEX1BST1ZJU0lPTkVSX1NFQ1JFVF9OQU1FJ119IiwKICAgICAgICAgICAgICAgICAgICAg - ICAgICAgICJjc2kuc3RvcmFnZS5rOHMuaW8vY29udHJvbGxlci1leHBhbmQtc2VjcmV0LW5hbWUi - OiBmInJvb2ste3NlbGYub3V0X21hcFsnQ1NJX1JCRF9QUk9WSVNJT05FUl9TRUNSRVRfTkFNRSdd - fSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiY3NpLnN0b3JhZ2UuazhzLmlvL25vZGUt - c3RhZ2Utc2VjcmV0LW5hbWUiOiBmInJvb2ste3NlbGYub3V0X21hcFsnQ1NJX1JCRF9OT0RFX1NF - Q1JFVF9OQU1FJ119IiwKICAgICAgICAgICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAg - ICAgICB9CiAgICAgICAgICAgICAgICApCgogICAgICAgICMgaWYgJ1RPUE9MT0dZX1BPT0xTJywg - J1RPUE9MT0dZX0ZBSUxVUkVfRE9NQUlOX0xBQkVMJywgJ1RPUE9MT0dZX0ZBSUxVUkVfRE9NQUlO - X1ZBTFVFUycgIGV4aXN0cywKICAgICAgICAjIHRoZW4gb25seSBhZGQgJ3RvcG9sb2d5JyBTdG9y - YWdlQ2xhc3MKICAgICAgICBpZiAoCiAgICAgICAgICAgIHNlbGYub3V0X21hcFsiVE9QT0xPR1lf - UE9PTFMiXQogICAgICAgICAgICBhbmQgc2VsZi5vdXRfbWFwWyJUT1BPTE9HWV9GQUlMVVJFX0RP - TUFJTl9MQUJFTCJdCiAgICAgICAgICAgIGFuZCBzZWxmLm91dF9tYXBbIlRPUE9MT0dZX0ZBSUxV - UkVfRE9NQUlOX1ZBTFVFUyJdCiAgICAgICAgKToKICAgICAgICAgICAganNvbl9vdXQuYXBwZW5k - KAogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICJuYW1lIjogImNlcGgtcmJk - LXRvcG9sb2d5IiwKICAgICAgICAgICAgICAgICAgICAia2luZCI6ICJTdG9yYWdlQ2xhc3MiLAog - ICAgICAgICAgICAgICAgICAgICJkYXRhIjogewogICAgICAgICAgICAgICAgICAgICAgICAidG9w - b2xvZ3lGYWlsdXJlRG9tYWluTGFiZWwiOiBzZWxmLm91dF9tYXBbCiAgICAgICAgICAgICAgICAg - ICAgICAgICAgICAiVE9QT0xPR1lfRkFJTFVSRV9ET01BSU5fTEFCRUwiCiAgICAgICAgICAgICAg - ICAgICAgICAgIF0sCiAgICAgICAgICAgICAgICAgICAgICAgICJ0b3BvbG9neUZhaWx1cmVEb21h - aW5WYWx1ZXMiOiBzZWxmLm91dF9tYXBbCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiVE9Q - T0xPR1lfRkFJTFVSRV9ET01BSU5fVkFMVUVTIgogICAgICAgICAgICAgICAgICAgICAgICBdLAog - ICAgICAgICAgICAgICAgICAgICAgICAidG9wb2xvZ3lQb29scyI6IHNlbGYub3V0X21hcFsiVE9Q - T0xPR1lfUE9PTFMiXSwKICAgICAgICAgICAgICAgICAgICAgICAgImNzaS5zdG9yYWdlLms4cy5p - by9wcm92aXNpb25lci1zZWNyZXQtbmFtZSI6IGYicm9vay17c2VsZi5vdXRfbWFwWydDU0lfUkJE - X1BST1ZJU0lPTkVSX1NFQ1JFVF9OQU1FJ119IiwKICAgICAgICAgICAgICAgICAgICAgICAgImNz - aS5zdG9yYWdlLms4cy5pby9jb250cm9sbGVyLWV4cGFuZC1zZWNyZXQtbmFtZSI6IGYicm9vay17 - c2VsZi5vdXRfbWFwWydDU0lfUkJEX1BST1ZJU0lPTkVSX1NFQ1JFVF9OQU1FJ119IiwKICAgICAg - ICAgICAgICAgICAgICAgICAgImNzaS5zdG9yYWdlLms4cy5pby9ub2RlLXN0YWdlLXNlY3JldC1u - YW1lIjogZiJyb29rLXtzZWxmLm91dF9tYXBbJ0NTSV9SQkRfTk9ERV9TRUNSRVRfTkFNRSddfSIs - CiAgICAgICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgKQoK - ICAgICAgICAjIGlmICdDRVBIRlNfRlNfTkFNRScgZXhpc3RzLCB0aGVuIG9ubHkgYWRkICdjZXBo - ZnMnIFN0b3JhZ2VDbGFzcwogICAgICAgIGlmIHNlbGYub3V0X21hcFsiQ0VQSEZTX0ZTX05BTUUi - XToKICAgICAgICAgICAganNvbl9vdXQuYXBwZW5kKAogICAgICAgICAgICAgICAgewogICAgICAg - ICAgICAgICAgICAgICJuYW1lIjogImNlcGhmcyIsCiAgICAgICAgICAgICAgICAgICAgImtpbmQi - OiAiU3RvcmFnZUNsYXNzIiwKICAgICAgICAgICAgICAgICAgICAiZGF0YSI6IHsKICAgICAgICAg - ICAgICAgICAgICAgICAgImZzTmFtZSI6IHNlbGYub3V0X21hcFsiQ0VQSEZTX0ZTX05BTUUiXSwK - ICAgICAgICAgICAgICAgICAgICAgICAgInBvb2wiOiBzZWxmLm91dF9tYXBbIkNFUEhGU19QT09M - X05BTUUiXSwKICAgICAgICAgICAgICAgICAgICAgICAgImNzaS5zdG9yYWdlLms4cy5pby9wcm92 - aXNpb25lci1zZWNyZXQtbmFtZSI6IGYicm9vay17c2VsZi5vdXRfbWFwWydDU0lfQ0VQSEZTX1BS - T1ZJU0lPTkVSX1NFQ1JFVF9OQU1FJ119IiwKICAgICAgICAgICAgICAgICAgICAgICAgImNzaS5z - dG9yYWdlLms4cy5pby9jb250cm9sbGVyLWV4cGFuZC1zZWNyZXQtbmFtZSI6IGYicm9vay17c2Vs - Zi5vdXRfbWFwWydDU0lfQ0VQSEZTX1BST1ZJU0lPTkVSX1NFQ1JFVF9OQU1FJ119IiwKICAgICAg - ICAgICAgICAgICAgICAgICAgImNzaS5zdG9yYWdlLms4cy5pby9ub2RlLXN0YWdlLXNlY3JldC1u - YW1lIjogZiJyb29rLXtzZWxmLm91dF9tYXBbJ0NTSV9DRVBIRlNfTk9ERV9TRUNSRVRfTkFNRSdd - fSIsCiAgICAgICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAg - KQogICAgICAgICMgaWYgJ1JHV19FTkRQT0lOVCcgZXhpc3RzLCB0aGVuIG9ubHkgYWRkICdjZXBo - LXJndycgU3RvcmFnZUNsYXNzCiAgICAgICAgaWYgc2VsZi5vdXRfbWFwWyJSR1dfRU5EUE9JTlQi - XToKICAgICAgICAgICAganNvbl9vdXQuYXBwZW5kKAogICAgICAgICAgICAgICAgewogICAgICAg - ICAgICAgICAgICAgICJuYW1lIjogImNlcGgtcmd3IiwKICAgICAgICAgICAgICAgICAgICAia2lu - ZCI6ICJTdG9yYWdlQ2xhc3MiLAogICAgICAgICAgICAgICAgICAgICJkYXRhIjogewogICAgICAg - ICAgICAgICAgICAgICAgICAiZW5kcG9pbnQiOiBzZWxmLm91dF9tYXBbIlJHV19FTkRQT0lOVCJd - LAogICAgICAgICAgICAgICAgICAgICAgICAicG9vbFByZWZpeCI6IHNlbGYub3V0X21hcFsiUkdX - X1BPT0xfUFJFRklYIl0sCiAgICAgICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgIH0K - ICAgICAgICAgICAgKQogICAgICAgICAgICBqc29uX291dC5hcHBlbmQoCiAgICAgICAgICAgICAg - ICB7CiAgICAgICAgICAgICAgICAgICAgIm5hbWUiOiAicmd3LWFkbWluLW9wcy11c2VyIiwKICAg + ewogICAgICAgICAgICAgICAgICAgICJuYW1lIjogZiJyb29rLXtzZWxmLm91dF9tYXBbJ0NTSV9D + RVBIRlNfTk9ERV9TRUNSRVRfTkFNRSddfSIsCiAgICAgICAgICAgICAgICAgICAgImtpbmQiOiAi + U2VjcmV0IiwKICAgICAgICAgICAgICAgICAgICAiZGF0YSI6IHsKICAgICAgICAgICAgICAgICAg + ICAgICAgImFkbWluSUQiOiBzZWxmLm91dF9tYXBbIkNTSV9DRVBIRlNfTk9ERV9TRUNSRVRfTkFN + RSJdLAogICAgICAgICAgICAgICAgICAgICAgICAiYWRtaW5LZXkiOiBzZWxmLm91dF9tYXBbIkNT + SV9DRVBIRlNfTk9ERV9TRUNSRVQiXSwKICAgICAgICAgICAgICAgICAgICB9LAogICAgICAgICAg + ICAgICAgfQogICAgICAgICAgICApCiAgICAgICAgIyBpZiAnUk9PS19FWFRFUk5BTF9EQVNIQk9B + UkRfTElOSycgZXhpc3RzLCB0aGVuIG9ubHkgYWRkICdyb29rLWNlcGgtZGFzaGJvYXJkLWxpbmsn + IFNlY3JldAogICAgICAgIGlmIHNlbGYub3V0X21hcFsiUk9PS19FWFRFUk5BTF9EQVNIQk9BUkRf + TElOSyJdOgogICAgICAgICAgICBqc29uX291dC5hcHBlbmQoCiAgICAgICAgICAgICAgICB7CiAg + ICAgICAgICAgICAgICAgICAgIm5hbWUiOiAicm9vay1jZXBoLWRhc2hib2FyZC1saW5rIiwKICAg ICAgICAgICAgICAgICAgICAia2luZCI6ICJTZWNyZXQiLAogICAgICAgICAgICAgICAgICAgICJk - YXRhIjogewogICAgICAgICAgICAgICAgICAgICAgICAiYWNjZXNzS2V5Ijogc2VsZi5vdXRfbWFw - WyJSR1dfQURNSU5fT1BTX1VTRVJfQUNDRVNTX0tFWSJdLAogICAgICAgICAgICAgICAgICAgICAg - ICAic2VjcmV0S2V5Ijogc2VsZi5vdXRfbWFwWyJSR1dfQURNSU5fT1BTX1VTRVJfU0VDUkVUX0tF - WSJdLAogICAgICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAg - ICkKICAgICAgICAjIGlmICdSR1dfVExTX0NFUlQnIGV4aXN0cywgdGhlbiBvbmx5IGFkZCB0aGUg - ImNlcGgtcmd3LXRscy1jZXJ0IiBzZWNyZXQKICAgICAgICBpZiBzZWxmLm91dF9tYXBbIlJHV19U - TFNfQ0VSVCJdOgogICAgICAgICAgICBqc29uX291dC5hcHBlbmQoCiAgICAgICAgICAgICAgICB7 - CiAgICAgICAgICAgICAgICAgICAgIm5hbWUiOiAiY2VwaC1yZ3ctdGxzLWNlcnQiLAogICAgICAg - ICAgICAgICAgICAgICJraW5kIjogIlNlY3JldCIsCiAgICAgICAgICAgICAgICAgICAgImRhdGEi - OiB7CiAgICAgICAgICAgICAgICAgICAgICAgICJjZXJ0Ijogc2VsZi5vdXRfbWFwWyJSR1dfVExT - X0NFUlQiXSwKICAgICAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgfQogICAgICAg - ICAgICApCgogICAgICAgIHJldHVybiBqc29uLmR1bXBzKGpzb25fb3V0KSArIExJTkVTRVAKCiAg - ICBkZWYgdXBncmFkZV91c2Vyc19wZXJtaXNzaW9ucyhzZWxmKToKICAgICAgICB1c2VycyA9IFsK - ICAgICAgICAgICAgImNsaWVudC5jc2ktY2VwaGZzLW5vZGUiLAogICAgICAgICAgICAiY2xpZW50 - LmNzaS1jZXBoZnMtcHJvdmlzaW9uZXIiLAogICAgICAgICAgICAiY2xpZW50LmNzaS1yYmQtbm9k - ZSIsCiAgICAgICAgICAgICJjbGllbnQuY3NpLXJiZC1wcm92aXNpb25lciIsCiAgICAgICAgICAg - ICJjbGllbnQuaGVhbHRoY2hlY2tlciIsCiAgICAgICAgXQogICAgICAgIGlmIHNlbGYucnVuX2Fz - X3VzZXIgIT0gIiIgYW5kIHNlbGYucnVuX2FzX3VzZXIgbm90IGluIHVzZXJzOgogICAgICAgICAg - ICB1c2Vycy5hcHBlbmQoc2VsZi5ydW5fYXNfdXNlcikKICAgICAgICBmb3IgdXNlciBpbiB1c2Vy - czoKICAgICAgICAgICAgc2VsZi51cGdyYWRlX3VzZXJfcGVybWlzc2lvbnModXNlcikKCiAgICBk - ZWYgZ2V0X3Jnd19wb29sX25hbWVfZHVyaW5nX3VwZ3JhZGUoc2VsZiwgdXNlciwgY2Fwcyk6CiAg - ICAgICAgaWYgdXNlciA9PSAiY2xpZW50LmhlYWx0aGNoZWNrZXIiOgogICAgICAgICAgICAjIHdo - ZW4gYWRtaW4gaGFzIG5vdCBwcm92aWRlZCByZ3cgcG9vbCBuYW1lIGR1cmluZyB1cGdyYWRlLAog - ICAgICAgICAgICAjIGdldCB0aGUgcmd3IHBvb2wgbmFtZSBmcm9tIGNsaWVudC5oZWFsdGhjaGVj - a2VyIHVzZXIgd2hpY2ggd2FzIHVzZWQgZHVyaW5nIGNvbm5lY3Rpb24KICAgICAgICAgICAgaWYg - bm90IHNlbGYuX2FyZ19wYXJzZXIucmd3X3Bvb2xfcHJlZml4OgogICAgICAgICAgICAgICAgIyBU - byBnZXQgdmFsdWUgJ2RlZmF1bHQnIHdoaWNoIGlzIHJndyBwb29sIG5hbWUgZnJvbSAnYWxsb3cg - cnd4IHBvb2w9ZGVmYXVsdC5yZ3cubWV0YScKICAgICAgICAgICAgICAgIHBhdHRlcm4gPSByInBv - b2w9KC4qPylcLnJnd1wubWV0YSIKICAgICAgICAgICAgICAgIG1hdGNoID0gcmUuc2VhcmNoKHBh - dHRlcm4sIGNhcHMpCiAgICAgICAgICAgICAgICBpZiBtYXRjaDoKICAgICAgICAgICAgICAgICAg - ICBzZWxmLl9hcmdfcGFyc2VyLnJnd19wb29sX3ByZWZpeCA9IG1hdGNoLmdyb3VwKDEpCiAgICAg - ICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgICAgIHJhaXNlIEV4ZWN1dGlvbkZhaWx1 - cmVFeGNlcHRpb24oCiAgICAgICAgICAgICAgICAgICAgICAgICJmYWlsZWQgdG8gZ2V0IHJndyBw - b29sIG5hbWUgZm9yIHVwZ3JhZGUiCiAgICAgICAgICAgICAgICAgICAgKQoKICAgIGRlZiB1cGdy - YWRlX3VzZXJfcGVybWlzc2lvbnMoc2VsZiwgdXNlcik6CiAgICAgICAgIyBjaGVjayB3aGV0aGVy - IHRoZSBnaXZlbiB1c2VyIGV4aXN0cyBvciBub3QKICAgICAgICBjbWRfanNvbiA9IHsicHJlZml4 - IjogImF1dGggZ2V0IiwgImVudGl0eSI6IGYie3VzZXJ9IiwgImZvcm1hdCI6ICJqc29uIn0KICAg - ICAgICByZXRfdmFsLCBqc29uX291dCwgZXJyX21zZyA9IHNlbGYuX2NvbW1vbl9jbWRfanNvbl9n - ZW4oY21kX2pzb24pCiAgICAgICAgaWYgcmV0X3ZhbCAhPSAwIG9yIGxlbihqc29uX291dCkgPT0g - MDoKICAgICAgICAgICAgcHJpbnQoZiJ1c2VyIHt1c2VyfSBub3QgZm91bmQgZm9yIHVwZ3JhZGlu - Zy4iKQogICAgICAgICAgICByZXR1cm4KICAgICAgICBleGlzdGluZ19jYXBzID0ganNvbl9vdXRb - MF1bImNhcHMiXQogICAgICAgIHNlbGYuZ2V0X3Jnd19wb29sX25hbWVfZHVyaW5nX3VwZ3JhZGUo - dXNlciwgc3RyKGV4aXN0aW5nX2NhcHMpKQogICAgICAgIG5ld19jYXAsIF8gPSBzZWxmLmdldF9j - YXBzX2FuZF9lbnRpdHkodXNlcikKICAgICAgICBjYXBfa2V5cyA9IFsibW9uIiwgIm1nciIsICJv - c2QiLCAibWRzIl0KICAgICAgICBjYXBzID0gW10KICAgICAgICBmb3IgZWFjaENhcCBpbiBjYXBf - a2V5czoKICAgICAgICAgICAgY3VyX2NhcF92YWx1ZXMgPSBleGlzdGluZ19jYXBzLmdldChlYWNo - Q2FwLCAiIikKICAgICAgICAgICAgbmV3X2NhcF92YWx1ZXMgPSBuZXdfY2FwLmdldChlYWNoQ2Fw - LCAiIikKICAgICAgICAgICAgY3VyX2NhcF9wZXJtX2xpc3QgPSBbCiAgICAgICAgICAgICAgICB4 - LnN0cmlwKCkgZm9yIHggaW4gY3VyX2NhcF92YWx1ZXMuc3BsaXQoIiwiKSBpZiB4LnN0cmlwKCkK - ICAgICAgICAgICAgXQogICAgICAgICAgICBuZXdfY2FwX3Blcm1fbGlzdCA9IFsKICAgICAgICAg - ICAgICAgIHguc3RyaXAoKSBmb3IgeCBpbiBuZXdfY2FwX3ZhbHVlcy5zcGxpdCgiLCIpIGlmIHgu - c3RyaXAoKQogICAgICAgICAgICBdCiAgICAgICAgICAgICMgYXBwZW5kIG5ld19jYXBfbGlzdCB0 - byBjdXJfY2FwX2xpc3QgdG8gbWFpbnRhaW4gdGhlIG9yZGVyIG9mIGNhcHMKICAgICAgICAgICAg - Y3VyX2NhcF9wZXJtX2xpc3QuZXh0ZW5kKG5ld19jYXBfcGVybV9saXN0KQogICAgICAgICAgICAj - IGVsaW1pbmF0ZSBkdXBsaWNhdGVzIHdpdGhvdXQgdXNpbmcgJ3NldCcKICAgICAgICAgICAgIyBz - ZXQgcmUtb3JkZXJzIGl0ZW1zIGluIHRoZSBsaXN0IGFuZCB3ZSBoYXZlIHRvIGtlZXAgdGhlIG9y - ZGVyCiAgICAgICAgICAgIG5ld19jYXBfbGlzdCA9IFtdCiAgICAgICAgICAgIFtuZXdfY2FwX2xp - c3QuYXBwZW5kKHgpIGZvciB4IGluIGN1cl9jYXBfcGVybV9saXN0IGlmIHggbm90IGluIG5ld19j - YXBfbGlzdF0KICAgICAgICAgICAgZXhpc3RpbmdfY2Fwc1tlYWNoQ2FwXSA9ICIsICIuam9pbihu - ZXdfY2FwX2xpc3QpCiAgICAgICAgICAgIGlmIGV4aXN0aW5nX2NhcHNbZWFjaENhcF06CiAgICAg - ICAgICAgICAgICBjYXBzLmFwcGVuZChlYWNoQ2FwKQogICAgICAgICAgICAgICAgY2Fwcy5hcHBl - bmQoZXhpc3RpbmdfY2Fwc1tlYWNoQ2FwXSkKICAgICAgICBjbWRfanNvbiA9IHsKICAgICAgICAg - ICAgInByZWZpeCI6ICJhdXRoIGNhcHMiLAogICAgICAgICAgICAiZW50aXR5IjogdXNlciwKICAg - ICAgICAgICAgImNhcHMiOiBjYXBzLAogICAgICAgICAgICAiZm9ybWF0IjogImpzb24iLAogICAg - ICAgIH0KICAgICAgICByZXRfdmFsLCBqc29uX291dCwgZXJyX21zZyA9IHNlbGYuX2NvbW1vbl9j - bWRfanNvbl9nZW4oY21kX2pzb24pCiAgICAgICAgaWYgcmV0X3ZhbCAhPSAwOgogICAgICAgICAg - ICByYWlzZSBFeGVjdXRpb25GYWlsdXJlRXhjZXB0aW9uKAogICAgICAgICAgICAgICAgZiInYXV0 - aCBjYXBzIHt1c2VyfScgY29tbWFuZCBmYWlsZWQuXG4gRXJyb3I6IHtlcnJfbXNnfSIKICAgICAg - ICAgICAgKQogICAgICAgIHByaW50KGYiVXBkYXRlZCB1c2VyIHt1c2VyfSBzdWNjZXNzZnVsbHku - IikKCiAgICBkZWYgbWFpbihzZWxmKToKICAgICAgICBnZW5lcmF0ZWRfb3V0cHV0ID0gIiIKICAg - ICAgICBpZiBzZWxmLl9hcmdfcGFyc2VyLnVwZ3JhZGU6CiAgICAgICAgICAgIHNlbGYudXBncmFk - ZV91c2Vyc19wZXJtaXNzaW9ucygpCiAgICAgICAgZWxpZiBzZWxmLl9hcmdfcGFyc2VyLmZvcm1h - dCA9PSAianNvbiI6CiAgICAgICAgICAgIGdlbmVyYXRlZF9vdXRwdXQgPSBzZWxmLmdlbl9qc29u - X291dCgpCiAgICAgICAgZWxpZiBzZWxmLl9hcmdfcGFyc2VyLmZvcm1hdCA9PSAiYmFzaCI6CiAg - ICAgICAgICAgIGdlbmVyYXRlZF9vdXRwdXQgPSBzZWxmLmdlbl9zaGVsbF9vdXQoKQogICAgICAg - IGVsc2U6CiAgICAgICAgICAgIHJhaXNlIEV4ZWN1dGlvbkZhaWx1cmVFeGNlcHRpb24oCiAgICAg - ICAgICAgICAgICBmIlVuc3VwcG9ydGVkIGZvcm1hdDoge3NlbGYuX2FyZ19wYXJzZXIuZm9ybWF0 - fSIKICAgICAgICAgICAgKQogICAgICAgIHByaW50KGdlbmVyYXRlZF9vdXRwdXQpCiAgICAgICAg - aWYgc2VsZi5vdXRwdXRfZmlsZSBhbmQgZ2VuZXJhdGVkX291dHB1dDoKICAgICAgICAgICAgZk91 - dCA9IG9wZW4oc2VsZi5vdXRwdXRfZmlsZSwgbW9kZT0idyIsIGVuY29kaW5nPSJVVEYtOCIpCiAg - ICAgICAgICAgIGZPdXQud3JpdGUoZ2VuZXJhdGVkX291dHB1dCkKICAgICAgICAgICAgZk91dC5j - bG9zZSgpCgoKIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMj - CiMjIyMjIyMjIyMjIyMjIyMjIyMjIyBNQUlOICMjIyMjIyMjIyMjIyMjIyMjIyMjIwojIyMjIyMj - IyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKaWYgX19uYW1lX18gPT0g - Il9fbWFpbl9fIjoKICAgIHJqT2JqID0gUmFkb3NKU09OKCkKICAgIHRyeToKICAgICAgICByak9i - ai5tYWluKCkKICAgIGV4Y2VwdCBFeGVjdXRpb25GYWlsdXJlRXhjZXB0aW9uIGFzIGVycjoKICAg - ICAgICBwcmludChmIkV4ZWN1dGlvbiBGYWlsZWQ6IHtlcnJ9IikKICAgICAgICByYWlzZSBlcnIK - ICAgIGV4Y2VwdCBLZXlFcnJvciBhcyBrRXJyOgogICAgICAgIHByaW50KGYiS2V5RXJyb3I6IHtr - RXJyfSIpCiAgICBleGNlcHQgT1NFcnJvciBhcyBvc0VycjoKICAgICAgICBwcmludChmIkVycm9y - IHdoaWxlIHRyeWluZyB0byBvdXRwdXQgdGhlIGRhdGE6IHtvc0Vycn0iKQogICAgZmluYWxseToK - ICAgICAgICByak9iai5zaHV0ZG93bigpCg== + YXRhIjogewogICAgICAgICAgICAgICAgICAgICAgICAidXNlcklEIjogImNlcGgtZGFzaGJvYXJk + LWxpbmsiLAogICAgICAgICAgICAgICAgICAgICAgICAidXNlcktleSI6IHNlbGYub3V0X21hcFsi + Uk9PS19FWFRFUk5BTF9EQVNIQk9BUkRfTElOSyJdLAogICAgICAgICAgICAgICAgICAgIH0sCiAg + ICAgICAgICAgICAgICB9CiAgICAgICAgICAgICkKICAgICAgICAjIGlmICdSQURPU19OQU1FU1BB + Q0UnIGV4aXN0cywgdGhlbiBvbmx5IGFkZCB0aGUgIlJBRE9TX05BTUVTUEFDRSIgbmFtZXNwYWNl + CiAgICAgICAgaWYgKAogICAgICAgICAgICBzZWxmLm91dF9tYXBbIlJBRE9TX05BTUVTUEFDRSJd + CiAgICAgICAgICAgIGFuZCBzZWxmLm91dF9tYXBbIlJFU1RSSUNURURfQVVUSF9QRVJNSVNTSU9O + Il0KICAgICAgICAgICAgYW5kIG5vdCBzZWxmLm91dF9tYXBbIlJCRF9NRVRBREFUQV9FQ19QT09M + X05BTUUiXQogICAgICAgICk6CiAgICAgICAgICAgIGpzb25fb3V0LmFwcGVuZCgKICAgICAgICAg + ICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAibmFtZSI6ICJyYWRvcy1uYW1lc3BhY2UiLAog + ICAgICAgICAgICAgICAgICAgICJraW5kIjogIkNlcGhCbG9ja1Bvb2xSYWRvc05hbWVzcGFjZSIs + CiAgICAgICAgICAgICAgICAgICAgImRhdGEiOiB7CiAgICAgICAgICAgICAgICAgICAgICAgICJy + YWRvc05hbWVzcGFjZU5hbWUiOiBzZWxmLm91dF9tYXBbIlJBRE9TX05BTUVTUEFDRSJdLAogICAg + ICAgICAgICAgICAgICAgICAgICAicG9vbCI6IHNlbGYub3V0X21hcFsiUkJEX1BPT0xfTkFNRSJd + LAogICAgICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICkK + ICAgICAgICAgICAganNvbl9vdXQuYXBwZW5kKAogICAgICAgICAgICAgICAgewogICAgICAgICAg + ICAgICAgICAgICJuYW1lIjogZiJjZXBoLXJiZC1yYWRvcy1uYW1lc3BhY2Ute3NlbGYub3V0X21h + cFsnUkFET1NfTkFNRVNQQUNFJ119IiwKICAgICAgICAgICAgICAgICAgICAia2luZCI6ICJTdG9y + YWdlQ2xhc3MiLAogICAgICAgICAgICAgICAgICAgICJkYXRhIjogewogICAgICAgICAgICAgICAg + ICAgICAgICAicG9vbCI6IHNlbGYub3V0X21hcFsiUkJEX1BPT0xfTkFNRSJdLAogICAgICAgICAg + ICAgICAgICAgICAgICAiY3NpLnN0b3JhZ2UuazhzLmlvL3Byb3Zpc2lvbmVyLXNlY3JldC1uYW1l + IjogZiJyb29rLXtzZWxmLm91dF9tYXBbJ0NTSV9SQkRfUFJPVklTSU9ORVJfU0VDUkVUX05BTUUn + XX0iLAogICAgICAgICAgICAgICAgICAgICAgICAiY3NpLnN0b3JhZ2UuazhzLmlvL2NvbnRyb2xs + ZXItZXhwYW5kLXNlY3JldC1uYW1lIjogZiJyb29rLXtzZWxmLm91dF9tYXBbJ0NTSV9SQkRfUFJP + VklTSU9ORVJfU0VDUkVUX05BTUUnXX0iLAogICAgICAgICAgICAgICAgICAgICAgICAiY3NpLnN0 + b3JhZ2UuazhzLmlvL25vZGUtc3RhZ2Utc2VjcmV0LW5hbWUiOiBmInJvb2ste3NlbGYub3V0X21h + cFsnQ1NJX1JCRF9OT0RFX1NFQ1JFVF9OQU1FJ119IiwKICAgICAgICAgICAgICAgICAgICB9LAog + ICAgICAgICAgICAgICAgfQogICAgICAgICAgICApCiAgICAgICAgZWxzZToKICAgICAgICAgICAg + aWYgc2VsZi5vdXRfbWFwWyJSQkRfTUVUQURBVEFfRUNfUE9PTF9OQU1FIl06CiAgICAgICAgICAg + ICAgICBqc29uX291dC5hcHBlbmQoCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAg + ICAgICAgICAgICAibmFtZSI6ICJjZXBoLXJiZCIsCiAgICAgICAgICAgICAgICAgICAgICAgICJr + aW5kIjogIlN0b3JhZ2VDbGFzcyIsCiAgICAgICAgICAgICAgICAgICAgICAgICJkYXRhIjogewog + ICAgICAgICAgICAgICAgICAgICAgICAgICAgImRhdGFQb29sIjogc2VsZi5vdXRfbWFwWyJSQkRf + UE9PTF9OQU1FIl0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAicG9vbCI6IHNlbGYub3V0 + X21hcFsiUkJEX01FVEFEQVRBX0VDX1BPT0xfTkFNRSJdLAogICAgICAgICAgICAgICAgICAgICAg + ICAgICAgImNzaS5zdG9yYWdlLms4cy5pby9wcm92aXNpb25lci1zZWNyZXQtbmFtZSI6IGYicm9v + ay17c2VsZi5vdXRfbWFwWydDU0lfUkJEX1BST1ZJU0lPTkVSX1NFQ1JFVF9OQU1FJ119IiwKICAg + ICAgICAgICAgICAgICAgICAgICAgICAgICJjc2kuc3RvcmFnZS5rOHMuaW8vY29udHJvbGxlci1l + eHBhbmQtc2VjcmV0LW5hbWUiOiBmInJvb2ste3NlbGYub3V0X21hcFsnQ1NJX1JCRF9QUk9WSVNJ + T05FUl9TRUNSRVRfTkFNRSddfSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiY3NpLnN0 + b3JhZ2UuazhzLmlvL25vZGUtc3RhZ2Utc2VjcmV0LW5hbWUiOiBmInJvb2ste3NlbGYub3V0X21h + cFsnQ1NJX1JCRF9OT0RFX1NFQ1JFVF9OQU1FJ119IiwKICAgICAgICAgICAgICAgICAgICAgICAg + fSwKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICApCiAgICAgICAgICAgIGVs + c2U6CiAgICAgICAgICAgICAgICBqc29uX291dC5hcHBlbmQoCiAgICAgICAgICAgICAgICAgICAg + ewogICAgICAgICAgICAgICAgICAgICAgICAibmFtZSI6ICJjZXBoLXJiZCIsCiAgICAgICAgICAg + ICAgICAgICAgICAgICJraW5kIjogIlN0b3JhZ2VDbGFzcyIsCiAgICAgICAgICAgICAgICAgICAg + ICAgICJkYXRhIjogewogICAgICAgICAgICAgICAgICAgICAgICAgICAgInBvb2wiOiBzZWxmLm91 + dF9tYXBbIlJCRF9QT09MX05BTUUiXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJjc2ku + c3RvcmFnZS5rOHMuaW8vcHJvdmlzaW9uZXItc2VjcmV0LW5hbWUiOiBmInJvb2ste3NlbGYub3V0 + X21hcFsnQ1NJX1JCRF9QUk9WSVNJT05FUl9TRUNSRVRfTkFNRSddfSIsCiAgICAgICAgICAgICAg + ICAgICAgICAgICAgICAiY3NpLnN0b3JhZ2UuazhzLmlvL2NvbnRyb2xsZXItZXhwYW5kLXNlY3Jl + dC1uYW1lIjogZiJyb29rLXtzZWxmLm91dF9tYXBbJ0NTSV9SQkRfUFJPVklTSU9ORVJfU0VDUkVU + X05BTUUnXX0iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgImNzaS5zdG9yYWdlLms4cy5p + by9ub2RlLXN0YWdlLXNlY3JldC1uYW1lIjogZiJyb29rLXtzZWxmLm91dF9tYXBbJ0NTSV9SQkRf + Tk9ERV9TRUNSRVRfTkFNRSddfSIsCiAgICAgICAgICAgICAgICAgICAgICAgIH0sCiAgICAgICAg + ICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgKQoKICAgICAgICAjIGlmICdUT1BPTE9HWV9Q + T09MUycsICdUT1BPTE9HWV9GQUlMVVJFX0RPTUFJTl9MQUJFTCcsICdUT1BPTE9HWV9GQUlMVVJF + X0RPTUFJTl9WQUxVRVMnICBleGlzdHMsCiAgICAgICAgIyB0aGVuIG9ubHkgYWRkICd0b3BvbG9n + eScgU3RvcmFnZUNsYXNzCiAgICAgICAgaWYgKAogICAgICAgICAgICBzZWxmLm91dF9tYXBbIlRP + UE9MT0dZX1BPT0xTIl0KICAgICAgICAgICAgYW5kIHNlbGYub3V0X21hcFsiVE9QT0xPR1lfRkFJ + TFVSRV9ET01BSU5fTEFCRUwiXQogICAgICAgICAgICBhbmQgc2VsZi5vdXRfbWFwWyJUT1BPTE9H + WV9GQUlMVVJFX0RPTUFJTl9WQUxVRVMiXQogICAgICAgICk6CiAgICAgICAgICAgIGpzb25fb3V0 + LmFwcGVuZCgKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAibmFtZSI6ICJj + ZXBoLXJiZC10b3BvbG9neSIsCiAgICAgICAgICAgICAgICAgICAgImtpbmQiOiAiU3RvcmFnZUNs + YXNzIiwKICAgICAgICAgICAgICAgICAgICAiZGF0YSI6IHsKICAgICAgICAgICAgICAgICAgICAg + ICAgInRvcG9sb2d5RmFpbHVyZURvbWFpbkxhYmVsIjogc2VsZi5vdXRfbWFwWwogICAgICAgICAg + ICAgICAgICAgICAgICAgICAgIlRPUE9MT0dZX0ZBSUxVUkVfRE9NQUlOX0xBQkVMIgogICAgICAg + ICAgICAgICAgICAgICAgICBdLAogICAgICAgICAgICAgICAgICAgICAgICAidG9wb2xvZ3lGYWls + dXJlRG9tYWluVmFsdWVzIjogc2VsZi5vdXRfbWFwWwogICAgICAgICAgICAgICAgICAgICAgICAg + ICAgIlRPUE9MT0dZX0ZBSUxVUkVfRE9NQUlOX1ZBTFVFUyIKICAgICAgICAgICAgICAgICAgICAg + ICAgXSwKICAgICAgICAgICAgICAgICAgICAgICAgInRvcG9sb2d5UG9vbHMiOiBzZWxmLm91dF9t + YXBbIlRPUE9MT0dZX1BPT0xTIl0sCiAgICAgICAgICAgICAgICAgICAgICAgICJjc2kuc3RvcmFn + ZS5rOHMuaW8vcHJvdmlzaW9uZXItc2VjcmV0LW5hbWUiOiBmInJvb2ste3NlbGYub3V0X21hcFsn + Q1NJX1JCRF9QUk9WSVNJT05FUl9TRUNSRVRfTkFNRSddfSIsCiAgICAgICAgICAgICAgICAgICAg + ICAgICJjc2kuc3RvcmFnZS5rOHMuaW8vY29udHJvbGxlci1leHBhbmQtc2VjcmV0LW5hbWUiOiBm + InJvb2ste3NlbGYub3V0X21hcFsnQ1NJX1JCRF9QUk9WSVNJT05FUl9TRUNSRVRfTkFNRSddfSIs + CiAgICAgICAgICAgICAgICAgICAgICAgICJjc2kuc3RvcmFnZS5rOHMuaW8vbm9kZS1zdGFnZS1z + ZWNyZXQtbmFtZSI6IGYicm9vay17c2VsZi5vdXRfbWFwWydDU0lfUkJEX05PREVfU0VDUkVUX05B + TUUnXX0iLAogICAgICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICB9CiAgICAgICAg + ICAgICkKCiAgICAgICAgIyBpZiAnQ0VQSEZTX0ZTX05BTUUnIGV4aXN0cywgdGhlbiBvbmx5IGFk + ZCAnY2VwaGZzJyBTdG9yYWdlQ2xhc3MKICAgICAgICBpZiBzZWxmLm91dF9tYXBbIkNFUEhGU19G + U19OQU1FIl06CiAgICAgICAgICAgIGpzb25fb3V0LmFwcGVuZCgKICAgICAgICAgICAgICAgIHsK + ICAgICAgICAgICAgICAgICAgICAibmFtZSI6ICJjZXBoZnMiLAogICAgICAgICAgICAgICAgICAg + ICJraW5kIjogIlN0b3JhZ2VDbGFzcyIsCiAgICAgICAgICAgICAgICAgICAgImRhdGEiOiB7CiAg + ICAgICAgICAgICAgICAgICAgICAgICJmc05hbWUiOiBzZWxmLm91dF9tYXBbIkNFUEhGU19GU19O + QU1FIl0sCiAgICAgICAgICAgICAgICAgICAgICAgICJwb29sIjogc2VsZi5vdXRfbWFwWyJDRVBI + RlNfUE9PTF9OQU1FIl0sCiAgICAgICAgICAgICAgICAgICAgICAgICJjc2kuc3RvcmFnZS5rOHMu + aW8vcHJvdmlzaW9uZXItc2VjcmV0LW5hbWUiOiBmInJvb2ste3NlbGYub3V0X21hcFsnQ1NJX0NF + UEhGU19QUk9WSVNJT05FUl9TRUNSRVRfTkFNRSddfSIsCiAgICAgICAgICAgICAgICAgICAgICAg + ICJjc2kuc3RvcmFnZS5rOHMuaW8vY29udHJvbGxlci1leHBhbmQtc2VjcmV0LW5hbWUiOiBmInJv + b2ste3NlbGYub3V0X21hcFsnQ1NJX0NFUEhGU19QUk9WSVNJT05FUl9TRUNSRVRfTkFNRSddfSIs + CiAgICAgICAgICAgICAgICAgICAgICAgICJjc2kuc3RvcmFnZS5rOHMuaW8vbm9kZS1zdGFnZS1z + ZWNyZXQtbmFtZSI6IGYicm9vay17c2VsZi5vdXRfbWFwWydDU0lfQ0VQSEZTX05PREVfU0VDUkVU + X05BTUUnXX0iLAogICAgICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICB9CiAgICAg + ICAgICAgICkKICAgICAgICAjIGlmICdSR1dfRU5EUE9JTlQnIGV4aXN0cywgdGhlbiBvbmx5IGFk + ZCAnY2VwaC1yZ3cnIFN0b3JhZ2VDbGFzcwogICAgICAgIGlmIHNlbGYub3V0X21hcFsiUkdXX0VO + RFBPSU5UIl06CiAgICAgICAgICAgIGpzb25fb3V0LmFwcGVuZCgKICAgICAgICAgICAgICAgIHsK + ICAgICAgICAgICAgICAgICAgICAibmFtZSI6ICJjZXBoLXJndyIsCiAgICAgICAgICAgICAgICAg + ICAgImtpbmQiOiAiU3RvcmFnZUNsYXNzIiwKICAgICAgICAgICAgICAgICAgICAiZGF0YSI6IHsK + ICAgICAgICAgICAgICAgICAgICAgICAgImVuZHBvaW50Ijogc2VsZi5vdXRfbWFwWyJSR1dfRU5E + UE9JTlQiXSwKICAgICAgICAgICAgICAgICAgICAgICAgInBvb2xQcmVmaXgiOiBzZWxmLm91dF9t + YXBbIlJHV19QT09MX1BSRUZJWCJdLAogICAgICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAg + ICAgICB9CiAgICAgICAgICAgICkKICAgICAgICAgICAganNvbl9vdXQuYXBwZW5kKAogICAgICAg + ICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICJuYW1lIjogInJndy1hZG1pbi1vcHMtdXNl + ciIsCiAgICAgICAgICAgICAgICAgICAgImtpbmQiOiAiU2VjcmV0IiwKICAgICAgICAgICAgICAg + ICAgICAiZGF0YSI6IHsKICAgICAgICAgICAgICAgICAgICAgICAgImFjY2Vzc0tleSI6IHNlbGYu + b3V0X21hcFsiUkdXX0FETUlOX09QU19VU0VSX0FDQ0VTU19LRVkiXSwKICAgICAgICAgICAgICAg + ICAgICAgICAgInNlY3JldEtleSI6IHNlbGYub3V0X21hcFsiUkdXX0FETUlOX09QU19VU0VSX1NF + Q1JFVF9LRVkiXSwKICAgICAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgfQogICAg + ICAgICAgICApCiAgICAgICAgIyBpZiAnUkdXX1RMU19DRVJUJyBleGlzdHMsIHRoZW4gb25seSBh + ZGQgdGhlICJjZXBoLXJndy10bHMtY2VydCIgc2VjcmV0CiAgICAgICAgaWYgc2VsZi5vdXRfbWFw + WyJSR1dfVExTX0NFUlQiXToKICAgICAgICAgICAganNvbl9vdXQuYXBwZW5kKAogICAgICAgICAg + ICAgICAgewogICAgICAgICAgICAgICAgICAgICJuYW1lIjogImNlcGgtcmd3LXRscy1jZXJ0IiwK + ICAgICAgICAgICAgICAgICAgICAia2luZCI6ICJTZWNyZXQiLAogICAgICAgICAgICAgICAgICAg + ICJkYXRhIjogewogICAgICAgICAgICAgICAgICAgICAgICAiY2VydCI6IHNlbGYub3V0X21hcFsi + UkdXX1RMU19DRVJUIl0sCiAgICAgICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgIH0K + ICAgICAgICAgICAgKQoKICAgICAgICByZXR1cm4ganNvbi5kdW1wcyhqc29uX291dCkgKyBMSU5F + U0VQCgogICAgZGVmIHVwZ3JhZGVfdXNlcnNfcGVybWlzc2lvbnMoc2VsZik6CiAgICAgICAgdXNl + cnMgPSBbCiAgICAgICAgICAgICJjbGllbnQuY3NpLWNlcGhmcy1ub2RlIiwKICAgICAgICAgICAg + ImNsaWVudC5jc2ktY2VwaGZzLXByb3Zpc2lvbmVyIiwKICAgICAgICAgICAgImNsaWVudC5jc2kt + cmJkLW5vZGUiLAogICAgICAgICAgICAiY2xpZW50LmNzaS1yYmQtcHJvdmlzaW9uZXIiLAogICAg + ICAgICAgICAiY2xpZW50LmhlYWx0aGNoZWNrZXIiLAogICAgICAgIF0KICAgICAgICBpZiBzZWxm + LnJ1bl9hc191c2VyICE9ICIiIGFuZCBzZWxmLnJ1bl9hc191c2VyIG5vdCBpbiB1c2VyczoKICAg + ICAgICAgICAgdXNlcnMuYXBwZW5kKHNlbGYucnVuX2FzX3VzZXIpCiAgICAgICAgZm9yIHVzZXIg + aW4gdXNlcnM6CiAgICAgICAgICAgIHNlbGYudXBncmFkZV91c2VyX3Blcm1pc3Npb25zKHVzZXIp + CgogICAgZGVmIGdldF9yZ3dfcG9vbF9uYW1lX2R1cmluZ191cGdyYWRlKHNlbGYsIHVzZXIsIGNh + cHMpOgogICAgICAgIGlmIHVzZXIgPT0gImNsaWVudC5oZWFsdGhjaGVja2VyIjoKICAgICAgICAg + ICAgIyB3aGVuIGFkbWluIGhhcyBub3QgcHJvdmlkZWQgcmd3IHBvb2wgbmFtZSBkdXJpbmcgdXBn + cmFkZSwKICAgICAgICAgICAgIyBnZXQgdGhlIHJndyBwb29sIG5hbWUgZnJvbSBjbGllbnQuaGVh + bHRoY2hlY2tlciB1c2VyIHdoaWNoIHdhcyB1c2VkIGR1cmluZyBjb25uZWN0aW9uCiAgICAgICAg + ICAgIGlmIG5vdCBzZWxmLl9hcmdfcGFyc2VyLnJnd19wb29sX3ByZWZpeDoKICAgICAgICAgICAg + ICAgICMgVG8gZ2V0IHZhbHVlICdkZWZhdWx0JyB3aGljaCBpcyByZ3cgcG9vbCBuYW1lIGZyb20g + J2FsbG93IHJ3eCBwb29sPWRlZmF1bHQucmd3Lm1ldGEnCiAgICAgICAgICAgICAgICBwYXR0ZXJu + ID0gciJwb29sPSguKj8pXC5yZ3dcLm1ldGEiCiAgICAgICAgICAgICAgICBtYXRjaCA9IHJlLnNl + YXJjaChwYXR0ZXJuLCBjYXBzKQogICAgICAgICAgICAgICAgaWYgbWF0Y2g6CiAgICAgICAgICAg + ICAgICAgICAgc2VsZi5fYXJnX3BhcnNlci5yZ3dfcG9vbF9wcmVmaXggPSBtYXRjaC5ncm91cCgx + KQogICAgICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgICAgICByYWlzZSBFeGVjdXRp + b25GYWlsdXJlRXhjZXB0aW9uKAogICAgICAgICAgICAgICAgICAgICAgICAiZmFpbGVkIHRvIGdl + dCByZ3cgcG9vbCBuYW1lIGZvciB1cGdyYWRlIgogICAgICAgICAgICAgICAgICAgICkKCiAgICBk + ZWYgdXBncmFkZV91c2VyX3Blcm1pc3Npb25zKHNlbGYsIHVzZXIpOgogICAgICAgICMgY2hlY2sg + d2hldGhlciB0aGUgZ2l2ZW4gdXNlciBleGlzdHMgb3Igbm90CiAgICAgICAgY21kX2pzb24gPSB7 + InByZWZpeCI6ICJhdXRoIGdldCIsICJlbnRpdHkiOiBmInt1c2VyfSIsICJmb3JtYXQiOiAianNv + biJ9CiAgICAgICAgcmV0X3ZhbCwganNvbl9vdXQsIGVycl9tc2cgPSBzZWxmLl9jb21tb25fY21k + X2pzb25fZ2VuKGNtZF9qc29uKQogICAgICAgIGlmIHJldF92YWwgIT0gMCBvciBsZW4oanNvbl9v + dXQpID09IDA6CiAgICAgICAgICAgIHByaW50KGYidXNlciB7dXNlcn0gbm90IGZvdW5kIGZvciB1 + cGdyYWRpbmcuIikKICAgICAgICAgICAgcmV0dXJuCiAgICAgICAgZXhpc3RpbmdfY2FwcyA9IGpz + b25fb3V0WzBdWyJjYXBzIl0KICAgICAgICBzZWxmLmdldF9yZ3dfcG9vbF9uYW1lX2R1cmluZ191 + cGdyYWRlKHVzZXIsIHN0cihleGlzdGluZ19jYXBzKSkKICAgICAgICBuZXdfY2FwLCBfID0gc2Vs + Zi5nZXRfY2Fwc19hbmRfZW50aXR5KHVzZXIpCiAgICAgICAgY2FwX2tleXMgPSBbIm1vbiIsICJt + Z3IiLCAib3NkIiwgIm1kcyJdCiAgICAgICAgY2FwcyA9IFtdCiAgICAgICAgZm9yIGVhY2hDYXAg + aW4gY2FwX2tleXM6CiAgICAgICAgICAgIGN1cl9jYXBfdmFsdWVzID0gZXhpc3RpbmdfY2Fwcy5n + ZXQoZWFjaENhcCwgIiIpCiAgICAgICAgICAgIG5ld19jYXBfdmFsdWVzID0gbmV3X2NhcC5nZXQo + ZWFjaENhcCwgIiIpCiAgICAgICAgICAgIGN1cl9jYXBfcGVybV9saXN0ID0gWwogICAgICAgICAg + ICAgICAgeC5zdHJpcCgpIGZvciB4IGluIGN1cl9jYXBfdmFsdWVzLnNwbGl0KCIsIikgaWYgeC5z + dHJpcCgpCiAgICAgICAgICAgIF0KICAgICAgICAgICAgbmV3X2NhcF9wZXJtX2xpc3QgPSBbCiAg + ICAgICAgICAgICAgICB4LnN0cmlwKCkgZm9yIHggaW4gbmV3X2NhcF92YWx1ZXMuc3BsaXQoIiwi + KSBpZiB4LnN0cmlwKCkKICAgICAgICAgICAgXQogICAgICAgICAgICAjIGFwcGVuZCBuZXdfY2Fw + X2xpc3QgdG8gY3VyX2NhcF9saXN0IHRvIG1haW50YWluIHRoZSBvcmRlciBvZiBjYXBzCiAgICAg + ICAgICAgIGN1cl9jYXBfcGVybV9saXN0LmV4dGVuZChuZXdfY2FwX3Blcm1fbGlzdCkKICAgICAg + ICAgICAgIyBlbGltaW5hdGUgZHVwbGljYXRlcyB3aXRob3V0IHVzaW5nICdzZXQnCiAgICAgICAg + ICAgICMgc2V0IHJlLW9yZGVycyBpdGVtcyBpbiB0aGUgbGlzdCBhbmQgd2UgaGF2ZSB0byBrZWVw + IHRoZSBvcmRlcgogICAgICAgICAgICBuZXdfY2FwX2xpc3QgPSBbXQogICAgICAgICAgICBbbmV3 + X2NhcF9saXN0LmFwcGVuZCh4KSBmb3IgeCBpbiBjdXJfY2FwX3Blcm1fbGlzdCBpZiB4IG5vdCBp + biBuZXdfY2FwX2xpc3RdCiAgICAgICAgICAgIGV4aXN0aW5nX2NhcHNbZWFjaENhcF0gPSAiLCAi + LmpvaW4obmV3X2NhcF9saXN0KQogICAgICAgICAgICBpZiBleGlzdGluZ19jYXBzW2VhY2hDYXBd + OgogICAgICAgICAgICAgICAgY2Fwcy5hcHBlbmQoZWFjaENhcCkKICAgICAgICAgICAgICAgIGNh + cHMuYXBwZW5kKGV4aXN0aW5nX2NhcHNbZWFjaENhcF0pCiAgICAgICAgY21kX2pzb24gPSB7CiAg + ICAgICAgICAgICJwcmVmaXgiOiAiYXV0aCBjYXBzIiwKICAgICAgICAgICAgImVudGl0eSI6IHVz + ZXIsCiAgICAgICAgICAgICJjYXBzIjogY2FwcywKICAgICAgICAgICAgImZvcm1hdCI6ICJqc29u + IiwKICAgICAgICB9CiAgICAgICAgcmV0X3ZhbCwganNvbl9vdXQsIGVycl9tc2cgPSBzZWxmLl9j + b21tb25fY21kX2pzb25fZ2VuKGNtZF9qc29uKQogICAgICAgIGlmIHJldF92YWwgIT0gMDoKICAg + ICAgICAgICAgcmFpc2UgRXhlY3V0aW9uRmFpbHVyZUV4Y2VwdGlvbigKICAgICAgICAgICAgICAg + IGYiJ2F1dGggY2FwcyB7dXNlcn0nIGNvbW1hbmQgZmFpbGVkLlxuIEVycm9yOiB7ZXJyX21zZ30i + CiAgICAgICAgICAgICkKICAgICAgICBwcmludChmIlVwZGF0ZWQgdXNlciB7dXNlcn0gc3VjY2Vz + c2Z1bGx5LiIpCgogICAgZGVmIG1haW4oc2VsZik6CiAgICAgICAgZ2VuZXJhdGVkX291dHB1dCA9 + ICIiCiAgICAgICAgaWYgc2VsZi5fYXJnX3BhcnNlci51cGdyYWRlOgogICAgICAgICAgICBzZWxm + LnVwZ3JhZGVfdXNlcnNfcGVybWlzc2lvbnMoKQogICAgICAgIGVsaWYgc2VsZi5fYXJnX3BhcnNl + ci5mb3JtYXQgPT0gImpzb24iOgogICAgICAgICAgICBnZW5lcmF0ZWRfb3V0cHV0ID0gc2VsZi5n + ZW5fanNvbl9vdXQoKQogICAgICAgIGVsaWYgc2VsZi5fYXJnX3BhcnNlci5mb3JtYXQgPT0gImJh + c2giOgogICAgICAgICAgICBnZW5lcmF0ZWRfb3V0cHV0ID0gc2VsZi5nZW5fc2hlbGxfb3V0KCkK + ICAgICAgICBlbHNlOgogICAgICAgICAgICByYWlzZSBFeGVjdXRpb25GYWlsdXJlRXhjZXB0aW9u + KAogICAgICAgICAgICAgICAgZiJVbnN1cHBvcnRlZCBmb3JtYXQ6IHtzZWxmLl9hcmdfcGFyc2Vy + LmZvcm1hdH0iCiAgICAgICAgICAgICkKICAgICAgICBwcmludChnZW5lcmF0ZWRfb3V0cHV0KQog + ICAgICAgIGlmIHNlbGYub3V0cHV0X2ZpbGUgYW5kIGdlbmVyYXRlZF9vdXRwdXQ6CiAgICAgICAg + ICAgIGZPdXQgPSBvcGVuKHNlbGYub3V0cHV0X2ZpbGUsIG1vZGU9InciLCBlbmNvZGluZz0iVVRG + LTgiKQogICAgICAgICAgICBmT3V0LndyaXRlKGdlbmVyYXRlZF9vdXRwdXQpCiAgICAgICAgICAg + IGZPdXQuY2xvc2UoKQoKCiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMj + IyMjIyMjIwojIyMjIyMjIyMjIyMjIyMjIyMjIyMgTUFJTiAjIyMjIyMjIyMjIyMjIyMjIyMjIyMK + IyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCmlmIF9fbmFt + ZV9fID09ICJfX21haW5fXyI6CiAgICByak9iaiA9IFJhZG9zSlNPTigpCiAgICB0cnk6CiAgICAg + ICAgcmpPYmoubWFpbigpCiAgICBleGNlcHQgRXhlY3V0aW9uRmFpbHVyZUV4Y2VwdGlvbiBhcyBl + cnI6CiAgICAgICAgcHJpbnQoZiJFeGVjdXRpb24gRmFpbGVkOiB7ZXJyfSIpCiAgICAgICAgcmFp + c2UgZXJyCiAgICBleGNlcHQgS2V5RXJyb3IgYXMga0VycjoKICAgICAgICBwcmludChmIktleUVy + cm9yOiB7a0Vycn0iKQogICAgZXhjZXB0IE9TRXJyb3IgYXMgb3NFcnI6CiAgICAgICAgcHJpbnQo + ZiJFcnJvciB3aGlsZSB0cnlpbmcgdG8gb3V0cHV0IHRoZSBkYXRhOiB7b3NFcnJ9IikKICAgIGZp + bmFsbHk6CiAgICAgICAgcmpPYmouc2h1dGRvd24oKQo= kind: ConfigMap metadata: name: rook-ceph-external-cluster-script-config