Ressources

This commit is contained in:
admju 2024-09-06 14:08:05 +00:00
parent 052e6f1368
commit da9aab90eb
8 changed files with 907 additions and 8 deletions

View File

@ -2,6 +2,7 @@ package helm
import (
"fmt"
"strconv"
"os"
"os/exec"
"strings"
@ -41,7 +42,6 @@ func (this HelmChart) Install() (string, error) {
if err != nil {
return "", err
}
// existe := false
if existe {
return "Existe déjà", nil
@ -137,6 +137,7 @@ func (this HelmChart) exists() (bool, error) {
cmd := exec.Command(cmd_args[0], cmd_args[1:]...)
stdout, err := cmd.CombinedOutput()
if err != nil {
log.Log().Debug().Msg(string(stdout))
return false, errors.New(string(stdout))
}
@ -144,6 +145,15 @@ func (this HelmChart) exists() (bool, error) {
res = strings.TrimSuffix(res, "\n")
log.Log().Debug().Msg(string(stdout))
log.Log().Debug().Msg(strconv.FormatBool(res != ""))
return res != "", nil
}
func (this HelmChart) GetRessources() (map[string]string, error) {
hs := HelmStatus{Name: this.Name}
hs.New(this.Bin)
data, _ := hs.getRessources()
return data, nil
}

38
src/helm/command.go Normal file
View File

@ -0,0 +1,38 @@
package helm
import (
"fmt"
"strings"
"errors"
"os/exec"
log "oc-deploy/log_wrapper"
)
type HelmCommandInterface interface {
Status(string) (string, error)
}
type HelmCommandData struct {
bin string
// name string
}
type RealHelmCommandStatus HelmCommandData
func (this RealHelmCommandStatus) Status(name string) (string, error) {
msg := fmt.Sprintf("%s status %s --show-resources -o json", this.bin, name)
log.Log().Debug().Msg(msg)
cmd_args := strings.Split(msg, " ")
cmd := exec.Command(cmd_args[0], cmd_args[1:]...)
stdout, err := cmd.CombinedOutput()
if err != nil {
log.Log().Debug().Msg(string(stdout))
return "", errors.New(string(stdout))
}
return string(stdout), nil
}

84
src/helm/ressources.go Normal file
View File

@ -0,0 +1,84 @@
package helm
import (
// "fmt"
"encoding/json"
)
type HelmStatus struct {
Name string // Nom
command HelmCommandInterface
}
func (this *HelmStatus) New(bin string) {
this.command = RealHelmCommandStatus{bin: bin}
}
func (this *HelmStatus) NewMock(mock HelmCommandInterface) {
this.command = mock
}
////
type parseStatusInfoResourcesMetadata struct {
Name string `json:"name"`
}
// type parseStatusInfoResourcesPod struct {
// Api string `json:"apiVersion"`
// }
type parseStatusInfoResourcesStatefulSet struct {
Api string `json:"apiVersion"`
Kind string `json:"kind"`
Metadata parseStatusInfoResourcesMetadata `json:"metadata"`
}
type parseStatusInfoResourcesDeployment struct {
Api string `json:"apiVersion"`
Kind string `json:"kind"`
Metadata parseStatusInfoResourcesMetadata `json:"metadata"`
}
type parseStatusInfoResources struct {
// Pod []parseStatusInfoResourcesPod `json:"v1/Pod(related)"`
StatefulSet []parseStatusInfoResourcesStatefulSet `json:"v1/StatefulSet"`
Deployment []parseStatusInfoResourcesDeployment `json:"v1/Deployment"`
}
type parseStatusInfo struct {
Status string `json:"status"`
Resources parseStatusInfoResources `json:"Resources"`
}
type parseStatus struct {
Name string `json:"name"`
Info parseStatusInfo `json:"info"`
}
func (this HelmStatus) getRessources() (map[string]string, error) {
res := make(map[string]string)
status, err := this.command.Status(this.Name)
if err != nil {
return res, err
}
var objmap parseStatus
err = json.Unmarshal([]byte(status), &objmap)
if err != nil {
return res, err
}
for _, ele := range objmap.Info.Resources.StatefulSet {
res[ele.Metadata.Name] = ele.Kind
}
for _, ele := range objmap.Info.Resources.Deployment {
res[ele.Metadata.Name] = ele.Kind
}
return res, nil
}

View File

@ -0,0 +1,28 @@
package helm
import (
"os"
"path/filepath"
"testing"
"github.com/stretchr/testify/assert"
)
type MockCommandStatus HelmCommandData
func TestHelmStatus(t *testing.T){
hs := HelmStatus{Name: "oc-catalog"}
hs.NewMock(MockCommandStatus{})
data, _ := hs.getRessources()
assert.Equal(t, "StatefulSet", data["oc-catalog-oc-catalog"], "TestHelmStatus error")
}
// Mock
func (this MockCommandStatus) Status(name string) (string, error) {
fileName := filepath.Join(TEST_SRC_DIR, "helm_status.json")
data, _ := os.ReadFile(fileName)
return string(data), nil
}

View File

@ -134,8 +134,6 @@ func (this *InstallClass) installChart(helm_bin string, kubectl_bin string, char
Values: chart.Values,
FileValues: chart.FileValues}
obj := kubectl.KubeObject{Bin: kubectl_bin,
Name: chart.Name}
res, err := helmchart.Install()
if err != nil {
@ -144,10 +142,19 @@ func (this *InstallClass) installChart(helm_bin string, kubectl_bin string, char
}
log.Log().Info().Msg(fmt.Sprintf(" >> %s (%s)", helmchart.Name, res))
err = obj.Wait()
if err != nil {
log.Log().Error().Msg(fmt.Sprintf(" >> %s %s (%s)", chart.Name, "KO", err))
} else {
log.Log().Info().Msg(fmt.Sprintf(" >> %s %s", chart.Name, "OK"))
ressources, _ := helmchart.GetRessources()
for key, value := range ressources {
obj := kubectl.KubeObject{Bin: kubectl_bin,
Kind: value,
Name: key}
err := obj.Wait()
if err != nil {
log.Log().Error().Msg(fmt.Sprintf(" >> %s/%s KO (%s)", chart.Name, key, err))
} else {
log.Log().Info().Msg(fmt.Sprintf(" >> %s/%s OK", chart.Name, key))
}
}
}

29
src/kubectl/command.go Normal file
View File

@ -0,0 +1,29 @@
package kubectl
// import (
// "fmt"
// )
// type KubectlCommandInterface interface {
// // GetDeployment() (string, error)
// GetDeployment() (string, error)
// }
// type KubectlCommandData struct {
// bin string
// command string
// }
// type Real KubectlCommandStatus KubectlCommandData
// // func (this KubectlCommandStatus) Status() (string, error) {
// // fmt.Println("BIN ", this.bin)
// // fmt.Println("COMMAND status")
// // return "Res de KubectlCommandStatus", nil
// // }
// func (this KubectlCommandStatus) GetDeployment() (string, error) {
// fmt.Println("BIN ", this.bin)
// fmt.Println("COMMAND status")
// return "Res de GetDeployment", nil
// }

View File

@ -13,6 +13,7 @@ import (
type KubeObject struct {
Bin string // Chemin vers le binaire
Name string
Kind string
}
type getOutput struct {
@ -26,6 +27,12 @@ type getStatusOutput struct {
}
func (this KubeObject) Get() (map[string]any, error) {
if this.Kind == "Deployment" {return this.getDeployment()}
if this.Kind == "StatefulSet" {return this.getStatefulSet()}
return make(map[string]any), fmt.Errorf("Kind %s inconnu", this.Kind)
}
func (this KubeObject) getDeployment() (map[string]any, error) {
bin := this.Bin
name := this.Name
@ -57,6 +64,38 @@ func (this KubeObject) Get() (map[string]any, error) {
return m, nil
}
func (this KubeObject) getStatefulSet() (map[string]any, error) {
bin := this.Bin
name := this.Name
msg := fmt.Sprintf("%s get statefulset %s -o json", bin, name)
log.Log().Debug().Msg(msg)
m := make(map[string]any)
cmd_args := strings.Split(msg, " ")
cmd := exec.Command(cmd_args[0], cmd_args[1:]...)
stdout, err := cmd.CombinedOutput()
if err != nil {
return m, errors.New(string(stdout))
}
var objmap getOutput
json.Unmarshal(stdout, &objmap)
kind := objmap.Kind
status := objmap.Status
m["name"] = name
m["kind"] = kind
m["replicas"] = status.Replicas
m["UnavailableReplicas"] = status.UnavailableReplicas
return m, nil
}
func (this KubeObject) Wait() (error) {
boucle := 10
@ -75,6 +114,7 @@ func (this KubeObject) Wait() (error) {
return nil
}
log.Log().Info().Msg(fmt.Sprintf(" >> %s (Unavailable : %d)...", this.Name, ko))
time.Sleep(sleep)
}

663
test/helm/helm_status.json Normal file
View File

@ -0,0 +1,663 @@
{
"name": "oc-catalog",
"info": {
"first_deployed": "2024-09-05T19:06:44.16497388+02:00",
"last_deployed": "2024-09-05T19:06:44.16497388+02:00",
"deleted": "",
"description": "Install complete",
"status": "deployed",
"resources": {
"v1/Pod(related)": [
{
"apiVersion": "v1",
"items": [
{
"apiVersion": "v1",
"kind": "Pod",
"metadata": {
"annotations": {
"cni.projectcalico.org/containerID": "bc524c3ff4a2fceaeb9a996a9324807c0fddfc4c3e02cd59d73a9945d27d5f1b",
"cni.projectcalico.org/podIP": "10.42.2.10/32",
"cni.projectcalico.org/podIPs": "10.42.2.10/32"
},
"creationTimestamp": "2024-09-05T17:06:44Z",
"generateName": "oc-catalog-oc-catalog-",
"labels": {
"app": "oc-catalog",
"apps.kubernetes.io/pod-index": "0",
"controller-revision-hash": "oc-catalog-oc-catalog-7d7859dd76",
"statefulset.kubernetes.io/pod-name": "oc-catalog-oc-catalog-0"
},
"managedFields": [
{
"apiVersion": "v1",
"fieldsType": "FieldsV1",
"fieldsV1": {
"f:metadata": {
"f:annotations": {
".": {},
"f:cni.projectcalico.org/containerID": {},
"f:cni.projectcalico.org/podIP": {},
"f:cni.projectcalico.org/podIPs": {}
}
}
},
"manager": "calico",
"operation": "Update",
"subresource": "status",
"time": "2024-09-05T17:06:44Z"
},
{
"apiVersion": "v1",
"fieldsType": "FieldsV1",
"fieldsV1": {
"f:metadata": {
"f:generateName": {},
"f:labels": {
".": {},
"f:app": {},
"f:apps.kubernetes.io/pod-index": {},
"f:controller-revision-hash": {},
"f:statefulset.kubernetes.io/pod-name": {}
},
"f:ownerReferences": {
".": {},
"k:{\"uid\":\"10aa222e-dc37-451e-a5ee-e88f88b4e136\"}": {}
}
},
"f:spec": {
"f:containers": {
"k:{\"name\":\"oc-catalog\"}": {
".": {},
"f:env": {
".": {},
"k:{\"name\":\"MONGO_DATABASE\"}": {
".": {},
"f:name": {},
"f:value": {}
},
"k:{\"name\":\"MONGO_URI\"}": {
".": {},
"f:name": {},
"f:value": {}
}
},
"f:image": {},
"f:imagePullPolicy": {},
"f:name": {},
"f:ports": {
".": {},
"k:{\"containerPort\":8080,\"protocol\":\"TCP\"}": {
".": {},
"f:containerPort": {},
"f:protocol": {}
}
},
"f:resources": {},
"f:terminationMessagePath": {},
"f:terminationMessagePolicy": {}
}
},
"f:dnsPolicy": {},
"f:enableServiceLinks": {},
"f:hostname": {},
"f:imagePullSecrets": {
".": {},
"k:{\"name\":\"regcred\"}": {}
},
"f:restartPolicy": {},
"f:schedulerName": {},
"f:securityContext": {},
"f:subdomain": {},
"f:terminationGracePeriodSeconds": {}
}
},
"manager": "kube-controller-manager",
"operation": "Update",
"time": "2024-09-05T17:06:44Z"
},
{
"apiVersion": "v1",
"fieldsType": "FieldsV1",
"fieldsV1": {
"f:status": {
"f:conditions": {
"k:{\"type\":\"ContainersReady\"}": {
".": {},
"f:lastProbeTime": {},
"f:lastTransitionTime": {},
"f:status": {},
"f:type": {}
},
"k:{\"type\":\"Initialized\"}": {
".": {},
"f:lastProbeTime": {},
"f:lastTransitionTime": {},
"f:status": {},
"f:type": {}
},
"k:{\"type\":\"Ready\"}": {
".": {},
"f:lastProbeTime": {},
"f:lastTransitionTime": {},
"f:status": {},
"f:type": {}
}
},
"f:containerStatuses": {},
"f:hostIP": {},
"f:phase": {},
"f:podIP": {},
"f:podIPs": {
".": {},
"k:{\"ip\":\"10.42.2.10\"}": {
".": {},
"f:ip": {}
}
},
"f:startTime": {}
}
},
"manager": "kubelet",
"operation": "Update",
"subresource": "status",
"time": "2024-09-05T17:06:46Z"
}
],
"name": "oc-catalog-oc-catalog-0",
"namespace": "default",
"ownerReferences": [
{
"apiVersion": "apps/v1",
"blockOwnerDeletion": true,
"controller": true,
"kind": "StatefulSet",
"name": "oc-catalog-oc-catalog",
"uid": "10aa222e-dc37-451e-a5ee-e88f88b4e136"
}
],
"resourceVersion": "7811984",
"uid": "f2b3e7d0-68de-4f60-a8b7-75446ee3ebf1"
},
"spec": {
"containers": [
{
"env": [
{
"name": "MONGO_DATABASE",
"value": "DC_myDC"
},
{
"name": "MONGO_URI",
"value": "mongodb://mongo:27017"
}
],
"image": "harbor.dtf/dev/oc-catalog:1.0",
"imagePullPolicy": "IfNotPresent",
"name": "oc-catalog",
"ports": [
{
"containerPort": 8080,
"protocol": "TCP"
}
],
"resources": {},
"terminationMessagePath": "/dev/termination-log",
"terminationMessagePolicy": "File",
"volumeMounts": [
{
"mountPath": "/var/run/secrets/kubernetes.io/serviceaccount",
"name": "kube-api-access-lpks6",
"readOnly": true
}
]
}
],
"dnsPolicy": "ClusterFirst",
"enableServiceLinks": true,
"hostname": "oc-catalog-oc-catalog-0",
"imagePullSecrets": [
{
"name": "regcred"
}
],
"nodeName": "rke2-worker1",
"preemptionPolicy": "PreemptLowerPriority",
"priority": 0,
"restartPolicy": "Always",
"schedulerName": "default-scheduler",
"securityContext": {},
"serviceAccount": "default",
"serviceAccountName": "default",
"subdomain": "oc-catalog-oc-catalog",
"terminationGracePeriodSeconds": 30,
"tolerations": [
{
"effect": "NoExecute",
"key": "node.kubernetes.io/not-ready",
"operator": "Exists",
"tolerationSeconds": 300
},
{
"effect": "NoExecute",
"key": "node.kubernetes.io/unreachable",
"operator": "Exists",
"tolerationSeconds": 300
}
],
"volumes": [
{
"name": "kube-api-access-lpks6",
"projected": {
"defaultMode": 420,
"sources": [
{
"serviceAccountToken": {
"expirationSeconds": 3607,
"path": "token"
}
},
{
"configMap": {
"items": [
{
"key": "ca.crt",
"path": "ca.crt"
}
],
"name": "kube-root-ca.crt"
}
},
{
"downwardAPI": {
"items": [
{
"fieldRef": {
"apiVersion": "v1",
"fieldPath": "metadata.namespace"
},
"path": "namespace"
}
]
}
}
]
}
}
]
},
"status": {
"conditions": [
{
"lastProbeTime": null,
"lastTransitionTime": "2024-09-05T17:06:44Z",
"status": "True",
"type": "Initialized"
},
{
"lastProbeTime": null,
"lastTransitionTime": "2024-09-05T17:06:46Z",
"status": "True",
"type": "Ready"
},
{
"lastProbeTime": null,
"lastTransitionTime": "2024-09-05T17:06:46Z",
"status": "True",
"type": "ContainersReady"
},
{
"lastProbeTime": null,
"lastTransitionTime": "2024-09-05T17:06:44Z",
"status": "True",
"type": "PodScheduled"
}
],
"containerStatuses": [
{
"containerID": "containerd://b50252d915ab1bdf1ade5c9afff589e8f6b7cd98e1c507eb5f398c390d7f120c",
"image": "harbor.dtf/dev/oc-catalog:1.0",
"imageID": "harbor.dtf/dev/oc-catalog@sha256:b4e135ecc4e69b93636118f42e436eb0948f9781ffbec4911bb944b79fd415b3",
"lastState": {},
"name": "oc-catalog",
"ready": true,
"restartCount": 0,
"started": true,
"state": {
"running": {
"startedAt": "2024-09-05T17:06:46Z"
}
}
}
],
"hostIP": "172.17.40.249",
"phase": "Running",
"podIP": "10.42.2.10",
"podIPs": [
{
"ip": "10.42.2.10"
}
],
"qosClass": "BestEffort",
"startTime": "2024-09-05T17:06:44Z"
}
}
],
"kind": "PodList",
"metadata": {
"resourceVersion": "8001092"
}
}
],
"v1/Service": [
{
"apiVersion": "v1",
"kind": "Service",
"metadata": {
"annotations": {
"meta.helm.sh/release-name": "oc-catalog",
"meta.helm.sh/release-namespace": "default"
},
"creationTimestamp": "2024-09-05T17:06:44Z",
"labels": {
"app.kubernetes.io/managed-by": "Helm"
},
"managedFields": [
{
"apiVersion": "v1",
"fieldsType": "FieldsV1",
"fieldsV1": {
"f:metadata": {
"f:annotations": {
".": {},
"f:meta.helm.sh/release-name": {},
"f:meta.helm.sh/release-namespace": {}
},
"f:labels": {
".": {},
"f:app.kubernetes.io/managed-by": {}
}
},
"f:spec": {
"f:externalTrafficPolicy": {},
"f:internalTrafficPolicy": {},
"f:ports": {
".": {},
"k:{\"port\":8087,\"protocol\":\"TCP\"}": {
".": {},
"f:port": {},
"f:protocol": {},
"f:targetPort": {}
}
},
"f:selector": {},
"f:sessionAffinity": {},
"f:type": {}
}
},
"manager": "helm",
"operation": "Update",
"time": "2024-09-05T17:06:44Z"
}
],
"name": "oc-catalog-oc-catalog",
"namespace": "default",
"resourceVersion": "7811955",
"uid": "bb9f6cd3-298c-4d98-9f6a-59cbd70ddac2"
},
"spec": {
"clusterIP": "10.43.6.251",
"clusterIPs": [
"10.43.6.251"
],
"externalTrafficPolicy": "Cluster",
"internalTrafficPolicy": "Cluster",
"ipFamilies": [
"IPv4"
],
"ipFamilyPolicy": "SingleStack",
"ports": [
{
"nodePort": 32692,
"port": 8087,
"protocol": "TCP",
"targetPort": 8080
}
],
"selector": {
"app": "oc-catalog"
},
"sessionAffinity": "None",
"type": "NodePort"
},
"status": {
"loadBalancer": {}
}
}
],
"v1/StatefulSet": [
{
"apiVersion": "apps/v1",
"kind": "StatefulSet",
"metadata": {
"annotations": {
"meta.helm.sh/release-name": "oc-catalog",
"meta.helm.sh/release-namespace": "default"
},
"creationTimestamp": "2024-09-05T17:06:44Z",
"generation": 1,
"labels": {
"app": "oc-catalog",
"app.kubernetes.io/managed-by": "Helm"
},
"managedFields": [
{
"apiVersion": "apps/v1",
"fieldsType": "FieldsV1",
"fieldsV1": {
"f:metadata": {
"f:annotations": {
".": {},
"f:meta.helm.sh/release-name": {},
"f:meta.helm.sh/release-namespace": {}
},
"f:labels": {
".": {},
"f:app": {},
"f:app.kubernetes.io/managed-by": {}
}
},
"f:spec": {
"f:persistentVolumeClaimRetentionPolicy": {
".": {},
"f:whenDeleted": {},
"f:whenScaled": {}
},
"f:podManagementPolicy": {},
"f:replicas": {},
"f:revisionHistoryLimit": {},
"f:selector": {},
"f:serviceName": {},
"f:template": {
"f:metadata": {
"f:labels": {
".": {},
"f:app": {}
}
},
"f:spec": {
"f:containers": {
"k:{\"name\":\"oc-catalog\"}": {
".": {},
"f:env": {
".": {},
"k:{\"name\":\"MONGO_DATABASE\"}": {
".": {},
"f:name": {},
"f:value": {}
},
"k:{\"name\":\"MONGO_URI\"}": {
".": {},
"f:name": {},
"f:value": {}
}
},
"f:image": {},
"f:imagePullPolicy": {},
"f:name": {},
"f:ports": {
".": {},
"k:{\"containerPort\":8080,\"protocol\":\"TCP\"}": {
".": {},
"f:containerPort": {},
"f:protocol": {}
}
},
"f:resources": {},
"f:terminationMessagePath": {},
"f:terminationMessagePolicy": {}
}
},
"f:dnsPolicy": {},
"f:imagePullSecrets": {
".": {},
"k:{\"name\":\"regcred\"}": {}
},
"f:restartPolicy": {},
"f:schedulerName": {},
"f:securityContext": {},
"f:terminationGracePeriodSeconds": {}
}
},
"f:updateStrategy": {
"f:rollingUpdate": {
".": {},
"f:partition": {}
},
"f:type": {}
}
}
},
"manager": "helm",
"operation": "Update",
"time": "2024-09-05T17:06:44Z"
},
{
"apiVersion": "apps/v1",
"fieldsType": "FieldsV1",
"fieldsV1": {
"f:status": {
"f:availableReplicas": {},
"f:collisionCount": {},
"f:currentReplicas": {},
"f:currentRevision": {},
"f:observedGeneration": {},
"f:readyReplicas": {},
"f:replicas": {},
"f:updateRevision": {},
"f:updatedReplicas": {}
}
},
"manager": "kube-controller-manager",
"operation": "Update",
"subresource": "status",
"time": "2024-09-05T17:06:46Z"
}
],
"name": "oc-catalog-oc-catalog",
"namespace": "default",
"resourceVersion": "7811987",
"uid": "10aa222e-dc37-451e-a5ee-e88f88b4e136"
},
"spec": {
"persistentVolumeClaimRetentionPolicy": {
"whenDeleted": "Retain",
"whenScaled": "Retain"
},
"podManagementPolicy": "OrderedReady",
"replicas": 1,
"revisionHistoryLimit": 10,
"selector": {
"matchLabels": {
"app": "oc-catalog"
}
},
"serviceName": "oc-catalog-oc-catalog",
"template": {
"metadata": {
"creationTimestamp": null,
"labels": {
"app": "oc-catalog"
}
},
"spec": {
"containers": [
{
"env": [
{
"name": "MONGO_DATABASE",
"value": "DC_myDC"
},
{
"name": "MONGO_URI",
"value": "mongodb://mongo:27017"
}
],
"image": "harbor.dtf/dev/oc-catalog:1.0",
"imagePullPolicy": "IfNotPresent",
"name": "oc-catalog",
"ports": [
{
"containerPort": 8080,
"protocol": "TCP"
}
],
"resources": {},
"terminationMessagePath": "/dev/termination-log",
"terminationMessagePolicy": "File"
}
],
"dnsPolicy": "ClusterFirst",
"imagePullSecrets": [
{
"name": "regcred"
}
],
"restartPolicy": "Always",
"schedulerName": "default-scheduler",
"securityContext": {},
"terminationGracePeriodSeconds": 30
}
},
"updateStrategy": {
"rollingUpdate": {
"partition": 0
},
"type": "RollingUpdate"
}
},
"status": {
"availableReplicas": 1,
"collisionCount": 0,
"currentReplicas": 1,
"currentRevision": "oc-catalog-oc-catalog-7d7859dd76",
"observedGeneration": 1,
"readyReplicas": 1,
"replicas": 1,
"updateRevision": "oc-catalog-oc-catalog-7d7859dd76",
"updatedReplicas": 1
}
}
]
}
},
"config": {
"image": {
"repository": "harbor.dtf/dev/oc-catalog",
"tag": "1.0"
}
},
"manifest": "---\n# Source: oc-catalog/templates/service.yml\napiVersion: v1\nkind: Service\nmetadata:\n name: oc-catalog-oc-catalog\nspec:\n selector:\n app: oc-catalog\n ports:\n - protocol: TCP\n port: 8087\n targetPort: 8080\n type: NodePort\n---\n# Source: oc-catalog/templates/statefulset.yml\napiVersion: apps/v1\nkind: StatefulSet\nmetadata:\n name: oc-catalog-oc-catalog\n labels:\n app: oc-catalog\nspec:\n serviceName: \"oc-catalog-oc-catalog\"\n replicas: 1\n selector:\n matchLabels:\n app: oc-catalog\n template:\n metadata:\n labels:\n app: oc-catalog\n spec:\n containers:\n - name: oc-catalog\n image: \"harbor.dtf/dev/oc-catalog:1.0\"\n ports:\n - containerPort: 8080\n env:\n - name: MONGO_DATABASE\n value: \"DC_myDC\"\n - name: MONGO_URI\n value: \"mongodb://mongo:27017\"\n imagePullSecrets:\n - name: regcred\n",
"version": 1,
"namespace": "default"
}