diff --git a/.gimps.yaml b/.gimps.yaml index 3733676d..ee7bcf63 100644 --- a/.gimps.yaml +++ b/.gimps.yaml @@ -14,16 +14,13 @@ # This is the configuration for https://github.com/xrstf/gimps. -importOrder: [std, external, envoy, kubermatic, kubernetes] +importOrder: [std, external, kubermatic, kubernetes] sets: - name: kubermatic patterns: - - 'k8c.io/**' - - 'github.com/kubermatic/**' + - "k8c.io/**" + - "github.com/kubermatic/**" - name: kubernetes patterns: - - 'k8s.io/**' - - '*.k8s.io/**' - - name: envoy - patterns: - - 'github.com/envoyproxy/**' + - "k8s.io/**" + - "*.k8s.io/**" diff --git a/.gitignore b/.gitignore index 0d39912f..2054554f 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ _build .vscode/ .local +.DS_Store \ No newline at end of file diff --git a/.golangci.yml b/.golangci.yml index 33b19dc3..22e9135a 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -42,7 +42,3 @@ linters: linters-settings: goimports: local-prefixes: k8c.io/operating-system-manager - -issues: - exclude: - - type name will be used as config.ConfigVarResolver by other packages, and that stutters; consider calling this VarResolver diff --git a/.prow.yaml b/.prow.yaml index c0afa697..347be508 100644 --- a/.prow.yaml +++ b/.prow.yaml @@ -24,7 +24,7 @@ presubmits: preset-goproxy: "true" spec: containers: - - image: quay.io/kubermatic-labs/boilerplate:v0.1.1 + - image: quay.io/kubermatic-labs/boilerplate:v0.2.0 command: - make args: diff --git a/README.md b/README.md index 2e09ea69..35a53575 100644 --- a/README.md +++ b/README.md @@ -14,10 +14,12 @@ This project is experimental and currently a work-in-progress. **This is not sup Currently this workflow has the following limitations/issues: -- Machine Controller expects **ALL** the supported OS plugins to exist and be ready. User might only be interested in a subset of the available operating systems. -- The `cloud-configs` are generated against pre-defined templates like [this](https://github.com/kubermatic/machine-controller/blob/master/pkg/userdata/ubuntu/provider.go#L133). This is not ideal because code changes are required to update those templates. -- Each cloud provider sets some limit for `user-data` size, machine won't be created in case of non-compliance. For example, at the time of writing this, AWS has set a [hard limit of 16KB](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instancedata-add-user-data.html) for `user-data` size. +- Machine Controller expects **ALL** the supported user-data plugins to exist and be ready. User might only be interested in a subset of the available operating systems. For example, user might only want to work with `ubuntu`. +- The user-data plugins have templates defined [in-code](https://github.com/kubermatic/machine-controller/blob/master/pkg/userdata/ubuntu/provider.go#L133). Which is not ideal because code changes are required to update those templates. - Managing configs for multiple cloud providers, OS flavors and OS versions, adds a lot of complexity and redundancy in machine-controller. +- Since the templates are defined in-code, there is no way for an end user to customize them to suit their use-cases. +- Each cloud provider sets some sort of limits for the size of `user-data`, machine won't be created in case of non-compliance. For example, at the time of writing this, AWS has set a [hard limit of 16KB](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instancedata-add-user-data.html). +- Better support for air-gapped environments is required. ### Solution @@ -27,33 +29,33 @@ Operating System Manager was created to solve the above mentioned issues. It dec OSM introduces the following resources: -- OperatingSystemProfile: A resource that represents the details of each operating system. -- OperatingSystemConfig: A resource that contains the `cloud-configs` that are going to be used to bootstrap and provision the worker nodes. -`OperatingSystemConfig` are a subset of `OperatingSystemProfile` and are auto-generated by the `osc-controller` against a certain OSP and MachineDeployment. -For each cluster there are at least two OSC objects: +### OperatingSystemProfile -1. OSC for accessing the cluster; OSC is sent to the worker node via user-data and processed as a cloud-init or ignition config, in order to fetch the second OSC object. -2. OSC for provisioning the machine; OSC represents the actual cloud-config that provision the worker node. +Templatized resource that represents the details of each operating system. OSPs are immutable and default OSPs for supported operating systems are provided/installed automatically by kubermatic. End users can create custom OSPs as well to fit their own use-cases. -The created OSCs are processed by the controllers and they eventually generate a secret inside each user cluster. Which is then consumed by the worker nodes. +Its dedicated controller runs in the **seed** cluster, in user cluster namespace, and operates on the `OperatingSystemProfile` custom resource. It is responsible for installing the default OSPs in user-cluster namespace. -![Architecture](./docs/images/architecture-osm.png) +### OperatingSystemConfig + +Immutable resource that contains the actual configurations that are going to be used to bootstrap and provision the worker nodes. It is a subset of OperatingSystemProfile, rendered using OperatingSystemProfile, MachineDeployment and flags + +Its dedicated controller runs in the **seed** cluster, in user cluster namespace, and is responsible for generating the OSCs in **seed** and secrets in `cloud-init-settings` namespace in the user cluster. -### OperatingSystemProfile Controller -This controller runs in the `master` cluster and operates on the `OperatingSystemProfile` custom resource. It is responsible for creating the `OperatingSystemConfig` resources. +For each cluster there are at least two OSC objects: + +1. **Bootstrap**: OSC used for initial configuration of machine and to fetch the provisioning OSC object. +2. **Provisioning**: OSC with the actual cloud-config that provision the worker node. -### OperatingSystemConfig Controller +OSCs are processed by controllers to eventually generate **secrets inside each user cluster**. These secrets are then consumed by worker nodes. -This controller runs in the `seed` cluster in the namespace of the user cluster and operates on the `OperatingSystemConfig` custom resource. It is responsible for generating `user-data` secret through the OperatingSystemConfig resource. +![Architecture](./docs/images/architecture-osm.png) ### Air-gapped Environment This controller was designed by keeping air-gapped environments in mind. Customers can use their own VM images by creating custom OSP profiles to provision nodes in a cluster that doesn't have outbound internet access. -![Architecture](./docs/images/architecture-osm-air-gapped.png) - More work is being done to make it even easier to use OSM in air-gapped environments. ## Support @@ -68,10 +70,6 @@ _The code and sample YAML files in the master branch of the operating-system-man ## Development -### Testing - -Simply run `make test` - ### Local Development To run OSM locally: @@ -81,6 +79,10 @@ To run OSM locally: - Create relevant OperatingSystemProfile resources. Check [sample](./deploy/osps/default) for reference. - Run `make run` +### Testing + +Simply run `make test` + ## Troubleshooting If you encounter issues [file an issue][1] or talk to us on the [#kubermatic channel][6] on the [Kubermatic Slack][7]. diff --git a/cmd/osm-controller/main.go b/cmd/osm-controller/main.go index 0d06d479..3758b995 100644 --- a/cmd/osm-controller/main.go +++ b/cmd/osm-controller/main.go @@ -21,14 +21,13 @@ import ( "flag" "fmt" "net" - "os" - "path" "strconv" "strings" "go.uber.org/zap" clusterv1alpha1 "github.com/kubermatic/machine-controller/pkg/apis/cluster/v1alpha1" + "github.com/kubermatic/machine-controller/pkg/containerruntime" "k8c.io/operating-system-manager/pkg/controllers/osc" "k8c.io/operating-system-manager/pkg/controllers/osp" osmv1alpha1 "k8c.io/operating-system-manager/pkg/crd/osm/v1alpha1" @@ -40,7 +39,6 @@ import ( "k8s.io/client-go/kubernetes/scheme" clientgoscheme "k8s.io/client-go/kubernetes/scheme" "k8s.io/client-go/tools/clientcmd" - "k8s.io/client-go/util/homedir" "k8s.io/klog" ctrl "sigs.k8s.io/controller-runtime" ctrlruntimeclient "sigs.k8s.io/controller-runtime/pkg/client" @@ -57,8 +55,6 @@ type options struct { externalCloudProvider bool pauseImage string initialTaints string - nodeHTTPProxy string - nodeNoProxy string nodePortRange string podCidr string enableLeaderElection bool @@ -71,6 +67,16 @@ type options struct { metricsAddress string workerHealthProbeAddress string workerMetricsAddress string + + // Flags for configuring CRI + nodeInsecureRegistries string + nodeRegistryMirrors string + nodeRegistryCredentialsSecret string + nodeContainerdRegistryMirrors containerruntime.RegistryMirrorsFlags + + // Flags for proxy + nodeHTTPProxy string + nodeNoProxy string } func init() { @@ -95,12 +101,16 @@ func main() { flag.StringVar(&opt.clusterDNSIPs, "cluster-dns", "10.10.10.10", "Comma-separated list of DNS server IP address.") flag.StringVar(&opt.pauseImage, "pause-image", "", "pause image to use in Kubelet.") flag.StringVar(&opt.initialTaints, "initial-taints", "", "taints to use when creating the node.") - flag.StringVar(&opt.nodeHTTPProxy, "node-http-proxy", "", "If set, it configures the 'HTTP_PROXY' & 'HTTPS_PROXY' environment variable on the nodes.") - flag.StringVar(&opt.nodeNoProxy, "node-no-proxy", ".svc,.cluster.local,localhost,127.0.0.1", "If set, it configures the 'NO_PROXY' environment variable on the nodes.") + flag.StringVar(&opt.podCidr, "pod-cidr", "172.25.0.0/16", "The network ranges from which POD networks are allocated") flag.StringVar(&opt.nodePortRange, "node-port-range", "30000-32767", "A port range to reserve for services with NodePort visibility") flag.StringVar(&opt.kubeletFeatureGates, "node-kubelet-feature-gates", "RotateKubeletServerCertificate=true", "Feature gates to set on the kubelet") + flag.StringVar(&opt.nodeHTTPProxy, "node-http-proxy", "", "If set, it configures the 'HTTP_PROXY' & 'HTTPS_PROXY' environment variable on the nodes.") + flag.StringVar(&opt.nodeNoProxy, "node-no-proxy", ".svc,.cluster.local,localhost,127.0.0.1", "If set, it configures the 'NO_PROXY' environment variable on the nodes.") + flag.StringVar(&opt.nodeInsecureRegistries, "node-insecure-registries", "", "Comma separated list of registries which should be configured as insecure on the container runtime") + flag.StringVar(&opt.nodeRegistryMirrors, "node-registry-mirrors", "", "Comma separated list of Docker image mirrors") + flag.StringVar(&opt.healthProbeAddress, "health-probe-address", "127.0.0.1:8085", "The address on which the liveness check on /healthz and readiness check on /readyz will be available") flag.StringVar(&opt.metricsAddress, "metrics-address", "127.0.0.1:8080", "The address on which Prometheus metrics will be available under /metrics") @@ -120,6 +130,7 @@ func main() { opt.kubeconfig = flag.Lookup("kubeconfig").Value.(flag.Getter).Get().(string) + // Parse flags parsedClusterDNSIPs, err := parseClusterDNSIPs(opt.clusterDNSIPs) if err != nil { klog.Fatalf("invalid cluster dns specified: %v", err) @@ -130,6 +141,19 @@ func main() { klog.Fatalf("invalid kubelet feature gates specified: %v", err) } + containerRuntimeOpts := containerruntime.Opts{ + ContainerRuntime: opt.containerRuntime, + ContainerdRegistryMirrors: opt.nodeContainerdRegistryMirrors, + InsecureRegistries: opt.nodeInsecureRegistries, + PauseImage: opt.pauseImage, + RegistryMirrors: opt.nodeRegistryMirrors, + RegistryCredentialsSecret: opt.nodeRegistryCredentialsSecret, + } + containerRuntimeConfig, err := containerruntime.BuildConfig(containerRuntimeOpts) + if err != nil { + klog.Fatalf("failed to generate container runtime config: %v", err) + } + logger, err := zap.NewProduction() if err != nil { klog.Fatal(err) @@ -218,6 +242,8 @@ func main() { opt.nodeNoProxy, opt.nodePortRange, opt.podCidr, + containerRuntimeConfig, + opt.nodeRegistryCredentialsSecret, parsedKubeletFeatureGates, ); err != nil { klog.Fatal(err) @@ -238,7 +264,10 @@ func createManager(opt *options) (manager.Manager, error) { HealthProbeBindAddress: opt.healthProbeAddress, MetricsBindAddress: opt.metricsAddress, Port: 9443, - Namespace: opt.namespace, + } + + if opt.workerClusterKubeconfig != "" { + options.Namespace = opt.namespace } mgr, err := manager.New(config.GetConfigOrDie(), options) @@ -292,11 +321,3 @@ func parseKubeletFeatureGates(s string) (map[string]bool, error) { } return featureGates, nil } - -// getKubeConfigPath returns the path to the kubeconfig file. -func getKubeConfigPath() string { - if os.Getenv("KUBECONFIG") != "" { - return os.Getenv("KUBECONFIG") - } - return path.Join(homedir.HomeDir(), ".kube/config") -} diff --git a/deploy/osps/default/osp-amzn2.yaml b/deploy/osps/default/osp-amzn2.yaml index 0a2f2876..ea105787 100644 --- a/deploy/osps/default/osp-amzn2.yaml +++ b/deploy/osps/default/osp-amzn2.yaml @@ -16,11 +16,11 @@ apiVersion: operatingsystemmanager.k8c.io/v1alpha1 kind: OperatingSystemProfile metadata: name: osp-amzn2 - namespace: cloud-init-settings + namespace: kube-system spec: osName: "amzn2" osVersion: "2.0" - version: "v0.1.0" + version: "v0.1.1" supportedCloudProviders: - name: "aws" supportedContainerRuntimes: @@ -32,23 +32,7 @@ spec: inline: encoding: b64 data: | - version = 2 - - [metrics] - address = "127.0.0.1:1338" - - [plugins] - [plugins."io.containerd.grpc.v1.cri"] - [plugins."io.containerd.grpc.v1.cri".containerd] - [plugins."io.containerd.grpc.v1.cri".containerd.runtimes] - [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc] - runtime_type = "io.containerd.runc.v2" - [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options] - SystemdCgroup = true - [plugins."io.containerd.grpc.v1.cri".registry] - [plugins."io.containerd.grpc.v1.cri".registry.mirrors] - [plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"] - endpoint = ["https://registry-1.docker.io"] + {{ .ContainerRuntimeConfig}} templates: containerRuntimeInstallation: |- mkdir -p /etc/systemd/system/containerd.service.d @@ -79,7 +63,7 @@ spec: inline: encoding: b64 data: |- - {"exec-opts":["native.cgroupdriver=systemd"],"storage-driver":"overlay2","log-driver":"json-file","log-opts":{"max-file":"5","max-size":"100m"}} + {{ .ContainerRuntimeConfig}} templates: containerRuntimeInstallation: |- mkdir -p /etc/systemd/system/containerd.service.d /etc/systemd/system/docker.service.d @@ -503,6 +487,19 @@ spec: - "{{ . }}" {{- end }} clusterDomain: cluster.local + {{- /* containerLogMaxSize and containerLogMaxFiles have no effect for docker */}} + {{- if ne .ContainerRuntime "docker" }} + {{- if .ContainerLogMaxSize }} + containerLogMaxSize: {{ .ContainerLogMaxSize }} + {{- else }} + containerLogMaxSize: 100Mi + {{- end }} + {{- if .ContainerLogMaxFiles }} + containerLogMaxFiles: {{ .ContainerLogMaxFiles }} + {{- else }} + containerLogMaxFiles: 5 + {{- end }} + {{- end }} featureGates: {{- if .KubeletFeatureGates -}} {{ range $key, $val := .KubeletFeatureGates }} diff --git a/deploy/osps/default/osp-centos.yaml b/deploy/osps/default/osp-centos.yaml index aa00f4d5..f2475478 100644 --- a/deploy/osps/default/osp-centos.yaml +++ b/deploy/osps/default/osp-centos.yaml @@ -16,11 +16,11 @@ apiVersion: operatingsystemmanager.k8c.io/v1alpha1 kind: OperatingSystemProfile metadata: name: osp-centos - namespace: cloud-init-settings + namespace: kube-system spec: osName: "centos" osVersion: "7.7" - version: "v0.1.0" + version: "v0.1.1" supportedCloudProviders: - name: "aws" - name: "azure" @@ -39,23 +39,7 @@ spec: inline: encoding: b64 data: | - version = 2 - - [metrics] - address = "127.0.0.1:1338" - - [plugins] - [plugins."io.containerd.grpc.v1.cri"] - [plugins."io.containerd.grpc.v1.cri".containerd] - [plugins."io.containerd.grpc.v1.cri".containerd.runtimes] - [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc] - runtime_type = "io.containerd.runc.v2" - [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options] - SystemdCgroup = true - [plugins."io.containerd.grpc.v1.cri".registry] - [plugins."io.containerd.grpc.v1.cri".registry.mirrors] - [plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"] - endpoint = ["https://registry-1.docker.io"] + {{ .ContainerRuntimeConfig}} templates: containerRuntimeInstallation: |- yum install -y yum-utils @@ -91,7 +75,7 @@ spec: inline: encoding: b64 data: |- - {"exec-opts":["native.cgroupdriver=systemd"],"storage-driver":"overlay2","log-driver":"json-file","log-opts":{"max-file":"5","max-size":"100m"}} + {{ .ContainerRuntimeConfig}} templates: containerRuntimeInstallation: |- yum install -y yum-utils @@ -532,6 +516,19 @@ spec: - "{{ . }}" {{- end }} clusterDomain: cluster.local + {{- /* containerLogMaxSize and containerLogMaxFiles have no effect for docker */}} + {{- if ne .ContainerRuntime "docker" }} + {{- if .ContainerLogMaxSize }} + containerLogMaxSize: {{ .ContainerLogMaxSize }} + {{- else }} + containerLogMaxSize: 100Mi + {{- end }} + {{- if .ContainerLogMaxFiles }} + containerLogMaxFiles: {{ .ContainerLogMaxFiles }} + {{- else }} + containerLogMaxFiles: 5 + {{- end }} + {{- end }} featureGates: {{- if .KubeletFeatureGates -}} {{ range $key, $val := .KubeletFeatureGates }} diff --git a/deploy/osps/default/osp-flatcar.yaml b/deploy/osps/default/osp-flatcar.yaml index f955487f..259bd358 100644 --- a/deploy/osps/default/osp-flatcar.yaml +++ b/deploy/osps/default/osp-flatcar.yaml @@ -16,12 +16,12 @@ apiVersion: operatingsystemmanager.k8c.io/v1alpha1 kind: OperatingSystemProfile metadata: name: osp-flatcar - namespace: cloud-init-settings + namespace: kube-system spec: osName: flatcar ## Flatcar Stable (09/11/2021) osVersion: "2983.2.0" - version: "v0.1.0" + version: "v0.1.1" supportedCloudProviders: - name: aws - name: azure @@ -36,23 +36,7 @@ spec: content: inline: data: | - version = 2 - - [metrics] - address = "127.0.0.1:1338" - - [plugins] - [plugins."io.containerd.grpc.v1.cri"] - [plugins."io.containerd.grpc.v1.cri".containerd] - [plugins."io.containerd.grpc.v1.cri".containerd.runtimes] - [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc] - runtime_type = "io.containerd.runc.v2" - [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options] - SystemdCgroup = true - [plugins."io.containerd.grpc.v1.cri".registry] - [plugins."io.containerd.grpc.v1.cri".registry.mirrors] - [plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"] - endpoint = ["https://registry-1.docker.io"] + {{ .ContainerRuntimeConfig}} - path: /etc/systemd/system/containerd.service.d/10-custom.conf content: inline: @@ -77,7 +61,7 @@ spec: content: inline: data: |- - {"exec-opts":["native.cgroupdriver=systemd"],"storage-driver":"overlay2","log-driver":"json-file","log-opts":{"max-file":"5","max-size":"100m"}} + {{ .ContainerRuntimeConfig}} - path: /etc/systemd/system/docker.service.d/10-custom.conf permissions: 0644 content: @@ -542,6 +526,19 @@ spec: - "{{ . }}" {{- end }} clusterDomain: cluster.local + {{- /* containerLogMaxSize and containerLogMaxFiles have no effect for docker */}} + {{- if ne .ContainerRuntime "docker" }} + {{- if .ContainerLogMaxSize }} + containerLogMaxSize: {{ .ContainerLogMaxSize }} + {{- else }} + containerLogMaxSize: 100Mi + {{- end }} + {{- if .ContainerLogMaxFiles }} + containerLogMaxFiles: {{ .ContainerLogMaxFiles }} + {{- else }} + containerLogMaxFiles: 5 + {{- end }} + {{- end }} featureGates: {{- if .KubeletFeatureGates -}} {{ range $key, $val := .KubeletFeatureGates }} diff --git a/deploy/osps/default/osp-rhel.yaml b/deploy/osps/default/osp-rhel.yaml index 26c8b07e..b89eee38 100644 --- a/deploy/osps/default/osp-rhel.yaml +++ b/deploy/osps/default/osp-rhel.yaml @@ -16,11 +16,11 @@ apiVersion: operatingsystemmanager.k8c.io/v1alpha1 kind: OperatingSystemProfile metadata: name: osp-rhel - namespace: cloud-init-settings + namespace: kube-system spec: osName: "rhel" osVersion: "8.4" - version: "v0.1.0" + version: "v0.1.1" supportedCloudProviders: - name: "aws" - name: "azure" @@ -36,23 +36,7 @@ spec: inline: encoding: b64 data: | - version = 2 - - [metrics] - address = "127.0.0.1:1338" - - [plugins] - [plugins."io.containerd.grpc.v1.cri"] - [plugins."io.containerd.grpc.v1.cri".containerd] - [plugins."io.containerd.grpc.v1.cri".containerd.runtimes] - [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc] - runtime_type = "io.containerd.runc.v2" - [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options] - SystemdCgroup = true - [plugins."io.containerd.grpc.v1.cri".registry] - [plugins."io.containerd.grpc.v1.cri".registry.mirrors] - [plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"] - endpoint = ["https://registry-1.docker.io"] + {{ .ContainerRuntimeConfig}} templates: containerRuntimeInstallation: |- yum install -y yum-utils @@ -88,7 +72,7 @@ spec: inline: encoding: b64 data: |- - {"exec-opts":["native.cgroupdriver=systemd"],"storage-driver":"overlay2","log-driver":"json-file","log-opts":{"max-file":"5","max-size":"10m"}} + {{ .ContainerRuntimeConfig}} templates: containerRuntimeInstallation: |- yum install -y yum-utils @@ -531,6 +515,19 @@ spec: - "{{ . }}" {{- end }} clusterDomain: cluster.local + {{- /* containerLogMaxSize and containerLogMaxFiles have no effect for docker */}} + {{- if ne .ContainerRuntime "docker" }} + {{- if .ContainerLogMaxSize }} + containerLogMaxSize: {{ .ContainerLogMaxSize }} + {{- else }} + containerLogMaxSize: 100Mi + {{- end }} + {{- if .ContainerLogMaxFiles }} + containerLogMaxFiles: {{ .ContainerLogMaxFiles }} + {{- else }} + containerLogMaxFiles: 5 + {{- end }} + {{- end }} featureGates: {{- if .KubeletFeatureGates -}} {{ range $key, $val := .KubeletFeatureGates }} diff --git a/deploy/osps/default/osp-sles.yaml b/deploy/osps/default/osp-sles.yaml index 2a997139..18d99d6b 100644 --- a/deploy/osps/default/osp-sles.yaml +++ b/deploy/osps/default/osp-sles.yaml @@ -16,11 +16,11 @@ apiVersion: operatingsystemmanager.k8c.io/v1alpha1 kind: OperatingSystemProfile metadata: name: osp-sles - namespace: cloud-init-settings + namespace: kube-system spec: osName: sles osVersion: "15-SP-1" - version: "v0.1.0" + version: "v0.1.1" supportedCloudProviders: - name: aws supportedContainerRuntimes: @@ -32,7 +32,7 @@ spec: inline: encoding: b64 data: |- - {"exec-opts":["native.cgroupdriver=systemd"],"storage-driver":"overlay2","log-driver":"json-file","log-opts":{"max-file":"5","max-size":"100m"}} + {{ .ContainerRuntimeConfig}} - path: /etc/systemd/system/docker.service.d/10-custom.conf permissions: 0644 content: @@ -436,6 +436,19 @@ spec: - "{{ . }}" {{- end }} clusterDomain: cluster.local + {{- /* containerLogMaxSize and containerLogMaxFiles have no effect for docker */}} + {{- if ne .ContainerRuntime "docker" }} + {{- if .ContainerLogMaxSize }} + containerLogMaxSize: {{ .ContainerLogMaxSize }} + {{- else }} + containerLogMaxSize: 100Mi + {{- end }} + {{- if .ContainerLogMaxFiles }} + containerLogMaxFiles: {{ .ContainerLogMaxFiles }} + {{- else }} + containerLogMaxFiles: 5 + {{- end }} + {{- end }} featureGates: {{- if .KubeletFeatureGates -}} {{ range $key, $val := .KubeletFeatureGates }} diff --git a/deploy/osps/default/osp-ubuntu.yaml b/deploy/osps/default/osp-ubuntu.yaml index b4efaa62..5162f9c7 100644 --- a/deploy/osps/default/osp-ubuntu.yaml +++ b/deploy/osps/default/osp-ubuntu.yaml @@ -16,11 +16,11 @@ apiVersion: operatingsystemmanager.k8c.io/v1alpha1 kind: OperatingSystemProfile metadata: name: osp-ubuntu - namespace: cloud-init-settings + namespace: kube-system spec: osName: "ubuntu" osVersion: "20.04" - version: "v0.1.0" + version: "v0.1.1" supportedCloudProviders: - name: "aws" - name: "azure" @@ -40,23 +40,7 @@ spec: inline: encoding: b64 data: | - version = 2 - - [metrics] - address = "127.0.0.1:1338" - - [plugins] - [plugins."io.containerd.grpc.v1.cri"] - [plugins."io.containerd.grpc.v1.cri".containerd] - [plugins."io.containerd.grpc.v1.cri".containerd.runtimes] - [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc] - runtime_type = "io.containerd.runc.v2" - [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options] - SystemdCgroup = true - [plugins."io.containerd.grpc.v1.cri".registry] - [plugins."io.containerd.grpc.v1.cri".registry.mirrors] - [plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"] - endpoint = ["https://registry-1.docker.io"] + {{ .ContainerRuntimeConfig}} templates: containerRuntimeInstallation: |- apt-get update @@ -89,7 +73,7 @@ spec: inline: encoding: b64 data: |- - {"exec-opts":["native.cgroupdriver=systemd"],"storage-driver":"overlay2","log-driver":"json-file","log-opts":{"max-file":"5","max-size":"100m"}} + {{ .ContainerRuntimeConfig}} templates: containerRuntimeInstallation: |- apt-get update @@ -526,6 +510,19 @@ spec: - "{{ . }}" {{- end }} clusterDomain: cluster.local + {{- /* containerLogMaxSize and containerLogMaxFiles have no effect for docker */}} + {{- if ne .ContainerRuntime "docker" }} + {{- if .ContainerLogMaxSize }} + containerLogMaxSize: {{ .ContainerLogMaxSize }} + {{- else }} + containerLogMaxSize: 100Mi + {{- end }} + {{- if .ContainerLogMaxFiles }} + containerLogMaxFiles: {{ .ContainerLogMaxFiles }} + {{- else }} + containerLogMaxFiles: 5 + {{- end }} + {{- end }} featureGates: {{- if .KubeletFeatureGates -}} {{ range $key, $val := .KubeletFeatureGates }} diff --git a/docs/images/architecture-osm.png b/docs/images/architecture-osm.png index c5123f2d..85f52de4 100644 Binary files a/docs/images/architecture-osm.png and b/docs/images/architecture-osm.png differ diff --git a/go.mod b/go.mod index 4ad4a506..c87c2a36 100644 --- a/go.mod +++ b/go.mod @@ -7,7 +7,7 @@ require ( github.com/Masterminds/sprig/v3 v3.2.2 github.com/go-test/deep v1.0.7 github.com/kinvolk/container-linux-config-transpiler v0.9.1 - github.com/kubermatic/machine-controller v1.40.1 + github.com/kubermatic/machine-controller v1.42.2 github.com/onsi/ginkgo v1.16.4 github.com/pkg/errors v0.9.1 github.com/pmezard/go-difflib v1.0.0 @@ -87,9 +87,9 @@ require ( go.uber.org/atomic v1.7.0 // indirect go.uber.org/multierr v1.6.0 // indirect go4.org v0.0.0-20201209231011-d4a079459e60 // indirect - golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83 // indirect + golang.org/x/crypto v0.0.0-20211202192323-5770296d904e // indirect golang.org/x/mod v0.4.2 // indirect - golang.org/x/net v0.0.0-20210525063256-abc453219eb5 // indirect + golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2 // indirect golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c // indirect golang.org/x/sys v0.0.0-20210817190340-bfb29a6856f2 // indirect golang.org/x/term v0.0.0-20210503060354-a79de5458b56 // indirect diff --git a/go.sum b/go.sum index 42d47a26..acd48f91 100644 --- a/go.sum +++ b/go.sum @@ -312,6 +312,7 @@ github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFP github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= github.com/elazarl/goproxy v0.0.0-20170405201442-c4fc26588b6e/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= +github.com/embik/nutanix-client-go v0.0.0-20220106131900-50b8f27e5f60/go.mod h1:gkKNSxfEt3QtYG3S/wKiN8OmrJ4fpU7JbTlbnrMDOL8= github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= github.com/emicklei/go-restful v2.10.0+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= @@ -660,6 +661,7 @@ github.com/googleapis/gnostic v0.5.5 h1:9fHAtK0uDfpveeqqo1hkEZJcFvYXAiCN3UutL8F9 github.com/googleapis/gnostic v0.5.5/go.mod h1:7+EbHbldMins07ALC74bsA81Ovc97DwqyJO1AENw9kA= github.com/gophercloud/gophercloud v0.1.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8= github.com/gophercloud/gophercloud v0.14.0/go.mod h1:VX0Ibx85B60B5XOrZr6kaNwrmPUzcmMpwxvQ1WQIIWM= +github.com/gophercloud/gophercloud v0.24.0/go.mod h1:Q8fZtyi5zZxPS/j9aj3sSxtvj41AdQMDwyo1myduD5c= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= github.com/gorilla/csrf v1.6.2/go.mod h1:7tSf8kmjNYr7IWDCYhd3U8Ck34iQ/Yw5CJu7bAkHEGI= @@ -818,6 +820,7 @@ github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pty v1.0.0/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= @@ -829,8 +832,9 @@ github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kubermatic/machine-controller v1.23.1/go.mod h1:mXWbT7SjqpgFhzCFT3yMEHKdIlT+KkGy4KQCkNRM9Fc= github.com/kubermatic/machine-controller v1.26.0/go.mod h1:dcJ+GdDSCxCwM0poxwOK8hVO7epiOORDmNMmb2veyw4= github.com/kubermatic/machine-controller v1.36.1/go.mod h1:6BFZEvEMZi8OT8aHOsS7DXYsF6ZSpmsNxsci7OLTTn8= -github.com/kubermatic/machine-controller v1.40.1 h1:+xolKmQZMGDPfOw0KEwUtlXAF+8TsADldW0WeP0BGsU= github.com/kubermatic/machine-controller v1.40.1/go.mod h1:5LVcN4tCybGg+55hIHcVzCjNsBJy2PlnXG0xIzKmXGY= +github.com/kubermatic/machine-controller v1.42.2 h1:5Ppu5UNRhxwoOLPOoHBoX9Uouq82Jp1GRRYO7LswLF4= +github.com/kubermatic/machine-controller v1.42.2/go.mod h1:vr6i5XWfd5FIq2yodXcgdlKvOhMnM5uzn2XEZ2wcoFM= github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k= github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= @@ -941,7 +945,6 @@ github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OS github.com/nbio/st v0.0.0-20140626010706-e9e8d9816f32/go.mod h1:9wM+0iRr9ahx58uYLpLIr5fm8diHn0JbqRycJi6w0Ms= github.com/nelsam/hel v0.0.0-20200611165952-2d829bae0c66/go.mod h1:Rl/hm4V2s75ScsPmI9cNz87HLNg5MoFAMJwA90fzbkw= github.com/nelsam/hel/v2 v2.3.2/go.mod h1:1ZTGfU2PFTOd5mx22i5O0Lc2GY933lQ2wb/ggy+rL3w= -github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= @@ -1366,8 +1369,9 @@ golang.org/x/crypto v0.0.0-20200709230013-948cd5f35899/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201124201722-c8d3bf9c5392/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= -golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83 h1:/ZScEX8SfEmUGRHs0gxpqteO5nfNW6axyZbBdw9A12g= golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= +golang.org/x/crypto v0.0.0-20211202192323-5770296d904e h1:MUP6MR3rJ7Gk9LEia0LP2ytiH6MuCfs7qYz+47jGdD8= +golang.org/x/crypto v0.0.0-20211202192323-5770296d904e/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -1470,8 +1474,9 @@ golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwY golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/net v0.0.0-20210520170846-37e1c6afe023/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20210525063256-abc453219eb5 h1:wjuX4b5yYQnEQHzd+CBcrcC6OVR2J1CN6mUy0oSxIPo= golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2 h1:CIJ76btIcR3eFI5EgSo6k1qKw9KJexJuRLI9G7Hp5wE= +golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181106182150-f42d05182288/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -1587,6 +1592,7 @@ golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210601080250-7ecdf8ef093b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210817190340-bfb29a6856f2 h1:c8PlLMqBbOHoqtjteWm5/kbe6rNY2pbRfbIMVnepueo= golang.org/x/sys v0.0.0-20210817190340-bfb29a6856f2/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -1853,8 +1859,9 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/check.v1 v1.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= @@ -1930,6 +1937,7 @@ k8c.io/kubermatic/v2 v2.16.2 h1:tjPfI+VV51pggXCvcDL/qG1r7KHDBQPSPYngPxpRtp8= k8c.io/kubermatic/v2 v2.16.2/go.mod h1:NdW+2mq4ynRtfZs9yPnvcnFWQpzmM7ngntW6GeuQicU= k8c.io/operating-system-manager v0.1.0/go.mod h1:ULyZQO1irKjsQTNjIdrHld7SZ+joHjmPnOEs5Db8G8M= k8c.io/operating-system-manager v0.3.0/go.mod h1:ME5GOCNUrHG+57igEKP1JCJKVHynaLfodT8bRiYH3MY= +k8c.io/operating-system-manager v0.3.9/go.mod h1:aFyB/RH9DBAk0Kj5JVtCixhm9ugTeC8akgRGMW28lPg= k8s.io/api v0.0.0-20181018013834-843ad2d9b9ae/go.mod h1:iuAfoD4hCxJ8Onx9kaTIt30j7jUFS00AXQi6QMi99vA= k8s.io/api v0.0.0-20181115043458-b799cb063522/go.mod h1:iuAfoD4hCxJ8Onx9kaTIt30j7jUFS00AXQi6QMi99vA= k8s.io/api v0.0.0-20190725062911-6607c48751ae/go.mod h1:1O0xzX/RAtnm7l+5VEUxZ1ysO2ghatfq/OZED4zM9kA= diff --git a/hack/run-operating-system-manager.sh b/hack/run-operating-system-manager.sh index 5aa3e85a..dc1ee0b0 100755 --- a/hack/run-operating-system-manager.sh +++ b/hack/run-operating-system-manager.sh @@ -24,5 +24,5 @@ rm -rf $(dirname $0)/../_build/ make -C $(dirname $0)/.. build $(dirname $0)/../_build/osm-controller \ -worker-cluster-kubeconfig=$OSM_KUBECONFIG \ - -namespace=cloud-init-settings \ + -namespace=kube-system \ -worker-count=50 \ No newline at end of file diff --git a/hack/tools.go b/hack/tools.go index 3029e6a8..c0d0dcc2 100755 --- a/hack/tools.go +++ b/hack/tools.go @@ -1,4 +1,4 @@ -// +build tools +//go:build tools /* Copyright 2021 The Operating System Manager contributors. diff --git a/pkg/cloudprovider/gce/provider.go b/pkg/cloudprovider/gce/provider.go index 6c00ab97..e1537997 100644 --- a/pkg/cloudprovider/gce/provider.go +++ b/pkg/cloudprovider/gce/provider.go @@ -66,11 +66,11 @@ func getConfig(pconfig providerconfigtypes.Config) (*types.CloudConfig, error) { return nil, fmt.Errorf("cannot retrieve zone: %v", err) } - opts.MultiZone, err = config.GetConfigVarResolver().GetConfigVarBoolValue(rawConfig.MultiZone) + opts.MultiZone, _, err = config.GetConfigVarResolver().GetConfigVarBoolValue(rawConfig.MultiZone) if err != nil { return nil, fmt.Errorf("failed to retrieve multizone: %v", err) } - opts.Regional, err = config.GetConfigVarResolver().GetConfigVarBoolValue(rawConfig.Regional) + opts.Regional, _, err = config.GetConfigVarResolver().GetConfigVarBoolValue(rawConfig.Regional) if err != nil { return nil, fmt.Errorf("failed to retrieve regional: %v", err) } diff --git a/pkg/cloudprovider/openstack/provider.go b/pkg/cloudprovider/openstack/provider.go index 1d40626a..e6fdbac3 100644 --- a/pkg/cloudprovider/openstack/provider.go +++ b/pkg/cloudprovider/openstack/provider.go @@ -71,7 +71,7 @@ func getConfig(pconfig providerconfigtypes.Config, kubeletVersion string) (*type return nil, fmt.Errorf("failed to get the value of \"identityEndpoint\" field, error = %v", err) } - trustDevicePath, err := config.GetConfigVarResolver().GetConfigVarBoolValue(rawConfig.TrustDevicePath) + trustDevicePath, _, err := config.GetConfigVarResolver().GetConfigVarBoolValue(rawConfig.TrustDevicePath) if err != nil { return nil, err } diff --git a/pkg/controllers/osc/osc_controller.go b/pkg/controllers/osc/osc_controller.go index 03bf648b..fef15e7c 100644 --- a/pkg/controllers/osc/osc_controller.go +++ b/pkg/controllers/osc/osc_controller.go @@ -24,11 +24,11 @@ import ( "go.uber.org/zap" clusterv1alpha1 "github.com/kubermatic/machine-controller/pkg/apis/cluster/v1alpha1" + "github.com/kubermatic/machine-controller/pkg/containerruntime" kuberneteshelper "k8c.io/kubermatic/v2/pkg/kubernetes" "k8c.io/operating-system-manager/pkg/controllers/osc/resources" osmv1alpha1 "k8c.io/operating-system-manager/pkg/crd/osm/v1alpha1" "k8c.io/operating-system-manager/pkg/generator" - "k8c.io/operating-system-manager/pkg/resources/reconciling" corev1 "k8s.io/api/core/v1" kerrors "k8s.io/apimachinery/pkg/api/errors" @@ -54,21 +54,24 @@ const ( type Reconciler struct { client.Client workerClient client.Client - log *zap.SugaredLogger - - namespace string - containerRuntime string - externalCloudProvider bool - pauseImage string - initialTaints string - generator generator.CloudConfigGenerator - clusterDNSIPs []net.IP - caCert string - nodeHTTPProxy string - nodeNoProxy string - podCIDR string - nodePortRange string - kubeletFeatureGates map[string]bool + + log *zap.SugaredLogger + + namespace string + containerRuntime string + externalCloudProvider bool + pauseImage string + initialTaints string + generator generator.CloudConfigGenerator + clusterDNSIPs []net.IP + caCert string + nodeHTTPProxy string + nodeNoProxy string + podCIDR string + nodePortRange string + nodeRegistryCredentialsSecret string + containerRuntimeConfig containerruntime.Config + kubeletFeatureGates map[string]bool } func Add( @@ -89,24 +92,28 @@ func Add( nodeNoProxy string, podCIDR string, nodePortRange string, + containerRuntimeConfig containerruntime.Config, + nodeRegistryCredentialsSecret string, kubeletFeatureGates map[string]bool) error { reconciler := &Reconciler{ - log: log, - workerClient: workerClient, - Client: client, - caCert: caCert, - namespace: namespace, - generator: generator, - clusterDNSIPs: clusterDNSIPs, - containerRuntime: containerRuntime, - pauseImage: pauseImage, - initialTaints: initialTaints, - externalCloudProvider: externalCloudProvider, - nodeHTTPProxy: nodeHTTPProxy, - nodeNoProxy: nodeNoProxy, - podCIDR: podCIDR, - nodePortRange: nodePortRange, - kubeletFeatureGates: kubeletFeatureGates, + log: log, + workerClient: workerClient, + Client: client, + caCert: caCert, + namespace: namespace, + generator: generator, + clusterDNSIPs: clusterDNSIPs, + containerRuntime: containerRuntime, + pauseImage: pauseImage, + initialTaints: initialTaints, + externalCloudProvider: externalCloudProvider, + nodeHTTPProxy: nodeHTTPProxy, + nodeNoProxy: nodeNoProxy, + podCIDR: podCIDR, + nodePortRange: nodePortRange, + containerRuntimeConfig: containerRuntimeConfig, + nodeRegistryCredentialsSecret: nodeRegistryCredentialsSecret, + kubeletFeatureGates: kubeletFeatureGates, } log.Info("Reconciling OSC resource..") c, err := controller.New(ControllerName, mgr, controller.Options{Reconciler: reconciler, MaxConcurrentReconciles: workerCount}) @@ -128,6 +135,7 @@ func (r *Reconciler) Reconcile(ctx context.Context, req ctrlruntime.Request) (re machineDeployment := &clusterv1alpha1.MachineDeployment{} if err := r.workerClient.Get(ctx, req.NamespacedName, machineDeployment); err != nil { if kerrors.IsNotFound(err) { + return reconcile.Result{}, nil } return reconcile.Result{}, err @@ -135,6 +143,7 @@ func (r *Reconciler) Reconcile(ctx context.Context, req ctrlruntime.Request) (re // Resource is marked for deletion if machineDeployment.DeletionTimestamp != nil { + log.Debug("Cleaning up resources against machine deployment") if kuberneteshelper.HasFinalizer(machineDeployment, MachineDeploymentCleanupFinalizer) { return r.handleMachineDeploymentCleanup(ctx, machineDeployment) @@ -173,7 +182,7 @@ func (r *Reconciler) reconcile(ctx context.Context, md *clusterv1alpha1.MachineD func (r *Reconciler) reconcileOperatingSystemConfigs(ctx context.Context, md *clusterv1alpha1.MachineDeployment) error { // Check if OSC already exists, in that case we don't need to do anything since OSC are immutable - oscName := fmt.Sprintf(resources.MachineDeploymentSubresourceNamePattern, md.Name, resources.ProvisioningCloudConfig) + oscName := fmt.Sprintf(resources.MachineDeploymentSubresourceNamePattern, md.Name, md.Namespace, resources.ProvisioningCloudConfig) osc := &osmv1alpha1.OperatingSystemConfig{} if err := r.Get(ctx, types.NamespacedName{Name: oscName, Namespace: r.namespace}, osc); err == nil { // Early return since the object already exists @@ -187,31 +196,47 @@ func (r *Reconciler) reconcileOperatingSystemConfigs(ctx context.Context, md *cl return fmt.Errorf("failed to get OperatingSystemProfile: %v", err) } - if err := reconciling.ReconcileOperatingSystemConfigs(ctx, []reconciling.NamedOperatingSystemConfigCreatorGetter{ - resources.OperatingSystemConfigCreator( - md, - osp, - r.caCert, - r.clusterDNSIPs, - r.containerRuntime, - r.externalCloudProvider, - r.pauseImage, - r.initialTaints, - r.nodeHTTPProxy, - r.nodeNoProxy, - r.nodePortRange, - r.podCIDR, - r.kubeletFeatureGates, - ), - }, r.namespace, r.Client); err != nil { - return fmt.Errorf("failed to reconcile provisioning operating system config: %v", err) + if r.nodeRegistryCredentialsSecret != "" { + registryCredentials, err := containerruntime.GetContainerdAuthConfig(ctx, r.Client, r.nodeRegistryCredentialsSecret) + if err != nil { + return fmt.Errorf("failed to get containerd auth config: %v", err) + } + r.containerRuntimeConfig.RegistryCredentials = registryCredentials + } + + // We need to create OSC resource as it doesn't exist + osc, err := resources.GenerateOperatingSystemConfig( + md, + osp, + oscName, + r.namespace, + r.caCert, + r.clusterDNSIPs, + r.containerRuntime, + r.externalCloudProvider, + r.pauseImage, + r.initialTaints, + r.nodeHTTPProxy, + r.nodeNoProxy, + r.nodePortRange, + r.podCIDR, + r.containerRuntimeConfig, + r.kubeletFeatureGates, + ) + if err != nil { + return fmt.Errorf("failed to generate %s osc: %v", oscName, err) } + // Create resource in cluster + if err := r.Create(ctx, osc); err != nil { + return fmt.Errorf("failed to create %s osc: %v", oscName, err) + } + r.log.Infof("successfully generated provisioning osc: %v", oscName) return nil } func (r *Reconciler) reconcileSecrets(ctx context.Context, md *clusterv1alpha1.MachineDeployment) error { - oscName := fmt.Sprintf(resources.MachineDeploymentSubresourceNamePattern, md.Name, resources.ProvisioningCloudConfig) + oscName := fmt.Sprintf(resources.MachineDeploymentSubresourceNamePattern, md.Name, md.Namespace, resources.ProvisioningCloudConfig) // Check if secret already exists, in that case we don't need to do anything since secrets are immutable secret := &corev1.Secret{} @@ -230,13 +255,14 @@ func (r *Reconciler) reconcileSecrets(ctx context.Context, md *clusterv1alpha1.M return fmt.Errorf("failed to generate provisioning data") } - if err := reconciling.ReconcileSecrets(ctx, []reconciling.NamedSecretCreatorGetter{ - resources.CloudConfigSecretCreator(md.Name, resources.ProvisioningCloudConfig, provisionData), - }, CloudInitSettingsNamespace, r.workerClient); err != nil { - return fmt.Errorf("failed to reconcile provisioning secrets: %v", err) - } - r.log.Infof("successfully generated provisioning secret: %v", fmt.Sprintf(resources.MachineDeploymentSubresourceNamePattern, md.Name, resources.ProvisioningCloudConfig)) + // Generate secret for cloud-config + secret = resources.GenerateCloudConfigSecret(oscName, CloudInitSettingsNamespace, provisionData) + // Create resource in cluster + if err := r.workerClient.Create(ctx, secret); err != nil { + return fmt.Errorf("failed to create %s provisioning secret: %v", oscName, err) + } + r.log.Infof("successfully generated provisioning secret: %v", oscName) return nil } @@ -266,7 +292,7 @@ func (r *Reconciler) handleMachineDeploymentCleanup(ctx context.Context, md *clu // deleteOperatingSystemConfig deletes the OperatingSystemConfig created against a MachineDeployment func (r *Reconciler) deleteOperatingSystemConfig(ctx context.Context, md *clusterv1alpha1.MachineDeployment) error { - oscName := fmt.Sprintf(resources.MachineDeploymentSubresourceNamePattern, md.Name, resources.ProvisioningCloudConfig) + oscName := fmt.Sprintf(resources.MachineDeploymentSubresourceNamePattern, md.Name, md.Namespace, resources.ProvisioningCloudConfig) osc := &osmv1alpha1.OperatingSystemConfig{} if err := r.Get(ctx, types.NamespacedName{Name: oscName, Namespace: r.namespace}, osc); err != nil { if kerrors.IsNotFound(err) { @@ -282,7 +308,7 @@ func (r *Reconciler) deleteOperatingSystemConfig(ctx context.Context, md *cluste // deleteGeneratedSecrets deletes the secrets created against a MachineDeployment func (r *Reconciler) deleteGeneratedSecrets(ctx context.Context, md *clusterv1alpha1.MachineDeployment) error { - secretName := fmt.Sprintf(resources.MachineDeploymentSubresourceNamePattern, md.Name, resources.ProvisioningCloudConfig) + secretName := fmt.Sprintf(resources.MachineDeploymentSubresourceNamePattern, md.Name, md.Namespace, resources.ProvisioningCloudConfig) secret := &corev1.Secret{} if err := r.workerClient.Get(ctx, types.NamespacedName{Name: secretName, Namespace: CloudInitSettingsNamespace}, secret); err != nil { if kerrors.IsNotFound(err) { diff --git a/pkg/controllers/osc/osc_reconciler_test.go b/pkg/controllers/osc/osc_reconciler_test.go index 82793472..93552965 100644 --- a/pkg/controllers/osc/osc_reconciler_test.go +++ b/pkg/controllers/osc/osc_reconciler_test.go @@ -28,6 +28,7 @@ import ( "time" "github.com/kubermatic/machine-controller/pkg/apis/cluster/v1alpha1" + "github.com/kubermatic/machine-controller/pkg/containerruntime" providerconfigtypes "github.com/kubermatic/machine-controller/pkg/providerconfig/types" "k8c.io/operating-system-manager/pkg/controllers/osc/resources" osmv1alpha1 "k8c.io/operating-system-manager/pkg/crd/osm/v1alpha1" @@ -42,7 +43,6 @@ import ( "k8s.io/client-go/kubernetes/scheme" "sigs.k8s.io/controller-runtime/pkg/client" fakectrlruntimeclient "sigs.k8s.io/controller-runtime/pkg/client/fake" - "sigs.k8s.io/controller-runtime/pkg/reconcile" "sigs.k8s.io/yaml" ) @@ -95,29 +95,30 @@ type testConfig struct { func TestReconciler_Reconcile(t *testing.T) { var testCases = []struct { - name string - ospFile string - ospName string - oscFile string - oscName string - operatingSystem providerconfigtypes.OperatingSystem - mdName string - secretFile string - config testConfig - cloudProvider string - cloudProviderSpec runtime.RawExtension + name string + ospFile string + ospName string + oscFile string + oscName string + operatingSystem providerconfigtypes.OperatingSystem + mdName string + secretFile string + config testConfig + cloudProvider string + cloudProviderSpec runtime.RawExtension + additionalAnnotations map[string]string }{ { name: "Ubuntu OS in AWS with Containerd", - ospFile: "osp-ubuntu-20.04.yaml", + ospFile: "osp-ubuntu.yaml", ospName: "osp-ubuntu", operatingSystem: providerconfigtypes.OperatingSystemUbuntu, - oscFile: "osc-ubuntu-20.04-aws-containerd.yaml", - oscName: "ubuntu-20.04-aws-osc-provisioning", - mdName: "ubuntu-20.04-aws", - secretFile: "secret-ubuntu-20.04-aws-containerd.yaml", + oscFile: "osc-ubuntu-aws-containerd.yaml", + oscName: "ubuntu-aws-kube-system-osc-provisioning", + mdName: "ubuntu-aws", + secretFile: "secret-ubuntu-aws-containerd.yaml", config: testConfig{ - namespace: "cloud-init-settings", + namespace: "kube-system", containerRuntime: "containerd", kubeVersion: "1.22.1", clusterDNSIPs: []net.IP{net.IPv4(10, 0, 0, 0)}, @@ -127,15 +128,15 @@ func TestReconciler_Reconcile(t *testing.T) { }, { name: "Ubuntu OS in AWS with Docker", - ospFile: "osp-ubuntu-20.04.yaml", + ospFile: "osp-ubuntu.yaml", ospName: "osp-ubuntu", operatingSystem: providerconfigtypes.OperatingSystemUbuntu, - oscFile: "osc-ubuntu-20.04-aws-docker.yaml", - oscName: "ubuntu-20.04-aws-osc-provisioning", - mdName: "ubuntu-20.04-aws", - secretFile: "secret-ubuntu-20.04-aws-docker.yaml", + oscFile: "osc-ubuntu-aws-docker.yaml", + oscName: "ubuntu-aws-kube-system-osc-provisioning", + mdName: "ubuntu-aws", + secretFile: "secret-ubuntu-aws-docker.yaml", config: testConfig{ - namespace: "cloud-init-settings", + namespace: "kube-system", containerRuntime: "docker", kubeVersion: "1.22.1", clusterDNSIPs: []net.IP{net.IPv4(10, 0, 0, 0)}, @@ -149,11 +150,11 @@ func TestReconciler_Reconcile(t *testing.T) { ospName: "osp-flatcar", operatingSystem: providerconfigtypes.OperatingSystemFlatcar, oscFile: "osc-flatcar-aws-containerd.yaml", - oscName: "flatcar-aws-containerd-osc-provisioning", + oscName: "flatcar-aws-containerd-kube-system-osc-provisioning", mdName: "flatcar-aws-containerd", secretFile: "secret-flatcar-aws-containerd.yaml", config: testConfig{ - namespace: "cloud-init-settings", + namespace: "kube-system", containerRuntime: "containerd", kubeVersion: "1.22.1", clusterDNSIPs: []net.IP{net.IPv4(10, 0, 0, 0)}, @@ -167,11 +168,11 @@ func TestReconciler_Reconcile(t *testing.T) { ospName: "osp-flatcar", operatingSystem: providerconfigtypes.OperatingSystemFlatcar, oscFile: "osc-flatcar-aws-docker.yaml", - oscName: "flatcar-aws-docker-osc-provisioning", + oscName: "flatcar-aws-docker-kube-system-osc-provisioning", mdName: "flatcar-aws-docker", secretFile: "secret-flatcar-aws-docker.yaml", config: testConfig{ - namespace: "cloud-init-settings", + namespace: "kube-system", containerRuntime: "docker", kubeVersion: "1.22.1", clusterDNSIPs: []net.IP{net.IPv4(10, 0, 0, 0)}, @@ -185,17 +186,67 @@ func TestReconciler_Reconcile(t *testing.T) { ospName: "osp-rhel", operatingSystem: providerconfigtypes.OperatingSystemRHEL, oscFile: "osc-rhel-8.x-containerd.yaml", - oscName: "osp-rhel-aws-osc-provisioning", + oscName: "osp-rhel-aws-kube-system-osc-provisioning", mdName: "osp-rhel-aws", secretFile: "secret-rhel-8.x-containerd.yaml", config: testConfig{ - namespace: "cloud-init-settings", + namespace: "kube-system", + containerRuntime: "containerd", + kubeVersion: "1.22.1", + clusterDNSIPs: []net.IP{net.IPv4(10, 0, 0, 0)}, + }, + cloudProvider: "aws", + cloudProviderSpec: runtime.RawExtension{Raw: []byte(`{"zone": "eu-central-1b", "vpc": "e-123f", "subnetID": "test-subnet"}`)}, + }, + { + name: "Kubelet configuration with docker", + ospFile: "osp-ubuntu.yaml", + ospName: "osp-ubuntu", + operatingSystem: providerconfigtypes.OperatingSystemUbuntu, + oscFile: "osc-kubelet-configuration-docker.yaml", + oscName: "kubelet-configuration-kube-system-osc-provisioning", + mdName: "kubelet-configuration", + secretFile: "secret-kubelet-configuration-docker.yaml", + config: testConfig{ + namespace: "kube-system", + containerRuntime: "docker", + kubeVersion: "1.22.1", + clusterDNSIPs: []net.IP{net.IPv4(10, 0, 0, 0)}, + }, + cloudProvider: "aws", + cloudProviderSpec: runtime.RawExtension{Raw: []byte(`{"zone": "eu-central-1b", "vpc": "e-123f", "subnetID": "test-subnet"}`)}, + additionalAnnotations: map[string]string{ + "v1.kubelet-config.machine-controller.kubermatic.io/ContainerLogMaxSize": "300Mi", + "v1.kubelet-config.machine-controller.kubermatic.io/ContainerLogMaxFiles": "30", + "v1.kubelet-config.machine-controller.kubermatic.io/SystemReserved": "ephemeral-storage=30Gi,cpu=30m", + "v1.kubelet-config.machine-controller.kubermatic.io/KubeReserved": "ephemeral-storage=30Gi,cpu=30m", + "v1.kubelet-config.machine-controller.kubermatic.io/EvictionHard": "memory.available<30Mi", + }, + }, + { + name: "Kubelet configuration with containerd", + ospFile: "osp-ubuntu.yaml", + ospName: "osp-ubuntu", + operatingSystem: providerconfigtypes.OperatingSystemUbuntu, + oscFile: "osc-kubelet-configuration-containerd.yaml", + oscName: "kubelet-configuration-kube-system-osc-provisioning", + mdName: "kubelet-configuration", + secretFile: "secret-kubelet-configuration-containerd.yaml", + config: testConfig{ + namespace: "kube-system", containerRuntime: "containerd", kubeVersion: "1.22.1", clusterDNSIPs: []net.IP{net.IPv4(10, 0, 0, 0)}, }, cloudProvider: "aws", cloudProviderSpec: runtime.RawExtension{Raw: []byte(`{"zone": "eu-central-1b", "vpc": "e-123f", "subnetID": "test-subnet"}`)}, + additionalAnnotations: map[string]string{ + "v1.kubelet-config.machine-controller.kubermatic.io/ContainerLogMaxSize": "300Mi", + "v1.kubelet-config.machine-controller.kubermatic.io/ContainerLogMaxFiles": "30", + "v1.kubelet-config.machine-controller.kubermatic.io/SystemReserved": "ephemeral-storage=30Gi,cpu=30m", + "v1.kubelet-config.machine-controller.kubermatic.io/KubeReserved": "ephemeral-storage=30Gi,cpu=30m", + "v1.kubelet-config.machine-controller.kubermatic.io/EvictionHard": "memory.available<30Mi", + }, }, } @@ -217,7 +268,21 @@ func TestReconciler_Reconcile(t *testing.T) { t.Run(testCase.name, func(t *testing.T) { ctx := context.Background() - md := generateMachineDeployment(t, testCase.mdName, testCase.config.namespace, testCase.ospName, testCase.operatingSystem, testCase.cloudProvider, testCase.cloudProviderSpec) + md := generateMachineDeployment(t, testCase.mdName, testCase.config.namespace, testCase.ospName, testCase.operatingSystem, testCase.cloudProvider, testCase.cloudProviderSpec, testCase.additionalAnnotations) + + // Configure containerRuntimeConfig + containerRuntimeOpts := containerruntime.Opts{ + ContainerRuntime: testCase.config.containerRuntime, + InsecureRegistries: "192.168.100.100:5000, 10.0.0.1:5000", + PauseImage: "192.168.100.100:5000/kubernetes/pause:v3.1", + RegistryMirrors: "https://registry.docker-cn.com", + } + containerRuntimeConfig, err := containerruntime.BuildConfig(containerRuntimeOpts) + if err != nil { + t.Fatalf("failed to generate container runtime config: %v", err) + } + + reconciler.containerRuntimeConfig = containerRuntimeConfig if err := reconciler.reconcile(ctx, md); err != nil { t.Fatalf("failed to reconcile: %v", err) @@ -244,7 +309,7 @@ func TestReconciler_Reconcile(t *testing.T) { secret := &corev1.Secret{} if err := fakeClient.Get(ctx, types.NamespacedName{ - Namespace: "cloud-init-settings", + Namespace: CloudInitSettingsNamespace, Name: testCase.oscName}, secret); err != nil { t.Fatalf("failed to get secret: %v", err) @@ -281,15 +346,15 @@ func TestMachineDeploymentDeletion(t *testing.T) { { name: "test the deletion of machineDeployment", - ospFile: "osp-ubuntu-20.04.yaml", + ospFile: "osp-ubuntu.yaml", ospName: "osp-ubuntu", operatingSystem: providerconfigtypes.OperatingSystemUbuntu, - oscFile: "osc-ubuntu-20.04-aws-containerd.yaml", - oscName: "ubuntu-20.04-aws-osc-provisioning", - mdName: "ubuntu-20.04-aws", - secretFile: "secret-ubuntu-20.04-aws-containerd.yaml", + oscFile: "osc-ubuntu-aws-containerd.yaml", + oscName: "ubuntu-aws-kube-system-osc-provisioning", + mdName: "ubuntu-aws", + secretFile: "secret-ubuntu-aws-containerd.yaml", config: testConfig{ - namespace: "cloud-init-settings", + namespace: "kube-system", containerRuntime: "containerd", }, cloudProvider: "aws", @@ -305,7 +370,7 @@ func TestMachineDeploymentDeletion(t *testing.T) { t.Fatalf("failed loading osp %s from testdata: %v", testCase.name, err) } - md := generateMachineDeployment(t, testCase.mdName, testCase.config.namespace, testCase.ospName, testCase.operatingSystem, testCase.cloudProvider, testCase.cloudProviderSpec) + md := generateMachineDeployment(t, testCase.mdName, testCase.config.namespace, testCase.ospName, testCase.operatingSystem, testCase.cloudProvider, testCase.cloudProviderSpec, nil) fakeClient := fakectrlruntimeclient. NewClientBuilder(). WithScheme(scheme.Scheme). @@ -333,54 +398,41 @@ func TestMachineDeploymentDeletion(t *testing.T) { // Ensure that corresponding secret was created secret := &corev1.Secret{} if err := fakeClient.Get(ctx, types.NamespacedName{ - Namespace: testCase.config.namespace, + Namespace: CloudInitSettingsNamespace, Name: testCase.oscName}, secret); err != nil { t.Fatalf("failed to get secret: %v", err) } - // Retrieve MachineDeployment - machineDeployment := &v1alpha1.MachineDeployment{} - if err := fakeClient.Get(ctx, types.NamespacedName{ - Namespace: testCase.config.namespace, - Name: testCase.mdName}, - machineDeployment); err != nil { - t.Fatalf("failed to get machine deployment: %v", err) - } - // Add deletionTimestamp to Machinedeployment to queue it up for deletion - machineDeployment.ObjectMeta.DeletionTimestamp = &metav1.Time{Time: time.Now()} - err := fakeClient.Update(ctx, machineDeployment) - if err != nil { - t.Fatalf("failed to update machine deployment with deletionTimestamp: %v", err) - } + md.ObjectMeta.DeletionTimestamp = &metav1.Time{Time: time.Now()} // Reconcile to trigger delete workflow - _, err = reconciler.Reconcile(ctx, reconcile.Request{NamespacedName: types.NamespacedName{Name: md.Name, Namespace: md.Namespace}}) + _, err := reconciler.handleMachineDeploymentCleanup(ctx, md) if err != nil { t.Fatalf("failed to reconcile: %v", err) } // Ensure that OperatingSystemConfig was deleted if err := fakeClient.Get(ctx, types.NamespacedName{ - Namespace: "cloud-init-settings", - Name: fmt.Sprintf("ubuntu-20.04-lts-osc-%s", resources.ProvisioningCloudConfig)}, + Namespace: CloudInitSettingsNamespace, + Name: testCase.oscName}, osc); err == nil || !kerrors.IsNotFound(err) { - t.Fatalf("failed to delete osc") + t.Fatalf("failed to ensure that osc is deleted: %v", err) } // Ensure that corresponding secret was deleted if err := fakeClient.Get(ctx, types.NamespacedName{ - Namespace: "cloud-init-settings", - Name: fmt.Sprintf("ubuntu-20.04-lts-osc-%s", resources.ProvisioningCloudConfig)}, + Namespace: CloudInitSettingsNamespace, + Name: testCase.oscName}, secret); err == nil || !kerrors.IsNotFound(err) { - t.Fatalf("failed to delete secret") + t.Fatalf("failed to ensure that secret is deleted: %s", err) } }) } } -func generateMachineDeployment(t *testing.T, name, namespace, osp string, os providerconfigtypes.OperatingSystem, cloudprovider string, cloudProviderSpec runtime.RawExtension) *v1alpha1.MachineDeployment { +func generateMachineDeployment(t *testing.T, name, namespace, osp string, os providerconfigtypes.OperatingSystem, cloudprovider string, cloudProviderSpec runtime.RawExtension, additionalAnnotations map[string]string) *v1alpha1.MachineDeployment { pconfig := providerconfigtypes.Config{ SSHPublicKeys: []string{"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDdOIhYmzCK5DSVLu3c"}, OperatingSystem: os, @@ -392,13 +444,17 @@ func generateMachineDeployment(t *testing.T, name, namespace, osp string, os pro t.Fatalf("failed to generate machine deployment: %v", err) } + annotations := make(map[string]string) + annotations[resources.MachineDeploymentOSPAnnotation] = osp + for k, v := range additionalAnnotations { + annotations[k] = v + } + md := &v1alpha1.MachineDeployment{ ObjectMeta: metav1.ObjectMeta{ - Name: name, - Namespace: namespace, - Annotations: map[string]string{ - resources.MachineDeploymentOSPAnnotation: osp, - }, + Name: name, + Namespace: namespace, + Annotations: annotations, }, Spec: v1alpha1.MachineDeploymentSpec{ Template: v1alpha1.MachineTemplateSpec{ @@ -437,8 +493,9 @@ func loadFile(obj runtime.Object, name string) error { func buildReconciler(fakeClient client.Client, config testConfig) Reconciler { return Reconciler{ - Client: fakeClient, - workerClient: fakeClient, + Client: fakeClient, + workerClient: fakeClient, + log: testUtil.DefaultLogger, generator: generator.NewDefaultCloudConfigGenerator(""), namespace: config.namespace, diff --git a/pkg/controllers/osc/resources/operating_system_config.go b/pkg/controllers/osc/resources/operating_system_config.go index e53b55d8..cf7f17e0 100644 --- a/pkg/controllers/osc/resources/operating_system_config.go +++ b/pkg/controllers/osc/resources/operating_system_config.go @@ -28,6 +28,7 @@ import ( "github.com/Masterminds/semver/v3" "github.com/kubermatic/machine-controller/pkg/apis/cluster/common" "github.com/kubermatic/machine-controller/pkg/apis/cluster/v1alpha1" + "github.com/kubermatic/machine-controller/pkg/containerruntime" providerconfigtypes "github.com/kubermatic/machine-controller/pkg/providerconfig/types" "k8c.io/operating-system-manager/pkg/cloudprovider" @@ -38,8 +39,9 @@ import ( "k8c.io/operating-system-manager/pkg/providerconfig/rhel" "k8c.io/operating-system-manager/pkg/providerconfig/sles" "k8c.io/operating-system-manager/pkg/providerconfig/ubuntu" - "k8c.io/operating-system-manager/pkg/resources/reconciling" "k8s.io/apimachinery/pkg/runtime" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) type CloudConfigSecret string @@ -47,13 +49,16 @@ type CloudConfigSecret string const ( ProvisioningCloudConfig CloudConfigSecret = "provisioning" - MachineDeploymentSubresourceNamePattern = "%s-osc-%s" + MachineDeploymentSubresourceNamePattern = "%s-%s-osc-%s" MachineDeploymentOSPAnnotation = "k8c.io/operating-system-profile" ) -func OperatingSystemConfigCreator( +// GenerateOperatingSystemConfig return an OperatingSystemConfig generated against the input data +func GenerateOperatingSystemConfig( md *v1alpha1.MachineDeployment, osp *osmv1alpha1.OperatingSystemProfile, + oscName string, + namespace string, caCert string, clusterDNSIPs []net.IP, containerRuntime string, @@ -64,135 +69,153 @@ func OperatingSystemConfigCreator( nodeNoProxy string, nodePortRange string, podCidr string, + containerRuntimeConfig containerruntime.Config, kubeletFeatureGates map[string]bool, -) reconciling.NamedOperatingSystemConfigCreatorGetter { - return func() (string, reconciling.OperatingSystemConfigCreator) { - var oscName = fmt.Sprintf(MachineDeploymentSubresourceNamePattern, md.Name, ProvisioningCloudConfig) - - return oscName, func(osc *osmv1alpha1.OperatingSystemConfig) (*osmv1alpha1.OperatingSystemConfig, error) { - ospOriginal := osp.DeepCopy() - - // Get providerConfig from machineDeployment - providerConfig := providerconfigtypes.Config{} - err := json.Unmarshal(md.Spec.Template.Spec.ProviderSpec.Value.Raw, &providerConfig) - if err != nil { - return nil, fmt.Errorf("failed to decode provider configs: %v", err) - } +) (*osmv1alpha1.OperatingSystemConfig, error) { + ospOriginal := osp.DeepCopy() + + // Set metadata for OSC + osc := &osmv1alpha1.OperatingSystemConfig{ + ObjectMeta: metav1.ObjectMeta{ + Name: oscName, + Namespace: namespace, + }, + } - var cloudConfig string - if providerConfig.OverwriteCloudConfig != nil { - cloudConfig = *providerConfig.OverwriteCloudConfig - } else { - cloudConfig, err = cloudprovider.GetCloudConfig(providerConfig, md.Spec.Template.Spec.Versions.Kubelet) - if err != nil { - return nil, fmt.Errorf("failed to fetch cloud-config: %v", err) - } - } + // Get providerConfig from machineDeployment + providerConfig := providerconfigtypes.Config{} + err := json.Unmarshal(md.Spec.Template.Spec.ProviderSpec.Value.Raw, &providerConfig) + if err != nil { + return nil, fmt.Errorf("failed to decode provider configs: %v", err) + } - // ensure that Kubelet version is prefixed by "v" - kubeletVersion, err := semver.NewVersion(md.Spec.Template.Spec.Versions.Kubelet) - if err != nil { - return nil, fmt.Errorf("invalid kubelet version: %w", err) - } + var cloudConfig string + if providerConfig.OverwriteCloudConfig != nil { + cloudConfig = *providerConfig.OverwriteCloudConfig + } else { + cloudConfig, err = cloudprovider.GetCloudConfig(providerConfig, md.Spec.Template.Spec.Versions.Kubelet) + if err != nil { + return nil, fmt.Errorf("failed to fetch cloud-config: %v", err) + } + } - kubeletVersionStr := kubeletVersion.String() - if !strings.HasPrefix(kubeletVersionStr, "v") { - kubeletVersionStr = fmt.Sprintf("v%s", kubeletVersionStr) - } + // Ensure that Kubelet version is prefixed by "v" + kubeletVersion, err := semver.NewVersion(md.Spec.Template.Spec.Versions.Kubelet) + if err != nil { + return nil, fmt.Errorf("invalid kubelet version: %w", err) + } - inTreeCCM, external, err := cloudprovider.KubeletCloudProviderConfig(providerConfig.CloudProvider) - if err != nil { - return nil, err - } + kubeletVersionStr := kubeletVersion.String() + if !strings.HasPrefix(kubeletVersionStr, "v") { + kubeletVersionStr = fmt.Sprintf("v%s", kubeletVersionStr) + } - if external { - externalCloudProvider = true - } + inTreeCCM, external, err := cloudprovider.KubeletCloudProviderConfig(providerConfig.CloudProvider) + if err != nil { + return nil, err + } - data := filesData{ - KubeVersion: kubeletVersionStr, - ClusterDNSIPs: clusterDNSIPs, - KubernetesCACert: caCert, - InTreeCCMAvailable: inTreeCCM, - CloudConfig: cloudConfig, - ContainerRuntime: containerRuntime, - CloudProviderName: osmv1alpha1.CloudProvider(providerConfig.CloudProvider), - ExternalCloudProvider: externalCloudProvider, - PauseImage: pauseImage, - InitialTaints: initialTaints, - PodCIDR: podCidr, - NodePortRange: nodePortRange, - KubeletFeatureGates: kubeletFeatureGates, - } + // Handling for kubelet configuration + kubeletConfigs := getKubeletConfigs(md.Annotations) + if kubeletConfigs.ContainerLogMaxSize != nil && len(*kubeletConfigs.ContainerLogMaxSize) > 0 { + containerRuntimeConfig.ContainerLogMaxSize = *kubeletConfigs.ContainerLogMaxSize + } - if len(nodeHTTPProxy) > 0 { - data.HTTPProxy = &nodeHTTPProxy - } - if len(nodeNoProxy) > 0 { - data.NoProxy = &nodeNoProxy - } - if providerConfig.Network != nil { - data.NetworkConfig = providerConfig.Network - } + if kubeletConfigs.ContainerLogMaxFiles != nil && len(*kubeletConfigs.ContainerLogMaxFiles) > 0 { + containerRuntimeConfig.ContainerLogMaxFiles = *kubeletConfigs.ContainerLogMaxFiles + } - err = setOperatingSystemConfig(providerConfig.OperatingSystem, providerConfig.OperatingSystemSpec, &data) - if err != nil { - return nil, fmt.Errorf("failed to add operating system spec: %v", err) - } + crEngine := containerRuntimeConfig.Engine(kubeletVersion) + crConfig, err := crEngine.Config() + if err != nil { + return nil, fmt.Errorf("failed to generate container runtime config: %w", err) + } - // Handling for kubelet configuration - data.kubeletConfig = kubeletResourceManagementConfig(md.Annotations) + if external { + externalCloudProvider = true + } - // Handle files - osp.Spec.Files = append(osp.Spec.Files, selectAdditionalFiles(osp, containerRuntime)...) - additionalTemplates, err := selectAdditionalTemplates(osp, containerRuntime, data) - if err != nil { - return nil, fmt.Errorf("failed to add OSP templates: %v", err) - } - populatedFiles, err := populateFilesList(osp.Spec.Files, additionalTemplates, data) - if err != nil { - return nil, fmt.Errorf("failed to populate OSP file template: %v", err) - } + data := filesData{ + KubeVersion: kubeletVersionStr, + ClusterDNSIPs: clusterDNSIPs, + KubernetesCACert: caCert, + InTreeCCMAvailable: inTreeCCM, + CloudConfig: cloudConfig, + ContainerRuntime: containerRuntime, + CloudProviderName: osmv1alpha1.CloudProvider(providerConfig.CloudProvider), + ExternalCloudProvider: externalCloudProvider, + PauseImage: pauseImage, + InitialTaints: initialTaints, + PodCIDR: podCidr, + NodePortRange: nodePortRange, + ContainerRuntimeConfig: crConfig, + KubeletFeatureGates: kubeletFeatureGates, + kubeletConfig: kubeletConfigs, + } - osc.Spec = osmv1alpha1.OperatingSystemConfigSpec{ - OSName: ospOriginal.Spec.OSName, - OSVersion: ospOriginal.Spec.OSVersion, - Units: ospOriginal.Spec.Units, - Files: populatedFiles, - CloudProvider: osmv1alpha1.CloudProviderSpec{ - Name: osmv1alpha1.CloudProvider(providerConfig.CloudProvider), - Spec: providerConfig.CloudProviderSpec, - }, - UserSSHKeys: providerConfig.SSHPublicKeys, - CloudInitModules: osp.Spec.CloudInitModules, - } + if len(nodeHTTPProxy) > 0 { + data.HTTPProxy = &nodeHTTPProxy + } + if len(nodeNoProxy) > 0 { + data.NoProxy = &nodeNoProxy + } + if providerConfig.Network != nil { + data.NetworkConfig = providerConfig.Network + } - return osc, nil - } + err = setOperatingSystemConfig(providerConfig.OperatingSystem, providerConfig.OperatingSystemSpec, &data) + if err != nil { + return nil, fmt.Errorf("failed to add operating system spec: %v", err) + } + + // Handle files + osp.Spec.Files = append(osp.Spec.Files, selectAdditionalFiles(osp, containerRuntime)...) + additionalTemplates, err := selectAdditionalTemplates(osp, containerRuntime, data) + if err != nil { + return nil, fmt.Errorf("failed to add OSP templates: %v", err) + } + populatedFiles, err := populateFilesList(osp.Spec.Files, additionalTemplates, data) + if err != nil { + return nil, fmt.Errorf("failed to populate OSP file template: %v", err) + } + + osc.Spec = osmv1alpha1.OperatingSystemConfigSpec{ + OSName: ospOriginal.Spec.OSName, + OSVersion: ospOriginal.Spec.OSVersion, + Units: ospOriginal.Spec.Units, + Files: populatedFiles, + CloudProvider: osmv1alpha1.CloudProviderSpec{ + Name: osmv1alpha1.CloudProvider(providerConfig.CloudProvider), + Spec: providerConfig.CloudProviderSpec, + }, + UserSSHKeys: providerConfig.SSHPublicKeys, + CloudInitModules: osp.Spec.CloudInitModules, } + return osc, nil } type filesData struct { - KubeVersion string - KubeletConfiguration string - KubeletSystemdUnit string - InTreeCCMAvailable bool - CNIVersion string - ClusterDNSIPs []net.IP - KubernetesCACert string - ServerAddress string - CloudConfig string - ContainerRuntime string - CloudProviderName osmv1alpha1.CloudProvider - NetworkConfig *providerconfigtypes.NetworkConfig - ExternalCloudProvider bool - PauseImage string - InitialTaints string - HTTPProxy *string - NoProxy *string - PodCIDR string - NodePortRange string - KubeletFeatureGates map[string]bool + KubeVersion string + KubeletConfiguration string + KubeletSystemdUnit string + InTreeCCMAvailable bool + CNIVersion string + ClusterDNSIPs []net.IP + KubernetesCACert string + ServerAddress string + CloudConfig string + ContainerRuntime string + CloudProviderName osmv1alpha1.CloudProvider + NetworkConfig *providerconfigtypes.NetworkConfig + ExternalCloudProvider bool + PauseImage string + InitialTaints string + HTTPProxy *string + NoProxy *string + PodCIDR string + NodePortRange string + ContainerRuntimeConfig string + KubeletFeatureGates map[string]bool kubeletConfig OperatingSystemConfig @@ -208,9 +231,11 @@ type OperatingSystemConfig struct { } type kubeletConfig struct { - KubeReserved *map[string]string - SystemReserved *map[string]string - EvictionHard *map[string]string + KubeReserved *map[string]string + SystemReserved *map[string]string + EvictionHard *map[string]string + ContainerLogMaxSize *string + ContainerLogMaxFiles *string } func populateFilesList(files []osmv1alpha1.File, additionalTemplates []string, d filesData) ([]osmv1alpha1.File, error) { @@ -341,7 +366,7 @@ func setOperatingSystemConfig(os providerconfigtypes.OperatingSystem, operatingS return errors.New("unknown OperatingSystem") } -func kubeletResourceManagementConfig(annotations map[string]string) kubeletConfig { +func getKubeletConfigs(annotations map[string]string) kubeletConfig { var cfg kubeletConfig kubeletConfigs := common.GetKubeletConfigs(annotations) @@ -349,16 +374,24 @@ func kubeletResourceManagementConfig(annotations map[string]string) kubeletConfi return cfg } - if kubeReserved, ok := kubeletConfigs[common.KubeReservedKubeletConfig]; ok { - cfg.KubeReserved = getKeyValueMap(kubeReserved, "=") + if val, ok := kubeletConfigs[common.KubeReservedKubeletConfig]; ok { + cfg.KubeReserved = getKeyValueMap(val, "=") + } + + if val, ok := kubeletConfigs[common.SystemReservedKubeletConfig]; ok { + cfg.SystemReserved = getKeyValueMap(val, "=") + } + + if val, ok := kubeletConfigs[common.EvictionHardKubeletConfig]; ok { + cfg.EvictionHard = getKeyValueMap(val, "<") } - if systemReserved, ok := kubeletConfigs[common.SystemReservedKubeletConfig]; ok { - cfg.SystemReserved = getKeyValueMap(systemReserved, "=") + if val, ok := kubeletConfigs[common.ContainerLogMaxSizeKubeletConfig]; ok { + cfg.ContainerLogMaxSize = &val } - if evictionHard, ok := kubeletConfigs[common.EvictionHardKubeletConfig]; ok { - cfg.EvictionHard = getKeyValueMap(evictionHard, "<") + if val, ok := kubeletConfigs[common.ContainerLogMaxFilesKubeletConfig]; ok { + cfg.ContainerLogMaxFiles = &val } return cfg } diff --git a/pkg/controllers/osc/resources/secrets.go b/pkg/controllers/osc/resources/secrets.go index 2a33922d..73529b65 100644 --- a/pkg/controllers/osc/resources/secrets.go +++ b/pkg/controllers/osc/resources/secrets.go @@ -17,27 +17,26 @@ limitations under the License. package resources import ( - "fmt" - - "k8c.io/operating-system-manager/pkg/resources/reconciling" - corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/utils/pointer" ) -// CloudConfigSecretCreator returns a function to create a secret that contains the cloud-init or ignition configurations. -func CloudConfigSecretCreator(mdName string, oscType CloudConfigSecret, data []byte) reconciling.NamedSecretCreatorGetter { - return func() (string, reconciling.SecretCreator) { - secretName := fmt.Sprintf(MachineDeploymentSubresourceNamePattern, mdName, oscType) - return secretName, func(sec *corev1.Secret) (*corev1.Secret, error) { - if sec.Data == nil { - sec.Data = map[string][]byte{} - } - sec.Data["cloud-config"] = data +// GenerateCloudConfigSecret returns a secret that contains the cloud-init or ignition configurations. +func GenerateCloudConfigSecret(name, namespace string, data []byte) *corev1.Secret { + secret := corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: namespace, + }, + Type: corev1.SecretTypeOpaque, + // Cloud config secret is immutable + Immutable: pointer.Bool(true), + } - // Cloud config secret is immutable - sec.Immutable = pointer.Bool(true) - return sec, nil - } + if secret.Data == nil { + secret.Data = map[string][]byte{} } + secret.Data["cloud-config"] = data + return &secret } diff --git a/pkg/controllers/osc/testdata/osc-flatcar-aws-containerd.yaml b/pkg/controllers/osc/testdata/osc-flatcar-aws-containerd.yaml index 176d6078..311d34a8 100644 --- a/pkg/controllers/osc/testdata/osc-flatcar-aws-containerd.yaml +++ b/pkg/controllers/osc/testdata/osc-flatcar-aws-containerd.yaml @@ -2,8 +2,8 @@ apiVersion: operatingsystemmanager.k8c.io/v1alpha1 kind: OperatingSystemConfig metadata: creationTimestamp: null - name: flatcar-aws-containerd-osc-provisioning - namespace: cloud-init-settings + name: flatcar-aws-containerd-kube-system-osc-provisioning + namespace: kube-system resourceVersion: "1" spec: cloudProvider: @@ -128,6 +128,17 @@ spec: tar xvf "$cni_filename" rm -f "$cni_filename" cd - + CRI_TOOLS_RELEASE="${CRI_TOOLS_RELEASE:-v1.22.0}" + cri_tools_base_url="https://github.com/kubernetes-sigs/cri-tools/releases/download/${CRI_TOOLS_RELEASE}" + cri_tools_filename="crictl-${CRI_TOOLS_RELEASE}-linux-${arch}.tar.gz" + curl -Lfo "$opt_bin/$cri_tools_filename" "$cri_tools_base_url/$cri_tools_filename" + cri_tools_sum=$(curl -Lf "$cri_tools_base_url/$cri_tools_filename.sha256" | sed 's/\*\///') + cd "$opt_bin" + sha256sum -c <<<"$cri_tools_sum" + tar xvf "$cri_tools_filename" + rm -f "$cri_tools_filename" + ln -sf "$opt_bin/crictl" "$usr_local_bin"/crictl || echo "symbolic link is skipped" + cd - KUBE_VERSION="${KUBE_VERSION:-v1.22.1}" kube_dir="$opt_bin/kubernetes-$KUBE_VERSION" kube_base_url="https://storage.googleapis.com/kubernetes-release/release/$KUBE_VERSION/bin/linux/$arch" @@ -280,6 +291,8 @@ spec: clusterDNS: - "10.0.0.0" clusterDomain: cluster.local + containerLogMaxSize: 100Mi + containerLogMaxFiles: 5 featureGates: GracefulNodeShutdown: true IdentifyPodOS: false @@ -361,7 +374,7 @@ spec: permissions: 384 - content: inline: - data: | + data: |+ version = 2 [metrics] @@ -369,6 +382,7 @@ spec: [plugins] [plugins."io.containerd.grpc.v1.cri"] + sandbox_image = "192.168.100.100:5000/kubernetes/pause:v3.1" [plugins."io.containerd.grpc.v1.cri".containerd] [plugins."io.containerd.grpc.v1.cri".containerd.runtimes] [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc] @@ -378,7 +392,15 @@ spec: [plugins."io.containerd.grpc.v1.cri".registry] [plugins."io.containerd.grpc.v1.cri".registry.mirrors] [plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"] - endpoint = ["https://registry-1.docker.io"] + endpoint = ["https://registry.docker-cn.com"] + [plugins."io.containerd.grpc.v1.cri".registry.configs] + [plugins."io.containerd.grpc.v1.cri".registry.configs."10.0.0.1:5000"] + [plugins."io.containerd.grpc.v1.cri".registry.configs."10.0.0.1:5000".tls] + insecure_skip_verify = true + [plugins."io.containerd.grpc.v1.cri".registry.configs."192.168.100.100:5000"] + [plugins."io.containerd.grpc.v1.cri".registry.configs."192.168.100.100:5000".tls] + insecure_skip_verify = true + path: /etc/containerd/config.toml permissions: 420 - content: diff --git a/pkg/controllers/osc/testdata/osc-flatcar-aws-docker.yaml b/pkg/controllers/osc/testdata/osc-flatcar-aws-docker.yaml index 9da181ba..11009426 100644 --- a/pkg/controllers/osc/testdata/osc-flatcar-aws-docker.yaml +++ b/pkg/controllers/osc/testdata/osc-flatcar-aws-docker.yaml @@ -2,8 +2,8 @@ apiVersion: operatingsystemmanager.k8c.io/v1alpha1 kind: OperatingSystemConfig metadata: creationTimestamp: null - name: flatcar-aws-docker-osc-provisioning - namespace: cloud-init-settings + name: flatcar-aws-docker-kube-system-osc-provisioning + namespace: kube-system resourceVersion: "1" spec: cloudProvider: @@ -126,6 +126,17 @@ spec: tar xvf "$cni_filename" rm -f "$cni_filename" cd - + CRI_TOOLS_RELEASE="${CRI_TOOLS_RELEASE:-v1.22.0}" + cri_tools_base_url="https://github.com/kubernetes-sigs/cri-tools/releases/download/${CRI_TOOLS_RELEASE}" + cri_tools_filename="crictl-${CRI_TOOLS_RELEASE}-linux-${arch}.tar.gz" + curl -Lfo "$opt_bin/$cri_tools_filename" "$cri_tools_base_url/$cri_tools_filename" + cri_tools_sum=$(curl -Lf "$cri_tools_base_url/$cri_tools_filename.sha256" | sed 's/\*\///') + cd "$opt_bin" + sha256sum -c <<<"$cri_tools_sum" + tar xvf "$cri_tools_filename" + rm -f "$cri_tools_filename" + ln -sf "$opt_bin/crictl" "$usr_local_bin"/crictl || echo "symbolic link is skipped" + cd - KUBE_VERSION="${KUBE_VERSION:-v1.22.1}" kube_dir="$opt_bin/kubernetes-$KUBE_VERSION" kube_base_url="https://storage.googleapis.com/kubernetes-release/release/$KUBE_VERSION/bin/linux/$arch" @@ -359,7 +370,7 @@ spec: permissions: 384 - content: inline: - data: '{"exec-opts":["native.cgroupdriver=systemd"],"storage-driver":"overlay2","log-driver":"json-file","log-opts":{"max-file":"5","max-size":"100m"}}' + data: '{"exec-opts":["native.cgroupdriver=systemd"],"storage-driver":"overlay2","log-driver":"json-file","log-opts":{"max-file":"5","max-size":"100m"},"insecure-registries":["192.168.100.100:5000","10.0.0.1:5000"],"registry-mirrors":["https://registry.docker-cn.com"]}' path: /etc/docker/daemon.json permissions: 420 - content: diff --git a/pkg/controllers/osc/testdata/osc-kubelet-configuration-containerd.yaml b/pkg/controllers/osc/testdata/osc-kubelet-configuration-containerd.yaml new file mode 100644 index 00000000..2e5433d5 --- /dev/null +++ b/pkg/controllers/osc/testdata/osc-kubelet-configuration-containerd.yaml @@ -0,0 +1,444 @@ +apiVersion: operatingsystemmanager.k8c.io/v1alpha1 +kind: OperatingSystemConfig +metadata: + creationTimestamp: null + name: kubelet-configuration-kube-system-osc-provisioning + namespace: kube-system + resourceVersion: "1" +spec: + cloudProvider: + name: aws + spec: + subnetID: test-subnet + vpc: e-123f + zone: eu-central-1b + files: + - content: + inline: + data: | + [Journal] + SystemMaxUse=5G + encoding: b64 + path: /etc/systemd/journald.conf.d/max_disk_use.conf + - content: + inline: + data: | + #!/usr/bin/env bash + set -euo pipefail + + modprobe ip_vs + modprobe ip_vs_rr + modprobe ip_vs_wrr + modprobe ip_vs_sh + + if modinfo nf_conntrack_ipv4 &> /dev/null; then + modprobe nf_conntrack_ipv4 + else + modprobe nf_conntrack + fi + encoding: b64 + path: /opt/load-kernel-modules.sh + permissions: 493 + - content: + inline: + data: | + net.bridge.bridge-nf-call-ip6tables = 1 + net.bridge.bridge-nf-call-iptables = 1 + kernel.panic_on_oops = 1 + kernel.panic = 10 + net.ipv4.ip_forward = 1 + vm.overcommit_memory = 1 + fs.inotify.max_user_watches = 1048576 + encoding: b64 + path: /etc/sysctl.d/k8s.conf + - content: + inline: + data: | + # Added by kubermatic machine-controller + # Enable cgroups memory and swap accounting + GRUB_CMDLINE_LINUX="cgroup_enable=memory swapaccount=1" + encoding: b64 + path: /etc/default/grub.d/60-swap-accounting.cfg + - content: + inline: + data: | + #!/bin/bash + set -xeuo pipefail + if systemctl is-active ufw; then systemctl stop ufw; fi + systemctl mask ufw + systemctl restart systemd-modules-load.service + sysctl --system + sed -i.orig '/.*swap.*/d' /etc/fstab + swapoff -a + + apt-get update + + DEBIAN_FRONTEND=noninteractive apt-get -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confold" install -y \ + curl \ + ca-certificates \ + ceph-common \ + cifs-utils \ + conntrack \ + e2fsprogs \ + ebtables \ + ethtool \ + glusterfs-client \ + iptables \ + jq \ + kmod \ + openssh-client \ + nfs-common \ + socat \ + util-linux \ + ipvsadm + apt-get update + apt-get install -y apt-transport-https ca-certificates curl software-properties-common lsb-release + curl -fsSL https://download.docker.com/linux/ubuntu/gpg | apt-key add - + add-apt-repository "deb https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" + + cat <"$kube_sum_file" + + for bin in kubelet kubeadm kubectl; do + curl -Lfo "$kube_dir/$bin" "$kube_base_url/$bin" + chmod +x "$kube_dir/$bin" + sum=$(curl -Lf "$kube_base_url/$bin.sha256") + echo "$sum $kube_dir/$bin" >>"$kube_sum_file" + done + sha256sum -c "$kube_sum_file" + + for bin in kubelet kubeadm kubectl; do + ln -sf "$kube_dir/$bin" "$opt_bin"/$bin + done + + if [[ ! -x /opt/bin/health-monitor.sh ]]; then + curl -Lfo /opt/bin/health-monitor.sh https://raw.githubusercontent.com/kubermatic/machine-controller/7967a0af2b75f29ad2ab227eeaa26ea7b0f2fbde/pkg/userdata/scripts/health-monitor.sh + chmod +x /opt/bin/health-monitor.sh + fi + + # set kubelet nodeip environment variable + /opt/bin/setup_net_env.sh + + systemctl enable --now kubelet + systemctl enable --now --no-block kubelet-healthcheck.service + encoding: b64 + path: /opt/bin/setup + permissions: 493 + - content: + inline: + data: | + #!/bin/bash + set -xeuo pipefail + while ! "$@"; do + sleep 1 + done + encoding: b64 + path: /opt/bin/supervise.sh + permissions: 493 + - content: + inline: + data: | + [Unit] + After=containerd.service + Requires=containerd.service + + Description=kubelet: The Kubernetes Node Agent + Documentation=https://kubernetes.io/docs/home/ + + [Service] + Restart=always + StartLimitInterval=0 + RestartSec=10 + CPUAccounting=true + MemoryAccounting=true + + Environment="PATH=/opt/bin:/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin/" + EnvironmentFile=-/etc/environment + + ExecStartPre=/bin/bash /opt/load-kernel-modules.sh + ExecStartPre=/bin/bash /opt/bin/setup_net_env.sh + ExecStart=/opt/bin/kubelet $KUBELET_EXTRA_ARGS \ + --bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf \ + --kubeconfig=/var/lib/kubelet/kubeconfig \ + --config=/etc/kubernetes/kubelet.conf \ + --network-plugin=cni \ + --cert-dir=/etc/kubernetes/pki \ + --cloud-provider=aws \ + --cloud-config=/etc/kubernetes/cloud-config \ + --dynamic-config-dir=/etc/kubernetes/dynamic-config-dir \ + --feature-gates=DynamicKubeletConfig=true \ + --exit-on-lock-contention \ + --lock-file=/tmp/kubelet.lock \ + --container-runtime=remote \ + --container-runtime-endpoint=unix:///run/containerd/containerd.sock \ + --node-ip ${KUBELET_NODE_IP} + + [Install] + WantedBy=multi-user.target + encoding: b64 + path: /etc/systemd/system/kubelet.service + - content: + inline: + data: | + [Service] + Environment="KUBELET_EXTRA_ARGS=--resolv-conf=/run/systemd/resolve/resolv.conf" + encoding: b64 + path: /etc/systemd/system/kubelet.service.d/extras.conf + - content: + inline: + data: |+ + [global] + Zone="" + VPC="" + SubnetID="test-subnet" + + encoding: b64 + path: /etc/kubernetes/cloud-config + permissions: 384 + - content: + inline: + data: | + #!/usr/bin/env bash + echodate() { + echo "[$(date -Is)]" "$@" + } + + # get the default interface IP address + DEFAULT_IFC_IP=$(ip -o route get 1 | grep -oP "src \K\S+") + + if [ -z "${DEFAULT_IFC_IP}" ] + then + echodate "Failed to get IP address for the default route interface" + exit 1 + fi + + # get the full hostname + FULL_HOSTNAME=$(hostname -f) + + # write the nodeip_env file + # we need the line below because flatcar has the same string "coreos" in that file + if grep -q coreos /etc/os-release + then + echo "KUBELET_NODE_IP=${DEFAULT_IFC_IP}\nKUBELET_HOSTNAME=${FULL_HOSTNAME}" > /etc/kubernetes/nodeip.conf + elif [ ! -d /etc/systemd/system/kubelet.service.d ] + then + echodate "Can't find kubelet service extras directory" + exit 1 + else + echo -e "[Service]\nEnvironment=\"KUBELET_NODE_IP=${DEFAULT_IFC_IP}\"\nEnvironment=\"KUBELET_HOSTNAME=${FULL_HOSTNAME}\"" > /etc/systemd/system/kubelet.service.d/nodeip.conf + fi + encoding: b64 + path: /opt/bin/setup_net_env.sh + permissions: 493 + - content: + inline: + data: | + -----BEGIN CERTIFICATE----- + MIIEWjCCA0KgAwIBAgIJALfRlWsI8YQHMA0GCSqGSIb3DQEBBQUAMHsxCzAJBgNV + BAYTAlVTMQswCQYDVQQIEwJDQTEWMBQGA1UEBxMNU2FuIEZyYW5jaXNjbzEUMBIG + A1UEChMLQnJhZGZpdHppbmMxEjAQBgNVBAMTCWxvY2FsaG9zdDEdMBsGCSqGSIb3 + DQEJARYOYnJhZEBkYW5nYS5jb20wHhcNMTQwNzE1MjA0NjA1WhcNMTcwNTA0MjA0 + NjA1WjB7MQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0ExFjAUBgNVBAcTDVNhbiBG + cmFuY2lzY28xFDASBgNVBAoTC0JyYWRmaXR6aW5jMRIwEAYDVQQDEwlsb2NhbGhv + c3QxHTAbBgkqhkiG9w0BCQEWDmJyYWRAZGFuZ2EuY29tMIIBIjANBgkqhkiG9w0B + AQEFAAOCAQ8AMIIBCgKCAQEAt5fAjp4fTcekWUTfzsp0kyih1OYbsGL0KX1eRbSS + R8Od0+9Q62Hyny+GFwMTb4A/KU8mssoHvcceSAAbwfbxFK/+s51TobqUnORZrOoT + ZjkUygbyXDSK99YBbcR1Pip8vwMTm4XKuLtCigeBBdjjAQdgUO28LENGlsMnmeYk + JfODVGnVmr5Ltb9ANA8IKyTfsnHJ4iOCS/PlPbUj2q7YnoVLposUBMlgUb/CykX3 + mOoLb4yJJQyA/iST6ZxiIEj36D4yWZ5lg7YJl+UiiBQHGCnPdGyipqV06ex0heYW + caiW8LWZSUQ93jQ+WVCH8hT7DQO1dmsvUmXlq/JeAlwQ/QIDAQABo4HgMIHdMB0G + A1UdDgQWBBRcAROthS4P4U7vTfjByC569R7E6DCBrQYDVR0jBIGlMIGigBRcAROt + hS4P4U7vTfjByC569R7E6KF/pH0wezELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNB + MRYwFAYDVQQHEw1TYW4gRnJhbmNpc2NvMRQwEgYDVQQKEwtCcmFkZml0emluYzES + MBAGA1UEAxMJbG9jYWxob3N0MR0wGwYJKoZIhvcNAQkBFg5icmFkQGRhbmdhLmNv + bYIJALfRlWsI8YQHMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAG6h + U9f9sNH0/6oBbGGy2EVU0UgITUQIrFWo9rFkrW5k/XkDjQm+3lzjT0iGR4IxE/Ao + eU6sQhua7wrWeFEn47GL98lnCsJdD7oZNhFmQ95Tb/LnDUjs5Yj9brP0NWzXfYU4 + UK2ZnINJRcJpB8iRCaCxE8DdcUF0XqIEq6pA272snoLmiXLMvNl3kYEdm+je6voD + 58SNVEUsztzQyXmJEhCpwVI0A6QCjzXj+qvpmw3ZZHi8JwXei8ZZBLTSFBki8Z7n + sH9BBH38/SzUmAN4QHSPy1gjqm00OAE8NaYDkh/bzE4d7mLGGMWp/WE3KPSu82HF + kPe6XoSbiLm/kxk32T0= + -----END CERTIFICATE----- + encoding: b64 + path: /etc/kubernetes/pki/ca.crt + - content: + inline: + data: | + [Install] + WantedBy=multi-user.target + + [Unit] + Requires=network-online.target + After=network-online.target + + [Service] + Type=oneshot + RemainAfterExit=true + EnvironmentFile=-/etc/environment + ExecStart=/opt/bin/supervise.sh /opt/bin/setup + encoding: b64 + path: /etc/systemd/system/setup.service + permissions: 420 + - content: + inline: + data: | + export PATH="/opt/bin:$PATH" + encoding: b64 + path: /etc/profile.d/opt-bin-path.sh + permissions: 420 + - content: + inline: + data: | + apiVersion: kubelet.config.k8s.io/v1beta1 + kind: KubeletConfiguration + authentication: + anonymous: + enabled: false + webhook: + enabled: true + x509: + clientCAFile: /etc/kubernetes/pki/ca.crt + authorization: + mode: Webhook + cgroupDriver: systemd + clusterDNS: + - "10.0.0.0" + clusterDomain: cluster.local + containerLogMaxSize: 300Mi + containerLogMaxFiles: 30 + featureGates: + GracefulNodeShutdown: true + IdentifyPodOS: false + protectKernelDefaults: true + readOnlyPort: 0 + rotateCertificates: true + serverTLSBootstrap: true + staticPodPath: /etc/kubernetes/manifests + kubeReserved: + cpu: 30m + ephemeral-storage: 30Gi + systemReserved: + cpu: 30m + ephemeral-storage: 30Gi + evictionHard: + memory.available: 30Mi + tlsCipherSuites: + - TLS_AES_128_GCM_SHA256 + - TLS_AES_256_GCM_SHA384 + - TLS_CHACHA20_POLY1305_SHA256 + - TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 + - TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 + - TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305 + - TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 + - TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 + - TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305 + volumePluginDir: /var/lib/kubelet/volumeplugins + encoding: b64 + path: /etc/kubernetes/kubelet.conf + - content: + inline: + data: | + [Unit] + Requires=kubelet.service + After=kubelet.service + + [Service] + ExecStart=/opt/bin/health-monitor.sh kubelet + + [Install] + WantedBy=multi-user.target + encoding: b64 + path: /etc/systemd/system/kubelet-healthcheck.service + permissions: 420 + - content: + inline: + data: |+ + version = 2 + + [metrics] + address = "127.0.0.1:1338" + + [plugins] + [plugins."io.containerd.grpc.v1.cri"] + sandbox_image = "192.168.100.100:5000/kubernetes/pause:v3.1" + [plugins."io.containerd.grpc.v1.cri".containerd] + [plugins."io.containerd.grpc.v1.cri".containerd.runtimes] + [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc] + runtime_type = "io.containerd.runc.v2" + [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options] + SystemdCgroup = true + [plugins."io.containerd.grpc.v1.cri".registry] + [plugins."io.containerd.grpc.v1.cri".registry.mirrors] + [plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"] + endpoint = ["https://registry.docker-cn.com"] + [plugins."io.containerd.grpc.v1.cri".registry.configs] + [plugins."io.containerd.grpc.v1.cri".registry.configs."10.0.0.1:5000"] + [plugins."io.containerd.grpc.v1.cri".registry.configs."10.0.0.1:5000".tls] + insecure_skip_verify = true + [plugins."io.containerd.grpc.v1.cri".registry.configs."192.168.100.100:5000"] + [plugins."io.containerd.grpc.v1.cri".registry.configs."192.168.100.100:5000".tls] + insecure_skip_verify = true + + encoding: b64 + path: /etc/containerd/config.toml + permissions: 420 + modules: + bootcmd: + - echo hello + - echo world + rh_subscription: + password: password + username: username + osName: ubuntu + osVersion: "20.04" + userSSHKeys: + - ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDdOIhYmzCK5DSVLu3c diff --git a/pkg/controllers/osc/testdata/osc-kubelet-configuration-docker.yaml b/pkg/controllers/osc/testdata/osc-kubelet-configuration-docker.yaml new file mode 100644 index 00000000..bd3902a1 --- /dev/null +++ b/pkg/controllers/osc/testdata/osc-kubelet-configuration-docker.yaml @@ -0,0 +1,416 @@ +apiVersion: operatingsystemmanager.k8c.io/v1alpha1 +kind: OperatingSystemConfig +metadata: + creationTimestamp: null + name: kubelet-configuration-kube-system-osc-provisioning + namespace: kube-system + resourceVersion: "1" +spec: + cloudProvider: + name: aws + spec: + subnetID: test-subnet + vpc: e-123f + zone: eu-central-1b + files: + - content: + inline: + data: | + [Journal] + SystemMaxUse=5G + encoding: b64 + path: /etc/systemd/journald.conf.d/max_disk_use.conf + - content: + inline: + data: | + #!/usr/bin/env bash + set -euo pipefail + + modprobe ip_vs + modprobe ip_vs_rr + modprobe ip_vs_wrr + modprobe ip_vs_sh + + if modinfo nf_conntrack_ipv4 &> /dev/null; then + modprobe nf_conntrack_ipv4 + else + modprobe nf_conntrack + fi + encoding: b64 + path: /opt/load-kernel-modules.sh + permissions: 493 + - content: + inline: + data: | + net.bridge.bridge-nf-call-ip6tables = 1 + net.bridge.bridge-nf-call-iptables = 1 + kernel.panic_on_oops = 1 + kernel.panic = 10 + net.ipv4.ip_forward = 1 + vm.overcommit_memory = 1 + fs.inotify.max_user_watches = 1048576 + encoding: b64 + path: /etc/sysctl.d/k8s.conf + - content: + inline: + data: | + # Added by kubermatic machine-controller + # Enable cgroups memory and swap accounting + GRUB_CMDLINE_LINUX="cgroup_enable=memory swapaccount=1" + encoding: b64 + path: /etc/default/grub.d/60-swap-accounting.cfg + - content: + inline: + data: | + #!/bin/bash + set -xeuo pipefail + if systemctl is-active ufw; then systemctl stop ufw; fi + systemctl mask ufw + systemctl restart systemd-modules-load.service + sysctl --system + sed -i.orig '/.*swap.*/d' /etc/fstab + swapoff -a + + apt-get update + + DEBIAN_FRONTEND=noninteractive apt-get -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confold" install -y \ + curl \ + ca-certificates \ + ceph-common \ + cifs-utils \ + conntrack \ + e2fsprogs \ + ebtables \ + ethtool \ + glusterfs-client \ + iptables \ + jq \ + kmod \ + openssh-client \ + nfs-common \ + socat \ + util-linux \ + ipvsadm + apt-get update + apt-get install -y apt-transport-https ca-certificates curl software-properties-common lsb-release + curl -fsSL https://download.docker.com/linux/ubuntu/gpg | apt-key add - + add-apt-repository "deb https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" + + mkdir -p /etc/systemd/system/containerd.service.d /etc/systemd/system/docker.service.d + + cat <"$kube_sum_file" + + for bin in kubelet kubeadm kubectl; do + curl -Lfo "$kube_dir/$bin" "$kube_base_url/$bin" + chmod +x "$kube_dir/$bin" + sum=$(curl -Lf "$kube_base_url/$bin.sha256") + echo "$sum $kube_dir/$bin" >>"$kube_sum_file" + done + sha256sum -c "$kube_sum_file" + + for bin in kubelet kubeadm kubectl; do + ln -sf "$kube_dir/$bin" "$opt_bin"/$bin + done + + if [[ ! -x /opt/bin/health-monitor.sh ]]; then + curl -Lfo /opt/bin/health-monitor.sh https://raw.githubusercontent.com/kubermatic/machine-controller/7967a0af2b75f29ad2ab227eeaa26ea7b0f2fbde/pkg/userdata/scripts/health-monitor.sh + chmod +x /opt/bin/health-monitor.sh + fi + + # set kubelet nodeip environment variable + /opt/bin/setup_net_env.sh + + systemctl enable --now kubelet + systemctl enable --now --no-block kubelet-healthcheck.service + encoding: b64 + path: /opt/bin/setup + permissions: 493 + - content: + inline: + data: | + #!/bin/bash + set -xeuo pipefail + while ! "$@"; do + sleep 1 + done + encoding: b64 + path: /opt/bin/supervise.sh + permissions: 493 + - content: + inline: + data: | + [Unit] + After=docker.service + Requires=docker.service + + Description=kubelet: The Kubernetes Node Agent + Documentation=https://kubernetes.io/docs/home/ + + [Service] + Restart=always + StartLimitInterval=0 + RestartSec=10 + CPUAccounting=true + MemoryAccounting=true + + Environment="PATH=/opt/bin:/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin/" + EnvironmentFile=-/etc/environment + + ExecStartPre=/bin/bash /opt/load-kernel-modules.sh + ExecStartPre=/bin/bash /opt/bin/setup_net_env.sh + ExecStart=/opt/bin/kubelet $KUBELET_EXTRA_ARGS \ + --bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf \ + --kubeconfig=/var/lib/kubelet/kubeconfig \ + --config=/etc/kubernetes/kubelet.conf \ + --network-plugin=cni \ + --cert-dir=/etc/kubernetes/pki \ + --cloud-provider=aws \ + --cloud-config=/etc/kubernetes/cloud-config \ + --dynamic-config-dir=/etc/kubernetes/dynamic-config-dir \ + --feature-gates=DynamicKubeletConfig=true \ + --exit-on-lock-contention \ + --lock-file=/tmp/kubelet.lock \ + --container-runtime=docker \ + --container-runtime-endpoint=unix:///var/run/dockershim.sock \ + --node-ip ${KUBELET_NODE_IP} + + [Install] + WantedBy=multi-user.target + encoding: b64 + path: /etc/systemd/system/kubelet.service + - content: + inline: + data: | + [Service] + Environment="KUBELET_EXTRA_ARGS=--resolv-conf=/run/systemd/resolve/resolv.conf" + encoding: b64 + path: /etc/systemd/system/kubelet.service.d/extras.conf + - content: + inline: + data: |+ + [global] + Zone="" + VPC="" + SubnetID="test-subnet" + + encoding: b64 + path: /etc/kubernetes/cloud-config + permissions: 384 + - content: + inline: + data: | + #!/usr/bin/env bash + echodate() { + echo "[$(date -Is)]" "$@" + } + + # get the default interface IP address + DEFAULT_IFC_IP=$(ip -o route get 1 | grep -oP "src \K\S+") + + if [ -z "${DEFAULT_IFC_IP}" ] + then + echodate "Failed to get IP address for the default route interface" + exit 1 + fi + + # get the full hostname + FULL_HOSTNAME=$(hostname -f) + + # write the nodeip_env file + # we need the line below because flatcar has the same string "coreos" in that file + if grep -q coreos /etc/os-release + then + echo "KUBELET_NODE_IP=${DEFAULT_IFC_IP}\nKUBELET_HOSTNAME=${FULL_HOSTNAME}" > /etc/kubernetes/nodeip.conf + elif [ ! -d /etc/systemd/system/kubelet.service.d ] + then + echodate "Can't find kubelet service extras directory" + exit 1 + else + echo -e "[Service]\nEnvironment=\"KUBELET_NODE_IP=${DEFAULT_IFC_IP}\"\nEnvironment=\"KUBELET_HOSTNAME=${FULL_HOSTNAME}\"" > /etc/systemd/system/kubelet.service.d/nodeip.conf + fi + encoding: b64 + path: /opt/bin/setup_net_env.sh + permissions: 493 + - content: + inline: + data: | + -----BEGIN CERTIFICATE----- + MIIEWjCCA0KgAwIBAgIJALfRlWsI8YQHMA0GCSqGSIb3DQEBBQUAMHsxCzAJBgNV + BAYTAlVTMQswCQYDVQQIEwJDQTEWMBQGA1UEBxMNU2FuIEZyYW5jaXNjbzEUMBIG + A1UEChMLQnJhZGZpdHppbmMxEjAQBgNVBAMTCWxvY2FsaG9zdDEdMBsGCSqGSIb3 + DQEJARYOYnJhZEBkYW5nYS5jb20wHhcNMTQwNzE1MjA0NjA1WhcNMTcwNTA0MjA0 + NjA1WjB7MQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0ExFjAUBgNVBAcTDVNhbiBG + cmFuY2lzY28xFDASBgNVBAoTC0JyYWRmaXR6aW5jMRIwEAYDVQQDEwlsb2NhbGhv + c3QxHTAbBgkqhkiG9w0BCQEWDmJyYWRAZGFuZ2EuY29tMIIBIjANBgkqhkiG9w0B + AQEFAAOCAQ8AMIIBCgKCAQEAt5fAjp4fTcekWUTfzsp0kyih1OYbsGL0KX1eRbSS + R8Od0+9Q62Hyny+GFwMTb4A/KU8mssoHvcceSAAbwfbxFK/+s51TobqUnORZrOoT + ZjkUygbyXDSK99YBbcR1Pip8vwMTm4XKuLtCigeBBdjjAQdgUO28LENGlsMnmeYk + JfODVGnVmr5Ltb9ANA8IKyTfsnHJ4iOCS/PlPbUj2q7YnoVLposUBMlgUb/CykX3 + mOoLb4yJJQyA/iST6ZxiIEj36D4yWZ5lg7YJl+UiiBQHGCnPdGyipqV06ex0heYW + caiW8LWZSUQ93jQ+WVCH8hT7DQO1dmsvUmXlq/JeAlwQ/QIDAQABo4HgMIHdMB0G + A1UdDgQWBBRcAROthS4P4U7vTfjByC569R7E6DCBrQYDVR0jBIGlMIGigBRcAROt + hS4P4U7vTfjByC569R7E6KF/pH0wezELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNB + MRYwFAYDVQQHEw1TYW4gRnJhbmNpc2NvMRQwEgYDVQQKEwtCcmFkZml0emluYzES + MBAGA1UEAxMJbG9jYWxob3N0MR0wGwYJKoZIhvcNAQkBFg5icmFkQGRhbmdhLmNv + bYIJALfRlWsI8YQHMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAG6h + U9f9sNH0/6oBbGGy2EVU0UgITUQIrFWo9rFkrW5k/XkDjQm+3lzjT0iGR4IxE/Ao + eU6sQhua7wrWeFEn47GL98lnCsJdD7oZNhFmQ95Tb/LnDUjs5Yj9brP0NWzXfYU4 + UK2ZnINJRcJpB8iRCaCxE8DdcUF0XqIEq6pA272snoLmiXLMvNl3kYEdm+je6voD + 58SNVEUsztzQyXmJEhCpwVI0A6QCjzXj+qvpmw3ZZHi8JwXei8ZZBLTSFBki8Z7n + sH9BBH38/SzUmAN4QHSPy1gjqm00OAE8NaYDkh/bzE4d7mLGGMWp/WE3KPSu82HF + kPe6XoSbiLm/kxk32T0= + -----END CERTIFICATE----- + encoding: b64 + path: /etc/kubernetes/pki/ca.crt + - content: + inline: + data: | + [Install] + WantedBy=multi-user.target + + [Unit] + Requires=network-online.target + After=network-online.target + + [Service] + Type=oneshot + RemainAfterExit=true + EnvironmentFile=-/etc/environment + ExecStart=/opt/bin/supervise.sh /opt/bin/setup + encoding: b64 + path: /etc/systemd/system/setup.service + permissions: 420 + - content: + inline: + data: | + export PATH="/opt/bin:$PATH" + encoding: b64 + path: /etc/profile.d/opt-bin-path.sh + permissions: 420 + - content: + inline: + data: | + apiVersion: kubelet.config.k8s.io/v1beta1 + kind: KubeletConfiguration + authentication: + anonymous: + enabled: false + webhook: + enabled: true + x509: + clientCAFile: /etc/kubernetes/pki/ca.crt + authorization: + mode: Webhook + cgroupDriver: systemd + clusterDNS: + - "10.0.0.0" + clusterDomain: cluster.local + featureGates: + GracefulNodeShutdown: true + IdentifyPodOS: false + protectKernelDefaults: true + readOnlyPort: 0 + rotateCertificates: true + serverTLSBootstrap: true + staticPodPath: /etc/kubernetes/manifests + kubeReserved: + cpu: 30m + ephemeral-storage: 30Gi + systemReserved: + cpu: 30m + ephemeral-storage: 30Gi + evictionHard: + memory.available: 30Mi + tlsCipherSuites: + - TLS_AES_128_GCM_SHA256 + - TLS_AES_256_GCM_SHA384 + - TLS_CHACHA20_POLY1305_SHA256 + - TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 + - TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 + - TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305 + - TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 + - TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 + - TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305 + volumePluginDir: /var/lib/kubelet/volumeplugins + encoding: b64 + path: /etc/kubernetes/kubelet.conf + - content: + inline: + data: | + [Unit] + Requires=kubelet.service + After=kubelet.service + + [Service] + ExecStart=/opt/bin/health-monitor.sh kubelet + + [Install] + WantedBy=multi-user.target + encoding: b64 + path: /etc/systemd/system/kubelet-healthcheck.service + permissions: 420 + - content: + inline: + data: '{"exec-opts":["native.cgroupdriver=systemd"],"storage-driver":"overlay2","log-driver":"json-file","log-opts":{"max-file":"30","max-size":"300m"},"insecure-registries":["192.168.100.100:5000","10.0.0.1:5000"],"registry-mirrors":["https://registry.docker-cn.com"]}' + encoding: b64 + path: /etc/docker/daemon.json + permissions: 420 + modules: + bootcmd: + - echo hello + - echo world + rh_subscription: + password: password + username: username + osName: ubuntu + osVersion: "20.04" + userSSHKeys: + - ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDdOIhYmzCK5DSVLu3c diff --git a/pkg/controllers/osc/testdata/osc-rhel-8.x-containerd.yaml b/pkg/controllers/osc/testdata/osc-rhel-8.x-containerd.yaml index a3a8e9fa..17528f7b 100644 --- a/pkg/controllers/osc/testdata/osc-rhel-8.x-containerd.yaml +++ b/pkg/controllers/osc/testdata/osc-rhel-8.x-containerd.yaml @@ -2,8 +2,8 @@ apiVersion: operatingsystemmanager.k8c.io/v1alpha1 kind: OperatingSystemConfig metadata: creationTimestamp: null - name: osp-rhel-aws-osc-provisioning - namespace: cloud-init-settings + name: osp-rhel-aws-kube-system-osc-provisioning + namespace: kube-system resourceVersion: "1" spec: cloudProvider: @@ -113,6 +113,7 @@ spec: systemctl daemon-reload systemctl enable --now containerd opt_bin=/opt/bin + usr_local_bin=/usr/local/bin cni_bin_dir=/opt/cni/bin mkdir -p /etc/cni/net.d /etc/kubernetes/dynamic-config-dir /etc/kubernetes/manifests "$opt_bin" "$cni_bin_dir" arch=${HOST_ARCH-} @@ -141,6 +142,17 @@ spec: tar xvf "$cni_filename" rm -f "$cni_filename" cd - + CRI_TOOLS_RELEASE="${CRI_TOOLS_RELEASE:-v1.22.0}" + cri_tools_base_url="https://github.com/kubernetes-sigs/cri-tools/releases/download/${CRI_TOOLS_RELEASE}" + cri_tools_filename="crictl-${CRI_TOOLS_RELEASE}-linux-${arch}.tar.gz" + curl -Lfo "$opt_bin/$cri_tools_filename" "$cri_tools_base_url/$cri_tools_filename" + cri_tools_sum=$(curl -Lf "$cri_tools_base_url/$cri_tools_filename.sha256" | sed 's/\*\///') + cd "$opt_bin" + sha256sum -c <<<"$cri_tools_sum" + tar xvf "$cri_tools_filename" + rm -f "$cri_tools_filename" + ln -sf "$opt_bin/crictl" "$usr_local_bin"/crictl || echo "symbolic link is skipped" + cd - KUBE_VERSION="${KUBE_VERSION:-v1.22.1}" kube_dir="$opt_bin/kubernetes-$KUBE_VERSION" kube_base_url="https://storage.googleapis.com/kubernetes-release/release/$KUBE_VERSION/bin/linux/$arch" @@ -347,6 +359,8 @@ spec: clusterDNS: - "10.0.0.0" clusterDomain: cluster.local + containerLogMaxSize: 100Mi + containerLogMaxFiles: 5 featureGates: GracefulNodeShutdown: true IdentifyPodOS: false @@ -398,7 +412,7 @@ spec: permissions: 420 - content: inline: - data: | + data: |+ version = 2 [metrics] @@ -406,6 +420,7 @@ spec: [plugins] [plugins."io.containerd.grpc.v1.cri"] + sandbox_image = "192.168.100.100:5000/kubernetes/pause:v3.1" [plugins."io.containerd.grpc.v1.cri".containerd] [plugins."io.containerd.grpc.v1.cri".containerd.runtimes] [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc] @@ -415,7 +430,15 @@ spec: [plugins."io.containerd.grpc.v1.cri".registry] [plugins."io.containerd.grpc.v1.cri".registry.mirrors] [plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"] - endpoint = ["https://registry-1.docker.io"] + endpoint = ["https://registry.docker-cn.com"] + [plugins."io.containerd.grpc.v1.cri".registry.configs] + [plugins."io.containerd.grpc.v1.cri".registry.configs."10.0.0.1:5000"] + [plugins."io.containerd.grpc.v1.cri".registry.configs."10.0.0.1:5000".tls] + insecure_skip_verify = true + [plugins."io.containerd.grpc.v1.cri".registry.configs."192.168.100.100:5000"] + [plugins."io.containerd.grpc.v1.cri".registry.configs."192.168.100.100:5000".tls] + insecure_skip_verify = true + encoding: b64 path: /etc/containerd/config.toml permissions: 420 diff --git a/pkg/controllers/osc/testdata/osc-ubuntu-20.04-aws-containerd.yaml b/pkg/controllers/osc/testdata/osc-ubuntu-aws-containerd.yaml similarity index 95% rename from pkg/controllers/osc/testdata/osc-ubuntu-20.04-aws-containerd.yaml rename to pkg/controllers/osc/testdata/osc-ubuntu-aws-containerd.yaml index 6e00a1cd..41e0f09a 100644 --- a/pkg/controllers/osc/testdata/osc-ubuntu-20.04-aws-containerd.yaml +++ b/pkg/controllers/osc/testdata/osc-ubuntu-aws-containerd.yaml @@ -2,8 +2,8 @@ apiVersion: operatingsystemmanager.k8c.io/v1alpha1 kind: OperatingSystemConfig metadata: creationTimestamp: null - name: ubuntu-20.04-aws-osc-provisioning - namespace: cloud-init-settings + name: ubuntu-aws-kube-system-osc-provisioning + namespace: kube-system resourceVersion: "1" spec: cloudProvider: @@ -353,6 +353,8 @@ spec: clusterDNS: - "10.0.0.0" clusterDomain: cluster.local + containerLogMaxSize: 100Mi + containerLogMaxFiles: 5 featureGates: GracefulNodeShutdown: true IdentifyPodOS: false @@ -404,7 +406,7 @@ spec: permissions: 420 - content: inline: - data: | + data: |+ version = 2 [metrics] @@ -412,6 +414,7 @@ spec: [plugins] [plugins."io.containerd.grpc.v1.cri"] + sandbox_image = "192.168.100.100:5000/kubernetes/pause:v3.1" [plugins."io.containerd.grpc.v1.cri".containerd] [plugins."io.containerd.grpc.v1.cri".containerd.runtimes] [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc] @@ -421,7 +424,15 @@ spec: [plugins."io.containerd.grpc.v1.cri".registry] [plugins."io.containerd.grpc.v1.cri".registry.mirrors] [plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"] - endpoint = ["https://registry-1.docker.io"] + endpoint = ["https://registry.docker-cn.com"] + [plugins."io.containerd.grpc.v1.cri".registry.configs] + [plugins."io.containerd.grpc.v1.cri".registry.configs."10.0.0.1:5000"] + [plugins."io.containerd.grpc.v1.cri".registry.configs."10.0.0.1:5000".tls] + insecure_skip_verify = true + [plugins."io.containerd.grpc.v1.cri".registry.configs."192.168.100.100:5000"] + [plugins."io.containerd.grpc.v1.cri".registry.configs."192.168.100.100:5000".tls] + insecure_skip_verify = true + encoding: b64 path: /etc/containerd/config.toml permissions: 420 diff --git a/pkg/controllers/osc/testdata/osc-ubuntu-20.04-aws-docker.yaml b/pkg/controllers/osc/testdata/osc-ubuntu-aws-docker.yaml similarity index 98% rename from pkg/controllers/osc/testdata/osc-ubuntu-20.04-aws-docker.yaml rename to pkg/controllers/osc/testdata/osc-ubuntu-aws-docker.yaml index 9b4a3a12..1b2fb7c5 100644 --- a/pkg/controllers/osc/testdata/osc-ubuntu-20.04-aws-docker.yaml +++ b/pkg/controllers/osc/testdata/osc-ubuntu-aws-docker.yaml @@ -2,8 +2,8 @@ apiVersion: operatingsystemmanager.k8c.io/v1alpha1 kind: OperatingSystemConfig metadata: creationTimestamp: null - name: ubuntu-20.04-aws-osc-provisioning - namespace: cloud-init-settings + name: ubuntu-aws-kube-system-osc-provisioning + namespace: kube-system resourceVersion: "1" spec: cloudProvider: @@ -404,7 +404,7 @@ spec: permissions: 420 - content: inline: - data: '{"exec-opts":["native.cgroupdriver=systemd"],"storage-driver":"overlay2","log-driver":"json-file","log-opts":{"max-file":"5","max-size":"100m"}}' + data: '{"exec-opts":["native.cgroupdriver=systemd"],"storage-driver":"overlay2","log-driver":"json-file","log-opts":{"max-file":"5","max-size":"100m"},"insecure-registries":["192.168.100.100:5000","10.0.0.1:5000"],"registry-mirrors":["https://registry.docker-cn.com"]}' encoding: b64 path: /etc/docker/daemon.json permissions: 420 diff --git a/pkg/controllers/osc/testdata/osp-flatcar.yaml b/pkg/controllers/osc/testdata/osp-flatcar.yaml index f8780598..259bd358 100644 --- a/pkg/controllers/osc/testdata/osp-flatcar.yaml +++ b/pkg/controllers/osc/testdata/osp-flatcar.yaml @@ -16,11 +16,12 @@ apiVersion: operatingsystemmanager.k8c.io/v1alpha1 kind: OperatingSystemProfile metadata: name: osp-flatcar - namespace: cloud-init-settings + namespace: kube-system spec: osName: flatcar ## Flatcar Stable (09/11/2021) osVersion: "2983.2.0" + version: "v0.1.1" supportedCloudProviders: - name: aws - name: azure @@ -35,23 +36,7 @@ spec: content: inline: data: | - version = 2 - - [metrics] - address = "127.0.0.1:1338" - - [plugins] - [plugins."io.containerd.grpc.v1.cri"] - [plugins."io.containerd.grpc.v1.cri".containerd] - [plugins."io.containerd.grpc.v1.cri".containerd.runtimes] - [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc] - runtime_type = "io.containerd.runc.v2" - [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options] - SystemdCgroup = true - [plugins."io.containerd.grpc.v1.cri".registry] - [plugins."io.containerd.grpc.v1.cri".registry.mirrors] - [plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"] - endpoint = ["https://registry-1.docker.io"] + {{ .ContainerRuntimeConfig}} - path: /etc/systemd/system/containerd.service.d/10-custom.conf content: inline: @@ -76,7 +61,7 @@ spec: content: inline: data: |- - {"exec-opts":["native.cgroupdriver=systemd"],"storage-driver":"overlay2","log-driver":"json-file","log-opts":{"max-file":"5","max-size":"100m"}} + {{ .ContainerRuntimeConfig}} - path: /etc/systemd/system/docker.service.d/10-custom.conf permissions: 0644 content: @@ -133,6 +118,28 @@ spec: rm -f "$cni_filename" cd - + {{- /* # cri-tools variables */}} + CRI_TOOLS_RELEASE="${CRI_TOOLS_RELEASE:-v1.22.0}" + cri_tools_base_url="https://github.com/kubernetes-sigs/cri-tools/releases/download/${CRI_TOOLS_RELEASE}" + cri_tools_filename="crictl-${CRI_TOOLS_RELEASE}-linux-${arch}.tar.gz" + + {{- /* download cri-tools */}} + curl -Lfo "$opt_bin/$cri_tools_filename" "$cri_tools_base_url/$cri_tools_filename" + + {{- /* download cri-tools checksum */}} + {{- /* the cri-tools checksum file has a filename prefix that breaks sha256sum so we need to drop it with sed */}} + cri_tools_sum=$(curl -Lf "$cri_tools_base_url/$cri_tools_filename.sha256" | sed 's/\*\///') + cd "$opt_bin" + + {{- /* verify cri-tools checksum */}} + sha256sum -c <<<"$cri_tools_sum" + + {{- /* unpack cri-tools and symlink to path so it's available to all users */}} + tar xvf "$cri_tools_filename" + rm -f "$cri_tools_filename" + ln -sf "$opt_bin/crictl" "$usr_local_bin"/crictl || echo "symbolic link is skipped" + cd - + {{- /* kubelet */}} KUBE_VERSION="${KUBE_VERSION:-{{ .KubeVersion }}}" kube_dir="$opt_bin/kubernetes-$KUBE_VERSION" @@ -519,6 +526,19 @@ spec: - "{{ . }}" {{- end }} clusterDomain: cluster.local + {{- /* containerLogMaxSize and containerLogMaxFiles have no effect for docker */}} + {{- if ne .ContainerRuntime "docker" }} + {{- if .ContainerLogMaxSize }} + containerLogMaxSize: {{ .ContainerLogMaxSize }} + {{- else }} + containerLogMaxSize: 100Mi + {{- end }} + {{- if .ContainerLogMaxFiles }} + containerLogMaxFiles: {{ .ContainerLogMaxFiles }} + {{- else }} + containerLogMaxFiles: 5 + {{- end }} + {{- end }} featureGates: {{- if .KubeletFeatureGates -}} {{ range $key, $val := .KubeletFeatureGates }} diff --git a/pkg/controllers/osc/testdata/osp-rhel.yaml b/pkg/controllers/osc/testdata/osp-rhel.yaml index 1f035137..b89eee38 100644 --- a/pkg/controllers/osc/testdata/osp-rhel.yaml +++ b/pkg/controllers/osc/testdata/osp-rhel.yaml @@ -16,10 +16,11 @@ apiVersion: operatingsystemmanager.k8c.io/v1alpha1 kind: OperatingSystemProfile metadata: name: osp-rhel - namespace: cloud-init-settings + namespace: kube-system spec: osName: "rhel" osVersion: "8.4" + version: "v0.1.1" supportedCloudProviders: - name: "aws" - name: "azure" @@ -35,23 +36,7 @@ spec: inline: encoding: b64 data: | - version = 2 - - [metrics] - address = "127.0.0.1:1338" - - [plugins] - [plugins."io.containerd.grpc.v1.cri"] - [plugins."io.containerd.grpc.v1.cri".containerd] - [plugins."io.containerd.grpc.v1.cri".containerd.runtimes] - [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc] - runtime_type = "io.containerd.runc.v2" - [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options] - SystemdCgroup = true - [plugins."io.containerd.grpc.v1.cri".registry] - [plugins."io.containerd.grpc.v1.cri".registry.mirrors] - [plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"] - endpoint = ["https://registry-1.docker.io"] + {{ .ContainerRuntimeConfig}} templates: containerRuntimeInstallation: |- yum install -y yum-utils @@ -87,7 +72,7 @@ spec: inline: encoding: b64 data: |- - {"exec-opts":["native.cgroupdriver=systemd"],"storage-driver":"overlay2","log-driver":"json-file","log-opts":{"max-file":"5","max-size":"10m"}} + {{ .ContainerRuntimeConfig}} templates: containerRuntimeInstallation: |- yum install -y yum-utils @@ -116,6 +101,7 @@ spec: safeDownloadBinariesScript: |- {{- /*setup some common directories */ -}} opt_bin=/opt/bin + usr_local_bin=/usr/local/bin cni_bin_dir=/opt/cni/bin {{- /* create all the necessary dirs */}} @@ -159,6 +145,28 @@ spec: rm -f "$cni_filename" cd - + {{- /* # cri-tools variables */}} + CRI_TOOLS_RELEASE="${CRI_TOOLS_RELEASE:-v1.22.0}" + cri_tools_base_url="https://github.com/kubernetes-sigs/cri-tools/releases/download/${CRI_TOOLS_RELEASE}" + cri_tools_filename="crictl-${CRI_TOOLS_RELEASE}-linux-${arch}.tar.gz" + + {{- /* download cri-tools */}} + curl -Lfo "$opt_bin/$cri_tools_filename" "$cri_tools_base_url/$cri_tools_filename" + + {{- /* download cri-tools checksum */}} + {{- /* the cri-tools checksum file has a filename prefix that breaks sha256sum so we need to drop it with sed */}} + cri_tools_sum=$(curl -Lf "$cri_tools_base_url/$cri_tools_filename.sha256" | sed 's/\*\///') + cd "$opt_bin" + + {{- /* verify cri-tools checksum */}} + sha256sum -c <<<"$cri_tools_sum" + + {{- /* unpack cri-tools and symlink to path so it's available to all users */}} + tar xvf "$cri_tools_filename" + rm -f "$cri_tools_filename" + ln -sf "$opt_bin/crictl" "$usr_local_bin"/crictl || echo "symbolic link is skipped" + cd - + {{- /* kubelet */}} KUBE_VERSION="${KUBE_VERSION:-{{ .KubeVersion }}}" kube_dir="$opt_bin/kubernetes-$KUBE_VERSION" @@ -265,8 +273,6 @@ spec: # mls - Multi Level Security protection. SELINUXTYPE=targeted - - - path: "/opt/bin/setup" permissions: 0755 content: @@ -309,8 +315,16 @@ spec: {{- if eq .CloudProviderName "vsphere" }} open-vm-tools \ {{- end }} + {{- if eq .CloudProviderName "nutanix" }} + iscsi-initiator-utils \ + {{- end }} ipvsadm + {{- /* iscsid service is required on Nutanix machines for CSI driver to attach volumes. */}} + {{- if eq .CloudProviderName "nutanix" }} + systemctl enable --now iscsid + {{ end }} + {{- template "containerRuntimeInstallation" }} {{- template "safeDownloadBinariesScript" }} @@ -501,6 +515,19 @@ spec: - "{{ . }}" {{- end }} clusterDomain: cluster.local + {{- /* containerLogMaxSize and containerLogMaxFiles have no effect for docker */}} + {{- if ne .ContainerRuntime "docker" }} + {{- if .ContainerLogMaxSize }} + containerLogMaxSize: {{ .ContainerLogMaxSize }} + {{- else }} + containerLogMaxSize: 100Mi + {{- end }} + {{- if .ContainerLogMaxFiles }} + containerLogMaxFiles: {{ .ContainerLogMaxFiles }} + {{- else }} + containerLogMaxFiles: 5 + {{- end }} + {{- end }} featureGates: {{- if .KubeletFeatureGates -}} {{ range $key, $val := .KubeletFeatureGates }} @@ -572,4 +599,4 @@ spec: WantedBy=multi-user.target modules: bootcmd: - - modprobe ip_tables \ No newline at end of file + - modprobe ip_tables diff --git a/pkg/controllers/osc/testdata/osp-ubuntu-20.04.yaml b/pkg/controllers/osc/testdata/osp-ubuntu.yaml similarity index 94% rename from pkg/controllers/osc/testdata/osp-ubuntu-20.04.yaml rename to pkg/controllers/osc/testdata/osp-ubuntu.yaml index 38fc2806..70b1f884 100644 --- a/pkg/controllers/osc/testdata/osp-ubuntu-20.04.yaml +++ b/pkg/controllers/osc/testdata/osp-ubuntu.yaml @@ -16,7 +16,7 @@ apiVersion: operatingsystemmanager.k8c.io/v1alpha1 kind: OperatingSystemProfile metadata: name: osp-ubuntu - namespace: cloud-init-settings + namespace: kube-system spec: osName: "ubuntu" osVersion: "20.04" @@ -43,23 +43,7 @@ spec: inline: encoding: b64 data: | - version = 2 - - [metrics] - address = "127.0.0.1:1338" - - [plugins] - [plugins."io.containerd.grpc.v1.cri"] - [plugins."io.containerd.grpc.v1.cri".containerd] - [plugins."io.containerd.grpc.v1.cri".containerd.runtimes] - [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc] - runtime_type = "io.containerd.runc.v2" - [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options] - SystemdCgroup = true - [plugins."io.containerd.grpc.v1.cri".registry] - [plugins."io.containerd.grpc.v1.cri".registry.mirrors] - [plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"] - endpoint = ["https://registry-1.docker.io"] + {{ .ContainerRuntimeConfig}} templates: containerRuntimeInstallation: |- apt-get update @@ -92,7 +76,7 @@ spec: inline: encoding: b64 data: |- - {"exec-opts":["native.cgroupdriver=systemd"],"storage-driver":"overlay2","log-driver":"json-file","log-opts":{"max-file":"5","max-size":"100m"}} + {{ .ContainerRuntimeConfig}} templates: containerRuntimeInstallation: |- apt-get update @@ -505,6 +489,19 @@ spec: - "{{ . }}" {{- end }} clusterDomain: cluster.local + {{- /* containerLogMaxSize and containerLogMaxFiles have no effect for docker */}} + {{- if ne .ContainerRuntime "docker" }} + {{- if .ContainerLogMaxSize }} + containerLogMaxSize: {{ .ContainerLogMaxSize }} + {{- else }} + containerLogMaxSize: 100Mi + {{- end }} + {{- if .ContainerLogMaxFiles }} + containerLogMaxFiles: {{ .ContainerLogMaxFiles }} + {{- else }} + containerLogMaxFiles: 5 + {{- end }} + {{- end }} featureGates: {{- if .KubeletFeatureGates -}} {{ range $key, $val := .KubeletFeatureGates }} diff --git a/pkg/controllers/osc/testdata/secret-flatcar-aws-containerd.yaml b/pkg/controllers/osc/testdata/secret-flatcar-aws-containerd.yaml index e541d553..de175b63 100644 --- a/pkg/controllers/osc/testdata/secret-flatcar-aws-containerd.yaml +++ b/pkg/controllers/osc/testdata/secret-flatcar-aws-containerd.yaml @@ -1,10 +1,11 @@ apiVersion: v1 data: - cloud-config: eyJpZ25pdGlvbiI6eyJjb25maWciOnt9LCJzZWN1cml0eSI6eyJ0bHMiOnt9fSwidGltZW91dHMiOnt9LCJ2ZXJzaW9uIjoiMi4zLjAifSwibmV0d29ya2QiOnt9LCJwYXNzd2QiOnsidXNlcnMiOlt7Im5hbWUiOiJjb3JlIiwic3NoQXV0aG9yaXplZEtleXMiOlsic3NoLXJzYSBBQUFBQjNOemFDMXljMkVBQUFBREFRQUJBQUFDQVFEZE9JaFltekNLNURTVkx1M2MiXX1dfSwic3RvcmFnZSI6eyJmaWxlcyI6W3siZmlsZXN5c3RlbSI6InJvb3QiLCJwYXRoIjoiL2V0Yy9zeXN0ZW1kL2pvdXJuYWxkLmNvbmYuZC9tYXhfZGlza191c2UuY29uZiIsImNvbnRlbnRzIjp7InNvdXJjZSI6ImRhdGE6LCU1QkpvdXJuYWwlNUQlMEFTeXN0ZW1NYXhVc2UlM0Q1RyUwQSIsInZlcmlmaWNhdGlvbiI6e319LCJtb2RlIjo0MjB9LHsiZmlsZXN5c3RlbSI6InJvb3QiLCJwYXRoIjoiL29wdC9sb2FkLWtlcm5lbC1tb2R1bGVzLnNoIiwiY29udGVudHMiOnsic291cmNlIjoiZGF0YTosJTIzISUyRnVzciUyRmJpbiUyRmVudiUyMGJhc2glMEFzZXQlMjAtZXVvJTIwcGlwZWZhaWwlMEElMEFtb2Rwcm9iZSUyMGlwX3ZzJTBBbW9kcHJvYmUlMjBpcF92c19yciUwQW1vZHByb2JlJTIwaXBfdnNfd3JyJTBBbW9kcHJvYmUlMjBpcF92c19zaCUwQSUwQWlmJTIwbW9kaW5mbyUyMG5mX2Nvbm50cmFja19pcHY0JTIwJTI2JTNFJTIwJTJGZGV2JTJGbnVsbCUzQiUyMHRoZW4lMEElMjAlMjBtb2Rwcm9iZSUyMG5mX2Nvbm50cmFja19pcHY0JTBBZWxzZSUwQSUyMCUyMG1vZHByb2JlJTIwbmZfY29ubnRyYWNrJTBBZmklMEEiLCJ2ZXJpZmljYXRpb24iOnt9fSwibW9kZSI6NDkzfSx7ImZpbGVzeXN0ZW0iOiJyb290IiwicGF0aCI6Ii9ldGMvc3lzY3RsLmQvazhzLmNvbmYiLCJjb250ZW50cyI6eyJzb3VyY2UiOiJkYXRhOixuZXQuYnJpZGdlLmJyaWRnZS1uZi1jYWxsLWlwNnRhYmxlcyUyMCUzRCUyMDElMEFuZXQuYnJpZGdlLmJyaWRnZS1uZi1jYWxsLWlwdGFibGVzJTIwJTNEJTIwMSUwQWtlcm5lbC5wYW5pY19vbl9vb3BzJTIwJTNEJTIwMSUwQWtlcm5lbC5wYW5pYyUyMCUzRCUyMDEwJTBBbmV0LmlwdjQuaXBfZm9yd2FyZCUyMCUzRCUyMDElMEF2bS5vdmVyY29tbWl0X21lbW9yeSUyMCUzRCUyMDElMEFmcy5pbm90aWZ5Lm1heF91c2VyX3dhdGNoZXMlMjAlM0QlMjAxMDQ4NTc2JTBBIiwidmVyaWZpY2F0aW9uIjp7fX0sIm1vZGUiOjQyMH0seyJmaWxlc3lzdGVtIjoicm9vdCIsInBhdGgiOiIvb3B0L2Jpbi9zZXR1cF9uZXRfZW52LnNoIiwiY29udGVudHMiOnsic291cmNlIjoiZGF0YTosJTIzISUyRnVzciUyRmJpbiUyRmVudiUyMGJhc2glMEFlY2hvZGF0ZSgpJTIwJTdCJTBBJTIwJTIwZWNobyUyMCUyMiU1QiUyNChkYXRlJTIwLUlzKSU1RCUyMiUyMCUyMiUyNCU0MCUyMiUwQSU3RCUwQSUwQSUyMyUyMGdldCUyMHRoZSUyMGRlZmF1bHQlMjBpbnRlcmZhY2UlMjBJUCUyMGFkZHJlc3MlMEFERUZBVUxUX0lGQ19JUCUzRCUyNChpcCUyMC1vJTIwJTIwcm91dGUlMjBnZXQlMjAxJTIwJTdDJTIwZ3JlcCUyMC1vUCUyMCUyMnNyYyUyMCU1Q0slNUNTJTJCJTIyKSUwQSUwQWlmJTIwJTVCJTIwLXolMjAlMjIlMjQlN0JERUZBVUxUX0lGQ19JUCU3RCUyMiUyMCU1RCUwQXRoZW4lMEElMjAlMjBlY2hvZGF0ZSUyMCUyMkZhaWxlZCUyMHRvJTIwZ2V0JTIwSVAlMjBhZGRyZXNzJTIwZm9yJTIwdGhlJTIwZGVmYXVsdCUyMHJvdXRlJTIwaW50ZXJmYWNlJTIyJTBBJTIwJTIwZXhpdCUyMDElMEFmaSUwQSUwQSUyMyUyMGdldCUyMHRoZSUyMGZ1bGwlMjBob3N0bmFtZSUwQUZVTExfSE9TVE5BTUUlM0QlMjQoaG9zdG5hbWUlMjAtZiklMEElMjMlMjBpZiUyMCUyRmV0YyUyRmhvc3RuYW1lJTIwaXMlMjBub3QlMjBlbXB0eSUyMHRoZW4lMjB1c2UlMjB0aGUlMjBob3N0bmFtZSUyMGZyb20lMjB0aGVyZSUwQWlmJTIwJTVCJTIwLXMlMjAlMkZldGMlMkZob3N0bmFtZSUyMCU1RCUzQiUyMHRoZW4lMEElMjAlMjAlMjAlMjBGVUxMX0hPU1ROQU1FJTNEJTI0KGNhdCUyMCUyRmV0YyUyRmhvc3RuYW1lKSUwQWZpJTBBJTBBJTIzJTIwd3JpdGUlMjB0aGUlMjBub2RlaXBfZW52JTIwZmlsZSUwQSUyMyUyMHdlJTIwbmVlZCUyMHRoZSUyMGxpbmUlMjBiZWxvdyUyMGJlY2F1c2UlMjBmbGF0Y2FyJTIwaGFzJTIwdGhlJTIwc2FtZSUyMHN0cmluZyUyMCUyMmNvcmVvcyUyMiUyMGluJTIwdGhhdCUyMGZpbGUlMEFpZiUyMGdyZXAlMjAtcSUyMGNvcmVvcyUyMCUyRmV0YyUyRm9zLXJlbGVhc2UlMEF0aGVuJTBBJTIwJTIwZWNobyUyMC1lJTIwJTIyS1VCRUxFVF9OT0RFX0lQJTNEJTI0JTdCREVGQVVMVF9JRkNfSVAlN0QlNUNuS1VCRUxFVF9IT1NUTkFNRSUzRCUyNCU3QkZVTExfSE9TVE5BTUUlN0QlMjIlMjAlM0UlMjAlMkZldGMlMkZrdWJlcm5ldGVzJTJGbm9kZWlwLmNvbmYlMEFlbGlmJTIwJTVCJTIwISUyMC1kJTIwJTJGZXRjJTJGc3lzdGVtZCUyRnN5c3RlbSUyRmt1YmVsZXQuc2VydmljZS5kJTIwJTVEJTBBdGhlbiUwQSUyMCUyMGVjaG9kYXRlJTIwJTIyQ2FuJ3QlMjBmaW5kJTIwa3ViZWxldCUyMHNlcnZpY2UlMjBleHRyYXMlMjBkaXJlY3RvcnklMjIlMEElMjAlMjBleGl0JTIwMSUwQWVsc2UlMEElMjAlMjBlY2hvJTIwLWUlMjAlMjIlNUJTZXJ2aWNlJTVEJTVDbkVudmlyb25tZW50JTNEJTVDJTIyS1VCRUxFVF9OT0RFX0lQJTNEJTI0JTdCREVGQVVMVF9JRkNfSVAlN0QlNUMlMjIlNUNuRW52aXJvbm1lbnQlM0QlNUMlMjJLVUJFTEVUX0hPU1ROQU1FJTNEJTI0JTdCRlVMTF9IT1NUTkFNRSU3RCU1QyUyMiUyMiUyMCUzRSUyMCUyRmV0YyUyRnN5c3RlbWQlMkZzeXN0ZW0lMkZrdWJlbGV0LnNlcnZpY2UuZCUyRm5vZGVpcC5jb25mJTBBZmklMEEiLCJ2ZXJpZmljYXRpb24iOnt9fSwibW9kZSI6NDkzfSx7ImZpbGVzeXN0ZW0iOiJyb290IiwicGF0aCI6Ii9vcHQvYmluL2NvbmZpZ3VyZV9zdGF0aWNfbmV0d29yay5zaCIsImNvbnRlbnRzIjp7InNvdXJjZSI6ImRhdGE6LCUyMyElMkZ1c3IlMkZiaW4lMkZlbnYlMjBiYXNoJTBBc2V0JTIwLXhldW8lMjBwaXBlZmFpbCUwQSIsInZlcmlmaWNhdGlvbiI6e319LCJtb2RlIjo0OTN9LHsiZmlsZXN5c3RlbSI6InJvb3QiLCJwYXRoIjoiL29wdC9iaW4vZG93bmxvYWQuc2giLCJjb250ZW50cyI6eyJzb3VyY2UiOiJkYXRhOiwlMjMhJTJGdXNyJTJGYmluJTJGZW52JTIwYmFzaCUwQXNldCUyMC14ZXVvJTIwcGlwZWZhaWwlMEFvcHRfYmluJTNEJTJGb3B0JTJGYmluJTBBdXNyX2xvY2FsX2JpbiUzRCUyRnVzciUyRmxvY2FsJTJGYmluJTBBY25pX2Jpbl9kaXIlM0QlMkZvcHQlMkZjbmklMkZiaW4lMEFta2RpciUyMC1wJTIwJTJGZXRjJTJGY25pJTJGbmV0LmQlMjAlMkZldGMlMkZrdWJlcm5ldGVzJTJGZHluYW1pYy1jb25maWctZGlyJTIwJTJGZXRjJTJGa3ViZXJuZXRlcyUyRm1hbmlmZXN0cyUyMCUyMiUyNG9wdF9iaW4lMjIlMjAlMjIlMjRjbmlfYmluX2RpciUyMiUwQWFyY2glM0QlMjQlN0JIT1NUX0FSQ0gtJTdEJTBBaWYlMjAlNUIlMjAteiUyMCUyMiUyNGFyY2glMjIlMjAlNUQlMEF0aGVuJTBBY2FzZSUyMCUyNCh1bmFtZSUyMC1tKSUyMGluJTBBeDg2XzY0KSUwQSUyMCUyMCUyMCUyMGFyY2glM0QlMjJhbWQ2NCUyMiUwQSUyMCUyMCUyMCUyMCUzQiUzQiUwQWFhcmNoNjQpJTBBJTIwJTIwJTIwJTIwYXJjaCUzRCUyMmFybTY0JTIyJTBBJTIwJTIwJTIwJTIwJTNCJTNCJTBBKiklMEElMjAlMjAlMjAlMjBlY2hvJTIwJTIydW5zdXBwb3J0ZWQlMjBDUFUlMjBhcmNoaXRlY3R1cmUlMkMlMjBleGl0aW5nJTIyJTBBJTIwJTIwJTIwJTIwZXhpdCUyMDElMEElMjAlMjAlMjAlMjAlM0IlM0IlMEFlc2FjJTBBZmklMEFDTklfVkVSU0lPTiUzRCUyMiUyNCU3QkNOSV9WRVJTSU9OJTNBLXYwLjguNyU3RCUyMiUwQWNuaV9iYXNlX3VybCUzRCUyMmh0dHBzJTNBJTJGJTJGZ2l0aHViLmNvbSUyRmNvbnRhaW5lcm5ldHdvcmtpbmclMkZwbHVnaW5zJTJGcmVsZWFzZXMlMkZkb3dubG9hZCUyRiUyNENOSV9WRVJTSU9OJTIyJTBBY25pX2ZpbGVuYW1lJTNEJTIyY25pLXBsdWdpbnMtbGludXgtJTI0YXJjaC0lMjRDTklfVkVSU0lPTi50Z3olMjIlMEFjdXJsJTIwLUxmbyUyMCUyMiUyNGNuaV9iaW5fZGlyJTJGJTI0Y25pX2ZpbGVuYW1lJTIyJTIwJTIyJTI0Y25pX2Jhc2VfdXJsJTJGJTI0Y25pX2ZpbGVuYW1lJTIyJTBBY25pX3N1bSUzRCUyNChjdXJsJTIwLUxmJTIwJTIyJTI0Y25pX2Jhc2VfdXJsJTJGJTI0Y25pX2ZpbGVuYW1lLnNoYTI1NiUyMiklMEFjZCUyMCUyMiUyNGNuaV9iaW5fZGlyJTIyJTBBc2hhMjU2c3VtJTIwLWMlMjAlM0MlM0MlM0MlMjIlMjRjbmlfc3VtJTIyJTBBdGFyJTIweHZmJTIwJTIyJTI0Y25pX2ZpbGVuYW1lJTIyJTBBcm0lMjAtZiUyMCUyMiUyNGNuaV9maWxlbmFtZSUyMiUwQWNkJTIwLSUwQUtVQkVfVkVSU0lPTiUzRCUyMiUyNCU3QktVQkVfVkVSU0lPTiUzQS12MS4yMi4xJTdEJTIyJTBBa3ViZV9kaXIlM0QlMjIlMjRvcHRfYmluJTJGa3ViZXJuZXRlcy0lMjRLVUJFX1ZFUlNJT04lMjIlMEFrdWJlX2Jhc2VfdXJsJTNEJTIyaHR0cHMlM0ElMkYlMkZzdG9yYWdlLmdvb2dsZWFwaXMuY29tJTJGa3ViZXJuZXRlcy1yZWxlYXNlJTJGcmVsZWFzZSUyRiUyNEtVQkVfVkVSU0lPTiUyRmJpbiUyRmxpbnV4JTJGJTI0YXJjaCUyMiUwQWt1YmVfc3VtX2ZpbGUlM0QlMjIlMjRrdWJlX2RpciUyRnNoYTI1NiUyMiUwQW1rZGlyJTIwLXAlMjAlMjIlMjRrdWJlX2RpciUyMiUwQSUzQSUyMCUzRSUyMiUyNGt1YmVfc3VtX2ZpbGUlMjIlMEElMEFmb3IlMjBiaW4lMjBpbiUyMGt1YmVsZXQlMjBrdWJlYWRtJTIwa3ViZWN0bCUzQiUyMGRvJTBBJTIwJTIwJTIwJTIwY3VybCUyMC1MZm8lMjAlMjIlMjRrdWJlX2RpciUyRiUyNGJpbiUyMiUyMCUyMiUyNGt1YmVfYmFzZV91cmwlMkYlMjRiaW4lMjIlMEElMjAlMjAlMjAlMjBjaG1vZCUyMCUyQnglMjAlMjIlMjRrdWJlX2RpciUyRiUyNGJpbiUyMiUwQSUyMCUyMCUyMCUyMHN1bSUzRCUyNChjdXJsJTIwLUxmJTIwJTIyJTI0a3ViZV9iYXNlX3VybCUyRiUyNGJpbi5zaGEyNTYlMjIpJTBBJTIwJTIwJTIwJTIwZWNobyUyMCUyMiUyNHN1bSUyMCUyMCUyNGt1YmVfZGlyJTJGJTI0YmluJTIyJTIwJTNFJTNFJTIyJTI0a3ViZV9zdW1fZmlsZSUyMiUwQWRvbmUlMEFzaGEyNTZzdW0lMjAtYyUyMCUyMiUyNGt1YmVfc3VtX2ZpbGUlMjIlMEElMEFmb3IlMjBiaW4lMjBpbiUyMGt1YmVsZXQlMjBrdWJlYWRtJTIwa3ViZWN0bCUzQiUyMGRvJTBBJTIwJTIwJTIwJTIwbG4lMjAtc2YlMjAlMjIlMjRrdWJlX2RpciUyRiUyNGJpbiUyMiUyMCUyMiUyNG9wdF9iaW4lMjIlMkYlMjRiaW4lMEFkb25lJTBBJTBBaWYlMjAlNUIlNUIlMjAhJTIwLXglMjAlMkZvcHQlMkZiaW4lMkZoZWFsdGgtbW9uaXRvci5zaCUyMCU1RCU1RCUzQiUyMHRoZW4lMEElMjAlMjAlMjAlMjBjdXJsJTIwLUxmbyUyMCUyRm9wdCUyRmJpbiUyRmhlYWx0aC1tb25pdG9yLnNoJTIwaHR0cHMlM0ElMkYlMkZyYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tJTJGa3ViZXJtYXRpYyUyRm1hY2hpbmUtY29udHJvbGxlciUyRjc5NjdhMGFmMmI3NWYyOWFkMmFiMjI3ZWVhYTI2ZWE3YjBmMmZiZGUlMkZwa2clMkZ1c2VyZGF0YSUyRnNjcmlwdHMlMkZoZWFsdGgtbW9uaXRvci5zaCUwQSUyMCUyMCUyMCUyMGNobW9kJTIwJTJCeCUyMCUyRm9wdCUyRmJpbiUyRmhlYWx0aC1tb25pdG9yLnNoJTBBZmklMEElMEFzeXN0ZW1jdGwlMjBkaXNhYmxlJTIwZG93bmxvYWQtc2NyaXB0LnNlcnZpY2UlMEEiLCJ2ZXJpZmljYXRpb24iOnt9fSwibW9kZSI6NDkzfSx7ImZpbGVzeXN0ZW0iOiJyb290IiwicGF0aCI6Ii9vcHQvYmluL3NldHVwIiwiY29udGVudHMiOnsic291cmNlIjoiZGF0YTosJTIzISUyRmJpbiUyRmJhc2glMEFzZXQlMjAteGV1byUyMHBpcGVmYWlsJTBBY2F0JTIwJTNDJTNDJTIwRU9GJTIwJTdDJTIwdGVlJTIwJTJGZXRjJTJGcG9sa2l0LTElMkZydWxlcy5kJTJGNjAtbm9yZWJvb3Rfbm9yZXN0YXJ0LnJ1bGVzJTBBcG9sa2l0LmFkZFJ1bGUoZnVuY3Rpb24oYWN0aW9uJTJDJTIwc3ViamVjdCklMjAlN0IlMEElMjAlMjBpZiUyMChhY3Rpb24uaWQlMjAlM0QlM0QlMjAlMjJvcmcuZnJlZWRlc2t0b3AubG9naW4xLnJlYm9vdCUyMiUyMCU3QyU3QyUwQSUyMCUyMCUyMCUyMCUyMCUyMGFjdGlvbi5pZCUyMCUzRCUzRCUyMCUyMm9yZy5mcmVlZGVza3RvcC5sb2dpbjEucmVib290LW11bHRpcGxlLXNlc3Npb25zJTIyKSUyMCU3QiUwQSUyMCUyMCUyMCUyMCUyMCUyMGlmJTIwKHN1YmplY3QudXNlciUyMCUzRCUzRCUyMCUyMmNvcmUlMjIpJTIwJTdCJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwcmV0dXJuJTIwcG9sa2l0LlJlc3VsdC5ZRVMlM0IlMEElMjAlMjAlMjAlMjAlMjAlMjAlN0QlMjBlbHNlJTIwJTdCJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwcmV0dXJuJTIwcG9sa2l0LlJlc3VsdC5BVVRIX0FETUlOJTNCJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTdEJTBBJTIwJTIwJTdEJTBBJTdEKSUzQiUwQUVPRiUwQXN5c3RlbWN0bCUyMHN0b3AlMjBkb2NrZXIlMEFzeXN0ZW1jdGwlMjBkaXNhYmxlJTIwZG9ja2VyJTBBJTBBc3lzdGVtY3RsJTIwZW5hYmxlJTIwLS1ub3clMjBrdWJlbGV0JTBBc3lzdGVtY3RsJTIwZW5hYmxlJTIwLS1ub3clMjAtLW5vLWJsb2NrJTIwa3ViZWxldC1oZWFsdGhjaGVjay5zZXJ2aWNlJTBBc3lzdGVtY3RsJTIwZGlzYWJsZSUyMHNldHVwLnNlcnZpY2UlMEEiLCJ2ZXJpZmljYXRpb24iOnt9fSwibW9kZSI6NDkzfSx7ImZpbGVzeXN0ZW0iOiJyb290IiwicGF0aCI6Ii9ldGMva3ViZXJuZXRlcy9wa2kvY2EuY3J0IiwiY29udGVudHMiOnsic291cmNlIjoiZGF0YTosLS0tLS1CRUdJTiUyMENFUlRJRklDQVRFLS0tLS0lMEFNSUlFV2pDQ0EwS2dBd0lCQWdJSkFMZlJsV3NJOFlRSE1BMEdDU3FHU0liM0RRRUJCUVVBTUhzeEN6QUpCZ05WJTBBQkFZVEFsVlRNUXN3Q1FZRFZRUUlFd0pEUVRFV01CUUdBMVVFQnhNTlUyRnVJRVp5WVc1amFYTmpiekVVTUJJRyUwQUExVUVDaE1MUW5KaFpHWnBkSHBwYm1NeEVqQVFCZ05WQkFNVENXeHZZMkZzYUc5emRERWRNQnNHQ1NxR1NJYjMlMEFEUUVKQVJZT1luSmhaRUJrWVc1bllTNWpiMjB3SGhjTk1UUXdOekUxTWpBME5qQTFXaGNOTVRjd05UQTBNakEwJTBBTmpBMVdqQjdNUXN3Q1FZRFZRUUdFd0pWVXpFTE1Ba0dBMVVFQ0JNQ1EwRXhGakFVQmdOVkJBY1REVk5oYmlCRyUwQWNtRnVZMmx6WTI4eEZEQVNCZ05WQkFvVEMwSnlZV1JtYVhSNmFXNWpNUkl3RUFZRFZRUURFd2xzYjJOaGJHaHYlMEFjM1F4SFRBYkJna3Foa2lHOXcwQkNRRVdEbUp5WVdSQVpHRnVaMkV1WTI5dE1JSUJJakFOQmdrcWhraUc5dzBCJTBBQVFFRkFBT0NBUThBTUlJQkNnS0NBUUVBdDVmQWpwNGZUY2VrV1VUZnpzcDBreWloMU9ZYnNHTDBLWDFlUmJTUyUwQVI4T2QwJTJCOVE2Mkh5bnklMkJHRndNVGI0QSUyRktVOG1zc29IdmNjZVNBQWJ3ZmJ4RkslMkYlMkJzNTFUb2JxVW5PUlpyT29UJTBBWmprVXlnYnlYRFNLOTlZQmJjUjFQaXA4dndNVG00WEt1THRDaWdlQkJkampBUWRnVU8yOExFTkdsc01ubWVZayUwQUpmT0RWR25WbXI1THRiOUFOQThJS3lUZnNuSEo0aU9DUyUyRlBsUGJVajJxN1lub1ZMcG9zVUJNbGdVYiUyRkN5a1gzJTBBbU9vTGI0eUpKUXlBJTJGaVNUNlp4aUlFajM2RDR5V1o1bGc3WUpsJTJCVWlpQlFIR0NuUGRHeWlwcVYwNmV4MGhlWVclMEFjYWlXOExXWlNVUTkzalElMkJXVkNIOGhUN0RRTzFkbXN2VW1YbHElMkZKZUFsd1ElMkZRSURBUUFCbzRIZ01JSGRNQjBHJTBBQTFVZERnUVdCQlJjQVJPdGhTNFA0VTd2VGZqQnlDNTY5UjdFNkRDQnJRWURWUjBqQklHbE1JR2lnQlJjQVJPdCUwQWhTNFA0VTd2VGZqQnlDNTY5UjdFNktGJTJGcEgwd2V6RUxNQWtHQTFVRUJoTUNWVk14Q3pBSkJnTlZCQWdUQWtOQiUwQU1SWXdGQVlEVlFRSEV3MVRZVzRnUm5KaGJtTnBjMk52TVJRd0VnWURWUVFLRXd0Q2NtRmtabWwwZW1sdVl6RVMlMEFNQkFHQTFVRUF4TUpiRzlqWVd4b2IzTjBNUjB3R3dZSktvWklodmNOQVFrQkZnNWljbUZrUUdSaGJtZGhMbU52JTBBYllJSkFMZlJsV3NJOFlRSE1Bd0dBMVVkRXdRRk1BTUJBZjh3RFFZSktvWklodmNOQVFFRkJRQURnZ0VCQUc2aCUwQVU5ZjlzTkgwJTJGNm9CYkdHeTJFVlUwVWdJVFVRSXJGV285ckZrclc1ayUyRlhrRGpRbSUyQjNsempUMGlHUjRJeEUlMkZBbyUwQWVVNnNRaHVhN3dyV2VGRW40N0dMOThsbkNzSmREN29aTmhGbVE5NVRiJTJGTG5EVWpzNVlqOWJyUDBOV3pYZllVNCUwQVVLMlpuSU5KUmNKcEI4aVJDYUN4RThEZGNVRjBYcUlFcTZwQTI3MnNub0xtaVhMTXZObDNrWUVkbSUyQmplNnZvRCUwQTU4U05WRVVzenR6UXlYbUpFaENwd1ZJMEE2UUNqelhqJTJCcXZwbXczWlpIaThKd1hlaThaWkJMVFNGQmtpOFo3biUwQXNIOUJCSDM4JTJGU3pVbUFONFFIU1B5MWdqcW0wME9BRThOYVlEa2glMkZiekU0ZDdtTEdHTVdwJTJGV0UzS1BTdTgySEYlMEFrUGU2WG9TYmlMbSUyRmt4azMyVDAlM0QlMEEtLS0tLUVORCUyMENFUlRJRklDQVRFLS0tLS0lMEEiLCJ2ZXJpZmljYXRpb24iOnt9fSwibW9kZSI6NDIwfSx7ImZpbGVzeXN0ZW0iOiJyb290IiwicGF0aCI6Ii9ldGMvc3lzdGVtZC9zeXN0ZW0va3ViZWxldC5zZXJ2aWNlIiwiY29udGVudHMiOnsic291cmNlIjoiZGF0YTosJTVCVW5pdCU1RCUwQUFmdGVyJTNEY29udGFpbmVyZC5zZXJ2aWNlJTBBUmVxdWlyZXMlM0Rjb250YWluZXJkLnNlcnZpY2UlMEElMEFEZXNjcmlwdGlvbiUzRGt1YmVsZXQlM0ElMjBUaGUlMjBLdWJlcm5ldGVzJTIwTm9kZSUyMEFnZW50JTBBRG9jdW1lbnRhdGlvbiUzRGh0dHBzJTNBJTJGJTJGa3ViZXJuZXRlcy5pbyUyRmRvY3MlMkZob21lJTJGJTBBJTBBJTVCU2VydmljZSU1RCUwQVJlc3RhcnQlM0RhbHdheXMlMEFTdGFydExpbWl0SW50ZXJ2YWwlM0QwJTBBUmVzdGFydFNlYyUzRDEwJTBBQ1BVQWNjb3VudGluZyUzRHRydWUlMEFNZW1vcnlBY2NvdW50aW5nJTNEdHJ1ZSUwQSUwQUVudmlyb25tZW50JTNEJTIyUEFUSCUzRCUyRm9wdCUyRmJpbiUzQSUyRmJpbiUzQSUyRnVzciUyRmxvY2FsJTJGc2JpbiUzQSUyRnVzciUyRmxvY2FsJTJGYmluJTNBJTJGdXNyJTJGc2JpbiUzQSUyRnVzciUyRmJpbiUzQSUyRnNiaW4lMkYlMjIlMEFFbnZpcm9ubWVudEZpbGUlM0QtJTJGZXRjJTJGZW52aXJvbm1lbnQlMEFFbnZpcm9ubWVudEZpbGUlM0QlMkZldGMlMkZrdWJlcm5ldGVzJTJGbm9kZWlwLmNvbmYlMEElMEFFeGVjU3RhcnRQcmUlM0QlMkZiaW4lMkZiYXNoJTIwJTJGb3B0JTJGbG9hZC1rZXJuZWwtbW9kdWxlcy5zaCUwQUV4ZWNTdGFydFByZSUzRCUyRmJpbiUyRmJhc2glMjAlMkZvcHQlMkZiaW4lMkZzZXR1cF9uZXRfZW52LnNoJTBBRXhlY1N0YXJ0JTNEJTJGb3B0JTJGYmluJTJGa3ViZWxldCUyMCUyNEtVQkVMRVRfRVhUUkFfQVJHUyUyMCU1QyUwQSUyMCUyMC0tYm9vdHN0cmFwLWt1YmVjb25maWclM0QlMkZldGMlMkZrdWJlcm5ldGVzJTJGYm9vdHN0cmFwLWt1YmVsZXQuY29uZiUyMCU1QyUwQSUyMCUyMC0ta3ViZWNvbmZpZyUzRCUyRnZhciUyRmxpYiUyRmt1YmVsZXQlMkZrdWJlY29uZmlnJTIwJTVDJTBBJTIwJTIwLS1jb25maWclM0QlMkZldGMlMkZrdWJlcm5ldGVzJTJGa3ViZWxldC5jb25mJTIwJTVDJTBBJTIwJTIwLS1uZXR3b3JrLXBsdWdpbiUzRGNuaSUyMCU1QyUwQSUyMCUyMC0tY2VydC1kaXIlM0QlMkZldGMlMkZrdWJlcm5ldGVzJTJGcGtpJTIwJTVDJTBBJTIwJTIwLS1jbG91ZC1wcm92aWRlciUzRGF3cyUyMCU1QyUwQSUyMCUyMC0tY2xvdWQtY29uZmlnJTNEJTJGZXRjJTJGa3ViZXJuZXRlcyUyRmNsb3VkLWNvbmZpZyUyMCU1QyUwQSUyMCUyMC0tZHluYW1pYy1jb25maWctZGlyJTNEJTJGZXRjJTJGa3ViZXJuZXRlcyUyRmR5bmFtaWMtY29uZmlnLWRpciUyMCU1QyUwQSUyMCUyMC0tZmVhdHVyZS1nYXRlcyUzRER5bmFtaWNLdWJlbGV0Q29uZmlnJTNEdHJ1ZSUyMCU1QyUwQSUyMCUyMC0tZXhpdC1vbi1sb2NrLWNvbnRlbnRpb24lMjAlNUMlMEElMjAlMjAtLWxvY2stZmlsZSUzRCUyRnRtcCUyRmt1YmVsZXQubG9jayUyMCU1QyUwQSUyMCUyMC0tY29udGFpbmVyLXJ1bnRpbWUlM0RyZW1vdGUlMjAlNUMlMEElMjAlMjAtLWNvbnRhaW5lci1ydW50aW1lLWVuZHBvaW50JTNEdW5peCUzQSUyRiUyRiUyRnJ1biUyRmNvbnRhaW5lcmQlMkZjb250YWluZXJkLnNvY2slMjAlNUMlMEElMjAlMjAtLW5vZGUtaXAlMjAlMjQlN0JLVUJFTEVUX05PREVfSVAlN0QlMEElMEElNUJJbnN0YWxsJTVEJTBBV2FudGVkQnklM0RtdWx0aS11c2VyLnRhcmdldCUwQSIsInZlcmlmaWNhdGlvbiI6e319LCJtb2RlIjo0MjB9LHsiZmlsZXN5c3RlbSI6InJvb3QiLCJwYXRoIjoiL2V0Yy9rdWJlcm5ldGVzL2Nsb3VkLWNvbmZpZyIsImNvbnRlbnRzIjp7InNvdXJjZSI6ImRhdGE6LCU1Qmdsb2JhbCU1RCUwQVpvbmUlM0QlMjIlMjIlMEFWUEMlM0QlMjIlMjIlMEFTdWJuZXRJRCUzRCUyMnRlc3Qtc3VibmV0JTIyJTBBIiwidmVyaWZpY2F0aW9uIjp7fX0sIm1vZGUiOjI1Nn0seyJmaWxlc3lzdGVtIjoicm9vdCIsInBhdGgiOiIvZXRjL2t1YmVybmV0ZXMva3ViZWxldC5jb25mIiwiY29udGVudHMiOnsic291cmNlIjoiZGF0YTosYXBpVmVyc2lvbiUzQSUyMGt1YmVsZXQuY29uZmlnLms4cy5pbyUyRnYxYmV0YTElMEFraW5kJTNBJTIwS3ViZWxldENvbmZpZ3VyYXRpb24lMEFhdXRoZW50aWNhdGlvbiUzQSUwQSUyMCUyMGFub255bW91cyUzQSUwQSUyMCUyMCUyMCUyMGVuYWJsZWQlM0ElMjBmYWxzZSUwQSUyMCUyMHdlYmhvb2slM0ElMEElMjAlMjAlMjAlMjBlbmFibGVkJTNBJTIwdHJ1ZSUwQSUyMCUyMHg1MDklM0ElMEElMjAlMjAlMjAlMjBjbGllbnRDQUZpbGUlM0ElMjAlMkZldGMlMkZrdWJlcm5ldGVzJTJGcGtpJTJGY2EuY3J0JTBBYXV0aG9yaXphdGlvbiUzQSUwQSUyMCUyMG1vZGUlM0ElMjBXZWJob29rJTBBY2dyb3VwRHJpdmVyJTNBJTIwc3lzdGVtZCUwQWNsdXN0ZXJETlMlM0ElMEEtJTIwJTIyMTAuMC4wLjAlMjIlMEFjbHVzdGVyRG9tYWluJTNBJTIwY2x1c3Rlci5sb2NhbCUwQWZlYXR1cmVHYXRlcyUzQSUwQSUyMCUyMEdyYWNlZnVsTm9kZVNodXRkb3duJTNBJTIwdHJ1ZSUwQSUyMCUyMElkZW50aWZ5UG9kT1MlM0ElMjBmYWxzZSUwQXByb3RlY3RLZXJuZWxEZWZhdWx0cyUzQSUyMHRydWUlMEFyZWFkT25seVBvcnQlM0ElMjAwJTBBcm90YXRlQ2VydGlmaWNhdGVzJTNBJTIwdHJ1ZSUwQXNlcnZlclRMU0Jvb3RzdHJhcCUzQSUyMHRydWUlMEFzdGF0aWNQb2RQYXRoJTNBJTIwJTJGZXRjJTJGa3ViZXJuZXRlcyUyRm1hbmlmZXN0cyUwQWt1YmVSZXNlcnZlZCUzQSUwQSUyMCUyMGNwdSUzQSUyMDIwMG0lMEElMjAlMjBlcGhlbWVyYWwtc3RvcmFnZSUzQSUyMDFHaSUwQSUyMCUyMG1lbW9yeSUzQSUyMDIwME1pJTBBc3lzdGVtUmVzZXJ2ZWQlM0ElMEElMjAlMjBjcHUlM0ElMjAyMDBtJTBBJTIwJTIwZXBoZW1lcmFsLXN0b3JhZ2UlM0ElMjAxR2klMEElMjAlMjBtZW1vcnklM0ElMjAyMDBNaSUwQWV2aWN0aW9uSGFyZCUzQSUwQSUyMCUyMGltYWdlZnMuYXZhaWxhYmxlJTNBJTIwMTUlMjUlMEElMjAlMjBtZW1vcnkuYXZhaWxhYmxlJTNBJTIwMTAwTWklMEElMjAlMjBub2RlZnMuYXZhaWxhYmxlJTNBJTIwMTAlMjUlMEElMjAlMjBub2RlZnMuaW5vZGVzRnJlZSUzQSUyMDUlMjUlMEF0bHNDaXBoZXJTdWl0ZXMlM0ElMEEtJTIwVExTX0FFU18xMjhfR0NNX1NIQTI1NiUwQS0lMjBUTFNfQUVTXzI1Nl9HQ01fU0hBMzg0JTBBLSUyMFRMU19DSEFDSEEyMF9QT0xZMTMwNV9TSEEyNTYlMEEtJTIwVExTX0VDREhFX0VDRFNBX1dJVEhfQUVTXzEyOF9HQ01fU0hBMjU2JTBBLSUyMFRMU19FQ0RIRV9FQ0RTQV9XSVRIX0FFU18yNTZfR0NNX1NIQTM4NCUwQS0lMjBUTFNfRUNESEVfRUNEU0FfV0lUSF9DSEFDSEEyMF9QT0xZMTMwNSUwQS0lMjBUTFNfRUNESEVfUlNBX1dJVEhfQUVTXzEyOF9HQ01fU0hBMjU2JTBBLSUyMFRMU19FQ0RIRV9SU0FfV0lUSF9BRVNfMjU2X0dDTV9TSEEzODQlMEEtJTIwVExTX0VDREhFX1JTQV9XSVRIX0NIQUNIQTIwX1BPTFkxMzA1JTBBdm9sdW1lUGx1Z2luRGlyJTNBJTIwJTJGdmFyJTJGbGliJTJGa3ViZWxldCUyRnZvbHVtZXBsdWdpbnMlMEEiLCJ2ZXJpZmljYXRpb24iOnt9fSwibW9kZSI6NDIwfSx7ImZpbGVzeXN0ZW0iOiJyb290IiwicGF0aCI6Ii9ldGMvc3lzdGVtZC9zeXN0ZW0va3ViZWxldC1oZWFsdGhjaGVjay5zZXJ2aWNlIiwiY29udGVudHMiOnsic291cmNlIjoiZGF0YTosJTVCVW5pdCU1RCUwQVJlcXVpcmVzJTNEa3ViZWxldC5zZXJ2aWNlJTBBQWZ0ZXIlM0RrdWJlbGV0LnNlcnZpY2UlMEElMEElNUJTZXJ2aWNlJTVEJTBBRXhlY1N0YXJ0JTNEJTJGb3B0JTJGYmluJTJGaGVhbHRoLW1vbml0b3Iuc2glMjBrdWJlbGV0JTBBJTBBJTVCSW5zdGFsbCU1RCUwQVdhbnRlZEJ5JTNEbXVsdGktdXNlci50YXJnZXQlMEEiLCJ2ZXJpZmljYXRpb24iOnt9fSwibW9kZSI6NDIwfSx7ImZpbGVzeXN0ZW0iOiJyb290IiwicGF0aCI6Ii9wcm9jL3N5cy9rZXJuZWwvcGFuaWNfb25fb29wcyIsImNvbnRlbnRzIjp7InNvdXJjZSI6ImRhdGE6LDElMEEiLCJ2ZXJpZmljYXRpb24iOnt9fSwibW9kZSI6NDIwfSx7ImZpbGVzeXN0ZW0iOiJyb290IiwicGF0aCI6Ii9wcm9jL3N5cy9rZXJuZWwvcGFuaWMiLCJjb250ZW50cyI6eyJzb3VyY2UiOiJkYXRhOiwxMCUwQSIsInZlcmlmaWNhdGlvbiI6e319LCJtb2RlIjo0MjB9LHsiZmlsZXN5c3RlbSI6InJvb3QiLCJwYXRoIjoiL3Byb2Mvc3lzL3ZtL292ZXJjb21taXRfbWVtb3J5IiwiY29udGVudHMiOnsic291cmNlIjoiZGF0YTosMSUwQSIsInZlcmlmaWNhdGlvbiI6e319LCJtb2RlIjo0MjB9LHsiZmlsZXN5c3RlbSI6InJvb3QiLCJwYXRoIjoiL2V0Yy9zc2gvc3NoZF9jb25maWciLCJjb250ZW50cyI6eyJzb3VyY2UiOiJkYXRhOiwlMjMlMjBVc2UlMjBtb3N0JTIwZGVmYXVsdHMlMjBmb3IlMjBzc2hkJTIwY29uZmlndXJhdGlvbi4lMEFTdWJzeXN0ZW0lMjBzZnRwJTIwaW50ZXJuYWwtc2Z0cCUwQUNsaWVudEFsaXZlSW50ZXJ2YWwlMjAxODAlMEFVc2VETlMlMjBubyUwQVVzZVBBTSUyMHllcyUwQVByaW50TGFzdExvZyUyMG5vJTIwJTIzJTIwaGFuZGxlZCUyMGJ5JTIwUEFNJTBBUHJpbnRNb3RkJTIwbm8lMjAlMjMlMjBoYW5kbGVkJTIwYnklMjBQQU0lMEFQYXNzd29yZEF1dGhlbnRpY2F0aW9uJTIwbm8lMEFDaGFsbGVuZ2VSZXNwb25zZUF1dGhlbnRpY2F0aW9uJTIwbm8lMEEiLCJ2ZXJpZmljYXRpb24iOnt9fSwibW9kZSI6Mzg0fSx7ImZpbGVzeXN0ZW0iOiJyb290IiwicGF0aCI6Ii9ldGMvY29udGFpbmVyZC9jb25maWcudG9tbCIsImNvbnRlbnRzIjp7InNvdXJjZSI6ImRhdGE6LHZlcnNpb24lMjAlM0QlMjAyJTBBJTBBJTVCbWV0cmljcyU1RCUwQWFkZHJlc3MlMjAlM0QlMjAlMjIxMjcuMC4wLjElM0ExMzM4JTIyJTBBJTBBJTVCcGx1Z2lucyU1RCUwQSU1QnBsdWdpbnMuJTIyaW8uY29udGFpbmVyZC5ncnBjLnYxLmNyaSUyMiU1RCUwQSU1QnBsdWdpbnMuJTIyaW8uY29udGFpbmVyZC5ncnBjLnYxLmNyaSUyMi5jb250YWluZXJkJTVEJTBBJTVCcGx1Z2lucy4lMjJpby5jb250YWluZXJkLmdycGMudjEuY3JpJTIyLmNvbnRhaW5lcmQucnVudGltZXMlNUQlMEElNUJwbHVnaW5zLiUyMmlvLmNvbnRhaW5lcmQuZ3JwYy52MS5jcmklMjIuY29udGFpbmVyZC5ydW50aW1lcy5ydW5jJTVEJTBBcnVudGltZV90eXBlJTIwJTNEJTIwJTIyaW8uY29udGFpbmVyZC5ydW5jLnYyJTIyJTBBJTVCcGx1Z2lucy4lMjJpby5jb250YWluZXJkLmdycGMudjEuY3JpJTIyLmNvbnRhaW5lcmQucnVudGltZXMucnVuYy5vcHRpb25zJTVEJTBBU3lzdGVtZENncm91cCUyMCUzRCUyMHRydWUlMEElNUJwbHVnaW5zLiUyMmlvLmNvbnRhaW5lcmQuZ3JwYy52MS5jcmklMjIucmVnaXN0cnklNUQlMEElNUJwbHVnaW5zLiUyMmlvLmNvbnRhaW5lcmQuZ3JwYy52MS5jcmklMjIucmVnaXN0cnkubWlycm9ycyU1RCUwQSU1QnBsdWdpbnMuJTIyaW8uY29udGFpbmVyZC5ncnBjLnYxLmNyaSUyMi5yZWdpc3RyeS5taXJyb3JzLiUyMmRvY2tlci5pbyUyMiU1RCUwQWVuZHBvaW50JTIwJTNEJTIwJTVCJTIyaHR0cHMlM0ElMkYlMkZyZWdpc3RyeS0xLmRvY2tlci5pbyUyMiU1RCUwQSIsInZlcmlmaWNhdGlvbiI6e319LCJtb2RlIjo0MjB9LHsiZmlsZXN5c3RlbSI6InJvb3QiLCJwYXRoIjoiL2V0Yy9zeXN0ZW1kL3N5c3RlbS9jb250YWluZXJkLnNlcnZpY2UuZC8xMC1jdXN0b20uY29uZiIsImNvbnRlbnRzIjp7InNvdXJjZSI6ImRhdGE6LCU1QlNlcnZpY2UlNUQlMEFSZXN0YXJ0JTNEYWx3YXlzJTBBRW52aXJvbm1lbnRGaWxlJTNELSUyRmV0YyUyRmVudmlyb25tZW50JTBBRW52aXJvbm1lbnRGaWxlJTNEJTJGcnVuJTJGbWV0YWRhdGElMkZ0b3JjeCUwQUVudmlyb25tZW50JTNEQ09OVEFJTkVSRF9DT05GSUclM0QlMkZldGMlMkZjb250YWluZXJkJTJGY29uZmlnLnRvbWwlMEFFeGVjU3RhcnQlM0QlMEFFeGVjU3RhcnQlM0QlMkZ1c3IlMkZiaW4lMkZlbnYlMjBQQVRIJTNEJTI0JTdCVE9SQ1hfQklORElSJTdEJTNBJTI0JTdCUEFUSCU3RCUyMCUyNCU3QlRPUkNYX0JJTkRJUiU3RCUyRmNvbnRhaW5lcmQlMjAtLWNvbmZpZyUyMCUyNCU3QkNPTlRBSU5FUkRfQ09ORklHJTdEJTBBIiwidmVyaWZpY2F0aW9uIjp7fX0sIm1vZGUiOjQyMH0seyJmaWxlc3lzdGVtIjoicm9vdCIsInBhdGgiOiIvZXRjL2NyaWN0bC55YW1sIiwiY29udGVudHMiOnsic291cmNlIjoiZGF0YToscnVudGltZS1lbmRwb2ludCUzQSUyMHVuaXglM0ElMkYlMkYlMkZydW4lMkZjb250YWluZXJkJTJGY29udGFpbmVyZC5zb2NrJTBBIiwidmVyaWZpY2F0aW9uIjp7fX0sIm1vZGUiOjQyMH1dfSwic3lzdGVtZCI6eyJ1bml0cyI6W3siY29udGVudHMiOiJbSW5zdGFsbF1cbldhbnRlZEJ5PW11bHRpLXVzZXIudGFyZ2V0XG5cbltVbml0XVxuUmVxdWlyZXM9ZG93bmxvYWQtc2NyaXB0LnNlcnZpY2VcblJlcXVpcmVzPW5vZGVpcC5zZXJ2aWNlXG5BZnRlcj1kb3dubG9hZC1zY3JpcHQuc2VydmljZVxuQWZ0ZXI9bm9kZWlwLnNlcnZpY2VcblxuW1NlcnZpY2VdXG5UeXBlPW9uZXNob3RcblJlbWFpbkFmdGVyRXhpdD10cnVlXG5FbnZpcm9ubWVudEZpbGU9LS9ldGMvZW52aXJvbm1lbnRcbkV4ZWNTdGFydD0vb3B0L2Jpbi9zZXR1cFxuIiwiZW5hYmxlZCI6dHJ1ZSwibmFtZSI6InNldHVwLnNlcnZpY2UifSx7ImNvbnRlbnRzIjoiW0luc3RhbGxdXG5XYW50ZWRCeT1tdWx0aS11c2VyLnRhcmdldFxuXG5bVW5pdF1cblJlcXVpcmVzPW5ldHdvcmstb25saW5lLnRhcmdldFxuQWZ0ZXI9bmV0d29yay1vbmxpbmUudGFyZ2V0XG5cbltTZXJ2aWNlXVxuVHlwZT1vbmVzaG90XG5SZW1haW5BZnRlckV4aXQ9dHJ1ZVxuRW52aXJvbm1lbnRGaWxlPS0vZXRjL2Vudmlyb25tZW50XG5FeGVjU3RhcnQ9L29wdC9iaW4vZG93bmxvYWQuc2hcbiIsImVuYWJsZWQiOnRydWUsIm5hbWUiOiJkb3dubG9hZC1zY3JpcHQuc2VydmljZSJ9LHsiY29udGVudHMiOiJbVW5pdF1cbkRlc2NyaXB0aW9uPVNldHVwIEt1YmVsZXQgTm9kZSBJUCBFbnZcblJlcXVpcmVzPW5ldHdvcmstb25saW5lLnRhcmdldFxuQWZ0ZXI9bmV0d29yay1vbmxpbmUudGFyZ2V0XG5cbltTZXJ2aWNlXVxuRXhlY1N0YXJ0PS9vcHQvYmluL3NldHVwX25ldF9lbnYuc2hcblJlbWFpbkFmdGVyRXhpdD15ZXNcblR5cGU9b25lc2hvdFxuW0luc3RhbGxdXG5XYW50ZWRCeT1tdWx0aS11c2VyLnRhcmdldFxuIiwiZW5hYmxlZCI6dHJ1ZSwibmFtZSI6Im5vZGVpcC5zZXJ2aWNlIn0seyJjb250ZW50cyI6IltVbml0XVxuRGVzY3JpcHRpb249U2V0dXAgU3RhdGljIE5ldHdvcmtpbmdcblJlcXVpcmVzPW5ldHdvcmstb25saW5lLnRhcmdldFxuQWZ0ZXI9bmV0d29yay1vbmxpbmUudGFyZ2V0XG5cbltTZXJ2aWNlXVxuRXhlY1N0YXJ0PS9vcHQvYmluL2NvbmZpZ3VyZV9zdGF0aWNfbmV0d29yay5zaFxuUmVtYWluQWZ0ZXJFeGl0PXllc1xuVHlwZT1vbmVzaG90XG5bSW5zdGFsbF1cbldhbnRlZEJ5PW11bHRpLXVzZXIudGFyZ2V0XG4iLCJlbmFibGVkIjp0cnVlLCJuYW1lIjoic3RhdGljLW5ldHdvcmstc2NyaXB0LnNlcnZpY2UifV19fQ== + cloud-config: eyJpZ25pdGlvbiI6eyJjb25maWciOnt9LCJzZWN1cml0eSI6eyJ0bHMiOnt9fSwidGltZW91dHMiOnt9LCJ2ZXJzaW9uIjoiMi4zLjAifSwibmV0d29ya2QiOnt9LCJwYXNzd2QiOnsidXNlcnMiOlt7Im5hbWUiOiJjb3JlIiwic3NoQXV0aG9yaXplZEtleXMiOlsic3NoLXJzYSBBQUFBQjNOemFDMXljMkVBQUFBREFRQUJBQUFDQVFEZE9JaFltekNLNURTVkx1M2MiXX1dfSwic3RvcmFnZSI6eyJmaWxlcyI6W3siZmlsZXN5c3RlbSI6InJvb3QiLCJwYXRoIjoiL2V0Yy9zeXN0ZW1kL2pvdXJuYWxkLmNvbmYuZC9tYXhfZGlza191c2UuY29uZiIsImNvbnRlbnRzIjp7InNvdXJjZSI6ImRhdGE6LCU1QkpvdXJuYWwlNUQlMEFTeXN0ZW1NYXhVc2UlM0Q1RyUwQSIsInZlcmlmaWNhdGlvbiI6e319LCJtb2RlIjo0MjB9LHsiZmlsZXN5c3RlbSI6InJvb3QiLCJwYXRoIjoiL29wdC9sb2FkLWtlcm5lbC1tb2R1bGVzLnNoIiwiY29udGVudHMiOnsic291cmNlIjoiZGF0YTosJTIzISUyRnVzciUyRmJpbiUyRmVudiUyMGJhc2glMEFzZXQlMjAtZXVvJTIwcGlwZWZhaWwlMEElMEFtb2Rwcm9iZSUyMGlwX3ZzJTBBbW9kcHJvYmUlMjBpcF92c19yciUwQW1vZHByb2JlJTIwaXBfdnNfd3JyJTBBbW9kcHJvYmUlMjBpcF92c19zaCUwQSUwQWlmJTIwbW9kaW5mbyUyMG5mX2Nvbm50cmFja19pcHY0JTIwJTI2JTNFJTIwJTJGZGV2JTJGbnVsbCUzQiUyMHRoZW4lMEElMjAlMjBtb2Rwcm9iZSUyMG5mX2Nvbm50cmFja19pcHY0JTBBZWxzZSUwQSUyMCUyMG1vZHByb2JlJTIwbmZfY29ubnRyYWNrJTBBZmklMEEiLCJ2ZXJpZmljYXRpb24iOnt9fSwibW9kZSI6NDkzfSx7ImZpbGVzeXN0ZW0iOiJyb290IiwicGF0aCI6Ii9ldGMvc3lzY3RsLmQvazhzLmNvbmYiLCJjb250ZW50cyI6eyJzb3VyY2UiOiJkYXRhOixuZXQuYnJpZGdlLmJyaWRnZS1uZi1jYWxsLWlwNnRhYmxlcyUyMCUzRCUyMDElMEFuZXQuYnJpZGdlLmJyaWRnZS1uZi1jYWxsLWlwdGFibGVzJTIwJTNEJTIwMSUwQWtlcm5lbC5wYW5pY19vbl9vb3BzJTIwJTNEJTIwMSUwQWtlcm5lbC5wYW5pYyUyMCUzRCUyMDEwJTBBbmV0LmlwdjQuaXBfZm9yd2FyZCUyMCUzRCUyMDElMEF2bS5vdmVyY29tbWl0X21lbW9yeSUyMCUzRCUyMDElMEFmcy5pbm90aWZ5Lm1heF91c2VyX3dhdGNoZXMlMjAlM0QlMjAxMDQ4NTc2JTBBIiwidmVyaWZpY2F0aW9uIjp7fX0sIm1vZGUiOjQyMH0seyJmaWxlc3lzdGVtIjoicm9vdCIsInBhdGgiOiIvb3B0L2Jpbi9zZXR1cF9uZXRfZW52LnNoIiwiY29udGVudHMiOnsic291cmNlIjoiZGF0YTosJTIzISUyRnVzciUyRmJpbiUyRmVudiUyMGJhc2glMEFlY2hvZGF0ZSgpJTIwJTdCJTBBJTIwJTIwZWNobyUyMCUyMiU1QiUyNChkYXRlJTIwLUlzKSU1RCUyMiUyMCUyMiUyNCU0MCUyMiUwQSU3RCUwQSUwQSUyMyUyMGdldCUyMHRoZSUyMGRlZmF1bHQlMjBpbnRlcmZhY2UlMjBJUCUyMGFkZHJlc3MlMEFERUZBVUxUX0lGQ19JUCUzRCUyNChpcCUyMC1vJTIwJTIwcm91dGUlMjBnZXQlMjAxJTIwJTdDJTIwZ3JlcCUyMC1vUCUyMCUyMnNyYyUyMCU1Q0slNUNTJTJCJTIyKSUwQSUwQWlmJTIwJTVCJTIwLXolMjAlMjIlMjQlN0JERUZBVUxUX0lGQ19JUCU3RCUyMiUyMCU1RCUwQXRoZW4lMEElMjAlMjBlY2hvZGF0ZSUyMCUyMkZhaWxlZCUyMHRvJTIwZ2V0JTIwSVAlMjBhZGRyZXNzJTIwZm9yJTIwdGhlJTIwZGVmYXVsdCUyMHJvdXRlJTIwaW50ZXJmYWNlJTIyJTBBJTIwJTIwZXhpdCUyMDElMEFmaSUwQSUwQSUyMyUyMGdldCUyMHRoZSUyMGZ1bGwlMjBob3N0bmFtZSUwQUZVTExfSE9TVE5BTUUlM0QlMjQoaG9zdG5hbWUlMjAtZiklMEElMjMlMjBpZiUyMCUyRmV0YyUyRmhvc3RuYW1lJTIwaXMlMjBub3QlMjBlbXB0eSUyMHRoZW4lMjB1c2UlMjB0aGUlMjBob3N0bmFtZSUyMGZyb20lMjB0aGVyZSUwQWlmJTIwJTVCJTIwLXMlMjAlMkZldGMlMkZob3N0bmFtZSUyMCU1RCUzQiUyMHRoZW4lMEElMjAlMjAlMjAlMjBGVUxMX0hPU1ROQU1FJTNEJTI0KGNhdCUyMCUyRmV0YyUyRmhvc3RuYW1lKSUwQWZpJTBBJTBBJTIzJTIwd3JpdGUlMjB0aGUlMjBub2RlaXBfZW52JTIwZmlsZSUwQSUyMyUyMHdlJTIwbmVlZCUyMHRoZSUyMGxpbmUlMjBiZWxvdyUyMGJlY2F1c2UlMjBmbGF0Y2FyJTIwaGFzJTIwdGhlJTIwc2FtZSUyMHN0cmluZyUyMCUyMmNvcmVvcyUyMiUyMGluJTIwdGhhdCUyMGZpbGUlMEFpZiUyMGdyZXAlMjAtcSUyMGNvcmVvcyUyMCUyRmV0YyUyRm9zLXJlbGVhc2UlMEF0aGVuJTBBJTIwJTIwZWNobyUyMC1lJTIwJTIyS1VCRUxFVF9OT0RFX0lQJTNEJTI0JTdCREVGQVVMVF9JRkNfSVAlN0QlNUNuS1VCRUxFVF9IT1NUTkFNRSUzRCUyNCU3QkZVTExfSE9TVE5BTUUlN0QlMjIlMjAlM0UlMjAlMkZldGMlMkZrdWJlcm5ldGVzJTJGbm9kZWlwLmNvbmYlMEFlbGlmJTIwJTVCJTIwISUyMC1kJTIwJTJGZXRjJTJGc3lzdGVtZCUyRnN5c3RlbSUyRmt1YmVsZXQuc2VydmljZS5kJTIwJTVEJTBBdGhlbiUwQSUyMCUyMGVjaG9kYXRlJTIwJTIyQ2FuJ3QlMjBmaW5kJTIwa3ViZWxldCUyMHNlcnZpY2UlMjBleHRyYXMlMjBkaXJlY3RvcnklMjIlMEElMjAlMjBleGl0JTIwMSUwQWVsc2UlMEElMjAlMjBlY2hvJTIwLWUlMjAlMjIlNUJTZXJ2aWNlJTVEJTVDbkVudmlyb25tZW50JTNEJTVDJTIyS1VCRUxFVF9OT0RFX0lQJTNEJTI0JTdCREVGQVVMVF9JRkNfSVAlN0QlNUMlMjIlNUNuRW52aXJvbm1lbnQlM0QlNUMlMjJLVUJFTEVUX0hPU1ROQU1FJTNEJTI0JTdCRlVMTF9IT1NUTkFNRSU3RCU1QyUyMiUyMiUyMCUzRSUyMCUyRmV0YyUyRnN5c3RlbWQlMkZzeXN0ZW0lMkZrdWJlbGV0LnNlcnZpY2UuZCUyRm5vZGVpcC5jb25mJTBBZmklMEEiLCJ2ZXJpZmljYXRpb24iOnt9fSwibW9kZSI6NDkzfSx7ImZpbGVzeXN0ZW0iOiJyb290IiwicGF0aCI6Ii9vcHQvYmluL2NvbmZpZ3VyZV9zdGF0aWNfbmV0d29yay5zaCIsImNvbnRlbnRzIjp7InNvdXJjZSI6ImRhdGE6LCUyMyElMkZ1c3IlMkZiaW4lMkZlbnYlMjBiYXNoJTBBc2V0JTIwLXhldW8lMjBwaXBlZmFpbCUwQSIsInZlcmlmaWNhdGlvbiI6e319LCJtb2RlIjo0OTN9LHsiZmlsZXN5c3RlbSI6InJvb3QiLCJwYXRoIjoiL29wdC9iaW4vZG93bmxvYWQuc2giLCJjb250ZW50cyI6eyJzb3VyY2UiOiJkYXRhOiwlMjMhJTJGdXNyJTJGYmluJTJGZW52JTIwYmFzaCUwQXNldCUyMC14ZXVvJTIwcGlwZWZhaWwlMEFvcHRfYmluJTNEJTJGb3B0JTJGYmluJTBBdXNyX2xvY2FsX2JpbiUzRCUyRnVzciUyRmxvY2FsJTJGYmluJTBBY25pX2Jpbl9kaXIlM0QlMkZvcHQlMkZjbmklMkZiaW4lMEFta2RpciUyMC1wJTIwJTJGZXRjJTJGY25pJTJGbmV0LmQlMjAlMkZldGMlMkZrdWJlcm5ldGVzJTJGZHluYW1pYy1jb25maWctZGlyJTIwJTJGZXRjJTJGa3ViZXJuZXRlcyUyRm1hbmlmZXN0cyUyMCUyMiUyNG9wdF9iaW4lMjIlMjAlMjIlMjRjbmlfYmluX2RpciUyMiUwQWFyY2glM0QlMjQlN0JIT1NUX0FSQ0gtJTdEJTBBaWYlMjAlNUIlMjAteiUyMCUyMiUyNGFyY2glMjIlMjAlNUQlMEF0aGVuJTBBY2FzZSUyMCUyNCh1bmFtZSUyMC1tKSUyMGluJTBBeDg2XzY0KSUwQSUyMCUyMCUyMCUyMGFyY2glM0QlMjJhbWQ2NCUyMiUwQSUyMCUyMCUyMCUyMCUzQiUzQiUwQWFhcmNoNjQpJTBBJTIwJTIwJTIwJTIwYXJjaCUzRCUyMmFybTY0JTIyJTBBJTIwJTIwJTIwJTIwJTNCJTNCJTBBKiklMEElMjAlMjAlMjAlMjBlY2hvJTIwJTIydW5zdXBwb3J0ZWQlMjBDUFUlMjBhcmNoaXRlY3R1cmUlMkMlMjBleGl0aW5nJTIyJTBBJTIwJTIwJTIwJTIwZXhpdCUyMDElMEElMjAlMjAlMjAlMjAlM0IlM0IlMEFlc2FjJTBBZmklMEFDTklfVkVSU0lPTiUzRCUyMiUyNCU3QkNOSV9WRVJTSU9OJTNBLXYwLjguNyU3RCUyMiUwQWNuaV9iYXNlX3VybCUzRCUyMmh0dHBzJTNBJTJGJTJGZ2l0aHViLmNvbSUyRmNvbnRhaW5lcm5ldHdvcmtpbmclMkZwbHVnaW5zJTJGcmVsZWFzZXMlMkZkb3dubG9hZCUyRiUyNENOSV9WRVJTSU9OJTIyJTBBY25pX2ZpbGVuYW1lJTNEJTIyY25pLXBsdWdpbnMtbGludXgtJTI0YXJjaC0lMjRDTklfVkVSU0lPTi50Z3olMjIlMEFjdXJsJTIwLUxmbyUyMCUyMiUyNGNuaV9iaW5fZGlyJTJGJTI0Y25pX2ZpbGVuYW1lJTIyJTIwJTIyJTI0Y25pX2Jhc2VfdXJsJTJGJTI0Y25pX2ZpbGVuYW1lJTIyJTBBY25pX3N1bSUzRCUyNChjdXJsJTIwLUxmJTIwJTIyJTI0Y25pX2Jhc2VfdXJsJTJGJTI0Y25pX2ZpbGVuYW1lLnNoYTI1NiUyMiklMEFjZCUyMCUyMiUyNGNuaV9iaW5fZGlyJTIyJTBBc2hhMjU2c3VtJTIwLWMlMjAlM0MlM0MlM0MlMjIlMjRjbmlfc3VtJTIyJTBBdGFyJTIweHZmJTIwJTIyJTI0Y25pX2ZpbGVuYW1lJTIyJTBBcm0lMjAtZiUyMCUyMiUyNGNuaV9maWxlbmFtZSUyMiUwQWNkJTIwLSUwQUNSSV9UT09MU19SRUxFQVNFJTNEJTIyJTI0JTdCQ1JJX1RPT0xTX1JFTEVBU0UlM0EtdjEuMjIuMCU3RCUyMiUwQWNyaV90b29sc19iYXNlX3VybCUzRCUyMmh0dHBzJTNBJTJGJTJGZ2l0aHViLmNvbSUyRmt1YmVybmV0ZXMtc2lncyUyRmNyaS10b29scyUyRnJlbGVhc2VzJTJGZG93bmxvYWQlMkYlMjQlN0JDUklfVE9PTFNfUkVMRUFTRSU3RCUyMiUwQWNyaV90b29sc19maWxlbmFtZSUzRCUyMmNyaWN0bC0lMjQlN0JDUklfVE9PTFNfUkVMRUFTRSU3RC1saW51eC0lMjQlN0JhcmNoJTdELnRhci5neiUyMiUwQWN1cmwlMjAtTGZvJTIwJTIyJTI0b3B0X2JpbiUyRiUyNGNyaV90b29sc19maWxlbmFtZSUyMiUyMCUyMiUyNGNyaV90b29sc19iYXNlX3VybCUyRiUyNGNyaV90b29sc19maWxlbmFtZSUyMiUwQWNyaV90b29sc19zdW0lM0QlMjQoY3VybCUyMC1MZiUyMCUyMiUyNGNyaV90b29sc19iYXNlX3VybCUyRiUyNGNyaV90b29sc19maWxlbmFtZS5zaGEyNTYlMjIlMjAlN0MlMjBzZWQlMjAncyUyRiU1QyolNUMlMkYlMkYlMkYnKSUwQWNkJTIwJTIyJTI0b3B0X2JpbiUyMiUwQXNoYTI1NnN1bSUyMC1jJTIwJTNDJTNDJTNDJTIyJTI0Y3JpX3Rvb2xzX3N1bSUyMiUwQXRhciUyMHh2ZiUyMCUyMiUyNGNyaV90b29sc19maWxlbmFtZSUyMiUwQXJtJTIwLWYlMjAlMjIlMjRjcmlfdG9vbHNfZmlsZW5hbWUlMjIlMEFsbiUyMC1zZiUyMCUyMiUyNG9wdF9iaW4lMkZjcmljdGwlMjIlMjAlMjIlMjR1c3JfbG9jYWxfYmluJTIyJTJGY3JpY3RsJTIwJTdDJTdDJTIwZWNobyUyMCUyMnN5bWJvbGljJTIwbGluayUyMGlzJTIwc2tpcHBlZCUyMiUwQWNkJTIwLSUwQUtVQkVfVkVSU0lPTiUzRCUyMiUyNCU3QktVQkVfVkVSU0lPTiUzQS12MS4yMi4xJTdEJTIyJTBBa3ViZV9kaXIlM0QlMjIlMjRvcHRfYmluJTJGa3ViZXJuZXRlcy0lMjRLVUJFX1ZFUlNJT04lMjIlMEFrdWJlX2Jhc2VfdXJsJTNEJTIyaHR0cHMlM0ElMkYlMkZzdG9yYWdlLmdvb2dsZWFwaXMuY29tJTJGa3ViZXJuZXRlcy1yZWxlYXNlJTJGcmVsZWFzZSUyRiUyNEtVQkVfVkVSU0lPTiUyRmJpbiUyRmxpbnV4JTJGJTI0YXJjaCUyMiUwQWt1YmVfc3VtX2ZpbGUlM0QlMjIlMjRrdWJlX2RpciUyRnNoYTI1NiUyMiUwQW1rZGlyJTIwLXAlMjAlMjIlMjRrdWJlX2RpciUyMiUwQSUzQSUyMCUzRSUyMiUyNGt1YmVfc3VtX2ZpbGUlMjIlMEElMEFmb3IlMjBiaW4lMjBpbiUyMGt1YmVsZXQlMjBrdWJlYWRtJTIwa3ViZWN0bCUzQiUyMGRvJTBBJTIwJTIwJTIwJTIwY3VybCUyMC1MZm8lMjAlMjIlMjRrdWJlX2RpciUyRiUyNGJpbiUyMiUyMCUyMiUyNGt1YmVfYmFzZV91cmwlMkYlMjRiaW4lMjIlMEElMjAlMjAlMjAlMjBjaG1vZCUyMCUyQnglMjAlMjIlMjRrdWJlX2RpciUyRiUyNGJpbiUyMiUwQSUyMCUyMCUyMCUyMHN1bSUzRCUyNChjdXJsJTIwLUxmJTIwJTIyJTI0a3ViZV9iYXNlX3VybCUyRiUyNGJpbi5zaGEyNTYlMjIpJTBBJTIwJTIwJTIwJTIwZWNobyUyMCUyMiUyNHN1bSUyMCUyMCUyNGt1YmVfZGlyJTJGJTI0YmluJTIyJTIwJTNFJTNFJTIyJTI0a3ViZV9zdW1fZmlsZSUyMiUwQWRvbmUlMEFzaGEyNTZzdW0lMjAtYyUyMCUyMiUyNGt1YmVfc3VtX2ZpbGUlMjIlMEElMEFmb3IlMjBiaW4lMjBpbiUyMGt1YmVsZXQlMjBrdWJlYWRtJTIwa3ViZWN0bCUzQiUyMGRvJTBBJTIwJTIwJTIwJTIwbG4lMjAtc2YlMjAlMjIlMjRrdWJlX2RpciUyRiUyNGJpbiUyMiUyMCUyMiUyNG9wdF9iaW4lMjIlMkYlMjRiaW4lMEFkb25lJTBBJTBBaWYlMjAlNUIlNUIlMjAhJTIwLXglMjAlMkZvcHQlMkZiaW4lMkZoZWFsdGgtbW9uaXRvci5zaCUyMCU1RCU1RCUzQiUyMHRoZW4lMEElMjAlMjAlMjAlMjBjdXJsJTIwLUxmbyUyMCUyRm9wdCUyRmJpbiUyRmhlYWx0aC1tb25pdG9yLnNoJTIwaHR0cHMlM0ElMkYlMkZyYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tJTJGa3ViZXJtYXRpYyUyRm1hY2hpbmUtY29udHJvbGxlciUyRjc5NjdhMGFmMmI3NWYyOWFkMmFiMjI3ZWVhYTI2ZWE3YjBmMmZiZGUlMkZwa2clMkZ1c2VyZGF0YSUyRnNjcmlwdHMlMkZoZWFsdGgtbW9uaXRvci5zaCUwQSUyMCUyMCUyMCUyMGNobW9kJTIwJTJCeCUyMCUyRm9wdCUyRmJpbiUyRmhlYWx0aC1tb25pdG9yLnNoJTBBZmklMEElMEFzeXN0ZW1jdGwlMjBkaXNhYmxlJTIwZG93bmxvYWQtc2NyaXB0LnNlcnZpY2UlMEEiLCJ2ZXJpZmljYXRpb24iOnt9fSwibW9kZSI6NDkzfSx7ImZpbGVzeXN0ZW0iOiJyb290IiwicGF0aCI6Ii9vcHQvYmluL3NldHVwIiwiY29udGVudHMiOnsic291cmNlIjoiZGF0YTosJTIzISUyRmJpbiUyRmJhc2glMEFzZXQlMjAteGV1byUyMHBpcGVmYWlsJTBBY2F0JTIwJTNDJTNDJTIwRU9GJTIwJTdDJTIwdGVlJTIwJTJGZXRjJTJGcG9sa2l0LTElMkZydWxlcy5kJTJGNjAtbm9yZWJvb3Rfbm9yZXN0YXJ0LnJ1bGVzJTBBcG9sa2l0LmFkZFJ1bGUoZnVuY3Rpb24oYWN0aW9uJTJDJTIwc3ViamVjdCklMjAlN0IlMEElMjAlMjBpZiUyMChhY3Rpb24uaWQlMjAlM0QlM0QlMjAlMjJvcmcuZnJlZWRlc2t0b3AubG9naW4xLnJlYm9vdCUyMiUyMCU3QyU3QyUwQSUyMCUyMCUyMCUyMCUyMCUyMGFjdGlvbi5pZCUyMCUzRCUzRCUyMCUyMm9yZy5mcmVlZGVza3RvcC5sb2dpbjEucmVib290LW11bHRpcGxlLXNlc3Npb25zJTIyKSUyMCU3QiUwQSUyMCUyMCUyMCUyMCUyMCUyMGlmJTIwKHN1YmplY3QudXNlciUyMCUzRCUzRCUyMCUyMmNvcmUlMjIpJTIwJTdCJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwcmV0dXJuJTIwcG9sa2l0LlJlc3VsdC5ZRVMlM0IlMEElMjAlMjAlMjAlMjAlMjAlMjAlN0QlMjBlbHNlJTIwJTdCJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwcmV0dXJuJTIwcG9sa2l0LlJlc3VsdC5BVVRIX0FETUlOJTNCJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTdEJTBBJTIwJTIwJTdEJTBBJTdEKSUzQiUwQUVPRiUwQXN5c3RlbWN0bCUyMHN0b3AlMjBkb2NrZXIlMEFzeXN0ZW1jdGwlMjBkaXNhYmxlJTIwZG9ja2VyJTBBJTBBc3lzdGVtY3RsJTIwZW5hYmxlJTIwLS1ub3clMjBrdWJlbGV0JTBBc3lzdGVtY3RsJTIwZW5hYmxlJTIwLS1ub3clMjAtLW5vLWJsb2NrJTIwa3ViZWxldC1oZWFsdGhjaGVjay5zZXJ2aWNlJTBBc3lzdGVtY3RsJTIwZGlzYWJsZSUyMHNldHVwLnNlcnZpY2UlMEEiLCJ2ZXJpZmljYXRpb24iOnt9fSwibW9kZSI6NDkzfSx7ImZpbGVzeXN0ZW0iOiJyb290IiwicGF0aCI6Ii9ldGMva3ViZXJuZXRlcy9wa2kvY2EuY3J0IiwiY29udGVudHMiOnsic291cmNlIjoiZGF0YTosLS0tLS1CRUdJTiUyMENFUlRJRklDQVRFLS0tLS0lMEFNSUlFV2pDQ0EwS2dBd0lCQWdJSkFMZlJsV3NJOFlRSE1BMEdDU3FHU0liM0RRRUJCUVVBTUhzeEN6QUpCZ05WJTBBQkFZVEFsVlRNUXN3Q1FZRFZRUUlFd0pEUVRFV01CUUdBMVVFQnhNTlUyRnVJRVp5WVc1amFYTmpiekVVTUJJRyUwQUExVUVDaE1MUW5KaFpHWnBkSHBwYm1NeEVqQVFCZ05WQkFNVENXeHZZMkZzYUc5emRERWRNQnNHQ1NxR1NJYjMlMEFEUUVKQVJZT1luSmhaRUJrWVc1bllTNWpiMjB3SGhjTk1UUXdOekUxTWpBME5qQTFXaGNOTVRjd05UQTBNakEwJTBBTmpBMVdqQjdNUXN3Q1FZRFZRUUdFd0pWVXpFTE1Ba0dBMVVFQ0JNQ1EwRXhGakFVQmdOVkJBY1REVk5oYmlCRyUwQWNtRnVZMmx6WTI4eEZEQVNCZ05WQkFvVEMwSnlZV1JtYVhSNmFXNWpNUkl3RUFZRFZRUURFd2xzYjJOaGJHaHYlMEFjM1F4SFRBYkJna3Foa2lHOXcwQkNRRVdEbUp5WVdSQVpHRnVaMkV1WTI5dE1JSUJJakFOQmdrcWhraUc5dzBCJTBBQVFFRkFBT0NBUThBTUlJQkNnS0NBUUVBdDVmQWpwNGZUY2VrV1VUZnpzcDBreWloMU9ZYnNHTDBLWDFlUmJTUyUwQVI4T2QwJTJCOVE2Mkh5bnklMkJHRndNVGI0QSUyRktVOG1zc29IdmNjZVNBQWJ3ZmJ4RkslMkYlMkJzNTFUb2JxVW5PUlpyT29UJTBBWmprVXlnYnlYRFNLOTlZQmJjUjFQaXA4dndNVG00WEt1THRDaWdlQkJkampBUWRnVU8yOExFTkdsc01ubWVZayUwQUpmT0RWR25WbXI1THRiOUFOQThJS3lUZnNuSEo0aU9DUyUyRlBsUGJVajJxN1lub1ZMcG9zVUJNbGdVYiUyRkN5a1gzJTBBbU9vTGI0eUpKUXlBJTJGaVNUNlp4aUlFajM2RDR5V1o1bGc3WUpsJTJCVWlpQlFIR0NuUGRHeWlwcVYwNmV4MGhlWVclMEFjYWlXOExXWlNVUTkzalElMkJXVkNIOGhUN0RRTzFkbXN2VW1YbHElMkZKZUFsd1ElMkZRSURBUUFCbzRIZ01JSGRNQjBHJTBBQTFVZERnUVdCQlJjQVJPdGhTNFA0VTd2VGZqQnlDNTY5UjdFNkRDQnJRWURWUjBqQklHbE1JR2lnQlJjQVJPdCUwQWhTNFA0VTd2VGZqQnlDNTY5UjdFNktGJTJGcEgwd2V6RUxNQWtHQTFVRUJoTUNWVk14Q3pBSkJnTlZCQWdUQWtOQiUwQU1SWXdGQVlEVlFRSEV3MVRZVzRnUm5KaGJtTnBjMk52TVJRd0VnWURWUVFLRXd0Q2NtRmtabWwwZW1sdVl6RVMlMEFNQkFHQTFVRUF4TUpiRzlqWVd4b2IzTjBNUjB3R3dZSktvWklodmNOQVFrQkZnNWljbUZrUUdSaGJtZGhMbU52JTBBYllJSkFMZlJsV3NJOFlRSE1Bd0dBMVVkRXdRRk1BTUJBZjh3RFFZSktvWklodmNOQVFFRkJRQURnZ0VCQUc2aCUwQVU5ZjlzTkgwJTJGNm9CYkdHeTJFVlUwVWdJVFVRSXJGV285ckZrclc1ayUyRlhrRGpRbSUyQjNsempUMGlHUjRJeEUlMkZBbyUwQWVVNnNRaHVhN3dyV2VGRW40N0dMOThsbkNzSmREN29aTmhGbVE5NVRiJTJGTG5EVWpzNVlqOWJyUDBOV3pYZllVNCUwQVVLMlpuSU5KUmNKcEI4aVJDYUN4RThEZGNVRjBYcUlFcTZwQTI3MnNub0xtaVhMTXZObDNrWUVkbSUyQmplNnZvRCUwQTU4U05WRVVzenR6UXlYbUpFaENwd1ZJMEE2UUNqelhqJTJCcXZwbXczWlpIaThKd1hlaThaWkJMVFNGQmtpOFo3biUwQXNIOUJCSDM4JTJGU3pVbUFONFFIU1B5MWdqcW0wME9BRThOYVlEa2glMkZiekU0ZDdtTEdHTVdwJTJGV0UzS1BTdTgySEYlMEFrUGU2WG9TYmlMbSUyRmt4azMyVDAlM0QlMEEtLS0tLUVORCUyMENFUlRJRklDQVRFLS0tLS0lMEEiLCJ2ZXJpZmljYXRpb24iOnt9fSwibW9kZSI6NDIwfSx7ImZpbGVzeXN0ZW0iOiJyb290IiwicGF0aCI6Ii9ldGMvc3lzdGVtZC9zeXN0ZW0va3ViZWxldC5zZXJ2aWNlIiwiY29udGVudHMiOnsic291cmNlIjoiZGF0YTosJTVCVW5pdCU1RCUwQUFmdGVyJTNEY29udGFpbmVyZC5zZXJ2aWNlJTBBUmVxdWlyZXMlM0Rjb250YWluZXJkLnNlcnZpY2UlMEElMEFEZXNjcmlwdGlvbiUzRGt1YmVsZXQlM0ElMjBUaGUlMjBLdWJlcm5ldGVzJTIwTm9kZSUyMEFnZW50JTBBRG9jdW1lbnRhdGlvbiUzRGh0dHBzJTNBJTJGJTJGa3ViZXJuZXRlcy5pbyUyRmRvY3MlMkZob21lJTJGJTBBJTBBJTVCU2VydmljZSU1RCUwQVJlc3RhcnQlM0RhbHdheXMlMEFTdGFydExpbWl0SW50ZXJ2YWwlM0QwJTBBUmVzdGFydFNlYyUzRDEwJTBBQ1BVQWNjb3VudGluZyUzRHRydWUlMEFNZW1vcnlBY2NvdW50aW5nJTNEdHJ1ZSUwQSUwQUVudmlyb25tZW50JTNEJTIyUEFUSCUzRCUyRm9wdCUyRmJpbiUzQSUyRmJpbiUzQSUyRnVzciUyRmxvY2FsJTJGc2JpbiUzQSUyRnVzciUyRmxvY2FsJTJGYmluJTNBJTJGdXNyJTJGc2JpbiUzQSUyRnVzciUyRmJpbiUzQSUyRnNiaW4lMkYlMjIlMEFFbnZpcm9ubWVudEZpbGUlM0QtJTJGZXRjJTJGZW52aXJvbm1lbnQlMEFFbnZpcm9ubWVudEZpbGUlM0QlMkZldGMlMkZrdWJlcm5ldGVzJTJGbm9kZWlwLmNvbmYlMEElMEFFeGVjU3RhcnRQcmUlM0QlMkZiaW4lMkZiYXNoJTIwJTJGb3B0JTJGbG9hZC1rZXJuZWwtbW9kdWxlcy5zaCUwQUV4ZWNTdGFydFByZSUzRCUyRmJpbiUyRmJhc2glMjAlMkZvcHQlMkZiaW4lMkZzZXR1cF9uZXRfZW52LnNoJTBBRXhlY1N0YXJ0JTNEJTJGb3B0JTJGYmluJTJGa3ViZWxldCUyMCUyNEtVQkVMRVRfRVhUUkFfQVJHUyUyMCU1QyUwQSUyMCUyMC0tYm9vdHN0cmFwLWt1YmVjb25maWclM0QlMkZldGMlMkZrdWJlcm5ldGVzJTJGYm9vdHN0cmFwLWt1YmVsZXQuY29uZiUyMCU1QyUwQSUyMCUyMC0ta3ViZWNvbmZpZyUzRCUyRnZhciUyRmxpYiUyRmt1YmVsZXQlMkZrdWJlY29uZmlnJTIwJTVDJTBBJTIwJTIwLS1jb25maWclM0QlMkZldGMlMkZrdWJlcm5ldGVzJTJGa3ViZWxldC5jb25mJTIwJTVDJTBBJTIwJTIwLS1uZXR3b3JrLXBsdWdpbiUzRGNuaSUyMCU1QyUwQSUyMCUyMC0tY2VydC1kaXIlM0QlMkZldGMlMkZrdWJlcm5ldGVzJTJGcGtpJTIwJTVDJTBBJTIwJTIwLS1jbG91ZC1wcm92aWRlciUzRGF3cyUyMCU1QyUwQSUyMCUyMC0tY2xvdWQtY29uZmlnJTNEJTJGZXRjJTJGa3ViZXJuZXRlcyUyRmNsb3VkLWNvbmZpZyUyMCU1QyUwQSUyMCUyMC0tZHluYW1pYy1jb25maWctZGlyJTNEJTJGZXRjJTJGa3ViZXJuZXRlcyUyRmR5bmFtaWMtY29uZmlnLWRpciUyMCU1QyUwQSUyMCUyMC0tZmVhdHVyZS1nYXRlcyUzRER5bmFtaWNLdWJlbGV0Q29uZmlnJTNEdHJ1ZSUyMCU1QyUwQSUyMCUyMC0tZXhpdC1vbi1sb2NrLWNvbnRlbnRpb24lMjAlNUMlMEElMjAlMjAtLWxvY2stZmlsZSUzRCUyRnRtcCUyRmt1YmVsZXQubG9jayUyMCU1QyUwQSUyMCUyMC0tY29udGFpbmVyLXJ1bnRpbWUlM0RyZW1vdGUlMjAlNUMlMEElMjAlMjAtLWNvbnRhaW5lci1ydW50aW1lLWVuZHBvaW50JTNEdW5peCUzQSUyRiUyRiUyRnJ1biUyRmNvbnRhaW5lcmQlMkZjb250YWluZXJkLnNvY2slMjAlNUMlMEElMjAlMjAtLW5vZGUtaXAlMjAlMjQlN0JLVUJFTEVUX05PREVfSVAlN0QlMEElMEElNUJJbnN0YWxsJTVEJTBBV2FudGVkQnklM0RtdWx0aS11c2VyLnRhcmdldCUwQSIsInZlcmlmaWNhdGlvbiI6e319LCJtb2RlIjo0MjB9LHsiZmlsZXN5c3RlbSI6InJvb3QiLCJwYXRoIjoiL2V0Yy9rdWJlcm5ldGVzL2Nsb3VkLWNvbmZpZyIsImNvbnRlbnRzIjp7InNvdXJjZSI6ImRhdGE6LCU1Qmdsb2JhbCU1RCUwQVpvbmUlM0QlMjIlMjIlMEFWUEMlM0QlMjIlMjIlMEFTdWJuZXRJRCUzRCUyMnRlc3Qtc3VibmV0JTIyJTBBIiwidmVyaWZpY2F0aW9uIjp7fX0sIm1vZGUiOjI1Nn0seyJmaWxlc3lzdGVtIjoicm9vdCIsInBhdGgiOiIvZXRjL2t1YmVybmV0ZXMva3ViZWxldC5jb25mIiwiY29udGVudHMiOnsic291cmNlIjoiZGF0YTosYXBpVmVyc2lvbiUzQSUyMGt1YmVsZXQuY29uZmlnLms4cy5pbyUyRnYxYmV0YTElMEFraW5kJTNBJTIwS3ViZWxldENvbmZpZ3VyYXRpb24lMEFhdXRoZW50aWNhdGlvbiUzQSUwQSUyMCUyMGFub255bW91cyUzQSUwQSUyMCUyMCUyMCUyMGVuYWJsZWQlM0ElMjBmYWxzZSUwQSUyMCUyMHdlYmhvb2slM0ElMEElMjAlMjAlMjAlMjBlbmFibGVkJTNBJTIwdHJ1ZSUwQSUyMCUyMHg1MDklM0ElMEElMjAlMjAlMjAlMjBjbGllbnRDQUZpbGUlM0ElMjAlMkZldGMlMkZrdWJlcm5ldGVzJTJGcGtpJTJGY2EuY3J0JTBBYXV0aG9yaXphdGlvbiUzQSUwQSUyMCUyMG1vZGUlM0ElMjBXZWJob29rJTBBY2dyb3VwRHJpdmVyJTNBJTIwc3lzdGVtZCUwQWNsdXN0ZXJETlMlM0ElMEEtJTIwJTIyMTAuMC4wLjAlMjIlMEFjbHVzdGVyRG9tYWluJTNBJTIwY2x1c3Rlci5sb2NhbCUwQWNvbnRhaW5lckxvZ01heFNpemUlM0ElMjAxMDBNaSUwQWNvbnRhaW5lckxvZ01heEZpbGVzJTNBJTIwNSUwQWZlYXR1cmVHYXRlcyUzQSUwQSUyMCUyMEdyYWNlZnVsTm9kZVNodXRkb3duJTNBJTIwdHJ1ZSUwQSUyMCUyMElkZW50aWZ5UG9kT1MlM0ElMjBmYWxzZSUwQXByb3RlY3RLZXJuZWxEZWZhdWx0cyUzQSUyMHRydWUlMEFyZWFkT25seVBvcnQlM0ElMjAwJTBBcm90YXRlQ2VydGlmaWNhdGVzJTNBJTIwdHJ1ZSUwQXNlcnZlclRMU0Jvb3RzdHJhcCUzQSUyMHRydWUlMEFzdGF0aWNQb2RQYXRoJTNBJTIwJTJGZXRjJTJGa3ViZXJuZXRlcyUyRm1hbmlmZXN0cyUwQWt1YmVSZXNlcnZlZCUzQSUwQSUyMCUyMGNwdSUzQSUyMDIwMG0lMEElMjAlMjBlcGhlbWVyYWwtc3RvcmFnZSUzQSUyMDFHaSUwQSUyMCUyMG1lbW9yeSUzQSUyMDIwME1pJTBBc3lzdGVtUmVzZXJ2ZWQlM0ElMEElMjAlMjBjcHUlM0ElMjAyMDBtJTBBJTIwJTIwZXBoZW1lcmFsLXN0b3JhZ2UlM0ElMjAxR2klMEElMjAlMjBtZW1vcnklM0ElMjAyMDBNaSUwQWV2aWN0aW9uSGFyZCUzQSUwQSUyMCUyMGltYWdlZnMuYXZhaWxhYmxlJTNBJTIwMTUlMjUlMEElMjAlMjBtZW1vcnkuYXZhaWxhYmxlJTNBJTIwMTAwTWklMEElMjAlMjBub2RlZnMuYXZhaWxhYmxlJTNBJTIwMTAlMjUlMEElMjAlMjBub2RlZnMuaW5vZGVzRnJlZSUzQSUyMDUlMjUlMEF0bHNDaXBoZXJTdWl0ZXMlM0ElMEEtJTIwVExTX0FFU18xMjhfR0NNX1NIQTI1NiUwQS0lMjBUTFNfQUVTXzI1Nl9HQ01fU0hBMzg0JTBBLSUyMFRMU19DSEFDSEEyMF9QT0xZMTMwNV9TSEEyNTYlMEEtJTIwVExTX0VDREhFX0VDRFNBX1dJVEhfQUVTXzEyOF9HQ01fU0hBMjU2JTBBLSUyMFRMU19FQ0RIRV9FQ0RTQV9XSVRIX0FFU18yNTZfR0NNX1NIQTM4NCUwQS0lMjBUTFNfRUNESEVfRUNEU0FfV0lUSF9DSEFDSEEyMF9QT0xZMTMwNSUwQS0lMjBUTFNfRUNESEVfUlNBX1dJVEhfQUVTXzEyOF9HQ01fU0hBMjU2JTBBLSUyMFRMU19FQ0RIRV9SU0FfV0lUSF9BRVNfMjU2X0dDTV9TSEEzODQlMEEtJTIwVExTX0VDREhFX1JTQV9XSVRIX0NIQUNIQTIwX1BPTFkxMzA1JTBBdm9sdW1lUGx1Z2luRGlyJTNBJTIwJTJGdmFyJTJGbGliJTJGa3ViZWxldCUyRnZvbHVtZXBsdWdpbnMlMEEiLCJ2ZXJpZmljYXRpb24iOnt9fSwibW9kZSI6NDIwfSx7ImZpbGVzeXN0ZW0iOiJyb290IiwicGF0aCI6Ii9ldGMvc3lzdGVtZC9zeXN0ZW0va3ViZWxldC1oZWFsdGhjaGVjay5zZXJ2aWNlIiwiY29udGVudHMiOnsic291cmNlIjoiZGF0YTosJTVCVW5pdCU1RCUwQVJlcXVpcmVzJTNEa3ViZWxldC5zZXJ2aWNlJTBBQWZ0ZXIlM0RrdWJlbGV0LnNlcnZpY2UlMEElMEElNUJTZXJ2aWNlJTVEJTBBRXhlY1N0YXJ0JTNEJTJGb3B0JTJGYmluJTJGaGVhbHRoLW1vbml0b3Iuc2glMjBrdWJlbGV0JTBBJTBBJTVCSW5zdGFsbCU1RCUwQVdhbnRlZEJ5JTNEbXVsdGktdXNlci50YXJnZXQlMEEiLCJ2ZXJpZmljYXRpb24iOnt9fSwibW9kZSI6NDIwfSx7ImZpbGVzeXN0ZW0iOiJyb290IiwicGF0aCI6Ii9wcm9jL3N5cy9rZXJuZWwvcGFuaWNfb25fb29wcyIsImNvbnRlbnRzIjp7InNvdXJjZSI6ImRhdGE6LDElMEEiLCJ2ZXJpZmljYXRpb24iOnt9fSwibW9kZSI6NDIwfSx7ImZpbGVzeXN0ZW0iOiJyb290IiwicGF0aCI6Ii9wcm9jL3N5cy9rZXJuZWwvcGFuaWMiLCJjb250ZW50cyI6eyJzb3VyY2UiOiJkYXRhOiwxMCUwQSIsInZlcmlmaWNhdGlvbiI6e319LCJtb2RlIjo0MjB9LHsiZmlsZXN5c3RlbSI6InJvb3QiLCJwYXRoIjoiL3Byb2Mvc3lzL3ZtL292ZXJjb21taXRfbWVtb3J5IiwiY29udGVudHMiOnsic291cmNlIjoiZGF0YTosMSUwQSIsInZlcmlmaWNhdGlvbiI6e319LCJtb2RlIjo0MjB9LHsiZmlsZXN5c3RlbSI6InJvb3QiLCJwYXRoIjoiL2V0Yy9zc2gvc3NoZF9jb25maWciLCJjb250ZW50cyI6eyJzb3VyY2UiOiJkYXRhOiwlMjMlMjBVc2UlMjBtb3N0JTIwZGVmYXVsdHMlMjBmb3IlMjBzc2hkJTIwY29uZmlndXJhdGlvbi4lMEFTdWJzeXN0ZW0lMjBzZnRwJTIwaW50ZXJuYWwtc2Z0cCUwQUNsaWVudEFsaXZlSW50ZXJ2YWwlMjAxODAlMEFVc2VETlMlMjBubyUwQVVzZVBBTSUyMHllcyUwQVByaW50TGFzdExvZyUyMG5vJTIwJTIzJTIwaGFuZGxlZCUyMGJ5JTIwUEFNJTBBUHJpbnRNb3RkJTIwbm8lMjAlMjMlMjBoYW5kbGVkJTIwYnklMjBQQU0lMEFQYXNzd29yZEF1dGhlbnRpY2F0aW9uJTIwbm8lMEFDaGFsbGVuZ2VSZXNwb25zZUF1dGhlbnRpY2F0aW9uJTIwbm8lMEEiLCJ2ZXJpZmljYXRpb24iOnt9fSwibW9kZSI6Mzg0fSx7ImZpbGVzeXN0ZW0iOiJyb290IiwicGF0aCI6Ii9ldGMvY29udGFpbmVyZC9jb25maWcudG9tbCIsImNvbnRlbnRzIjp7InNvdXJjZSI6ImRhdGE6LHZlcnNpb24lMjAlM0QlMjAyJTBBJTBBJTVCbWV0cmljcyU1RCUwQWFkZHJlc3MlMjAlM0QlMjAlMjIxMjcuMC4wLjElM0ExMzM4JTIyJTBBJTBBJTVCcGx1Z2lucyU1RCUwQSU1QnBsdWdpbnMuJTIyaW8uY29udGFpbmVyZC5ncnBjLnYxLmNyaSUyMiU1RCUwQXNhbmRib3hfaW1hZ2UlMjAlM0QlMjAlMjIxOTIuMTY4LjEwMC4xMDAlM0E1MDAwJTJGa3ViZXJuZXRlcyUyRnBhdXNlJTNBdjMuMSUyMiUwQSU1QnBsdWdpbnMuJTIyaW8uY29udGFpbmVyZC5ncnBjLnYxLmNyaSUyMi5jb250YWluZXJkJTVEJTBBJTVCcGx1Z2lucy4lMjJpby5jb250YWluZXJkLmdycGMudjEuY3JpJTIyLmNvbnRhaW5lcmQucnVudGltZXMlNUQlMEElNUJwbHVnaW5zLiUyMmlvLmNvbnRhaW5lcmQuZ3JwYy52MS5jcmklMjIuY29udGFpbmVyZC5ydW50aW1lcy5ydW5jJTVEJTBBcnVudGltZV90eXBlJTIwJTNEJTIwJTIyaW8uY29udGFpbmVyZC5ydW5jLnYyJTIyJTBBJTVCcGx1Z2lucy4lMjJpby5jb250YWluZXJkLmdycGMudjEuY3JpJTIyLmNvbnRhaW5lcmQucnVudGltZXMucnVuYy5vcHRpb25zJTVEJTBBU3lzdGVtZENncm91cCUyMCUzRCUyMHRydWUlMEElNUJwbHVnaW5zLiUyMmlvLmNvbnRhaW5lcmQuZ3JwYy52MS5jcmklMjIucmVnaXN0cnklNUQlMEElNUJwbHVnaW5zLiUyMmlvLmNvbnRhaW5lcmQuZ3JwYy52MS5jcmklMjIucmVnaXN0cnkubWlycm9ycyU1RCUwQSU1QnBsdWdpbnMuJTIyaW8uY29udGFpbmVyZC5ncnBjLnYxLmNyaSUyMi5yZWdpc3RyeS5taXJyb3JzLiUyMmRvY2tlci5pbyUyMiU1RCUwQWVuZHBvaW50JTIwJTNEJTIwJTVCJTIyaHR0cHMlM0ElMkYlMkZyZWdpc3RyeS5kb2NrZXItY24uY29tJTIyJTVEJTBBJTVCcGx1Z2lucy4lMjJpby5jb250YWluZXJkLmdycGMudjEuY3JpJTIyLnJlZ2lzdHJ5LmNvbmZpZ3MlNUQlMEElNUJwbHVnaW5zLiUyMmlvLmNvbnRhaW5lcmQuZ3JwYy52MS5jcmklMjIucmVnaXN0cnkuY29uZmlncy4lMjIxMC4wLjAuMSUzQTUwMDAlMjIlNUQlMEElNUJwbHVnaW5zLiUyMmlvLmNvbnRhaW5lcmQuZ3JwYy52MS5jcmklMjIucmVnaXN0cnkuY29uZmlncy4lMjIxMC4wLjAuMSUzQTUwMDAlMjIudGxzJTVEJTBBaW5zZWN1cmVfc2tpcF92ZXJpZnklMjAlM0QlMjB0cnVlJTBBJTVCcGx1Z2lucy4lMjJpby5jb250YWluZXJkLmdycGMudjEuY3JpJTIyLnJlZ2lzdHJ5LmNvbmZpZ3MuJTIyMTkyLjE2OC4xMDAuMTAwJTNBNTAwMCUyMiU1RCUwQSU1QnBsdWdpbnMuJTIyaW8uY29udGFpbmVyZC5ncnBjLnYxLmNyaSUyMi5yZWdpc3RyeS5jb25maWdzLiUyMjE5Mi4xNjguMTAwLjEwMCUzQTUwMDAlMjIudGxzJTVEJTBBaW5zZWN1cmVfc2tpcF92ZXJpZnklMjAlM0QlMjB0cnVlJTBBIiwidmVyaWZpY2F0aW9uIjp7fX0sIm1vZGUiOjQyMH0seyJmaWxlc3lzdGVtIjoicm9vdCIsInBhdGgiOiIvZXRjL3N5c3RlbWQvc3lzdGVtL2NvbnRhaW5lcmQuc2VydmljZS5kLzEwLWN1c3RvbS5jb25mIiwiY29udGVudHMiOnsic291cmNlIjoiZGF0YTosJTVCU2VydmljZSU1RCUwQVJlc3RhcnQlM0RhbHdheXMlMEFFbnZpcm9ubWVudEZpbGUlM0QtJTJGZXRjJTJGZW52aXJvbm1lbnQlMEFFbnZpcm9ubWVudEZpbGUlM0QlMkZydW4lMkZtZXRhZGF0YSUyRnRvcmN4JTBBRW52aXJvbm1lbnQlM0RDT05UQUlORVJEX0NPTkZJRyUzRCUyRmV0YyUyRmNvbnRhaW5lcmQlMkZjb25maWcudG9tbCUwQUV4ZWNTdGFydCUzRCUwQUV4ZWNTdGFydCUzRCUyRnVzciUyRmJpbiUyRmVudiUyMFBBVEglM0QlMjQlN0JUT1JDWF9CSU5ESVIlN0QlM0ElMjQlN0JQQVRIJTdEJTIwJTI0JTdCVE9SQ1hfQklORElSJTdEJTJGY29udGFpbmVyZCUyMC0tY29uZmlnJTIwJTI0JTdCQ09OVEFJTkVSRF9DT05GSUclN0QlMEEiLCJ2ZXJpZmljYXRpb24iOnt9fSwibW9kZSI6NDIwfSx7ImZpbGVzeXN0ZW0iOiJyb290IiwicGF0aCI6Ii9ldGMvY3JpY3RsLnlhbWwiLCJjb250ZW50cyI6eyJzb3VyY2UiOiJkYXRhOixydW50aW1lLWVuZHBvaW50JTNBJTIwdW5peCUzQSUyRiUyRiUyRnJ1biUyRmNvbnRhaW5lcmQlMkZjb250YWluZXJkLnNvY2slMEEiLCJ2ZXJpZmljYXRpb24iOnt9fSwibW9kZSI6NDIwfV19LCJzeXN0ZW1kIjp7InVuaXRzIjpbeyJjb250ZW50cyI6IltJbnN0YWxsXVxuV2FudGVkQnk9bXVsdGktdXNlci50YXJnZXRcblxuW1VuaXRdXG5SZXF1aXJlcz1kb3dubG9hZC1zY3JpcHQuc2VydmljZVxuUmVxdWlyZXM9bm9kZWlwLnNlcnZpY2VcbkFmdGVyPWRvd25sb2FkLXNjcmlwdC5zZXJ2aWNlXG5BZnRlcj1ub2RlaXAuc2VydmljZVxuXG5bU2VydmljZV1cblR5cGU9b25lc2hvdFxuUmVtYWluQWZ0ZXJFeGl0PXRydWVcbkVudmlyb25tZW50RmlsZT0tL2V0Yy9lbnZpcm9ubWVudFxuRXhlY1N0YXJ0PS9vcHQvYmluL3NldHVwXG4iLCJlbmFibGVkIjp0cnVlLCJuYW1lIjoic2V0dXAuc2VydmljZSJ9LHsiY29udGVudHMiOiJbSW5zdGFsbF1cbldhbnRlZEJ5PW11bHRpLXVzZXIudGFyZ2V0XG5cbltVbml0XVxuUmVxdWlyZXM9bmV0d29yay1vbmxpbmUudGFyZ2V0XG5BZnRlcj1uZXR3b3JrLW9ubGluZS50YXJnZXRcblxuW1NlcnZpY2VdXG5UeXBlPW9uZXNob3RcblJlbWFpbkFmdGVyRXhpdD10cnVlXG5FbnZpcm9ubWVudEZpbGU9LS9ldGMvZW52aXJvbm1lbnRcbkV4ZWNTdGFydD0vb3B0L2Jpbi9kb3dubG9hZC5zaFxuIiwiZW5hYmxlZCI6dHJ1ZSwibmFtZSI6ImRvd25sb2FkLXNjcmlwdC5zZXJ2aWNlIn0seyJjb250ZW50cyI6IltVbml0XVxuRGVzY3JpcHRpb249U2V0dXAgS3ViZWxldCBOb2RlIElQIEVudlxuUmVxdWlyZXM9bmV0d29yay1vbmxpbmUudGFyZ2V0XG5BZnRlcj1uZXR3b3JrLW9ubGluZS50YXJnZXRcblxuW1NlcnZpY2VdXG5FeGVjU3RhcnQ9L29wdC9iaW4vc2V0dXBfbmV0X2Vudi5zaFxuUmVtYWluQWZ0ZXJFeGl0PXllc1xuVHlwZT1vbmVzaG90XG5bSW5zdGFsbF1cbldhbnRlZEJ5PW11bHRpLXVzZXIudGFyZ2V0XG4iLCJlbmFibGVkIjp0cnVlLCJuYW1lIjoibm9kZWlwLnNlcnZpY2UifSx7ImNvbnRlbnRzIjoiW1VuaXRdXG5EZXNjcmlwdGlvbj1TZXR1cCBTdGF0aWMgTmV0d29ya2luZ1xuUmVxdWlyZXM9bmV0d29yay1vbmxpbmUudGFyZ2V0XG5BZnRlcj1uZXR3b3JrLW9ubGluZS50YXJnZXRcblxuW1NlcnZpY2VdXG5FeGVjU3RhcnQ9L29wdC9iaW4vY29uZmlndXJlX3N0YXRpY19uZXR3b3JrLnNoXG5SZW1haW5BZnRlckV4aXQ9eWVzXG5UeXBlPW9uZXNob3RcbltJbnN0YWxsXVxuV2FudGVkQnk9bXVsdGktdXNlci50YXJnZXRcbiIsImVuYWJsZWQiOnRydWUsIm5hbWUiOiJzdGF0aWMtbmV0d29yay1zY3JpcHQuc2VydmljZSJ9XX19 immutable: true kind: Secret metadata: creationTimestamp: null - name: flatcar-aws-containerd-osc-provisioning + name: flatcar-aws-containerd-kube-system-osc-provisioning namespace: cloud-init-settings resourceVersion: "1" +type: Opaque diff --git a/pkg/controllers/osc/testdata/secret-flatcar-aws-docker.yaml b/pkg/controllers/osc/testdata/secret-flatcar-aws-docker.yaml index 185684f1..d7b25f56 100644 --- a/pkg/controllers/osc/testdata/secret-flatcar-aws-docker.yaml +++ b/pkg/controllers/osc/testdata/secret-flatcar-aws-docker.yaml @@ -1,10 +1,11 @@ apiVersion: v1 data: - cloud-config: eyJpZ25pdGlvbiI6eyJjb25maWciOnt9LCJzZWN1cml0eSI6eyJ0bHMiOnt9fSwidGltZW91dHMiOnt9LCJ2ZXJzaW9uIjoiMi4zLjAifSwibmV0d29ya2QiOnt9LCJwYXNzd2QiOnsidXNlcnMiOlt7Im5hbWUiOiJjb3JlIiwic3NoQXV0aG9yaXplZEtleXMiOlsic3NoLXJzYSBBQUFBQjNOemFDMXljMkVBQUFBREFRQUJBQUFDQVFEZE9JaFltekNLNURTVkx1M2MiXX1dfSwic3RvcmFnZSI6eyJmaWxlcyI6W3siZmlsZXN5c3RlbSI6InJvb3QiLCJwYXRoIjoiL2V0Yy9zeXN0ZW1kL2pvdXJuYWxkLmNvbmYuZC9tYXhfZGlza191c2UuY29uZiIsImNvbnRlbnRzIjp7InNvdXJjZSI6ImRhdGE6LCU1QkpvdXJuYWwlNUQlMEFTeXN0ZW1NYXhVc2UlM0Q1RyUwQSIsInZlcmlmaWNhdGlvbiI6e319LCJtb2RlIjo0MjB9LHsiZmlsZXN5c3RlbSI6InJvb3QiLCJwYXRoIjoiL29wdC9sb2FkLWtlcm5lbC1tb2R1bGVzLnNoIiwiY29udGVudHMiOnsic291cmNlIjoiZGF0YTosJTIzISUyRnVzciUyRmJpbiUyRmVudiUyMGJhc2glMEFzZXQlMjAtZXVvJTIwcGlwZWZhaWwlMEElMEFtb2Rwcm9iZSUyMGlwX3ZzJTBBbW9kcHJvYmUlMjBpcF92c19yciUwQW1vZHByb2JlJTIwaXBfdnNfd3JyJTBBbW9kcHJvYmUlMjBpcF92c19zaCUwQSUwQWlmJTIwbW9kaW5mbyUyMG5mX2Nvbm50cmFja19pcHY0JTIwJTI2JTNFJTIwJTJGZGV2JTJGbnVsbCUzQiUyMHRoZW4lMEElMjAlMjBtb2Rwcm9iZSUyMG5mX2Nvbm50cmFja19pcHY0JTBBZWxzZSUwQSUyMCUyMG1vZHByb2JlJTIwbmZfY29ubnRyYWNrJTBBZmklMEEiLCJ2ZXJpZmljYXRpb24iOnt9fSwibW9kZSI6NDkzfSx7ImZpbGVzeXN0ZW0iOiJyb290IiwicGF0aCI6Ii9ldGMvc3lzY3RsLmQvazhzLmNvbmYiLCJjb250ZW50cyI6eyJzb3VyY2UiOiJkYXRhOixuZXQuYnJpZGdlLmJyaWRnZS1uZi1jYWxsLWlwNnRhYmxlcyUyMCUzRCUyMDElMEFuZXQuYnJpZGdlLmJyaWRnZS1uZi1jYWxsLWlwdGFibGVzJTIwJTNEJTIwMSUwQWtlcm5lbC5wYW5pY19vbl9vb3BzJTIwJTNEJTIwMSUwQWtlcm5lbC5wYW5pYyUyMCUzRCUyMDEwJTBBbmV0LmlwdjQuaXBfZm9yd2FyZCUyMCUzRCUyMDElMEF2bS5vdmVyY29tbWl0X21lbW9yeSUyMCUzRCUyMDElMEFmcy5pbm90aWZ5Lm1heF91c2VyX3dhdGNoZXMlMjAlM0QlMjAxMDQ4NTc2JTBBIiwidmVyaWZpY2F0aW9uIjp7fX0sIm1vZGUiOjQyMH0seyJmaWxlc3lzdGVtIjoicm9vdCIsInBhdGgiOiIvb3B0L2Jpbi9zZXR1cF9uZXRfZW52LnNoIiwiY29udGVudHMiOnsic291cmNlIjoiZGF0YTosJTIzISUyRnVzciUyRmJpbiUyRmVudiUyMGJhc2glMEFlY2hvZGF0ZSgpJTIwJTdCJTBBJTIwJTIwZWNobyUyMCUyMiU1QiUyNChkYXRlJTIwLUlzKSU1RCUyMiUyMCUyMiUyNCU0MCUyMiUwQSU3RCUwQSUwQSUyMyUyMGdldCUyMHRoZSUyMGRlZmF1bHQlMjBpbnRlcmZhY2UlMjBJUCUyMGFkZHJlc3MlMEFERUZBVUxUX0lGQ19JUCUzRCUyNChpcCUyMC1vJTIwJTIwcm91dGUlMjBnZXQlMjAxJTIwJTdDJTIwZ3JlcCUyMC1vUCUyMCUyMnNyYyUyMCU1Q0slNUNTJTJCJTIyKSUwQSUwQWlmJTIwJTVCJTIwLXolMjAlMjIlMjQlN0JERUZBVUxUX0lGQ19JUCU3RCUyMiUyMCU1RCUwQXRoZW4lMEElMjAlMjBlY2hvZGF0ZSUyMCUyMkZhaWxlZCUyMHRvJTIwZ2V0JTIwSVAlMjBhZGRyZXNzJTIwZm9yJTIwdGhlJTIwZGVmYXVsdCUyMHJvdXRlJTIwaW50ZXJmYWNlJTIyJTBBJTIwJTIwZXhpdCUyMDElMEFmaSUwQSUwQSUyMyUyMGdldCUyMHRoZSUyMGZ1bGwlMjBob3N0bmFtZSUwQUZVTExfSE9TVE5BTUUlM0QlMjQoaG9zdG5hbWUlMjAtZiklMEElMjMlMjBpZiUyMCUyRmV0YyUyRmhvc3RuYW1lJTIwaXMlMjBub3QlMjBlbXB0eSUyMHRoZW4lMjB1c2UlMjB0aGUlMjBob3N0bmFtZSUyMGZyb20lMjB0aGVyZSUwQWlmJTIwJTVCJTIwLXMlMjAlMkZldGMlMkZob3N0bmFtZSUyMCU1RCUzQiUyMHRoZW4lMEElMjAlMjAlMjAlMjBGVUxMX0hPU1ROQU1FJTNEJTI0KGNhdCUyMCUyRmV0YyUyRmhvc3RuYW1lKSUwQWZpJTBBJTBBJTIzJTIwd3JpdGUlMjB0aGUlMjBub2RlaXBfZW52JTIwZmlsZSUwQSUyMyUyMHdlJTIwbmVlZCUyMHRoZSUyMGxpbmUlMjBiZWxvdyUyMGJlY2F1c2UlMjBmbGF0Y2FyJTIwaGFzJTIwdGhlJTIwc2FtZSUyMHN0cmluZyUyMCUyMmNvcmVvcyUyMiUyMGluJTIwdGhhdCUyMGZpbGUlMEFpZiUyMGdyZXAlMjAtcSUyMGNvcmVvcyUyMCUyRmV0YyUyRm9zLXJlbGVhc2UlMEF0aGVuJTBBJTIwJTIwZWNobyUyMC1lJTIwJTIyS1VCRUxFVF9OT0RFX0lQJTNEJTI0JTdCREVGQVVMVF9JRkNfSVAlN0QlNUNuS1VCRUxFVF9IT1NUTkFNRSUzRCUyNCU3QkZVTExfSE9TVE5BTUUlN0QlMjIlMjAlM0UlMjAlMkZldGMlMkZrdWJlcm5ldGVzJTJGbm9kZWlwLmNvbmYlMEFlbGlmJTIwJTVCJTIwISUyMC1kJTIwJTJGZXRjJTJGc3lzdGVtZCUyRnN5c3RlbSUyRmt1YmVsZXQuc2VydmljZS5kJTIwJTVEJTBBdGhlbiUwQSUyMCUyMGVjaG9kYXRlJTIwJTIyQ2FuJ3QlMjBmaW5kJTIwa3ViZWxldCUyMHNlcnZpY2UlMjBleHRyYXMlMjBkaXJlY3RvcnklMjIlMEElMjAlMjBleGl0JTIwMSUwQWVsc2UlMEElMjAlMjBlY2hvJTIwLWUlMjAlMjIlNUJTZXJ2aWNlJTVEJTVDbkVudmlyb25tZW50JTNEJTVDJTIyS1VCRUxFVF9OT0RFX0lQJTNEJTI0JTdCREVGQVVMVF9JRkNfSVAlN0QlNUMlMjIlNUNuRW52aXJvbm1lbnQlM0QlNUMlMjJLVUJFTEVUX0hPU1ROQU1FJTNEJTI0JTdCRlVMTF9IT1NUTkFNRSU3RCU1QyUyMiUyMiUyMCUzRSUyMCUyRmV0YyUyRnN5c3RlbWQlMkZzeXN0ZW0lMkZrdWJlbGV0LnNlcnZpY2UuZCUyRm5vZGVpcC5jb25mJTBBZmklMEEiLCJ2ZXJpZmljYXRpb24iOnt9fSwibW9kZSI6NDkzfSx7ImZpbGVzeXN0ZW0iOiJyb290IiwicGF0aCI6Ii9vcHQvYmluL2NvbmZpZ3VyZV9zdGF0aWNfbmV0d29yay5zaCIsImNvbnRlbnRzIjp7InNvdXJjZSI6ImRhdGE6LCUyMyElMkZ1c3IlMkZiaW4lMkZlbnYlMjBiYXNoJTBBc2V0JTIwLXhldW8lMjBwaXBlZmFpbCUwQSIsInZlcmlmaWNhdGlvbiI6e319LCJtb2RlIjo0OTN9LHsiZmlsZXN5c3RlbSI6InJvb3QiLCJwYXRoIjoiL29wdC9iaW4vZG93bmxvYWQuc2giLCJjb250ZW50cyI6eyJzb3VyY2UiOiJkYXRhOiwlMjMhJTJGdXNyJTJGYmluJTJGZW52JTIwYmFzaCUwQXNldCUyMC14ZXVvJTIwcGlwZWZhaWwlMEFvcHRfYmluJTNEJTJGb3B0JTJGYmluJTBBdXNyX2xvY2FsX2JpbiUzRCUyRnVzciUyRmxvY2FsJTJGYmluJTBBY25pX2Jpbl9kaXIlM0QlMkZvcHQlMkZjbmklMkZiaW4lMEFta2RpciUyMC1wJTIwJTJGZXRjJTJGY25pJTJGbmV0LmQlMjAlMkZldGMlMkZrdWJlcm5ldGVzJTJGZHluYW1pYy1jb25maWctZGlyJTIwJTJGZXRjJTJGa3ViZXJuZXRlcyUyRm1hbmlmZXN0cyUyMCUyMiUyNG9wdF9iaW4lMjIlMjAlMjIlMjRjbmlfYmluX2RpciUyMiUwQWFyY2glM0QlMjQlN0JIT1NUX0FSQ0gtJTdEJTBBaWYlMjAlNUIlMjAteiUyMCUyMiUyNGFyY2glMjIlMjAlNUQlMEF0aGVuJTBBY2FzZSUyMCUyNCh1bmFtZSUyMC1tKSUyMGluJTBBeDg2XzY0KSUwQSUyMCUyMCUyMCUyMGFyY2glM0QlMjJhbWQ2NCUyMiUwQSUyMCUyMCUyMCUyMCUzQiUzQiUwQWFhcmNoNjQpJTBBJTIwJTIwJTIwJTIwYXJjaCUzRCUyMmFybTY0JTIyJTBBJTIwJTIwJTIwJTIwJTNCJTNCJTBBKiklMEElMjAlMjAlMjAlMjBlY2hvJTIwJTIydW5zdXBwb3J0ZWQlMjBDUFUlMjBhcmNoaXRlY3R1cmUlMkMlMjBleGl0aW5nJTIyJTBBJTIwJTIwJTIwJTIwZXhpdCUyMDElMEElMjAlMjAlMjAlMjAlM0IlM0IlMEFlc2FjJTBBZmklMEFDTklfVkVSU0lPTiUzRCUyMiUyNCU3QkNOSV9WRVJTSU9OJTNBLXYwLjguNyU3RCUyMiUwQWNuaV9iYXNlX3VybCUzRCUyMmh0dHBzJTNBJTJGJTJGZ2l0aHViLmNvbSUyRmNvbnRhaW5lcm5ldHdvcmtpbmclMkZwbHVnaW5zJTJGcmVsZWFzZXMlMkZkb3dubG9hZCUyRiUyNENOSV9WRVJTSU9OJTIyJTBBY25pX2ZpbGVuYW1lJTNEJTIyY25pLXBsdWdpbnMtbGludXgtJTI0YXJjaC0lMjRDTklfVkVSU0lPTi50Z3olMjIlMEFjdXJsJTIwLUxmbyUyMCUyMiUyNGNuaV9iaW5fZGlyJTJGJTI0Y25pX2ZpbGVuYW1lJTIyJTIwJTIyJTI0Y25pX2Jhc2VfdXJsJTJGJTI0Y25pX2ZpbGVuYW1lJTIyJTBBY25pX3N1bSUzRCUyNChjdXJsJTIwLUxmJTIwJTIyJTI0Y25pX2Jhc2VfdXJsJTJGJTI0Y25pX2ZpbGVuYW1lLnNoYTI1NiUyMiklMEFjZCUyMCUyMiUyNGNuaV9iaW5fZGlyJTIyJTBBc2hhMjU2c3VtJTIwLWMlMjAlM0MlM0MlM0MlMjIlMjRjbmlfc3VtJTIyJTBBdGFyJTIweHZmJTIwJTIyJTI0Y25pX2ZpbGVuYW1lJTIyJTBBcm0lMjAtZiUyMCUyMiUyNGNuaV9maWxlbmFtZSUyMiUwQWNkJTIwLSUwQUtVQkVfVkVSU0lPTiUzRCUyMiUyNCU3QktVQkVfVkVSU0lPTiUzQS12MS4yMi4xJTdEJTIyJTBBa3ViZV9kaXIlM0QlMjIlMjRvcHRfYmluJTJGa3ViZXJuZXRlcy0lMjRLVUJFX1ZFUlNJT04lMjIlMEFrdWJlX2Jhc2VfdXJsJTNEJTIyaHR0cHMlM0ElMkYlMkZzdG9yYWdlLmdvb2dsZWFwaXMuY29tJTJGa3ViZXJuZXRlcy1yZWxlYXNlJTJGcmVsZWFzZSUyRiUyNEtVQkVfVkVSU0lPTiUyRmJpbiUyRmxpbnV4JTJGJTI0YXJjaCUyMiUwQWt1YmVfc3VtX2ZpbGUlM0QlMjIlMjRrdWJlX2RpciUyRnNoYTI1NiUyMiUwQW1rZGlyJTIwLXAlMjAlMjIlMjRrdWJlX2RpciUyMiUwQSUzQSUyMCUzRSUyMiUyNGt1YmVfc3VtX2ZpbGUlMjIlMEElMEFmb3IlMjBiaW4lMjBpbiUyMGt1YmVsZXQlMjBrdWJlYWRtJTIwa3ViZWN0bCUzQiUyMGRvJTBBJTIwJTIwJTIwJTIwY3VybCUyMC1MZm8lMjAlMjIlMjRrdWJlX2RpciUyRiUyNGJpbiUyMiUyMCUyMiUyNGt1YmVfYmFzZV91cmwlMkYlMjRiaW4lMjIlMEElMjAlMjAlMjAlMjBjaG1vZCUyMCUyQnglMjAlMjIlMjRrdWJlX2RpciUyRiUyNGJpbiUyMiUwQSUyMCUyMCUyMCUyMHN1bSUzRCUyNChjdXJsJTIwLUxmJTIwJTIyJTI0a3ViZV9iYXNlX3VybCUyRiUyNGJpbi5zaGEyNTYlMjIpJTBBJTIwJTIwJTIwJTIwZWNobyUyMCUyMiUyNHN1bSUyMCUyMCUyNGt1YmVfZGlyJTJGJTI0YmluJTIyJTIwJTNFJTNFJTIyJTI0a3ViZV9zdW1fZmlsZSUyMiUwQWRvbmUlMEFzaGEyNTZzdW0lMjAtYyUyMCUyMiUyNGt1YmVfc3VtX2ZpbGUlMjIlMEElMEFmb3IlMjBiaW4lMjBpbiUyMGt1YmVsZXQlMjBrdWJlYWRtJTIwa3ViZWN0bCUzQiUyMGRvJTBBJTIwJTIwJTIwJTIwbG4lMjAtc2YlMjAlMjIlMjRrdWJlX2RpciUyRiUyNGJpbiUyMiUyMCUyMiUyNG9wdF9iaW4lMjIlMkYlMjRiaW4lMEFkb25lJTBBJTBBaWYlMjAlNUIlNUIlMjAhJTIwLXglMjAlMkZvcHQlMkZiaW4lMkZoZWFsdGgtbW9uaXRvci5zaCUyMCU1RCU1RCUzQiUyMHRoZW4lMEElMjAlMjAlMjAlMjBjdXJsJTIwLUxmbyUyMCUyRm9wdCUyRmJpbiUyRmhlYWx0aC1tb25pdG9yLnNoJTIwaHR0cHMlM0ElMkYlMkZyYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tJTJGa3ViZXJtYXRpYyUyRm1hY2hpbmUtY29udHJvbGxlciUyRjc5NjdhMGFmMmI3NWYyOWFkMmFiMjI3ZWVhYTI2ZWE3YjBmMmZiZGUlMkZwa2clMkZ1c2VyZGF0YSUyRnNjcmlwdHMlMkZoZWFsdGgtbW9uaXRvci5zaCUwQSUyMCUyMCUyMCUyMGNobW9kJTIwJTJCeCUyMCUyRm9wdCUyRmJpbiUyRmhlYWx0aC1tb25pdG9yLnNoJTBBZmklMEElMEFzeXN0ZW1jdGwlMjBkaXNhYmxlJTIwZG93bmxvYWQtc2NyaXB0LnNlcnZpY2UlMEEiLCJ2ZXJpZmljYXRpb24iOnt9fSwibW9kZSI6NDkzfSx7ImZpbGVzeXN0ZW0iOiJyb290IiwicGF0aCI6Ii9vcHQvYmluL3NldHVwIiwiY29udGVudHMiOnsic291cmNlIjoiZGF0YTosJTIzISUyRmJpbiUyRmJhc2glMEFzZXQlMjAteGV1byUyMHBpcGVmYWlsJTBBY2F0JTIwJTNDJTNDJTIwRU9GJTIwJTdDJTIwdGVlJTIwJTJGZXRjJTJGcG9sa2l0LTElMkZydWxlcy5kJTJGNjAtbm9yZWJvb3Rfbm9yZXN0YXJ0LnJ1bGVzJTBBcG9sa2l0LmFkZFJ1bGUoZnVuY3Rpb24oYWN0aW9uJTJDJTIwc3ViamVjdCklMjAlN0IlMEElMjAlMjBpZiUyMChhY3Rpb24uaWQlMjAlM0QlM0QlMjAlMjJvcmcuZnJlZWRlc2t0b3AubG9naW4xLnJlYm9vdCUyMiUyMCU3QyU3QyUwQSUyMCUyMCUyMCUyMCUyMCUyMGFjdGlvbi5pZCUyMCUzRCUzRCUyMCUyMm9yZy5mcmVlZGVza3RvcC5sb2dpbjEucmVib290LW11bHRpcGxlLXNlc3Npb25zJTIyKSUyMCU3QiUwQSUyMCUyMCUyMCUyMCUyMCUyMGlmJTIwKHN1YmplY3QudXNlciUyMCUzRCUzRCUyMCUyMmNvcmUlMjIpJTIwJTdCJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwcmV0dXJuJTIwcG9sa2l0LlJlc3VsdC5ZRVMlM0IlMEElMjAlMjAlMjAlMjAlMjAlMjAlN0QlMjBlbHNlJTIwJTdCJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwcmV0dXJuJTIwcG9sa2l0LlJlc3VsdC5BVVRIX0FETUlOJTNCJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTdEJTBBJTIwJTIwJTdEJTBBJTdEKSUzQiUwQUVPRiUwQXN5c3RlbWN0bCUyMHN0b3AlMjBjb250YWluZXJkJTBBc3lzdGVtY3RsJTIwZGlzYWJsZSUyMGNvbnRhaW5lcmQlMEElMEFzeXN0ZW1jdGwlMjBlbmFibGUlMjAtLW5vdyUyMGt1YmVsZXQlMEFzeXN0ZW1jdGwlMjBlbmFibGUlMjAtLW5vdyUyMC0tbm8tYmxvY2slMjBrdWJlbGV0LWhlYWx0aGNoZWNrLnNlcnZpY2UlMEFzeXN0ZW1jdGwlMjBkaXNhYmxlJTIwc2V0dXAuc2VydmljZSUwQSIsInZlcmlmaWNhdGlvbiI6e319LCJtb2RlIjo0OTN9LHsiZmlsZXN5c3RlbSI6InJvb3QiLCJwYXRoIjoiL2V0Yy9rdWJlcm5ldGVzL3BraS9jYS5jcnQiLCJjb250ZW50cyI6eyJzb3VyY2UiOiJkYXRhOiwtLS0tLUJFR0lOJTIwQ0VSVElGSUNBVEUtLS0tLSUwQU1JSUVXakNDQTBLZ0F3SUJBZ0lKQUxmUmxXc0k4WVFITUEwR0NTcUdTSWIzRFFFQkJRVUFNSHN4Q3pBSkJnTlYlMEFCQVlUQWxWVE1Rc3dDUVlEVlFRSUV3SkRRVEVXTUJRR0ExVUVCeE1OVTJGdUlFWnlZVzVqYVhOamJ6RVVNQklHJTBBQTFVRUNoTUxRbkpoWkdacGRIcHBibU14RWpBUUJnTlZCQU1UQ1d4dlkyRnNhRzl6ZERFZE1Cc0dDU3FHU0liMyUwQURRRUpBUllPWW5KaFpFQmtZVzVuWVM1amIyMHdIaGNOTVRRd056RTFNakEwTmpBMVdoY05NVGN3TlRBME1qQTAlMEFOakExV2pCN01Rc3dDUVlEVlFRR0V3SlZVekVMTUFrR0ExVUVDQk1DUTBFeEZqQVVCZ05WQkFjVERWTmhiaUJHJTBBY21GdVkybHpZMjh4RkRBU0JnTlZCQW9UQzBKeVlXUm1hWFI2YVc1ak1SSXdFQVlEVlFRREV3bHNiMk5oYkdodiUwQWMzUXhIVEFiQmdrcWhraUc5dzBCQ1FFV0RtSnlZV1JBWkdGdVoyRXVZMjl0TUlJQklqQU5CZ2txaGtpRzl3MEIlMEFBUUVGQUFPQ0FROEFNSUlCQ2dLQ0FRRUF0NWZBanA0ZlRjZWtXVVRmenNwMGt5aWgxT1lic0dMMEtYMWVSYlNTJTBBUjhPZDAlMkI5UTYySHlueSUyQkdGd01UYjRBJTJGS1U4bXNzb0h2Y2NlU0FBYndmYnhGSyUyRiUyQnM1MVRvYnFVbk9SWnJPb1QlMEFaamtVeWdieVhEU0s5OVlCYmNSMVBpcDh2d01UbTRYS3VMdENpZ2VCQmRqakFRZGdVTzI4TEVOR2xzTW5tZVlrJTBBSmZPRFZHblZtcjVMdGI5QU5BOElLeVRmc25ISjRpT0NTJTJGUGxQYlVqMnE3WW5vVkxwb3NVQk1sZ1ViJTJGQ3lrWDMlMEFtT29MYjR5SkpReUElMkZpU1Q2WnhpSUVqMzZENHlXWjVsZzdZSmwlMkJVaWlCUUhHQ25QZEd5aXBxVjA2ZXgwaGVZVyUwQWNhaVc4TFdaU1VROTNqUSUyQldWQ0g4aFQ3RFFPMWRtc3ZVbVhscSUyRkplQWx3USUyRlFJREFRQUJvNEhnTUlIZE1CMEclMEFBMVVkRGdRV0JCUmNBUk90aFM0UDRVN3ZUZmpCeUM1NjlSN0U2RENCclFZRFZSMGpCSUdsTUlHaWdCUmNBUk90JTBBaFM0UDRVN3ZUZmpCeUM1NjlSN0U2S0YlMkZwSDB3ZXpFTE1Ba0dBMVVFQmhNQ1ZWTXhDekFKQmdOVkJBZ1RBa05CJTBBTVJZd0ZBWURWUVFIRXcxVFlXNGdSbkpoYm1OcGMyTnZNUlF3RWdZRFZRUUtFd3RDY21Ga1ptbDBlbWx1WXpFUyUwQU1CQUdBMVVFQXhNSmJHOWpZV3hvYjNOME1SMHdHd1lKS29aSWh2Y05BUWtCRmc1aWNtRmtRR1JoYm1kaExtTnYlMEFiWUlKQUxmUmxXc0k4WVFITUF3R0ExVWRFd1FGTUFNQkFmOHdEUVlKS29aSWh2Y05BUUVGQlFBRGdnRUJBRzZoJTBBVTlmOXNOSDAlMkY2b0JiR0d5MkVWVTBVZ0lUVVFJckZXbzlyRmtyVzVrJTJGWGtEalFtJTJCM2x6alQwaUdSNEl4RSUyRkFvJTBBZVU2c1FodWE3d3JXZUZFbjQ3R0w5OGxuQ3NKZEQ3b1pOaEZtUTk1VGIlMkZMbkRVanM1WWo5YnJQME5XelhmWVU0JTBBVUsyWm5JTkpSY0pwQjhpUkNhQ3hFOERkY1VGMFhxSUVxNnBBMjcyc25vTG1pWExNdk5sM2tZRWRtJTJCamU2dm9EJTBBNThTTlZFVXN6dHpReVhtSkVoQ3B3VkkwQTZRQ2p6WGolMkJxdnBtdzNaWkhpOEp3WGVpOFpaQkxUU0ZCa2k4WjduJTBBc0g5QkJIMzglMkZTelVtQU40UUhTUHkxZ2pxbTAwT0FFOE5hWURraCUyRmJ6RTRkN21MR0dNV3AlMkZXRTNLUFN1ODJIRiUwQWtQZTZYb1NiaUxtJTJGa3hrMzJUMCUzRCUwQS0tLS0tRU5EJTIwQ0VSVElGSUNBVEUtLS0tLSUwQSIsInZlcmlmaWNhdGlvbiI6e319LCJtb2RlIjo0MjB9LHsiZmlsZXN5c3RlbSI6InJvb3QiLCJwYXRoIjoiL2V0Yy9zeXN0ZW1kL3N5c3RlbS9rdWJlbGV0LnNlcnZpY2UiLCJjb250ZW50cyI6eyJzb3VyY2UiOiJkYXRhOiwlNUJVbml0JTVEJTBBQWZ0ZXIlM0Rkb2NrZXIuc2VydmljZSUwQVJlcXVpcmVzJTNEZG9ja2VyLnNlcnZpY2UlMEElMEFEZXNjcmlwdGlvbiUzRGt1YmVsZXQlM0ElMjBUaGUlMjBLdWJlcm5ldGVzJTIwTm9kZSUyMEFnZW50JTBBRG9jdW1lbnRhdGlvbiUzRGh0dHBzJTNBJTJGJTJGa3ViZXJuZXRlcy5pbyUyRmRvY3MlMkZob21lJTJGJTBBJTBBJTVCU2VydmljZSU1RCUwQVJlc3RhcnQlM0RhbHdheXMlMEFTdGFydExpbWl0SW50ZXJ2YWwlM0QwJTBBUmVzdGFydFNlYyUzRDEwJTBBQ1BVQWNjb3VudGluZyUzRHRydWUlMEFNZW1vcnlBY2NvdW50aW5nJTNEdHJ1ZSUwQSUwQUVudmlyb25tZW50JTNEJTIyUEFUSCUzRCUyRm9wdCUyRmJpbiUzQSUyRmJpbiUzQSUyRnVzciUyRmxvY2FsJTJGc2JpbiUzQSUyRnVzciUyRmxvY2FsJTJGYmluJTNBJTJGdXNyJTJGc2JpbiUzQSUyRnVzciUyRmJpbiUzQSUyRnNiaW4lMkYlMjIlMEFFbnZpcm9ubWVudEZpbGUlM0QtJTJGZXRjJTJGZW52aXJvbm1lbnQlMEFFbnZpcm9ubWVudEZpbGUlM0QlMkZldGMlMkZrdWJlcm5ldGVzJTJGbm9kZWlwLmNvbmYlMEElMEFFeGVjU3RhcnRQcmUlM0QlMkZiaW4lMkZiYXNoJTIwJTJGb3B0JTJGbG9hZC1rZXJuZWwtbW9kdWxlcy5zaCUwQUV4ZWNTdGFydFByZSUzRCUyRmJpbiUyRmJhc2glMjAlMkZvcHQlMkZiaW4lMkZzZXR1cF9uZXRfZW52LnNoJTBBRXhlY1N0YXJ0JTNEJTJGb3B0JTJGYmluJTJGa3ViZWxldCUyMCUyNEtVQkVMRVRfRVhUUkFfQVJHUyUyMCU1QyUwQSUyMCUyMC0tYm9vdHN0cmFwLWt1YmVjb25maWclM0QlMkZldGMlMkZrdWJlcm5ldGVzJTJGYm9vdHN0cmFwLWt1YmVsZXQuY29uZiUyMCU1QyUwQSUyMCUyMC0ta3ViZWNvbmZpZyUzRCUyRnZhciUyRmxpYiUyRmt1YmVsZXQlMkZrdWJlY29uZmlnJTIwJTVDJTBBJTIwJTIwLS1jb25maWclM0QlMkZldGMlMkZrdWJlcm5ldGVzJTJGa3ViZWxldC5jb25mJTIwJTVDJTBBJTIwJTIwLS1uZXR3b3JrLXBsdWdpbiUzRGNuaSUyMCU1QyUwQSUyMCUyMC0tY2VydC1kaXIlM0QlMkZldGMlMkZrdWJlcm5ldGVzJTJGcGtpJTIwJTVDJTBBJTIwJTIwLS1jbG91ZC1wcm92aWRlciUzRGF3cyUyMCU1QyUwQSUyMCUyMC0tY2xvdWQtY29uZmlnJTNEJTJGZXRjJTJGa3ViZXJuZXRlcyUyRmNsb3VkLWNvbmZpZyUyMCU1QyUwQSUyMCUyMC0tZHluYW1pYy1jb25maWctZGlyJTNEJTJGZXRjJTJGa3ViZXJuZXRlcyUyRmR5bmFtaWMtY29uZmlnLWRpciUyMCU1QyUwQSUyMCUyMC0tZmVhdHVyZS1nYXRlcyUzRER5bmFtaWNLdWJlbGV0Q29uZmlnJTNEdHJ1ZSUyMCU1QyUwQSUyMCUyMC0tZXhpdC1vbi1sb2NrLWNvbnRlbnRpb24lMjAlNUMlMEElMjAlMjAtLWxvY2stZmlsZSUzRCUyRnRtcCUyRmt1YmVsZXQubG9jayUyMCU1QyUwQSUyMCUyMC0tY29udGFpbmVyLXJ1bnRpbWUlM0Rkb2NrZXIlMjAlNUMlMEElMjAlMjAtLWNvbnRhaW5lci1ydW50aW1lLWVuZHBvaW50JTNEdW5peCUzQSUyRiUyRiUyRnZhciUyRnJ1biUyRmRvY2tlcnNoaW0uc29jayUyMCU1QyUwQSUyMCUyMC0tbm9kZS1pcCUyMCUyNCU3QktVQkVMRVRfTk9ERV9JUCU3RCUwQSUwQSU1Qkluc3RhbGwlNUQlMEFXYW50ZWRCeSUzRG11bHRpLXVzZXIudGFyZ2V0JTBBIiwidmVyaWZpY2F0aW9uIjp7fX0sIm1vZGUiOjQyMH0seyJmaWxlc3lzdGVtIjoicm9vdCIsInBhdGgiOiIvZXRjL2t1YmVybmV0ZXMvY2xvdWQtY29uZmlnIiwiY29udGVudHMiOnsic291cmNlIjoiZGF0YTosJTVCZ2xvYmFsJTVEJTBBWm9uZSUzRCUyMiUyMiUwQVZQQyUzRCUyMiUyMiUwQVN1Ym5ldElEJTNEJTIyJTIyJTBBIiwidmVyaWZpY2F0aW9uIjp7fX0sIm1vZGUiOjI1Nn0seyJmaWxlc3lzdGVtIjoicm9vdCIsInBhdGgiOiIvZXRjL2t1YmVybmV0ZXMva3ViZWxldC5jb25mIiwiY29udGVudHMiOnsic291cmNlIjoiZGF0YTosYXBpVmVyc2lvbiUzQSUyMGt1YmVsZXQuY29uZmlnLms4cy5pbyUyRnYxYmV0YTElMEFraW5kJTNBJTIwS3ViZWxldENvbmZpZ3VyYXRpb24lMEFhdXRoZW50aWNhdGlvbiUzQSUwQSUyMCUyMGFub255bW91cyUzQSUwQSUyMCUyMCUyMCUyMGVuYWJsZWQlM0ElMjBmYWxzZSUwQSUyMCUyMHdlYmhvb2slM0ElMEElMjAlMjAlMjAlMjBlbmFibGVkJTNBJTIwdHJ1ZSUwQSUyMCUyMHg1MDklM0ElMEElMjAlMjAlMjAlMjBjbGllbnRDQUZpbGUlM0ElMjAlMkZldGMlMkZrdWJlcm5ldGVzJTJGcGtpJTJGY2EuY3J0JTBBYXV0aG9yaXphdGlvbiUzQSUwQSUyMCUyMG1vZGUlM0ElMjBXZWJob29rJTBBY2dyb3VwRHJpdmVyJTNBJTIwc3lzdGVtZCUwQWNsdXN0ZXJETlMlM0ElMEEtJTIwJTIyMTAuMC4wLjAlMjIlMEFjbHVzdGVyRG9tYWluJTNBJTIwY2x1c3Rlci5sb2NhbCUwQWZlYXR1cmVHYXRlcyUzQSUwQSUyMCUyMEdyYWNlZnVsTm9kZVNodXRkb3duJTNBJTIwdHJ1ZSUwQSUyMCUyMElkZW50aWZ5UG9kT1MlM0ElMjBmYWxzZSUwQXByb3RlY3RLZXJuZWxEZWZhdWx0cyUzQSUyMHRydWUlMEFyZWFkT25seVBvcnQlM0ElMjAwJTBBcm90YXRlQ2VydGlmaWNhdGVzJTNBJTIwdHJ1ZSUwQXNlcnZlclRMU0Jvb3RzdHJhcCUzQSUyMHRydWUlMEFzdGF0aWNQb2RQYXRoJTNBJTIwJTJGZXRjJTJGa3ViZXJuZXRlcyUyRm1hbmlmZXN0cyUwQWt1YmVSZXNlcnZlZCUzQSUwQSUyMCUyMGNwdSUzQSUyMDIwMG0lMEElMjAlMjBlcGhlbWVyYWwtc3RvcmFnZSUzQSUyMDFHaSUwQSUyMCUyMG1lbW9yeSUzQSUyMDIwME1pJTBBc3lzdGVtUmVzZXJ2ZWQlM0ElMEElMjAlMjBjcHUlM0ElMjAyMDBtJTBBJTIwJTIwZXBoZW1lcmFsLXN0b3JhZ2UlM0ElMjAxR2klMEElMjAlMjBtZW1vcnklM0ElMjAyMDBNaSUwQWV2aWN0aW9uSGFyZCUzQSUwQSUyMCUyMGltYWdlZnMuYXZhaWxhYmxlJTNBJTIwMTUlMjUlMEElMjAlMjBtZW1vcnkuYXZhaWxhYmxlJTNBJTIwMTAwTWklMEElMjAlMjBub2RlZnMuYXZhaWxhYmxlJTNBJTIwMTAlMjUlMEElMjAlMjBub2RlZnMuaW5vZGVzRnJlZSUzQSUyMDUlMjUlMEF0bHNDaXBoZXJTdWl0ZXMlM0ElMEEtJTIwVExTX0FFU18xMjhfR0NNX1NIQTI1NiUwQS0lMjBUTFNfQUVTXzI1Nl9HQ01fU0hBMzg0JTBBLSUyMFRMU19DSEFDSEEyMF9QT0xZMTMwNV9TSEEyNTYlMEEtJTIwVExTX0VDREhFX0VDRFNBX1dJVEhfQUVTXzEyOF9HQ01fU0hBMjU2JTBBLSUyMFRMU19FQ0RIRV9FQ0RTQV9XSVRIX0FFU18yNTZfR0NNX1NIQTM4NCUwQS0lMjBUTFNfRUNESEVfRUNEU0FfV0lUSF9DSEFDSEEyMF9QT0xZMTMwNSUwQS0lMjBUTFNfRUNESEVfUlNBX1dJVEhfQUVTXzEyOF9HQ01fU0hBMjU2JTBBLSUyMFRMU19FQ0RIRV9SU0FfV0lUSF9BRVNfMjU2X0dDTV9TSEEzODQlMEEtJTIwVExTX0VDREhFX1JTQV9XSVRIX0NIQUNIQTIwX1BPTFkxMzA1JTBBdm9sdW1lUGx1Z2luRGlyJTNBJTIwJTJGdmFyJTJGbGliJTJGa3ViZWxldCUyRnZvbHVtZXBsdWdpbnMlMEEiLCJ2ZXJpZmljYXRpb24iOnt9fSwibW9kZSI6NDIwfSx7ImZpbGVzeXN0ZW0iOiJyb290IiwicGF0aCI6Ii9ldGMvc3lzdGVtZC9zeXN0ZW0va3ViZWxldC1oZWFsdGhjaGVjay5zZXJ2aWNlIiwiY29udGVudHMiOnsic291cmNlIjoiZGF0YTosJTVCVW5pdCU1RCUwQVJlcXVpcmVzJTNEa3ViZWxldC5zZXJ2aWNlJTBBQWZ0ZXIlM0RrdWJlbGV0LnNlcnZpY2UlMEElMEElNUJTZXJ2aWNlJTVEJTBBRXhlY1N0YXJ0JTNEJTJGb3B0JTJGYmluJTJGaGVhbHRoLW1vbml0b3Iuc2glMjBrdWJlbGV0JTBBJTBBJTVCSW5zdGFsbCU1RCUwQVdhbnRlZEJ5JTNEbXVsdGktdXNlci50YXJnZXQlMEEiLCJ2ZXJpZmljYXRpb24iOnt9fSwibW9kZSI6NDIwfSx7ImZpbGVzeXN0ZW0iOiJyb290IiwicGF0aCI6Ii9wcm9jL3N5cy9rZXJuZWwvcGFuaWNfb25fb29wcyIsImNvbnRlbnRzIjp7InNvdXJjZSI6ImRhdGE6LDElMEEiLCJ2ZXJpZmljYXRpb24iOnt9fSwibW9kZSI6NDIwfSx7ImZpbGVzeXN0ZW0iOiJyb290IiwicGF0aCI6Ii9wcm9jL3N5cy9rZXJuZWwvcGFuaWMiLCJjb250ZW50cyI6eyJzb3VyY2UiOiJkYXRhOiwxMCUwQSIsInZlcmlmaWNhdGlvbiI6e319LCJtb2RlIjo0MjB9LHsiZmlsZXN5c3RlbSI6InJvb3QiLCJwYXRoIjoiL3Byb2Mvc3lzL3ZtL292ZXJjb21taXRfbWVtb3J5IiwiY29udGVudHMiOnsic291cmNlIjoiZGF0YTosMSUwQSIsInZlcmlmaWNhdGlvbiI6e319LCJtb2RlIjo0MjB9LHsiZmlsZXN5c3RlbSI6InJvb3QiLCJwYXRoIjoiL2V0Yy9zc2gvc3NoZF9jb25maWciLCJjb250ZW50cyI6eyJzb3VyY2UiOiJkYXRhOiwlMjMlMjBVc2UlMjBtb3N0JTIwZGVmYXVsdHMlMjBmb3IlMjBzc2hkJTIwY29uZmlndXJhdGlvbi4lMEFTdWJzeXN0ZW0lMjBzZnRwJTIwaW50ZXJuYWwtc2Z0cCUwQUNsaWVudEFsaXZlSW50ZXJ2YWwlMjAxODAlMEFVc2VETlMlMjBubyUwQVVzZVBBTSUyMHllcyUwQVByaW50TGFzdExvZyUyMG5vJTIwJTIzJTIwaGFuZGxlZCUyMGJ5JTIwUEFNJTBBUHJpbnRNb3RkJTIwbm8lMjAlMjMlMjBoYW5kbGVkJTIwYnklMjBQQU0lMEFQYXNzd29yZEF1dGhlbnRpY2F0aW9uJTIwbm8lMEFDaGFsbGVuZ2VSZXNwb25zZUF1dGhlbnRpY2F0aW9uJTIwbm8lMEEiLCJ2ZXJpZmljYXRpb24iOnt9fSwibW9kZSI6Mzg0fSx7ImZpbGVzeXN0ZW0iOiJyb290IiwicGF0aCI6Ii9ldGMvZG9ja2VyL2RhZW1vbi5qc29uIiwiY29udGVudHMiOnsic291cmNlIjoiZGF0YTosJTdCJTIyZXhlYy1vcHRzJTIyJTNBJTVCJTIybmF0aXZlLmNncm91cGRyaXZlciUzRHN5c3RlbWQlMjIlNUQlMkMlMjJzdG9yYWdlLWRyaXZlciUyMiUzQSUyMm92ZXJsYXkyJTIyJTJDJTIybG9nLWRyaXZlciUyMiUzQSUyMmpzb24tZmlsZSUyMiUyQyUyMmxvZy1vcHRzJTIyJTNBJTdCJTIybWF4LWZpbGUlMjIlM0ElMjI1JTIyJTJDJTIybWF4LXNpemUlMjIlM0ElMjIxMDBtJTIyJTdEJTdEJTBBIiwidmVyaWZpY2F0aW9uIjp7fX0sIm1vZGUiOjQyMH0seyJmaWxlc3lzdGVtIjoicm9vdCIsInBhdGgiOiIvZXRjL3N5c3RlbWQvc3lzdGVtL2RvY2tlci5zZXJ2aWNlLmQvMTAtY3VzdG9tLmNvbmYiLCJjb250ZW50cyI6eyJzb3VyY2UiOiJkYXRhOiwlNUJTZXJ2aWNlJTVEJTBBRW52aXJvbm1lbnRGaWxlJTNELSUyRmV0YyUyRmVudmlyb25tZW50JTBBIiwidmVyaWZpY2F0aW9uIjp7fX0sIm1vZGUiOjQyMH1dfSwic3lzdGVtZCI6eyJ1bml0cyI6W3siY29udGVudHMiOiJbSW5zdGFsbF1cbldhbnRlZEJ5PW11bHRpLXVzZXIudGFyZ2V0XG5cbltVbml0XVxuUmVxdWlyZXM9ZG93bmxvYWQtc2NyaXB0LnNlcnZpY2VcblJlcXVpcmVzPW5vZGVpcC5zZXJ2aWNlXG5BZnRlcj1kb3dubG9hZC1zY3JpcHQuc2VydmljZVxuQWZ0ZXI9bm9kZWlwLnNlcnZpY2VcblxuW1NlcnZpY2VdXG5UeXBlPW9uZXNob3RcblJlbWFpbkFmdGVyRXhpdD10cnVlXG5FbnZpcm9ubWVudEZpbGU9LS9ldGMvZW52aXJvbm1lbnRcbkV4ZWNTdGFydD0vb3B0L2Jpbi9zZXR1cFxuIiwiZW5hYmxlZCI6dHJ1ZSwibmFtZSI6InNldHVwLnNlcnZpY2UifSx7ImNvbnRlbnRzIjoiW0luc3RhbGxdXG5XYW50ZWRCeT1tdWx0aS11c2VyLnRhcmdldFxuXG5bVW5pdF1cblJlcXVpcmVzPW5ldHdvcmstb25saW5lLnRhcmdldFxuQWZ0ZXI9bmV0d29yay1vbmxpbmUudGFyZ2V0XG5cbltTZXJ2aWNlXVxuVHlwZT1vbmVzaG90XG5SZW1haW5BZnRlckV4aXQ9dHJ1ZVxuRW52aXJvbm1lbnRGaWxlPS0vZXRjL2Vudmlyb25tZW50XG5FeGVjU3RhcnQ9L29wdC9iaW4vZG93bmxvYWQuc2hcbiIsImVuYWJsZWQiOnRydWUsIm5hbWUiOiJkb3dubG9hZC1zY3JpcHQuc2VydmljZSJ9LHsiY29udGVudHMiOiJbVW5pdF1cbkRlc2NyaXB0aW9uPVNldHVwIEt1YmVsZXQgTm9kZSBJUCBFbnZcblJlcXVpcmVzPW5ldHdvcmstb25saW5lLnRhcmdldFxuQWZ0ZXI9bmV0d29yay1vbmxpbmUudGFyZ2V0XG5cbltTZXJ2aWNlXVxuRXhlY1N0YXJ0PS9vcHQvYmluL3NldHVwX25ldF9lbnYuc2hcblJlbWFpbkFmdGVyRXhpdD15ZXNcblR5cGU9b25lc2hvdFxuW0luc3RhbGxdXG5XYW50ZWRCeT1tdWx0aS11c2VyLnRhcmdldFxuIiwiZW5hYmxlZCI6dHJ1ZSwibmFtZSI6Im5vZGVpcC5zZXJ2aWNlIn0seyJjb250ZW50cyI6IltVbml0XVxuRGVzY3JpcHRpb249U2V0dXAgU3RhdGljIE5ldHdvcmtpbmdcblJlcXVpcmVzPW5ldHdvcmstb25saW5lLnRhcmdldFxuQWZ0ZXI9bmV0d29yay1vbmxpbmUudGFyZ2V0XG5cbltTZXJ2aWNlXVxuRXhlY1N0YXJ0PS9vcHQvYmluL2NvbmZpZ3VyZV9zdGF0aWNfbmV0d29yay5zaFxuUmVtYWluQWZ0ZXJFeGl0PXllc1xuVHlwZT1vbmVzaG90XG5bSW5zdGFsbF1cbldhbnRlZEJ5PW11bHRpLXVzZXIudGFyZ2V0XG4iLCJlbmFibGVkIjp0cnVlLCJuYW1lIjoic3RhdGljLW5ldHdvcmstc2NyaXB0LnNlcnZpY2UifV19fQ== + cloud-config: eyJpZ25pdGlvbiI6eyJjb25maWciOnt9LCJzZWN1cml0eSI6eyJ0bHMiOnt9fSwidGltZW91dHMiOnt9LCJ2ZXJzaW9uIjoiMi4zLjAifSwibmV0d29ya2QiOnt9LCJwYXNzd2QiOnsidXNlcnMiOlt7Im5hbWUiOiJjb3JlIiwic3NoQXV0aG9yaXplZEtleXMiOlsic3NoLXJzYSBBQUFBQjNOemFDMXljMkVBQUFBREFRQUJBQUFDQVFEZE9JaFltekNLNURTVkx1M2MiXX1dfSwic3RvcmFnZSI6eyJmaWxlcyI6W3siZmlsZXN5c3RlbSI6InJvb3QiLCJwYXRoIjoiL2V0Yy9zeXN0ZW1kL2pvdXJuYWxkLmNvbmYuZC9tYXhfZGlza191c2UuY29uZiIsImNvbnRlbnRzIjp7InNvdXJjZSI6ImRhdGE6LCU1QkpvdXJuYWwlNUQlMEFTeXN0ZW1NYXhVc2UlM0Q1RyUwQSIsInZlcmlmaWNhdGlvbiI6e319LCJtb2RlIjo0MjB9LHsiZmlsZXN5c3RlbSI6InJvb3QiLCJwYXRoIjoiL29wdC9sb2FkLWtlcm5lbC1tb2R1bGVzLnNoIiwiY29udGVudHMiOnsic291cmNlIjoiZGF0YTosJTIzISUyRnVzciUyRmJpbiUyRmVudiUyMGJhc2glMEFzZXQlMjAtZXVvJTIwcGlwZWZhaWwlMEElMEFtb2Rwcm9iZSUyMGlwX3ZzJTBBbW9kcHJvYmUlMjBpcF92c19yciUwQW1vZHByb2JlJTIwaXBfdnNfd3JyJTBBbW9kcHJvYmUlMjBpcF92c19zaCUwQSUwQWlmJTIwbW9kaW5mbyUyMG5mX2Nvbm50cmFja19pcHY0JTIwJTI2JTNFJTIwJTJGZGV2JTJGbnVsbCUzQiUyMHRoZW4lMEElMjAlMjBtb2Rwcm9iZSUyMG5mX2Nvbm50cmFja19pcHY0JTBBZWxzZSUwQSUyMCUyMG1vZHByb2JlJTIwbmZfY29ubnRyYWNrJTBBZmklMEEiLCJ2ZXJpZmljYXRpb24iOnt9fSwibW9kZSI6NDkzfSx7ImZpbGVzeXN0ZW0iOiJyb290IiwicGF0aCI6Ii9ldGMvc3lzY3RsLmQvazhzLmNvbmYiLCJjb250ZW50cyI6eyJzb3VyY2UiOiJkYXRhOixuZXQuYnJpZGdlLmJyaWRnZS1uZi1jYWxsLWlwNnRhYmxlcyUyMCUzRCUyMDElMEFuZXQuYnJpZGdlLmJyaWRnZS1uZi1jYWxsLWlwdGFibGVzJTIwJTNEJTIwMSUwQWtlcm5lbC5wYW5pY19vbl9vb3BzJTIwJTNEJTIwMSUwQWtlcm5lbC5wYW5pYyUyMCUzRCUyMDEwJTBBbmV0LmlwdjQuaXBfZm9yd2FyZCUyMCUzRCUyMDElMEF2bS5vdmVyY29tbWl0X21lbW9yeSUyMCUzRCUyMDElMEFmcy5pbm90aWZ5Lm1heF91c2VyX3dhdGNoZXMlMjAlM0QlMjAxMDQ4NTc2JTBBIiwidmVyaWZpY2F0aW9uIjp7fX0sIm1vZGUiOjQyMH0seyJmaWxlc3lzdGVtIjoicm9vdCIsInBhdGgiOiIvb3B0L2Jpbi9zZXR1cF9uZXRfZW52LnNoIiwiY29udGVudHMiOnsic291cmNlIjoiZGF0YTosJTIzISUyRnVzciUyRmJpbiUyRmVudiUyMGJhc2glMEFlY2hvZGF0ZSgpJTIwJTdCJTBBJTIwJTIwZWNobyUyMCUyMiU1QiUyNChkYXRlJTIwLUlzKSU1RCUyMiUyMCUyMiUyNCU0MCUyMiUwQSU3RCUwQSUwQSUyMyUyMGdldCUyMHRoZSUyMGRlZmF1bHQlMjBpbnRlcmZhY2UlMjBJUCUyMGFkZHJlc3MlMEFERUZBVUxUX0lGQ19JUCUzRCUyNChpcCUyMC1vJTIwJTIwcm91dGUlMjBnZXQlMjAxJTIwJTdDJTIwZ3JlcCUyMC1vUCUyMCUyMnNyYyUyMCU1Q0slNUNTJTJCJTIyKSUwQSUwQWlmJTIwJTVCJTIwLXolMjAlMjIlMjQlN0JERUZBVUxUX0lGQ19JUCU3RCUyMiUyMCU1RCUwQXRoZW4lMEElMjAlMjBlY2hvZGF0ZSUyMCUyMkZhaWxlZCUyMHRvJTIwZ2V0JTIwSVAlMjBhZGRyZXNzJTIwZm9yJTIwdGhlJTIwZGVmYXVsdCUyMHJvdXRlJTIwaW50ZXJmYWNlJTIyJTBBJTIwJTIwZXhpdCUyMDElMEFmaSUwQSUwQSUyMyUyMGdldCUyMHRoZSUyMGZ1bGwlMjBob3N0bmFtZSUwQUZVTExfSE9TVE5BTUUlM0QlMjQoaG9zdG5hbWUlMjAtZiklMEElMjMlMjBpZiUyMCUyRmV0YyUyRmhvc3RuYW1lJTIwaXMlMjBub3QlMjBlbXB0eSUyMHRoZW4lMjB1c2UlMjB0aGUlMjBob3N0bmFtZSUyMGZyb20lMjB0aGVyZSUwQWlmJTIwJTVCJTIwLXMlMjAlMkZldGMlMkZob3N0bmFtZSUyMCU1RCUzQiUyMHRoZW4lMEElMjAlMjAlMjAlMjBGVUxMX0hPU1ROQU1FJTNEJTI0KGNhdCUyMCUyRmV0YyUyRmhvc3RuYW1lKSUwQWZpJTBBJTBBJTIzJTIwd3JpdGUlMjB0aGUlMjBub2RlaXBfZW52JTIwZmlsZSUwQSUyMyUyMHdlJTIwbmVlZCUyMHRoZSUyMGxpbmUlMjBiZWxvdyUyMGJlY2F1c2UlMjBmbGF0Y2FyJTIwaGFzJTIwdGhlJTIwc2FtZSUyMHN0cmluZyUyMCUyMmNvcmVvcyUyMiUyMGluJTIwdGhhdCUyMGZpbGUlMEFpZiUyMGdyZXAlMjAtcSUyMGNvcmVvcyUyMCUyRmV0YyUyRm9zLXJlbGVhc2UlMEF0aGVuJTBBJTIwJTIwZWNobyUyMC1lJTIwJTIyS1VCRUxFVF9OT0RFX0lQJTNEJTI0JTdCREVGQVVMVF9JRkNfSVAlN0QlNUNuS1VCRUxFVF9IT1NUTkFNRSUzRCUyNCU3QkZVTExfSE9TVE5BTUUlN0QlMjIlMjAlM0UlMjAlMkZldGMlMkZrdWJlcm5ldGVzJTJGbm9kZWlwLmNvbmYlMEFlbGlmJTIwJTVCJTIwISUyMC1kJTIwJTJGZXRjJTJGc3lzdGVtZCUyRnN5c3RlbSUyRmt1YmVsZXQuc2VydmljZS5kJTIwJTVEJTBBdGhlbiUwQSUyMCUyMGVjaG9kYXRlJTIwJTIyQ2FuJ3QlMjBmaW5kJTIwa3ViZWxldCUyMHNlcnZpY2UlMjBleHRyYXMlMjBkaXJlY3RvcnklMjIlMEElMjAlMjBleGl0JTIwMSUwQWVsc2UlMEElMjAlMjBlY2hvJTIwLWUlMjAlMjIlNUJTZXJ2aWNlJTVEJTVDbkVudmlyb25tZW50JTNEJTVDJTIyS1VCRUxFVF9OT0RFX0lQJTNEJTI0JTdCREVGQVVMVF9JRkNfSVAlN0QlNUMlMjIlNUNuRW52aXJvbm1lbnQlM0QlNUMlMjJLVUJFTEVUX0hPU1ROQU1FJTNEJTI0JTdCRlVMTF9IT1NUTkFNRSU3RCU1QyUyMiUyMiUyMCUzRSUyMCUyRmV0YyUyRnN5c3RlbWQlMkZzeXN0ZW0lMkZrdWJlbGV0LnNlcnZpY2UuZCUyRm5vZGVpcC5jb25mJTBBZmklMEEiLCJ2ZXJpZmljYXRpb24iOnt9fSwibW9kZSI6NDkzfSx7ImZpbGVzeXN0ZW0iOiJyb290IiwicGF0aCI6Ii9vcHQvYmluL2NvbmZpZ3VyZV9zdGF0aWNfbmV0d29yay5zaCIsImNvbnRlbnRzIjp7InNvdXJjZSI6ImRhdGE6LCUyMyElMkZ1c3IlMkZiaW4lMkZlbnYlMjBiYXNoJTBBc2V0JTIwLXhldW8lMjBwaXBlZmFpbCUwQSIsInZlcmlmaWNhdGlvbiI6e319LCJtb2RlIjo0OTN9LHsiZmlsZXN5c3RlbSI6InJvb3QiLCJwYXRoIjoiL29wdC9iaW4vZG93bmxvYWQuc2giLCJjb250ZW50cyI6eyJzb3VyY2UiOiJkYXRhOiwlMjMhJTJGdXNyJTJGYmluJTJGZW52JTIwYmFzaCUwQXNldCUyMC14ZXVvJTIwcGlwZWZhaWwlMEFvcHRfYmluJTNEJTJGb3B0JTJGYmluJTBBdXNyX2xvY2FsX2JpbiUzRCUyRnVzciUyRmxvY2FsJTJGYmluJTBBY25pX2Jpbl9kaXIlM0QlMkZvcHQlMkZjbmklMkZiaW4lMEFta2RpciUyMC1wJTIwJTJGZXRjJTJGY25pJTJGbmV0LmQlMjAlMkZldGMlMkZrdWJlcm5ldGVzJTJGZHluYW1pYy1jb25maWctZGlyJTIwJTJGZXRjJTJGa3ViZXJuZXRlcyUyRm1hbmlmZXN0cyUyMCUyMiUyNG9wdF9iaW4lMjIlMjAlMjIlMjRjbmlfYmluX2RpciUyMiUwQWFyY2glM0QlMjQlN0JIT1NUX0FSQ0gtJTdEJTBBaWYlMjAlNUIlMjAteiUyMCUyMiUyNGFyY2glMjIlMjAlNUQlMEF0aGVuJTBBY2FzZSUyMCUyNCh1bmFtZSUyMC1tKSUyMGluJTBBeDg2XzY0KSUwQSUyMCUyMCUyMCUyMGFyY2glM0QlMjJhbWQ2NCUyMiUwQSUyMCUyMCUyMCUyMCUzQiUzQiUwQWFhcmNoNjQpJTBBJTIwJTIwJTIwJTIwYXJjaCUzRCUyMmFybTY0JTIyJTBBJTIwJTIwJTIwJTIwJTNCJTNCJTBBKiklMEElMjAlMjAlMjAlMjBlY2hvJTIwJTIydW5zdXBwb3J0ZWQlMjBDUFUlMjBhcmNoaXRlY3R1cmUlMkMlMjBleGl0aW5nJTIyJTBBJTIwJTIwJTIwJTIwZXhpdCUyMDElMEElMjAlMjAlMjAlMjAlM0IlM0IlMEFlc2FjJTBBZmklMEFDTklfVkVSU0lPTiUzRCUyMiUyNCU3QkNOSV9WRVJTSU9OJTNBLXYwLjguNyU3RCUyMiUwQWNuaV9iYXNlX3VybCUzRCUyMmh0dHBzJTNBJTJGJTJGZ2l0aHViLmNvbSUyRmNvbnRhaW5lcm5ldHdvcmtpbmclMkZwbHVnaW5zJTJGcmVsZWFzZXMlMkZkb3dubG9hZCUyRiUyNENOSV9WRVJTSU9OJTIyJTBBY25pX2ZpbGVuYW1lJTNEJTIyY25pLXBsdWdpbnMtbGludXgtJTI0YXJjaC0lMjRDTklfVkVSU0lPTi50Z3olMjIlMEFjdXJsJTIwLUxmbyUyMCUyMiUyNGNuaV9iaW5fZGlyJTJGJTI0Y25pX2ZpbGVuYW1lJTIyJTIwJTIyJTI0Y25pX2Jhc2VfdXJsJTJGJTI0Y25pX2ZpbGVuYW1lJTIyJTBBY25pX3N1bSUzRCUyNChjdXJsJTIwLUxmJTIwJTIyJTI0Y25pX2Jhc2VfdXJsJTJGJTI0Y25pX2ZpbGVuYW1lLnNoYTI1NiUyMiklMEFjZCUyMCUyMiUyNGNuaV9iaW5fZGlyJTIyJTBBc2hhMjU2c3VtJTIwLWMlMjAlM0MlM0MlM0MlMjIlMjRjbmlfc3VtJTIyJTBBdGFyJTIweHZmJTIwJTIyJTI0Y25pX2ZpbGVuYW1lJTIyJTBBcm0lMjAtZiUyMCUyMiUyNGNuaV9maWxlbmFtZSUyMiUwQWNkJTIwLSUwQUNSSV9UT09MU19SRUxFQVNFJTNEJTIyJTI0JTdCQ1JJX1RPT0xTX1JFTEVBU0UlM0EtdjEuMjIuMCU3RCUyMiUwQWNyaV90b29sc19iYXNlX3VybCUzRCUyMmh0dHBzJTNBJTJGJTJGZ2l0aHViLmNvbSUyRmt1YmVybmV0ZXMtc2lncyUyRmNyaS10b29scyUyRnJlbGVhc2VzJTJGZG93bmxvYWQlMkYlMjQlN0JDUklfVE9PTFNfUkVMRUFTRSU3RCUyMiUwQWNyaV90b29sc19maWxlbmFtZSUzRCUyMmNyaWN0bC0lMjQlN0JDUklfVE9PTFNfUkVMRUFTRSU3RC1saW51eC0lMjQlN0JhcmNoJTdELnRhci5neiUyMiUwQWN1cmwlMjAtTGZvJTIwJTIyJTI0b3B0X2JpbiUyRiUyNGNyaV90b29sc19maWxlbmFtZSUyMiUyMCUyMiUyNGNyaV90b29sc19iYXNlX3VybCUyRiUyNGNyaV90b29sc19maWxlbmFtZSUyMiUwQWNyaV90b29sc19zdW0lM0QlMjQoY3VybCUyMC1MZiUyMCUyMiUyNGNyaV90b29sc19iYXNlX3VybCUyRiUyNGNyaV90b29sc19maWxlbmFtZS5zaGEyNTYlMjIlMjAlN0MlMjBzZWQlMjAncyUyRiU1QyolNUMlMkYlMkYlMkYnKSUwQWNkJTIwJTIyJTI0b3B0X2JpbiUyMiUwQXNoYTI1NnN1bSUyMC1jJTIwJTNDJTNDJTNDJTIyJTI0Y3JpX3Rvb2xzX3N1bSUyMiUwQXRhciUyMHh2ZiUyMCUyMiUyNGNyaV90b29sc19maWxlbmFtZSUyMiUwQXJtJTIwLWYlMjAlMjIlMjRjcmlfdG9vbHNfZmlsZW5hbWUlMjIlMEFsbiUyMC1zZiUyMCUyMiUyNG9wdF9iaW4lMkZjcmljdGwlMjIlMjAlMjIlMjR1c3JfbG9jYWxfYmluJTIyJTJGY3JpY3RsJTIwJTdDJTdDJTIwZWNobyUyMCUyMnN5bWJvbGljJTIwbGluayUyMGlzJTIwc2tpcHBlZCUyMiUwQWNkJTIwLSUwQUtVQkVfVkVSU0lPTiUzRCUyMiUyNCU3QktVQkVfVkVSU0lPTiUzQS12MS4yMi4xJTdEJTIyJTBBa3ViZV9kaXIlM0QlMjIlMjRvcHRfYmluJTJGa3ViZXJuZXRlcy0lMjRLVUJFX1ZFUlNJT04lMjIlMEFrdWJlX2Jhc2VfdXJsJTNEJTIyaHR0cHMlM0ElMkYlMkZzdG9yYWdlLmdvb2dsZWFwaXMuY29tJTJGa3ViZXJuZXRlcy1yZWxlYXNlJTJGcmVsZWFzZSUyRiUyNEtVQkVfVkVSU0lPTiUyRmJpbiUyRmxpbnV4JTJGJTI0YXJjaCUyMiUwQWt1YmVfc3VtX2ZpbGUlM0QlMjIlMjRrdWJlX2RpciUyRnNoYTI1NiUyMiUwQW1rZGlyJTIwLXAlMjAlMjIlMjRrdWJlX2RpciUyMiUwQSUzQSUyMCUzRSUyMiUyNGt1YmVfc3VtX2ZpbGUlMjIlMEElMEFmb3IlMjBiaW4lMjBpbiUyMGt1YmVsZXQlMjBrdWJlYWRtJTIwa3ViZWN0bCUzQiUyMGRvJTBBJTIwJTIwJTIwJTIwY3VybCUyMC1MZm8lMjAlMjIlMjRrdWJlX2RpciUyRiUyNGJpbiUyMiUyMCUyMiUyNGt1YmVfYmFzZV91cmwlMkYlMjRiaW4lMjIlMEElMjAlMjAlMjAlMjBjaG1vZCUyMCUyQnglMjAlMjIlMjRrdWJlX2RpciUyRiUyNGJpbiUyMiUwQSUyMCUyMCUyMCUyMHN1bSUzRCUyNChjdXJsJTIwLUxmJTIwJTIyJTI0a3ViZV9iYXNlX3VybCUyRiUyNGJpbi5zaGEyNTYlMjIpJTBBJTIwJTIwJTIwJTIwZWNobyUyMCUyMiUyNHN1bSUyMCUyMCUyNGt1YmVfZGlyJTJGJTI0YmluJTIyJTIwJTNFJTNFJTIyJTI0a3ViZV9zdW1fZmlsZSUyMiUwQWRvbmUlMEFzaGEyNTZzdW0lMjAtYyUyMCUyMiUyNGt1YmVfc3VtX2ZpbGUlMjIlMEElMEFmb3IlMjBiaW4lMjBpbiUyMGt1YmVsZXQlMjBrdWJlYWRtJTIwa3ViZWN0bCUzQiUyMGRvJTBBJTIwJTIwJTIwJTIwbG4lMjAtc2YlMjAlMjIlMjRrdWJlX2RpciUyRiUyNGJpbiUyMiUyMCUyMiUyNG9wdF9iaW4lMjIlMkYlMjRiaW4lMEFkb25lJTBBJTBBaWYlMjAlNUIlNUIlMjAhJTIwLXglMjAlMkZvcHQlMkZiaW4lMkZoZWFsdGgtbW9uaXRvci5zaCUyMCU1RCU1RCUzQiUyMHRoZW4lMEElMjAlMjAlMjAlMjBjdXJsJTIwLUxmbyUyMCUyRm9wdCUyRmJpbiUyRmhlYWx0aC1tb25pdG9yLnNoJTIwaHR0cHMlM0ElMkYlMkZyYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tJTJGa3ViZXJtYXRpYyUyRm1hY2hpbmUtY29udHJvbGxlciUyRjc5NjdhMGFmMmI3NWYyOWFkMmFiMjI3ZWVhYTI2ZWE3YjBmMmZiZGUlMkZwa2clMkZ1c2VyZGF0YSUyRnNjcmlwdHMlMkZoZWFsdGgtbW9uaXRvci5zaCUwQSUyMCUyMCUyMCUyMGNobW9kJTIwJTJCeCUyMCUyRm9wdCUyRmJpbiUyRmhlYWx0aC1tb25pdG9yLnNoJTBBZmklMEElMEFzeXN0ZW1jdGwlMjBkaXNhYmxlJTIwZG93bmxvYWQtc2NyaXB0LnNlcnZpY2UlMEEiLCJ2ZXJpZmljYXRpb24iOnt9fSwibW9kZSI6NDkzfSx7ImZpbGVzeXN0ZW0iOiJyb290IiwicGF0aCI6Ii9vcHQvYmluL3NldHVwIiwiY29udGVudHMiOnsic291cmNlIjoiZGF0YTosJTIzISUyRmJpbiUyRmJhc2glMEFzZXQlMjAteGV1byUyMHBpcGVmYWlsJTBBY2F0JTIwJTNDJTNDJTIwRU9GJTIwJTdDJTIwdGVlJTIwJTJGZXRjJTJGcG9sa2l0LTElMkZydWxlcy5kJTJGNjAtbm9yZWJvb3Rfbm9yZXN0YXJ0LnJ1bGVzJTBBcG9sa2l0LmFkZFJ1bGUoZnVuY3Rpb24oYWN0aW9uJTJDJTIwc3ViamVjdCklMjAlN0IlMEElMjAlMjBpZiUyMChhY3Rpb24uaWQlMjAlM0QlM0QlMjAlMjJvcmcuZnJlZWRlc2t0b3AubG9naW4xLnJlYm9vdCUyMiUyMCU3QyU3QyUwQSUyMCUyMCUyMCUyMCUyMCUyMGFjdGlvbi5pZCUyMCUzRCUzRCUyMCUyMm9yZy5mcmVlZGVza3RvcC5sb2dpbjEucmVib290LW11bHRpcGxlLXNlc3Npb25zJTIyKSUyMCU3QiUwQSUyMCUyMCUyMCUyMCUyMCUyMGlmJTIwKHN1YmplY3QudXNlciUyMCUzRCUzRCUyMCUyMmNvcmUlMjIpJTIwJTdCJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwcmV0dXJuJTIwcG9sa2l0LlJlc3VsdC5ZRVMlM0IlMEElMjAlMjAlMjAlMjAlMjAlMjAlN0QlMjBlbHNlJTIwJTdCJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwcmV0dXJuJTIwcG9sa2l0LlJlc3VsdC5BVVRIX0FETUlOJTNCJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTdEJTBBJTIwJTIwJTdEJTBBJTdEKSUzQiUwQUVPRiUwQXN5c3RlbWN0bCUyMHN0b3AlMjBjb250YWluZXJkJTBBc3lzdGVtY3RsJTIwZGlzYWJsZSUyMGNvbnRhaW5lcmQlMEElMEFzeXN0ZW1jdGwlMjBlbmFibGUlMjAtLW5vdyUyMGt1YmVsZXQlMEFzeXN0ZW1jdGwlMjBlbmFibGUlMjAtLW5vdyUyMC0tbm8tYmxvY2slMjBrdWJlbGV0LWhlYWx0aGNoZWNrLnNlcnZpY2UlMEFzeXN0ZW1jdGwlMjBkaXNhYmxlJTIwc2V0dXAuc2VydmljZSUwQSIsInZlcmlmaWNhdGlvbiI6e319LCJtb2RlIjo0OTN9LHsiZmlsZXN5c3RlbSI6InJvb3QiLCJwYXRoIjoiL2V0Yy9rdWJlcm5ldGVzL3BraS9jYS5jcnQiLCJjb250ZW50cyI6eyJzb3VyY2UiOiJkYXRhOiwtLS0tLUJFR0lOJTIwQ0VSVElGSUNBVEUtLS0tLSUwQU1JSUVXakNDQTBLZ0F3SUJBZ0lKQUxmUmxXc0k4WVFITUEwR0NTcUdTSWIzRFFFQkJRVUFNSHN4Q3pBSkJnTlYlMEFCQVlUQWxWVE1Rc3dDUVlEVlFRSUV3SkRRVEVXTUJRR0ExVUVCeE1OVTJGdUlFWnlZVzVqYVhOamJ6RVVNQklHJTBBQTFVRUNoTUxRbkpoWkdacGRIcHBibU14RWpBUUJnTlZCQU1UQ1d4dlkyRnNhRzl6ZERFZE1Cc0dDU3FHU0liMyUwQURRRUpBUllPWW5KaFpFQmtZVzVuWVM1amIyMHdIaGNOTVRRd056RTFNakEwTmpBMVdoY05NVGN3TlRBME1qQTAlMEFOakExV2pCN01Rc3dDUVlEVlFRR0V3SlZVekVMTUFrR0ExVUVDQk1DUTBFeEZqQVVCZ05WQkFjVERWTmhiaUJHJTBBY21GdVkybHpZMjh4RkRBU0JnTlZCQW9UQzBKeVlXUm1hWFI2YVc1ak1SSXdFQVlEVlFRREV3bHNiMk5oYkdodiUwQWMzUXhIVEFiQmdrcWhraUc5dzBCQ1FFV0RtSnlZV1JBWkdGdVoyRXVZMjl0TUlJQklqQU5CZ2txaGtpRzl3MEIlMEFBUUVGQUFPQ0FROEFNSUlCQ2dLQ0FRRUF0NWZBanA0ZlRjZWtXVVRmenNwMGt5aWgxT1lic0dMMEtYMWVSYlNTJTBBUjhPZDAlMkI5UTYySHlueSUyQkdGd01UYjRBJTJGS1U4bXNzb0h2Y2NlU0FBYndmYnhGSyUyRiUyQnM1MVRvYnFVbk9SWnJPb1QlMEFaamtVeWdieVhEU0s5OVlCYmNSMVBpcDh2d01UbTRYS3VMdENpZ2VCQmRqakFRZGdVTzI4TEVOR2xzTW5tZVlrJTBBSmZPRFZHblZtcjVMdGI5QU5BOElLeVRmc25ISjRpT0NTJTJGUGxQYlVqMnE3WW5vVkxwb3NVQk1sZ1ViJTJGQ3lrWDMlMEFtT29MYjR5SkpReUElMkZpU1Q2WnhpSUVqMzZENHlXWjVsZzdZSmwlMkJVaWlCUUhHQ25QZEd5aXBxVjA2ZXgwaGVZVyUwQWNhaVc4TFdaU1VROTNqUSUyQldWQ0g4aFQ3RFFPMWRtc3ZVbVhscSUyRkplQWx3USUyRlFJREFRQUJvNEhnTUlIZE1CMEclMEFBMVVkRGdRV0JCUmNBUk90aFM0UDRVN3ZUZmpCeUM1NjlSN0U2RENCclFZRFZSMGpCSUdsTUlHaWdCUmNBUk90JTBBaFM0UDRVN3ZUZmpCeUM1NjlSN0U2S0YlMkZwSDB3ZXpFTE1Ba0dBMVVFQmhNQ1ZWTXhDekFKQmdOVkJBZ1RBa05CJTBBTVJZd0ZBWURWUVFIRXcxVFlXNGdSbkpoYm1OcGMyTnZNUlF3RWdZRFZRUUtFd3RDY21Ga1ptbDBlbWx1WXpFUyUwQU1CQUdBMVVFQXhNSmJHOWpZV3hvYjNOME1SMHdHd1lKS29aSWh2Y05BUWtCRmc1aWNtRmtRR1JoYm1kaExtTnYlMEFiWUlKQUxmUmxXc0k4WVFITUF3R0ExVWRFd1FGTUFNQkFmOHdEUVlKS29aSWh2Y05BUUVGQlFBRGdnRUJBRzZoJTBBVTlmOXNOSDAlMkY2b0JiR0d5MkVWVTBVZ0lUVVFJckZXbzlyRmtyVzVrJTJGWGtEalFtJTJCM2x6alQwaUdSNEl4RSUyRkFvJTBBZVU2c1FodWE3d3JXZUZFbjQ3R0w5OGxuQ3NKZEQ3b1pOaEZtUTk1VGIlMkZMbkRVanM1WWo5YnJQME5XelhmWVU0JTBBVUsyWm5JTkpSY0pwQjhpUkNhQ3hFOERkY1VGMFhxSUVxNnBBMjcyc25vTG1pWExNdk5sM2tZRWRtJTJCamU2dm9EJTBBNThTTlZFVXN6dHpReVhtSkVoQ3B3VkkwQTZRQ2p6WGolMkJxdnBtdzNaWkhpOEp3WGVpOFpaQkxUU0ZCa2k4WjduJTBBc0g5QkJIMzglMkZTelVtQU40UUhTUHkxZ2pxbTAwT0FFOE5hWURraCUyRmJ6RTRkN21MR0dNV3AlMkZXRTNLUFN1ODJIRiUwQWtQZTZYb1NiaUxtJTJGa3hrMzJUMCUzRCUwQS0tLS0tRU5EJTIwQ0VSVElGSUNBVEUtLS0tLSUwQSIsInZlcmlmaWNhdGlvbiI6e319LCJtb2RlIjo0MjB9LHsiZmlsZXN5c3RlbSI6InJvb3QiLCJwYXRoIjoiL2V0Yy9zeXN0ZW1kL3N5c3RlbS9rdWJlbGV0LnNlcnZpY2UiLCJjb250ZW50cyI6eyJzb3VyY2UiOiJkYXRhOiwlNUJVbml0JTVEJTBBQWZ0ZXIlM0Rkb2NrZXIuc2VydmljZSUwQVJlcXVpcmVzJTNEZG9ja2VyLnNlcnZpY2UlMEElMEFEZXNjcmlwdGlvbiUzRGt1YmVsZXQlM0ElMjBUaGUlMjBLdWJlcm5ldGVzJTIwTm9kZSUyMEFnZW50JTBBRG9jdW1lbnRhdGlvbiUzRGh0dHBzJTNBJTJGJTJGa3ViZXJuZXRlcy5pbyUyRmRvY3MlMkZob21lJTJGJTBBJTBBJTVCU2VydmljZSU1RCUwQVJlc3RhcnQlM0RhbHdheXMlMEFTdGFydExpbWl0SW50ZXJ2YWwlM0QwJTBBUmVzdGFydFNlYyUzRDEwJTBBQ1BVQWNjb3VudGluZyUzRHRydWUlMEFNZW1vcnlBY2NvdW50aW5nJTNEdHJ1ZSUwQSUwQUVudmlyb25tZW50JTNEJTIyUEFUSCUzRCUyRm9wdCUyRmJpbiUzQSUyRmJpbiUzQSUyRnVzciUyRmxvY2FsJTJGc2JpbiUzQSUyRnVzciUyRmxvY2FsJTJGYmluJTNBJTJGdXNyJTJGc2JpbiUzQSUyRnVzciUyRmJpbiUzQSUyRnNiaW4lMkYlMjIlMEFFbnZpcm9ubWVudEZpbGUlM0QtJTJGZXRjJTJGZW52aXJvbm1lbnQlMEFFbnZpcm9ubWVudEZpbGUlM0QlMkZldGMlMkZrdWJlcm5ldGVzJTJGbm9kZWlwLmNvbmYlMEElMEFFeGVjU3RhcnRQcmUlM0QlMkZiaW4lMkZiYXNoJTIwJTJGb3B0JTJGbG9hZC1rZXJuZWwtbW9kdWxlcy5zaCUwQUV4ZWNTdGFydFByZSUzRCUyRmJpbiUyRmJhc2glMjAlMkZvcHQlMkZiaW4lMkZzZXR1cF9uZXRfZW52LnNoJTBBRXhlY1N0YXJ0JTNEJTJGb3B0JTJGYmluJTJGa3ViZWxldCUyMCUyNEtVQkVMRVRfRVhUUkFfQVJHUyUyMCU1QyUwQSUyMCUyMC0tYm9vdHN0cmFwLWt1YmVjb25maWclM0QlMkZldGMlMkZrdWJlcm5ldGVzJTJGYm9vdHN0cmFwLWt1YmVsZXQuY29uZiUyMCU1QyUwQSUyMCUyMC0ta3ViZWNvbmZpZyUzRCUyRnZhciUyRmxpYiUyRmt1YmVsZXQlMkZrdWJlY29uZmlnJTIwJTVDJTBBJTIwJTIwLS1jb25maWclM0QlMkZldGMlMkZrdWJlcm5ldGVzJTJGa3ViZWxldC5jb25mJTIwJTVDJTBBJTIwJTIwLS1uZXR3b3JrLXBsdWdpbiUzRGNuaSUyMCU1QyUwQSUyMCUyMC0tY2VydC1kaXIlM0QlMkZldGMlMkZrdWJlcm5ldGVzJTJGcGtpJTIwJTVDJTBBJTIwJTIwLS1jbG91ZC1wcm92aWRlciUzRGF3cyUyMCU1QyUwQSUyMCUyMC0tY2xvdWQtY29uZmlnJTNEJTJGZXRjJTJGa3ViZXJuZXRlcyUyRmNsb3VkLWNvbmZpZyUyMCU1QyUwQSUyMCUyMC0tZHluYW1pYy1jb25maWctZGlyJTNEJTJGZXRjJTJGa3ViZXJuZXRlcyUyRmR5bmFtaWMtY29uZmlnLWRpciUyMCU1QyUwQSUyMCUyMC0tZmVhdHVyZS1nYXRlcyUzRER5bmFtaWNLdWJlbGV0Q29uZmlnJTNEdHJ1ZSUyMCU1QyUwQSUyMCUyMC0tZXhpdC1vbi1sb2NrLWNvbnRlbnRpb24lMjAlNUMlMEElMjAlMjAtLWxvY2stZmlsZSUzRCUyRnRtcCUyRmt1YmVsZXQubG9jayUyMCU1QyUwQSUyMCUyMC0tY29udGFpbmVyLXJ1bnRpbWUlM0Rkb2NrZXIlMjAlNUMlMEElMjAlMjAtLWNvbnRhaW5lci1ydW50aW1lLWVuZHBvaW50JTNEdW5peCUzQSUyRiUyRiUyRnZhciUyRnJ1biUyRmRvY2tlcnNoaW0uc29jayUyMCU1QyUwQSUyMCUyMC0tbm9kZS1pcCUyMCUyNCU3QktVQkVMRVRfTk9ERV9JUCU3RCUwQSUwQSU1Qkluc3RhbGwlNUQlMEFXYW50ZWRCeSUzRG11bHRpLXVzZXIudGFyZ2V0JTBBIiwidmVyaWZpY2F0aW9uIjp7fX0sIm1vZGUiOjQyMH0seyJmaWxlc3lzdGVtIjoicm9vdCIsInBhdGgiOiIvZXRjL2t1YmVybmV0ZXMvY2xvdWQtY29uZmlnIiwiY29udGVudHMiOnsic291cmNlIjoiZGF0YTosJTVCZ2xvYmFsJTVEJTBBWm9uZSUzRCUyMiUyMiUwQVZQQyUzRCUyMiUyMiUwQVN1Ym5ldElEJTNEJTIyJTIyJTBBIiwidmVyaWZpY2F0aW9uIjp7fX0sIm1vZGUiOjI1Nn0seyJmaWxlc3lzdGVtIjoicm9vdCIsInBhdGgiOiIvZXRjL2t1YmVybmV0ZXMva3ViZWxldC5jb25mIiwiY29udGVudHMiOnsic291cmNlIjoiZGF0YTosYXBpVmVyc2lvbiUzQSUyMGt1YmVsZXQuY29uZmlnLms4cy5pbyUyRnYxYmV0YTElMEFraW5kJTNBJTIwS3ViZWxldENvbmZpZ3VyYXRpb24lMEFhdXRoZW50aWNhdGlvbiUzQSUwQSUyMCUyMGFub255bW91cyUzQSUwQSUyMCUyMCUyMCUyMGVuYWJsZWQlM0ElMjBmYWxzZSUwQSUyMCUyMHdlYmhvb2slM0ElMEElMjAlMjAlMjAlMjBlbmFibGVkJTNBJTIwdHJ1ZSUwQSUyMCUyMHg1MDklM0ElMEElMjAlMjAlMjAlMjBjbGllbnRDQUZpbGUlM0ElMjAlMkZldGMlMkZrdWJlcm5ldGVzJTJGcGtpJTJGY2EuY3J0JTBBYXV0aG9yaXphdGlvbiUzQSUwQSUyMCUyMG1vZGUlM0ElMjBXZWJob29rJTBBY2dyb3VwRHJpdmVyJTNBJTIwc3lzdGVtZCUwQWNsdXN0ZXJETlMlM0ElMEEtJTIwJTIyMTAuMC4wLjAlMjIlMEFjbHVzdGVyRG9tYWluJTNBJTIwY2x1c3Rlci5sb2NhbCUwQWZlYXR1cmVHYXRlcyUzQSUwQSUyMCUyMEdyYWNlZnVsTm9kZVNodXRkb3duJTNBJTIwdHJ1ZSUwQSUyMCUyMElkZW50aWZ5UG9kT1MlM0ElMjBmYWxzZSUwQXByb3RlY3RLZXJuZWxEZWZhdWx0cyUzQSUyMHRydWUlMEFyZWFkT25seVBvcnQlM0ElMjAwJTBBcm90YXRlQ2VydGlmaWNhdGVzJTNBJTIwdHJ1ZSUwQXNlcnZlclRMU0Jvb3RzdHJhcCUzQSUyMHRydWUlMEFzdGF0aWNQb2RQYXRoJTNBJTIwJTJGZXRjJTJGa3ViZXJuZXRlcyUyRm1hbmlmZXN0cyUwQWt1YmVSZXNlcnZlZCUzQSUwQSUyMCUyMGNwdSUzQSUyMDIwMG0lMEElMjAlMjBlcGhlbWVyYWwtc3RvcmFnZSUzQSUyMDFHaSUwQSUyMCUyMG1lbW9yeSUzQSUyMDIwME1pJTBBc3lzdGVtUmVzZXJ2ZWQlM0ElMEElMjAlMjBjcHUlM0ElMjAyMDBtJTBBJTIwJTIwZXBoZW1lcmFsLXN0b3JhZ2UlM0ElMjAxR2klMEElMjAlMjBtZW1vcnklM0ElMjAyMDBNaSUwQWV2aWN0aW9uSGFyZCUzQSUwQSUyMCUyMGltYWdlZnMuYXZhaWxhYmxlJTNBJTIwMTUlMjUlMEElMjAlMjBtZW1vcnkuYXZhaWxhYmxlJTNBJTIwMTAwTWklMEElMjAlMjBub2RlZnMuYXZhaWxhYmxlJTNBJTIwMTAlMjUlMEElMjAlMjBub2RlZnMuaW5vZGVzRnJlZSUzQSUyMDUlMjUlMEF0bHNDaXBoZXJTdWl0ZXMlM0ElMEEtJTIwVExTX0FFU18xMjhfR0NNX1NIQTI1NiUwQS0lMjBUTFNfQUVTXzI1Nl9HQ01fU0hBMzg0JTBBLSUyMFRMU19DSEFDSEEyMF9QT0xZMTMwNV9TSEEyNTYlMEEtJTIwVExTX0VDREhFX0VDRFNBX1dJVEhfQUVTXzEyOF9HQ01fU0hBMjU2JTBBLSUyMFRMU19FQ0RIRV9FQ0RTQV9XSVRIX0FFU18yNTZfR0NNX1NIQTM4NCUwQS0lMjBUTFNfRUNESEVfRUNEU0FfV0lUSF9DSEFDSEEyMF9QT0xZMTMwNSUwQS0lMjBUTFNfRUNESEVfUlNBX1dJVEhfQUVTXzEyOF9HQ01fU0hBMjU2JTBBLSUyMFRMU19FQ0RIRV9SU0FfV0lUSF9BRVNfMjU2X0dDTV9TSEEzODQlMEEtJTIwVExTX0VDREhFX1JTQV9XSVRIX0NIQUNIQTIwX1BPTFkxMzA1JTBBdm9sdW1lUGx1Z2luRGlyJTNBJTIwJTJGdmFyJTJGbGliJTJGa3ViZWxldCUyRnZvbHVtZXBsdWdpbnMlMEEiLCJ2ZXJpZmljYXRpb24iOnt9fSwibW9kZSI6NDIwfSx7ImZpbGVzeXN0ZW0iOiJyb290IiwicGF0aCI6Ii9ldGMvc3lzdGVtZC9zeXN0ZW0va3ViZWxldC1oZWFsdGhjaGVjay5zZXJ2aWNlIiwiY29udGVudHMiOnsic291cmNlIjoiZGF0YTosJTVCVW5pdCU1RCUwQVJlcXVpcmVzJTNEa3ViZWxldC5zZXJ2aWNlJTBBQWZ0ZXIlM0RrdWJlbGV0LnNlcnZpY2UlMEElMEElNUJTZXJ2aWNlJTVEJTBBRXhlY1N0YXJ0JTNEJTJGb3B0JTJGYmluJTJGaGVhbHRoLW1vbml0b3Iuc2glMjBrdWJlbGV0JTBBJTBBJTVCSW5zdGFsbCU1RCUwQVdhbnRlZEJ5JTNEbXVsdGktdXNlci50YXJnZXQlMEEiLCJ2ZXJpZmljYXRpb24iOnt9fSwibW9kZSI6NDIwfSx7ImZpbGVzeXN0ZW0iOiJyb290IiwicGF0aCI6Ii9wcm9jL3N5cy9rZXJuZWwvcGFuaWNfb25fb29wcyIsImNvbnRlbnRzIjp7InNvdXJjZSI6ImRhdGE6LDElMEEiLCJ2ZXJpZmljYXRpb24iOnt9fSwibW9kZSI6NDIwfSx7ImZpbGVzeXN0ZW0iOiJyb290IiwicGF0aCI6Ii9wcm9jL3N5cy9rZXJuZWwvcGFuaWMiLCJjb250ZW50cyI6eyJzb3VyY2UiOiJkYXRhOiwxMCUwQSIsInZlcmlmaWNhdGlvbiI6e319LCJtb2RlIjo0MjB9LHsiZmlsZXN5c3RlbSI6InJvb3QiLCJwYXRoIjoiL3Byb2Mvc3lzL3ZtL292ZXJjb21taXRfbWVtb3J5IiwiY29udGVudHMiOnsic291cmNlIjoiZGF0YTosMSUwQSIsInZlcmlmaWNhdGlvbiI6e319LCJtb2RlIjo0MjB9LHsiZmlsZXN5c3RlbSI6InJvb3QiLCJwYXRoIjoiL2V0Yy9zc2gvc3NoZF9jb25maWciLCJjb250ZW50cyI6eyJzb3VyY2UiOiJkYXRhOiwlMjMlMjBVc2UlMjBtb3N0JTIwZGVmYXVsdHMlMjBmb3IlMjBzc2hkJTIwY29uZmlndXJhdGlvbi4lMEFTdWJzeXN0ZW0lMjBzZnRwJTIwaW50ZXJuYWwtc2Z0cCUwQUNsaWVudEFsaXZlSW50ZXJ2YWwlMjAxODAlMEFVc2VETlMlMjBubyUwQVVzZVBBTSUyMHllcyUwQVByaW50TGFzdExvZyUyMG5vJTIwJTIzJTIwaGFuZGxlZCUyMGJ5JTIwUEFNJTBBUHJpbnRNb3RkJTIwbm8lMjAlMjMlMjBoYW5kbGVkJTIwYnklMjBQQU0lMEFQYXNzd29yZEF1dGhlbnRpY2F0aW9uJTIwbm8lMEFDaGFsbGVuZ2VSZXNwb25zZUF1dGhlbnRpY2F0aW9uJTIwbm8lMEEiLCJ2ZXJpZmljYXRpb24iOnt9fSwibW9kZSI6Mzg0fSx7ImZpbGVzeXN0ZW0iOiJyb290IiwicGF0aCI6Ii9ldGMvZG9ja2VyL2RhZW1vbi5qc29uIiwiY29udGVudHMiOnsic291cmNlIjoiZGF0YTosJTdCJTIyZXhlYy1vcHRzJTIyJTNBJTVCJTIybmF0aXZlLmNncm91cGRyaXZlciUzRHN5c3RlbWQlMjIlNUQlMkMlMjJzdG9yYWdlLWRyaXZlciUyMiUzQSUyMm92ZXJsYXkyJTIyJTJDJTIybG9nLWRyaXZlciUyMiUzQSUyMmpzb24tZmlsZSUyMiUyQyUyMmxvZy1vcHRzJTIyJTNBJTdCJTIybWF4LWZpbGUlMjIlM0ElMjI1JTIyJTJDJTIybWF4LXNpemUlMjIlM0ElMjIxMDBtJTIyJTdEJTJDJTIyaW5zZWN1cmUtcmVnaXN0cmllcyUyMiUzQSU1QiUyMjE5Mi4xNjguMTAwLjEwMCUzQTUwMDAlMjIlMkMlMjIxMC4wLjAuMSUzQTUwMDAlMjIlNUQlMkMlMjJyZWdpc3RyeS1taXJyb3JzJTIyJTNBJTVCJTIyaHR0cHMlM0ElMkYlMkZyZWdpc3RyeS5kb2NrZXItY24uY29tJTIyJTVEJTdEJTBBIiwidmVyaWZpY2F0aW9uIjp7fX0sIm1vZGUiOjQyMH0seyJmaWxlc3lzdGVtIjoicm9vdCIsInBhdGgiOiIvZXRjL3N5c3RlbWQvc3lzdGVtL2RvY2tlci5zZXJ2aWNlLmQvMTAtY3VzdG9tLmNvbmYiLCJjb250ZW50cyI6eyJzb3VyY2UiOiJkYXRhOiwlNUJTZXJ2aWNlJTVEJTBBRW52aXJvbm1lbnRGaWxlJTNELSUyRmV0YyUyRmVudmlyb25tZW50JTBBIiwidmVyaWZpY2F0aW9uIjp7fX0sIm1vZGUiOjQyMH1dfSwic3lzdGVtZCI6eyJ1bml0cyI6W3siY29udGVudHMiOiJbSW5zdGFsbF1cbldhbnRlZEJ5PW11bHRpLXVzZXIudGFyZ2V0XG5cbltVbml0XVxuUmVxdWlyZXM9ZG93bmxvYWQtc2NyaXB0LnNlcnZpY2VcblJlcXVpcmVzPW5vZGVpcC5zZXJ2aWNlXG5BZnRlcj1kb3dubG9hZC1zY3JpcHQuc2VydmljZVxuQWZ0ZXI9bm9kZWlwLnNlcnZpY2VcblxuW1NlcnZpY2VdXG5UeXBlPW9uZXNob3RcblJlbWFpbkFmdGVyRXhpdD10cnVlXG5FbnZpcm9ubWVudEZpbGU9LS9ldGMvZW52aXJvbm1lbnRcbkV4ZWNTdGFydD0vb3B0L2Jpbi9zZXR1cFxuIiwiZW5hYmxlZCI6dHJ1ZSwibmFtZSI6InNldHVwLnNlcnZpY2UifSx7ImNvbnRlbnRzIjoiW0luc3RhbGxdXG5XYW50ZWRCeT1tdWx0aS11c2VyLnRhcmdldFxuXG5bVW5pdF1cblJlcXVpcmVzPW5ldHdvcmstb25saW5lLnRhcmdldFxuQWZ0ZXI9bmV0d29yay1vbmxpbmUudGFyZ2V0XG5cbltTZXJ2aWNlXVxuVHlwZT1vbmVzaG90XG5SZW1haW5BZnRlckV4aXQ9dHJ1ZVxuRW52aXJvbm1lbnRGaWxlPS0vZXRjL2Vudmlyb25tZW50XG5FeGVjU3RhcnQ9L29wdC9iaW4vZG93bmxvYWQuc2hcbiIsImVuYWJsZWQiOnRydWUsIm5hbWUiOiJkb3dubG9hZC1zY3JpcHQuc2VydmljZSJ9LHsiY29udGVudHMiOiJbVW5pdF1cbkRlc2NyaXB0aW9uPVNldHVwIEt1YmVsZXQgTm9kZSBJUCBFbnZcblJlcXVpcmVzPW5ldHdvcmstb25saW5lLnRhcmdldFxuQWZ0ZXI9bmV0d29yay1vbmxpbmUudGFyZ2V0XG5cbltTZXJ2aWNlXVxuRXhlY1N0YXJ0PS9vcHQvYmluL3NldHVwX25ldF9lbnYuc2hcblJlbWFpbkFmdGVyRXhpdD15ZXNcblR5cGU9b25lc2hvdFxuW0luc3RhbGxdXG5XYW50ZWRCeT1tdWx0aS11c2VyLnRhcmdldFxuIiwiZW5hYmxlZCI6dHJ1ZSwibmFtZSI6Im5vZGVpcC5zZXJ2aWNlIn0seyJjb250ZW50cyI6IltVbml0XVxuRGVzY3JpcHRpb249U2V0dXAgU3RhdGljIE5ldHdvcmtpbmdcblJlcXVpcmVzPW5ldHdvcmstb25saW5lLnRhcmdldFxuQWZ0ZXI9bmV0d29yay1vbmxpbmUudGFyZ2V0XG5cbltTZXJ2aWNlXVxuRXhlY1N0YXJ0PS9vcHQvYmluL2NvbmZpZ3VyZV9zdGF0aWNfbmV0d29yay5zaFxuUmVtYWluQWZ0ZXJFeGl0PXllc1xuVHlwZT1vbmVzaG90XG5bSW5zdGFsbF1cbldhbnRlZEJ5PW11bHRpLXVzZXIudGFyZ2V0XG4iLCJlbmFibGVkIjp0cnVlLCJuYW1lIjoic3RhdGljLW5ldHdvcmstc2NyaXB0LnNlcnZpY2UifV19fQ== immutable: true kind: Secret metadata: creationTimestamp: null - name: flatcar-aws-docker-osc-provisioning + name: flatcar-aws-docker-kube-system-osc-provisioning namespace: cloud-init-settings resourceVersion: "1" +type: Opaque diff --git a/pkg/controllers/osc/testdata/secret-kubelet-configuration-containerd.yaml b/pkg/controllers/osc/testdata/secret-kubelet-configuration-containerd.yaml new file mode 100644 index 00000000..3698c4dc --- /dev/null +++ b/pkg/controllers/osc/testdata/secret-kubelet-configuration-containerd.yaml @@ -0,0 +1,11 @@ +apiVersion: v1 +data: + cloud-config: I2Nsb3VkLWNvbmZpZwoKc3NoX3B3YXV0aDogbm8Kc3NoX2F1dGhvcml6ZWRfa2V5czoKLSAnc3NoLXJzYSBBQUFBQjNOemFDMXljMkVBQUFBREFRQUJBQUFDQVFEZE9JaFltekNLNURTVkx1M2MnCndyaXRlX2ZpbGVzOgotIHBhdGg6ICcvZXRjL3N5c3RlbWQvam91cm5hbGQuY29uZi5kL21heF9kaXNrX3VzZS5jb25mJwogIGNvbnRlbnQ6IHwtCiAgICBbSm91cm5hbF0KICAgIFN5c3RlbU1heFVzZT01RwogICAgCgotIHBhdGg6ICcvb3B0L2xvYWQta2VybmVsLW1vZHVsZXMuc2gnCiAgcGVybWlzc2lvbnM6ICcwNzU1JwogIGNvbnRlbnQ6IHwtCiAgICAjIS91c3IvYmluL2VudiBiYXNoCiAgICBzZXQgLWV1byBwaXBlZmFpbAogICAgCiAgICBtb2Rwcm9iZSBpcF92cwogICAgbW9kcHJvYmUgaXBfdnNfcnIKICAgIG1vZHByb2JlIGlwX3ZzX3dycgogICAgbW9kcHJvYmUgaXBfdnNfc2gKICAgIAogICAgaWYgbW9kaW5mbyBuZl9jb25udHJhY2tfaXB2NCAmPiAvZGV2L251bGw7IHRoZW4KICAgICAgbW9kcHJvYmUgbmZfY29ubnRyYWNrX2lwdjQKICAgIGVsc2UKICAgICAgbW9kcHJvYmUgbmZfY29ubnRyYWNrCiAgICBmaQogICAgCgotIHBhdGg6ICcvZXRjL3N5c2N0bC5kL2s4cy5jb25mJwogIGNvbnRlbnQ6IHwtCiAgICBuZXQuYnJpZGdlLmJyaWRnZS1uZi1jYWxsLWlwNnRhYmxlcyA9IDEKICAgIG5ldC5icmlkZ2UuYnJpZGdlLW5mLWNhbGwtaXB0YWJsZXMgPSAxCiAgICBrZXJuZWwucGFuaWNfb25fb29wcyA9IDEKICAgIGtlcm5lbC5wYW5pYyA9IDEwCiAgICBuZXQuaXB2NC5pcF9mb3J3YXJkID0gMQogICAgdm0ub3ZlcmNvbW1pdF9tZW1vcnkgPSAxCiAgICBmcy5pbm90aWZ5Lm1heF91c2VyX3dhdGNoZXMgPSAxMDQ4NTc2CiAgICAKCi0gcGF0aDogJy9ldGMvZGVmYXVsdC9ncnViLmQvNjAtc3dhcC1hY2NvdW50aW5nLmNmZycKICBjb250ZW50OiB8LQogICAgIyBBZGRlZCBieSBrdWJlcm1hdGljIG1hY2hpbmUtY29udHJvbGxlcgogICAgIyBFbmFibGUgY2dyb3VwcyBtZW1vcnkgYW5kIHN3YXAgYWNjb3VudGluZwogICAgR1JVQl9DTURMSU5FX0xJTlVYPSJjZ3JvdXBfZW5hYmxlPW1lbW9yeSBzd2FwYWNjb3VudD0xIgogICAgCgotIHBhdGg6ICcvb3B0L2Jpbi9zZXR1cCcKICBwZXJtaXNzaW9uczogJzA3NTUnCiAgY29udGVudDogfC0KICAgICMhL2Jpbi9iYXNoCiAgICBzZXQgLXhldW8gcGlwZWZhaWwKICAgIGlmIHN5c3RlbWN0bCBpcy1hY3RpdmUgdWZ3OyB0aGVuIHN5c3RlbWN0bCBzdG9wIHVmdzsgZmkKICAgIHN5c3RlbWN0bCBtYXNrIHVmdwogICAgc3lzdGVtY3RsIHJlc3RhcnQgc3lzdGVtZC1tb2R1bGVzLWxvYWQuc2VydmljZQogICAgc3lzY3RsIC0tc3lzdGVtCiAgICBzZWQgLWkub3JpZyAnLy4qc3dhcC4qL2QnIC9ldGMvZnN0YWIKICAgIHN3YXBvZmYgLWEKICAgIAogICAgYXB0LWdldCB1cGRhdGUKICAgIAogICAgREVCSUFOX0ZST05URU5EPW5vbmludGVyYWN0aXZlIGFwdC1nZXQgLW8gRHBrZzo6T3B0aW9uczo6PSItLWZvcmNlLWNvbmZkZWYiIC1vIERwa2c6Ok9wdGlvbnM6Oj0iLS1mb3JjZS1jb25mb2xkIiBpbnN0YWxsIC15IFwKICAgICAgY3VybCBcCiAgICAgIGNhLWNlcnRpZmljYXRlcyBcCiAgICAgIGNlcGgtY29tbW9uIFwKICAgICAgY2lmcy11dGlscyBcCiAgICAgIGNvbm50cmFjayBcCiAgICAgIGUyZnNwcm9ncyBcCiAgICAgIGVidGFibGVzIFwKICAgICAgZXRodG9vbCBcCiAgICAgIGdsdXN0ZXJmcy1jbGllbnQgXAogICAgICBpcHRhYmxlcyBcCiAgICAgIGpxIFwKICAgICAga21vZCBcCiAgICAgIG9wZW5zc2gtY2xpZW50IFwKICAgICAgbmZzLWNvbW1vbiBcCiAgICAgIHNvY2F0IFwKICAgICAgdXRpbC1saW51eCBcCiAgICAgIGlwdnNhZG0KICAgIGFwdC1nZXQgdXBkYXRlCiAgICBhcHQtZ2V0IGluc3RhbGwgLXkgYXB0LXRyYW5zcG9ydC1odHRwcyBjYS1jZXJ0aWZpY2F0ZXMgY3VybCBzb2Z0d2FyZS1wcm9wZXJ0aWVzLWNvbW1vbiBsc2ItcmVsZWFzZQogICAgY3VybCAtZnNTTCBodHRwczovL2Rvd25sb2FkLmRvY2tlci5jb20vbGludXgvdWJ1bnR1L2dwZyB8IGFwdC1rZXkgYWRkIC0KICAgIGFkZC1hcHQtcmVwb3NpdG9yeSAiZGViIGh0dHBzOi8vZG93bmxvYWQuZG9ja2VyLmNvbS9saW51eC91YnVudHUgJChsc2JfcmVsZWFzZSAtY3MpIHN0YWJsZSIKICAgIAogICAgY2F0IDw8RU9GIHwgdGVlIC9ldGMvY3JpY3RsLnlhbWwKICAgIHJ1bnRpbWUtZW5kcG9pbnQ6IHVuaXg6Ly8vcnVuL2NvbnRhaW5lcmQvY29udGFpbmVyZC5zb2NrCiAgICBFT0YKICAgIAogICAgbWtkaXIgLXAgL2V0Yy9zeXN0ZW1kL3N5c3RlbS9jb250YWluZXJkLnNlcnZpY2UuZAogICAgY2F0IDw8RU9GIHwgdGVlIC9ldGMvc3lzdGVtZC9zeXN0ZW0vY29udGFpbmVyZC5zZXJ2aWNlLmQvZW52aXJvbm1lbnQuY29uZgogICAgW1NlcnZpY2VdCiAgICBSZXN0YXJ0PWFsd2F5cwogICAgRW52aXJvbm1lbnRGaWxlPS0vZXRjL2Vudmlyb25tZW50CiAgICBFT0YKICAgIAogICAgYXB0LWdldCBpbnN0YWxsIC15IC0tYWxsb3ctZG93bmdyYWRlcyBjb250YWluZXJkLmlvPTEuNCoKICAgIGFwdC1tYXJrIGhvbGQgY29udGFpbmVyZC5pbwogICAgCiAgICBzeXN0ZW1jdGwgZGFlbW9uLXJlbG9hZAogICAgc3lzdGVtY3RsIGVuYWJsZSAtLW5vdyBjb250YWluZXJkCiAgICBvcHRfYmluPS9vcHQvYmluCiAgICBjbmlfYmluX2Rpcj0vb3B0L2NuaS9iaW4KICAgIG1rZGlyIC1wIC9ldGMvY25pL25ldC5kIC9ldGMva3ViZXJuZXRlcy9keW5hbWljLWNvbmZpZy1kaXIgL2V0Yy9rdWJlcm5ldGVzL21hbmlmZXN0cyAiJG9wdF9iaW4iICIkY25pX2Jpbl9kaXIiCiAgICBhcmNoPSR7SE9TVF9BUkNILX0KICAgIGlmIFsgLXogIiRhcmNoIiBdCiAgICB0aGVuCiAgICBjYXNlICQodW5hbWUgLW0pIGluCiAgICB4ODZfNjQpCiAgICAgICAgYXJjaD0iYW1kNjQiCiAgICAgICAgOzsKICAgIGFhcmNoNjQpCiAgICAgICAgYXJjaD0iYXJtNjQiCiAgICAgICAgOzsKICAgICopCiAgICAgICAgZWNobyAidW5zdXBwb3J0ZWQgQ1BVIGFyY2hpdGVjdHVyZSwgZXhpdGluZyIKICAgICAgICBleGl0IDEKICAgICAgICA7OwogICAgZXNhYwogICAgZmkKICAgIENOSV9WRVJTSU9OPSIke0NOSV9WRVJTSU9OOi12MC44Ljd9IgogICAgY25pX2Jhc2VfdXJsPSJodHRwczovL2dpdGh1Yi5jb20vY29udGFpbmVybmV0d29ya2luZy9wbHVnaW5zL3JlbGVhc2VzL2Rvd25sb2FkLyRDTklfVkVSU0lPTiIKICAgIGNuaV9maWxlbmFtZT0iY25pLXBsdWdpbnMtbGludXgtJGFyY2gtJENOSV9WRVJTSU9OLnRneiIKICAgIGN1cmwgLUxmbyAiJGNuaV9iaW5fZGlyLyRjbmlfZmlsZW5hbWUiICIkY25pX2Jhc2VfdXJsLyRjbmlfZmlsZW5hbWUiCiAgICBjbmlfc3VtPSQoY3VybCAtTGYgIiRjbmlfYmFzZV91cmwvJGNuaV9maWxlbmFtZS5zaGEyNTYiKQogICAgY2QgIiRjbmlfYmluX2RpciIKICAgIHNoYTI1NnN1bSAtYyA8PDwiJGNuaV9zdW0iCiAgICB0YXIgeHZmICIkY25pX2ZpbGVuYW1lIgogICAgcm0gLWYgIiRjbmlfZmlsZW5hbWUiCiAgICBjZCAtCiAgICBLVUJFX1ZFUlNJT049IiR7S1VCRV9WRVJTSU9OOi12MS4yMi4xfSIKICAgIGt1YmVfZGlyPSIkb3B0X2Jpbi9rdWJlcm5ldGVzLSRLVUJFX1ZFUlNJT04iCiAgICBrdWJlX2Jhc2VfdXJsPSJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20va3ViZXJuZXRlcy1yZWxlYXNlL3JlbGVhc2UvJEtVQkVfVkVSU0lPTi9iaW4vbGludXgvJGFyY2giCiAgICBrdWJlX3N1bV9maWxlPSIka3ViZV9kaXIvc2hhMjU2IgogICAgbWtkaXIgLXAgIiRrdWJlX2RpciIKICAgIDogPiIka3ViZV9zdW1fZmlsZSIKICAgIAogICAgZm9yIGJpbiBpbiBrdWJlbGV0IGt1YmVhZG0ga3ViZWN0bDsgZG8KICAgICAgICBjdXJsIC1MZm8gIiRrdWJlX2Rpci8kYmluIiAiJGt1YmVfYmFzZV91cmwvJGJpbiIKICAgICAgICBjaG1vZCAreCAiJGt1YmVfZGlyLyRiaW4iCiAgICAgICAgc3VtPSQoY3VybCAtTGYgIiRrdWJlX2Jhc2VfdXJsLyRiaW4uc2hhMjU2IikKICAgICAgICBlY2hvICIkc3VtICAka3ViZV9kaXIvJGJpbiIgPj4iJGt1YmVfc3VtX2ZpbGUiCiAgICBkb25lCiAgICBzaGEyNTZzdW0gLWMgIiRrdWJlX3N1bV9maWxlIgogICAgCiAgICBmb3IgYmluIGluIGt1YmVsZXQga3ViZWFkbSBrdWJlY3RsOyBkbwogICAgICAgIGxuIC1zZiAiJGt1YmVfZGlyLyRiaW4iICIkb3B0X2JpbiIvJGJpbgogICAgZG9uZQogICAgCiAgICBpZiBbWyAhIC14IC9vcHQvYmluL2hlYWx0aC1tb25pdG9yLnNoIF1dOyB0aGVuCiAgICAgICAgY3VybCAtTGZvIC9vcHQvYmluL2hlYWx0aC1tb25pdG9yLnNoIGh0dHBzOi8vcmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbS9rdWJlcm1hdGljL21hY2hpbmUtY29udHJvbGxlci83OTY3YTBhZjJiNzVmMjlhZDJhYjIyN2VlYWEyNmVhN2IwZjJmYmRlL3BrZy91c2VyZGF0YS9zY3JpcHRzL2hlYWx0aC1tb25pdG9yLnNoCiAgICAgICAgY2htb2QgK3ggL29wdC9iaW4vaGVhbHRoLW1vbml0b3Iuc2gKICAgIGZpCiAgICAKICAgICMgc2V0IGt1YmVsZXQgbm9kZWlwIGVudmlyb25tZW50IHZhcmlhYmxlCiAgICAvb3B0L2Jpbi9zZXR1cF9uZXRfZW52LnNoCiAgICAKICAgIHN5c3RlbWN0bCBlbmFibGUgLS1ub3cga3ViZWxldAogICAgc3lzdGVtY3RsIGVuYWJsZSAtLW5vdyAtLW5vLWJsb2NrIGt1YmVsZXQtaGVhbHRoY2hlY2suc2VydmljZQogICAgCgotIHBhdGg6ICcvb3B0L2Jpbi9zdXBlcnZpc2Uuc2gnCiAgcGVybWlzc2lvbnM6ICcwNzU1JwogIGNvbnRlbnQ6IHwtCiAgICAjIS9iaW4vYmFzaAogICAgc2V0IC14ZXVvIHBpcGVmYWlsCiAgICB3aGlsZSAhICIkQCI7IGRvCiAgICAgIHNsZWVwIDEKICAgIGRvbmUKICAgIAoKLSBwYXRoOiAnL2V0Yy9zeXN0ZW1kL3N5c3RlbS9rdWJlbGV0LnNlcnZpY2UnCiAgY29udGVudDogfC0KICAgIFtVbml0XQogICAgQWZ0ZXI9Y29udGFpbmVyZC5zZXJ2aWNlCiAgICBSZXF1aXJlcz1jb250YWluZXJkLnNlcnZpY2UKICAgIAogICAgRGVzY3JpcHRpb249a3ViZWxldDogVGhlIEt1YmVybmV0ZXMgTm9kZSBBZ2VudAogICAgRG9jdW1lbnRhdGlvbj1odHRwczovL2t1YmVybmV0ZXMuaW8vZG9jcy9ob21lLwogICAgCiAgICBbU2VydmljZV0KICAgIFJlc3RhcnQ9YWx3YXlzCiAgICBTdGFydExpbWl0SW50ZXJ2YWw9MAogICAgUmVzdGFydFNlYz0xMAogICAgQ1BVQWNjb3VudGluZz10cnVlCiAgICBNZW1vcnlBY2NvdW50aW5nPXRydWUKICAgIAogICAgRW52aXJvbm1lbnQ9IlBBVEg9L29wdC9iaW46L2JpbjovdXNyL2xvY2FsL3NiaW46L3Vzci9sb2NhbC9iaW46L3Vzci9zYmluOi91c3IvYmluOi9zYmluLyIKICAgIEVudmlyb25tZW50RmlsZT0tL2V0Yy9lbnZpcm9ubWVudAogICAgCiAgICBFeGVjU3RhcnRQcmU9L2Jpbi9iYXNoIC9vcHQvbG9hZC1rZXJuZWwtbW9kdWxlcy5zaAogICAgRXhlY1N0YXJ0UHJlPS9iaW4vYmFzaCAvb3B0L2Jpbi9zZXR1cF9uZXRfZW52LnNoCiAgICBFeGVjU3RhcnQ9L29wdC9iaW4va3ViZWxldCAkS1VCRUxFVF9FWFRSQV9BUkdTIFwKICAgICAgLS1ib290c3RyYXAta3ViZWNvbmZpZz0vZXRjL2t1YmVybmV0ZXMvYm9vdHN0cmFwLWt1YmVsZXQuY29uZiBcCiAgICAgIC0ta3ViZWNvbmZpZz0vdmFyL2xpYi9rdWJlbGV0L2t1YmVjb25maWcgXAogICAgICAtLWNvbmZpZz0vZXRjL2t1YmVybmV0ZXMva3ViZWxldC5jb25mIFwKICAgICAgLS1uZXR3b3JrLXBsdWdpbj1jbmkgXAogICAgICAtLWNlcnQtZGlyPS9ldGMva3ViZXJuZXRlcy9wa2kgXAogICAgICAtLWNsb3VkLXByb3ZpZGVyPWF3cyBcCiAgICAgIC0tY2xvdWQtY29uZmlnPS9ldGMva3ViZXJuZXRlcy9jbG91ZC1jb25maWcgXAogICAgICAtLWR5bmFtaWMtY29uZmlnLWRpcj0vZXRjL2t1YmVybmV0ZXMvZHluYW1pYy1jb25maWctZGlyIFwKICAgICAgLS1mZWF0dXJlLWdhdGVzPUR5bmFtaWNLdWJlbGV0Q29uZmlnPXRydWUgXAogICAgICAtLWV4aXQtb24tbG9jay1jb250ZW50aW9uIFwKICAgICAgLS1sb2NrLWZpbGU9L3RtcC9rdWJlbGV0LmxvY2sgXAogICAgICAtLWNvbnRhaW5lci1ydW50aW1lPXJlbW90ZSBcCiAgICAgIC0tY29udGFpbmVyLXJ1bnRpbWUtZW5kcG9pbnQ9dW5peDovLy9ydW4vY29udGFpbmVyZC9jb250YWluZXJkLnNvY2sgXAogICAgICAtLW5vZGUtaXAgJHtLVUJFTEVUX05PREVfSVB9CiAgICAKICAgIFtJbnN0YWxsXQogICAgV2FudGVkQnk9bXVsdGktdXNlci50YXJnZXQKICAgIAoKLSBwYXRoOiAnL2V0Yy9zeXN0ZW1kL3N5c3RlbS9rdWJlbGV0LnNlcnZpY2UuZC9leHRyYXMuY29uZicKICBjb250ZW50OiB8LQogICAgW1NlcnZpY2VdCiAgICBFbnZpcm9ubWVudD0iS1VCRUxFVF9FWFRSQV9BUkdTPS0tcmVzb2x2LWNvbmY9L3J1bi9zeXN0ZW1kL3Jlc29sdmUvcmVzb2x2LmNvbmYiCiAgICAKCi0gcGF0aDogJy9ldGMva3ViZXJuZXRlcy9jbG91ZC1jb25maWcnCiAgcGVybWlzc2lvbnM6ICcwNjAwJwogIGNvbnRlbnQ6IHwtCiAgICBbZ2xvYmFsXQogICAgWm9uZT0iIgogICAgVlBDPSIiCiAgICBTdWJuZXRJRD0idGVzdC1zdWJuZXQiCiAgICAKICAgIAoKLSBwYXRoOiAnL29wdC9iaW4vc2V0dXBfbmV0X2Vudi5zaCcKICBwZXJtaXNzaW9uczogJzA3NTUnCiAgY29udGVudDogfC0KICAgICMhL3Vzci9iaW4vZW52IGJhc2gKICAgIGVjaG9kYXRlKCkgewogICAgICBlY2hvICJbJChkYXRlIC1JcyldIiAiJEAiCiAgICB9CiAgICAKICAgICMgZ2V0IHRoZSBkZWZhdWx0IGludGVyZmFjZSBJUCBhZGRyZXNzCiAgICBERUZBVUxUX0lGQ19JUD0kKGlwIC1vICByb3V0ZSBnZXQgMSB8IGdyZXAgLW9QICJzcmMgXEtcUysiKQogICAgCiAgICBpZiBbIC16ICIke0RFRkFVTFRfSUZDX0lQfSIgXQogICAgdGhlbgogICAgICBlY2hvZGF0ZSAiRmFpbGVkIHRvIGdldCBJUCBhZGRyZXNzIGZvciB0aGUgZGVmYXVsdCByb3V0ZSBpbnRlcmZhY2UiCiAgICAgIGV4aXQgMQogICAgZmkKICAgIAogICAgICMgZ2V0IHRoZSBmdWxsIGhvc3RuYW1lCiAgICBGVUxMX0hPU1ROQU1FPSQoaG9zdG5hbWUgLWYpCiAgICAKICAgICMgd3JpdGUgdGhlIG5vZGVpcF9lbnYgZmlsZQogICAgIyB3ZSBuZWVkIHRoZSBsaW5lIGJlbG93IGJlY2F1c2UgZmxhdGNhciBoYXMgdGhlIHNhbWUgc3RyaW5nICJjb3Jlb3MiIGluIHRoYXQgZmlsZQogICAgaWYgZ3JlcCAtcSBjb3Jlb3MgL2V0Yy9vcy1yZWxlYXNlCiAgICB0aGVuCiAgICAgIGVjaG8gIktVQkVMRVRfTk9ERV9JUD0ke0RFRkFVTFRfSUZDX0lQfVxuS1VCRUxFVF9IT1NUTkFNRT0ke0ZVTExfSE9TVE5BTUV9IiA+IC9ldGMva3ViZXJuZXRlcy9ub2RlaXAuY29uZgogICAgZWxpZiBbICEgLWQgL2V0Yy9zeXN0ZW1kL3N5c3RlbS9rdWJlbGV0LnNlcnZpY2UuZCBdCiAgICB0aGVuCiAgICAgIGVjaG9kYXRlICJDYW4ndCBmaW5kIGt1YmVsZXQgc2VydmljZSBleHRyYXMgZGlyZWN0b3J5IgogICAgICBleGl0IDEKICAgIGVsc2UKICAgICAgZWNobyAtZSAiW1NlcnZpY2VdXG5FbnZpcm9ubWVudD1cIktVQkVMRVRfTk9ERV9JUD0ke0RFRkFVTFRfSUZDX0lQfVwiXG5FbnZpcm9ubWVudD1cIktVQkVMRVRfSE9TVE5BTUU9JHtGVUxMX0hPU1ROQU1FfVwiIiA+IC9ldGMvc3lzdGVtZC9zeXN0ZW0va3ViZWxldC5zZXJ2aWNlLmQvbm9kZWlwLmNvbmYKICAgIGZpCiAgICAKCi0gcGF0aDogJy9ldGMva3ViZXJuZXRlcy9wa2kvY2EuY3J0JwogIGNvbnRlbnQ6IHwtCiAgICAtLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KICAgIE1JSUVXakNDQTBLZ0F3SUJBZ0lKQUxmUmxXc0k4WVFITUEwR0NTcUdTSWIzRFFFQkJRVUFNSHN4Q3pBSkJnTlYKICAgIEJBWVRBbFZUTVFzd0NRWURWUVFJRXdKRFFURVdNQlFHQTFVRUJ4TU5VMkZ1SUVaeVlXNWphWE5qYnpFVU1CSUcKICAgIEExVUVDaE1MUW5KaFpHWnBkSHBwYm1NeEVqQVFCZ05WQkFNVENXeHZZMkZzYUc5emRERWRNQnNHQ1NxR1NJYjMKICAgIERRRUpBUllPWW5KaFpFQmtZVzVuWVM1amIyMHdIaGNOTVRRd056RTFNakEwTmpBMVdoY05NVGN3TlRBME1qQTAKICAgIE5qQTFXakI3TVFzd0NRWURWUVFHRXdKVlV6RUxNQWtHQTFVRUNCTUNRMEV4RmpBVUJnTlZCQWNURFZOaGJpQkcKICAgIGNtRnVZMmx6WTI4eEZEQVNCZ05WQkFvVEMwSnlZV1JtYVhSNmFXNWpNUkl3RUFZRFZRUURFd2xzYjJOaGJHaHYKICAgIGMzUXhIVEFiQmdrcWhraUc5dzBCQ1FFV0RtSnlZV1JBWkdGdVoyRXVZMjl0TUlJQklqQU5CZ2txaGtpRzl3MEIKICAgIEFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXQ1ZkFqcDRmVGNla1dVVGZ6c3Awa3lpaDFPWWJzR0wwS1gxZVJiU1MKICAgIFI4T2QwKzlRNjJIeW55K0dGd01UYjRBL0tVOG1zc29IdmNjZVNBQWJ3ZmJ4RksvK3M1MVRvYnFVbk9SWnJPb1QKICAgIFpqa1V5Z2J5WERTSzk5WUJiY1IxUGlwOHZ3TVRtNFhLdUx0Q2lnZUJCZGpqQVFkZ1VPMjhMRU5HbHNNbm1lWWsKICAgIEpmT0RWR25WbXI1THRiOUFOQThJS3lUZnNuSEo0aU9DUy9QbFBiVWoycTdZbm9WTHBvc1VCTWxnVWIvQ3lrWDMKICAgIG1Pb0xiNHlKSlF5QS9pU1Q2WnhpSUVqMzZENHlXWjVsZzdZSmwrVWlpQlFIR0NuUGRHeWlwcVYwNmV4MGhlWVcKICAgIGNhaVc4TFdaU1VROTNqUStXVkNIOGhUN0RRTzFkbXN2VW1YbHEvSmVBbHdRL1FJREFRQUJvNEhnTUlIZE1CMEcKICAgIEExVWREZ1FXQkJSY0FST3RoUzRQNFU3dlRmakJ5QzU2OVI3RTZEQ0JyUVlEVlIwakJJR2xNSUdpZ0JSY0FST3QKICAgIGhTNFA0VTd2VGZqQnlDNTY5UjdFNktGL3BIMHdlekVMTUFrR0ExVUVCaE1DVlZNeEN6QUpCZ05WQkFnVEFrTkIKICAgIE1SWXdGQVlEVlFRSEV3MVRZVzRnUm5KaGJtTnBjMk52TVJRd0VnWURWUVFLRXd0Q2NtRmtabWwwZW1sdVl6RVMKICAgIE1CQUdBMVVFQXhNSmJHOWpZV3hvYjNOME1SMHdHd1lKS29aSWh2Y05BUWtCRmc1aWNtRmtRR1JoYm1kaExtTnYKICAgIGJZSUpBTGZSbFdzSThZUUhNQXdHQTFVZEV3UUZNQU1CQWY4d0RRWUpLb1pJaHZjTkFRRUZCUUFEZ2dFQkFHNmgKICAgIFU5ZjlzTkgwLzZvQmJHR3kyRVZVMFVnSVRVUUlyRldvOXJGa3JXNWsvWGtEalFtKzNsempUMGlHUjRJeEUvQW8KICAgIGVVNnNRaHVhN3dyV2VGRW40N0dMOThsbkNzSmREN29aTmhGbVE5NVRiL0xuRFVqczVZajliclAwTld6WGZZVTQKICAgIFVLMlpuSU5KUmNKcEI4aVJDYUN4RThEZGNVRjBYcUlFcTZwQTI3MnNub0xtaVhMTXZObDNrWUVkbStqZTZ2b0QKICAgIDU4U05WRVVzenR6UXlYbUpFaENwd1ZJMEE2UUNqelhqK3F2cG13M1paSGk4SndYZWk4WlpCTFRTRkJraThaN24KICAgIHNIOUJCSDM4L1N6VW1BTjRRSFNQeTFnanFtMDBPQUU4TmFZRGtoL2J6RTRkN21MR0dNV3AvV0UzS1BTdTgySEYKICAgIGtQZTZYb1NiaUxtL2t4azMyVDA9CiAgICAtLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCiAgICAKCi0gcGF0aDogJy9ldGMvc3lzdGVtZC9zeXN0ZW0vc2V0dXAuc2VydmljZScKICBwZXJtaXNzaW9uczogJzA2NDQnCiAgY29udGVudDogfC0KICAgIFtJbnN0YWxsXQogICAgV2FudGVkQnk9bXVsdGktdXNlci50YXJnZXQKICAgIAogICAgW1VuaXRdCiAgICBSZXF1aXJlcz1uZXR3b3JrLW9ubGluZS50YXJnZXQKICAgIEFmdGVyPW5ldHdvcmstb25saW5lLnRhcmdldAogICAgCiAgICBbU2VydmljZV0KICAgIFR5cGU9b25lc2hvdAogICAgUmVtYWluQWZ0ZXJFeGl0PXRydWUKICAgIEVudmlyb25tZW50RmlsZT0tL2V0Yy9lbnZpcm9ubWVudAogICAgRXhlY1N0YXJ0PS9vcHQvYmluL3N1cGVydmlzZS5zaCAvb3B0L2Jpbi9zZXR1cAogICAgCgotIHBhdGg6ICcvZXRjL3Byb2ZpbGUuZC9vcHQtYmluLXBhdGguc2gnCiAgcGVybWlzc2lvbnM6ICcwNjQ0JwogIGNvbnRlbnQ6IHwtCiAgICBleHBvcnQgUEFUSD0iL29wdC9iaW46JFBBVEgiCiAgICAKCi0gcGF0aDogJy9ldGMva3ViZXJuZXRlcy9rdWJlbGV0LmNvbmYnCiAgY29udGVudDogfC0KICAgIGFwaVZlcnNpb246IGt1YmVsZXQuY29uZmlnLms4cy5pby92MWJldGExCiAgICBraW5kOiBLdWJlbGV0Q29uZmlndXJhdGlvbgogICAgYXV0aGVudGljYXRpb246CiAgICAgIGFub255bW91czoKICAgICAgICBlbmFibGVkOiBmYWxzZQogICAgICB3ZWJob29rOgogICAgICAgIGVuYWJsZWQ6IHRydWUKICAgICAgeDUwOToKICAgICAgICBjbGllbnRDQUZpbGU6IC9ldGMva3ViZXJuZXRlcy9wa2kvY2EuY3J0CiAgICBhdXRob3JpemF0aW9uOgogICAgICBtb2RlOiBXZWJob29rCiAgICBjZ3JvdXBEcml2ZXI6IHN5c3RlbWQKICAgIGNsdXN0ZXJETlM6CiAgICAtICIxMC4wLjAuMCIKICAgIGNsdXN0ZXJEb21haW46IGNsdXN0ZXIubG9jYWwKICAgIGNvbnRhaW5lckxvZ01heFNpemU6IDMwME1pCiAgICBjb250YWluZXJMb2dNYXhGaWxlczogMzAKICAgIGZlYXR1cmVHYXRlczoKICAgICAgR3JhY2VmdWxOb2RlU2h1dGRvd246IHRydWUKICAgICAgSWRlbnRpZnlQb2RPUzogZmFsc2UKICAgIHByb3RlY3RLZXJuZWxEZWZhdWx0czogdHJ1ZQogICAgcmVhZE9ubHlQb3J0OiAwCiAgICByb3RhdGVDZXJ0aWZpY2F0ZXM6IHRydWUKICAgIHNlcnZlclRMU0Jvb3RzdHJhcDogdHJ1ZQogICAgc3RhdGljUG9kUGF0aDogL2V0Yy9rdWJlcm5ldGVzL21hbmlmZXN0cwogICAga3ViZVJlc2VydmVkOgogICAgICBjcHU6IDMwbQogICAgICBlcGhlbWVyYWwtc3RvcmFnZTogMzBHaQogICAgc3lzdGVtUmVzZXJ2ZWQ6CiAgICAgIGNwdTogMzBtCiAgICAgIGVwaGVtZXJhbC1zdG9yYWdlOiAzMEdpCiAgICBldmljdGlvbkhhcmQ6CiAgICAgIG1lbW9yeS5hdmFpbGFibGU6IDMwTWkKICAgIHRsc0NpcGhlclN1aXRlczoKICAgIC0gVExTX0FFU18xMjhfR0NNX1NIQTI1NgogICAgLSBUTFNfQUVTXzI1Nl9HQ01fU0hBMzg0CiAgICAtIFRMU19DSEFDSEEyMF9QT0xZMTMwNV9TSEEyNTYKICAgIC0gVExTX0VDREhFX0VDRFNBX1dJVEhfQUVTXzEyOF9HQ01fU0hBMjU2CiAgICAtIFRMU19FQ0RIRV9FQ0RTQV9XSVRIX0FFU18yNTZfR0NNX1NIQTM4NAogICAgLSBUTFNfRUNESEVfRUNEU0FfV0lUSF9DSEFDSEEyMF9QT0xZMTMwNQogICAgLSBUTFNfRUNESEVfUlNBX1dJVEhfQUVTXzEyOF9HQ01fU0hBMjU2CiAgICAtIFRMU19FQ0RIRV9SU0FfV0lUSF9BRVNfMjU2X0dDTV9TSEEzODQKICAgIC0gVExTX0VDREhFX1JTQV9XSVRIX0NIQUNIQTIwX1BPTFkxMzA1CiAgICB2b2x1bWVQbHVnaW5EaXI6IC92YXIvbGliL2t1YmVsZXQvdm9sdW1lcGx1Z2lucwogICAgCgotIHBhdGg6ICcvZXRjL3N5c3RlbWQvc3lzdGVtL2t1YmVsZXQtaGVhbHRoY2hlY2suc2VydmljZScKICBwZXJtaXNzaW9uczogJzA2NDQnCiAgY29udGVudDogfC0KICAgIFtVbml0XQogICAgUmVxdWlyZXM9a3ViZWxldC5zZXJ2aWNlCiAgICBBZnRlcj1rdWJlbGV0LnNlcnZpY2UKICAgIAogICAgW1NlcnZpY2VdCiAgICBFeGVjU3RhcnQ9L29wdC9iaW4vaGVhbHRoLW1vbml0b3Iuc2gga3ViZWxldAogICAgCiAgICBbSW5zdGFsbF0KICAgIFdhbnRlZEJ5PW11bHRpLXVzZXIudGFyZ2V0CiAgICAKCi0gcGF0aDogJy9ldGMvY29udGFpbmVyZC9jb25maWcudG9tbCcKICBwZXJtaXNzaW9uczogJzA2NDQnCiAgY29udGVudDogfC0KICAgIHZlcnNpb24gPSAyCiAgICAKICAgIFttZXRyaWNzXQogICAgYWRkcmVzcyA9ICIxMjcuMC4wLjE6MTMzOCIKICAgIAogICAgW3BsdWdpbnNdCiAgICBbcGx1Z2lucy4iaW8uY29udGFpbmVyZC5ncnBjLnYxLmNyaSJdCiAgICBzYW5kYm94X2ltYWdlID0gIjE5Mi4xNjguMTAwLjEwMDo1MDAwL2t1YmVybmV0ZXMvcGF1c2U6djMuMSIKICAgIFtwbHVnaW5zLiJpby5jb250YWluZXJkLmdycGMudjEuY3JpIi5jb250YWluZXJkXQogICAgW3BsdWdpbnMuImlvLmNvbnRhaW5lcmQuZ3JwYy52MS5jcmkiLmNvbnRhaW5lcmQucnVudGltZXNdCiAgICBbcGx1Z2lucy4iaW8uY29udGFpbmVyZC5ncnBjLnYxLmNyaSIuY29udGFpbmVyZC5ydW50aW1lcy5ydW5jXQogICAgcnVudGltZV90eXBlID0gImlvLmNvbnRhaW5lcmQucnVuYy52MiIKICAgIFtwbHVnaW5zLiJpby5jb250YWluZXJkLmdycGMudjEuY3JpIi5jb250YWluZXJkLnJ1bnRpbWVzLnJ1bmMub3B0aW9uc10KICAgIFN5c3RlbWRDZ3JvdXAgPSB0cnVlCiAgICBbcGx1Z2lucy4iaW8uY29udGFpbmVyZC5ncnBjLnYxLmNyaSIucmVnaXN0cnldCiAgICBbcGx1Z2lucy4iaW8uY29udGFpbmVyZC5ncnBjLnYxLmNyaSIucmVnaXN0cnkubWlycm9yc10KICAgIFtwbHVnaW5zLiJpby5jb250YWluZXJkLmdycGMudjEuY3JpIi5yZWdpc3RyeS5taXJyb3JzLiJkb2NrZXIuaW8iXQogICAgZW5kcG9pbnQgPSBbImh0dHBzOi8vcmVnaXN0cnkuZG9ja2VyLWNuLmNvbSJdCiAgICBbcGx1Z2lucy4iaW8uY29udGFpbmVyZC5ncnBjLnYxLmNyaSIucmVnaXN0cnkuY29uZmlnc10KICAgIFtwbHVnaW5zLiJpby5jb250YWluZXJkLmdycGMudjEuY3JpIi5yZWdpc3RyeS5jb25maWdzLiIxMC4wLjAuMTo1MDAwIl0KICAgIFtwbHVnaW5zLiJpby5jb250YWluZXJkLmdycGMudjEuY3JpIi5yZWdpc3RyeS5jb25maWdzLiIxMC4wLjAuMTo1MDAwIi50bHNdCiAgICBpbnNlY3VyZV9za2lwX3ZlcmlmeSA9IHRydWUKICAgIFtwbHVnaW5zLiJpby5jb250YWluZXJkLmdycGMudjEuY3JpIi5yZWdpc3RyeS5jb25maWdzLiIxOTIuMTY4LjEwMC4xMDA6NTAwMCJdCiAgICBbcGx1Z2lucy4iaW8uY29udGFpbmVyZC5ncnBjLnYxLmNyaSIucmVnaXN0cnkuY29uZmlncy4iMTkyLjE2OC4xMDAuMTAwOjUwMDAiLnRsc10KICAgIGluc2VjdXJlX3NraXBfdmVyaWZ5ID0gdHJ1ZQogICAgCiAgICAKCmJvb3RjbWQ6Ci0gZWNobyBoZWxsbwotIGVjaG8gd29ybGQKCnJoX3N1YnNjcmlwdGlvbjoKICAgIHBhc3N3b3JkOiBwYXNzd29yZAogICAgdXNlcm5hbWU6IHVzZXJuYW1l +immutable: true +kind: Secret +metadata: + creationTimestamp: null + name: kubelet-configuration-kube-system-osc-provisioning + namespace: cloud-init-settings + resourceVersion: "1" +type: Opaque diff --git a/pkg/controllers/osc/testdata/secret-kubelet-configuration-docker.yaml b/pkg/controllers/osc/testdata/secret-kubelet-configuration-docker.yaml new file mode 100644 index 00000000..19635782 --- /dev/null +++ b/pkg/controllers/osc/testdata/secret-kubelet-configuration-docker.yaml @@ -0,0 +1,11 @@ +apiVersion: v1 +data: + cloud-config: I2Nsb3VkLWNvbmZpZwoKc3NoX3B3YXV0aDogbm8Kc3NoX2F1dGhvcml6ZWRfa2V5czoKLSAnc3NoLXJzYSBBQUFBQjNOemFDMXljMkVBQUFBREFRQUJBQUFDQVFEZE9JaFltekNLNURTVkx1M2MnCndyaXRlX2ZpbGVzOgotIHBhdGg6ICcvZXRjL3N5c3RlbWQvam91cm5hbGQuY29uZi5kL21heF9kaXNrX3VzZS5jb25mJwogIGNvbnRlbnQ6IHwtCiAgICBbSm91cm5hbF0KICAgIFN5c3RlbU1heFVzZT01RwogICAgCgotIHBhdGg6ICcvb3B0L2xvYWQta2VybmVsLW1vZHVsZXMuc2gnCiAgcGVybWlzc2lvbnM6ICcwNzU1JwogIGNvbnRlbnQ6IHwtCiAgICAjIS91c3IvYmluL2VudiBiYXNoCiAgICBzZXQgLWV1byBwaXBlZmFpbAogICAgCiAgICBtb2Rwcm9iZSBpcF92cwogICAgbW9kcHJvYmUgaXBfdnNfcnIKICAgIG1vZHByb2JlIGlwX3ZzX3dycgogICAgbW9kcHJvYmUgaXBfdnNfc2gKICAgIAogICAgaWYgbW9kaW5mbyBuZl9jb25udHJhY2tfaXB2NCAmPiAvZGV2L251bGw7IHRoZW4KICAgICAgbW9kcHJvYmUgbmZfY29ubnRyYWNrX2lwdjQKICAgIGVsc2UKICAgICAgbW9kcHJvYmUgbmZfY29ubnRyYWNrCiAgICBmaQogICAgCgotIHBhdGg6ICcvZXRjL3N5c2N0bC5kL2s4cy5jb25mJwogIGNvbnRlbnQ6IHwtCiAgICBuZXQuYnJpZGdlLmJyaWRnZS1uZi1jYWxsLWlwNnRhYmxlcyA9IDEKICAgIG5ldC5icmlkZ2UuYnJpZGdlLW5mLWNhbGwtaXB0YWJsZXMgPSAxCiAgICBrZXJuZWwucGFuaWNfb25fb29wcyA9IDEKICAgIGtlcm5lbC5wYW5pYyA9IDEwCiAgICBuZXQuaXB2NC5pcF9mb3J3YXJkID0gMQogICAgdm0ub3ZlcmNvbW1pdF9tZW1vcnkgPSAxCiAgICBmcy5pbm90aWZ5Lm1heF91c2VyX3dhdGNoZXMgPSAxMDQ4NTc2CiAgICAKCi0gcGF0aDogJy9ldGMvZGVmYXVsdC9ncnViLmQvNjAtc3dhcC1hY2NvdW50aW5nLmNmZycKICBjb250ZW50OiB8LQogICAgIyBBZGRlZCBieSBrdWJlcm1hdGljIG1hY2hpbmUtY29udHJvbGxlcgogICAgIyBFbmFibGUgY2dyb3VwcyBtZW1vcnkgYW5kIHN3YXAgYWNjb3VudGluZwogICAgR1JVQl9DTURMSU5FX0xJTlVYPSJjZ3JvdXBfZW5hYmxlPW1lbW9yeSBzd2FwYWNjb3VudD0xIgogICAgCgotIHBhdGg6ICcvb3B0L2Jpbi9zZXR1cCcKICBwZXJtaXNzaW9uczogJzA3NTUnCiAgY29udGVudDogfC0KICAgICMhL2Jpbi9iYXNoCiAgICBzZXQgLXhldW8gcGlwZWZhaWwKICAgIGlmIHN5c3RlbWN0bCBpcy1hY3RpdmUgdWZ3OyB0aGVuIHN5c3RlbWN0bCBzdG9wIHVmdzsgZmkKICAgIHN5c3RlbWN0bCBtYXNrIHVmdwogICAgc3lzdGVtY3RsIHJlc3RhcnQgc3lzdGVtZC1tb2R1bGVzLWxvYWQuc2VydmljZQogICAgc3lzY3RsIC0tc3lzdGVtCiAgICBzZWQgLWkub3JpZyAnLy4qc3dhcC4qL2QnIC9ldGMvZnN0YWIKICAgIHN3YXBvZmYgLWEKICAgIAogICAgYXB0LWdldCB1cGRhdGUKICAgIAogICAgREVCSUFOX0ZST05URU5EPW5vbmludGVyYWN0aXZlIGFwdC1nZXQgLW8gRHBrZzo6T3B0aW9uczo6PSItLWZvcmNlLWNvbmZkZWYiIC1vIERwa2c6Ok9wdGlvbnM6Oj0iLS1mb3JjZS1jb25mb2xkIiBpbnN0YWxsIC15IFwKICAgICAgY3VybCBcCiAgICAgIGNhLWNlcnRpZmljYXRlcyBcCiAgICAgIGNlcGgtY29tbW9uIFwKICAgICAgY2lmcy11dGlscyBcCiAgICAgIGNvbm50cmFjayBcCiAgICAgIGUyZnNwcm9ncyBcCiAgICAgIGVidGFibGVzIFwKICAgICAgZXRodG9vbCBcCiAgICAgIGdsdXN0ZXJmcy1jbGllbnQgXAogICAgICBpcHRhYmxlcyBcCiAgICAgIGpxIFwKICAgICAga21vZCBcCiAgICAgIG9wZW5zc2gtY2xpZW50IFwKICAgICAgbmZzLWNvbW1vbiBcCiAgICAgIHNvY2F0IFwKICAgICAgdXRpbC1saW51eCBcCiAgICAgIGlwdnNhZG0KICAgIGFwdC1nZXQgdXBkYXRlCiAgICBhcHQtZ2V0IGluc3RhbGwgLXkgYXB0LXRyYW5zcG9ydC1odHRwcyBjYS1jZXJ0aWZpY2F0ZXMgY3VybCBzb2Z0d2FyZS1wcm9wZXJ0aWVzLWNvbW1vbiBsc2ItcmVsZWFzZQogICAgY3VybCAtZnNTTCBodHRwczovL2Rvd25sb2FkLmRvY2tlci5jb20vbGludXgvdWJ1bnR1L2dwZyB8IGFwdC1rZXkgYWRkIC0KICAgIGFkZC1hcHQtcmVwb3NpdG9yeSAiZGViIGh0dHBzOi8vZG93bmxvYWQuZG9ja2VyLmNvbS9saW51eC91YnVudHUgJChsc2JfcmVsZWFzZSAtY3MpIHN0YWJsZSIKICAgIAogICAgbWtkaXIgLXAgL2V0Yy9zeXN0ZW1kL3N5c3RlbS9jb250YWluZXJkLnNlcnZpY2UuZCAvZXRjL3N5c3RlbWQvc3lzdGVtL2RvY2tlci5zZXJ2aWNlLmQKICAgIAogICAgY2F0IDw8RU9GIHwgdGVlIC9ldGMvc3lzdGVtZC9zeXN0ZW0vY29udGFpbmVyZC5zZXJ2aWNlLmQvZW52aXJvbm1lbnQuY29uZiAvZXRjL3N5c3RlbWQvc3lzdGVtL2RvY2tlci5zZXJ2aWNlLmQvZW52aXJvbm1lbnQuY29uZgogICAgW1NlcnZpY2VdCiAgICBSZXN0YXJ0PWFsd2F5cwogICAgRW52aXJvbm1lbnRGaWxlPS0vZXRjL2Vudmlyb25tZW50CiAgICBFT0YKICAgIAogICAgYXB0LWdldCBpbnN0YWxsIC15IFwKICAgICAgICBjb250YWluZXJkLmlvPTEuNC4zKiBcCiAgICAgICAgZG9ja2VyLWNlPTU6MTkuMDMuMTMqIFwKICAgICAgICBkb2NrZXItY2UtY2xpPTU6MTkuMDMuMTMqCiAgICBhcHQtbWFyayBob2xkIGRvY2tlci1jZSBkb2NrZXItY2UtY2xpIGNvbnRhaW5lcmQuaW8KICAgIAogICAgc3lzdGVtY3RsIGRhZW1vbi1yZWxvYWQKICAgIHN5c3RlbWN0bCBlbmFibGUgLS1ub3cgZG9ja2VyCiAgICBvcHRfYmluPS9vcHQvYmluCiAgICBjbmlfYmluX2Rpcj0vb3B0L2NuaS9iaW4KICAgIG1rZGlyIC1wIC9ldGMvY25pL25ldC5kIC9ldGMva3ViZXJuZXRlcy9keW5hbWljLWNvbmZpZy1kaXIgL2V0Yy9rdWJlcm5ldGVzL21hbmlmZXN0cyAiJG9wdF9iaW4iICIkY25pX2Jpbl9kaXIiCiAgICBhcmNoPSR7SE9TVF9BUkNILX0KICAgIGlmIFsgLXogIiRhcmNoIiBdCiAgICB0aGVuCiAgICBjYXNlICQodW5hbWUgLW0pIGluCiAgICB4ODZfNjQpCiAgICAgICAgYXJjaD0iYW1kNjQiCiAgICAgICAgOzsKICAgIGFhcmNoNjQpCiAgICAgICAgYXJjaD0iYXJtNjQiCiAgICAgICAgOzsKICAgICopCiAgICAgICAgZWNobyAidW5zdXBwb3J0ZWQgQ1BVIGFyY2hpdGVjdHVyZSwgZXhpdGluZyIKICAgICAgICBleGl0IDEKICAgICAgICA7OwogICAgZXNhYwogICAgZmkKICAgIENOSV9WRVJTSU9OPSIke0NOSV9WRVJTSU9OOi12MC44Ljd9IgogICAgY25pX2Jhc2VfdXJsPSJodHRwczovL2dpdGh1Yi5jb20vY29udGFpbmVybmV0d29ya2luZy9wbHVnaW5zL3JlbGVhc2VzL2Rvd25sb2FkLyRDTklfVkVSU0lPTiIKICAgIGNuaV9maWxlbmFtZT0iY25pLXBsdWdpbnMtbGludXgtJGFyY2gtJENOSV9WRVJTSU9OLnRneiIKICAgIGN1cmwgLUxmbyAiJGNuaV9iaW5fZGlyLyRjbmlfZmlsZW5hbWUiICIkY25pX2Jhc2VfdXJsLyRjbmlfZmlsZW5hbWUiCiAgICBjbmlfc3VtPSQoY3VybCAtTGYgIiRjbmlfYmFzZV91cmwvJGNuaV9maWxlbmFtZS5zaGEyNTYiKQogICAgY2QgIiRjbmlfYmluX2RpciIKICAgIHNoYTI1NnN1bSAtYyA8PDwiJGNuaV9zdW0iCiAgICB0YXIgeHZmICIkY25pX2ZpbGVuYW1lIgogICAgcm0gLWYgIiRjbmlfZmlsZW5hbWUiCiAgICBjZCAtCiAgICBLVUJFX1ZFUlNJT049IiR7S1VCRV9WRVJTSU9OOi12MS4yMi4xfSIKICAgIGt1YmVfZGlyPSIkb3B0X2Jpbi9rdWJlcm5ldGVzLSRLVUJFX1ZFUlNJT04iCiAgICBrdWJlX2Jhc2VfdXJsPSJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20va3ViZXJuZXRlcy1yZWxlYXNlL3JlbGVhc2UvJEtVQkVfVkVSU0lPTi9iaW4vbGludXgvJGFyY2giCiAgICBrdWJlX3N1bV9maWxlPSIka3ViZV9kaXIvc2hhMjU2IgogICAgbWtkaXIgLXAgIiRrdWJlX2RpciIKICAgIDogPiIka3ViZV9zdW1fZmlsZSIKICAgIAogICAgZm9yIGJpbiBpbiBrdWJlbGV0IGt1YmVhZG0ga3ViZWN0bDsgZG8KICAgICAgICBjdXJsIC1MZm8gIiRrdWJlX2Rpci8kYmluIiAiJGt1YmVfYmFzZV91cmwvJGJpbiIKICAgICAgICBjaG1vZCAreCAiJGt1YmVfZGlyLyRiaW4iCiAgICAgICAgc3VtPSQoY3VybCAtTGYgIiRrdWJlX2Jhc2VfdXJsLyRiaW4uc2hhMjU2IikKICAgICAgICBlY2hvICIkc3VtICAka3ViZV9kaXIvJGJpbiIgPj4iJGt1YmVfc3VtX2ZpbGUiCiAgICBkb25lCiAgICBzaGEyNTZzdW0gLWMgIiRrdWJlX3N1bV9maWxlIgogICAgCiAgICBmb3IgYmluIGluIGt1YmVsZXQga3ViZWFkbSBrdWJlY3RsOyBkbwogICAgICAgIGxuIC1zZiAiJGt1YmVfZGlyLyRiaW4iICIkb3B0X2JpbiIvJGJpbgogICAgZG9uZQogICAgCiAgICBpZiBbWyAhIC14IC9vcHQvYmluL2hlYWx0aC1tb25pdG9yLnNoIF1dOyB0aGVuCiAgICAgICAgY3VybCAtTGZvIC9vcHQvYmluL2hlYWx0aC1tb25pdG9yLnNoIGh0dHBzOi8vcmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbS9rdWJlcm1hdGljL21hY2hpbmUtY29udHJvbGxlci83OTY3YTBhZjJiNzVmMjlhZDJhYjIyN2VlYWEyNmVhN2IwZjJmYmRlL3BrZy91c2VyZGF0YS9zY3JpcHRzL2hlYWx0aC1tb25pdG9yLnNoCiAgICAgICAgY2htb2QgK3ggL29wdC9iaW4vaGVhbHRoLW1vbml0b3Iuc2gKICAgIGZpCiAgICAKICAgICMgc2V0IGt1YmVsZXQgbm9kZWlwIGVudmlyb25tZW50IHZhcmlhYmxlCiAgICAvb3B0L2Jpbi9zZXR1cF9uZXRfZW52LnNoCiAgICAKICAgIHN5c3RlbWN0bCBlbmFibGUgLS1ub3cga3ViZWxldAogICAgc3lzdGVtY3RsIGVuYWJsZSAtLW5vdyAtLW5vLWJsb2NrIGt1YmVsZXQtaGVhbHRoY2hlY2suc2VydmljZQogICAgCgotIHBhdGg6ICcvb3B0L2Jpbi9zdXBlcnZpc2Uuc2gnCiAgcGVybWlzc2lvbnM6ICcwNzU1JwogIGNvbnRlbnQ6IHwtCiAgICAjIS9iaW4vYmFzaAogICAgc2V0IC14ZXVvIHBpcGVmYWlsCiAgICB3aGlsZSAhICIkQCI7IGRvCiAgICAgIHNsZWVwIDEKICAgIGRvbmUKICAgIAoKLSBwYXRoOiAnL2V0Yy9zeXN0ZW1kL3N5c3RlbS9rdWJlbGV0LnNlcnZpY2UnCiAgY29udGVudDogfC0KICAgIFtVbml0XQogICAgQWZ0ZXI9ZG9ja2VyLnNlcnZpY2UKICAgIFJlcXVpcmVzPWRvY2tlci5zZXJ2aWNlCiAgICAKICAgIERlc2NyaXB0aW9uPWt1YmVsZXQ6IFRoZSBLdWJlcm5ldGVzIE5vZGUgQWdlbnQKICAgIERvY3VtZW50YXRpb249aHR0cHM6Ly9rdWJlcm5ldGVzLmlvL2RvY3MvaG9tZS8KICAgIAogICAgW1NlcnZpY2VdCiAgICBSZXN0YXJ0PWFsd2F5cwogICAgU3RhcnRMaW1pdEludGVydmFsPTAKICAgIFJlc3RhcnRTZWM9MTAKICAgIENQVUFjY291bnRpbmc9dHJ1ZQogICAgTWVtb3J5QWNjb3VudGluZz10cnVlCiAgICAKICAgIEVudmlyb25tZW50PSJQQVRIPS9vcHQvYmluOi9iaW46L3Vzci9sb2NhbC9zYmluOi91c3IvbG9jYWwvYmluOi91c3Ivc2JpbjovdXNyL2Jpbjovc2Jpbi8iCiAgICBFbnZpcm9ubWVudEZpbGU9LS9ldGMvZW52aXJvbm1lbnQKICAgIAogICAgRXhlY1N0YXJ0UHJlPS9iaW4vYmFzaCAvb3B0L2xvYWQta2VybmVsLW1vZHVsZXMuc2gKICAgIEV4ZWNTdGFydFByZT0vYmluL2Jhc2ggL29wdC9iaW4vc2V0dXBfbmV0X2Vudi5zaAogICAgRXhlY1N0YXJ0PS9vcHQvYmluL2t1YmVsZXQgJEtVQkVMRVRfRVhUUkFfQVJHUyBcCiAgICAgIC0tYm9vdHN0cmFwLWt1YmVjb25maWc9L2V0Yy9rdWJlcm5ldGVzL2Jvb3RzdHJhcC1rdWJlbGV0LmNvbmYgXAogICAgICAtLWt1YmVjb25maWc9L3Zhci9saWIva3ViZWxldC9rdWJlY29uZmlnIFwKICAgICAgLS1jb25maWc9L2V0Yy9rdWJlcm5ldGVzL2t1YmVsZXQuY29uZiBcCiAgICAgIC0tbmV0d29yay1wbHVnaW49Y25pIFwKICAgICAgLS1jZXJ0LWRpcj0vZXRjL2t1YmVybmV0ZXMvcGtpIFwKICAgICAgLS1jbG91ZC1wcm92aWRlcj1hd3MgXAogICAgICAtLWNsb3VkLWNvbmZpZz0vZXRjL2t1YmVybmV0ZXMvY2xvdWQtY29uZmlnIFwKICAgICAgLS1keW5hbWljLWNvbmZpZy1kaXI9L2V0Yy9rdWJlcm5ldGVzL2R5bmFtaWMtY29uZmlnLWRpciBcCiAgICAgIC0tZmVhdHVyZS1nYXRlcz1EeW5hbWljS3ViZWxldENvbmZpZz10cnVlIFwKICAgICAgLS1leGl0LW9uLWxvY2stY29udGVudGlvbiBcCiAgICAgIC0tbG9jay1maWxlPS90bXAva3ViZWxldC5sb2NrIFwKICAgICAgLS1jb250YWluZXItcnVudGltZT1kb2NrZXIgXAogICAgICAtLWNvbnRhaW5lci1ydW50aW1lLWVuZHBvaW50PXVuaXg6Ly8vdmFyL3J1bi9kb2NrZXJzaGltLnNvY2sgXAogICAgICAtLW5vZGUtaXAgJHtLVUJFTEVUX05PREVfSVB9CiAgICAKICAgIFtJbnN0YWxsXQogICAgV2FudGVkQnk9bXVsdGktdXNlci50YXJnZXQKICAgIAoKLSBwYXRoOiAnL2V0Yy9zeXN0ZW1kL3N5c3RlbS9rdWJlbGV0LnNlcnZpY2UuZC9leHRyYXMuY29uZicKICBjb250ZW50OiB8LQogICAgW1NlcnZpY2VdCiAgICBFbnZpcm9ubWVudD0iS1VCRUxFVF9FWFRSQV9BUkdTPS0tcmVzb2x2LWNvbmY9L3J1bi9zeXN0ZW1kL3Jlc29sdmUvcmVzb2x2LmNvbmYiCiAgICAKCi0gcGF0aDogJy9ldGMva3ViZXJuZXRlcy9jbG91ZC1jb25maWcnCiAgcGVybWlzc2lvbnM6ICcwNjAwJwogIGNvbnRlbnQ6IHwtCiAgICBbZ2xvYmFsXQogICAgWm9uZT0iIgogICAgVlBDPSIiCiAgICBTdWJuZXRJRD0idGVzdC1zdWJuZXQiCiAgICAKICAgIAoKLSBwYXRoOiAnL29wdC9iaW4vc2V0dXBfbmV0X2Vudi5zaCcKICBwZXJtaXNzaW9uczogJzA3NTUnCiAgY29udGVudDogfC0KICAgICMhL3Vzci9iaW4vZW52IGJhc2gKICAgIGVjaG9kYXRlKCkgewogICAgICBlY2hvICJbJChkYXRlIC1JcyldIiAiJEAiCiAgICB9CiAgICAKICAgICMgZ2V0IHRoZSBkZWZhdWx0IGludGVyZmFjZSBJUCBhZGRyZXNzCiAgICBERUZBVUxUX0lGQ19JUD0kKGlwIC1vICByb3V0ZSBnZXQgMSB8IGdyZXAgLW9QICJzcmMgXEtcUysiKQogICAgCiAgICBpZiBbIC16ICIke0RFRkFVTFRfSUZDX0lQfSIgXQogICAgdGhlbgogICAgICBlY2hvZGF0ZSAiRmFpbGVkIHRvIGdldCBJUCBhZGRyZXNzIGZvciB0aGUgZGVmYXVsdCByb3V0ZSBpbnRlcmZhY2UiCiAgICAgIGV4aXQgMQogICAgZmkKICAgIAogICAgICMgZ2V0IHRoZSBmdWxsIGhvc3RuYW1lCiAgICBGVUxMX0hPU1ROQU1FPSQoaG9zdG5hbWUgLWYpCiAgICAKICAgICMgd3JpdGUgdGhlIG5vZGVpcF9lbnYgZmlsZQogICAgIyB3ZSBuZWVkIHRoZSBsaW5lIGJlbG93IGJlY2F1c2UgZmxhdGNhciBoYXMgdGhlIHNhbWUgc3RyaW5nICJjb3Jlb3MiIGluIHRoYXQgZmlsZQogICAgaWYgZ3JlcCAtcSBjb3Jlb3MgL2V0Yy9vcy1yZWxlYXNlCiAgICB0aGVuCiAgICAgIGVjaG8gIktVQkVMRVRfTk9ERV9JUD0ke0RFRkFVTFRfSUZDX0lQfVxuS1VCRUxFVF9IT1NUTkFNRT0ke0ZVTExfSE9TVE5BTUV9IiA+IC9ldGMva3ViZXJuZXRlcy9ub2RlaXAuY29uZgogICAgZWxpZiBbICEgLWQgL2V0Yy9zeXN0ZW1kL3N5c3RlbS9rdWJlbGV0LnNlcnZpY2UuZCBdCiAgICB0aGVuCiAgICAgIGVjaG9kYXRlICJDYW4ndCBmaW5kIGt1YmVsZXQgc2VydmljZSBleHRyYXMgZGlyZWN0b3J5IgogICAgICBleGl0IDEKICAgIGVsc2UKICAgICAgZWNobyAtZSAiW1NlcnZpY2VdXG5FbnZpcm9ubWVudD1cIktVQkVMRVRfTk9ERV9JUD0ke0RFRkFVTFRfSUZDX0lQfVwiXG5FbnZpcm9ubWVudD1cIktVQkVMRVRfSE9TVE5BTUU9JHtGVUxMX0hPU1ROQU1FfVwiIiA+IC9ldGMvc3lzdGVtZC9zeXN0ZW0va3ViZWxldC5zZXJ2aWNlLmQvbm9kZWlwLmNvbmYKICAgIGZpCiAgICAKCi0gcGF0aDogJy9ldGMva3ViZXJuZXRlcy9wa2kvY2EuY3J0JwogIGNvbnRlbnQ6IHwtCiAgICAtLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KICAgIE1JSUVXakNDQTBLZ0F3SUJBZ0lKQUxmUmxXc0k4WVFITUEwR0NTcUdTSWIzRFFFQkJRVUFNSHN4Q3pBSkJnTlYKICAgIEJBWVRBbFZUTVFzd0NRWURWUVFJRXdKRFFURVdNQlFHQTFVRUJ4TU5VMkZ1SUVaeVlXNWphWE5qYnpFVU1CSUcKICAgIEExVUVDaE1MUW5KaFpHWnBkSHBwYm1NeEVqQVFCZ05WQkFNVENXeHZZMkZzYUc5emRERWRNQnNHQ1NxR1NJYjMKICAgIERRRUpBUllPWW5KaFpFQmtZVzVuWVM1amIyMHdIaGNOTVRRd056RTFNakEwTmpBMVdoY05NVGN3TlRBME1qQTAKICAgIE5qQTFXakI3TVFzd0NRWURWUVFHRXdKVlV6RUxNQWtHQTFVRUNCTUNRMEV4RmpBVUJnTlZCQWNURFZOaGJpQkcKICAgIGNtRnVZMmx6WTI4eEZEQVNCZ05WQkFvVEMwSnlZV1JtYVhSNmFXNWpNUkl3RUFZRFZRUURFd2xzYjJOaGJHaHYKICAgIGMzUXhIVEFiQmdrcWhraUc5dzBCQ1FFV0RtSnlZV1JBWkdGdVoyRXVZMjl0TUlJQklqQU5CZ2txaGtpRzl3MEIKICAgIEFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXQ1ZkFqcDRmVGNla1dVVGZ6c3Awa3lpaDFPWWJzR0wwS1gxZVJiU1MKICAgIFI4T2QwKzlRNjJIeW55K0dGd01UYjRBL0tVOG1zc29IdmNjZVNBQWJ3ZmJ4RksvK3M1MVRvYnFVbk9SWnJPb1QKICAgIFpqa1V5Z2J5WERTSzk5WUJiY1IxUGlwOHZ3TVRtNFhLdUx0Q2lnZUJCZGpqQVFkZ1VPMjhMRU5HbHNNbm1lWWsKICAgIEpmT0RWR25WbXI1THRiOUFOQThJS3lUZnNuSEo0aU9DUy9QbFBiVWoycTdZbm9WTHBvc1VCTWxnVWIvQ3lrWDMKICAgIG1Pb0xiNHlKSlF5QS9pU1Q2WnhpSUVqMzZENHlXWjVsZzdZSmwrVWlpQlFIR0NuUGRHeWlwcVYwNmV4MGhlWVcKICAgIGNhaVc4TFdaU1VROTNqUStXVkNIOGhUN0RRTzFkbXN2VW1YbHEvSmVBbHdRL1FJREFRQUJvNEhnTUlIZE1CMEcKICAgIEExVWREZ1FXQkJSY0FST3RoUzRQNFU3dlRmakJ5QzU2OVI3RTZEQ0JyUVlEVlIwakJJR2xNSUdpZ0JSY0FST3QKICAgIGhTNFA0VTd2VGZqQnlDNTY5UjdFNktGL3BIMHdlekVMTUFrR0ExVUVCaE1DVlZNeEN6QUpCZ05WQkFnVEFrTkIKICAgIE1SWXdGQVlEVlFRSEV3MVRZVzRnUm5KaGJtTnBjMk52TVJRd0VnWURWUVFLRXd0Q2NtRmtabWwwZW1sdVl6RVMKICAgIE1CQUdBMVVFQXhNSmJHOWpZV3hvYjNOME1SMHdHd1lKS29aSWh2Y05BUWtCRmc1aWNtRmtRR1JoYm1kaExtTnYKICAgIGJZSUpBTGZSbFdzSThZUUhNQXdHQTFVZEV3UUZNQU1CQWY4d0RRWUpLb1pJaHZjTkFRRUZCUUFEZ2dFQkFHNmgKICAgIFU5ZjlzTkgwLzZvQmJHR3kyRVZVMFVnSVRVUUlyRldvOXJGa3JXNWsvWGtEalFtKzNsempUMGlHUjRJeEUvQW8KICAgIGVVNnNRaHVhN3dyV2VGRW40N0dMOThsbkNzSmREN29aTmhGbVE5NVRiL0xuRFVqczVZajliclAwTld6WGZZVTQKICAgIFVLMlpuSU5KUmNKcEI4aVJDYUN4RThEZGNVRjBYcUlFcTZwQTI3MnNub0xtaVhMTXZObDNrWUVkbStqZTZ2b0QKICAgIDU4U05WRVVzenR6UXlYbUpFaENwd1ZJMEE2UUNqelhqK3F2cG13M1paSGk4SndYZWk4WlpCTFRTRkJraThaN24KICAgIHNIOUJCSDM4L1N6VW1BTjRRSFNQeTFnanFtMDBPQUU4TmFZRGtoL2J6RTRkN21MR0dNV3AvV0UzS1BTdTgySEYKICAgIGtQZTZYb1NiaUxtL2t4azMyVDA9CiAgICAtLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCiAgICAKCi0gcGF0aDogJy9ldGMvc3lzdGVtZC9zeXN0ZW0vc2V0dXAuc2VydmljZScKICBwZXJtaXNzaW9uczogJzA2NDQnCiAgY29udGVudDogfC0KICAgIFtJbnN0YWxsXQogICAgV2FudGVkQnk9bXVsdGktdXNlci50YXJnZXQKICAgIAogICAgW1VuaXRdCiAgICBSZXF1aXJlcz1uZXR3b3JrLW9ubGluZS50YXJnZXQKICAgIEFmdGVyPW5ldHdvcmstb25saW5lLnRhcmdldAogICAgCiAgICBbU2VydmljZV0KICAgIFR5cGU9b25lc2hvdAogICAgUmVtYWluQWZ0ZXJFeGl0PXRydWUKICAgIEVudmlyb25tZW50RmlsZT0tL2V0Yy9lbnZpcm9ubWVudAogICAgRXhlY1N0YXJ0PS9vcHQvYmluL3N1cGVydmlzZS5zaCAvb3B0L2Jpbi9zZXR1cAogICAgCgotIHBhdGg6ICcvZXRjL3Byb2ZpbGUuZC9vcHQtYmluLXBhdGguc2gnCiAgcGVybWlzc2lvbnM6ICcwNjQ0JwogIGNvbnRlbnQ6IHwtCiAgICBleHBvcnQgUEFUSD0iL29wdC9iaW46JFBBVEgiCiAgICAKCi0gcGF0aDogJy9ldGMva3ViZXJuZXRlcy9rdWJlbGV0LmNvbmYnCiAgY29udGVudDogfC0KICAgIGFwaVZlcnNpb246IGt1YmVsZXQuY29uZmlnLms4cy5pby92MWJldGExCiAgICBraW5kOiBLdWJlbGV0Q29uZmlndXJhdGlvbgogICAgYXV0aGVudGljYXRpb246CiAgICAgIGFub255bW91czoKICAgICAgICBlbmFibGVkOiBmYWxzZQogICAgICB3ZWJob29rOgogICAgICAgIGVuYWJsZWQ6IHRydWUKICAgICAgeDUwOToKICAgICAgICBjbGllbnRDQUZpbGU6IC9ldGMva3ViZXJuZXRlcy9wa2kvY2EuY3J0CiAgICBhdXRob3JpemF0aW9uOgogICAgICBtb2RlOiBXZWJob29rCiAgICBjZ3JvdXBEcml2ZXI6IHN5c3RlbWQKICAgIGNsdXN0ZXJETlM6CiAgICAtICIxMC4wLjAuMCIKICAgIGNsdXN0ZXJEb21haW46IGNsdXN0ZXIubG9jYWwKICAgIGZlYXR1cmVHYXRlczoKICAgICAgR3JhY2VmdWxOb2RlU2h1dGRvd246IHRydWUKICAgICAgSWRlbnRpZnlQb2RPUzogZmFsc2UKICAgIHByb3RlY3RLZXJuZWxEZWZhdWx0czogdHJ1ZQogICAgcmVhZE9ubHlQb3J0OiAwCiAgICByb3RhdGVDZXJ0aWZpY2F0ZXM6IHRydWUKICAgIHNlcnZlclRMU0Jvb3RzdHJhcDogdHJ1ZQogICAgc3RhdGljUG9kUGF0aDogL2V0Yy9rdWJlcm5ldGVzL21hbmlmZXN0cwogICAga3ViZVJlc2VydmVkOgogICAgICBjcHU6IDMwbQogICAgICBlcGhlbWVyYWwtc3RvcmFnZTogMzBHaQogICAgc3lzdGVtUmVzZXJ2ZWQ6CiAgICAgIGNwdTogMzBtCiAgICAgIGVwaGVtZXJhbC1zdG9yYWdlOiAzMEdpCiAgICBldmljdGlvbkhhcmQ6CiAgICAgIG1lbW9yeS5hdmFpbGFibGU6IDMwTWkKICAgIHRsc0NpcGhlclN1aXRlczoKICAgIC0gVExTX0FFU18xMjhfR0NNX1NIQTI1NgogICAgLSBUTFNfQUVTXzI1Nl9HQ01fU0hBMzg0CiAgICAtIFRMU19DSEFDSEEyMF9QT0xZMTMwNV9TSEEyNTYKICAgIC0gVExTX0VDREhFX0VDRFNBX1dJVEhfQUVTXzEyOF9HQ01fU0hBMjU2CiAgICAtIFRMU19FQ0RIRV9FQ0RTQV9XSVRIX0FFU18yNTZfR0NNX1NIQTM4NAogICAgLSBUTFNfRUNESEVfRUNEU0FfV0lUSF9DSEFDSEEyMF9QT0xZMTMwNQogICAgLSBUTFNfRUNESEVfUlNBX1dJVEhfQUVTXzEyOF9HQ01fU0hBMjU2CiAgICAtIFRMU19FQ0RIRV9SU0FfV0lUSF9BRVNfMjU2X0dDTV9TSEEzODQKICAgIC0gVExTX0VDREhFX1JTQV9XSVRIX0NIQUNIQTIwX1BPTFkxMzA1CiAgICB2b2x1bWVQbHVnaW5EaXI6IC92YXIvbGliL2t1YmVsZXQvdm9sdW1lcGx1Z2lucwogICAgCgotIHBhdGg6ICcvZXRjL3N5c3RlbWQvc3lzdGVtL2t1YmVsZXQtaGVhbHRoY2hlY2suc2VydmljZScKICBwZXJtaXNzaW9uczogJzA2NDQnCiAgY29udGVudDogfC0KICAgIFtVbml0XQogICAgUmVxdWlyZXM9a3ViZWxldC5zZXJ2aWNlCiAgICBBZnRlcj1rdWJlbGV0LnNlcnZpY2UKICAgIAogICAgW1NlcnZpY2VdCiAgICBFeGVjU3RhcnQ9L29wdC9iaW4vaGVhbHRoLW1vbml0b3Iuc2gga3ViZWxldAogICAgCiAgICBbSW5zdGFsbF0KICAgIFdhbnRlZEJ5PW11bHRpLXVzZXIudGFyZ2V0CiAgICAKCi0gcGF0aDogJy9ldGMvZG9ja2VyL2RhZW1vbi5qc29uJwogIHBlcm1pc3Npb25zOiAnMDY0NCcKICBjb250ZW50OiB8LQogICAgeyJleGVjLW9wdHMiOlsibmF0aXZlLmNncm91cGRyaXZlcj1zeXN0ZW1kIl0sInN0b3JhZ2UtZHJpdmVyIjoib3ZlcmxheTIiLCJsb2ctZHJpdmVyIjoianNvbi1maWxlIiwibG9nLW9wdHMiOnsibWF4LWZpbGUiOiIzMCIsIm1heC1zaXplIjoiMzAwbSJ9LCJpbnNlY3VyZS1yZWdpc3RyaWVzIjpbIjE5Mi4xNjguMTAwLjEwMDo1MDAwIiwiMTAuMC4wLjE6NTAwMCJdLCJyZWdpc3RyeS1taXJyb3JzIjpbImh0dHBzOi8vcmVnaXN0cnkuZG9ja2VyLWNuLmNvbSJdfQoKYm9vdGNtZDoKLSBlY2hvIGhlbGxvCi0gZWNobyB3b3JsZAoKcmhfc3Vic2NyaXB0aW9uOgogICAgcGFzc3dvcmQ6IHBhc3N3b3JkCiAgICB1c2VybmFtZTogdXNlcm5hbWU= +immutable: true +kind: Secret +metadata: + creationTimestamp: null + name: kubelet-configuration-kube-system-osc-provisioning + namespace: cloud-init-settings + resourceVersion: "1" +type: Opaque diff --git a/pkg/controllers/osc/testdata/secret-rhel-8.x-containerd.yaml b/pkg/controllers/osc/testdata/secret-rhel-8.x-containerd.yaml index dda94544..702cb7f8 100644 --- a/pkg/controllers/osc/testdata/secret-rhel-8.x-containerd.yaml +++ b/pkg/controllers/osc/testdata/secret-rhel-8.x-containerd.yaml @@ -1,10 +1,11 @@ apiVersion: v1 data: - cloud-config: I2Nsb3VkLWNvbmZpZwoKc3NoX3B3YXV0aDogbm8Kc3NoX2F1dGhvcml6ZWRfa2V5czoKLSAnc3NoLXJzYSBBQUFBQjNOemFDMXljMkVBQUFBREFRQUJBQUFDQVFEZE9JaFltekNLNURTVkx1M2MnCndyaXRlX2ZpbGVzOgotIHBhdGg6ICcvZXRjL3N5c3RlbWQvam91cm5hbGQuY29uZi5kL21heF9kaXNrX3VzZS5jb25mJwogIGNvbnRlbnQ6IHwtCiAgICBbSm91cm5hbF0KICAgIFN5c3RlbU1heFVzZT01RwogICAgCgotIHBhdGg6ICcvb3B0L2xvYWQta2VybmVsLW1vZHVsZXMuc2gnCiAgcGVybWlzc2lvbnM6ICcwNzU1JwogIGNvbnRlbnQ6IHwtCiAgICAjIS91c3IvYmluL2VudiBiYXNoCiAgICBzZXQgLWV1byBwaXBlZmFpbAogICAgCiAgICBtb2Rwcm9iZSBpcF92cwogICAgbW9kcHJvYmUgaXBfdnNfcnIKICAgIG1vZHByb2JlIGlwX3ZzX3dycgogICAgbW9kcHJvYmUgaXBfdnNfc2gKICAgIAogICAgaWYgbW9kaW5mbyBuZl9jb25udHJhY2tfaXB2NCAmPiAvZGV2L251bGw7IHRoZW4KICAgICAgbW9kcHJvYmUgbmZfY29ubnRyYWNrX2lwdjQKICAgIGVsc2UKICAgICAgbW9kcHJvYmUgbmZfY29ubnRyYWNrCiAgICBmaQogICAgCgotIHBhdGg6ICcvZXRjL3N5c2N0bC5kL2s4cy5jb25mJwogIGNvbnRlbnQ6IHwtCiAgICBuZXQuYnJpZGdlLmJyaWRnZS1uZi1jYWxsLWlwNnRhYmxlcyA9IDEKICAgIG5ldC5icmlkZ2UuYnJpZGdlLW5mLWNhbGwtaXB0YWJsZXMgPSAxCiAgICBrZXJuZWwucGFuaWNfb25fb29wcyA9IDEKICAgIGtlcm5lbC5wYW5pYyA9IDEwCiAgICBuZXQuaXB2NC5pcF9mb3J3YXJkID0gMQogICAgdm0ub3ZlcmNvbW1pdF9tZW1vcnkgPSAxCiAgICBmcy5pbm90aWZ5Lm1heF91c2VyX3dhdGNoZXMgPSAxMDQ4NTc2CiAgICAKCi0gcGF0aDogJy9ldGMvc2VsaW51eC9jb25maWcnCiAgY29udGVudDogfC0KICAgICMgVGhpcyBmaWxlIGNvbnRyb2xzIHRoZSBzdGF0ZSBvZiBTRUxpbnV4IG9uIHRoZSBzeXN0ZW0uCiAgICAjIFNFTElOVVg9IGNhbiB0YWtlIG9uZSBvZiB0aGVzZSB0aHJlZSB2YWx1ZXM6CiAgICAjICAgICBlbmZvcmNpbmcgLSBTRUxpbnV4IHNlY3VyaXR5IHBvbGljeSBpcyBlbmZvcmNlZC4KICAgICMgICAgIHBlcm1pc3NpdmUgLSBTRUxpbnV4IHByaW50cyB3YXJuaW5ncyBpbnN0ZWFkIG9mIGVuZm9yY2luZy4KICAgICMgICAgIGRpc2FibGVkIC0gTm8gU0VMaW51eCBwb2xpY3kgaXMgbG9hZGVkLgogICAgU0VMSU5VWD1wZXJtaXNzaXZlCiAgICAjIFNFTElOVVhUWVBFPSBjYW4gdGFrZSBvbmUgb2YgdGhyZWUgdHdvIHZhbHVlczoKICAgICMgICAgIHRhcmdldGVkIC0gVGFyZ2V0ZWQgcHJvY2Vzc2VzIGFyZSBwcm90ZWN0ZWQsCiAgICAjICAgICBtaW5pbXVtIC0gTW9kaWZpY2F0aW9uIG9mIHRhcmdldGVkIHBvbGljeS4gT25seSBzZWxlY3RlZCBwcm9jZXNzZXMgYXJlIHByb3RlY3RlZC4KICAgICMgICAgIG1scyAtIE11bHRpIExldmVsIFNlY3VyaXR5IHByb3RlY3Rpb24uCiAgICBTRUxJTlVYVFlQRT10YXJnZXRlZAogICAgCgotIHBhdGg6ICcvb3B0L2Jpbi9zZXR1cCcKICBwZXJtaXNzaW9uczogJzA3NTUnCiAgY29udGVudDogfC0KICAgICMhL2Jpbi9iYXNoCiAgICBzZXQgLXhldW8gcGlwZWZhaWwKICAgIAogICAgc2V0ZW5mb3JjZSAwIHx8IHRydWUKICAgIHN5c3RlbWN0bCByZXN0YXJ0IHN5c3RlbWQtbW9kdWxlcy1sb2FkLnNlcnZpY2UKICAgIHN5c2N0bCAtLXN5c3RlbQogICAgc2VkIC1pLm9yaWcgJy8uKnN3YXAuKi9kJyAvZXRjL2ZzdGFiCiAgICBzd2Fwb2ZmIC1hCiAgICAKICAgIAogICAgeXVtIGluc3RhbGwgLXkgXAogICAgICBkZXZpY2UtbWFwcGVyLXBlcnNpc3RlbnQtZGF0YSBcCiAgICAgIGx2bTIgXAogICAgICBlYnRhYmxlcyBcCiAgICAgIGV0aHRvb2wgXAogICAgICBuZnMtdXRpbHMgXAogICAgICBiYXNoLWNvbXBsZXRpb24gXAogICAgICBzdWRvIFwKICAgICAgc29jYXQgXAogICAgICB3Z2V0IFwKICAgICAgY3VybCBcCiAgICAgIGlwdnNhZG0KICAgIHl1bSBpbnN0YWxsIC15IHl1bS11dGlscwogICAgeXVtLWNvbmZpZy1tYW5hZ2VyIC0tYWRkLXJlcG89aHR0cHM6Ly9kb3dubG9hZC5kb2NrZXIuY29tL2xpbnV4L2NlbnRvcy9kb2NrZXItY2UucmVwbwogICAgeXVtLWNvbmZpZy1tYW5hZ2VyIC0tc2F2ZSAtLXNldG9wdD1kb2NrZXItY2Utc3RhYmxlLm1vZHVsZV9ob3RmaXhlcz10cnVlCiAgICAKICAgIGNhdCA8PEVPRiB8IHRlZSAvZXRjL2NyaWN0bC55YW1sCiAgICBydW50aW1lLWVuZHBvaW50OiB1bml4Oi8vL3J1bi9jb250YWluZXJkL2NvbnRhaW5lcmQuc29jawogICAgRU9GCiAgICAKICAgIG1rZGlyIC1wIC9ldGMvc3lzdGVtZC9zeXN0ZW0vY29udGFpbmVyZC5zZXJ2aWNlLmQKICAgIGNhdCA8PEVPRiB8IHRlZSAvZXRjL3N5c3RlbWQvc3lzdGVtL2NvbnRhaW5lcmQuc2VydmljZS5kL2Vudmlyb25tZW50LmNvbmYKICAgIFtTZXJ2aWNlXQogICAgUmVzdGFydD1hbHdheXMKICAgIEVudmlyb25tZW50RmlsZT0tL2V0Yy9lbnZpcm9ubWVudAogICAgRU9GCiAgICAKICAgIHl1bSBpbnN0YWxsIC15IGNvbnRhaW5lcmQuaW8tMS40KiB5dW0tcGx1Z2luLXZlcnNpb25sb2NrCiAgICB5dW0gdmVyc2lvbmxvY2sgYWRkIGNvbnRhaW5lcmQuaW8KICAgIAogICAgc3lzdGVtY3RsIGRhZW1vbi1yZWxvYWQKICAgIHN5c3RlbWN0bCBlbmFibGUgLS1ub3cgY29udGFpbmVyZAogICAgb3B0X2Jpbj0vb3B0L2JpbgogICAgY25pX2Jpbl9kaXI9L29wdC9jbmkvYmluCiAgICBta2RpciAtcCAvZXRjL2NuaS9uZXQuZCAvZXRjL2t1YmVybmV0ZXMvZHluYW1pYy1jb25maWctZGlyIC9ldGMva3ViZXJuZXRlcy9tYW5pZmVzdHMgIiRvcHRfYmluIiAiJGNuaV9iaW5fZGlyIgogICAgYXJjaD0ke0hPU1RfQVJDSC19CiAgICBpZiBbIC16ICIkYXJjaCIgXQogICAgdGhlbgogICAgY2FzZSAkKHVuYW1lIC1tKSBpbgogICAgeDg2XzY0KQogICAgICAgIGFyY2g9ImFtZDY0IgogICAgICAgIDs7CiAgICBhYXJjaDY0KQogICAgICAgIGFyY2g9ImFybTY0IgogICAgICAgIDs7CiAgICAqKQogICAgICAgIGVjaG8gInVuc3VwcG9ydGVkIENQVSBhcmNoaXRlY3R1cmUsIGV4aXRpbmciCiAgICAgICAgZXhpdCAxCiAgICAgICAgOzsKICAgIGVzYWMKICAgIGZpCiAgICBDTklfVkVSU0lPTj0iJHtDTklfVkVSU0lPTjotdjAuOC43fSIKICAgIGNuaV9iYXNlX3VybD0iaHR0cHM6Ly9naXRodWIuY29tL2NvbnRhaW5lcm5ldHdvcmtpbmcvcGx1Z2lucy9yZWxlYXNlcy9kb3dubG9hZC8kQ05JX1ZFUlNJT04iCiAgICBjbmlfZmlsZW5hbWU9ImNuaS1wbHVnaW5zLWxpbnV4LSRhcmNoLSRDTklfVkVSU0lPTi50Z3oiCiAgICBjdXJsIC1MZm8gIiRjbmlfYmluX2Rpci8kY25pX2ZpbGVuYW1lIiAiJGNuaV9iYXNlX3VybC8kY25pX2ZpbGVuYW1lIgogICAgY25pX3N1bT0kKGN1cmwgLUxmICIkY25pX2Jhc2VfdXJsLyRjbmlfZmlsZW5hbWUuc2hhMjU2IikKICAgIGNkICIkY25pX2Jpbl9kaXIiCiAgICBzaGEyNTZzdW0gLWMgPDw8IiRjbmlfc3VtIgogICAgdGFyIHh2ZiAiJGNuaV9maWxlbmFtZSIKICAgIHJtIC1mICIkY25pX2ZpbGVuYW1lIgogICAgY2QgLQogICAgS1VCRV9WRVJTSU9OPSIke0tVQkVfVkVSU0lPTjotdjEuMjIuMX0iCiAgICBrdWJlX2Rpcj0iJG9wdF9iaW4va3ViZXJuZXRlcy0kS1VCRV9WRVJTSU9OIgogICAga3ViZV9iYXNlX3VybD0iaHR0cHM6Ly9zdG9yYWdlLmdvb2dsZWFwaXMuY29tL2t1YmVybmV0ZXMtcmVsZWFzZS9yZWxlYXNlLyRLVUJFX1ZFUlNJT04vYmluL2xpbnV4LyRhcmNoIgogICAga3ViZV9zdW1fZmlsZT0iJGt1YmVfZGlyL3NoYTI1NiIKICAgIG1rZGlyIC1wICIka3ViZV9kaXIiCiAgICA6ID4iJGt1YmVfc3VtX2ZpbGUiCiAgICAKICAgIGZvciBiaW4gaW4ga3ViZWxldCBrdWJlYWRtIGt1YmVjdGw7IGRvCiAgICAgICAgY3VybCAtTGZvICIka3ViZV9kaXIvJGJpbiIgIiRrdWJlX2Jhc2VfdXJsLyRiaW4iCiAgICAgICAgY2htb2QgK3ggIiRrdWJlX2Rpci8kYmluIgogICAgICAgIHN1bT0kKGN1cmwgLUxmICIka3ViZV9iYXNlX3VybC8kYmluLnNoYTI1NiIpCiAgICAgICAgZWNobyAiJHN1bSAgJGt1YmVfZGlyLyRiaW4iID4+IiRrdWJlX3N1bV9maWxlIgogICAgZG9uZQogICAgc2hhMjU2c3VtIC1jICIka3ViZV9zdW1fZmlsZSIKICAgIAogICAgZm9yIGJpbiBpbiBrdWJlbGV0IGt1YmVhZG0ga3ViZWN0bDsgZG8KICAgICAgICBsbiAtc2YgIiRrdWJlX2Rpci8kYmluIiAiJG9wdF9iaW4iLyRiaW4KICAgIGRvbmUKICAgIAogICAgaWYgW1sgISAteCAvb3B0L2Jpbi9oZWFsdGgtbW9uaXRvci5zaCBdXTsgdGhlbgogICAgICAgIGN1cmwgLUxmbyAvb3B0L2Jpbi9oZWFsdGgtbW9uaXRvci5zaCBodHRwczovL3Jhdy5naXRodWJ1c2VyY29udGVudC5jb20va3ViZXJtYXRpYy9tYWNoaW5lLWNvbnRyb2xsZXIvNzk2N2EwYWYyYjc1ZjI5YWQyYWIyMjdlZWFhMjZlYTdiMGYyZmJkZS9wa2cvdXNlcmRhdGEvc2NyaXB0cy9oZWFsdGgtbW9uaXRvci5zaAogICAgICAgIGNobW9kICt4IC9vcHQvYmluL2hlYWx0aC1tb25pdG9yLnNoCiAgICBmaQogICAgCiAgICBta2RpciAtcCAvZXRjL3N5c3RlbWQvc3lzdGVtL2t1YmVsZXQuc2VydmljZS5kLwogICAgIyBzZXQga3ViZWxldCBub2RlaXAgZW52aXJvbm1lbnQgdmFyaWFibGUKICAgIC9vcHQvYmluL3NldHVwX25ldF9lbnYuc2gKICAgIAogICAgc3lzdGVtY3RsIGVuYWJsZSAtLW5vdyBrdWJlbGV0CiAgICBzeXN0ZW1jdGwgZW5hYmxlIC0tbm93IC0tbm8tYmxvY2sga3ViZWxldC1oZWFsdGhjaGVjay5zZXJ2aWNlCiAgICAKCi0gcGF0aDogJy9vcHQvYmluL3N1cGVydmlzZS5zaCcKICBwZXJtaXNzaW9uczogJzA3NTUnCiAgY29udGVudDogfC0KICAgICMhL2Jpbi9iYXNoCiAgICBzZXQgLXhldW8gcGlwZWZhaWwKICAgIHdoaWxlICEgIiRAIjsgZG8KICAgICAgc2xlZXAgMQogICAgZG9uZQogICAgCgotIHBhdGg6ICcvZXRjL3N5c3RlbWQvc3lzdGVtL2t1YmVsZXQuc2VydmljZScKICBjb250ZW50OiB8LQogICAgW1VuaXRdCiAgICBBZnRlcj1jb250YWluZXJkLnNlcnZpY2UKICAgIFJlcXVpcmVzPWNvbnRhaW5lcmQuc2VydmljZQogICAgCiAgICBEZXNjcmlwdGlvbj1rdWJlbGV0OiBUaGUgS3ViZXJuZXRlcyBOb2RlIEFnZW50CiAgICBEb2N1bWVudGF0aW9uPWh0dHBzOi8va3ViZXJuZXRlcy5pby9kb2NzL2hvbWUvCiAgICAKICAgIFtTZXJ2aWNlXQogICAgUmVzdGFydD1hbHdheXMKICAgIFN0YXJ0TGltaXRJbnRlcnZhbD0wCiAgICBSZXN0YXJ0U2VjPTEwCiAgICBDUFVBY2NvdW50aW5nPXRydWUKICAgIE1lbW9yeUFjY291bnRpbmc9dHJ1ZQogICAgCiAgICBFbnZpcm9ubWVudD0iUEFUSD0vb3B0L2JpbjovYmluOi91c3IvbG9jYWwvc2JpbjovdXNyL2xvY2FsL2JpbjovdXNyL3NiaW46L3Vzci9iaW46L3NiaW4vIgogICAgRW52aXJvbm1lbnRGaWxlPS0vZXRjL2Vudmlyb25tZW50CiAgICAKICAgIEV4ZWNTdGFydFByZT0vYmluL2Jhc2ggL29wdC9sb2FkLWtlcm5lbC1tb2R1bGVzLnNoCiAgICBFeGVjU3RhcnRQcmU9L2Jpbi9iYXNoIC9vcHQvYmluL3NldHVwX25ldF9lbnYuc2gKICAgIEV4ZWNTdGFydD0vb3B0L2Jpbi9rdWJlbGV0ICRLVUJFTEVUX0VYVFJBX0FSR1MgXAogICAgICAtLWJvb3RzdHJhcC1rdWJlY29uZmlnPS9ldGMva3ViZXJuZXRlcy9ib290c3RyYXAta3ViZWxldC5jb25mIFwKICAgICAgLS1rdWJlY29uZmlnPS92YXIvbGliL2t1YmVsZXQva3ViZWNvbmZpZyBcCiAgICAgIC0tY29uZmlnPS9ldGMva3ViZXJuZXRlcy9rdWJlbGV0LmNvbmYgXAogICAgICAtLW5ldHdvcmstcGx1Z2luPWNuaSBcCiAgICAgIC0tY2VydC1kaXI9L2V0Yy9rdWJlcm5ldGVzL3BraSBcCiAgICAgIC0tY2xvdWQtcHJvdmlkZXI9YXdzIFwKICAgICAgLS1jbG91ZC1jb25maWc9L2V0Yy9rdWJlcm5ldGVzL2Nsb3VkLWNvbmZpZyBcCiAgICAgIC0tZHluYW1pYy1jb25maWctZGlyPS9ldGMva3ViZXJuZXRlcy9keW5hbWljLWNvbmZpZy1kaXIgXAogICAgICAtLWZlYXR1cmUtZ2F0ZXM9RHluYW1pY0t1YmVsZXRDb25maWc9dHJ1ZSBcCiAgICAgIC0tZXhpdC1vbi1sb2NrLWNvbnRlbnRpb24gXAogICAgICAtLWxvY2stZmlsZT0vdG1wL2t1YmVsZXQubG9jayBcCiAgICAgIC0tY29udGFpbmVyLXJ1bnRpbWU9cmVtb3RlIFwKICAgICAgLS1jb250YWluZXItcnVudGltZS1lbmRwb2ludD11bml4Oi8vL3J1bi9jb250YWluZXJkL2NvbnRhaW5lcmQuc29jayBcCiAgICAgIC0tbm9kZS1pcCAke0tVQkVMRVRfTk9ERV9JUH0KICAgIAogICAgW0luc3RhbGxdCiAgICBXYW50ZWRCeT1tdWx0aS11c2VyLnRhcmdldAogICAgCgotIHBhdGg6ICcvZXRjL2t1YmVybmV0ZXMvY2xvdWQtY29uZmlnJwogIHBlcm1pc3Npb25zOiAnMDYwMCcKICBjb250ZW50OiB8LQogICAgW2dsb2JhbF0KICAgIFpvbmU9IiIKICAgIFZQQz0iIgogICAgU3VibmV0SUQ9InRlc3Qtc3VibmV0IgogICAgCiAgICAKCi0gcGF0aDogJy9vcHQvYmluL3NldHVwX25ldF9lbnYuc2gnCiAgcGVybWlzc2lvbnM6ICcwNzU1JwogIGNvbnRlbnQ6IHwtCiAgICAjIS91c3IvYmluL2VudiBiYXNoCiAgICBlY2hvZGF0ZSgpIHsKICAgICAgZWNobyAiWyQoZGF0ZSAtSXMpXSIgIiRAIgogICAgfQogICAgCiAgICAjIGdldCB0aGUgZGVmYXVsdCBpbnRlcmZhY2UgSVAgYWRkcmVzcwogICAgREVGQVVMVF9JRkNfSVA9JChpcCAtbyAgcm91dGUgZ2V0IDEgfCBncmVwIC1vUCAic3JjIFxLXFMrIikKICAgIAogICAgaWYgWyAteiAiJHtERUZBVUxUX0lGQ19JUH0iIF0KICAgIHRoZW4KICAgICAgZWNob2RhdGUgIkZhaWxlZCB0byBnZXQgSVAgYWRkcmVzcyBmb3IgdGhlIGRlZmF1bHQgcm91dGUgaW50ZXJmYWNlIgogICAgICBleGl0IDEKICAgIGZpCiAgICAKICAgICAjIGdldCB0aGUgZnVsbCBob3N0bmFtZQogICAgRlVMTF9IT1NUTkFNRT0kKGhvc3RuYW1lIC1mKQogICAgCiAgICAjIHdyaXRlIHRoZSBub2RlaXBfZW52IGZpbGUKICAgICMgd2UgbmVlZCB0aGUgbGluZSBiZWxvdyBiZWNhdXNlIGZsYXRjYXIgaGFzIHRoZSBzYW1lIHN0cmluZyAiY29yZW9zIiBpbiB0aGF0IGZpbGUKICAgIGlmIGdyZXAgLXEgY29yZW9zIC9ldGMvb3MtcmVsZWFzZQogICAgdGhlbgogICAgICBlY2hvICJLVUJFTEVUX05PREVfSVA9JHtERUZBVUxUX0lGQ19JUH1cbktVQkVMRVRfSE9TVE5BTUU9JHtGVUxMX0hPU1ROQU1FfSIgPiAvZXRjL2t1YmVybmV0ZXMvbm9kZWlwLmNvbmYKICAgIGVsaWYgWyAhIC1kIC9ldGMvc3lzdGVtZC9zeXN0ZW0va3ViZWxldC5zZXJ2aWNlLmQgXQogICAgdGhlbgogICAgICBlY2hvZGF0ZSAiQ2FuJ3QgZmluZCBrdWJlbGV0IHNlcnZpY2UgZXh0cmFzIGRpcmVjdG9yeSIKICAgICAgZXhpdCAxCiAgICBlbHNlCiAgICAgIGVjaG8gLWUgIltTZXJ2aWNlXVxuRW52aXJvbm1lbnQ9XCJLVUJFTEVUX05PREVfSVA9JHtERUZBVUxUX0lGQ19JUH1cIlxuRW52aXJvbm1lbnQ9XCJLVUJFTEVUX0hPU1ROQU1FPSR7RlVMTF9IT1NUTkFNRX1cIiIgPiAvZXRjL3N5c3RlbWQvc3lzdGVtL2t1YmVsZXQuc2VydmljZS5kL25vZGVpcC5jb25mCiAgICBmaQogICAgCgotIHBhdGg6ICcvZXRjL2t1YmVybmV0ZXMvcGtpL2NhLmNydCcKICBjb250ZW50OiB8LQogICAgLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCiAgICBNSUlFV2pDQ0EwS2dBd0lCQWdJSkFMZlJsV3NJOFlRSE1BMEdDU3FHU0liM0RRRUJCUVVBTUhzeEN6QUpCZ05WCiAgICBCQVlUQWxWVE1Rc3dDUVlEVlFRSUV3SkRRVEVXTUJRR0ExVUVCeE1OVTJGdUlFWnlZVzVqYVhOamJ6RVVNQklHCiAgICBBMVVFQ2hNTFFuSmhaR1pwZEhwcGJtTXhFakFRQmdOVkJBTVRDV3h2WTJGc2FHOXpkREVkTUJzR0NTcUdTSWIzCiAgICBEUUVKQVJZT1luSmhaRUJrWVc1bllTNWpiMjB3SGhjTk1UUXdOekUxTWpBME5qQTFXaGNOTVRjd05UQTBNakEwCiAgICBOakExV2pCN01Rc3dDUVlEVlFRR0V3SlZVekVMTUFrR0ExVUVDQk1DUTBFeEZqQVVCZ05WQkFjVERWTmhiaUJHCiAgICBjbUZ1WTJselkyOHhGREFTQmdOVkJBb1RDMEp5WVdSbWFYUjZhVzVqTVJJd0VBWURWUVFERXdsc2IyTmhiR2h2CiAgICBjM1F4SFRBYkJna3Foa2lHOXcwQkNRRVdEbUp5WVdSQVpHRnVaMkV1WTI5dE1JSUJJakFOQmdrcWhraUc5dzBCCiAgICBBUUVGQUFPQ0FROEFNSUlCQ2dLQ0FRRUF0NWZBanA0ZlRjZWtXVVRmenNwMGt5aWgxT1lic0dMMEtYMWVSYlNTCiAgICBSOE9kMCs5UTYySHlueStHRndNVGI0QS9LVThtc3NvSHZjY2VTQUFid2ZieEZLLytzNTFUb2JxVW5PUlpyT29UCiAgICBaamtVeWdieVhEU0s5OVlCYmNSMVBpcDh2d01UbTRYS3VMdENpZ2VCQmRqakFRZGdVTzI4TEVOR2xzTW5tZVlrCiAgICBKZk9EVkduVm1yNUx0YjlBTkE4SUt5VGZzbkhKNGlPQ1MvUGxQYlVqMnE3WW5vVkxwb3NVQk1sZ1ViL0N5a1gzCiAgICBtT29MYjR5SkpReUEvaVNUNlp4aUlFajM2RDR5V1o1bGc3WUpsK1VpaUJRSEdDblBkR3lpcHFWMDZleDBoZVlXCiAgICBjYWlXOExXWlNVUTkzalErV1ZDSDhoVDdEUU8xZG1zdlVtWGxxL0plQWx3US9RSURBUUFCbzRIZ01JSGRNQjBHCiAgICBBMVVkRGdRV0JCUmNBUk90aFM0UDRVN3ZUZmpCeUM1NjlSN0U2RENCclFZRFZSMGpCSUdsTUlHaWdCUmNBUk90CiAgICBoUzRQNFU3dlRmakJ5QzU2OVI3RTZLRi9wSDB3ZXpFTE1Ba0dBMVVFQmhNQ1ZWTXhDekFKQmdOVkJBZ1RBa05CCiAgICBNUll3RkFZRFZRUUhFdzFUWVc0Z1JuSmhibU5wYzJOdk1SUXdFZ1lEVlFRS0V3dENjbUZrWm1sMGVtbHVZekVTCiAgICBNQkFHQTFVRUF4TUpiRzlqWVd4b2IzTjBNUjB3R3dZSktvWklodmNOQVFrQkZnNWljbUZrUUdSaGJtZGhMbU52CiAgICBiWUlKQUxmUmxXc0k4WVFITUF3R0ExVWRFd1FGTUFNQkFmOHdEUVlKS29aSWh2Y05BUUVGQlFBRGdnRUJBRzZoCiAgICBVOWY5c05IMC82b0JiR0d5MkVWVTBVZ0lUVVFJckZXbzlyRmtyVzVrL1hrRGpRbSszbHpqVDBpR1I0SXhFL0FvCiAgICBlVTZzUWh1YTd3cldlRkVuNDdHTDk4bG5Dc0pkRDdvWk5oRm1ROTVUYi9MbkRVanM1WWo5YnJQME5XelhmWVU0CiAgICBVSzJabklOSlJjSnBCOGlSQ2FDeEU4RGRjVUYwWHFJRXE2cEEyNzJzbm9MbWlYTE12Tmwza1lFZG0ramU2dm9ECiAgICA1OFNOVkVVc3p0elF5WG1KRWhDcHdWSTBBNlFDanpYaitxdnBtdzNaWkhpOEp3WGVpOFpaQkxUU0ZCa2k4WjduCiAgICBzSDlCQkgzOC9TelVtQU40UUhTUHkxZ2pxbTAwT0FFOE5hWURraC9iekU0ZDdtTEdHTVdwL1dFM0tQU3U4MkhGCiAgICBrUGU2WG9TYmlMbS9reGszMlQwPQogICAgLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQogICAgCgotIHBhdGg6ICcvZXRjL3N5c3RlbWQvc3lzdGVtL3NldHVwLnNlcnZpY2UnCiAgcGVybWlzc2lvbnM6ICcwNjQ0JwogIGNvbnRlbnQ6IHwtCiAgICBbSW5zdGFsbF0KICAgIFdhbnRlZEJ5PW11bHRpLXVzZXIudGFyZ2V0CiAgICAKICAgIFtVbml0XQogICAgUmVxdWlyZXM9bmV0d29yay1vbmxpbmUudGFyZ2V0CiAgICBBZnRlcj1uZXR3b3JrLW9ubGluZS50YXJnZXQKICAgIAogICAgW1NlcnZpY2VdCiAgICBUeXBlPW9uZXNob3QKICAgIFJlbWFpbkFmdGVyRXhpdD10cnVlCiAgICBFbnZpcm9ubWVudEZpbGU9LS9ldGMvZW52aXJvbm1lbnQKICAgIEV4ZWNTdGFydD0vb3B0L2Jpbi9zdXBlcnZpc2Uuc2ggL29wdC9iaW4vc2V0dXAKICAgIAoKLSBwYXRoOiAnL2V0Yy9wcm9maWxlLmQvb3B0LWJpbi1wYXRoLnNoJwogIHBlcm1pc3Npb25zOiAnMDY0NCcKICBjb250ZW50OiB8LQogICAgZXhwb3J0IFBBVEg9Ii9vcHQvYmluOiRQQVRIIgogICAgCgotIHBhdGg6ICcvZXRjL2t1YmVybmV0ZXMva3ViZWxldC5jb25mJwogIGNvbnRlbnQ6IHwtCiAgICBhcGlWZXJzaW9uOiBrdWJlbGV0LmNvbmZpZy5rOHMuaW8vdjFiZXRhMQogICAga2luZDogS3ViZWxldENvbmZpZ3VyYXRpb24KICAgIGF1dGhlbnRpY2F0aW9uOgogICAgICBhbm9ueW1vdXM6CiAgICAgICAgZW5hYmxlZDogZmFsc2UKICAgICAgd2ViaG9vazoKICAgICAgICBlbmFibGVkOiB0cnVlCiAgICAgIHg1MDk6CiAgICAgICAgY2xpZW50Q0FGaWxlOiAvZXRjL2t1YmVybmV0ZXMvcGtpL2NhLmNydAogICAgYXV0aG9yaXphdGlvbjoKICAgICAgbW9kZTogV2ViaG9vawogICAgY2dyb3VwRHJpdmVyOiBzeXN0ZW1kCiAgICBjbHVzdGVyRE5TOgogICAgLSAiMTAuMC4wLjAiCiAgICBjbHVzdGVyRG9tYWluOiBjbHVzdGVyLmxvY2FsCiAgICBmZWF0dXJlR2F0ZXM6CiAgICAgIEdyYWNlZnVsTm9kZVNodXRkb3duOiB0cnVlCiAgICAgIElkZW50aWZ5UG9kT1M6IGZhbHNlCiAgICBwcm90ZWN0S2VybmVsRGVmYXVsdHM6IHRydWUKICAgIHJlYWRPbmx5UG9ydDogMAogICAgcm90YXRlQ2VydGlmaWNhdGVzOiB0cnVlCiAgICBzZXJ2ZXJUTFNCb290c3RyYXA6IHRydWUKICAgIHN0YXRpY1BvZFBhdGg6IC9ldGMva3ViZXJuZXRlcy9tYW5pZmVzdHMKICAgIGt1YmVSZXNlcnZlZDoKICAgICAgY3B1OiAyMDBtCiAgICAgIGVwaGVtZXJhbC1zdG9yYWdlOiAxR2kKICAgICAgbWVtb3J5OiAyMDBNaQogICAgc3lzdGVtUmVzZXJ2ZWQ6CiAgICAgIGNwdTogMjAwbQogICAgICBlcGhlbWVyYWwtc3RvcmFnZTogMUdpCiAgICAgIG1lbW9yeTogMjAwTWkKICAgIGV2aWN0aW9uSGFyZDoKICAgICAgaW1hZ2Vmcy5hdmFpbGFibGU6IDE1JQogICAgICBtZW1vcnkuYXZhaWxhYmxlOiAxMDBNaQogICAgICBub2RlZnMuYXZhaWxhYmxlOiAxMCUKICAgICAgbm9kZWZzLmlub2Rlc0ZyZWU6IDUlCiAgICB0bHNDaXBoZXJTdWl0ZXM6CiAgICAtIFRMU19BRVNfMTI4X0dDTV9TSEEyNTYKICAgIC0gVExTX0FFU18yNTZfR0NNX1NIQTM4NAogICAgLSBUTFNfQ0hBQ0hBMjBfUE9MWTEzMDVfU0hBMjU2CiAgICAtIFRMU19FQ0RIRV9FQ0RTQV9XSVRIX0FFU18xMjhfR0NNX1NIQTI1NgogICAgLSBUTFNfRUNESEVfRUNEU0FfV0lUSF9BRVNfMjU2X0dDTV9TSEEzODQKICAgIC0gVExTX0VDREhFX0VDRFNBX1dJVEhfQ0hBQ0hBMjBfUE9MWTEzMDUKICAgIC0gVExTX0VDREhFX1JTQV9XSVRIX0FFU18xMjhfR0NNX1NIQTI1NgogICAgLSBUTFNfRUNESEVfUlNBX1dJVEhfQUVTXzI1Nl9HQ01fU0hBMzg0CiAgICAtIFRMU19FQ0RIRV9SU0FfV0lUSF9DSEFDSEEyMF9QT0xZMTMwNQogICAgdm9sdW1lUGx1Z2luRGlyOiAvdmFyL2xpYi9rdWJlbGV0L3ZvbHVtZXBsdWdpbnMKICAgIAoKLSBwYXRoOiAnL2V0Yy9zeXN0ZW1kL3N5c3RlbS9rdWJlbGV0LWhlYWx0aGNoZWNrLnNlcnZpY2UnCiAgcGVybWlzc2lvbnM6ICcwNjQ0JwogIGNvbnRlbnQ6IHwtCiAgICBbVW5pdF0KICAgIFJlcXVpcmVzPWt1YmVsZXQuc2VydmljZQogICAgQWZ0ZXI9a3ViZWxldC5zZXJ2aWNlCiAgICAKICAgIFtTZXJ2aWNlXQogICAgRXhlY1N0YXJ0PS9vcHQvYmluL2hlYWx0aC1tb25pdG9yLnNoIGt1YmVsZXQKICAgIAogICAgW0luc3RhbGxdCiAgICBXYW50ZWRCeT1tdWx0aS11c2VyLnRhcmdldAogICAgCgotIHBhdGg6ICcvZXRjL2NvbnRhaW5lcmQvY29uZmlnLnRvbWwnCiAgcGVybWlzc2lvbnM6ICcwNjQ0JwogIGNvbnRlbnQ6IHwtCiAgICB2ZXJzaW9uID0gMgogICAgCiAgICBbbWV0cmljc10KICAgIGFkZHJlc3MgPSAiMTI3LjAuMC4xOjEzMzgiCiAgICAKICAgIFtwbHVnaW5zXQogICAgW3BsdWdpbnMuImlvLmNvbnRhaW5lcmQuZ3JwYy52MS5jcmkiXQogICAgW3BsdWdpbnMuImlvLmNvbnRhaW5lcmQuZ3JwYy52MS5jcmkiLmNvbnRhaW5lcmRdCiAgICBbcGx1Z2lucy4iaW8uY29udGFpbmVyZC5ncnBjLnYxLmNyaSIuY29udGFpbmVyZC5ydW50aW1lc10KICAgIFtwbHVnaW5zLiJpby5jb250YWluZXJkLmdycGMudjEuY3JpIi5jb250YWluZXJkLnJ1bnRpbWVzLnJ1bmNdCiAgICBydW50aW1lX3R5cGUgPSAiaW8uY29udGFpbmVyZC5ydW5jLnYyIgogICAgW3BsdWdpbnMuImlvLmNvbnRhaW5lcmQuZ3JwYy52MS5jcmkiLmNvbnRhaW5lcmQucnVudGltZXMucnVuYy5vcHRpb25zXQogICAgU3lzdGVtZENncm91cCA9IHRydWUKICAgIFtwbHVnaW5zLiJpby5jb250YWluZXJkLmdycGMudjEuY3JpIi5yZWdpc3RyeV0KICAgIFtwbHVnaW5zLiJpby5jb250YWluZXJkLmdycGMudjEuY3JpIi5yZWdpc3RyeS5taXJyb3JzXQogICAgW3BsdWdpbnMuImlvLmNvbnRhaW5lcmQuZ3JwYy52MS5jcmkiLnJlZ2lzdHJ5Lm1pcnJvcnMuImRvY2tlci5pbyJdCiAgICBlbmRwb2ludCA9IFsiaHR0cHM6Ly9yZWdpc3RyeS0xLmRvY2tlci5pbyJdCiAgICAKCmJvb3RjbWQ6Ci0gbW9kcHJvYmUgaXBfdGFibGVzCg== + cloud-config: I2Nsb3VkLWNvbmZpZwoKc3NoX3B3YXV0aDogbm8Kc3NoX2F1dGhvcml6ZWRfa2V5czoKLSAnc3NoLXJzYSBBQUFBQjNOemFDMXljMkVBQUFBREFRQUJBQUFDQVFEZE9JaFltekNLNURTVkx1M2MnCndyaXRlX2ZpbGVzOgotIHBhdGg6ICcvZXRjL3N5c3RlbWQvam91cm5hbGQuY29uZi5kL21heF9kaXNrX3VzZS5jb25mJwogIGNvbnRlbnQ6IHwtCiAgICBbSm91cm5hbF0KICAgIFN5c3RlbU1heFVzZT01RwogICAgCgotIHBhdGg6ICcvb3B0L2xvYWQta2VybmVsLW1vZHVsZXMuc2gnCiAgcGVybWlzc2lvbnM6ICcwNzU1JwogIGNvbnRlbnQ6IHwtCiAgICAjIS91c3IvYmluL2VudiBiYXNoCiAgICBzZXQgLWV1byBwaXBlZmFpbAogICAgCiAgICBtb2Rwcm9iZSBpcF92cwogICAgbW9kcHJvYmUgaXBfdnNfcnIKICAgIG1vZHByb2JlIGlwX3ZzX3dycgogICAgbW9kcHJvYmUgaXBfdnNfc2gKICAgIAogICAgaWYgbW9kaW5mbyBuZl9jb25udHJhY2tfaXB2NCAmPiAvZGV2L251bGw7IHRoZW4KICAgICAgbW9kcHJvYmUgbmZfY29ubnRyYWNrX2lwdjQKICAgIGVsc2UKICAgICAgbW9kcHJvYmUgbmZfY29ubnRyYWNrCiAgICBmaQogICAgCgotIHBhdGg6ICcvZXRjL3N5c2N0bC5kL2s4cy5jb25mJwogIGNvbnRlbnQ6IHwtCiAgICBuZXQuYnJpZGdlLmJyaWRnZS1uZi1jYWxsLWlwNnRhYmxlcyA9IDEKICAgIG5ldC5icmlkZ2UuYnJpZGdlLW5mLWNhbGwtaXB0YWJsZXMgPSAxCiAgICBrZXJuZWwucGFuaWNfb25fb29wcyA9IDEKICAgIGtlcm5lbC5wYW5pYyA9IDEwCiAgICBuZXQuaXB2NC5pcF9mb3J3YXJkID0gMQogICAgdm0ub3ZlcmNvbW1pdF9tZW1vcnkgPSAxCiAgICBmcy5pbm90aWZ5Lm1heF91c2VyX3dhdGNoZXMgPSAxMDQ4NTc2CiAgICAKCi0gcGF0aDogJy9ldGMvc2VsaW51eC9jb25maWcnCiAgY29udGVudDogfC0KICAgICMgVGhpcyBmaWxlIGNvbnRyb2xzIHRoZSBzdGF0ZSBvZiBTRUxpbnV4IG9uIHRoZSBzeXN0ZW0uCiAgICAjIFNFTElOVVg9IGNhbiB0YWtlIG9uZSBvZiB0aGVzZSB0aHJlZSB2YWx1ZXM6CiAgICAjICAgICBlbmZvcmNpbmcgLSBTRUxpbnV4IHNlY3VyaXR5IHBvbGljeSBpcyBlbmZvcmNlZC4KICAgICMgICAgIHBlcm1pc3NpdmUgLSBTRUxpbnV4IHByaW50cyB3YXJuaW5ncyBpbnN0ZWFkIG9mIGVuZm9yY2luZy4KICAgICMgICAgIGRpc2FibGVkIC0gTm8gU0VMaW51eCBwb2xpY3kgaXMgbG9hZGVkLgogICAgU0VMSU5VWD1wZXJtaXNzaXZlCiAgICAjIFNFTElOVVhUWVBFPSBjYW4gdGFrZSBvbmUgb2YgdGhyZWUgdHdvIHZhbHVlczoKICAgICMgICAgIHRhcmdldGVkIC0gVGFyZ2V0ZWQgcHJvY2Vzc2VzIGFyZSBwcm90ZWN0ZWQsCiAgICAjICAgICBtaW5pbXVtIC0gTW9kaWZpY2F0aW9uIG9mIHRhcmdldGVkIHBvbGljeS4gT25seSBzZWxlY3RlZCBwcm9jZXNzZXMgYXJlIHByb3RlY3RlZC4KICAgICMgICAgIG1scyAtIE11bHRpIExldmVsIFNlY3VyaXR5IHByb3RlY3Rpb24uCiAgICBTRUxJTlVYVFlQRT10YXJnZXRlZAogICAgCgotIHBhdGg6ICcvb3B0L2Jpbi9zZXR1cCcKICBwZXJtaXNzaW9uczogJzA3NTUnCiAgY29udGVudDogfC0KICAgICMhL2Jpbi9iYXNoCiAgICBzZXQgLXhldW8gcGlwZWZhaWwKICAgIAogICAgc2V0ZW5mb3JjZSAwIHx8IHRydWUKICAgIHN5c3RlbWN0bCByZXN0YXJ0IHN5c3RlbWQtbW9kdWxlcy1sb2FkLnNlcnZpY2UKICAgIHN5c2N0bCAtLXN5c3RlbQogICAgc2VkIC1pLm9yaWcgJy8uKnN3YXAuKi9kJyAvZXRjL2ZzdGFiCiAgICBzd2Fwb2ZmIC1hCiAgICAKICAgIAogICAgeXVtIGluc3RhbGwgLXkgXAogICAgICBkZXZpY2UtbWFwcGVyLXBlcnNpc3RlbnQtZGF0YSBcCiAgICAgIGx2bTIgXAogICAgICBlYnRhYmxlcyBcCiAgICAgIGV0aHRvb2wgXAogICAgICBuZnMtdXRpbHMgXAogICAgICBiYXNoLWNvbXBsZXRpb24gXAogICAgICBzdWRvIFwKICAgICAgc29jYXQgXAogICAgICB3Z2V0IFwKICAgICAgY3VybCBcCiAgICAgIGlwdnNhZG0KICAgIHl1bSBpbnN0YWxsIC15IHl1bS11dGlscwogICAgeXVtLWNvbmZpZy1tYW5hZ2VyIC0tYWRkLXJlcG89aHR0cHM6Ly9kb3dubG9hZC5kb2NrZXIuY29tL2xpbnV4L2NlbnRvcy9kb2NrZXItY2UucmVwbwogICAgeXVtLWNvbmZpZy1tYW5hZ2VyIC0tc2F2ZSAtLXNldG9wdD1kb2NrZXItY2Utc3RhYmxlLm1vZHVsZV9ob3RmaXhlcz10cnVlCiAgICAKICAgIGNhdCA8PEVPRiB8IHRlZSAvZXRjL2NyaWN0bC55YW1sCiAgICBydW50aW1lLWVuZHBvaW50OiB1bml4Oi8vL3J1bi9jb250YWluZXJkL2NvbnRhaW5lcmQuc29jawogICAgRU9GCiAgICAKICAgIG1rZGlyIC1wIC9ldGMvc3lzdGVtZC9zeXN0ZW0vY29udGFpbmVyZC5zZXJ2aWNlLmQKICAgIGNhdCA8PEVPRiB8IHRlZSAvZXRjL3N5c3RlbWQvc3lzdGVtL2NvbnRhaW5lcmQuc2VydmljZS5kL2Vudmlyb25tZW50LmNvbmYKICAgIFtTZXJ2aWNlXQogICAgUmVzdGFydD1hbHdheXMKICAgIEVudmlyb25tZW50RmlsZT0tL2V0Yy9lbnZpcm9ubWVudAogICAgRU9GCiAgICAKICAgIHl1bSBpbnN0YWxsIC15IGNvbnRhaW5lcmQuaW8tMS40KiB5dW0tcGx1Z2luLXZlcnNpb25sb2NrCiAgICB5dW0gdmVyc2lvbmxvY2sgYWRkIGNvbnRhaW5lcmQuaW8KICAgIAogICAgc3lzdGVtY3RsIGRhZW1vbi1yZWxvYWQKICAgIHN5c3RlbWN0bCBlbmFibGUgLS1ub3cgY29udGFpbmVyZAogICAgb3B0X2Jpbj0vb3B0L2JpbgogICAgdXNyX2xvY2FsX2Jpbj0vdXNyL2xvY2FsL2JpbgogICAgY25pX2Jpbl9kaXI9L29wdC9jbmkvYmluCiAgICBta2RpciAtcCAvZXRjL2NuaS9uZXQuZCAvZXRjL2t1YmVybmV0ZXMvZHluYW1pYy1jb25maWctZGlyIC9ldGMva3ViZXJuZXRlcy9tYW5pZmVzdHMgIiRvcHRfYmluIiAiJGNuaV9iaW5fZGlyIgogICAgYXJjaD0ke0hPU1RfQVJDSC19CiAgICBpZiBbIC16ICIkYXJjaCIgXQogICAgdGhlbgogICAgY2FzZSAkKHVuYW1lIC1tKSBpbgogICAgeDg2XzY0KQogICAgICAgIGFyY2g9ImFtZDY0IgogICAgICAgIDs7CiAgICBhYXJjaDY0KQogICAgICAgIGFyY2g9ImFybTY0IgogICAgICAgIDs7CiAgICAqKQogICAgICAgIGVjaG8gInVuc3VwcG9ydGVkIENQVSBhcmNoaXRlY3R1cmUsIGV4aXRpbmciCiAgICAgICAgZXhpdCAxCiAgICAgICAgOzsKICAgIGVzYWMKICAgIGZpCiAgICBDTklfVkVSU0lPTj0iJHtDTklfVkVSU0lPTjotdjAuOC43fSIKICAgIGNuaV9iYXNlX3VybD0iaHR0cHM6Ly9naXRodWIuY29tL2NvbnRhaW5lcm5ldHdvcmtpbmcvcGx1Z2lucy9yZWxlYXNlcy9kb3dubG9hZC8kQ05JX1ZFUlNJT04iCiAgICBjbmlfZmlsZW5hbWU9ImNuaS1wbHVnaW5zLWxpbnV4LSRhcmNoLSRDTklfVkVSU0lPTi50Z3oiCiAgICBjdXJsIC1MZm8gIiRjbmlfYmluX2Rpci8kY25pX2ZpbGVuYW1lIiAiJGNuaV9iYXNlX3VybC8kY25pX2ZpbGVuYW1lIgogICAgY25pX3N1bT0kKGN1cmwgLUxmICIkY25pX2Jhc2VfdXJsLyRjbmlfZmlsZW5hbWUuc2hhMjU2IikKICAgIGNkICIkY25pX2Jpbl9kaXIiCiAgICBzaGEyNTZzdW0gLWMgPDw8IiRjbmlfc3VtIgogICAgdGFyIHh2ZiAiJGNuaV9maWxlbmFtZSIKICAgIHJtIC1mICIkY25pX2ZpbGVuYW1lIgogICAgY2QgLQogICAgQ1JJX1RPT0xTX1JFTEVBU0U9IiR7Q1JJX1RPT0xTX1JFTEVBU0U6LXYxLjIyLjB9IgogICAgY3JpX3Rvb2xzX2Jhc2VfdXJsPSJodHRwczovL2dpdGh1Yi5jb20va3ViZXJuZXRlcy1zaWdzL2NyaS10b29scy9yZWxlYXNlcy9kb3dubG9hZC8ke0NSSV9UT09MU19SRUxFQVNFfSIKICAgIGNyaV90b29sc19maWxlbmFtZT0iY3JpY3RsLSR7Q1JJX1RPT0xTX1JFTEVBU0V9LWxpbnV4LSR7YXJjaH0udGFyLmd6IgogICAgY3VybCAtTGZvICIkb3B0X2Jpbi8kY3JpX3Rvb2xzX2ZpbGVuYW1lIiAiJGNyaV90b29sc19iYXNlX3VybC8kY3JpX3Rvb2xzX2ZpbGVuYW1lIgogICAgY3JpX3Rvb2xzX3N1bT0kKGN1cmwgLUxmICIkY3JpX3Rvb2xzX2Jhc2VfdXJsLyRjcmlfdG9vbHNfZmlsZW5hbWUuc2hhMjU2IiB8IHNlZCAncy9cKlwvLy8nKQogICAgY2QgIiRvcHRfYmluIgogICAgc2hhMjU2c3VtIC1jIDw8PCIkY3JpX3Rvb2xzX3N1bSIKICAgIHRhciB4dmYgIiRjcmlfdG9vbHNfZmlsZW5hbWUiCiAgICBybSAtZiAiJGNyaV90b29sc19maWxlbmFtZSIKICAgIGxuIC1zZiAiJG9wdF9iaW4vY3JpY3RsIiAiJHVzcl9sb2NhbF9iaW4iL2NyaWN0bCB8fCBlY2hvICJzeW1ib2xpYyBsaW5rIGlzIHNraXBwZWQiCiAgICBjZCAtCiAgICBLVUJFX1ZFUlNJT049IiR7S1VCRV9WRVJTSU9OOi12MS4yMi4xfSIKICAgIGt1YmVfZGlyPSIkb3B0X2Jpbi9rdWJlcm5ldGVzLSRLVUJFX1ZFUlNJT04iCiAgICBrdWJlX2Jhc2VfdXJsPSJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20va3ViZXJuZXRlcy1yZWxlYXNlL3JlbGVhc2UvJEtVQkVfVkVSU0lPTi9iaW4vbGludXgvJGFyY2giCiAgICBrdWJlX3N1bV9maWxlPSIka3ViZV9kaXIvc2hhMjU2IgogICAgbWtkaXIgLXAgIiRrdWJlX2RpciIKICAgIDogPiIka3ViZV9zdW1fZmlsZSIKICAgIAogICAgZm9yIGJpbiBpbiBrdWJlbGV0IGt1YmVhZG0ga3ViZWN0bDsgZG8KICAgICAgICBjdXJsIC1MZm8gIiRrdWJlX2Rpci8kYmluIiAiJGt1YmVfYmFzZV91cmwvJGJpbiIKICAgICAgICBjaG1vZCAreCAiJGt1YmVfZGlyLyRiaW4iCiAgICAgICAgc3VtPSQoY3VybCAtTGYgIiRrdWJlX2Jhc2VfdXJsLyRiaW4uc2hhMjU2IikKICAgICAgICBlY2hvICIkc3VtICAka3ViZV9kaXIvJGJpbiIgPj4iJGt1YmVfc3VtX2ZpbGUiCiAgICBkb25lCiAgICBzaGEyNTZzdW0gLWMgIiRrdWJlX3N1bV9maWxlIgogICAgCiAgICBmb3IgYmluIGluIGt1YmVsZXQga3ViZWFkbSBrdWJlY3RsOyBkbwogICAgICAgIGxuIC1zZiAiJGt1YmVfZGlyLyRiaW4iICIkb3B0X2JpbiIvJGJpbgogICAgZG9uZQogICAgCiAgICBpZiBbWyAhIC14IC9vcHQvYmluL2hlYWx0aC1tb25pdG9yLnNoIF1dOyB0aGVuCiAgICAgICAgY3VybCAtTGZvIC9vcHQvYmluL2hlYWx0aC1tb25pdG9yLnNoIGh0dHBzOi8vcmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbS9rdWJlcm1hdGljL21hY2hpbmUtY29udHJvbGxlci83OTY3YTBhZjJiNzVmMjlhZDJhYjIyN2VlYWEyNmVhN2IwZjJmYmRlL3BrZy91c2VyZGF0YS9zY3JpcHRzL2hlYWx0aC1tb25pdG9yLnNoCiAgICAgICAgY2htb2QgK3ggL29wdC9iaW4vaGVhbHRoLW1vbml0b3Iuc2gKICAgIGZpCiAgICAKICAgIG1rZGlyIC1wIC9ldGMvc3lzdGVtZC9zeXN0ZW0va3ViZWxldC5zZXJ2aWNlLmQvCiAgICAjIHNldCBrdWJlbGV0IG5vZGVpcCBlbnZpcm9ubWVudCB2YXJpYWJsZQogICAgL29wdC9iaW4vc2V0dXBfbmV0X2Vudi5zaAogICAgCiAgICBzeXN0ZW1jdGwgZW5hYmxlIC0tbm93IGt1YmVsZXQKICAgIHN5c3RlbWN0bCBlbmFibGUgLS1ub3cgLS1uby1ibG9jayBrdWJlbGV0LWhlYWx0aGNoZWNrLnNlcnZpY2UKICAgIAoKLSBwYXRoOiAnL29wdC9iaW4vc3VwZXJ2aXNlLnNoJwogIHBlcm1pc3Npb25zOiAnMDc1NScKICBjb250ZW50OiB8LQogICAgIyEvYmluL2Jhc2gKICAgIHNldCAteGV1byBwaXBlZmFpbAogICAgd2hpbGUgISAiJEAiOyBkbwogICAgICBzbGVlcCAxCiAgICBkb25lCiAgICAKCi0gcGF0aDogJy9ldGMvc3lzdGVtZC9zeXN0ZW0va3ViZWxldC5zZXJ2aWNlJwogIGNvbnRlbnQ6IHwtCiAgICBbVW5pdF0KICAgIEFmdGVyPWNvbnRhaW5lcmQuc2VydmljZQogICAgUmVxdWlyZXM9Y29udGFpbmVyZC5zZXJ2aWNlCiAgICAKICAgIERlc2NyaXB0aW9uPWt1YmVsZXQ6IFRoZSBLdWJlcm5ldGVzIE5vZGUgQWdlbnQKICAgIERvY3VtZW50YXRpb249aHR0cHM6Ly9rdWJlcm5ldGVzLmlvL2RvY3MvaG9tZS8KICAgIAogICAgW1NlcnZpY2VdCiAgICBSZXN0YXJ0PWFsd2F5cwogICAgU3RhcnRMaW1pdEludGVydmFsPTAKICAgIFJlc3RhcnRTZWM9MTAKICAgIENQVUFjY291bnRpbmc9dHJ1ZQogICAgTWVtb3J5QWNjb3VudGluZz10cnVlCiAgICAKICAgIEVudmlyb25tZW50PSJQQVRIPS9vcHQvYmluOi9iaW46L3Vzci9sb2NhbC9zYmluOi91c3IvbG9jYWwvYmluOi91c3Ivc2JpbjovdXNyL2Jpbjovc2Jpbi8iCiAgICBFbnZpcm9ubWVudEZpbGU9LS9ldGMvZW52aXJvbm1lbnQKICAgIAogICAgRXhlY1N0YXJ0UHJlPS9iaW4vYmFzaCAvb3B0L2xvYWQta2VybmVsLW1vZHVsZXMuc2gKICAgIEV4ZWNTdGFydFByZT0vYmluL2Jhc2ggL29wdC9iaW4vc2V0dXBfbmV0X2Vudi5zaAogICAgRXhlY1N0YXJ0PS9vcHQvYmluL2t1YmVsZXQgJEtVQkVMRVRfRVhUUkFfQVJHUyBcCiAgICAgIC0tYm9vdHN0cmFwLWt1YmVjb25maWc9L2V0Yy9rdWJlcm5ldGVzL2Jvb3RzdHJhcC1rdWJlbGV0LmNvbmYgXAogICAgICAtLWt1YmVjb25maWc9L3Zhci9saWIva3ViZWxldC9rdWJlY29uZmlnIFwKICAgICAgLS1jb25maWc9L2V0Yy9rdWJlcm5ldGVzL2t1YmVsZXQuY29uZiBcCiAgICAgIC0tbmV0d29yay1wbHVnaW49Y25pIFwKICAgICAgLS1jZXJ0LWRpcj0vZXRjL2t1YmVybmV0ZXMvcGtpIFwKICAgICAgLS1jbG91ZC1wcm92aWRlcj1hd3MgXAogICAgICAtLWNsb3VkLWNvbmZpZz0vZXRjL2t1YmVybmV0ZXMvY2xvdWQtY29uZmlnIFwKICAgICAgLS1keW5hbWljLWNvbmZpZy1kaXI9L2V0Yy9rdWJlcm5ldGVzL2R5bmFtaWMtY29uZmlnLWRpciBcCiAgICAgIC0tZmVhdHVyZS1nYXRlcz1EeW5hbWljS3ViZWxldENvbmZpZz10cnVlIFwKICAgICAgLS1leGl0LW9uLWxvY2stY29udGVudGlvbiBcCiAgICAgIC0tbG9jay1maWxlPS90bXAva3ViZWxldC5sb2NrIFwKICAgICAgLS1jb250YWluZXItcnVudGltZT1yZW1vdGUgXAogICAgICAtLWNvbnRhaW5lci1ydW50aW1lLWVuZHBvaW50PXVuaXg6Ly8vcnVuL2NvbnRhaW5lcmQvY29udGFpbmVyZC5zb2NrIFwKICAgICAgLS1ub2RlLWlwICR7S1VCRUxFVF9OT0RFX0lQfQogICAgCiAgICBbSW5zdGFsbF0KICAgIFdhbnRlZEJ5PW11bHRpLXVzZXIudGFyZ2V0CiAgICAKCi0gcGF0aDogJy9ldGMva3ViZXJuZXRlcy9jbG91ZC1jb25maWcnCiAgcGVybWlzc2lvbnM6ICcwNjAwJwogIGNvbnRlbnQ6IHwtCiAgICBbZ2xvYmFsXQogICAgWm9uZT0iIgogICAgVlBDPSIiCiAgICBTdWJuZXRJRD0idGVzdC1zdWJuZXQiCiAgICAKICAgIAoKLSBwYXRoOiAnL29wdC9iaW4vc2V0dXBfbmV0X2Vudi5zaCcKICBwZXJtaXNzaW9uczogJzA3NTUnCiAgY29udGVudDogfC0KICAgICMhL3Vzci9iaW4vZW52IGJhc2gKICAgIGVjaG9kYXRlKCkgewogICAgICBlY2hvICJbJChkYXRlIC1JcyldIiAiJEAiCiAgICB9CiAgICAKICAgICMgZ2V0IHRoZSBkZWZhdWx0IGludGVyZmFjZSBJUCBhZGRyZXNzCiAgICBERUZBVUxUX0lGQ19JUD0kKGlwIC1vICByb3V0ZSBnZXQgMSB8IGdyZXAgLW9QICJzcmMgXEtcUysiKQogICAgCiAgICBpZiBbIC16ICIke0RFRkFVTFRfSUZDX0lQfSIgXQogICAgdGhlbgogICAgICBlY2hvZGF0ZSAiRmFpbGVkIHRvIGdldCBJUCBhZGRyZXNzIGZvciB0aGUgZGVmYXVsdCByb3V0ZSBpbnRlcmZhY2UiCiAgICAgIGV4aXQgMQogICAgZmkKICAgIAogICAgICMgZ2V0IHRoZSBmdWxsIGhvc3RuYW1lCiAgICBGVUxMX0hPU1ROQU1FPSQoaG9zdG5hbWUgLWYpCiAgICAKICAgICMgd3JpdGUgdGhlIG5vZGVpcF9lbnYgZmlsZQogICAgIyB3ZSBuZWVkIHRoZSBsaW5lIGJlbG93IGJlY2F1c2UgZmxhdGNhciBoYXMgdGhlIHNhbWUgc3RyaW5nICJjb3Jlb3MiIGluIHRoYXQgZmlsZQogICAgaWYgZ3JlcCAtcSBjb3Jlb3MgL2V0Yy9vcy1yZWxlYXNlCiAgICB0aGVuCiAgICAgIGVjaG8gIktVQkVMRVRfTk9ERV9JUD0ke0RFRkFVTFRfSUZDX0lQfVxuS1VCRUxFVF9IT1NUTkFNRT0ke0ZVTExfSE9TVE5BTUV9IiA+IC9ldGMva3ViZXJuZXRlcy9ub2RlaXAuY29uZgogICAgZWxpZiBbICEgLWQgL2V0Yy9zeXN0ZW1kL3N5c3RlbS9rdWJlbGV0LnNlcnZpY2UuZCBdCiAgICB0aGVuCiAgICAgIGVjaG9kYXRlICJDYW4ndCBmaW5kIGt1YmVsZXQgc2VydmljZSBleHRyYXMgZGlyZWN0b3J5IgogICAgICBleGl0IDEKICAgIGVsc2UKICAgICAgZWNobyAtZSAiW1NlcnZpY2VdXG5FbnZpcm9ubWVudD1cIktVQkVMRVRfTk9ERV9JUD0ke0RFRkFVTFRfSUZDX0lQfVwiXG5FbnZpcm9ubWVudD1cIktVQkVMRVRfSE9TVE5BTUU9JHtGVUxMX0hPU1ROQU1FfVwiIiA+IC9ldGMvc3lzdGVtZC9zeXN0ZW0va3ViZWxldC5zZXJ2aWNlLmQvbm9kZWlwLmNvbmYKICAgIGZpCiAgICAKCi0gcGF0aDogJy9ldGMva3ViZXJuZXRlcy9wa2kvY2EuY3J0JwogIGNvbnRlbnQ6IHwtCiAgICAtLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KICAgIE1JSUVXakNDQTBLZ0F3SUJBZ0lKQUxmUmxXc0k4WVFITUEwR0NTcUdTSWIzRFFFQkJRVUFNSHN4Q3pBSkJnTlYKICAgIEJBWVRBbFZUTVFzd0NRWURWUVFJRXdKRFFURVdNQlFHQTFVRUJ4TU5VMkZ1SUVaeVlXNWphWE5qYnpFVU1CSUcKICAgIEExVUVDaE1MUW5KaFpHWnBkSHBwYm1NeEVqQVFCZ05WQkFNVENXeHZZMkZzYUc5emRERWRNQnNHQ1NxR1NJYjMKICAgIERRRUpBUllPWW5KaFpFQmtZVzVuWVM1amIyMHdIaGNOTVRRd056RTFNakEwTmpBMVdoY05NVGN3TlRBME1qQTAKICAgIE5qQTFXakI3TVFzd0NRWURWUVFHRXdKVlV6RUxNQWtHQTFVRUNCTUNRMEV4RmpBVUJnTlZCQWNURFZOaGJpQkcKICAgIGNtRnVZMmx6WTI4eEZEQVNCZ05WQkFvVEMwSnlZV1JtYVhSNmFXNWpNUkl3RUFZRFZRUURFd2xzYjJOaGJHaHYKICAgIGMzUXhIVEFiQmdrcWhraUc5dzBCQ1FFV0RtSnlZV1JBWkdGdVoyRXVZMjl0TUlJQklqQU5CZ2txaGtpRzl3MEIKICAgIEFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXQ1ZkFqcDRmVGNla1dVVGZ6c3Awa3lpaDFPWWJzR0wwS1gxZVJiU1MKICAgIFI4T2QwKzlRNjJIeW55K0dGd01UYjRBL0tVOG1zc29IdmNjZVNBQWJ3ZmJ4RksvK3M1MVRvYnFVbk9SWnJPb1QKICAgIFpqa1V5Z2J5WERTSzk5WUJiY1IxUGlwOHZ3TVRtNFhLdUx0Q2lnZUJCZGpqQVFkZ1VPMjhMRU5HbHNNbm1lWWsKICAgIEpmT0RWR25WbXI1THRiOUFOQThJS3lUZnNuSEo0aU9DUy9QbFBiVWoycTdZbm9WTHBvc1VCTWxnVWIvQ3lrWDMKICAgIG1Pb0xiNHlKSlF5QS9pU1Q2WnhpSUVqMzZENHlXWjVsZzdZSmwrVWlpQlFIR0NuUGRHeWlwcVYwNmV4MGhlWVcKICAgIGNhaVc4TFdaU1VROTNqUStXVkNIOGhUN0RRTzFkbXN2VW1YbHEvSmVBbHdRL1FJREFRQUJvNEhnTUlIZE1CMEcKICAgIEExVWREZ1FXQkJSY0FST3RoUzRQNFU3dlRmakJ5QzU2OVI3RTZEQ0JyUVlEVlIwakJJR2xNSUdpZ0JSY0FST3QKICAgIGhTNFA0VTd2VGZqQnlDNTY5UjdFNktGL3BIMHdlekVMTUFrR0ExVUVCaE1DVlZNeEN6QUpCZ05WQkFnVEFrTkIKICAgIE1SWXdGQVlEVlFRSEV3MVRZVzRnUm5KaGJtTnBjMk52TVJRd0VnWURWUVFLRXd0Q2NtRmtabWwwZW1sdVl6RVMKICAgIE1CQUdBMVVFQXhNSmJHOWpZV3hvYjNOME1SMHdHd1lKS29aSWh2Y05BUWtCRmc1aWNtRmtRR1JoYm1kaExtTnYKICAgIGJZSUpBTGZSbFdzSThZUUhNQXdHQTFVZEV3UUZNQU1CQWY4d0RRWUpLb1pJaHZjTkFRRUZCUUFEZ2dFQkFHNmgKICAgIFU5ZjlzTkgwLzZvQmJHR3kyRVZVMFVnSVRVUUlyRldvOXJGa3JXNWsvWGtEalFtKzNsempUMGlHUjRJeEUvQW8KICAgIGVVNnNRaHVhN3dyV2VGRW40N0dMOThsbkNzSmREN29aTmhGbVE5NVRiL0xuRFVqczVZajliclAwTld6WGZZVTQKICAgIFVLMlpuSU5KUmNKcEI4aVJDYUN4RThEZGNVRjBYcUlFcTZwQTI3MnNub0xtaVhMTXZObDNrWUVkbStqZTZ2b0QKICAgIDU4U05WRVVzenR6UXlYbUpFaENwd1ZJMEE2UUNqelhqK3F2cG13M1paSGk4SndYZWk4WlpCTFRTRkJraThaN24KICAgIHNIOUJCSDM4L1N6VW1BTjRRSFNQeTFnanFtMDBPQUU4TmFZRGtoL2J6RTRkN21MR0dNV3AvV0UzS1BTdTgySEYKICAgIGtQZTZYb1NiaUxtL2t4azMyVDA9CiAgICAtLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCiAgICAKCi0gcGF0aDogJy9ldGMvc3lzdGVtZC9zeXN0ZW0vc2V0dXAuc2VydmljZScKICBwZXJtaXNzaW9uczogJzA2NDQnCiAgY29udGVudDogfC0KICAgIFtJbnN0YWxsXQogICAgV2FudGVkQnk9bXVsdGktdXNlci50YXJnZXQKICAgIAogICAgW1VuaXRdCiAgICBSZXF1aXJlcz1uZXR3b3JrLW9ubGluZS50YXJnZXQKICAgIEFmdGVyPW5ldHdvcmstb25saW5lLnRhcmdldAogICAgCiAgICBbU2VydmljZV0KICAgIFR5cGU9b25lc2hvdAogICAgUmVtYWluQWZ0ZXJFeGl0PXRydWUKICAgIEVudmlyb25tZW50RmlsZT0tL2V0Yy9lbnZpcm9ubWVudAogICAgRXhlY1N0YXJ0PS9vcHQvYmluL3N1cGVydmlzZS5zaCAvb3B0L2Jpbi9zZXR1cAogICAgCgotIHBhdGg6ICcvZXRjL3Byb2ZpbGUuZC9vcHQtYmluLXBhdGguc2gnCiAgcGVybWlzc2lvbnM6ICcwNjQ0JwogIGNvbnRlbnQ6IHwtCiAgICBleHBvcnQgUEFUSD0iL29wdC9iaW46JFBBVEgiCiAgICAKCi0gcGF0aDogJy9ldGMva3ViZXJuZXRlcy9rdWJlbGV0LmNvbmYnCiAgY29udGVudDogfC0KICAgIGFwaVZlcnNpb246IGt1YmVsZXQuY29uZmlnLms4cy5pby92MWJldGExCiAgICBraW5kOiBLdWJlbGV0Q29uZmlndXJhdGlvbgogICAgYXV0aGVudGljYXRpb246CiAgICAgIGFub255bW91czoKICAgICAgICBlbmFibGVkOiBmYWxzZQogICAgICB3ZWJob29rOgogICAgICAgIGVuYWJsZWQ6IHRydWUKICAgICAgeDUwOToKICAgICAgICBjbGllbnRDQUZpbGU6IC9ldGMva3ViZXJuZXRlcy9wa2kvY2EuY3J0CiAgICBhdXRob3JpemF0aW9uOgogICAgICBtb2RlOiBXZWJob29rCiAgICBjZ3JvdXBEcml2ZXI6IHN5c3RlbWQKICAgIGNsdXN0ZXJETlM6CiAgICAtICIxMC4wLjAuMCIKICAgIGNsdXN0ZXJEb21haW46IGNsdXN0ZXIubG9jYWwKICAgIGNvbnRhaW5lckxvZ01heFNpemU6IDEwME1pCiAgICBjb250YWluZXJMb2dNYXhGaWxlczogNQogICAgZmVhdHVyZUdhdGVzOgogICAgICBHcmFjZWZ1bE5vZGVTaHV0ZG93bjogdHJ1ZQogICAgICBJZGVudGlmeVBvZE9TOiBmYWxzZQogICAgcHJvdGVjdEtlcm5lbERlZmF1bHRzOiB0cnVlCiAgICByZWFkT25seVBvcnQ6IDAKICAgIHJvdGF0ZUNlcnRpZmljYXRlczogdHJ1ZQogICAgc2VydmVyVExTQm9vdHN0cmFwOiB0cnVlCiAgICBzdGF0aWNQb2RQYXRoOiAvZXRjL2t1YmVybmV0ZXMvbWFuaWZlc3RzCiAgICBrdWJlUmVzZXJ2ZWQ6CiAgICAgIGNwdTogMjAwbQogICAgICBlcGhlbWVyYWwtc3RvcmFnZTogMUdpCiAgICAgIG1lbW9yeTogMjAwTWkKICAgIHN5c3RlbVJlc2VydmVkOgogICAgICBjcHU6IDIwMG0KICAgICAgZXBoZW1lcmFsLXN0b3JhZ2U6IDFHaQogICAgICBtZW1vcnk6IDIwME1pCiAgICBldmljdGlvbkhhcmQ6CiAgICAgIGltYWdlZnMuYXZhaWxhYmxlOiAxNSUKICAgICAgbWVtb3J5LmF2YWlsYWJsZTogMTAwTWkKICAgICAgbm9kZWZzLmF2YWlsYWJsZTogMTAlCiAgICAgIG5vZGVmcy5pbm9kZXNGcmVlOiA1JQogICAgdGxzQ2lwaGVyU3VpdGVzOgogICAgLSBUTFNfQUVTXzEyOF9HQ01fU0hBMjU2CiAgICAtIFRMU19BRVNfMjU2X0dDTV9TSEEzODQKICAgIC0gVExTX0NIQUNIQTIwX1BPTFkxMzA1X1NIQTI1NgogICAgLSBUTFNfRUNESEVfRUNEU0FfV0lUSF9BRVNfMTI4X0dDTV9TSEEyNTYKICAgIC0gVExTX0VDREhFX0VDRFNBX1dJVEhfQUVTXzI1Nl9HQ01fU0hBMzg0CiAgICAtIFRMU19FQ0RIRV9FQ0RTQV9XSVRIX0NIQUNIQTIwX1BPTFkxMzA1CiAgICAtIFRMU19FQ0RIRV9SU0FfV0lUSF9BRVNfMTI4X0dDTV9TSEEyNTYKICAgIC0gVExTX0VDREhFX1JTQV9XSVRIX0FFU18yNTZfR0NNX1NIQTM4NAogICAgLSBUTFNfRUNESEVfUlNBX1dJVEhfQ0hBQ0hBMjBfUE9MWTEzMDUKICAgIHZvbHVtZVBsdWdpbkRpcjogL3Zhci9saWIva3ViZWxldC92b2x1bWVwbHVnaW5zCiAgICAKCi0gcGF0aDogJy9ldGMvc3lzdGVtZC9zeXN0ZW0va3ViZWxldC1oZWFsdGhjaGVjay5zZXJ2aWNlJwogIHBlcm1pc3Npb25zOiAnMDY0NCcKICBjb250ZW50OiB8LQogICAgW1VuaXRdCiAgICBSZXF1aXJlcz1rdWJlbGV0LnNlcnZpY2UKICAgIEFmdGVyPWt1YmVsZXQuc2VydmljZQogICAgCiAgICBbU2VydmljZV0KICAgIEV4ZWNTdGFydD0vb3B0L2Jpbi9oZWFsdGgtbW9uaXRvci5zaCBrdWJlbGV0CiAgICAKICAgIFtJbnN0YWxsXQogICAgV2FudGVkQnk9bXVsdGktdXNlci50YXJnZXQKICAgIAoKLSBwYXRoOiAnL2V0Yy9jb250YWluZXJkL2NvbmZpZy50b21sJwogIHBlcm1pc3Npb25zOiAnMDY0NCcKICBjb250ZW50OiB8LQogICAgdmVyc2lvbiA9IDIKICAgIAogICAgW21ldHJpY3NdCiAgICBhZGRyZXNzID0gIjEyNy4wLjAuMToxMzM4IgogICAgCiAgICBbcGx1Z2luc10KICAgIFtwbHVnaW5zLiJpby5jb250YWluZXJkLmdycGMudjEuY3JpIl0KICAgIHNhbmRib3hfaW1hZ2UgPSAiMTkyLjE2OC4xMDAuMTAwOjUwMDAva3ViZXJuZXRlcy9wYXVzZTp2My4xIgogICAgW3BsdWdpbnMuImlvLmNvbnRhaW5lcmQuZ3JwYy52MS5jcmkiLmNvbnRhaW5lcmRdCiAgICBbcGx1Z2lucy4iaW8uY29udGFpbmVyZC5ncnBjLnYxLmNyaSIuY29udGFpbmVyZC5ydW50aW1lc10KICAgIFtwbHVnaW5zLiJpby5jb250YWluZXJkLmdycGMudjEuY3JpIi5jb250YWluZXJkLnJ1bnRpbWVzLnJ1bmNdCiAgICBydW50aW1lX3R5cGUgPSAiaW8uY29udGFpbmVyZC5ydW5jLnYyIgogICAgW3BsdWdpbnMuImlvLmNvbnRhaW5lcmQuZ3JwYy52MS5jcmkiLmNvbnRhaW5lcmQucnVudGltZXMucnVuYy5vcHRpb25zXQogICAgU3lzdGVtZENncm91cCA9IHRydWUKICAgIFtwbHVnaW5zLiJpby5jb250YWluZXJkLmdycGMudjEuY3JpIi5yZWdpc3RyeV0KICAgIFtwbHVnaW5zLiJpby5jb250YWluZXJkLmdycGMudjEuY3JpIi5yZWdpc3RyeS5taXJyb3JzXQogICAgW3BsdWdpbnMuImlvLmNvbnRhaW5lcmQuZ3JwYy52MS5jcmkiLnJlZ2lzdHJ5Lm1pcnJvcnMuImRvY2tlci5pbyJdCiAgICBlbmRwb2ludCA9IFsiaHR0cHM6Ly9yZWdpc3RyeS5kb2NrZXItY24uY29tIl0KICAgIFtwbHVnaW5zLiJpby5jb250YWluZXJkLmdycGMudjEuY3JpIi5yZWdpc3RyeS5jb25maWdzXQogICAgW3BsdWdpbnMuImlvLmNvbnRhaW5lcmQuZ3JwYy52MS5jcmkiLnJlZ2lzdHJ5LmNvbmZpZ3MuIjEwLjAuMC4xOjUwMDAiXQogICAgW3BsdWdpbnMuImlvLmNvbnRhaW5lcmQuZ3JwYy52MS5jcmkiLnJlZ2lzdHJ5LmNvbmZpZ3MuIjEwLjAuMC4xOjUwMDAiLnRsc10KICAgIGluc2VjdXJlX3NraXBfdmVyaWZ5ID0gdHJ1ZQogICAgW3BsdWdpbnMuImlvLmNvbnRhaW5lcmQuZ3JwYy52MS5jcmkiLnJlZ2lzdHJ5LmNvbmZpZ3MuIjE5Mi4xNjguMTAwLjEwMDo1MDAwIl0KICAgIFtwbHVnaW5zLiJpby5jb250YWluZXJkLmdycGMudjEuY3JpIi5yZWdpc3RyeS5jb25maWdzLiIxOTIuMTY4LjEwMC4xMDA6NTAwMCIudGxzXQogICAgaW5zZWN1cmVfc2tpcF92ZXJpZnkgPSB0cnVlCiAgICAKICAgIAoKYm9vdGNtZDoKLSBtb2Rwcm9iZSBpcF90YWJsZXMK immutable: true kind: Secret metadata: creationTimestamp: null - name: osp-rhel-aws-osc-provisioning + name: osp-rhel-aws-kube-system-osc-provisioning namespace: cloud-init-settings resourceVersion: "1" +type: Opaque diff --git a/pkg/controllers/osc/testdata/secret-ubuntu-20.04-aws-containerd.yaml b/pkg/controllers/osc/testdata/secret-ubuntu-aws-containerd.yaml similarity index 80% rename from pkg/controllers/osc/testdata/secret-ubuntu-20.04-aws-containerd.yaml rename to pkg/controllers/osc/testdata/secret-ubuntu-aws-containerd.yaml index 175823ee..84bad8dc 100644 --- a/pkg/controllers/osc/testdata/secret-ubuntu-20.04-aws-containerd.yaml +++ b/pkg/controllers/osc/testdata/secret-ubuntu-aws-containerd.yaml @@ -1,10 +1,11 @@ apiVersion: v1 data: - cloud-config: I2Nsb3VkLWNvbmZpZwoKc3NoX3B3YXV0aDogbm8Kc3NoX2F1dGhvcml6ZWRfa2V5czoKLSAnc3NoLXJzYSBBQUFBQjNOemFDMXljMkVBQUFBREFRQUJBQUFDQVFEZE9JaFltekNLNURTVkx1M2MnCndyaXRlX2ZpbGVzOgotIHBhdGg6ICcvZXRjL3N5c3RlbWQvam91cm5hbGQuY29uZi5kL21heF9kaXNrX3VzZS5jb25mJwogIGNvbnRlbnQ6IHwtCiAgICBbSm91cm5hbF0KICAgIFN5c3RlbU1heFVzZT01RwogICAgCgotIHBhdGg6ICcvb3B0L2xvYWQta2VybmVsLW1vZHVsZXMuc2gnCiAgcGVybWlzc2lvbnM6ICcwNzU1JwogIGNvbnRlbnQ6IHwtCiAgICAjIS91c3IvYmluL2VudiBiYXNoCiAgICBzZXQgLWV1byBwaXBlZmFpbAogICAgCiAgICBtb2Rwcm9iZSBpcF92cwogICAgbW9kcHJvYmUgaXBfdnNfcnIKICAgIG1vZHByb2JlIGlwX3ZzX3dycgogICAgbW9kcHJvYmUgaXBfdnNfc2gKICAgIAogICAgaWYgbW9kaW5mbyBuZl9jb25udHJhY2tfaXB2NCAmPiAvZGV2L251bGw7IHRoZW4KICAgICAgbW9kcHJvYmUgbmZfY29ubnRyYWNrX2lwdjQKICAgIGVsc2UKICAgICAgbW9kcHJvYmUgbmZfY29ubnRyYWNrCiAgICBmaQogICAgCgotIHBhdGg6ICcvZXRjL3N5c2N0bC5kL2s4cy5jb25mJwogIGNvbnRlbnQ6IHwtCiAgICBuZXQuYnJpZGdlLmJyaWRnZS1uZi1jYWxsLWlwNnRhYmxlcyA9IDEKICAgIG5ldC5icmlkZ2UuYnJpZGdlLW5mLWNhbGwtaXB0YWJsZXMgPSAxCiAgICBrZXJuZWwucGFuaWNfb25fb29wcyA9IDEKICAgIGtlcm5lbC5wYW5pYyA9IDEwCiAgICBuZXQuaXB2NC5pcF9mb3J3YXJkID0gMQogICAgdm0ub3ZlcmNvbW1pdF9tZW1vcnkgPSAxCiAgICBmcy5pbm90aWZ5Lm1heF91c2VyX3dhdGNoZXMgPSAxMDQ4NTc2CiAgICAKCi0gcGF0aDogJy9ldGMvZGVmYXVsdC9ncnViLmQvNjAtc3dhcC1hY2NvdW50aW5nLmNmZycKICBjb250ZW50OiB8LQogICAgIyBBZGRlZCBieSBrdWJlcm1hdGljIG1hY2hpbmUtY29udHJvbGxlcgogICAgIyBFbmFibGUgY2dyb3VwcyBtZW1vcnkgYW5kIHN3YXAgYWNjb3VudGluZwogICAgR1JVQl9DTURMSU5FX0xJTlVYPSJjZ3JvdXBfZW5hYmxlPW1lbW9yeSBzd2FwYWNjb3VudD0xIgogICAgCgotIHBhdGg6ICcvb3B0L2Jpbi9zZXR1cCcKICBwZXJtaXNzaW9uczogJzA3NTUnCiAgY29udGVudDogfC0KICAgICMhL2Jpbi9iYXNoCiAgICBzZXQgLXhldW8gcGlwZWZhaWwKICAgIGlmIHN5c3RlbWN0bCBpcy1hY3RpdmUgdWZ3OyB0aGVuIHN5c3RlbWN0bCBzdG9wIHVmdzsgZmkKICAgIHN5c3RlbWN0bCBtYXNrIHVmdwogICAgc3lzdGVtY3RsIHJlc3RhcnQgc3lzdGVtZC1tb2R1bGVzLWxvYWQuc2VydmljZQogICAgc3lzY3RsIC0tc3lzdGVtCiAgICBzZWQgLWkub3JpZyAnLy4qc3dhcC4qL2QnIC9ldGMvZnN0YWIKICAgIHN3YXBvZmYgLWEKICAgIAogICAgYXB0LWdldCB1cGRhdGUKICAgIAogICAgREVCSUFOX0ZST05URU5EPW5vbmludGVyYWN0aXZlIGFwdC1nZXQgLW8gRHBrZzo6T3B0aW9uczo6PSItLWZvcmNlLWNvbmZkZWYiIC1vIERwa2c6Ok9wdGlvbnM6Oj0iLS1mb3JjZS1jb25mb2xkIiBpbnN0YWxsIC15IFwKICAgICAgY3VybCBcCiAgICAgIGNhLWNlcnRpZmljYXRlcyBcCiAgICAgIGNlcGgtY29tbW9uIFwKICAgICAgY2lmcy11dGlscyBcCiAgICAgIGNvbm50cmFjayBcCiAgICAgIGUyZnNwcm9ncyBcCiAgICAgIGVidGFibGVzIFwKICAgICAgZXRodG9vbCBcCiAgICAgIGdsdXN0ZXJmcy1jbGllbnQgXAogICAgICBpcHRhYmxlcyBcCiAgICAgIGpxIFwKICAgICAga21vZCBcCiAgICAgIG9wZW5zc2gtY2xpZW50IFwKICAgICAgbmZzLWNvbW1vbiBcCiAgICAgIHNvY2F0IFwKICAgICAgdXRpbC1saW51eCBcCiAgICAgIGlwdnNhZG0KICAgIGFwdC1nZXQgdXBkYXRlCiAgICBhcHQtZ2V0IGluc3RhbGwgLXkgYXB0LXRyYW5zcG9ydC1odHRwcyBjYS1jZXJ0aWZpY2F0ZXMgY3VybCBzb2Z0d2FyZS1wcm9wZXJ0aWVzLWNvbW1vbiBsc2ItcmVsZWFzZQogICAgY3VybCAtZnNTTCBodHRwczovL2Rvd25sb2FkLmRvY2tlci5jb20vbGludXgvdWJ1bnR1L2dwZyB8IGFwdC1rZXkgYWRkIC0KICAgIGFkZC1hcHQtcmVwb3NpdG9yeSAiZGViIGh0dHBzOi8vZG93bmxvYWQuZG9ja2VyLmNvbS9saW51eC91YnVudHUgJChsc2JfcmVsZWFzZSAtY3MpIHN0YWJsZSIKICAgIAogICAgY2F0IDw8RU9GIHwgdGVlIC9ldGMvY3JpY3RsLnlhbWwKICAgIHJ1bnRpbWUtZW5kcG9pbnQ6IHVuaXg6Ly8vcnVuL2NvbnRhaW5lcmQvY29udGFpbmVyZC5zb2NrCiAgICBFT0YKICAgIAogICAgbWtkaXIgLXAgL2V0Yy9zeXN0ZW1kL3N5c3RlbS9jb250YWluZXJkLnNlcnZpY2UuZAogICAgY2F0IDw8RU9GIHwgdGVlIC9ldGMvc3lzdGVtZC9zeXN0ZW0vY29udGFpbmVyZC5zZXJ2aWNlLmQvZW52aXJvbm1lbnQuY29uZgogICAgW1NlcnZpY2VdCiAgICBSZXN0YXJ0PWFsd2F5cwogICAgRW52aXJvbm1lbnRGaWxlPS0vZXRjL2Vudmlyb25tZW50CiAgICBFT0YKICAgIAogICAgYXB0LWdldCBpbnN0YWxsIC15IC0tYWxsb3ctZG93bmdyYWRlcyBjb250YWluZXJkLmlvPTEuNCoKICAgIGFwdC1tYXJrIGhvbGQgY29udGFpbmVyZC5pbwogICAgCiAgICBzeXN0ZW1jdGwgZGFlbW9uLXJlbG9hZAogICAgc3lzdGVtY3RsIGVuYWJsZSAtLW5vdyBjb250YWluZXJkCiAgICBvcHRfYmluPS9vcHQvYmluCiAgICBjbmlfYmluX2Rpcj0vb3B0L2NuaS9iaW4KICAgIG1rZGlyIC1wIC9ldGMvY25pL25ldC5kIC9ldGMva3ViZXJuZXRlcy9keW5hbWljLWNvbmZpZy1kaXIgL2V0Yy9rdWJlcm5ldGVzL21hbmlmZXN0cyAiJG9wdF9iaW4iICIkY25pX2Jpbl9kaXIiCiAgICBhcmNoPSR7SE9TVF9BUkNILX0KICAgIGlmIFsgLXogIiRhcmNoIiBdCiAgICB0aGVuCiAgICBjYXNlICQodW5hbWUgLW0pIGluCiAgICB4ODZfNjQpCiAgICAgICAgYXJjaD0iYW1kNjQiCiAgICAgICAgOzsKICAgIGFhcmNoNjQpCiAgICAgICAgYXJjaD0iYXJtNjQiCiAgICAgICAgOzsKICAgICopCiAgICAgICAgZWNobyAidW5zdXBwb3J0ZWQgQ1BVIGFyY2hpdGVjdHVyZSwgZXhpdGluZyIKICAgICAgICBleGl0IDEKICAgICAgICA7OwogICAgZXNhYwogICAgZmkKICAgIENOSV9WRVJTSU9OPSIke0NOSV9WRVJTSU9OOi12MC44Ljd9IgogICAgY25pX2Jhc2VfdXJsPSJodHRwczovL2dpdGh1Yi5jb20vY29udGFpbmVybmV0d29ya2luZy9wbHVnaW5zL3JlbGVhc2VzL2Rvd25sb2FkLyRDTklfVkVSU0lPTiIKICAgIGNuaV9maWxlbmFtZT0iY25pLXBsdWdpbnMtbGludXgtJGFyY2gtJENOSV9WRVJTSU9OLnRneiIKICAgIGN1cmwgLUxmbyAiJGNuaV9iaW5fZGlyLyRjbmlfZmlsZW5hbWUiICIkY25pX2Jhc2VfdXJsLyRjbmlfZmlsZW5hbWUiCiAgICBjbmlfc3VtPSQoY3VybCAtTGYgIiRjbmlfYmFzZV91cmwvJGNuaV9maWxlbmFtZS5zaGEyNTYiKQogICAgY2QgIiRjbmlfYmluX2RpciIKICAgIHNoYTI1NnN1bSAtYyA8PDwiJGNuaV9zdW0iCiAgICB0YXIgeHZmICIkY25pX2ZpbGVuYW1lIgogICAgcm0gLWYgIiRjbmlfZmlsZW5hbWUiCiAgICBjZCAtCiAgICBLVUJFX1ZFUlNJT049IiR7S1VCRV9WRVJTSU9OOi12MS4yMi4xfSIKICAgIGt1YmVfZGlyPSIkb3B0X2Jpbi9rdWJlcm5ldGVzLSRLVUJFX1ZFUlNJT04iCiAgICBrdWJlX2Jhc2VfdXJsPSJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20va3ViZXJuZXRlcy1yZWxlYXNlL3JlbGVhc2UvJEtVQkVfVkVSU0lPTi9iaW4vbGludXgvJGFyY2giCiAgICBrdWJlX3N1bV9maWxlPSIka3ViZV9kaXIvc2hhMjU2IgogICAgbWtkaXIgLXAgIiRrdWJlX2RpciIKICAgIDogPiIka3ViZV9zdW1fZmlsZSIKICAgIAogICAgZm9yIGJpbiBpbiBrdWJlbGV0IGt1YmVhZG0ga3ViZWN0bDsgZG8KICAgICAgICBjdXJsIC1MZm8gIiRrdWJlX2Rpci8kYmluIiAiJGt1YmVfYmFzZV91cmwvJGJpbiIKICAgICAgICBjaG1vZCAreCAiJGt1YmVfZGlyLyRiaW4iCiAgICAgICAgc3VtPSQoY3VybCAtTGYgIiRrdWJlX2Jhc2VfdXJsLyRiaW4uc2hhMjU2IikKICAgICAgICBlY2hvICIkc3VtICAka3ViZV9kaXIvJGJpbiIgPj4iJGt1YmVfc3VtX2ZpbGUiCiAgICBkb25lCiAgICBzaGEyNTZzdW0gLWMgIiRrdWJlX3N1bV9maWxlIgogICAgCiAgICBmb3IgYmluIGluIGt1YmVsZXQga3ViZWFkbSBrdWJlY3RsOyBkbwogICAgICAgIGxuIC1zZiAiJGt1YmVfZGlyLyRiaW4iICIkb3B0X2JpbiIvJGJpbgogICAgZG9uZQogICAgCiAgICBpZiBbWyAhIC14IC9vcHQvYmluL2hlYWx0aC1tb25pdG9yLnNoIF1dOyB0aGVuCiAgICAgICAgY3VybCAtTGZvIC9vcHQvYmluL2hlYWx0aC1tb25pdG9yLnNoIGh0dHBzOi8vcmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbS9rdWJlcm1hdGljL21hY2hpbmUtY29udHJvbGxlci83OTY3YTBhZjJiNzVmMjlhZDJhYjIyN2VlYWEyNmVhN2IwZjJmYmRlL3BrZy91c2VyZGF0YS9zY3JpcHRzL2hlYWx0aC1tb25pdG9yLnNoCiAgICAgICAgY2htb2QgK3ggL29wdC9iaW4vaGVhbHRoLW1vbml0b3Iuc2gKICAgIGZpCiAgICAKICAgICMgc2V0IGt1YmVsZXQgbm9kZWlwIGVudmlyb25tZW50IHZhcmlhYmxlCiAgICAvb3B0L2Jpbi9zZXR1cF9uZXRfZW52LnNoCiAgICAKICAgIHN5c3RlbWN0bCBlbmFibGUgLS1ub3cga3ViZWxldAogICAgc3lzdGVtY3RsIGVuYWJsZSAtLW5vdyAtLW5vLWJsb2NrIGt1YmVsZXQtaGVhbHRoY2hlY2suc2VydmljZQogICAgCgotIHBhdGg6ICcvb3B0L2Jpbi9zdXBlcnZpc2Uuc2gnCiAgcGVybWlzc2lvbnM6ICcwNzU1JwogIGNvbnRlbnQ6IHwtCiAgICAjIS9iaW4vYmFzaAogICAgc2V0IC14ZXVvIHBpcGVmYWlsCiAgICB3aGlsZSAhICIkQCI7IGRvCiAgICAgIHNsZWVwIDEKICAgIGRvbmUKICAgIAoKLSBwYXRoOiAnL2V0Yy9zeXN0ZW1kL3N5c3RlbS9rdWJlbGV0LnNlcnZpY2UnCiAgY29udGVudDogfC0KICAgIFtVbml0XQogICAgQWZ0ZXI9Y29udGFpbmVyZC5zZXJ2aWNlCiAgICBSZXF1aXJlcz1jb250YWluZXJkLnNlcnZpY2UKICAgIAogICAgRGVzY3JpcHRpb249a3ViZWxldDogVGhlIEt1YmVybmV0ZXMgTm9kZSBBZ2VudAogICAgRG9jdW1lbnRhdGlvbj1odHRwczovL2t1YmVybmV0ZXMuaW8vZG9jcy9ob21lLwogICAgCiAgICBbU2VydmljZV0KICAgIFJlc3RhcnQ9YWx3YXlzCiAgICBTdGFydExpbWl0SW50ZXJ2YWw9MAogICAgUmVzdGFydFNlYz0xMAogICAgQ1BVQWNjb3VudGluZz10cnVlCiAgICBNZW1vcnlBY2NvdW50aW5nPXRydWUKICAgIAogICAgRW52aXJvbm1lbnQ9IlBBVEg9L29wdC9iaW46L2JpbjovdXNyL2xvY2FsL3NiaW46L3Vzci9sb2NhbC9iaW46L3Vzci9zYmluOi91c3IvYmluOi9zYmluLyIKICAgIEVudmlyb25tZW50RmlsZT0tL2V0Yy9lbnZpcm9ubWVudAogICAgCiAgICBFeGVjU3RhcnRQcmU9L2Jpbi9iYXNoIC9vcHQvbG9hZC1rZXJuZWwtbW9kdWxlcy5zaAogICAgRXhlY1N0YXJ0UHJlPS9iaW4vYmFzaCAvb3B0L2Jpbi9zZXR1cF9uZXRfZW52LnNoCiAgICBFeGVjU3RhcnQ9L29wdC9iaW4va3ViZWxldCAkS1VCRUxFVF9FWFRSQV9BUkdTIFwKICAgICAgLS1ib290c3RyYXAta3ViZWNvbmZpZz0vZXRjL2t1YmVybmV0ZXMvYm9vdHN0cmFwLWt1YmVsZXQuY29uZiBcCiAgICAgIC0ta3ViZWNvbmZpZz0vdmFyL2xpYi9rdWJlbGV0L2t1YmVjb25maWcgXAogICAgICAtLWNvbmZpZz0vZXRjL2t1YmVybmV0ZXMva3ViZWxldC5jb25mIFwKICAgICAgLS1uZXR3b3JrLXBsdWdpbj1jbmkgXAogICAgICAtLWNlcnQtZGlyPS9ldGMva3ViZXJuZXRlcy9wa2kgXAogICAgICAtLWNsb3VkLXByb3ZpZGVyPWF3cyBcCiAgICAgIC0tY2xvdWQtY29uZmlnPS9ldGMva3ViZXJuZXRlcy9jbG91ZC1jb25maWcgXAogICAgICAtLWR5bmFtaWMtY29uZmlnLWRpcj0vZXRjL2t1YmVybmV0ZXMvZHluYW1pYy1jb25maWctZGlyIFwKICAgICAgLS1mZWF0dXJlLWdhdGVzPUR5bmFtaWNLdWJlbGV0Q29uZmlnPXRydWUgXAogICAgICAtLWV4aXQtb24tbG9jay1jb250ZW50aW9uIFwKICAgICAgLS1sb2NrLWZpbGU9L3RtcC9rdWJlbGV0LmxvY2sgXAogICAgICAtLWNvbnRhaW5lci1ydW50aW1lPXJlbW90ZSBcCiAgICAgIC0tY29udGFpbmVyLXJ1bnRpbWUtZW5kcG9pbnQ9dW5peDovLy9ydW4vY29udGFpbmVyZC9jb250YWluZXJkLnNvY2sgXAogICAgICAtLW5vZGUtaXAgJHtLVUJFTEVUX05PREVfSVB9CiAgICAKICAgIFtJbnN0YWxsXQogICAgV2FudGVkQnk9bXVsdGktdXNlci50YXJnZXQKICAgIAoKLSBwYXRoOiAnL2V0Yy9zeXN0ZW1kL3N5c3RlbS9rdWJlbGV0LnNlcnZpY2UuZC9leHRyYXMuY29uZicKICBjb250ZW50OiB8LQogICAgW1NlcnZpY2VdCiAgICBFbnZpcm9ubWVudD0iS1VCRUxFVF9FWFRSQV9BUkdTPS0tcmVzb2x2LWNvbmY9L3J1bi9zeXN0ZW1kL3Jlc29sdmUvcmVzb2x2LmNvbmYiCiAgICAKCi0gcGF0aDogJy9ldGMva3ViZXJuZXRlcy9jbG91ZC1jb25maWcnCiAgcGVybWlzc2lvbnM6ICcwNjAwJwogIGNvbnRlbnQ6IHwtCiAgICBbZ2xvYmFsXQogICAgWm9uZT0iIgogICAgVlBDPSIiCiAgICBTdWJuZXRJRD0idGVzdC1zdWJuZXQiCiAgICAKICAgIAoKLSBwYXRoOiAnL29wdC9iaW4vc2V0dXBfbmV0X2Vudi5zaCcKICBwZXJtaXNzaW9uczogJzA3NTUnCiAgY29udGVudDogfC0KICAgICMhL3Vzci9iaW4vZW52IGJhc2gKICAgIGVjaG9kYXRlKCkgewogICAgICBlY2hvICJbJChkYXRlIC1JcyldIiAiJEAiCiAgICB9CiAgICAKICAgICMgZ2V0IHRoZSBkZWZhdWx0IGludGVyZmFjZSBJUCBhZGRyZXNzCiAgICBERUZBVUxUX0lGQ19JUD0kKGlwIC1vICByb3V0ZSBnZXQgMSB8IGdyZXAgLW9QICJzcmMgXEtcUysiKQogICAgCiAgICBpZiBbIC16ICIke0RFRkFVTFRfSUZDX0lQfSIgXQogICAgdGhlbgogICAgICBlY2hvZGF0ZSAiRmFpbGVkIHRvIGdldCBJUCBhZGRyZXNzIGZvciB0aGUgZGVmYXVsdCByb3V0ZSBpbnRlcmZhY2UiCiAgICAgIGV4aXQgMQogICAgZmkKICAgIAogICAgICMgZ2V0IHRoZSBmdWxsIGhvc3RuYW1lCiAgICBGVUxMX0hPU1ROQU1FPSQoaG9zdG5hbWUgLWYpCiAgICAKICAgICMgd3JpdGUgdGhlIG5vZGVpcF9lbnYgZmlsZQogICAgIyB3ZSBuZWVkIHRoZSBsaW5lIGJlbG93IGJlY2F1c2UgZmxhdGNhciBoYXMgdGhlIHNhbWUgc3RyaW5nICJjb3Jlb3MiIGluIHRoYXQgZmlsZQogICAgaWYgZ3JlcCAtcSBjb3Jlb3MgL2V0Yy9vcy1yZWxlYXNlCiAgICB0aGVuCiAgICAgIGVjaG8gIktVQkVMRVRfTk9ERV9JUD0ke0RFRkFVTFRfSUZDX0lQfVxuS1VCRUxFVF9IT1NUTkFNRT0ke0ZVTExfSE9TVE5BTUV9IiA+IC9ldGMva3ViZXJuZXRlcy9ub2RlaXAuY29uZgogICAgZWxpZiBbICEgLWQgL2V0Yy9zeXN0ZW1kL3N5c3RlbS9rdWJlbGV0LnNlcnZpY2UuZCBdCiAgICB0aGVuCiAgICAgIGVjaG9kYXRlICJDYW4ndCBmaW5kIGt1YmVsZXQgc2VydmljZSBleHRyYXMgZGlyZWN0b3J5IgogICAgICBleGl0IDEKICAgIGVsc2UKICAgICAgZWNobyAtZSAiW1NlcnZpY2VdXG5FbnZpcm9ubWVudD1cIktVQkVMRVRfTk9ERV9JUD0ke0RFRkFVTFRfSUZDX0lQfVwiXG5FbnZpcm9ubWVudD1cIktVQkVMRVRfSE9TVE5BTUU9JHtGVUxMX0hPU1ROQU1FfVwiIiA+IC9ldGMvc3lzdGVtZC9zeXN0ZW0va3ViZWxldC5zZXJ2aWNlLmQvbm9kZWlwLmNvbmYKICAgIGZpCiAgICAKCi0gcGF0aDogJy9ldGMva3ViZXJuZXRlcy9wa2kvY2EuY3J0JwogIGNvbnRlbnQ6IHwtCiAgICAtLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KICAgIE1JSUVXakNDQTBLZ0F3SUJBZ0lKQUxmUmxXc0k4WVFITUEwR0NTcUdTSWIzRFFFQkJRVUFNSHN4Q3pBSkJnTlYKICAgIEJBWVRBbFZUTVFzd0NRWURWUVFJRXdKRFFURVdNQlFHQTFVRUJ4TU5VMkZ1SUVaeVlXNWphWE5qYnpFVU1CSUcKICAgIEExVUVDaE1MUW5KaFpHWnBkSHBwYm1NeEVqQVFCZ05WQkFNVENXeHZZMkZzYUc5emRERWRNQnNHQ1NxR1NJYjMKICAgIERRRUpBUllPWW5KaFpFQmtZVzVuWVM1amIyMHdIaGNOTVRRd056RTFNakEwTmpBMVdoY05NVGN3TlRBME1qQTAKICAgIE5qQTFXakI3TVFzd0NRWURWUVFHRXdKVlV6RUxNQWtHQTFVRUNCTUNRMEV4RmpBVUJnTlZCQWNURFZOaGJpQkcKICAgIGNtRnVZMmx6WTI4eEZEQVNCZ05WQkFvVEMwSnlZV1JtYVhSNmFXNWpNUkl3RUFZRFZRUURFd2xzYjJOaGJHaHYKICAgIGMzUXhIVEFiQmdrcWhraUc5dzBCQ1FFV0RtSnlZV1JBWkdGdVoyRXVZMjl0TUlJQklqQU5CZ2txaGtpRzl3MEIKICAgIEFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXQ1ZkFqcDRmVGNla1dVVGZ6c3Awa3lpaDFPWWJzR0wwS1gxZVJiU1MKICAgIFI4T2QwKzlRNjJIeW55K0dGd01UYjRBL0tVOG1zc29IdmNjZVNBQWJ3ZmJ4RksvK3M1MVRvYnFVbk9SWnJPb1QKICAgIFpqa1V5Z2J5WERTSzk5WUJiY1IxUGlwOHZ3TVRtNFhLdUx0Q2lnZUJCZGpqQVFkZ1VPMjhMRU5HbHNNbm1lWWsKICAgIEpmT0RWR25WbXI1THRiOUFOQThJS3lUZnNuSEo0aU9DUy9QbFBiVWoycTdZbm9WTHBvc1VCTWxnVWIvQ3lrWDMKICAgIG1Pb0xiNHlKSlF5QS9pU1Q2WnhpSUVqMzZENHlXWjVsZzdZSmwrVWlpQlFIR0NuUGRHeWlwcVYwNmV4MGhlWVcKICAgIGNhaVc4TFdaU1VROTNqUStXVkNIOGhUN0RRTzFkbXN2VW1YbHEvSmVBbHdRL1FJREFRQUJvNEhnTUlIZE1CMEcKICAgIEExVWREZ1FXQkJSY0FST3RoUzRQNFU3dlRmakJ5QzU2OVI3RTZEQ0JyUVlEVlIwakJJR2xNSUdpZ0JSY0FST3QKICAgIGhTNFA0VTd2VGZqQnlDNTY5UjdFNktGL3BIMHdlekVMTUFrR0ExVUVCaE1DVlZNeEN6QUpCZ05WQkFnVEFrTkIKICAgIE1SWXdGQVlEVlFRSEV3MVRZVzRnUm5KaGJtTnBjMk52TVJRd0VnWURWUVFLRXd0Q2NtRmtabWwwZW1sdVl6RVMKICAgIE1CQUdBMVVFQXhNSmJHOWpZV3hvYjNOME1SMHdHd1lKS29aSWh2Y05BUWtCRmc1aWNtRmtRR1JoYm1kaExtTnYKICAgIGJZSUpBTGZSbFdzSThZUUhNQXdHQTFVZEV3UUZNQU1CQWY4d0RRWUpLb1pJaHZjTkFRRUZCUUFEZ2dFQkFHNmgKICAgIFU5ZjlzTkgwLzZvQmJHR3kyRVZVMFVnSVRVUUlyRldvOXJGa3JXNWsvWGtEalFtKzNsempUMGlHUjRJeEUvQW8KICAgIGVVNnNRaHVhN3dyV2VGRW40N0dMOThsbkNzSmREN29aTmhGbVE5NVRiL0xuRFVqczVZajliclAwTld6WGZZVTQKICAgIFVLMlpuSU5KUmNKcEI4aVJDYUN4RThEZGNVRjBYcUlFcTZwQTI3MnNub0xtaVhMTXZObDNrWUVkbStqZTZ2b0QKICAgIDU4U05WRVVzenR6UXlYbUpFaENwd1ZJMEE2UUNqelhqK3F2cG13M1paSGk4SndYZWk4WlpCTFRTRkJraThaN24KICAgIHNIOUJCSDM4L1N6VW1BTjRRSFNQeTFnanFtMDBPQUU4TmFZRGtoL2J6RTRkN21MR0dNV3AvV0UzS1BTdTgySEYKICAgIGtQZTZYb1NiaUxtL2t4azMyVDA9CiAgICAtLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCiAgICAKCi0gcGF0aDogJy9ldGMvc3lzdGVtZC9zeXN0ZW0vc2V0dXAuc2VydmljZScKICBwZXJtaXNzaW9uczogJzA2NDQnCiAgY29udGVudDogfC0KICAgIFtJbnN0YWxsXQogICAgV2FudGVkQnk9bXVsdGktdXNlci50YXJnZXQKICAgIAogICAgW1VuaXRdCiAgICBSZXF1aXJlcz1uZXR3b3JrLW9ubGluZS50YXJnZXQKICAgIEFmdGVyPW5ldHdvcmstb25saW5lLnRhcmdldAogICAgCiAgICBbU2VydmljZV0KICAgIFR5cGU9b25lc2hvdAogICAgUmVtYWluQWZ0ZXJFeGl0PXRydWUKICAgIEVudmlyb25tZW50RmlsZT0tL2V0Yy9lbnZpcm9ubWVudAogICAgRXhlY1N0YXJ0PS9vcHQvYmluL3N1cGVydmlzZS5zaCAvb3B0L2Jpbi9zZXR1cAogICAgCgotIHBhdGg6ICcvZXRjL3Byb2ZpbGUuZC9vcHQtYmluLXBhdGguc2gnCiAgcGVybWlzc2lvbnM6ICcwNjQ0JwogIGNvbnRlbnQ6IHwtCiAgICBleHBvcnQgUEFUSD0iL29wdC9iaW46JFBBVEgiCiAgICAKCi0gcGF0aDogJy9ldGMva3ViZXJuZXRlcy9rdWJlbGV0LmNvbmYnCiAgY29udGVudDogfC0KICAgIGFwaVZlcnNpb246IGt1YmVsZXQuY29uZmlnLms4cy5pby92MWJldGExCiAgICBraW5kOiBLdWJlbGV0Q29uZmlndXJhdGlvbgogICAgYXV0aGVudGljYXRpb246CiAgICAgIGFub255bW91czoKICAgICAgICBlbmFibGVkOiBmYWxzZQogICAgICB3ZWJob29rOgogICAgICAgIGVuYWJsZWQ6IHRydWUKICAgICAgeDUwOToKICAgICAgICBjbGllbnRDQUZpbGU6IC9ldGMva3ViZXJuZXRlcy9wa2kvY2EuY3J0CiAgICBhdXRob3JpemF0aW9uOgogICAgICBtb2RlOiBXZWJob29rCiAgICBjZ3JvdXBEcml2ZXI6IHN5c3RlbWQKICAgIGNsdXN0ZXJETlM6CiAgICAtICIxMC4wLjAuMCIKICAgIGNsdXN0ZXJEb21haW46IGNsdXN0ZXIubG9jYWwKICAgIGZlYXR1cmVHYXRlczoKICAgICAgR3JhY2VmdWxOb2RlU2h1dGRvd246IHRydWUKICAgICAgSWRlbnRpZnlQb2RPUzogZmFsc2UKICAgIHByb3RlY3RLZXJuZWxEZWZhdWx0czogdHJ1ZQogICAgcmVhZE9ubHlQb3J0OiAwCiAgICByb3RhdGVDZXJ0aWZpY2F0ZXM6IHRydWUKICAgIHNlcnZlclRMU0Jvb3RzdHJhcDogdHJ1ZQogICAgc3RhdGljUG9kUGF0aDogL2V0Yy9rdWJlcm5ldGVzL21hbmlmZXN0cwogICAga3ViZVJlc2VydmVkOgogICAgICBjcHU6IDIwMG0KICAgICAgZXBoZW1lcmFsLXN0b3JhZ2U6IDFHaQogICAgICBtZW1vcnk6IDIwME1pCiAgICBzeXN0ZW1SZXNlcnZlZDoKICAgICAgY3B1OiAyMDBtCiAgICAgIGVwaGVtZXJhbC1zdG9yYWdlOiAxR2kKICAgICAgbWVtb3J5OiAyMDBNaQogICAgZXZpY3Rpb25IYXJkOgogICAgICBpbWFnZWZzLmF2YWlsYWJsZTogMTUlCiAgICAgIG1lbW9yeS5hdmFpbGFibGU6IDEwME1pCiAgICAgIG5vZGVmcy5hdmFpbGFibGU6IDEwJQogICAgICBub2RlZnMuaW5vZGVzRnJlZTogNSUKICAgIHRsc0NpcGhlclN1aXRlczoKICAgIC0gVExTX0FFU18xMjhfR0NNX1NIQTI1NgogICAgLSBUTFNfQUVTXzI1Nl9HQ01fU0hBMzg0CiAgICAtIFRMU19DSEFDSEEyMF9QT0xZMTMwNV9TSEEyNTYKICAgIC0gVExTX0VDREhFX0VDRFNBX1dJVEhfQUVTXzEyOF9HQ01fU0hBMjU2CiAgICAtIFRMU19FQ0RIRV9FQ0RTQV9XSVRIX0FFU18yNTZfR0NNX1NIQTM4NAogICAgLSBUTFNfRUNESEVfRUNEU0FfV0lUSF9DSEFDSEEyMF9QT0xZMTMwNQogICAgLSBUTFNfRUNESEVfUlNBX1dJVEhfQUVTXzEyOF9HQ01fU0hBMjU2CiAgICAtIFRMU19FQ0RIRV9SU0FfV0lUSF9BRVNfMjU2X0dDTV9TSEEzODQKICAgIC0gVExTX0VDREhFX1JTQV9XSVRIX0NIQUNIQTIwX1BPTFkxMzA1CiAgICB2b2x1bWVQbHVnaW5EaXI6IC92YXIvbGliL2t1YmVsZXQvdm9sdW1lcGx1Z2lucwogICAgCgotIHBhdGg6ICcvZXRjL3N5c3RlbWQvc3lzdGVtL2t1YmVsZXQtaGVhbHRoY2hlY2suc2VydmljZScKICBwZXJtaXNzaW9uczogJzA2NDQnCiAgY29udGVudDogfC0KICAgIFtVbml0XQogICAgUmVxdWlyZXM9a3ViZWxldC5zZXJ2aWNlCiAgICBBZnRlcj1rdWJlbGV0LnNlcnZpY2UKICAgIAogICAgW1NlcnZpY2VdCiAgICBFeGVjU3RhcnQ9L29wdC9iaW4vaGVhbHRoLW1vbml0b3Iuc2gga3ViZWxldAogICAgCiAgICBbSW5zdGFsbF0KICAgIFdhbnRlZEJ5PW11bHRpLXVzZXIudGFyZ2V0CiAgICAKCi0gcGF0aDogJy9ldGMvY29udGFpbmVyZC9jb25maWcudG9tbCcKICBwZXJtaXNzaW9uczogJzA2NDQnCiAgY29udGVudDogfC0KICAgIHZlcnNpb24gPSAyCiAgICAKICAgIFttZXRyaWNzXQogICAgYWRkcmVzcyA9ICIxMjcuMC4wLjE6MTMzOCIKICAgIAogICAgW3BsdWdpbnNdCiAgICBbcGx1Z2lucy4iaW8uY29udGFpbmVyZC5ncnBjLnYxLmNyaSJdCiAgICBbcGx1Z2lucy4iaW8uY29udGFpbmVyZC5ncnBjLnYxLmNyaSIuY29udGFpbmVyZF0KICAgIFtwbHVnaW5zLiJpby5jb250YWluZXJkLmdycGMudjEuY3JpIi5jb250YWluZXJkLnJ1bnRpbWVzXQogICAgW3BsdWdpbnMuImlvLmNvbnRhaW5lcmQuZ3JwYy52MS5jcmkiLmNvbnRhaW5lcmQucnVudGltZXMucnVuY10KICAgIHJ1bnRpbWVfdHlwZSA9ICJpby5jb250YWluZXJkLnJ1bmMudjIiCiAgICBbcGx1Z2lucy4iaW8uY29udGFpbmVyZC5ncnBjLnYxLmNyaSIuY29udGFpbmVyZC5ydW50aW1lcy5ydW5jLm9wdGlvbnNdCiAgICBTeXN0ZW1kQ2dyb3VwID0gdHJ1ZQogICAgW3BsdWdpbnMuImlvLmNvbnRhaW5lcmQuZ3JwYy52MS5jcmkiLnJlZ2lzdHJ5XQogICAgW3BsdWdpbnMuImlvLmNvbnRhaW5lcmQuZ3JwYy52MS5jcmkiLnJlZ2lzdHJ5Lm1pcnJvcnNdCiAgICBbcGx1Z2lucy4iaW8uY29udGFpbmVyZC5ncnBjLnYxLmNyaSIucmVnaXN0cnkubWlycm9ycy4iZG9ja2VyLmlvIl0KICAgIGVuZHBvaW50ID0gWyJodHRwczovL3JlZ2lzdHJ5LTEuZG9ja2VyLmlvIl0KICAgIAoKYm9vdGNtZDoKLSBlY2hvIGhlbGxvCi0gZWNobyB3b3JsZAoKcmhfc3Vic2NyaXB0aW9uOgogICAgcGFzc3dvcmQ6IHBhc3N3b3JkCiAgICB1c2VybmFtZTogdXNlcm5hbWU= + cloud-config: I2Nsb3VkLWNvbmZpZwoKc3NoX3B3YXV0aDogbm8Kc3NoX2F1dGhvcml6ZWRfa2V5czoKLSAnc3NoLXJzYSBBQUFBQjNOemFDMXljMkVBQUFBREFRQUJBQUFDQVFEZE9JaFltekNLNURTVkx1M2MnCndyaXRlX2ZpbGVzOgotIHBhdGg6ICcvZXRjL3N5c3RlbWQvam91cm5hbGQuY29uZi5kL21heF9kaXNrX3VzZS5jb25mJwogIGNvbnRlbnQ6IHwtCiAgICBbSm91cm5hbF0KICAgIFN5c3RlbU1heFVzZT01RwogICAgCgotIHBhdGg6ICcvb3B0L2xvYWQta2VybmVsLW1vZHVsZXMuc2gnCiAgcGVybWlzc2lvbnM6ICcwNzU1JwogIGNvbnRlbnQ6IHwtCiAgICAjIS91c3IvYmluL2VudiBiYXNoCiAgICBzZXQgLWV1byBwaXBlZmFpbAogICAgCiAgICBtb2Rwcm9iZSBpcF92cwogICAgbW9kcHJvYmUgaXBfdnNfcnIKICAgIG1vZHByb2JlIGlwX3ZzX3dycgogICAgbW9kcHJvYmUgaXBfdnNfc2gKICAgIAogICAgaWYgbW9kaW5mbyBuZl9jb25udHJhY2tfaXB2NCAmPiAvZGV2L251bGw7IHRoZW4KICAgICAgbW9kcHJvYmUgbmZfY29ubnRyYWNrX2lwdjQKICAgIGVsc2UKICAgICAgbW9kcHJvYmUgbmZfY29ubnRyYWNrCiAgICBmaQogICAgCgotIHBhdGg6ICcvZXRjL3N5c2N0bC5kL2s4cy5jb25mJwogIGNvbnRlbnQ6IHwtCiAgICBuZXQuYnJpZGdlLmJyaWRnZS1uZi1jYWxsLWlwNnRhYmxlcyA9IDEKICAgIG5ldC5icmlkZ2UuYnJpZGdlLW5mLWNhbGwtaXB0YWJsZXMgPSAxCiAgICBrZXJuZWwucGFuaWNfb25fb29wcyA9IDEKICAgIGtlcm5lbC5wYW5pYyA9IDEwCiAgICBuZXQuaXB2NC5pcF9mb3J3YXJkID0gMQogICAgdm0ub3ZlcmNvbW1pdF9tZW1vcnkgPSAxCiAgICBmcy5pbm90aWZ5Lm1heF91c2VyX3dhdGNoZXMgPSAxMDQ4NTc2CiAgICAKCi0gcGF0aDogJy9ldGMvZGVmYXVsdC9ncnViLmQvNjAtc3dhcC1hY2NvdW50aW5nLmNmZycKICBjb250ZW50OiB8LQogICAgIyBBZGRlZCBieSBrdWJlcm1hdGljIG1hY2hpbmUtY29udHJvbGxlcgogICAgIyBFbmFibGUgY2dyb3VwcyBtZW1vcnkgYW5kIHN3YXAgYWNjb3VudGluZwogICAgR1JVQl9DTURMSU5FX0xJTlVYPSJjZ3JvdXBfZW5hYmxlPW1lbW9yeSBzd2FwYWNjb3VudD0xIgogICAgCgotIHBhdGg6ICcvb3B0L2Jpbi9zZXR1cCcKICBwZXJtaXNzaW9uczogJzA3NTUnCiAgY29udGVudDogfC0KICAgICMhL2Jpbi9iYXNoCiAgICBzZXQgLXhldW8gcGlwZWZhaWwKICAgIGlmIHN5c3RlbWN0bCBpcy1hY3RpdmUgdWZ3OyB0aGVuIHN5c3RlbWN0bCBzdG9wIHVmdzsgZmkKICAgIHN5c3RlbWN0bCBtYXNrIHVmdwogICAgc3lzdGVtY3RsIHJlc3RhcnQgc3lzdGVtZC1tb2R1bGVzLWxvYWQuc2VydmljZQogICAgc3lzY3RsIC0tc3lzdGVtCiAgICBzZWQgLWkub3JpZyAnLy4qc3dhcC4qL2QnIC9ldGMvZnN0YWIKICAgIHN3YXBvZmYgLWEKICAgIAogICAgYXB0LWdldCB1cGRhdGUKICAgIAogICAgREVCSUFOX0ZST05URU5EPW5vbmludGVyYWN0aXZlIGFwdC1nZXQgLW8gRHBrZzo6T3B0aW9uczo6PSItLWZvcmNlLWNvbmZkZWYiIC1vIERwa2c6Ok9wdGlvbnM6Oj0iLS1mb3JjZS1jb25mb2xkIiBpbnN0YWxsIC15IFwKICAgICAgY3VybCBcCiAgICAgIGNhLWNlcnRpZmljYXRlcyBcCiAgICAgIGNlcGgtY29tbW9uIFwKICAgICAgY2lmcy11dGlscyBcCiAgICAgIGNvbm50cmFjayBcCiAgICAgIGUyZnNwcm9ncyBcCiAgICAgIGVidGFibGVzIFwKICAgICAgZXRodG9vbCBcCiAgICAgIGdsdXN0ZXJmcy1jbGllbnQgXAogICAgICBpcHRhYmxlcyBcCiAgICAgIGpxIFwKICAgICAga21vZCBcCiAgICAgIG9wZW5zc2gtY2xpZW50IFwKICAgICAgbmZzLWNvbW1vbiBcCiAgICAgIHNvY2F0IFwKICAgICAgdXRpbC1saW51eCBcCiAgICAgIGlwdnNhZG0KICAgIGFwdC1nZXQgdXBkYXRlCiAgICBhcHQtZ2V0IGluc3RhbGwgLXkgYXB0LXRyYW5zcG9ydC1odHRwcyBjYS1jZXJ0aWZpY2F0ZXMgY3VybCBzb2Z0d2FyZS1wcm9wZXJ0aWVzLWNvbW1vbiBsc2ItcmVsZWFzZQogICAgY3VybCAtZnNTTCBodHRwczovL2Rvd25sb2FkLmRvY2tlci5jb20vbGludXgvdWJ1bnR1L2dwZyB8IGFwdC1rZXkgYWRkIC0KICAgIGFkZC1hcHQtcmVwb3NpdG9yeSAiZGViIGh0dHBzOi8vZG93bmxvYWQuZG9ja2VyLmNvbS9saW51eC91YnVudHUgJChsc2JfcmVsZWFzZSAtY3MpIHN0YWJsZSIKICAgIAogICAgY2F0IDw8RU9GIHwgdGVlIC9ldGMvY3JpY3RsLnlhbWwKICAgIHJ1bnRpbWUtZW5kcG9pbnQ6IHVuaXg6Ly8vcnVuL2NvbnRhaW5lcmQvY29udGFpbmVyZC5zb2NrCiAgICBFT0YKICAgIAogICAgbWtkaXIgLXAgL2V0Yy9zeXN0ZW1kL3N5c3RlbS9jb250YWluZXJkLnNlcnZpY2UuZAogICAgY2F0IDw8RU9GIHwgdGVlIC9ldGMvc3lzdGVtZC9zeXN0ZW0vY29udGFpbmVyZC5zZXJ2aWNlLmQvZW52aXJvbm1lbnQuY29uZgogICAgW1NlcnZpY2VdCiAgICBSZXN0YXJ0PWFsd2F5cwogICAgRW52aXJvbm1lbnRGaWxlPS0vZXRjL2Vudmlyb25tZW50CiAgICBFT0YKICAgIAogICAgYXB0LWdldCBpbnN0YWxsIC15IC0tYWxsb3ctZG93bmdyYWRlcyBjb250YWluZXJkLmlvPTEuNCoKICAgIGFwdC1tYXJrIGhvbGQgY29udGFpbmVyZC5pbwogICAgCiAgICBzeXN0ZW1jdGwgZGFlbW9uLXJlbG9hZAogICAgc3lzdGVtY3RsIGVuYWJsZSAtLW5vdyBjb250YWluZXJkCiAgICBvcHRfYmluPS9vcHQvYmluCiAgICBjbmlfYmluX2Rpcj0vb3B0L2NuaS9iaW4KICAgIG1rZGlyIC1wIC9ldGMvY25pL25ldC5kIC9ldGMva3ViZXJuZXRlcy9keW5hbWljLWNvbmZpZy1kaXIgL2V0Yy9rdWJlcm5ldGVzL21hbmlmZXN0cyAiJG9wdF9iaW4iICIkY25pX2Jpbl9kaXIiCiAgICBhcmNoPSR7SE9TVF9BUkNILX0KICAgIGlmIFsgLXogIiRhcmNoIiBdCiAgICB0aGVuCiAgICBjYXNlICQodW5hbWUgLW0pIGluCiAgICB4ODZfNjQpCiAgICAgICAgYXJjaD0iYW1kNjQiCiAgICAgICAgOzsKICAgIGFhcmNoNjQpCiAgICAgICAgYXJjaD0iYXJtNjQiCiAgICAgICAgOzsKICAgICopCiAgICAgICAgZWNobyAidW5zdXBwb3J0ZWQgQ1BVIGFyY2hpdGVjdHVyZSwgZXhpdGluZyIKICAgICAgICBleGl0IDEKICAgICAgICA7OwogICAgZXNhYwogICAgZmkKICAgIENOSV9WRVJTSU9OPSIke0NOSV9WRVJTSU9OOi12MC44Ljd9IgogICAgY25pX2Jhc2VfdXJsPSJodHRwczovL2dpdGh1Yi5jb20vY29udGFpbmVybmV0d29ya2luZy9wbHVnaW5zL3JlbGVhc2VzL2Rvd25sb2FkLyRDTklfVkVSU0lPTiIKICAgIGNuaV9maWxlbmFtZT0iY25pLXBsdWdpbnMtbGludXgtJGFyY2gtJENOSV9WRVJTSU9OLnRneiIKICAgIGN1cmwgLUxmbyAiJGNuaV9iaW5fZGlyLyRjbmlfZmlsZW5hbWUiICIkY25pX2Jhc2VfdXJsLyRjbmlfZmlsZW5hbWUiCiAgICBjbmlfc3VtPSQoY3VybCAtTGYgIiRjbmlfYmFzZV91cmwvJGNuaV9maWxlbmFtZS5zaGEyNTYiKQogICAgY2QgIiRjbmlfYmluX2RpciIKICAgIHNoYTI1NnN1bSAtYyA8PDwiJGNuaV9zdW0iCiAgICB0YXIgeHZmICIkY25pX2ZpbGVuYW1lIgogICAgcm0gLWYgIiRjbmlfZmlsZW5hbWUiCiAgICBjZCAtCiAgICBLVUJFX1ZFUlNJT049IiR7S1VCRV9WRVJTSU9OOi12MS4yMi4xfSIKICAgIGt1YmVfZGlyPSIkb3B0X2Jpbi9rdWJlcm5ldGVzLSRLVUJFX1ZFUlNJT04iCiAgICBrdWJlX2Jhc2VfdXJsPSJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20va3ViZXJuZXRlcy1yZWxlYXNlL3JlbGVhc2UvJEtVQkVfVkVSU0lPTi9iaW4vbGludXgvJGFyY2giCiAgICBrdWJlX3N1bV9maWxlPSIka3ViZV9kaXIvc2hhMjU2IgogICAgbWtkaXIgLXAgIiRrdWJlX2RpciIKICAgIDogPiIka3ViZV9zdW1fZmlsZSIKICAgIAogICAgZm9yIGJpbiBpbiBrdWJlbGV0IGt1YmVhZG0ga3ViZWN0bDsgZG8KICAgICAgICBjdXJsIC1MZm8gIiRrdWJlX2Rpci8kYmluIiAiJGt1YmVfYmFzZV91cmwvJGJpbiIKICAgICAgICBjaG1vZCAreCAiJGt1YmVfZGlyLyRiaW4iCiAgICAgICAgc3VtPSQoY3VybCAtTGYgIiRrdWJlX2Jhc2VfdXJsLyRiaW4uc2hhMjU2IikKICAgICAgICBlY2hvICIkc3VtICAka3ViZV9kaXIvJGJpbiIgPj4iJGt1YmVfc3VtX2ZpbGUiCiAgICBkb25lCiAgICBzaGEyNTZzdW0gLWMgIiRrdWJlX3N1bV9maWxlIgogICAgCiAgICBmb3IgYmluIGluIGt1YmVsZXQga3ViZWFkbSBrdWJlY3RsOyBkbwogICAgICAgIGxuIC1zZiAiJGt1YmVfZGlyLyRiaW4iICIkb3B0X2JpbiIvJGJpbgogICAgZG9uZQogICAgCiAgICBpZiBbWyAhIC14IC9vcHQvYmluL2hlYWx0aC1tb25pdG9yLnNoIF1dOyB0aGVuCiAgICAgICAgY3VybCAtTGZvIC9vcHQvYmluL2hlYWx0aC1tb25pdG9yLnNoIGh0dHBzOi8vcmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbS9rdWJlcm1hdGljL21hY2hpbmUtY29udHJvbGxlci83OTY3YTBhZjJiNzVmMjlhZDJhYjIyN2VlYWEyNmVhN2IwZjJmYmRlL3BrZy91c2VyZGF0YS9zY3JpcHRzL2hlYWx0aC1tb25pdG9yLnNoCiAgICAgICAgY2htb2QgK3ggL29wdC9iaW4vaGVhbHRoLW1vbml0b3Iuc2gKICAgIGZpCiAgICAKICAgICMgc2V0IGt1YmVsZXQgbm9kZWlwIGVudmlyb25tZW50IHZhcmlhYmxlCiAgICAvb3B0L2Jpbi9zZXR1cF9uZXRfZW52LnNoCiAgICAKICAgIHN5c3RlbWN0bCBlbmFibGUgLS1ub3cga3ViZWxldAogICAgc3lzdGVtY3RsIGVuYWJsZSAtLW5vdyAtLW5vLWJsb2NrIGt1YmVsZXQtaGVhbHRoY2hlY2suc2VydmljZQogICAgCgotIHBhdGg6ICcvb3B0L2Jpbi9zdXBlcnZpc2Uuc2gnCiAgcGVybWlzc2lvbnM6ICcwNzU1JwogIGNvbnRlbnQ6IHwtCiAgICAjIS9iaW4vYmFzaAogICAgc2V0IC14ZXVvIHBpcGVmYWlsCiAgICB3aGlsZSAhICIkQCI7IGRvCiAgICAgIHNsZWVwIDEKICAgIGRvbmUKICAgIAoKLSBwYXRoOiAnL2V0Yy9zeXN0ZW1kL3N5c3RlbS9rdWJlbGV0LnNlcnZpY2UnCiAgY29udGVudDogfC0KICAgIFtVbml0XQogICAgQWZ0ZXI9Y29udGFpbmVyZC5zZXJ2aWNlCiAgICBSZXF1aXJlcz1jb250YWluZXJkLnNlcnZpY2UKICAgIAogICAgRGVzY3JpcHRpb249a3ViZWxldDogVGhlIEt1YmVybmV0ZXMgTm9kZSBBZ2VudAogICAgRG9jdW1lbnRhdGlvbj1odHRwczovL2t1YmVybmV0ZXMuaW8vZG9jcy9ob21lLwogICAgCiAgICBbU2VydmljZV0KICAgIFJlc3RhcnQ9YWx3YXlzCiAgICBTdGFydExpbWl0SW50ZXJ2YWw9MAogICAgUmVzdGFydFNlYz0xMAogICAgQ1BVQWNjb3VudGluZz10cnVlCiAgICBNZW1vcnlBY2NvdW50aW5nPXRydWUKICAgIAogICAgRW52aXJvbm1lbnQ9IlBBVEg9L29wdC9iaW46L2JpbjovdXNyL2xvY2FsL3NiaW46L3Vzci9sb2NhbC9iaW46L3Vzci9zYmluOi91c3IvYmluOi9zYmluLyIKICAgIEVudmlyb25tZW50RmlsZT0tL2V0Yy9lbnZpcm9ubWVudAogICAgCiAgICBFeGVjU3RhcnRQcmU9L2Jpbi9iYXNoIC9vcHQvbG9hZC1rZXJuZWwtbW9kdWxlcy5zaAogICAgRXhlY1N0YXJ0UHJlPS9iaW4vYmFzaCAvb3B0L2Jpbi9zZXR1cF9uZXRfZW52LnNoCiAgICBFeGVjU3RhcnQ9L29wdC9iaW4va3ViZWxldCAkS1VCRUxFVF9FWFRSQV9BUkdTIFwKICAgICAgLS1ib290c3RyYXAta3ViZWNvbmZpZz0vZXRjL2t1YmVybmV0ZXMvYm9vdHN0cmFwLWt1YmVsZXQuY29uZiBcCiAgICAgIC0ta3ViZWNvbmZpZz0vdmFyL2xpYi9rdWJlbGV0L2t1YmVjb25maWcgXAogICAgICAtLWNvbmZpZz0vZXRjL2t1YmVybmV0ZXMva3ViZWxldC5jb25mIFwKICAgICAgLS1uZXR3b3JrLXBsdWdpbj1jbmkgXAogICAgICAtLWNlcnQtZGlyPS9ldGMva3ViZXJuZXRlcy9wa2kgXAogICAgICAtLWNsb3VkLXByb3ZpZGVyPWF3cyBcCiAgICAgIC0tY2xvdWQtY29uZmlnPS9ldGMva3ViZXJuZXRlcy9jbG91ZC1jb25maWcgXAogICAgICAtLWR5bmFtaWMtY29uZmlnLWRpcj0vZXRjL2t1YmVybmV0ZXMvZHluYW1pYy1jb25maWctZGlyIFwKICAgICAgLS1mZWF0dXJlLWdhdGVzPUR5bmFtaWNLdWJlbGV0Q29uZmlnPXRydWUgXAogICAgICAtLWV4aXQtb24tbG9jay1jb250ZW50aW9uIFwKICAgICAgLS1sb2NrLWZpbGU9L3RtcC9rdWJlbGV0LmxvY2sgXAogICAgICAtLWNvbnRhaW5lci1ydW50aW1lPXJlbW90ZSBcCiAgICAgIC0tY29udGFpbmVyLXJ1bnRpbWUtZW5kcG9pbnQ9dW5peDovLy9ydW4vY29udGFpbmVyZC9jb250YWluZXJkLnNvY2sgXAogICAgICAtLW5vZGUtaXAgJHtLVUJFTEVUX05PREVfSVB9CiAgICAKICAgIFtJbnN0YWxsXQogICAgV2FudGVkQnk9bXVsdGktdXNlci50YXJnZXQKICAgIAoKLSBwYXRoOiAnL2V0Yy9zeXN0ZW1kL3N5c3RlbS9rdWJlbGV0LnNlcnZpY2UuZC9leHRyYXMuY29uZicKICBjb250ZW50OiB8LQogICAgW1NlcnZpY2VdCiAgICBFbnZpcm9ubWVudD0iS1VCRUxFVF9FWFRSQV9BUkdTPS0tcmVzb2x2LWNvbmY9L3J1bi9zeXN0ZW1kL3Jlc29sdmUvcmVzb2x2LmNvbmYiCiAgICAKCi0gcGF0aDogJy9ldGMva3ViZXJuZXRlcy9jbG91ZC1jb25maWcnCiAgcGVybWlzc2lvbnM6ICcwNjAwJwogIGNvbnRlbnQ6IHwtCiAgICBbZ2xvYmFsXQogICAgWm9uZT0iIgogICAgVlBDPSIiCiAgICBTdWJuZXRJRD0idGVzdC1zdWJuZXQiCiAgICAKICAgIAoKLSBwYXRoOiAnL29wdC9iaW4vc2V0dXBfbmV0X2Vudi5zaCcKICBwZXJtaXNzaW9uczogJzA3NTUnCiAgY29udGVudDogfC0KICAgICMhL3Vzci9iaW4vZW52IGJhc2gKICAgIGVjaG9kYXRlKCkgewogICAgICBlY2hvICJbJChkYXRlIC1JcyldIiAiJEAiCiAgICB9CiAgICAKICAgICMgZ2V0IHRoZSBkZWZhdWx0IGludGVyZmFjZSBJUCBhZGRyZXNzCiAgICBERUZBVUxUX0lGQ19JUD0kKGlwIC1vICByb3V0ZSBnZXQgMSB8IGdyZXAgLW9QICJzcmMgXEtcUysiKQogICAgCiAgICBpZiBbIC16ICIke0RFRkFVTFRfSUZDX0lQfSIgXQogICAgdGhlbgogICAgICBlY2hvZGF0ZSAiRmFpbGVkIHRvIGdldCBJUCBhZGRyZXNzIGZvciB0aGUgZGVmYXVsdCByb3V0ZSBpbnRlcmZhY2UiCiAgICAgIGV4aXQgMQogICAgZmkKICAgIAogICAgICMgZ2V0IHRoZSBmdWxsIGhvc3RuYW1lCiAgICBGVUxMX0hPU1ROQU1FPSQoaG9zdG5hbWUgLWYpCiAgICAKICAgICMgd3JpdGUgdGhlIG5vZGVpcF9lbnYgZmlsZQogICAgIyB3ZSBuZWVkIHRoZSBsaW5lIGJlbG93IGJlY2F1c2UgZmxhdGNhciBoYXMgdGhlIHNhbWUgc3RyaW5nICJjb3Jlb3MiIGluIHRoYXQgZmlsZQogICAgaWYgZ3JlcCAtcSBjb3Jlb3MgL2V0Yy9vcy1yZWxlYXNlCiAgICB0aGVuCiAgICAgIGVjaG8gIktVQkVMRVRfTk9ERV9JUD0ke0RFRkFVTFRfSUZDX0lQfVxuS1VCRUxFVF9IT1NUTkFNRT0ke0ZVTExfSE9TVE5BTUV9IiA+IC9ldGMva3ViZXJuZXRlcy9ub2RlaXAuY29uZgogICAgZWxpZiBbICEgLWQgL2V0Yy9zeXN0ZW1kL3N5c3RlbS9rdWJlbGV0LnNlcnZpY2UuZCBdCiAgICB0aGVuCiAgICAgIGVjaG9kYXRlICJDYW4ndCBmaW5kIGt1YmVsZXQgc2VydmljZSBleHRyYXMgZGlyZWN0b3J5IgogICAgICBleGl0IDEKICAgIGVsc2UKICAgICAgZWNobyAtZSAiW1NlcnZpY2VdXG5FbnZpcm9ubWVudD1cIktVQkVMRVRfTk9ERV9JUD0ke0RFRkFVTFRfSUZDX0lQfVwiXG5FbnZpcm9ubWVudD1cIktVQkVMRVRfSE9TVE5BTUU9JHtGVUxMX0hPU1ROQU1FfVwiIiA+IC9ldGMvc3lzdGVtZC9zeXN0ZW0va3ViZWxldC5zZXJ2aWNlLmQvbm9kZWlwLmNvbmYKICAgIGZpCiAgICAKCi0gcGF0aDogJy9ldGMva3ViZXJuZXRlcy9wa2kvY2EuY3J0JwogIGNvbnRlbnQ6IHwtCiAgICAtLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KICAgIE1JSUVXakNDQTBLZ0F3SUJBZ0lKQUxmUmxXc0k4WVFITUEwR0NTcUdTSWIzRFFFQkJRVUFNSHN4Q3pBSkJnTlYKICAgIEJBWVRBbFZUTVFzd0NRWURWUVFJRXdKRFFURVdNQlFHQTFVRUJ4TU5VMkZ1SUVaeVlXNWphWE5qYnpFVU1CSUcKICAgIEExVUVDaE1MUW5KaFpHWnBkSHBwYm1NeEVqQVFCZ05WQkFNVENXeHZZMkZzYUc5emRERWRNQnNHQ1NxR1NJYjMKICAgIERRRUpBUllPWW5KaFpFQmtZVzVuWVM1amIyMHdIaGNOTVRRd056RTFNakEwTmpBMVdoY05NVGN3TlRBME1qQTAKICAgIE5qQTFXakI3TVFzd0NRWURWUVFHRXdKVlV6RUxNQWtHQTFVRUNCTUNRMEV4RmpBVUJnTlZCQWNURFZOaGJpQkcKICAgIGNtRnVZMmx6WTI4eEZEQVNCZ05WQkFvVEMwSnlZV1JtYVhSNmFXNWpNUkl3RUFZRFZRUURFd2xzYjJOaGJHaHYKICAgIGMzUXhIVEFiQmdrcWhraUc5dzBCQ1FFV0RtSnlZV1JBWkdGdVoyRXVZMjl0TUlJQklqQU5CZ2txaGtpRzl3MEIKICAgIEFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXQ1ZkFqcDRmVGNla1dVVGZ6c3Awa3lpaDFPWWJzR0wwS1gxZVJiU1MKICAgIFI4T2QwKzlRNjJIeW55K0dGd01UYjRBL0tVOG1zc29IdmNjZVNBQWJ3ZmJ4RksvK3M1MVRvYnFVbk9SWnJPb1QKICAgIFpqa1V5Z2J5WERTSzk5WUJiY1IxUGlwOHZ3TVRtNFhLdUx0Q2lnZUJCZGpqQVFkZ1VPMjhMRU5HbHNNbm1lWWsKICAgIEpmT0RWR25WbXI1THRiOUFOQThJS3lUZnNuSEo0aU9DUy9QbFBiVWoycTdZbm9WTHBvc1VCTWxnVWIvQ3lrWDMKICAgIG1Pb0xiNHlKSlF5QS9pU1Q2WnhpSUVqMzZENHlXWjVsZzdZSmwrVWlpQlFIR0NuUGRHeWlwcVYwNmV4MGhlWVcKICAgIGNhaVc4TFdaU1VROTNqUStXVkNIOGhUN0RRTzFkbXN2VW1YbHEvSmVBbHdRL1FJREFRQUJvNEhnTUlIZE1CMEcKICAgIEExVWREZ1FXQkJSY0FST3RoUzRQNFU3dlRmakJ5QzU2OVI3RTZEQ0JyUVlEVlIwakJJR2xNSUdpZ0JSY0FST3QKICAgIGhTNFA0VTd2VGZqQnlDNTY5UjdFNktGL3BIMHdlekVMTUFrR0ExVUVCaE1DVlZNeEN6QUpCZ05WQkFnVEFrTkIKICAgIE1SWXdGQVlEVlFRSEV3MVRZVzRnUm5KaGJtTnBjMk52TVJRd0VnWURWUVFLRXd0Q2NtRmtabWwwZW1sdVl6RVMKICAgIE1CQUdBMVVFQXhNSmJHOWpZV3hvYjNOME1SMHdHd1lKS29aSWh2Y05BUWtCRmc1aWNtRmtRR1JoYm1kaExtTnYKICAgIGJZSUpBTGZSbFdzSThZUUhNQXdHQTFVZEV3UUZNQU1CQWY4d0RRWUpLb1pJaHZjTkFRRUZCUUFEZ2dFQkFHNmgKICAgIFU5ZjlzTkgwLzZvQmJHR3kyRVZVMFVnSVRVUUlyRldvOXJGa3JXNWsvWGtEalFtKzNsempUMGlHUjRJeEUvQW8KICAgIGVVNnNRaHVhN3dyV2VGRW40N0dMOThsbkNzSmREN29aTmhGbVE5NVRiL0xuRFVqczVZajliclAwTld6WGZZVTQKICAgIFVLMlpuSU5KUmNKcEI4aVJDYUN4RThEZGNVRjBYcUlFcTZwQTI3MnNub0xtaVhMTXZObDNrWUVkbStqZTZ2b0QKICAgIDU4U05WRVVzenR6UXlYbUpFaENwd1ZJMEE2UUNqelhqK3F2cG13M1paSGk4SndYZWk4WlpCTFRTRkJraThaN24KICAgIHNIOUJCSDM4L1N6VW1BTjRRSFNQeTFnanFtMDBPQUU4TmFZRGtoL2J6RTRkN21MR0dNV3AvV0UzS1BTdTgySEYKICAgIGtQZTZYb1NiaUxtL2t4azMyVDA9CiAgICAtLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCiAgICAKCi0gcGF0aDogJy9ldGMvc3lzdGVtZC9zeXN0ZW0vc2V0dXAuc2VydmljZScKICBwZXJtaXNzaW9uczogJzA2NDQnCiAgY29udGVudDogfC0KICAgIFtJbnN0YWxsXQogICAgV2FudGVkQnk9bXVsdGktdXNlci50YXJnZXQKICAgIAogICAgW1VuaXRdCiAgICBSZXF1aXJlcz1uZXR3b3JrLW9ubGluZS50YXJnZXQKICAgIEFmdGVyPW5ldHdvcmstb25saW5lLnRhcmdldAogICAgCiAgICBbU2VydmljZV0KICAgIFR5cGU9b25lc2hvdAogICAgUmVtYWluQWZ0ZXJFeGl0PXRydWUKICAgIEVudmlyb25tZW50RmlsZT0tL2V0Yy9lbnZpcm9ubWVudAogICAgRXhlY1N0YXJ0PS9vcHQvYmluL3N1cGVydmlzZS5zaCAvb3B0L2Jpbi9zZXR1cAogICAgCgotIHBhdGg6ICcvZXRjL3Byb2ZpbGUuZC9vcHQtYmluLXBhdGguc2gnCiAgcGVybWlzc2lvbnM6ICcwNjQ0JwogIGNvbnRlbnQ6IHwtCiAgICBleHBvcnQgUEFUSD0iL29wdC9iaW46JFBBVEgiCiAgICAKCi0gcGF0aDogJy9ldGMva3ViZXJuZXRlcy9rdWJlbGV0LmNvbmYnCiAgY29udGVudDogfC0KICAgIGFwaVZlcnNpb246IGt1YmVsZXQuY29uZmlnLms4cy5pby92MWJldGExCiAgICBraW5kOiBLdWJlbGV0Q29uZmlndXJhdGlvbgogICAgYXV0aGVudGljYXRpb246CiAgICAgIGFub255bW91czoKICAgICAgICBlbmFibGVkOiBmYWxzZQogICAgICB3ZWJob29rOgogICAgICAgIGVuYWJsZWQ6IHRydWUKICAgICAgeDUwOToKICAgICAgICBjbGllbnRDQUZpbGU6IC9ldGMva3ViZXJuZXRlcy9wa2kvY2EuY3J0CiAgICBhdXRob3JpemF0aW9uOgogICAgICBtb2RlOiBXZWJob29rCiAgICBjZ3JvdXBEcml2ZXI6IHN5c3RlbWQKICAgIGNsdXN0ZXJETlM6CiAgICAtICIxMC4wLjAuMCIKICAgIGNsdXN0ZXJEb21haW46IGNsdXN0ZXIubG9jYWwKICAgIGNvbnRhaW5lckxvZ01heFNpemU6IDEwME1pCiAgICBjb250YWluZXJMb2dNYXhGaWxlczogNQogICAgZmVhdHVyZUdhdGVzOgogICAgICBHcmFjZWZ1bE5vZGVTaHV0ZG93bjogdHJ1ZQogICAgICBJZGVudGlmeVBvZE9TOiBmYWxzZQogICAgcHJvdGVjdEtlcm5lbERlZmF1bHRzOiB0cnVlCiAgICByZWFkT25seVBvcnQ6IDAKICAgIHJvdGF0ZUNlcnRpZmljYXRlczogdHJ1ZQogICAgc2VydmVyVExTQm9vdHN0cmFwOiB0cnVlCiAgICBzdGF0aWNQb2RQYXRoOiAvZXRjL2t1YmVybmV0ZXMvbWFuaWZlc3RzCiAgICBrdWJlUmVzZXJ2ZWQ6CiAgICAgIGNwdTogMjAwbQogICAgICBlcGhlbWVyYWwtc3RvcmFnZTogMUdpCiAgICAgIG1lbW9yeTogMjAwTWkKICAgIHN5c3RlbVJlc2VydmVkOgogICAgICBjcHU6IDIwMG0KICAgICAgZXBoZW1lcmFsLXN0b3JhZ2U6IDFHaQogICAgICBtZW1vcnk6IDIwME1pCiAgICBldmljdGlvbkhhcmQ6CiAgICAgIGltYWdlZnMuYXZhaWxhYmxlOiAxNSUKICAgICAgbWVtb3J5LmF2YWlsYWJsZTogMTAwTWkKICAgICAgbm9kZWZzLmF2YWlsYWJsZTogMTAlCiAgICAgIG5vZGVmcy5pbm9kZXNGcmVlOiA1JQogICAgdGxzQ2lwaGVyU3VpdGVzOgogICAgLSBUTFNfQUVTXzEyOF9HQ01fU0hBMjU2CiAgICAtIFRMU19BRVNfMjU2X0dDTV9TSEEzODQKICAgIC0gVExTX0NIQUNIQTIwX1BPTFkxMzA1X1NIQTI1NgogICAgLSBUTFNfRUNESEVfRUNEU0FfV0lUSF9BRVNfMTI4X0dDTV9TSEEyNTYKICAgIC0gVExTX0VDREhFX0VDRFNBX1dJVEhfQUVTXzI1Nl9HQ01fU0hBMzg0CiAgICAtIFRMU19FQ0RIRV9FQ0RTQV9XSVRIX0NIQUNIQTIwX1BPTFkxMzA1CiAgICAtIFRMU19FQ0RIRV9SU0FfV0lUSF9BRVNfMTI4X0dDTV9TSEEyNTYKICAgIC0gVExTX0VDREhFX1JTQV9XSVRIX0FFU18yNTZfR0NNX1NIQTM4NAogICAgLSBUTFNfRUNESEVfUlNBX1dJVEhfQ0hBQ0hBMjBfUE9MWTEzMDUKICAgIHZvbHVtZVBsdWdpbkRpcjogL3Zhci9saWIva3ViZWxldC92b2x1bWVwbHVnaW5zCiAgICAKCi0gcGF0aDogJy9ldGMvc3lzdGVtZC9zeXN0ZW0va3ViZWxldC1oZWFsdGhjaGVjay5zZXJ2aWNlJwogIHBlcm1pc3Npb25zOiAnMDY0NCcKICBjb250ZW50OiB8LQogICAgW1VuaXRdCiAgICBSZXF1aXJlcz1rdWJlbGV0LnNlcnZpY2UKICAgIEFmdGVyPWt1YmVsZXQuc2VydmljZQogICAgCiAgICBbU2VydmljZV0KICAgIEV4ZWNTdGFydD0vb3B0L2Jpbi9oZWFsdGgtbW9uaXRvci5zaCBrdWJlbGV0CiAgICAKICAgIFtJbnN0YWxsXQogICAgV2FudGVkQnk9bXVsdGktdXNlci50YXJnZXQKICAgIAoKLSBwYXRoOiAnL2V0Yy9jb250YWluZXJkL2NvbmZpZy50b21sJwogIHBlcm1pc3Npb25zOiAnMDY0NCcKICBjb250ZW50OiB8LQogICAgdmVyc2lvbiA9IDIKICAgIAogICAgW21ldHJpY3NdCiAgICBhZGRyZXNzID0gIjEyNy4wLjAuMToxMzM4IgogICAgCiAgICBbcGx1Z2luc10KICAgIFtwbHVnaW5zLiJpby5jb250YWluZXJkLmdycGMudjEuY3JpIl0KICAgIHNhbmRib3hfaW1hZ2UgPSAiMTkyLjE2OC4xMDAuMTAwOjUwMDAva3ViZXJuZXRlcy9wYXVzZTp2My4xIgogICAgW3BsdWdpbnMuImlvLmNvbnRhaW5lcmQuZ3JwYy52MS5jcmkiLmNvbnRhaW5lcmRdCiAgICBbcGx1Z2lucy4iaW8uY29udGFpbmVyZC5ncnBjLnYxLmNyaSIuY29udGFpbmVyZC5ydW50aW1lc10KICAgIFtwbHVnaW5zLiJpby5jb250YWluZXJkLmdycGMudjEuY3JpIi5jb250YWluZXJkLnJ1bnRpbWVzLnJ1bmNdCiAgICBydW50aW1lX3R5cGUgPSAiaW8uY29udGFpbmVyZC5ydW5jLnYyIgogICAgW3BsdWdpbnMuImlvLmNvbnRhaW5lcmQuZ3JwYy52MS5jcmkiLmNvbnRhaW5lcmQucnVudGltZXMucnVuYy5vcHRpb25zXQogICAgU3lzdGVtZENncm91cCA9IHRydWUKICAgIFtwbHVnaW5zLiJpby5jb250YWluZXJkLmdycGMudjEuY3JpIi5yZWdpc3RyeV0KICAgIFtwbHVnaW5zLiJpby5jb250YWluZXJkLmdycGMudjEuY3JpIi5yZWdpc3RyeS5taXJyb3JzXQogICAgW3BsdWdpbnMuImlvLmNvbnRhaW5lcmQuZ3JwYy52MS5jcmkiLnJlZ2lzdHJ5Lm1pcnJvcnMuImRvY2tlci5pbyJdCiAgICBlbmRwb2ludCA9IFsiaHR0cHM6Ly9yZWdpc3RyeS5kb2NrZXItY24uY29tIl0KICAgIFtwbHVnaW5zLiJpby5jb250YWluZXJkLmdycGMudjEuY3JpIi5yZWdpc3RyeS5jb25maWdzXQogICAgW3BsdWdpbnMuImlvLmNvbnRhaW5lcmQuZ3JwYy52MS5jcmkiLnJlZ2lzdHJ5LmNvbmZpZ3MuIjEwLjAuMC4xOjUwMDAiXQogICAgW3BsdWdpbnMuImlvLmNvbnRhaW5lcmQuZ3JwYy52MS5jcmkiLnJlZ2lzdHJ5LmNvbmZpZ3MuIjEwLjAuMC4xOjUwMDAiLnRsc10KICAgIGluc2VjdXJlX3NraXBfdmVyaWZ5ID0gdHJ1ZQogICAgW3BsdWdpbnMuImlvLmNvbnRhaW5lcmQuZ3JwYy52MS5jcmkiLnJlZ2lzdHJ5LmNvbmZpZ3MuIjE5Mi4xNjguMTAwLjEwMDo1MDAwIl0KICAgIFtwbHVnaW5zLiJpby5jb250YWluZXJkLmdycGMudjEuY3JpIi5yZWdpc3RyeS5jb25maWdzLiIxOTIuMTY4LjEwMC4xMDA6NTAwMCIudGxzXQogICAgaW5zZWN1cmVfc2tpcF92ZXJpZnkgPSB0cnVlCiAgICAKICAgIAoKYm9vdGNtZDoKLSBlY2hvIGhlbGxvCi0gZWNobyB3b3JsZAoKcmhfc3Vic2NyaXB0aW9uOgogICAgcGFzc3dvcmQ6IHBhc3N3b3JkCiAgICB1c2VybmFtZTogdXNlcm5hbWU= immutable: true kind: Secret metadata: creationTimestamp: null - name: ubuntu-20.04-aws-osc-provisioning + name: ubuntu-aws-kube-system-osc-provisioning namespace: cloud-init-settings resourceVersion: "1" +type: Opaque diff --git a/pkg/controllers/osc/testdata/secret-ubuntu-20.04-aws-docker.yaml b/pkg/controllers/osc/testdata/secret-ubuntu-aws-docker.yaml similarity index 97% rename from pkg/controllers/osc/testdata/secret-ubuntu-20.04-aws-docker.yaml rename to pkg/controllers/osc/testdata/secret-ubuntu-aws-docker.yaml index d516d11c..35c81e6a 100644 --- a/pkg/controllers/osc/testdata/secret-ubuntu-20.04-aws-docker.yaml +++ b/pkg/controllers/osc/testdata/secret-ubuntu-aws-docker.yaml @@ -1,10 +1,11 @@ apiVersion: v1 data: - cloud-config: I2Nsb3VkLWNvbmZpZwoKc3NoX3B3YXV0aDogbm8Kc3NoX2F1dGhvcml6ZWRfa2V5czoKLSAnc3NoLXJzYSBBQUFBQjNOemFDMXljMkVBQUFBREFRQUJBQUFDQVFEZE9JaFltekNLNURTVkx1M2MnCndyaXRlX2ZpbGVzOgotIHBhdGg6ICcvZXRjL3N5c3RlbWQvam91cm5hbGQuY29uZi5kL21heF9kaXNrX3VzZS5jb25mJwogIGNvbnRlbnQ6IHwtCiAgICBbSm91cm5hbF0KICAgIFN5c3RlbU1heFVzZT01RwogICAgCgotIHBhdGg6ICcvb3B0L2xvYWQta2VybmVsLW1vZHVsZXMuc2gnCiAgcGVybWlzc2lvbnM6ICcwNzU1JwogIGNvbnRlbnQ6IHwtCiAgICAjIS91c3IvYmluL2VudiBiYXNoCiAgICBzZXQgLWV1byBwaXBlZmFpbAogICAgCiAgICBtb2Rwcm9iZSBpcF92cwogICAgbW9kcHJvYmUgaXBfdnNfcnIKICAgIG1vZHByb2JlIGlwX3ZzX3dycgogICAgbW9kcHJvYmUgaXBfdnNfc2gKICAgIAogICAgaWYgbW9kaW5mbyBuZl9jb25udHJhY2tfaXB2NCAmPiAvZGV2L251bGw7IHRoZW4KICAgICAgbW9kcHJvYmUgbmZfY29ubnRyYWNrX2lwdjQKICAgIGVsc2UKICAgICAgbW9kcHJvYmUgbmZfY29ubnRyYWNrCiAgICBmaQogICAgCgotIHBhdGg6ICcvZXRjL3N5c2N0bC5kL2s4cy5jb25mJwogIGNvbnRlbnQ6IHwtCiAgICBuZXQuYnJpZGdlLmJyaWRnZS1uZi1jYWxsLWlwNnRhYmxlcyA9IDEKICAgIG5ldC5icmlkZ2UuYnJpZGdlLW5mLWNhbGwtaXB0YWJsZXMgPSAxCiAgICBrZXJuZWwucGFuaWNfb25fb29wcyA9IDEKICAgIGtlcm5lbC5wYW5pYyA9IDEwCiAgICBuZXQuaXB2NC5pcF9mb3J3YXJkID0gMQogICAgdm0ub3ZlcmNvbW1pdF9tZW1vcnkgPSAxCiAgICBmcy5pbm90aWZ5Lm1heF91c2VyX3dhdGNoZXMgPSAxMDQ4NTc2CiAgICAKCi0gcGF0aDogJy9ldGMvZGVmYXVsdC9ncnViLmQvNjAtc3dhcC1hY2NvdW50aW5nLmNmZycKICBjb250ZW50OiB8LQogICAgIyBBZGRlZCBieSBrdWJlcm1hdGljIG1hY2hpbmUtY29udHJvbGxlcgogICAgIyBFbmFibGUgY2dyb3VwcyBtZW1vcnkgYW5kIHN3YXAgYWNjb3VudGluZwogICAgR1JVQl9DTURMSU5FX0xJTlVYPSJjZ3JvdXBfZW5hYmxlPW1lbW9yeSBzd2FwYWNjb3VudD0xIgogICAgCgotIHBhdGg6ICcvb3B0L2Jpbi9zZXR1cCcKICBwZXJtaXNzaW9uczogJzA3NTUnCiAgY29udGVudDogfC0KICAgICMhL2Jpbi9iYXNoCiAgICBzZXQgLXhldW8gcGlwZWZhaWwKICAgIGlmIHN5c3RlbWN0bCBpcy1hY3RpdmUgdWZ3OyB0aGVuIHN5c3RlbWN0bCBzdG9wIHVmdzsgZmkKICAgIHN5c3RlbWN0bCBtYXNrIHVmdwogICAgc3lzdGVtY3RsIHJlc3RhcnQgc3lzdGVtZC1tb2R1bGVzLWxvYWQuc2VydmljZQogICAgc3lzY3RsIC0tc3lzdGVtCiAgICBzZWQgLWkub3JpZyAnLy4qc3dhcC4qL2QnIC9ldGMvZnN0YWIKICAgIHN3YXBvZmYgLWEKICAgIAogICAgYXB0LWdldCB1cGRhdGUKICAgIAogICAgREVCSUFOX0ZST05URU5EPW5vbmludGVyYWN0aXZlIGFwdC1nZXQgLW8gRHBrZzo6T3B0aW9uczo6PSItLWZvcmNlLWNvbmZkZWYiIC1vIERwa2c6Ok9wdGlvbnM6Oj0iLS1mb3JjZS1jb25mb2xkIiBpbnN0YWxsIC15IFwKICAgICAgY3VybCBcCiAgICAgIGNhLWNlcnRpZmljYXRlcyBcCiAgICAgIGNlcGgtY29tbW9uIFwKICAgICAgY2lmcy11dGlscyBcCiAgICAgIGNvbm50cmFjayBcCiAgICAgIGUyZnNwcm9ncyBcCiAgICAgIGVidGFibGVzIFwKICAgICAgZXRodG9vbCBcCiAgICAgIGdsdXN0ZXJmcy1jbGllbnQgXAogICAgICBpcHRhYmxlcyBcCiAgICAgIGpxIFwKICAgICAga21vZCBcCiAgICAgIG9wZW5zc2gtY2xpZW50IFwKICAgICAgbmZzLWNvbW1vbiBcCiAgICAgIHNvY2F0IFwKICAgICAgdXRpbC1saW51eCBcCiAgICAgIGlwdnNhZG0KICAgIGFwdC1nZXQgdXBkYXRlCiAgICBhcHQtZ2V0IGluc3RhbGwgLXkgYXB0LXRyYW5zcG9ydC1odHRwcyBjYS1jZXJ0aWZpY2F0ZXMgY3VybCBzb2Z0d2FyZS1wcm9wZXJ0aWVzLWNvbW1vbiBsc2ItcmVsZWFzZQogICAgY3VybCAtZnNTTCBodHRwczovL2Rvd25sb2FkLmRvY2tlci5jb20vbGludXgvdWJ1bnR1L2dwZyB8IGFwdC1rZXkgYWRkIC0KICAgIGFkZC1hcHQtcmVwb3NpdG9yeSAiZGViIGh0dHBzOi8vZG93bmxvYWQuZG9ja2VyLmNvbS9saW51eC91YnVudHUgJChsc2JfcmVsZWFzZSAtY3MpIHN0YWJsZSIKICAgIAogICAgbWtkaXIgLXAgL2V0Yy9zeXN0ZW1kL3N5c3RlbS9jb250YWluZXJkLnNlcnZpY2UuZCAvZXRjL3N5c3RlbWQvc3lzdGVtL2RvY2tlci5zZXJ2aWNlLmQKICAgIAogICAgY2F0IDw8RU9GIHwgdGVlIC9ldGMvc3lzdGVtZC9zeXN0ZW0vY29udGFpbmVyZC5zZXJ2aWNlLmQvZW52aXJvbm1lbnQuY29uZiAvZXRjL3N5c3RlbWQvc3lzdGVtL2RvY2tlci5zZXJ2aWNlLmQvZW52aXJvbm1lbnQuY29uZgogICAgW1NlcnZpY2VdCiAgICBSZXN0YXJ0PWFsd2F5cwogICAgRW52aXJvbm1lbnRGaWxlPS0vZXRjL2Vudmlyb25tZW50CiAgICBFT0YKICAgIAogICAgYXB0LWdldCBpbnN0YWxsIC15IFwKICAgICAgICBjb250YWluZXJkLmlvPTEuNC4zKiBcCiAgICAgICAgZG9ja2VyLWNlPTU6MTkuMDMuMTMqIFwKICAgICAgICBkb2NrZXItY2UtY2xpPTU6MTkuMDMuMTMqCiAgICBhcHQtbWFyayBob2xkIGRvY2tlci1jZSBkb2NrZXItY2UtY2xpIGNvbnRhaW5lcmQuaW8KICAgIAogICAgc3lzdGVtY3RsIGRhZW1vbi1yZWxvYWQKICAgIHN5c3RlbWN0bCBlbmFibGUgLS1ub3cgZG9ja2VyCiAgICBvcHRfYmluPS9vcHQvYmluCiAgICBjbmlfYmluX2Rpcj0vb3B0L2NuaS9iaW4KICAgIG1rZGlyIC1wIC9ldGMvY25pL25ldC5kIC9ldGMva3ViZXJuZXRlcy9keW5hbWljLWNvbmZpZy1kaXIgL2V0Yy9rdWJlcm5ldGVzL21hbmlmZXN0cyAiJG9wdF9iaW4iICIkY25pX2Jpbl9kaXIiCiAgICBhcmNoPSR7SE9TVF9BUkNILX0KICAgIGlmIFsgLXogIiRhcmNoIiBdCiAgICB0aGVuCiAgICBjYXNlICQodW5hbWUgLW0pIGluCiAgICB4ODZfNjQpCiAgICAgICAgYXJjaD0iYW1kNjQiCiAgICAgICAgOzsKICAgIGFhcmNoNjQpCiAgICAgICAgYXJjaD0iYXJtNjQiCiAgICAgICAgOzsKICAgICopCiAgICAgICAgZWNobyAidW5zdXBwb3J0ZWQgQ1BVIGFyY2hpdGVjdHVyZSwgZXhpdGluZyIKICAgICAgICBleGl0IDEKICAgICAgICA7OwogICAgZXNhYwogICAgZmkKICAgIENOSV9WRVJTSU9OPSIke0NOSV9WRVJTSU9OOi12MC44Ljd9IgogICAgY25pX2Jhc2VfdXJsPSJodHRwczovL2dpdGh1Yi5jb20vY29udGFpbmVybmV0d29ya2luZy9wbHVnaW5zL3JlbGVhc2VzL2Rvd25sb2FkLyRDTklfVkVSU0lPTiIKICAgIGNuaV9maWxlbmFtZT0iY25pLXBsdWdpbnMtbGludXgtJGFyY2gtJENOSV9WRVJTSU9OLnRneiIKICAgIGN1cmwgLUxmbyAiJGNuaV9iaW5fZGlyLyRjbmlfZmlsZW5hbWUiICIkY25pX2Jhc2VfdXJsLyRjbmlfZmlsZW5hbWUiCiAgICBjbmlfc3VtPSQoY3VybCAtTGYgIiRjbmlfYmFzZV91cmwvJGNuaV9maWxlbmFtZS5zaGEyNTYiKQogICAgY2QgIiRjbmlfYmluX2RpciIKICAgIHNoYTI1NnN1bSAtYyA8PDwiJGNuaV9zdW0iCiAgICB0YXIgeHZmICIkY25pX2ZpbGVuYW1lIgogICAgcm0gLWYgIiRjbmlfZmlsZW5hbWUiCiAgICBjZCAtCiAgICBLVUJFX1ZFUlNJT049IiR7S1VCRV9WRVJTSU9OOi12MS4yMi4xfSIKICAgIGt1YmVfZGlyPSIkb3B0X2Jpbi9rdWJlcm5ldGVzLSRLVUJFX1ZFUlNJT04iCiAgICBrdWJlX2Jhc2VfdXJsPSJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20va3ViZXJuZXRlcy1yZWxlYXNlL3JlbGVhc2UvJEtVQkVfVkVSU0lPTi9iaW4vbGludXgvJGFyY2giCiAgICBrdWJlX3N1bV9maWxlPSIka3ViZV9kaXIvc2hhMjU2IgogICAgbWtkaXIgLXAgIiRrdWJlX2RpciIKICAgIDogPiIka3ViZV9zdW1fZmlsZSIKICAgIAogICAgZm9yIGJpbiBpbiBrdWJlbGV0IGt1YmVhZG0ga3ViZWN0bDsgZG8KICAgICAgICBjdXJsIC1MZm8gIiRrdWJlX2Rpci8kYmluIiAiJGt1YmVfYmFzZV91cmwvJGJpbiIKICAgICAgICBjaG1vZCAreCAiJGt1YmVfZGlyLyRiaW4iCiAgICAgICAgc3VtPSQoY3VybCAtTGYgIiRrdWJlX2Jhc2VfdXJsLyRiaW4uc2hhMjU2IikKICAgICAgICBlY2hvICIkc3VtICAka3ViZV9kaXIvJGJpbiIgPj4iJGt1YmVfc3VtX2ZpbGUiCiAgICBkb25lCiAgICBzaGEyNTZzdW0gLWMgIiRrdWJlX3N1bV9maWxlIgogICAgCiAgICBmb3IgYmluIGluIGt1YmVsZXQga3ViZWFkbSBrdWJlY3RsOyBkbwogICAgICAgIGxuIC1zZiAiJGt1YmVfZGlyLyRiaW4iICIkb3B0X2JpbiIvJGJpbgogICAgZG9uZQogICAgCiAgICBpZiBbWyAhIC14IC9vcHQvYmluL2hlYWx0aC1tb25pdG9yLnNoIF1dOyB0aGVuCiAgICAgICAgY3VybCAtTGZvIC9vcHQvYmluL2hlYWx0aC1tb25pdG9yLnNoIGh0dHBzOi8vcmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbS9rdWJlcm1hdGljL21hY2hpbmUtY29udHJvbGxlci83OTY3YTBhZjJiNzVmMjlhZDJhYjIyN2VlYWEyNmVhN2IwZjJmYmRlL3BrZy91c2VyZGF0YS9zY3JpcHRzL2hlYWx0aC1tb25pdG9yLnNoCiAgICAgICAgY2htb2QgK3ggL29wdC9iaW4vaGVhbHRoLW1vbml0b3Iuc2gKICAgIGZpCiAgICAKICAgICMgc2V0IGt1YmVsZXQgbm9kZWlwIGVudmlyb25tZW50IHZhcmlhYmxlCiAgICAvb3B0L2Jpbi9zZXR1cF9uZXRfZW52LnNoCiAgICAKICAgIHN5c3RlbWN0bCBlbmFibGUgLS1ub3cga3ViZWxldAogICAgc3lzdGVtY3RsIGVuYWJsZSAtLW5vdyAtLW5vLWJsb2NrIGt1YmVsZXQtaGVhbHRoY2hlY2suc2VydmljZQogICAgCgotIHBhdGg6ICcvb3B0L2Jpbi9zdXBlcnZpc2Uuc2gnCiAgcGVybWlzc2lvbnM6ICcwNzU1JwogIGNvbnRlbnQ6IHwtCiAgICAjIS9iaW4vYmFzaAogICAgc2V0IC14ZXVvIHBpcGVmYWlsCiAgICB3aGlsZSAhICIkQCI7IGRvCiAgICAgIHNsZWVwIDEKICAgIGRvbmUKICAgIAoKLSBwYXRoOiAnL2V0Yy9zeXN0ZW1kL3N5c3RlbS9rdWJlbGV0LnNlcnZpY2UnCiAgY29udGVudDogfC0KICAgIFtVbml0XQogICAgQWZ0ZXI9ZG9ja2VyLnNlcnZpY2UKICAgIFJlcXVpcmVzPWRvY2tlci5zZXJ2aWNlCiAgICAKICAgIERlc2NyaXB0aW9uPWt1YmVsZXQ6IFRoZSBLdWJlcm5ldGVzIE5vZGUgQWdlbnQKICAgIERvY3VtZW50YXRpb249aHR0cHM6Ly9rdWJlcm5ldGVzLmlvL2RvY3MvaG9tZS8KICAgIAogICAgW1NlcnZpY2VdCiAgICBSZXN0YXJ0PWFsd2F5cwogICAgU3RhcnRMaW1pdEludGVydmFsPTAKICAgIFJlc3RhcnRTZWM9MTAKICAgIENQVUFjY291bnRpbmc9dHJ1ZQogICAgTWVtb3J5QWNjb3VudGluZz10cnVlCiAgICAKICAgIEVudmlyb25tZW50PSJQQVRIPS9vcHQvYmluOi9iaW46L3Vzci9sb2NhbC9zYmluOi91c3IvbG9jYWwvYmluOi91c3Ivc2JpbjovdXNyL2Jpbjovc2Jpbi8iCiAgICBFbnZpcm9ubWVudEZpbGU9LS9ldGMvZW52aXJvbm1lbnQKICAgIAogICAgRXhlY1N0YXJ0UHJlPS9iaW4vYmFzaCAvb3B0L2xvYWQta2VybmVsLW1vZHVsZXMuc2gKICAgIEV4ZWNTdGFydFByZT0vYmluL2Jhc2ggL29wdC9iaW4vc2V0dXBfbmV0X2Vudi5zaAogICAgRXhlY1N0YXJ0PS9vcHQvYmluL2t1YmVsZXQgJEtVQkVMRVRfRVhUUkFfQVJHUyBcCiAgICAgIC0tYm9vdHN0cmFwLWt1YmVjb25maWc9L2V0Yy9rdWJlcm5ldGVzL2Jvb3RzdHJhcC1rdWJlbGV0LmNvbmYgXAogICAgICAtLWt1YmVjb25maWc9L3Zhci9saWIva3ViZWxldC9rdWJlY29uZmlnIFwKICAgICAgLS1jb25maWc9L2V0Yy9rdWJlcm5ldGVzL2t1YmVsZXQuY29uZiBcCiAgICAgIC0tbmV0d29yay1wbHVnaW49Y25pIFwKICAgICAgLS1jZXJ0LWRpcj0vZXRjL2t1YmVybmV0ZXMvcGtpIFwKICAgICAgLS1jbG91ZC1wcm92aWRlcj1hd3MgXAogICAgICAtLWNsb3VkLWNvbmZpZz0vZXRjL2t1YmVybmV0ZXMvY2xvdWQtY29uZmlnIFwKICAgICAgLS1keW5hbWljLWNvbmZpZy1kaXI9L2V0Yy9rdWJlcm5ldGVzL2R5bmFtaWMtY29uZmlnLWRpciBcCiAgICAgIC0tZmVhdHVyZS1nYXRlcz1EeW5hbWljS3ViZWxldENvbmZpZz10cnVlIFwKICAgICAgLS1leGl0LW9uLWxvY2stY29udGVudGlvbiBcCiAgICAgIC0tbG9jay1maWxlPS90bXAva3ViZWxldC5sb2NrIFwKICAgICAgLS1jb250YWluZXItcnVudGltZT1kb2NrZXIgXAogICAgICAtLWNvbnRhaW5lci1ydW50aW1lLWVuZHBvaW50PXVuaXg6Ly8vdmFyL3J1bi9kb2NrZXJzaGltLnNvY2sgXAogICAgICAtLW5vZGUtaXAgJHtLVUJFTEVUX05PREVfSVB9CiAgICAKICAgIFtJbnN0YWxsXQogICAgV2FudGVkQnk9bXVsdGktdXNlci50YXJnZXQKICAgIAoKLSBwYXRoOiAnL2V0Yy9zeXN0ZW1kL3N5c3RlbS9rdWJlbGV0LnNlcnZpY2UuZC9leHRyYXMuY29uZicKICBjb250ZW50OiB8LQogICAgW1NlcnZpY2VdCiAgICBFbnZpcm9ubWVudD0iS1VCRUxFVF9FWFRSQV9BUkdTPS0tcmVzb2x2LWNvbmY9L3J1bi9zeXN0ZW1kL3Jlc29sdmUvcmVzb2x2LmNvbmYiCiAgICAKCi0gcGF0aDogJy9ldGMva3ViZXJuZXRlcy9jbG91ZC1jb25maWcnCiAgcGVybWlzc2lvbnM6ICcwNjAwJwogIGNvbnRlbnQ6IHwtCiAgICBbZ2xvYmFsXQogICAgWm9uZT0iIgogICAgVlBDPSIiCiAgICBTdWJuZXRJRD0idGVzdC1zdWJuZXQiCiAgICAKICAgIAoKLSBwYXRoOiAnL29wdC9iaW4vc2V0dXBfbmV0X2Vudi5zaCcKICBwZXJtaXNzaW9uczogJzA3NTUnCiAgY29udGVudDogfC0KICAgICMhL3Vzci9iaW4vZW52IGJhc2gKICAgIGVjaG9kYXRlKCkgewogICAgICBlY2hvICJbJChkYXRlIC1JcyldIiAiJEAiCiAgICB9CiAgICAKICAgICMgZ2V0IHRoZSBkZWZhdWx0IGludGVyZmFjZSBJUCBhZGRyZXNzCiAgICBERUZBVUxUX0lGQ19JUD0kKGlwIC1vICByb3V0ZSBnZXQgMSB8IGdyZXAgLW9QICJzcmMgXEtcUysiKQogICAgCiAgICBpZiBbIC16ICIke0RFRkFVTFRfSUZDX0lQfSIgXQogICAgdGhlbgogICAgICBlY2hvZGF0ZSAiRmFpbGVkIHRvIGdldCBJUCBhZGRyZXNzIGZvciB0aGUgZGVmYXVsdCByb3V0ZSBpbnRlcmZhY2UiCiAgICAgIGV4aXQgMQogICAgZmkKICAgIAogICAgICMgZ2V0IHRoZSBmdWxsIGhvc3RuYW1lCiAgICBGVUxMX0hPU1ROQU1FPSQoaG9zdG5hbWUgLWYpCiAgICAKICAgICMgd3JpdGUgdGhlIG5vZGVpcF9lbnYgZmlsZQogICAgIyB3ZSBuZWVkIHRoZSBsaW5lIGJlbG93IGJlY2F1c2UgZmxhdGNhciBoYXMgdGhlIHNhbWUgc3RyaW5nICJjb3Jlb3MiIGluIHRoYXQgZmlsZQogICAgaWYgZ3JlcCAtcSBjb3Jlb3MgL2V0Yy9vcy1yZWxlYXNlCiAgICB0aGVuCiAgICAgIGVjaG8gIktVQkVMRVRfTk9ERV9JUD0ke0RFRkFVTFRfSUZDX0lQfVxuS1VCRUxFVF9IT1NUTkFNRT0ke0ZVTExfSE9TVE5BTUV9IiA+IC9ldGMva3ViZXJuZXRlcy9ub2RlaXAuY29uZgogICAgZWxpZiBbICEgLWQgL2V0Yy9zeXN0ZW1kL3N5c3RlbS9rdWJlbGV0LnNlcnZpY2UuZCBdCiAgICB0aGVuCiAgICAgIGVjaG9kYXRlICJDYW4ndCBmaW5kIGt1YmVsZXQgc2VydmljZSBleHRyYXMgZGlyZWN0b3J5IgogICAgICBleGl0IDEKICAgIGVsc2UKICAgICAgZWNobyAtZSAiW1NlcnZpY2VdXG5FbnZpcm9ubWVudD1cIktVQkVMRVRfTk9ERV9JUD0ke0RFRkFVTFRfSUZDX0lQfVwiXG5FbnZpcm9ubWVudD1cIktVQkVMRVRfSE9TVE5BTUU9JHtGVUxMX0hPU1ROQU1FfVwiIiA+IC9ldGMvc3lzdGVtZC9zeXN0ZW0va3ViZWxldC5zZXJ2aWNlLmQvbm9kZWlwLmNvbmYKICAgIGZpCiAgICAKCi0gcGF0aDogJy9ldGMva3ViZXJuZXRlcy9wa2kvY2EuY3J0JwogIGNvbnRlbnQ6IHwtCiAgICAtLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KICAgIE1JSUVXakNDQTBLZ0F3SUJBZ0lKQUxmUmxXc0k4WVFITUEwR0NTcUdTSWIzRFFFQkJRVUFNSHN4Q3pBSkJnTlYKICAgIEJBWVRBbFZUTVFzd0NRWURWUVFJRXdKRFFURVdNQlFHQTFVRUJ4TU5VMkZ1SUVaeVlXNWphWE5qYnpFVU1CSUcKICAgIEExVUVDaE1MUW5KaFpHWnBkSHBwYm1NeEVqQVFCZ05WQkFNVENXeHZZMkZzYUc5emRERWRNQnNHQ1NxR1NJYjMKICAgIERRRUpBUllPWW5KaFpFQmtZVzVuWVM1amIyMHdIaGNOTVRRd056RTFNakEwTmpBMVdoY05NVGN3TlRBME1qQTAKICAgIE5qQTFXakI3TVFzd0NRWURWUVFHRXdKVlV6RUxNQWtHQTFVRUNCTUNRMEV4RmpBVUJnTlZCQWNURFZOaGJpQkcKICAgIGNtRnVZMmx6WTI4eEZEQVNCZ05WQkFvVEMwSnlZV1JtYVhSNmFXNWpNUkl3RUFZRFZRUURFd2xzYjJOaGJHaHYKICAgIGMzUXhIVEFiQmdrcWhraUc5dzBCQ1FFV0RtSnlZV1JBWkdGdVoyRXVZMjl0TUlJQklqQU5CZ2txaGtpRzl3MEIKICAgIEFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXQ1ZkFqcDRmVGNla1dVVGZ6c3Awa3lpaDFPWWJzR0wwS1gxZVJiU1MKICAgIFI4T2QwKzlRNjJIeW55K0dGd01UYjRBL0tVOG1zc29IdmNjZVNBQWJ3ZmJ4RksvK3M1MVRvYnFVbk9SWnJPb1QKICAgIFpqa1V5Z2J5WERTSzk5WUJiY1IxUGlwOHZ3TVRtNFhLdUx0Q2lnZUJCZGpqQVFkZ1VPMjhMRU5HbHNNbm1lWWsKICAgIEpmT0RWR25WbXI1THRiOUFOQThJS3lUZnNuSEo0aU9DUy9QbFBiVWoycTdZbm9WTHBvc1VCTWxnVWIvQ3lrWDMKICAgIG1Pb0xiNHlKSlF5QS9pU1Q2WnhpSUVqMzZENHlXWjVsZzdZSmwrVWlpQlFIR0NuUGRHeWlwcVYwNmV4MGhlWVcKICAgIGNhaVc4TFdaU1VROTNqUStXVkNIOGhUN0RRTzFkbXN2VW1YbHEvSmVBbHdRL1FJREFRQUJvNEhnTUlIZE1CMEcKICAgIEExVWREZ1FXQkJSY0FST3RoUzRQNFU3dlRmakJ5QzU2OVI3RTZEQ0JyUVlEVlIwakJJR2xNSUdpZ0JSY0FST3QKICAgIGhTNFA0VTd2VGZqQnlDNTY5UjdFNktGL3BIMHdlekVMTUFrR0ExVUVCaE1DVlZNeEN6QUpCZ05WQkFnVEFrTkIKICAgIE1SWXdGQVlEVlFRSEV3MVRZVzRnUm5KaGJtTnBjMk52TVJRd0VnWURWUVFLRXd0Q2NtRmtabWwwZW1sdVl6RVMKICAgIE1CQUdBMVVFQXhNSmJHOWpZV3hvYjNOME1SMHdHd1lKS29aSWh2Y05BUWtCRmc1aWNtRmtRR1JoYm1kaExtTnYKICAgIGJZSUpBTGZSbFdzSThZUUhNQXdHQTFVZEV3UUZNQU1CQWY4d0RRWUpLb1pJaHZjTkFRRUZCUUFEZ2dFQkFHNmgKICAgIFU5ZjlzTkgwLzZvQmJHR3kyRVZVMFVnSVRVUUlyRldvOXJGa3JXNWsvWGtEalFtKzNsempUMGlHUjRJeEUvQW8KICAgIGVVNnNRaHVhN3dyV2VGRW40N0dMOThsbkNzSmREN29aTmhGbVE5NVRiL0xuRFVqczVZajliclAwTld6WGZZVTQKICAgIFVLMlpuSU5KUmNKcEI4aVJDYUN4RThEZGNVRjBYcUlFcTZwQTI3MnNub0xtaVhMTXZObDNrWUVkbStqZTZ2b0QKICAgIDU4U05WRVVzenR6UXlYbUpFaENwd1ZJMEE2UUNqelhqK3F2cG13M1paSGk4SndYZWk4WlpCTFRTRkJraThaN24KICAgIHNIOUJCSDM4L1N6VW1BTjRRSFNQeTFnanFtMDBPQUU4TmFZRGtoL2J6RTRkN21MR0dNV3AvV0UzS1BTdTgySEYKICAgIGtQZTZYb1NiaUxtL2t4azMyVDA9CiAgICAtLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCiAgICAKCi0gcGF0aDogJy9ldGMvc3lzdGVtZC9zeXN0ZW0vc2V0dXAuc2VydmljZScKICBwZXJtaXNzaW9uczogJzA2NDQnCiAgY29udGVudDogfC0KICAgIFtJbnN0YWxsXQogICAgV2FudGVkQnk9bXVsdGktdXNlci50YXJnZXQKICAgIAogICAgW1VuaXRdCiAgICBSZXF1aXJlcz1uZXR3b3JrLW9ubGluZS50YXJnZXQKICAgIEFmdGVyPW5ldHdvcmstb25saW5lLnRhcmdldAogICAgCiAgICBbU2VydmljZV0KICAgIFR5cGU9b25lc2hvdAogICAgUmVtYWluQWZ0ZXJFeGl0PXRydWUKICAgIEVudmlyb25tZW50RmlsZT0tL2V0Yy9lbnZpcm9ubWVudAogICAgRXhlY1N0YXJ0PS9vcHQvYmluL3N1cGVydmlzZS5zaCAvb3B0L2Jpbi9zZXR1cAogICAgCgotIHBhdGg6ICcvZXRjL3Byb2ZpbGUuZC9vcHQtYmluLXBhdGguc2gnCiAgcGVybWlzc2lvbnM6ICcwNjQ0JwogIGNvbnRlbnQ6IHwtCiAgICBleHBvcnQgUEFUSD0iL29wdC9iaW46JFBBVEgiCiAgICAKCi0gcGF0aDogJy9ldGMva3ViZXJuZXRlcy9rdWJlbGV0LmNvbmYnCiAgY29udGVudDogfC0KICAgIGFwaVZlcnNpb246IGt1YmVsZXQuY29uZmlnLms4cy5pby92MWJldGExCiAgICBraW5kOiBLdWJlbGV0Q29uZmlndXJhdGlvbgogICAgYXV0aGVudGljYXRpb246CiAgICAgIGFub255bW91czoKICAgICAgICBlbmFibGVkOiBmYWxzZQogICAgICB3ZWJob29rOgogICAgICAgIGVuYWJsZWQ6IHRydWUKICAgICAgeDUwOToKICAgICAgICBjbGllbnRDQUZpbGU6IC9ldGMva3ViZXJuZXRlcy9wa2kvY2EuY3J0CiAgICBhdXRob3JpemF0aW9uOgogICAgICBtb2RlOiBXZWJob29rCiAgICBjZ3JvdXBEcml2ZXI6IHN5c3RlbWQKICAgIGNsdXN0ZXJETlM6CiAgICAtICIxMC4wLjAuMCIKICAgIGNsdXN0ZXJEb21haW46IGNsdXN0ZXIubG9jYWwKICAgIGZlYXR1cmVHYXRlczoKICAgICAgR3JhY2VmdWxOb2RlU2h1dGRvd246IHRydWUKICAgICAgSWRlbnRpZnlQb2RPUzogZmFsc2UKICAgIHByb3RlY3RLZXJuZWxEZWZhdWx0czogdHJ1ZQogICAgcmVhZE9ubHlQb3J0OiAwCiAgICByb3RhdGVDZXJ0aWZpY2F0ZXM6IHRydWUKICAgIHNlcnZlclRMU0Jvb3RzdHJhcDogdHJ1ZQogICAgc3RhdGljUG9kUGF0aDogL2V0Yy9rdWJlcm5ldGVzL21hbmlmZXN0cwogICAga3ViZVJlc2VydmVkOgogICAgICBjcHU6IDIwMG0KICAgICAgZXBoZW1lcmFsLXN0b3JhZ2U6IDFHaQogICAgICBtZW1vcnk6IDIwME1pCiAgICBzeXN0ZW1SZXNlcnZlZDoKICAgICAgY3B1OiAyMDBtCiAgICAgIGVwaGVtZXJhbC1zdG9yYWdlOiAxR2kKICAgICAgbWVtb3J5OiAyMDBNaQogICAgZXZpY3Rpb25IYXJkOgogICAgICBpbWFnZWZzLmF2YWlsYWJsZTogMTUlCiAgICAgIG1lbW9yeS5hdmFpbGFibGU6IDEwME1pCiAgICAgIG5vZGVmcy5hdmFpbGFibGU6IDEwJQogICAgICBub2RlZnMuaW5vZGVzRnJlZTogNSUKICAgIHRsc0NpcGhlclN1aXRlczoKICAgIC0gVExTX0FFU18xMjhfR0NNX1NIQTI1NgogICAgLSBUTFNfQUVTXzI1Nl9HQ01fU0hBMzg0CiAgICAtIFRMU19DSEFDSEEyMF9QT0xZMTMwNV9TSEEyNTYKICAgIC0gVExTX0VDREhFX0VDRFNBX1dJVEhfQUVTXzEyOF9HQ01fU0hBMjU2CiAgICAtIFRMU19FQ0RIRV9FQ0RTQV9XSVRIX0FFU18yNTZfR0NNX1NIQTM4NAogICAgLSBUTFNfRUNESEVfRUNEU0FfV0lUSF9DSEFDSEEyMF9QT0xZMTMwNQogICAgLSBUTFNfRUNESEVfUlNBX1dJVEhfQUVTXzEyOF9HQ01fU0hBMjU2CiAgICAtIFRMU19FQ0RIRV9SU0FfV0lUSF9BRVNfMjU2X0dDTV9TSEEzODQKICAgIC0gVExTX0VDREhFX1JTQV9XSVRIX0NIQUNIQTIwX1BPTFkxMzA1CiAgICB2b2x1bWVQbHVnaW5EaXI6IC92YXIvbGliL2t1YmVsZXQvdm9sdW1lcGx1Z2lucwogICAgCgotIHBhdGg6ICcvZXRjL3N5c3RlbWQvc3lzdGVtL2t1YmVsZXQtaGVhbHRoY2hlY2suc2VydmljZScKICBwZXJtaXNzaW9uczogJzA2NDQnCiAgY29udGVudDogfC0KICAgIFtVbml0XQogICAgUmVxdWlyZXM9a3ViZWxldC5zZXJ2aWNlCiAgICBBZnRlcj1rdWJlbGV0LnNlcnZpY2UKICAgIAogICAgW1NlcnZpY2VdCiAgICBFeGVjU3RhcnQ9L29wdC9iaW4vaGVhbHRoLW1vbml0b3Iuc2gga3ViZWxldAogICAgCiAgICBbSW5zdGFsbF0KICAgIFdhbnRlZEJ5PW11bHRpLXVzZXIudGFyZ2V0CiAgICAKCi0gcGF0aDogJy9ldGMvZG9ja2VyL2RhZW1vbi5qc29uJwogIHBlcm1pc3Npb25zOiAnMDY0NCcKICBjb250ZW50OiB8LQogICAgeyJleGVjLW9wdHMiOlsibmF0aXZlLmNncm91cGRyaXZlcj1zeXN0ZW1kIl0sInN0b3JhZ2UtZHJpdmVyIjoib3ZlcmxheTIiLCJsb2ctZHJpdmVyIjoianNvbi1maWxlIiwibG9nLW9wdHMiOnsibWF4LWZpbGUiOiI1IiwibWF4LXNpemUiOiIxMDBtIn19Cgpib290Y21kOgotIGVjaG8gaGVsbG8KLSBlY2hvIHdvcmxkCgpyaF9zdWJzY3JpcHRpb246CiAgICBwYXNzd29yZDogcGFzc3dvcmQKICAgIHVzZXJuYW1lOiB1c2VybmFtZQ== + cloud-config: I2Nsb3VkLWNvbmZpZwoKc3NoX3B3YXV0aDogbm8Kc3NoX2F1dGhvcml6ZWRfa2V5czoKLSAnc3NoLXJzYSBBQUFBQjNOemFDMXljMkVBQUFBREFRQUJBQUFDQVFEZE9JaFltekNLNURTVkx1M2MnCndyaXRlX2ZpbGVzOgotIHBhdGg6ICcvZXRjL3N5c3RlbWQvam91cm5hbGQuY29uZi5kL21heF9kaXNrX3VzZS5jb25mJwogIGNvbnRlbnQ6IHwtCiAgICBbSm91cm5hbF0KICAgIFN5c3RlbU1heFVzZT01RwogICAgCgotIHBhdGg6ICcvb3B0L2xvYWQta2VybmVsLW1vZHVsZXMuc2gnCiAgcGVybWlzc2lvbnM6ICcwNzU1JwogIGNvbnRlbnQ6IHwtCiAgICAjIS91c3IvYmluL2VudiBiYXNoCiAgICBzZXQgLWV1byBwaXBlZmFpbAogICAgCiAgICBtb2Rwcm9iZSBpcF92cwogICAgbW9kcHJvYmUgaXBfdnNfcnIKICAgIG1vZHByb2JlIGlwX3ZzX3dycgogICAgbW9kcHJvYmUgaXBfdnNfc2gKICAgIAogICAgaWYgbW9kaW5mbyBuZl9jb25udHJhY2tfaXB2NCAmPiAvZGV2L251bGw7IHRoZW4KICAgICAgbW9kcHJvYmUgbmZfY29ubnRyYWNrX2lwdjQKICAgIGVsc2UKICAgICAgbW9kcHJvYmUgbmZfY29ubnRyYWNrCiAgICBmaQogICAgCgotIHBhdGg6ICcvZXRjL3N5c2N0bC5kL2s4cy5jb25mJwogIGNvbnRlbnQ6IHwtCiAgICBuZXQuYnJpZGdlLmJyaWRnZS1uZi1jYWxsLWlwNnRhYmxlcyA9IDEKICAgIG5ldC5icmlkZ2UuYnJpZGdlLW5mLWNhbGwtaXB0YWJsZXMgPSAxCiAgICBrZXJuZWwucGFuaWNfb25fb29wcyA9IDEKICAgIGtlcm5lbC5wYW5pYyA9IDEwCiAgICBuZXQuaXB2NC5pcF9mb3J3YXJkID0gMQogICAgdm0ub3ZlcmNvbW1pdF9tZW1vcnkgPSAxCiAgICBmcy5pbm90aWZ5Lm1heF91c2VyX3dhdGNoZXMgPSAxMDQ4NTc2CiAgICAKCi0gcGF0aDogJy9ldGMvZGVmYXVsdC9ncnViLmQvNjAtc3dhcC1hY2NvdW50aW5nLmNmZycKICBjb250ZW50OiB8LQogICAgIyBBZGRlZCBieSBrdWJlcm1hdGljIG1hY2hpbmUtY29udHJvbGxlcgogICAgIyBFbmFibGUgY2dyb3VwcyBtZW1vcnkgYW5kIHN3YXAgYWNjb3VudGluZwogICAgR1JVQl9DTURMSU5FX0xJTlVYPSJjZ3JvdXBfZW5hYmxlPW1lbW9yeSBzd2FwYWNjb3VudD0xIgogICAgCgotIHBhdGg6ICcvb3B0L2Jpbi9zZXR1cCcKICBwZXJtaXNzaW9uczogJzA3NTUnCiAgY29udGVudDogfC0KICAgICMhL2Jpbi9iYXNoCiAgICBzZXQgLXhldW8gcGlwZWZhaWwKICAgIGlmIHN5c3RlbWN0bCBpcy1hY3RpdmUgdWZ3OyB0aGVuIHN5c3RlbWN0bCBzdG9wIHVmdzsgZmkKICAgIHN5c3RlbWN0bCBtYXNrIHVmdwogICAgc3lzdGVtY3RsIHJlc3RhcnQgc3lzdGVtZC1tb2R1bGVzLWxvYWQuc2VydmljZQogICAgc3lzY3RsIC0tc3lzdGVtCiAgICBzZWQgLWkub3JpZyAnLy4qc3dhcC4qL2QnIC9ldGMvZnN0YWIKICAgIHN3YXBvZmYgLWEKICAgIAogICAgYXB0LWdldCB1cGRhdGUKICAgIAogICAgREVCSUFOX0ZST05URU5EPW5vbmludGVyYWN0aXZlIGFwdC1nZXQgLW8gRHBrZzo6T3B0aW9uczo6PSItLWZvcmNlLWNvbmZkZWYiIC1vIERwa2c6Ok9wdGlvbnM6Oj0iLS1mb3JjZS1jb25mb2xkIiBpbnN0YWxsIC15IFwKICAgICAgY3VybCBcCiAgICAgIGNhLWNlcnRpZmljYXRlcyBcCiAgICAgIGNlcGgtY29tbW9uIFwKICAgICAgY2lmcy11dGlscyBcCiAgICAgIGNvbm50cmFjayBcCiAgICAgIGUyZnNwcm9ncyBcCiAgICAgIGVidGFibGVzIFwKICAgICAgZXRodG9vbCBcCiAgICAgIGdsdXN0ZXJmcy1jbGllbnQgXAogICAgICBpcHRhYmxlcyBcCiAgICAgIGpxIFwKICAgICAga21vZCBcCiAgICAgIG9wZW5zc2gtY2xpZW50IFwKICAgICAgbmZzLWNvbW1vbiBcCiAgICAgIHNvY2F0IFwKICAgICAgdXRpbC1saW51eCBcCiAgICAgIGlwdnNhZG0KICAgIGFwdC1nZXQgdXBkYXRlCiAgICBhcHQtZ2V0IGluc3RhbGwgLXkgYXB0LXRyYW5zcG9ydC1odHRwcyBjYS1jZXJ0aWZpY2F0ZXMgY3VybCBzb2Z0d2FyZS1wcm9wZXJ0aWVzLWNvbW1vbiBsc2ItcmVsZWFzZQogICAgY3VybCAtZnNTTCBodHRwczovL2Rvd25sb2FkLmRvY2tlci5jb20vbGludXgvdWJ1bnR1L2dwZyB8IGFwdC1rZXkgYWRkIC0KICAgIGFkZC1hcHQtcmVwb3NpdG9yeSAiZGViIGh0dHBzOi8vZG93bmxvYWQuZG9ja2VyLmNvbS9saW51eC91YnVudHUgJChsc2JfcmVsZWFzZSAtY3MpIHN0YWJsZSIKICAgIAogICAgbWtkaXIgLXAgL2V0Yy9zeXN0ZW1kL3N5c3RlbS9jb250YWluZXJkLnNlcnZpY2UuZCAvZXRjL3N5c3RlbWQvc3lzdGVtL2RvY2tlci5zZXJ2aWNlLmQKICAgIAogICAgY2F0IDw8RU9GIHwgdGVlIC9ldGMvc3lzdGVtZC9zeXN0ZW0vY29udGFpbmVyZC5zZXJ2aWNlLmQvZW52aXJvbm1lbnQuY29uZiAvZXRjL3N5c3RlbWQvc3lzdGVtL2RvY2tlci5zZXJ2aWNlLmQvZW52aXJvbm1lbnQuY29uZgogICAgW1NlcnZpY2VdCiAgICBSZXN0YXJ0PWFsd2F5cwogICAgRW52aXJvbm1lbnRGaWxlPS0vZXRjL2Vudmlyb25tZW50CiAgICBFT0YKICAgIAogICAgYXB0LWdldCBpbnN0YWxsIC15IFwKICAgICAgICBjb250YWluZXJkLmlvPTEuNC4zKiBcCiAgICAgICAgZG9ja2VyLWNlPTU6MTkuMDMuMTMqIFwKICAgICAgICBkb2NrZXItY2UtY2xpPTU6MTkuMDMuMTMqCiAgICBhcHQtbWFyayBob2xkIGRvY2tlci1jZSBkb2NrZXItY2UtY2xpIGNvbnRhaW5lcmQuaW8KICAgIAogICAgc3lzdGVtY3RsIGRhZW1vbi1yZWxvYWQKICAgIHN5c3RlbWN0bCBlbmFibGUgLS1ub3cgZG9ja2VyCiAgICBvcHRfYmluPS9vcHQvYmluCiAgICBjbmlfYmluX2Rpcj0vb3B0L2NuaS9iaW4KICAgIG1rZGlyIC1wIC9ldGMvY25pL25ldC5kIC9ldGMva3ViZXJuZXRlcy9keW5hbWljLWNvbmZpZy1kaXIgL2V0Yy9rdWJlcm5ldGVzL21hbmlmZXN0cyAiJG9wdF9iaW4iICIkY25pX2Jpbl9kaXIiCiAgICBhcmNoPSR7SE9TVF9BUkNILX0KICAgIGlmIFsgLXogIiRhcmNoIiBdCiAgICB0aGVuCiAgICBjYXNlICQodW5hbWUgLW0pIGluCiAgICB4ODZfNjQpCiAgICAgICAgYXJjaD0iYW1kNjQiCiAgICAgICAgOzsKICAgIGFhcmNoNjQpCiAgICAgICAgYXJjaD0iYXJtNjQiCiAgICAgICAgOzsKICAgICopCiAgICAgICAgZWNobyAidW5zdXBwb3J0ZWQgQ1BVIGFyY2hpdGVjdHVyZSwgZXhpdGluZyIKICAgICAgICBleGl0IDEKICAgICAgICA7OwogICAgZXNhYwogICAgZmkKICAgIENOSV9WRVJTSU9OPSIke0NOSV9WRVJTSU9OOi12MC44Ljd9IgogICAgY25pX2Jhc2VfdXJsPSJodHRwczovL2dpdGh1Yi5jb20vY29udGFpbmVybmV0d29ya2luZy9wbHVnaW5zL3JlbGVhc2VzL2Rvd25sb2FkLyRDTklfVkVSU0lPTiIKICAgIGNuaV9maWxlbmFtZT0iY25pLXBsdWdpbnMtbGludXgtJGFyY2gtJENOSV9WRVJTSU9OLnRneiIKICAgIGN1cmwgLUxmbyAiJGNuaV9iaW5fZGlyLyRjbmlfZmlsZW5hbWUiICIkY25pX2Jhc2VfdXJsLyRjbmlfZmlsZW5hbWUiCiAgICBjbmlfc3VtPSQoY3VybCAtTGYgIiRjbmlfYmFzZV91cmwvJGNuaV9maWxlbmFtZS5zaGEyNTYiKQogICAgY2QgIiRjbmlfYmluX2RpciIKICAgIHNoYTI1NnN1bSAtYyA8PDwiJGNuaV9zdW0iCiAgICB0YXIgeHZmICIkY25pX2ZpbGVuYW1lIgogICAgcm0gLWYgIiRjbmlfZmlsZW5hbWUiCiAgICBjZCAtCiAgICBLVUJFX1ZFUlNJT049IiR7S1VCRV9WRVJTSU9OOi12MS4yMi4xfSIKICAgIGt1YmVfZGlyPSIkb3B0X2Jpbi9rdWJlcm5ldGVzLSRLVUJFX1ZFUlNJT04iCiAgICBrdWJlX2Jhc2VfdXJsPSJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20va3ViZXJuZXRlcy1yZWxlYXNlL3JlbGVhc2UvJEtVQkVfVkVSU0lPTi9iaW4vbGludXgvJGFyY2giCiAgICBrdWJlX3N1bV9maWxlPSIka3ViZV9kaXIvc2hhMjU2IgogICAgbWtkaXIgLXAgIiRrdWJlX2RpciIKICAgIDogPiIka3ViZV9zdW1fZmlsZSIKICAgIAogICAgZm9yIGJpbiBpbiBrdWJlbGV0IGt1YmVhZG0ga3ViZWN0bDsgZG8KICAgICAgICBjdXJsIC1MZm8gIiRrdWJlX2Rpci8kYmluIiAiJGt1YmVfYmFzZV91cmwvJGJpbiIKICAgICAgICBjaG1vZCAreCAiJGt1YmVfZGlyLyRiaW4iCiAgICAgICAgc3VtPSQoY3VybCAtTGYgIiRrdWJlX2Jhc2VfdXJsLyRiaW4uc2hhMjU2IikKICAgICAgICBlY2hvICIkc3VtICAka3ViZV9kaXIvJGJpbiIgPj4iJGt1YmVfc3VtX2ZpbGUiCiAgICBkb25lCiAgICBzaGEyNTZzdW0gLWMgIiRrdWJlX3N1bV9maWxlIgogICAgCiAgICBmb3IgYmluIGluIGt1YmVsZXQga3ViZWFkbSBrdWJlY3RsOyBkbwogICAgICAgIGxuIC1zZiAiJGt1YmVfZGlyLyRiaW4iICIkb3B0X2JpbiIvJGJpbgogICAgZG9uZQogICAgCiAgICBpZiBbWyAhIC14IC9vcHQvYmluL2hlYWx0aC1tb25pdG9yLnNoIF1dOyB0aGVuCiAgICAgICAgY3VybCAtTGZvIC9vcHQvYmluL2hlYWx0aC1tb25pdG9yLnNoIGh0dHBzOi8vcmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbS9rdWJlcm1hdGljL21hY2hpbmUtY29udHJvbGxlci83OTY3YTBhZjJiNzVmMjlhZDJhYjIyN2VlYWEyNmVhN2IwZjJmYmRlL3BrZy91c2VyZGF0YS9zY3JpcHRzL2hlYWx0aC1tb25pdG9yLnNoCiAgICAgICAgY2htb2QgK3ggL29wdC9iaW4vaGVhbHRoLW1vbml0b3Iuc2gKICAgIGZpCiAgICAKICAgICMgc2V0IGt1YmVsZXQgbm9kZWlwIGVudmlyb25tZW50IHZhcmlhYmxlCiAgICAvb3B0L2Jpbi9zZXR1cF9uZXRfZW52LnNoCiAgICAKICAgIHN5c3RlbWN0bCBlbmFibGUgLS1ub3cga3ViZWxldAogICAgc3lzdGVtY3RsIGVuYWJsZSAtLW5vdyAtLW5vLWJsb2NrIGt1YmVsZXQtaGVhbHRoY2hlY2suc2VydmljZQogICAgCgotIHBhdGg6ICcvb3B0L2Jpbi9zdXBlcnZpc2Uuc2gnCiAgcGVybWlzc2lvbnM6ICcwNzU1JwogIGNvbnRlbnQ6IHwtCiAgICAjIS9iaW4vYmFzaAogICAgc2V0IC14ZXVvIHBpcGVmYWlsCiAgICB3aGlsZSAhICIkQCI7IGRvCiAgICAgIHNsZWVwIDEKICAgIGRvbmUKICAgIAoKLSBwYXRoOiAnL2V0Yy9zeXN0ZW1kL3N5c3RlbS9rdWJlbGV0LnNlcnZpY2UnCiAgY29udGVudDogfC0KICAgIFtVbml0XQogICAgQWZ0ZXI9ZG9ja2VyLnNlcnZpY2UKICAgIFJlcXVpcmVzPWRvY2tlci5zZXJ2aWNlCiAgICAKICAgIERlc2NyaXB0aW9uPWt1YmVsZXQ6IFRoZSBLdWJlcm5ldGVzIE5vZGUgQWdlbnQKICAgIERvY3VtZW50YXRpb249aHR0cHM6Ly9rdWJlcm5ldGVzLmlvL2RvY3MvaG9tZS8KICAgIAogICAgW1NlcnZpY2VdCiAgICBSZXN0YXJ0PWFsd2F5cwogICAgU3RhcnRMaW1pdEludGVydmFsPTAKICAgIFJlc3RhcnRTZWM9MTAKICAgIENQVUFjY291bnRpbmc9dHJ1ZQogICAgTWVtb3J5QWNjb3VudGluZz10cnVlCiAgICAKICAgIEVudmlyb25tZW50PSJQQVRIPS9vcHQvYmluOi9iaW46L3Vzci9sb2NhbC9zYmluOi91c3IvbG9jYWwvYmluOi91c3Ivc2JpbjovdXNyL2Jpbjovc2Jpbi8iCiAgICBFbnZpcm9ubWVudEZpbGU9LS9ldGMvZW52aXJvbm1lbnQKICAgIAogICAgRXhlY1N0YXJ0UHJlPS9iaW4vYmFzaCAvb3B0L2xvYWQta2VybmVsLW1vZHVsZXMuc2gKICAgIEV4ZWNTdGFydFByZT0vYmluL2Jhc2ggL29wdC9iaW4vc2V0dXBfbmV0X2Vudi5zaAogICAgRXhlY1N0YXJ0PS9vcHQvYmluL2t1YmVsZXQgJEtVQkVMRVRfRVhUUkFfQVJHUyBcCiAgICAgIC0tYm9vdHN0cmFwLWt1YmVjb25maWc9L2V0Yy9rdWJlcm5ldGVzL2Jvb3RzdHJhcC1rdWJlbGV0LmNvbmYgXAogICAgICAtLWt1YmVjb25maWc9L3Zhci9saWIva3ViZWxldC9rdWJlY29uZmlnIFwKICAgICAgLS1jb25maWc9L2V0Yy9rdWJlcm5ldGVzL2t1YmVsZXQuY29uZiBcCiAgICAgIC0tbmV0d29yay1wbHVnaW49Y25pIFwKICAgICAgLS1jZXJ0LWRpcj0vZXRjL2t1YmVybmV0ZXMvcGtpIFwKICAgICAgLS1jbG91ZC1wcm92aWRlcj1hd3MgXAogICAgICAtLWNsb3VkLWNvbmZpZz0vZXRjL2t1YmVybmV0ZXMvY2xvdWQtY29uZmlnIFwKICAgICAgLS1keW5hbWljLWNvbmZpZy1kaXI9L2V0Yy9rdWJlcm5ldGVzL2R5bmFtaWMtY29uZmlnLWRpciBcCiAgICAgIC0tZmVhdHVyZS1nYXRlcz1EeW5hbWljS3ViZWxldENvbmZpZz10cnVlIFwKICAgICAgLS1leGl0LW9uLWxvY2stY29udGVudGlvbiBcCiAgICAgIC0tbG9jay1maWxlPS90bXAva3ViZWxldC5sb2NrIFwKICAgICAgLS1jb250YWluZXItcnVudGltZT1kb2NrZXIgXAogICAgICAtLWNvbnRhaW5lci1ydW50aW1lLWVuZHBvaW50PXVuaXg6Ly8vdmFyL3J1bi9kb2NrZXJzaGltLnNvY2sgXAogICAgICAtLW5vZGUtaXAgJHtLVUJFTEVUX05PREVfSVB9CiAgICAKICAgIFtJbnN0YWxsXQogICAgV2FudGVkQnk9bXVsdGktdXNlci50YXJnZXQKICAgIAoKLSBwYXRoOiAnL2V0Yy9zeXN0ZW1kL3N5c3RlbS9rdWJlbGV0LnNlcnZpY2UuZC9leHRyYXMuY29uZicKICBjb250ZW50OiB8LQogICAgW1NlcnZpY2VdCiAgICBFbnZpcm9ubWVudD0iS1VCRUxFVF9FWFRSQV9BUkdTPS0tcmVzb2x2LWNvbmY9L3J1bi9zeXN0ZW1kL3Jlc29sdmUvcmVzb2x2LmNvbmYiCiAgICAKCi0gcGF0aDogJy9ldGMva3ViZXJuZXRlcy9jbG91ZC1jb25maWcnCiAgcGVybWlzc2lvbnM6ICcwNjAwJwogIGNvbnRlbnQ6IHwtCiAgICBbZ2xvYmFsXQogICAgWm9uZT0iIgogICAgVlBDPSIiCiAgICBTdWJuZXRJRD0idGVzdC1zdWJuZXQiCiAgICAKICAgIAoKLSBwYXRoOiAnL29wdC9iaW4vc2V0dXBfbmV0X2Vudi5zaCcKICBwZXJtaXNzaW9uczogJzA3NTUnCiAgY29udGVudDogfC0KICAgICMhL3Vzci9iaW4vZW52IGJhc2gKICAgIGVjaG9kYXRlKCkgewogICAgICBlY2hvICJbJChkYXRlIC1JcyldIiAiJEAiCiAgICB9CiAgICAKICAgICMgZ2V0IHRoZSBkZWZhdWx0IGludGVyZmFjZSBJUCBhZGRyZXNzCiAgICBERUZBVUxUX0lGQ19JUD0kKGlwIC1vICByb3V0ZSBnZXQgMSB8IGdyZXAgLW9QICJzcmMgXEtcUysiKQogICAgCiAgICBpZiBbIC16ICIke0RFRkFVTFRfSUZDX0lQfSIgXQogICAgdGhlbgogICAgICBlY2hvZGF0ZSAiRmFpbGVkIHRvIGdldCBJUCBhZGRyZXNzIGZvciB0aGUgZGVmYXVsdCByb3V0ZSBpbnRlcmZhY2UiCiAgICAgIGV4aXQgMQogICAgZmkKICAgIAogICAgICMgZ2V0IHRoZSBmdWxsIGhvc3RuYW1lCiAgICBGVUxMX0hPU1ROQU1FPSQoaG9zdG5hbWUgLWYpCiAgICAKICAgICMgd3JpdGUgdGhlIG5vZGVpcF9lbnYgZmlsZQogICAgIyB3ZSBuZWVkIHRoZSBsaW5lIGJlbG93IGJlY2F1c2UgZmxhdGNhciBoYXMgdGhlIHNhbWUgc3RyaW5nICJjb3Jlb3MiIGluIHRoYXQgZmlsZQogICAgaWYgZ3JlcCAtcSBjb3Jlb3MgL2V0Yy9vcy1yZWxlYXNlCiAgICB0aGVuCiAgICAgIGVjaG8gIktVQkVMRVRfTk9ERV9JUD0ke0RFRkFVTFRfSUZDX0lQfVxuS1VCRUxFVF9IT1NUTkFNRT0ke0ZVTExfSE9TVE5BTUV9IiA+IC9ldGMva3ViZXJuZXRlcy9ub2RlaXAuY29uZgogICAgZWxpZiBbICEgLWQgL2V0Yy9zeXN0ZW1kL3N5c3RlbS9rdWJlbGV0LnNlcnZpY2UuZCBdCiAgICB0aGVuCiAgICAgIGVjaG9kYXRlICJDYW4ndCBmaW5kIGt1YmVsZXQgc2VydmljZSBleHRyYXMgZGlyZWN0b3J5IgogICAgICBleGl0IDEKICAgIGVsc2UKICAgICAgZWNobyAtZSAiW1NlcnZpY2VdXG5FbnZpcm9ubWVudD1cIktVQkVMRVRfTk9ERV9JUD0ke0RFRkFVTFRfSUZDX0lQfVwiXG5FbnZpcm9ubWVudD1cIktVQkVMRVRfSE9TVE5BTUU9JHtGVUxMX0hPU1ROQU1FfVwiIiA+IC9ldGMvc3lzdGVtZC9zeXN0ZW0va3ViZWxldC5zZXJ2aWNlLmQvbm9kZWlwLmNvbmYKICAgIGZpCiAgICAKCi0gcGF0aDogJy9ldGMva3ViZXJuZXRlcy9wa2kvY2EuY3J0JwogIGNvbnRlbnQ6IHwtCiAgICAtLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KICAgIE1JSUVXakNDQTBLZ0F3SUJBZ0lKQUxmUmxXc0k4WVFITUEwR0NTcUdTSWIzRFFFQkJRVUFNSHN4Q3pBSkJnTlYKICAgIEJBWVRBbFZUTVFzd0NRWURWUVFJRXdKRFFURVdNQlFHQTFVRUJ4TU5VMkZ1SUVaeVlXNWphWE5qYnpFVU1CSUcKICAgIEExVUVDaE1MUW5KaFpHWnBkSHBwYm1NeEVqQVFCZ05WQkFNVENXeHZZMkZzYUc5emRERWRNQnNHQ1NxR1NJYjMKICAgIERRRUpBUllPWW5KaFpFQmtZVzVuWVM1amIyMHdIaGNOTVRRd056RTFNakEwTmpBMVdoY05NVGN3TlRBME1qQTAKICAgIE5qQTFXakI3TVFzd0NRWURWUVFHRXdKVlV6RUxNQWtHQTFVRUNCTUNRMEV4RmpBVUJnTlZCQWNURFZOaGJpQkcKICAgIGNtRnVZMmx6WTI4eEZEQVNCZ05WQkFvVEMwSnlZV1JtYVhSNmFXNWpNUkl3RUFZRFZRUURFd2xzYjJOaGJHaHYKICAgIGMzUXhIVEFiQmdrcWhraUc5dzBCQ1FFV0RtSnlZV1JBWkdGdVoyRXVZMjl0TUlJQklqQU5CZ2txaGtpRzl3MEIKICAgIEFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXQ1ZkFqcDRmVGNla1dVVGZ6c3Awa3lpaDFPWWJzR0wwS1gxZVJiU1MKICAgIFI4T2QwKzlRNjJIeW55K0dGd01UYjRBL0tVOG1zc29IdmNjZVNBQWJ3ZmJ4RksvK3M1MVRvYnFVbk9SWnJPb1QKICAgIFpqa1V5Z2J5WERTSzk5WUJiY1IxUGlwOHZ3TVRtNFhLdUx0Q2lnZUJCZGpqQVFkZ1VPMjhMRU5HbHNNbm1lWWsKICAgIEpmT0RWR25WbXI1THRiOUFOQThJS3lUZnNuSEo0aU9DUy9QbFBiVWoycTdZbm9WTHBvc1VCTWxnVWIvQ3lrWDMKICAgIG1Pb0xiNHlKSlF5QS9pU1Q2WnhpSUVqMzZENHlXWjVsZzdZSmwrVWlpQlFIR0NuUGRHeWlwcVYwNmV4MGhlWVcKICAgIGNhaVc4TFdaU1VROTNqUStXVkNIOGhUN0RRTzFkbXN2VW1YbHEvSmVBbHdRL1FJREFRQUJvNEhnTUlIZE1CMEcKICAgIEExVWREZ1FXQkJSY0FST3RoUzRQNFU3dlRmakJ5QzU2OVI3RTZEQ0JyUVlEVlIwakJJR2xNSUdpZ0JSY0FST3QKICAgIGhTNFA0VTd2VGZqQnlDNTY5UjdFNktGL3BIMHdlekVMTUFrR0ExVUVCaE1DVlZNeEN6QUpCZ05WQkFnVEFrTkIKICAgIE1SWXdGQVlEVlFRSEV3MVRZVzRnUm5KaGJtTnBjMk52TVJRd0VnWURWUVFLRXd0Q2NtRmtabWwwZW1sdVl6RVMKICAgIE1CQUdBMVVFQXhNSmJHOWpZV3hvYjNOME1SMHdHd1lKS29aSWh2Y05BUWtCRmc1aWNtRmtRR1JoYm1kaExtTnYKICAgIGJZSUpBTGZSbFdzSThZUUhNQXdHQTFVZEV3UUZNQU1CQWY4d0RRWUpLb1pJaHZjTkFRRUZCUUFEZ2dFQkFHNmgKICAgIFU5ZjlzTkgwLzZvQmJHR3kyRVZVMFVnSVRVUUlyRldvOXJGa3JXNWsvWGtEalFtKzNsempUMGlHUjRJeEUvQW8KICAgIGVVNnNRaHVhN3dyV2VGRW40N0dMOThsbkNzSmREN29aTmhGbVE5NVRiL0xuRFVqczVZajliclAwTld6WGZZVTQKICAgIFVLMlpuSU5KUmNKcEI4aVJDYUN4RThEZGNVRjBYcUlFcTZwQTI3MnNub0xtaVhMTXZObDNrWUVkbStqZTZ2b0QKICAgIDU4U05WRVVzenR6UXlYbUpFaENwd1ZJMEE2UUNqelhqK3F2cG13M1paSGk4SndYZWk4WlpCTFRTRkJraThaN24KICAgIHNIOUJCSDM4L1N6VW1BTjRRSFNQeTFnanFtMDBPQUU4TmFZRGtoL2J6RTRkN21MR0dNV3AvV0UzS1BTdTgySEYKICAgIGtQZTZYb1NiaUxtL2t4azMyVDA9CiAgICAtLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCiAgICAKCi0gcGF0aDogJy9ldGMvc3lzdGVtZC9zeXN0ZW0vc2V0dXAuc2VydmljZScKICBwZXJtaXNzaW9uczogJzA2NDQnCiAgY29udGVudDogfC0KICAgIFtJbnN0YWxsXQogICAgV2FudGVkQnk9bXVsdGktdXNlci50YXJnZXQKICAgIAogICAgW1VuaXRdCiAgICBSZXF1aXJlcz1uZXR3b3JrLW9ubGluZS50YXJnZXQKICAgIEFmdGVyPW5ldHdvcmstb25saW5lLnRhcmdldAogICAgCiAgICBbU2VydmljZV0KICAgIFR5cGU9b25lc2hvdAogICAgUmVtYWluQWZ0ZXJFeGl0PXRydWUKICAgIEVudmlyb25tZW50RmlsZT0tL2V0Yy9lbnZpcm9ubWVudAogICAgRXhlY1N0YXJ0PS9vcHQvYmluL3N1cGVydmlzZS5zaCAvb3B0L2Jpbi9zZXR1cAogICAgCgotIHBhdGg6ICcvZXRjL3Byb2ZpbGUuZC9vcHQtYmluLXBhdGguc2gnCiAgcGVybWlzc2lvbnM6ICcwNjQ0JwogIGNvbnRlbnQ6IHwtCiAgICBleHBvcnQgUEFUSD0iL29wdC9iaW46JFBBVEgiCiAgICAKCi0gcGF0aDogJy9ldGMva3ViZXJuZXRlcy9rdWJlbGV0LmNvbmYnCiAgY29udGVudDogfC0KICAgIGFwaVZlcnNpb246IGt1YmVsZXQuY29uZmlnLms4cy5pby92MWJldGExCiAgICBraW5kOiBLdWJlbGV0Q29uZmlndXJhdGlvbgogICAgYXV0aGVudGljYXRpb246CiAgICAgIGFub255bW91czoKICAgICAgICBlbmFibGVkOiBmYWxzZQogICAgICB3ZWJob29rOgogICAgICAgIGVuYWJsZWQ6IHRydWUKICAgICAgeDUwOToKICAgICAgICBjbGllbnRDQUZpbGU6IC9ldGMva3ViZXJuZXRlcy9wa2kvY2EuY3J0CiAgICBhdXRob3JpemF0aW9uOgogICAgICBtb2RlOiBXZWJob29rCiAgICBjZ3JvdXBEcml2ZXI6IHN5c3RlbWQKICAgIGNsdXN0ZXJETlM6CiAgICAtICIxMC4wLjAuMCIKICAgIGNsdXN0ZXJEb21haW46IGNsdXN0ZXIubG9jYWwKICAgIGZlYXR1cmVHYXRlczoKICAgICAgR3JhY2VmdWxOb2RlU2h1dGRvd246IHRydWUKICAgICAgSWRlbnRpZnlQb2RPUzogZmFsc2UKICAgIHByb3RlY3RLZXJuZWxEZWZhdWx0czogdHJ1ZQogICAgcmVhZE9ubHlQb3J0OiAwCiAgICByb3RhdGVDZXJ0aWZpY2F0ZXM6IHRydWUKICAgIHNlcnZlclRMU0Jvb3RzdHJhcDogdHJ1ZQogICAgc3RhdGljUG9kUGF0aDogL2V0Yy9rdWJlcm5ldGVzL21hbmlmZXN0cwogICAga3ViZVJlc2VydmVkOgogICAgICBjcHU6IDIwMG0KICAgICAgZXBoZW1lcmFsLXN0b3JhZ2U6IDFHaQogICAgICBtZW1vcnk6IDIwME1pCiAgICBzeXN0ZW1SZXNlcnZlZDoKICAgICAgY3B1OiAyMDBtCiAgICAgIGVwaGVtZXJhbC1zdG9yYWdlOiAxR2kKICAgICAgbWVtb3J5OiAyMDBNaQogICAgZXZpY3Rpb25IYXJkOgogICAgICBpbWFnZWZzLmF2YWlsYWJsZTogMTUlCiAgICAgIG1lbW9yeS5hdmFpbGFibGU6IDEwME1pCiAgICAgIG5vZGVmcy5hdmFpbGFibGU6IDEwJQogICAgICBub2RlZnMuaW5vZGVzRnJlZTogNSUKICAgIHRsc0NpcGhlclN1aXRlczoKICAgIC0gVExTX0FFU18xMjhfR0NNX1NIQTI1NgogICAgLSBUTFNfQUVTXzI1Nl9HQ01fU0hBMzg0CiAgICAtIFRMU19DSEFDSEEyMF9QT0xZMTMwNV9TSEEyNTYKICAgIC0gVExTX0VDREhFX0VDRFNBX1dJVEhfQUVTXzEyOF9HQ01fU0hBMjU2CiAgICAtIFRMU19FQ0RIRV9FQ0RTQV9XSVRIX0FFU18yNTZfR0NNX1NIQTM4NAogICAgLSBUTFNfRUNESEVfRUNEU0FfV0lUSF9DSEFDSEEyMF9QT0xZMTMwNQogICAgLSBUTFNfRUNESEVfUlNBX1dJVEhfQUVTXzEyOF9HQ01fU0hBMjU2CiAgICAtIFRMU19FQ0RIRV9SU0FfV0lUSF9BRVNfMjU2X0dDTV9TSEEzODQKICAgIC0gVExTX0VDREhFX1JTQV9XSVRIX0NIQUNIQTIwX1BPTFkxMzA1CiAgICB2b2x1bWVQbHVnaW5EaXI6IC92YXIvbGliL2t1YmVsZXQvdm9sdW1lcGx1Z2lucwogICAgCgotIHBhdGg6ICcvZXRjL3N5c3RlbWQvc3lzdGVtL2t1YmVsZXQtaGVhbHRoY2hlY2suc2VydmljZScKICBwZXJtaXNzaW9uczogJzA2NDQnCiAgY29udGVudDogfC0KICAgIFtVbml0XQogICAgUmVxdWlyZXM9a3ViZWxldC5zZXJ2aWNlCiAgICBBZnRlcj1rdWJlbGV0LnNlcnZpY2UKICAgIAogICAgW1NlcnZpY2VdCiAgICBFeGVjU3RhcnQ9L29wdC9iaW4vaGVhbHRoLW1vbml0b3Iuc2gga3ViZWxldAogICAgCiAgICBbSW5zdGFsbF0KICAgIFdhbnRlZEJ5PW11bHRpLXVzZXIudGFyZ2V0CiAgICAKCi0gcGF0aDogJy9ldGMvZG9ja2VyL2RhZW1vbi5qc29uJwogIHBlcm1pc3Npb25zOiAnMDY0NCcKICBjb250ZW50OiB8LQogICAgeyJleGVjLW9wdHMiOlsibmF0aXZlLmNncm91cGRyaXZlcj1zeXN0ZW1kIl0sInN0b3JhZ2UtZHJpdmVyIjoib3ZlcmxheTIiLCJsb2ctZHJpdmVyIjoianNvbi1maWxlIiwibG9nLW9wdHMiOnsibWF4LWZpbGUiOiI1IiwibWF4LXNpemUiOiIxMDBtIn0sImluc2VjdXJlLXJlZ2lzdHJpZXMiOlsiMTkyLjE2OC4xMDAuMTAwOjUwMDAiLCIxMC4wLjAuMTo1MDAwIl0sInJlZ2lzdHJ5LW1pcnJvcnMiOlsiaHR0cHM6Ly9yZWdpc3RyeS5kb2NrZXItY24uY29tIl19Cgpib290Y21kOgotIGVjaG8gaGVsbG8KLSBlY2hvIHdvcmxkCgpyaF9zdWJzY3JpcHRpb246CiAgICBwYXNzd29yZDogcGFzc3dvcmQKICAgIHVzZXJuYW1lOiB1c2VybmFtZQ== immutable: true kind: Secret metadata: creationTimestamp: null - name: ubuntu-20.04-aws-osc-provisioning + name: ubuntu-aws-kube-system-osc-provisioning namespace: cloud-init-settings resourceVersion: "1" +type: Opaque diff --git a/pkg/providerconfig/config/config.go b/pkg/providerconfig/config/config.go index 3f59e789..c7fb5406 100644 --- a/pkg/providerconfig/config/config.go +++ b/pkg/providerconfig/config/config.go @@ -26,14 +26,14 @@ import ( var ( // This is shared globally since the enclosing values won't change during the controller lifecycle - ConfigVarResolverInstance providerconfig.ConfigVarResolver + instance providerconfig.ConfigVarResolver ) // SetConfigVarResolver will instantiate the global ConfigVarResolver Instance func SetConfigVarResolver(ctx context.Context, client ctrlruntimeclient.Client, namespace string) { - ConfigVarResolverInstance = *providerconfig.NewConfigVarResolver(ctx, client) + instance = *providerconfig.NewConfigVarResolver(ctx, client) } func GetConfigVarResolver() *providerconfig.ConfigVarResolver { - return &ConfigVarResolverInstance + return &instance }