diff --git a/pkg/api/server.go b/pkg/api/server.go index 78297f7..8d7b7c3 100644 --- a/pkg/api/server.go +++ b/pkg/api/server.go @@ -305,6 +305,15 @@ func (h handler) getAPIV1ClusterResources(w http.ResponseWriter, r *http.Request w.WriteHeader(http.StatusInternalServerError) return } + case "configmaps": + result = k8s.GetEmptyConfigMapList() + dirName := filepath.Join(h.clusterData.ClusterResourcesDir, sbctlutil.GetSBCompatibleResourceName(resource)) + filenames, err = getJSONFileListFromDir(dirName) + if err != nil { + log.Error("failed to get configmap files from dir: ", err) + w.WriteHeader(http.StatusInternalServerError) + return + } } for _, fileName := range filenames { @@ -359,6 +368,9 @@ func (h handler) getAPIV1ClusterResources(w http.ResponseWriter, r *http.Request case *corev1.PersistentVolumeClaimList: r := result.(*corev1.PersistentVolumeClaimList) r.Items = append(r.Items, o.Items...) + case *corev1.ConfigMapList: + r := result.(*corev1.ConfigMapList) + r.Items = append(r.Items, o.Items...) default: result, err = sbctl.ToUnstructuredList(decoded) if err != nil { @@ -580,6 +592,13 @@ func (h handler) getAPIV1NamespaceResource(w http.ResponseWriter, r *http.Reques return } } + case *corev1.ConfigMapList: + for _, item := range o.Items { + if item.Name == name { + JSON(w, http.StatusOK, item) + return + } + } default: uObjList, err := sbctl.ToUnstructuredList(decoded) if err != nil { @@ -1601,6 +1620,13 @@ func toTable(object runtime.Object, r *http.Request) (runtime.Object, error) { return nil, errors.Wrap(err, "failed to convert ingress list") } object = converted + case *corev1.ConfigMapList: + converted := &apicore.ConfigMapList{} + err := apicorev1.Convert_v1_ConfigMapList_To_core_ConfigMapList(o, converted, nil) + if err != nil { + return nil, errors.Wrap(err, "failed to convert configmap list") + } + object = converted } ctx := context.TODO() diff --git a/pkg/k8s/objects.go b/pkg/k8s/objects.go index e7dfdec..cb3aed9 100644 --- a/pkg/k8s/objects.go +++ b/pkg/k8s/objects.go @@ -59,3 +59,14 @@ func GetEmptyPersistentVolumeClaimList() *corev1.PersistentVolumeClaimList { }) return r } + +func GetEmptyConfigMapList() *corev1.ConfigMapList { + r := &corev1.ConfigMapList{ + Items: []corev1.ConfigMap{}, + } + r.GetObjectKind().SetGroupVersionKind(schema.GroupVersionKind{ + Version: "v1", + Kind: "ConfigMapList", + }) + return r +} diff --git a/pkg/sbctl/compatibility.go b/pkg/sbctl/compatibility.go index 16460b9..2159d87 100644 --- a/pkg/sbctl/compatibility.go +++ b/pkg/sbctl/compatibility.go @@ -184,6 +184,13 @@ func Decode(resource string, data []byte) (runtime.Object, *schema.GroupVersionK Version: "v1", }) } + case *corev1.ConfigMapList: + for i := range o.Items { + o.Items[i].GetObjectKind().SetGroupVersionKind(schema.GroupVersionKind{ + Kind: "ConfigMap", + Version: "v1", + }) + } } return decoded, gvk, nil diff --git a/tests/configmaps_test.go b/tests/configmaps_test.go new file mode 100644 index 0000000..daa68d1 --- /dev/null +++ b/tests/configmaps_test.go @@ -0,0 +1,38 @@ +package tests + +import ( + _ "embed" + "fmt" + "net/http" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" +) + +//go:embed results/configmaps_all_namespaces.json +var expectedGetAllConfigmapsResult string + +//go:embed results/configmaps_kube_public_namespace.json +var expectedGetKubePublicConfigmapsResult string + +var _ = Describe("GET /api/v1/configmaps", func() { + Context("When getting configmaps in all namespaces", func() { + It("Returns all configmaps", func() { + resp, statusCode, err := HTTPExec("GET", fmt.Sprintf("%s/api/v1/configmaps", apiServerEndpoint), getHeaders) + Expect(err).NotTo(HaveOccurred()) + Expect(statusCode).To(Equal(http.StatusOK)) + Expect(resp).To(Similar(expectedGetAllConfigmapsResult)) + }) + }) +}) + +var _ = Describe("GET /api/v1/namespaces/{namespace}/configmaps", func() { + Context("When getting configmaps in kube-public namespace", func() { + It("Returns kube-public configmaps", func() { + resp, statusCode, err := HTTPExec("GET", fmt.Sprintf("%s/api/v1/namespaces/kube-public/configmaps", apiServerEndpoint), getHeaders) + Expect(err).NotTo(HaveOccurred()) + Expect(statusCode).To(Equal(http.StatusOK)) + Expect(resp).To(Similar(expectedGetKubePublicConfigmapsResult)) + }) + }) +}) diff --git a/tests/results/configmaps_all_namespaces.json b/tests/results/configmaps_all_namespaces.json new file mode 100644 index 0000000..b641118 --- /dev/null +++ b/tests/results/configmaps_all_namespaces.json @@ -0,0 +1 @@ +{"kind":"Table","apiVersion":"meta.k8s.io/v1","metadata":{},"columnDefinitions":[{"name":"Name","type":"string","format":"name","description":"Name must be unique within a namespace. Is required when creating resources, although some resources may allow a client to request the generation of an appropriate name automatically. Name is primarily intended for creation idempotence and configuration definition. Cannot be updated. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names#names","priority":0},{"name":"Data","type":"string","format":"","description":"Data contains the configuration data. Each key must consist of alphanumeric characters, '-', '_' or '.'. Values with non-UTF-8 byte sequences must use the BinaryData field. The keys stored in Data must not overlap with the keys in the BinaryData field, this is enforced during validation process.","priority":0},{"name":"Age","type":"string","format":"","description":"CreationTimestamp is a timestamp representing the server time when this object was created. It is not guaranteed to be set in happens-before order across separate operations. Clients may not set this value. It is represented in RFC3339 form and is in UTC.\n\nPopulated by the system. Read-only. Null for lists. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata","priority":0}],"rows":[{"cells":["kotsadm-application-metadata",2,"64d"],"object":{"kind":"PartialObjectMetadata","apiVersion":"meta.k8s.io/v1","metadata":{"name":"kotsadm-application-metadata","namespace":"default","uid":"eb16ac64-ffce-4963-83e9-de63850b736e","resourceVersion":"5021","creationTimestamp":"2024-02-17T06:16:47Z","labels":{"kots.io/backup":"velero","kots.io/kotsadm":"true","kotsadm":"application"},"managedFields":[{"manager":"kubectl-kots","operation":"Update","apiVersion":"v1","time":"2024-02-17T06:16:47Z","fieldsType":"FieldsV1","fieldsV1":{"f:data":{".":{},"f:application.yaml":{},"f:upstreamUri":{}},"f:metadata":{"f:labels":{".":{},"f:kots.io/backup":{},"f:kots.io/kotsadm":{},"f:kotsadm":{}}}}}]}}},{"cells":["kube-root-ca.crt",1,"64d"],"object":{"kind":"PartialObjectMetadata","apiVersion":"meta.k8s.io/v1","metadata":{"name":"kube-root-ca.crt","namespace":"default","uid":"f3f8cc0f-8434-465b-87a8-d58a44fdb575","resourceVersion":"331","creationTimestamp":"2024-02-17T05:55:36Z","annotations":{"kubernetes.io/description":"Contains a CA bundle that can be used to verify the kube-apiserver when using internal endpoints such as the internal service IP or kubernetes.default.svc. No other usage is guaranteed across distributions of Kubernetes clusters."},"managedFields":[{"manager":"kube-controller-manager","operation":"Update","apiVersion":"v1","time":"2024-02-17T05:55:36Z","fieldsType":"FieldsV1","fieldsV1":{"f:data":{".":{},"f:ca.crt":{}},"f:metadata":{"f:annotations":{".":{},"f:kubernetes.io/description":{}}}}}]}}},{"cells":["kube-root-ca.crt",1,"64d"],"object":{"kind":"PartialObjectMetadata","apiVersion":"meta.k8s.io/v1","metadata":{"name":"kube-root-ca.crt","namespace":"kube-node-lease","uid":"01acb543-79cc-4e17-a3de-e846b80a20f9","resourceVersion":"332","creationTimestamp":"2024-02-17T05:55:36Z","annotations":{"kubernetes.io/description":"Contains a CA bundle that can be used to verify the kube-apiserver when using internal endpoints such as the internal service IP or kubernetes.default.svc. No other usage is guaranteed across distributions of Kubernetes clusters."},"managedFields":[{"manager":"kube-controller-manager","operation":"Update","apiVersion":"v1","time":"2024-02-17T05:55:36Z","fieldsType":"FieldsV1","fieldsV1":{"f:data":{".":{},"f:ca.crt":{}},"f:metadata":{"f:annotations":{".":{},"f:kubernetes.io/description":{}}}}}]}}},{"cells":["kube-root-ca.crt",1,"64d"],"object":{"kind":"PartialObjectMetadata","apiVersion":"meta.k8s.io/v1","metadata":{"name":"kube-root-ca.crt","namespace":"kube-public","uid":"c42025cc-2d96-4626-805a-b7fc0575f24c","resourceVersion":"333","creationTimestamp":"2024-02-17T05:55:36Z","annotations":{"kubernetes.io/description":"Contains a CA bundle that can be used to verify the kube-apiserver when using internal endpoints such as the internal service IP or kubernetes.default.svc. No other usage is guaranteed across distributions of Kubernetes clusters."},"managedFields":[{"manager":"kube-controller-manager","operation":"Update","apiVersion":"v1","time":"2024-02-17T05:55:36Z","fieldsType":"FieldsV1","fieldsV1":{"f:data":{".":{},"f:ca.crt":{}},"f:metadata":{"f:annotations":{".":{},"f:kubernetes.io/description":{}}}}}]}}}]} diff --git a/tests/results/configmaps_kube_public_namespace.json b/tests/results/configmaps_kube_public_namespace.json new file mode 100644 index 0000000..b7d0eb6 --- /dev/null +++ b/tests/results/configmaps_kube_public_namespace.json @@ -0,0 +1 @@ +{"kind":"Table","apiVersion":"meta.k8s.io/v1","metadata":{"resourceVersion":"32367474"},"columnDefinitions":[{"name":"Name","type":"string","format":"name","description":"Name must be unique within a namespace. Is required when creating resources, although some resources may allow a client to request the generation of an appropriate name automatically. Name is primarily intended for creation idempotence and configuration definition. Cannot be updated. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names#names","priority":0},{"name":"Data","type":"string","format":"","description":"Data contains the configuration data. Each key must consist of alphanumeric characters, '-', '_' or '.'. Values with non-UTF-8 byte sequences must use the BinaryData field. The keys stored in Data must not overlap with the keys in the BinaryData field, this is enforced during validation process.","priority":0},{"name":"Age","type":"string","format":"","description":"CreationTimestamp is a timestamp representing the server time when this object was created. It is not guaranteed to be set in happens-before order across separate operations. Clients may not set this value. It is represented in RFC3339 form and is in UTC.\n\nPopulated by the system. Read-only. Null for lists. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata","priority":0}],"rows":[{"cells":["kube-root-ca.crt",1,"64d"],"object":{"kind":"PartialObjectMetadata","apiVersion":"meta.k8s.io/v1","metadata":{"name":"kube-root-ca.crt","namespace":"kube-public","uid":"c42025cc-2d96-4626-805a-b7fc0575f24c","resourceVersion":"333","creationTimestamp":"2024-02-17T05:55:36Z","annotations":{"kubernetes.io/description":"Contains a CA bundle that can be used to verify the kube-apiserver when using internal endpoints such as the internal service IP or kubernetes.default.svc. No other usage is guaranteed across distributions of Kubernetes clusters."},"managedFields":[{"manager":"kube-controller-manager","operation":"Update","apiVersion":"v1","time":"2024-02-17T05:55:36Z","fieldsType":"FieldsV1","fieldsV1":{"f:data":{".":{},"f:ca.crt":{}},"f:metadata":{"f:annotations":{".":{},"f:kubernetes.io/description":{}}}}}]}}}]} diff --git a/tests/support-bundle/cluster-resources/configmaps/default.json b/tests/support-bundle/cluster-resources/configmaps/default.json new file mode 100644 index 0000000..2b59343 --- /dev/null +++ b/tests/support-bundle/cluster-resources/configmaps/default.json @@ -0,0 +1,92 @@ +{ + "kind": "ConfigMapList", + "apiVersion": "v1", + "metadata": { + "resourceVersion": "32367468" + }, + "items": [ + { + "kind": "ConfigMap", + "apiVersion": "v1", + "metadata": { + "name": "kotsadm-application-metadata", + "namespace": "default", + "uid": "eb16ac64-ffce-4963-83e9-de63850b736e", + "resourceVersion": "5021", + "creationTimestamp": "2024-02-17T06:16:47Z", + "labels": { + "kots.io/backup": "velero", + "kots.io/kotsadm": "true", + "kotsadm": "application" + }, + "managedFields": [ + { + "manager": "kubectl-kots", + "operation": "Update", + "apiVersion": "v1", + "time": "2024-02-17T06:16:47Z", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:data": { + ".": {}, + "f:application.yaml": {}, + "f:upstreamUri": {} + }, + "f:metadata": { + "f:labels": { + ".": {}, + "f:kots.io/backup": {}, + "f:kots.io/kotsadm": {}, + "f:kotsadm": {} + } + } + } + } + ] + }, + "data": { + "application.yaml": "apiVersion: kots.io/v1beta1\nkind: Application\nmetadata:\n annotations:\n kots.io/exclude: \"true\"\n creationTimestamp: null\n name: Stoplight\nspec:\n icon: https://stoplight.io/images/mark_light_bg.png\n releaseNotes: See https://stoplight.io/blog/ for release updates.\n requireMinimalRBACPrivileges: true\n statusInformers:\n - deployment/platform-worker\n title: Stoplight\nstatus: {}\n", + "upstreamUri": "replicated://replicatehq/stable" + } + }, + { + "kind": "ConfigMap", + "Kind": "ConfigMap", + "apiVersion": "v1", + "metadata": { + "name": "kube-root-ca.crt", + "namespace": "default", + "uid": "f3f8cc0f-8434-465b-87a8-d58a44fdb575", + "resourceVersion": "331", + "creationTimestamp": "2024-02-17T05:55:36Z", + "annotations": { + "kubernetes.io/description": "Contains a CA bundle that can be used to verify the kube-apiserver when using internal endpoints such as the internal service IP or kubernetes.default.svc. No other usage is guaranteed across distributions of Kubernetes clusters." + }, + "managedFields": [ + { + "manager": "kube-controller-manager", + "operation": "Update", + "apiVersion": "v1", + "time": "2024-02-17T05:55:36Z", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:data": { + ".": {}, + "f:ca.crt": {} + }, + "f:metadata": { + "f:annotations": { + ".": {}, + "f:kubernetes.io/description": {} + } + } + } + } + ] + }, + "data": { + "ca.crt": "-----BEGIN CERTIFICATE-----\nMIIDBTCCAe2gAwIBAgIIaDHtQlkhzfMwDQYJKoZIhvcNAQELBQAwFTETMBEGA1UE\nAxMKa3ViZXJuZXRlczAeFw0yNDAyMTcwNTQ5NTdaFw0zNDAyMTQwNTU0NTdaMBUx\nEzARBgNVBAMTCmt1YmVybmV0ZXMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK\nAoIBAQDH/Q7uWgAMLl/KKv4jL9N+eRdcvU00S08IWF81aAW9vCKkrn9fUhdjznP0\njHXhTnRIyOjkLsRif60pFM9eziHPHMLMlwqvPzVq4RPtOJCLGvWsdm18DTzBIM0v\ncvj3ZhCHqwNoHpEcmeLcIPZhXUTP9P/HymHN7McPWlCubkUK0Rd3ZJcZTwlzNiSV\nLVm34/28sY0zQZslDKIz3prUQ9r4LtEX4Vj56Zj4H+DH+82JpIh3CQ2BCiLzUzrg\n5c1L4uQ6FKj9FH/Hgyz2ttVcCU38ObgX1ASaBXZtsHZPY07S7GLi6czrdcxdSEvb\nZDeCuG5c/4M0dP6Skz07sr3tF26tAgMBAAGjWTBXMA4GA1UdDwEB/wQEAwICpDAP\nBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBSzYh2i904R82VVx7d3syCW0ZkS7DAV\nBgNVHREEDjAMggprdWJlcm5ldGVzMA0GCSqGSIb3DQEBCwUAA4IBAQC+T2TvKB/V\ncPQ5QIeSNEolAe/B5MoSCao+WZTpo9P46Xq5kU9pGUVRFPi1/fVdHSgd1ZuRUPxl\n83GVy4Wsf2squXW8IrYFMeX2jZKVEGh6roAb4wUexTpouSyv+5Mln5Ov/dt8oV1a\nMUeRfWUiDlwunEX9Luly6BITE9uB5m3VR4GxlnuFL4f92rurXXNVoGMBwJohaYSj\nwYoZ+HvG2rl8aB7pnjiypAcZUpBtB9xkY4wtTOZ1lrR5jXjAYwDh4N1TvSRsSk60\nLUpoWZ+nAq3qvKoe1/511lKNWYvHW6cx//Bn3MZKfILInBLA0VK0OJJ0x+Kh6TFl\nV77zhWyQ9IXN\n-----END CERTIFICATE-----\n" + } + } + ] +} diff --git a/tests/support-bundle/cluster-resources/configmaps/kube-node-lease.json b/tests/support-bundle/cluster-resources/configmaps/kube-node-lease.json new file mode 100644 index 0000000..835f343 --- /dev/null +++ b/tests/support-bundle/cluster-resources/configmaps/kube-node-lease.json @@ -0,0 +1,47 @@ +{ + "kind": "ConfigMapList", + "apiVersion": "v1", + "metadata": { + "resourceVersion": "32367473" + }, + "items": [ + { + "kind": "ConfigMap", + "apiVersion": "v1", + "metadata": { + "name": "kube-root-ca.crt", + "namespace": "kube-node-lease", + "uid": "01acb543-79cc-4e17-a3de-e846b80a20f9", + "resourceVersion": "332", + "creationTimestamp": "2024-02-17T05:55:36Z", + "annotations": { + "kubernetes.io/description": "Contains a CA bundle that can be used to verify the kube-apiserver when using internal endpoints such as the internal service IP or kubernetes.default.svc. No other usage is guaranteed across distributions of Kubernetes clusters." + }, + "managedFields": [ + { + "manager": "kube-controller-manager", + "operation": "Update", + "apiVersion": "v1", + "time": "2024-02-17T05:55:36Z", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:data": { + ".": {}, + "f:ca.crt": {} + }, + "f:metadata": { + "f:annotations": { + ".": {}, + "f:kubernetes.io/description": {} + } + } + } + } + ] + }, + "data": { + "ca.crt": "-----BEGIN CERTIFICATE-----\nMIIDBTCCAe2gAwIBAgIIaDHtQlkhzfMwDQYJKoZIhvcNAQELBQAwFTETMBEGA1UE\nAxMKa3ViZXJuZXRlczAeFw0yNDAyMTcwNTQ5NTdaFw0zNDAyMTQwNTU0NTdaMBUx\nEzARBgNVBAMTCmt1YmVybmV0ZXMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK\nAoIBAQDH/Q7uWgAMLl/KKv4jL9N+eRdcvU00S08IWF81aAW9vCKkrn9fUhdjznP0\njHXhTnRIyOjkLsRif60pFM9eziHPHMLMlwqvPzVq4RPtOJCLGvWsdm18DTzBIM0v\ncvj3ZhCHqwNoHpEcmeLcIPZhXUTP9P/HymHN7McPWlCubkUK0Rd3ZJcZTwlzNiSV\nLVm34/28sY0zQZslDKIz3prUQ9r4LtEX4Vj56Zj4H+DH+82JpIh3CQ2BCiLzUzrg\n5c1L4uQ6FKj9FH/Hgyz2ttVcCU38ObgX1ASaBXZtsHZPY07S7GLi6czrdcxdSEvb\nZDeCuG5c/4M0dP6Skz07sr3tF26tAgMBAAGjWTBXMA4GA1UdDwEB/wQEAwICpDAP\nBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBSzYh2i904R82VVx7d3syCW0ZkS7DAV\nBgNVHREEDjAMggprdWJlcm5ldGVzMA0GCSqGSIb3DQEBCwUAA4IBAQC+T2TvKB/V\ncPQ5QIeSNEolAe/B5MoSCao+WZTpo9P46Xq5kU9pGUVRFPi1/fVdHSgd1ZuRUPxl\n83GVy4Wsf2squXW8IrYFMeX2jZKVEGh6roAb4wUexTpouSyv+5Mln5Ov/dt8oV1a\nMUeRfWUiDlwunEX9Luly6BITE9uB5m3VR4GxlnuFL4f92rurXXNVoGMBwJohaYSj\nwYoZ+HvG2rl8aB7pnjiypAcZUpBtB9xkY4wtTOZ1lrR5jXjAYwDh4N1TvSRsSk60\nLUpoWZ+nAq3qvKoe1/511lKNWYvHW6cx//Bn3MZKfILInBLA0VK0OJJ0x+Kh6TFl\nV77zhWyQ9IXN\n-----END CERTIFICATE-----\n" + } + } + ] +} diff --git a/tests/support-bundle/cluster-resources/configmaps/kube-public.json b/tests/support-bundle/cluster-resources/configmaps/kube-public.json new file mode 100644 index 0000000..cd12cea --- /dev/null +++ b/tests/support-bundle/cluster-resources/configmaps/kube-public.json @@ -0,0 +1,47 @@ +{ + "kind": "ConfigMapList", + "apiVersion": "v1", + "metadata": { + "resourceVersion": "32367474" + }, + "items": [ + { + "kind": "ConfigMap", + "apiVersion": "v1", + "metadata": { + "name": "kube-root-ca.crt", + "namespace": "kube-public", + "uid": "c42025cc-2d96-4626-805a-b7fc0575f24c", + "resourceVersion": "333", + "creationTimestamp": "2024-02-17T05:55:36Z", + "annotations": { + "kubernetes.io/description": "Contains a CA bundle that can be used to verify the kube-apiserver when using internal endpoints such as the internal service IP or kubernetes.default.svc. No other usage is guaranteed across distributions of Kubernetes clusters." + }, + "managedFields": [ + { + "manager": "kube-controller-manager", + "operation": "Update", + "apiVersion": "v1", + "time": "2024-02-17T05:55:36Z", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:data": { + ".": {}, + "f:ca.crt": {} + }, + "f:metadata": { + "f:annotations": { + ".": {}, + "f:kubernetes.io/description": {} + } + } + } + } + ] + }, + "data": { + "ca.crt": "-----BEGIN CERTIFICATE-----\nMIIDBTCCAe2gAwIBAgIIaDHtQlkhzfMwDQYJKoZIhvcNAQELBQAwFTETMBEGA1UE\nAxMKa3ViZXJuZXRlczAeFw0yNDAyMTcwNTQ5NTdaFw0zNDAyMTQwNTU0NTdaMBUx\nEzARBgNVBAMTCmt1YmVybmV0ZXMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK\nAoIBAQDH/Q7uWgAMLl/KKv4jL9N+eRdcvU00S08IWF81aAW9vCKkrn9fUhdjznP0\njHXhTnRIyOjkLsRif60pFM9eziHPHMLMlwqvPzVq4RPtOJCLGvWsdm18DTzBIM0v\ncvj3ZhCHqwNoHpEcmeLcIPZhXUTP9P/HymHN7McPWlCubkUK0Rd3ZJcZTwlzNiSV\nLVm34/28sY0zQZslDKIz3prUQ9r4LtEX4Vj56Zj4H+DH+82JpIh3CQ2BCiLzUzrg\n5c1L4uQ6FKj9FH/Hgyz2ttVcCU38ObgX1ASaBXZtsHZPY07S7GLi6czrdcxdSEvb\nZDeCuG5c/4M0dP6Skz07sr3tF26tAgMBAAGjWTBXMA4GA1UdDwEB/wQEAwICpDAP\nBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBSzYh2i904R82VVx7d3syCW0ZkS7DAV\nBgNVHREEDjAMggprdWJlcm5ldGVzMA0GCSqGSIb3DQEBCwUAA4IBAQC+T2TvKB/V\ncPQ5QIeSNEolAe/B5MoSCao+WZTpo9P46Xq5kU9pGUVRFPi1/fVdHSgd1ZuRUPxl\n83GVy4Wsf2squXW8IrYFMeX2jZKVEGh6roAb4wUexTpouSyv+5Mln5Ov/dt8oV1a\nMUeRfWUiDlwunEX9Luly6BITE9uB5m3VR4GxlnuFL4f92rurXXNVoGMBwJohaYSj\nwYoZ+HvG2rl8aB7pnjiypAcZUpBtB9xkY4wtTOZ1lrR5jXjAYwDh4N1TvSRsSk60\nLUpoWZ+nAq3qvKoe1/511lKNWYvHW6cx//Bn3MZKfILInBLA0VK0OJJ0x+Kh6TFl\nV77zhWyQ9IXN\n-----END CERTIFICATE-----\n" + } + } + ] +}