Przeglądaj źródła

convert multi-document yaml into array of jsons

sunguroku 5 lat temu
rodzic
commit
3b1d4572d0

+ 231 - 0
internal/helm/manifest_parser/manifest.yaml

@@ -0,0 +1,231 @@
+---
+# Source: cassandra/templates/cassandra-secret.yaml
+apiVersion: v1
+kind: Secret
+metadata:
+  name: my-release-cassandra
+  namespace: default
+  labels:
+    app.kubernetes.io/name: cassandra
+    helm.sh/chart: cassandra-6.0.1
+    app.kubernetes.io/instance: my-release
+    app.kubernetes.io/managed-by: Helm
+type: Opaque
+data:
+  cassandra-password: "SFVZRzR2VU4zaQ=="
+---
+# Source: cassandra/templates/headless-svc.yaml
+apiVersion: v1
+kind: Service
+metadata:
+  name: my-release-cassandra-headless
+  namespace: default
+  labels:
+    app.kubernetes.io/name: cassandra
+    helm.sh/chart: cassandra-6.0.1
+    app.kubernetes.io/instance: my-release
+    app.kubernetes.io/managed-by: Helm
+spec:
+  clusterIP: None
+  publishNotReadyAddresses: true
+  ports:
+    - name: intra
+      port: 7000
+      targetPort: intra
+    - name: tls
+      port: 7001
+      targetPort: tls
+    - name: jmx
+      port: 7199
+      targetPort: jmx
+    - name: cql
+      port: 9042
+      targetPort: cql
+    - name: thrift
+      port: 9160
+      targetPort: thrift
+  selector:
+    app.kubernetes.io/name: cassandra
+    app.kubernetes.io/instance: my-release
+---
+# Source: cassandra/templates/service.yaml
+apiVersion: v1
+kind: Service
+metadata:
+  name: my-release-cassandra
+  namespace: default
+  labels:
+    app.kubernetes.io/name: cassandra
+    helm.sh/chart: cassandra-6.0.1
+    app.kubernetes.io/instance: my-release
+    app.kubernetes.io/managed-by: Helm
+spec:
+  type: ClusterIP
+  ports:
+    - name: cql
+      port: 9042
+      targetPort: cql
+      nodePort: null
+    - name: thrift
+      port: 9160
+      targetPort: thrift
+      nodePort: null
+    - name: metrics
+      port: 8080
+      nodePort: null
+  selector:
+    app.kubernetes.io/name: cassandra
+    app.kubernetes.io/instance: my-release
+---
+# Source: cassandra/templates/statefulset.yaml
+apiVersion: apps/v1
+kind: StatefulSet
+metadata:
+  name: my-release-cassandra
+  namespace: default
+  labels:
+    app.kubernetes.io/name: cassandra
+    helm.sh/chart: cassandra-6.0.1
+    app.kubernetes.io/instance: my-release
+    app.kubernetes.io/managed-by: Helm
+spec:
+  selector:
+    matchLabels:
+      app.kubernetes.io/name: cassandra
+      app.kubernetes.io/instance: my-release
+  serviceName: my-release-cassandra-headless
+  podManagementPolicy: OrderedReady
+  replicas: 1
+  updateStrategy:
+    type: RollingUpdate
+  template:
+    metadata:
+      labels:
+        app.kubernetes.io/name: cassandra
+        helm.sh/chart: cassandra-6.0.1
+        app.kubernetes.io/instance: my-release
+        app.kubernetes.io/managed-by: Helm
+    spec:
+      
+      affinity:
+        podAffinity:
+          
+        podAntiAffinity:
+          preferredDuringSchedulingIgnoredDuringExecution:
+            - podAffinityTerm:
+                labelSelector:
+                  matchLabels:
+                    app.kubernetes.io/name: cassandra
+                    app.kubernetes.io/instance: my-release
+                namespaces:
+                  - default
+                topologyKey: kubernetes.io/hostname
+              weight: 1
+        nodeAffinity:
+          
+      securityContext:
+        fsGroup: 1001
+      containers:
+        - name: cassandra
+          command:
+            - bash
+            - -ec
+            - |
+              # Node 0 is the password seeder
+              if [[ $HOSTNAME =~ (.*)-0$ ]]; then
+                  echo "Setting node as password seeder"
+                  export CASSANDRA_PASSWORD_SEEDER=yes
+              else
+                  # Only node 0 will execute the startup initdb scripts
+                  export CASSANDRA_IGNORE_INITDB_SCRIPTS=1
+              fi
+              /opt/bitnami/scripts/cassandra/entrypoint.sh /opt/bitnami/scripts/cassandra/run.sh
+          image: docker.io/bitnami/cassandra:3.11.8-debian-10-r20
+          imagePullPolicy: "IfNotPresent"
+          securityContext:
+            runAsUser: 1001
+          env:
+            - name: BITNAMI_DEBUG
+              value: "false"
+            - name: CASSANDRA_CLUSTER_NAME
+              value: cassandra
+            - name: CASSANDRA_SEEDS
+              value: "my-release-cassandra-0.my-release-cassandra-headless.default.svc.cluster.local"
+            - name: CASSANDRA_PASSWORD
+              valueFrom:
+                secretKeyRef:
+                  name: my-release-cassandra
+                  key: cassandra-password
+            - name: POD_IP
+              valueFrom:
+                fieldRef:
+                  fieldPath: status.podIP
+            - name: CASSANDRA_USER
+              value: "cassandra"
+            - name: CASSANDRA_NUM_TOKENS
+              value: "256"
+            - name: CASSANDRA_DATACENTER
+              value: dc1
+            - name: CASSANDRA_ENDPOINT_SNITCH
+              value: SimpleSnitch
+            - name: CASSANDRA_RACK
+              value: rack1
+            - name: CASSANDRA_ENABLE_RPC
+              value: "true"
+          envFrom:
+          livenessProbe:
+            exec:
+              command:
+                - /bin/bash
+                - -ec
+                - |
+                  nodetool status
+            initialDelaySeconds: 60
+            periodSeconds: 30
+            timeoutSeconds: 5
+            successThreshold: 1
+            failureThreshold: 5
+          readinessProbe:
+            exec:
+              command:
+                - /bin/bash
+                - -ec
+                - |
+                  nodetool status | grep -E "^UN\\s+${POD_IP}"
+            initialDelaySeconds: 60
+            periodSeconds: 10
+            timeoutSeconds: 5
+            successThreshold: 1
+            failureThreshold: 5
+          ports:
+            - name: intra
+              containerPort: 7000
+            - name: tls
+              containerPort: 7001
+            - name: jmx
+              containerPort: 7199
+            - name: cql
+              containerPort: 9042
+            - name: thrift
+              containerPort: 9160
+          resources: 
+            limits: {}
+            requests: {}
+          volumeMounts:
+            - name: data
+              mountPath: /bitnami/cassandra
+            
+      volumes:
+  volumeClaimTemplates:
+    - metadata:
+        name: data
+        labels:
+          app.kubernetes.io/name: cassandra
+          app.kubernetes.io/instance: my-release
+      spec:
+        accessModes:
+          - "ReadWriteOnce"
+        resources:
+          requests:
+            storage: "8Gi"
+

+ 82 - 0
internal/helm/manifest_parser/parser.go

@@ -0,0 +1,82 @@
+package main
+
+import (
+	"bytes"
+	"encoding/json"
+	"fmt"
+	"io/ioutil"
+
+	"gopkg.in/yaml.v2"
+)
+
+func main() {
+	file, err := ioutil.ReadFile("./manifest.yaml")
+
+	if err != nil {
+		panic("AHHHHHH")
+	}
+
+	yamlArr := Parse(file)
+
+	for _, v := range yamlArr {
+		strmap := convertYAMLToJSON(v)
+		js, err := json.Marshal(strmap)
+		if err != nil {
+			fmt.Println(err)
+		}
+		fmt.Println(string(js))
+	}
+}
+
+// Parse is a helper function that goes through a yaml file with multiple documents (or objects)
+// separated by '---' or '...' and returns an array of yamls.
+func Parse(source []byte) (arr []map[interface{}]interface{}) {
+	dec := yaml.NewDecoder(bytes.NewReader(source))
+
+	for {
+		doc := make(map[interface{}]interface{})
+		if dec.Decode(&doc) != nil {
+			return arr
+		}
+		arr = append(arr, doc)
+	}
+
+}
+
+func convertYAMLToJSON(yaml map[interface{}]interface{}) map[string]interface{} {
+	strmap := recursiveConv(yaml).(map[string]interface{})
+	return strmap
+}
+
+// Recursively convert all key values in generic interface{} format into strings.
+// i.e. map[interface{}]interface{} --> map[string]interface{}
+func recursiveConv(m interface{}) interface{} {
+	switch o := m.(type) {
+
+	// quickly skip if object already has strings as keys
+	case map[string]interface{}:
+		for k, v := range o {
+			o[k] = recursiveConv(v)
+		}
+
+	case map[interface{}]interface{}:
+		res := make(map[string]interface{})
+		for k, v := range o {
+			// ✨ sprinkle of efficiency by skipping string keys
+			switch kt := k.(type) {
+			case string:
+				res[kt] = recursiveConv(v)
+			default:
+				res[fmt.Sprint(kt)] = recursiveConv(v)
+			}
+		}
+		m = res
+
+	case []interface{}:
+		for i, v := range o {
+			o[i] = recursiveConv(v)
+		}
+	}
+
+	return m
+}