diff --git a/.github/workflows/update-artifacts.yml b/.github/workflows/update-artifacts.yml new file mode 100644 index 000000000..162ef96fa --- /dev/null +++ b/.github/workflows/update-artifacts.yml @@ -0,0 +1,54 @@ +name: Update artifacts manifest + +on: + push: + branches: + - main + +jobs: + update-artifacts: + runs-on: ubuntu-latest + steps: + - name: Checkout Code + uses: actions/checkout@v3 + with: + fetch-depth: 0 + + - name: Setup Kubectl + id: install-kubectl + uses: azure/setup-kubectl@v3 + with: + version: 'v1.28.0' + + - name: Setup Helm + uses: azure/setup-helm@v4.2.0 + with: + version: v3.15.1 + + - uses: actions/setup-python@v5 + with: + python-version: '3.10' + + - name: Install python dependencies + run: pip install -r scripts/upload-artifacts/requirements.txt + + # Generate artifacts manifest for inframold charts + - name: Generate Artifacts Manifest for Each Chart + run: | + charts_list=(tfy-k8s-aws-eks-inframold tfy-k8s-azure-aks-inframold tfy-k8s-gcp-gke-autopilot-inframold tfy-k8s-gcp-gke-standard-inframold tfy-k8s-generic-inframold) + for chart in $charts_list; + do + version=$(cat charts/$chart/Chart.yaml | grep version | awk '{print $2}') + python scripts/generate-artifacts-manifest/artifacts_template_generator.py $chart https://truefoundry.github.io/infra-charts/ \ + $version charts/$chart/values.yaml charts/$chart/artifacts-manifest.json scripts/generate-artifacts-manifest/extra.json + done + + # Update the inframold artifacts manifest + - name: Create Pull Request + uses: peter-evans/create-pull-request@v6 + with: + commit-message: Update Inframold artifacts manifest + title: CI Update Inframold Artifacts-${{ github.sha }} + body: Update Inframold artifacts manifest + branch: update-inframold-artifacts-manifest-${{ github.sha }} + delete-branch: true diff --git a/charts/tfy-k8s-aws-eks-inframold/artifacts-manifest.json b/charts/tfy-k8s-aws-eks-inframold/artifacts-manifest.json new file mode 100644 index 000000000..428f773c3 --- /dev/null +++ b/charts/tfy-k8s-aws-eks-inframold/artifacts-manifest.json @@ -0,0 +1,498 @@ +[ + { + "type": "helm", + "details": { + "chart": "argo-rollouts", + "repoURL": "https://argoproj.github.io/argo-helm", + "targetRevision": "2.35.1" + } + }, + { + "type": "helm", + "details": { + "chart": "argo-workflows", + "repoURL": "https://argoproj.github.io/argo-helm", + "targetRevision": "0.41.1" + } + }, + { + "type": "helm", + "details": { + "chart": "tfy-grafana", + "repoURL": "https://truefoundry.github.io/infra-charts/", + "targetRevision": "0.1.4" + } + }, + { + "type": "helm", + "details": { + "chart": "base", + "repoURL": "https://istio-release.storage.googleapis.com/charts", + "targetRevision": "1.21.1" + } + }, + { + "type": "helm", + "details": { + "chart": "istiod", + "repoURL": "https://istio-release.storage.googleapis.com/charts", + "targetRevision": "1.21.1" + } + }, + { + "type": "helm", + "details": { + "chart": "keda", + "repoURL": "https://kedacore.github.io/charts", + "targetRevision": "2.13.2" + } + }, + { + "type": "helm", + "details": { + "chart": "cost-analyzer", + "repoURL": "https://kubecost.github.io/cost-analyzer/", + "targetRevision": "2.1.0" + } + }, + { + "type": "helm", + "details": { + "chart": "tfy-loki", + "repoURL": "https://truefoundry.github.io/infra-charts/", + "targetRevision": "0.1.1" + } + }, + { + "type": "helm", + "details": { + "chart": "metrics-server", + "repoURL": "https://kubernetes-sigs.github.io/metrics-server/", + "targetRevision": "3.12.1" + } + }, + { + "type": "helm", + "details": { + "chart": "tfy-notebook-controller", + "repoURL": "https://truefoundry.github.io/infra-charts/", + "targetRevision": "0.3.7-rc.1" + } + }, + { + "type": "helm", + "details": { + "chart": "kube-prometheus-stack", + "repoURL": "https://prometheus-community.github.io/helm-charts", + "targetRevision": "55.8.1" + } + }, + { + "type": "helm", + "details": { + "chart": "tfy-agent", + "repoURL": "https://truefoundry.github.io/infra-charts/", + "targetRevision": "0.2.22" + } + }, + { + "type": "helm", + "details": { + "chart": "aws-efs-csi-driver", + "repoURL": "https://kubernetes-sigs.github.io/aws-efs-csi-driver/", + "targetRevision": "3.0.5" + } + }, + { + "type": "helm", + "details": { + "chart": "aws-load-balancer-controller", + "repoURL": "https://aws.github.io/eks-charts", + "targetRevision": "1.7.1" + } + }, + { + "type": "helm", + "details": { + "chart": "tfy-karpenter-config", + "repoURL": "https://truefoundry.github.io/infra-charts/", + "targetRevision": "0.1.29" + } + }, + { + "type": "helm", + "details": { + "chart": "tfy-karpenter", + "repoURL": "https://truefoundry.github.io/infra-charts/", + "targetRevision": "0.3.0" + } + }, + { + "type": "helm", + "details": { + "chart": "tfy-gpu-operator", + "repoURL": "https://truefoundry.github.io/infra-charts/", + "targetRevision": "0.1.16-rc.5" + } + }, + { + "type": "helm", + "details": { + "chart": "argo-cd", + "repoURL": "https://argoproj.github.io/argo-helm", + "targetRevision": "6.7.10" + } + }, + { + "type": "helm", + "details": { + "chart": "tfy-istio-ingress", + "repoURL": "https://truefoundry.github.io/infra-charts/", + "targetRevision": "0.1.3" + } + }, + { + "type": "helm", + "details": { + "chart": "aws-ebs-csi-driver", + "repoURL": "https://kubernetes-sigs.github.io/aws-ebs-csi-driver", + "targetRevision": "2.31.0" + } + }, + { + "type": "image", + "details": { + "registryURL": "quay.io/argoproj/argo-rollouts:v1.6.6" + } + }, + { + "type": "image", + "details": { + "registryURL": "quay.io/argoproj/workflow-controller:v3.5.5" + } + }, + { + "type": "image", + "details": { + "registryURL": "quay.io/argoproj/argocli:v3.5.5" + } + }, + { + "type": "image", + "details": { + "registryURL": "docker.io/grafana/grafana:10.0.3" + } + }, + { + "type": "image", + "details": { + "registryURL": "docker.io/library/busybox:1.31.1" + } + }, + { + "type": "image", + "details": { + "registryURL": "docker.io/bats/bats:v1.4.1" + } + }, + { + "type": "image", + "details": { + "registryURL": "gcr.io/istio-release/pilot:1.21.1-distroless" + } + }, + { + "type": "image", + "details": { + "registryURL": "ghcr.io/kedacore/keda:2.13.1" + } + }, + { + "type": "image", + "details": { + "registryURL": "ghcr.io/kedacore/keda-metrics-apiserver:2.13.1" + } + }, + { + "type": "image", + "details": { + "registryURL": "ghcr.io/kedacore/keda-admission-webhooks:2.13.1" + } + }, + { + "type": "image", + "details": { + "registryURL": "gcr.io/kubecost1/cost-model:prod-2.1.0" + } + }, + { + "type": "image", + "details": { + "registryURL": "gcr.io/kubecost1/frontend:prod-2.1.0" + } + }, + { + "type": "image", + "details": { + "registryURL": "alpine/k8s:1.26.9" + } + }, + { + "type": "image", + "details": { + "registryURL": "docker.io/grafana/promtail:2.8.3" + } + }, + { + "type": "image", + "details": { + "registryURL": "docker.io/grafana/loki:2.8.4" + } + }, + { + "type": "image", + "details": { + "registryURL": "registry.k8s.io/metrics-server/metrics-server:v0.7.1" + } + }, + { + "type": "image", + "details": { + "registryURL": "public.ecr.aws/truefoundrycloud/tfy-notebook-controller:6df7e07ca442a53583ce3bcb507f249b15818152" + } + }, + { + "type": "image", + "details": { + "registryURL": "quay.io/prometheus/node-exporter:v1.7.0" + } + }, + { + "type": "image", + "details": { + "registryURL": "registry.k8s.io/kube-state-metrics/kube-state-metrics:v2.10.1" + } + }, + { + "type": "image", + "details": { + "registryURL": "quay.io/prometheus-operator/prometheus-operator:v0.70.0" + } + }, + { + "type": "image", + "details": { + "registryURL": "quay.io/prometheus/prometheus:v2.48.1" + } + }, + { + "type": "image", + "details": { + "registryURL": "registry.k8s.io/ingress-nginx/kube-webhook-certgen:v20221220-controller-v1.5.1-58-g787ea74b6" + } + }, + { + "type": "image", + "details": { + "registryURL": "public.ecr.aws/truefoundrycloud/tfy-agent-proxy:ed48db5daa1b95112f831740ce1bbfb18d5a3872" + } + }, + { + "type": "image", + "details": { + "registryURL": "public.ecr.aws/truefoundrycloud/tfy-agent:a7a0a82ea11054f5f4ff28c4b778d1464173ca66" + } + }, + { + "type": "image", + "details": { + "registryURL": "602401143452.dkr.ecr..amazonaws.com/eks/aws-efs-csi-driver:v2.0.4" + } + }, + { + "type": "image", + "details": { + "registryURL": "public.ecr.aws/eks-distro/kubernetes-csi/node-driver-registrar:v2.10.0-eks-1-29-7" + } + }, + { + "type": "image", + "details": { + "registryURL": "public.ecr.aws/eks-distro/kubernetes-csi/livenessprobe:v2.12.0-eks-1-29-7" + } + }, + { + "type": "image", + "details": { + "registryURL": "public.ecr.aws/eks-distro/kubernetes-csi/external-provisioner:v4.0.0-eks-1-29-7" + } + }, + { + "type": "image", + "details": { + "registryURL": "public.ecr.aws/eks/aws-load-balancer-controller:v2.7.1" + } + }, + { + "type": "image", + "details": { + "registryURL": "public.ecr.aws/karpenter/controller:0.35.4@sha256:27a73db80b78e523370bcca77418f6d2136eea10a99fc87d02d2df059fcf5fb7" + } + }, + { + "type": "image", + "details": { + "registryURL": "registry.k8s.io/nfd/node-feature-discovery:v0.15.4" + } + }, + { + "type": "image", + "details": { + "registryURL": "alpine:3.19" + } + }, + { + "type": "image", + "details": { + "registryURL": "nvcr.io/nvidia/gpu-operator:v24.3.0" + } + }, + { + "type": "image", + "details": { + "registryURL": "quay.io/argoproj/argocd:v2.10.6" + } + }, + { + "type": "image", + "details": { + "registryURL": "public.ecr.aws/docker/library/redis:7.2.4-alpine" + } + }, + { + "type": "image", + "details": { + "registryURL": "auto" + } + }, + { + "type": "image", + "details": { + "registryURL": "public.ecr.aws/ebs-csi-driver/aws-ebs-csi-driver:v1.31.0" + } + }, + { + "type": "image", + "details": { + "registryURL": "public.ecr.aws/eks-distro/kubernetes-csi/node-driver-registrar:v2.10.1-eks-1-30-4" + } + }, + { + "type": "image", + "details": { + "registryURL": "public.ecr.aws/eks-distro/kubernetes-csi/livenessprobe:v2.12.0-eks-1-30-4" + } + }, + { + "type": "image", + "details": { + "registryURL": "public.ecr.aws/eks-distro/kubernetes-csi/external-provisioner:v4.0.1-eks-1-30-4" + } + }, + { + "type": "image", + "details": { + "registryURL": "public.ecr.aws/eks-distro/kubernetes-csi/external-attacher:v4.5.1-eks-1-30-4" + } + }, + { + "type": "image", + "details": { + "registryURL": "public.ecr.aws/eks-distro/kubernetes-csi/external-resizer:v1.10.1-eks-1-30-4" + } + }, + { + "type": "image", + "details": { + "registryURL": "gcr.io/k8s-staging-test-infra/kubekins-e2e:v20240311-b09cdeb92c-master" + } + }, + { + "type": "image", + "details": { + "registryURL": "gcr.io/istio-release/proxyv2:1.21.1-distroless" + } + }, + { + "type": "image", + "details": { + "registryURL": "quay.io/argoproj/argocd:v2.11.3" + } + }, + { + "type": "image", + "details": { + "registryURL": "ghcr.io/kyverno/kyverno:v1.12.4" + } + }, + { + "type": "image", + "details": { + "registryURL": "ghcr.io/kyverno/kyvernopre:v1.12.4" + } + }, + { + "type": "image", + "details": { + "registryURL": "ghcr.io/kyverno/background-controller:v1.12.4" + } + }, + { + "type": "image", + "details": { + "registryURL": "ghcr.io/kyverno/cleanup-controller:v1.12.4" + } + }, + { + "type": "image", + "details": { + "registryURL": "ghcr.io/kyverno/reports-controller:v1.12.4" + } + }, + { + "type": "image", + "details": { + "registryURL": "bitnami/kubectl:1.28.5" + } + }, + { + "type": "image", + "details": { + "registryURL": "busybox:1.35" + } + }, + { + "type": "image", + "details": { + "registryURL": "ghcr.io/kyverno/kyverno-cli:v1.12.4" + } + }, + { + "type": "image", + "details": { + "registryURL": "gcr.io/istio-release/proxyv2:1.21.1-distroless" + } + }, + { + "type": "image", + "details": { + "registryURL": "quay.io/argoproj/argocd:v2.11.3" + } + }, + { + "type": "image", + "details": { + "registryURL": "redis:7.0.14-alpine" + } + } +] \ No newline at end of file diff --git a/charts/tfy-k8s-azure-aks-inframold/artifacts-manifest.json b/charts/tfy-k8s-azure-aks-inframold/artifacts-manifest.json new file mode 100644 index 000000000..427092780 --- /dev/null +++ b/charts/tfy-k8s-azure-aks-inframold/artifacts-manifest.json @@ -0,0 +1,360 @@ +[ + { + "type": "helm", + "details": { + "chart": "argo-rollouts", + "repoURL": "https://argoproj.github.io/argo-helm", + "targetRevision": "2.35.1" + } + }, + { + "type": "helm", + "details": { + "chart": "argo-workflows", + "repoURL": "https://argoproj.github.io/argo-helm", + "targetRevision": "0.41.1" + } + }, + { + "type": "helm", + "details": { + "chart": "tfy-grafana", + "repoURL": "https://truefoundry.github.io/infra-charts/", + "targetRevision": "0.1.4" + } + }, + { + "type": "helm", + "details": { + "chart": "base", + "repoURL": "https://istio-release.storage.googleapis.com/charts", + "targetRevision": "1.21.1" + } + }, + { + "type": "helm", + "details": { + "chart": "istiod", + "repoURL": "https://istio-release.storage.googleapis.com/charts", + "targetRevision": "1.21.1" + } + }, + { + "type": "helm", + "details": { + "chart": "keda", + "repoURL": "https://kedacore.github.io/charts", + "targetRevision": "2.13.2" + } + }, + { + "type": "helm", + "details": { + "chart": "cost-analyzer", + "repoURL": "https://kubecost.github.io/cost-analyzer/", + "targetRevision": "2.1.0" + } + }, + { + "type": "helm", + "details": { + "chart": "tfy-loki", + "repoURL": "https://truefoundry.github.io/infra-charts/", + "targetRevision": "0.1.1" + } + }, + { + "type": "helm", + "details": { + "chart": "tfy-notebook-controller", + "repoURL": "https://truefoundry.github.io/infra-charts/", + "targetRevision": "0.3.7-rc.1" + } + }, + { + "type": "helm", + "details": { + "chart": "kube-prometheus-stack", + "repoURL": "https://prometheus-community.github.io/helm-charts", + "targetRevision": "55.8.1" + } + }, + { + "type": "helm", + "details": { + "chart": "tfy-agent", + "repoURL": "https://truefoundry.github.io/infra-charts/", + "targetRevision": "0.2.22" + } + }, + { + "type": "helm", + "details": { + "chart": "tfy-gpu-operator", + "repoURL": "https://truefoundry.github.io/infra-charts/", + "targetRevision": "0.1.16-rc.5" + } + }, + { + "type": "helm", + "details": { + "chart": "argo-cd", + "repoURL": "https://argoproj.github.io/argo-helm", + "targetRevision": "6.7.10" + } + }, + { + "type": "helm", + "details": { + "chart": "tfy-istio-ingress", + "repoURL": "https://truefoundry.github.io/infra-charts/", + "targetRevision": "0.1.3" + } + }, + { + "type": "image", + "details": { + "registryURL": "quay.io/argoproj/argo-rollouts:v1.6.6" + } + }, + { + "type": "image", + "details": { + "registryURL": "quay.io/argoproj/workflow-controller:v3.5.5" + } + }, + { + "type": "image", + "details": { + "registryURL": "quay.io/argoproj/argocli:v3.5.5" + } + }, + { + "type": "image", + "details": { + "registryURL": "docker.io/grafana/grafana:10.0.3" + } + }, + { + "type": "image", + "details": { + "registryURL": "docker.io/library/busybox:1.31.1" + } + }, + { + "type": "image", + "details": { + "registryURL": "docker.io/bats/bats:v1.4.1" + } + }, + { + "type": "image", + "details": { + "registryURL": "gcr.io/istio-release/pilot:1.21.1-distroless" + } + }, + { + "type": "image", + "details": { + "registryURL": "ghcr.io/kedacore/keda:2.13.1" + } + }, + { + "type": "image", + "details": { + "registryURL": "ghcr.io/kedacore/keda-metrics-apiserver:2.13.1" + } + }, + { + "type": "image", + "details": { + "registryURL": "ghcr.io/kedacore/keda-admission-webhooks:2.13.1" + } + }, + { + "type": "image", + "details": { + "registryURL": "gcr.io/kubecost1/cost-model:prod-2.1.0" + } + }, + { + "type": "image", + "details": { + "registryURL": "gcr.io/kubecost1/frontend:prod-2.1.0" + } + }, + { + "type": "image", + "details": { + "registryURL": "alpine/k8s:1.26.9" + } + }, + { + "type": "image", + "details": { + "registryURL": "docker.io/grafana/promtail:2.8.3" + } + }, + { + "type": "image", + "details": { + "registryURL": "docker.io/grafana/loki:2.8.4" + } + }, + { + "type": "image", + "details": { + "registryURL": "public.ecr.aws/truefoundrycloud/tfy-notebook-controller:6df7e07ca442a53583ce3bcb507f249b15818152" + } + }, + { + "type": "image", + "details": { + "registryURL": "quay.io/prometheus/node-exporter:v1.7.0" + } + }, + { + "type": "image", + "details": { + "registryURL": "registry.k8s.io/kube-state-metrics/kube-state-metrics:v2.10.1" + } + }, + { + "type": "image", + "details": { + "registryURL": "quay.io/prometheus-operator/prometheus-operator:v0.70.0" + } + }, + { + "type": "image", + "details": { + "registryURL": "quay.io/prometheus/prometheus:v2.48.1" + } + }, + { + "type": "image", + "details": { + "registryURL": "registry.k8s.io/ingress-nginx/kube-webhook-certgen:v20221220-controller-v1.5.1-58-g787ea74b6" + } + }, + { + "type": "image", + "details": { + "registryURL": "public.ecr.aws/truefoundrycloud/tfy-agent-proxy:ed48db5daa1b95112f831740ce1bbfb18d5a3872" + } + }, + { + "type": "image", + "details": { + "registryURL": "public.ecr.aws/truefoundrycloud/tfy-agent:a7a0a82ea11054f5f4ff28c4b778d1464173ca66" + } + }, + { + "type": "image", + "details": { + "registryURL": "registry.k8s.io/nfd/node-feature-discovery:v0.15.4" + } + }, + { + "type": "image", + "details": { + "registryURL": "nvcr.io/nvidia/gpu-operator:v24.3.0" + } + }, + { + "type": "image", + "details": { + "registryURL": "quay.io/argoproj/argocd:v2.10.6" + } + }, + { + "type": "image", + "details": { + "registryURL": "public.ecr.aws/docker/library/redis:7.2.4-alpine" + } + }, + { + "type": "image", + "details": { + "registryURL": "auto" + } + }, + { + "type": "image", + "details": { + "registryURL": "gcr.io/istio-release/proxyv2:1.21.1-distroless" + } + }, + { + "type": "image", + "details": { + "registryURL": "quay.io/argoproj/argocd:v2.11.3" + } + }, + { + "type": "image", + "details": { + "registryURL": "ghcr.io/kyverno/kyverno:v1.12.4" + } + }, + { + "type": "image", + "details": { + "registryURL": "ghcr.io/kyverno/kyvernopre:v1.12.4" + } + }, + { + "type": "image", + "details": { + "registryURL": "ghcr.io/kyverno/background-controller:v1.12.4" + } + }, + { + "type": "image", + "details": { + "registryURL": "ghcr.io/kyverno/cleanup-controller:v1.12.4" + } + }, + { + "type": "image", + "details": { + "registryURL": "ghcr.io/kyverno/reports-controller:v1.12.4" + } + }, + { + "type": "image", + "details": { + "registryURL": "bitnami/kubectl:1.28.5" + } + }, + { + "type": "image", + "details": { + "registryURL": "busybox:1.35" + } + }, + { + "type": "image", + "details": { + "registryURL": "ghcr.io/kyverno/kyverno-cli:v1.12.4" + } + }, + { + "type": "image", + "details": { + "registryURL": "gcr.io/istio-release/proxyv2:1.21.1-distroless" + } + }, + { + "type": "image", + "details": { + "registryURL": "quay.io/argoproj/argocd:v2.11.3" + } + }, + { + "type": "image", + "details": { + "registryURL": "redis:7.0.14-alpine" + } + } +] \ No newline at end of file diff --git a/charts/tfy-k8s-civo-talos-inframold/artifacts-manifest.json b/charts/tfy-k8s-civo-talos-inframold/artifacts-manifest.json new file mode 100644 index 000000000..cf1cc3992 --- /dev/null +++ b/charts/tfy-k8s-civo-talos-inframold/artifacts-manifest.json @@ -0,0 +1,340 @@ +[ + { + "type": "helm", + "details": { + "chart": "argo-rollouts", + "repoURL": "https://argoproj.github.io/argo-helm", + "targetRevision": "2.35.1" + } + }, + { + "type": "helm", + "details": { + "chart": "argo-workflows", + "repoURL": "https://argoproj.github.io/argo-helm", + "targetRevision": "0.41.1" + } + }, + { + "type": "helm", + "details": { + "chart": "tfy-grafana", + "repoURL": "https://truefoundry.github.io/infra-charts/", + "targetRevision": "0.1.4" + } + }, + { + "type": "helm", + "details": { + "chart": "base", + "repoURL": "https://istio-release.storage.googleapis.com/charts", + "targetRevision": "1.21.1" + } + }, + { + "type": "helm", + "details": { + "chart": "istiod", + "repoURL": "https://istio-release.storage.googleapis.com/charts", + "targetRevision": "1.21.1" + } + }, + { + "type": "helm", + "details": { + "chart": "keda", + "repoURL": "https://kedacore.github.io/charts", + "targetRevision": "2.13.2" + } + }, + { + "type": "helm", + "details": { + "chart": "tfy-loki", + "repoURL": "https://truefoundry.github.io/infra-charts/", + "targetRevision": "0.1.1" + } + }, + { + "type": "helm", + "details": { + "chart": "tfy-notebook-controller", + "repoURL": "https://truefoundry.github.io/infra-charts/", + "targetRevision": "0.3.7-rc.1" + } + }, + { + "type": "helm", + "details": { + "chart": "kube-prometheus-stack", + "repoURL": "https://prometheus-community.github.io/helm-charts", + "targetRevision": "55.8.1" + } + }, + { + "type": "helm", + "details": { + "chart": "tfy-agent", + "repoURL": "https://truefoundry.github.io/infra-charts/", + "targetRevision": "0.2.22" + } + }, + { + "type": "helm", + "details": { + "chart": "tfy-gpu-operator", + "repoURL": "https://truefoundry.github.io/infra-charts/", + "targetRevision": "0.1.16-rc.5" + } + }, + { + "type": "helm", + "details": { + "chart": "argo-cd", + "repoURL": "https://argoproj.github.io/argo-helm", + "targetRevision": "6.7.10" + } + }, + { + "type": "helm", + "details": { + "chart": "tfy-istio-ingress", + "repoURL": "https://truefoundry.github.io/infra-charts/", + "targetRevision": "0.1.3" + } + }, + { + "type": "image", + "details": { + "registryURL": "quay.io/argoproj/argo-rollouts:v1.6.6" + } + }, + { + "type": "image", + "details": { + "registryURL": "quay.io/argoproj/workflow-controller:v3.5.5" + } + }, + { + "type": "image", + "details": { + "registryURL": "quay.io/argoproj/argocli:v3.5.5" + } + }, + { + "type": "image", + "details": { + "registryURL": "docker.io/grafana/grafana:10.0.3" + } + }, + { + "type": "image", + "details": { + "registryURL": "docker.io/library/busybox:1.31.1" + } + }, + { + "type": "image", + "details": { + "registryURL": "docker.io/bats/bats:v1.4.1" + } + }, + { + "type": "image", + "details": { + "registryURL": "gcr.io/istio-release/pilot:1.21.1-distroless" + } + }, + { + "type": "image", + "details": { + "registryURL": "ghcr.io/kedacore/keda:2.13.1" + } + }, + { + "type": "image", + "details": { + "registryURL": "ghcr.io/kedacore/keda-metrics-apiserver:2.13.1" + } + }, + { + "type": "image", + "details": { + "registryURL": "ghcr.io/kedacore/keda-admission-webhooks:2.13.1" + } + }, + { + "type": "image", + "details": { + "registryURL": "docker.io/grafana/promtail:2.8.3" + } + }, + { + "type": "image", + "details": { + "registryURL": "docker.io/grafana/loki:2.8.4" + } + }, + { + "type": "image", + "details": { + "registryURL": "public.ecr.aws/truefoundrycloud/tfy-notebook-controller:6df7e07ca442a53583ce3bcb507f249b15818152" + } + }, + { + "type": "image", + "details": { + "registryURL": "quay.io/prometheus/node-exporter:v1.7.0" + } + }, + { + "type": "image", + "details": { + "registryURL": "registry.k8s.io/kube-state-metrics/kube-state-metrics:v2.10.1" + } + }, + { + "type": "image", + "details": { + "registryURL": "quay.io/prometheus-operator/prometheus-operator:v0.70.0" + } + }, + { + "type": "image", + "details": { + "registryURL": "quay.io/prometheus/prometheus:v2.48.1" + } + }, + { + "type": "image", + "details": { + "registryURL": "registry.k8s.io/ingress-nginx/kube-webhook-certgen:v20221220-controller-v1.5.1-58-g787ea74b6" + } + }, + { + "type": "image", + "details": { + "registryURL": "public.ecr.aws/truefoundrycloud/tfy-agent-proxy:ed48db5daa1b95112f831740ce1bbfb18d5a3872" + } + }, + { + "type": "image", + "details": { + "registryURL": "public.ecr.aws/truefoundrycloud/tfy-agent:a7a0a82ea11054f5f4ff28c4b778d1464173ca66" + } + }, + { + "type": "image", + "details": { + "registryURL": "registry.k8s.io/nfd/node-feature-discovery:v0.15.4" + } + }, + { + "type": "image", + "details": { + "registryURL": "alpine:3.19" + } + }, + { + "type": "image", + "details": { + "registryURL": "nvcr.io/nvidia/gpu-operator:v24.3.0" + } + }, + { + "type": "image", + "details": { + "registryURL": "quay.io/argoproj/argocd:v2.10.6" + } + }, + { + "type": "image", + "details": { + "registryURL": "public.ecr.aws/docker/library/redis:7.2.4-alpine" + } + }, + { + "type": "image", + "details": { + "registryURL": "auto" + } + }, + { + "type": "image", + "details": { + "registryURL": "gcr.io/istio-release/proxyv2:1.21.1-distroless" + } + }, + { + "type": "image", + "details": { + "registryURL": "quay.io/argoproj/argocd:v2.11.3" + } + }, + { + "type": "image", + "details": { + "registryURL": "ghcr.io/kyverno/kyverno:v1.12.4" + } + }, + { + "type": "image", + "details": { + "registryURL": "ghcr.io/kyverno/kyvernopre:v1.12.4" + } + }, + { + "type": "image", + "details": { + "registryURL": "ghcr.io/kyverno/background-controller:v1.12.4" + } + }, + { + "type": "image", + "details": { + "registryURL": "ghcr.io/kyverno/cleanup-controller:v1.12.4" + } + }, + { + "type": "image", + "details": { + "registryURL": "ghcr.io/kyverno/reports-controller:v1.12.4" + } + }, + { + "type": "image", + "details": { + "registryURL": "bitnami/kubectl:1.28.5" + } + }, + { + "type": "image", + "details": { + "registryURL": "busybox:1.35" + } + }, + { + "type": "image", + "details": { + "registryURL": "ghcr.io/kyverno/kyverno-cli:v1.12.4" + } + }, + { + "type": "image", + "details": { + "registryURL": "gcr.io/istio-release/proxyv2:1.21.1-distroless" + } + }, + { + "type": "image", + "details": { + "registryURL": "quay.io/argoproj/argocd:v2.11.3" + } + }, + { + "type": "image", + "details": { + "registryURL": "redis:7.0.14-alpine" + } + } +] \ No newline at end of file diff --git a/charts/tfy-k8s-gcp-gke-autopilot-inframold/artifacts-manifest.json b/charts/tfy-k8s-gcp-gke-autopilot-inframold/artifacts-manifest.json new file mode 100644 index 000000000..46d0c4007 --- /dev/null +++ b/charts/tfy-k8s-gcp-gke-autopilot-inframold/artifacts-manifest.json @@ -0,0 +1,348 @@ +[ + { + "type": "helm", + "details": { + "chart": "argo-rollouts", + "repoURL": "https://argoproj.github.io/argo-helm", + "targetRevision": "2.35.1" + } + }, + { + "type": "helm", + "details": { + "chart": "argo-workflows", + "repoURL": "https://argoproj.github.io/argo-helm", + "targetRevision": "0.41.1" + } + }, + { + "type": "helm", + "details": { + "chart": "tfy-grafana", + "repoURL": "https://truefoundry.github.io/infra-charts/", + "targetRevision": "0.1.4" + } + }, + { + "type": "helm", + "details": { + "chart": "base", + "repoURL": "https://istio-release.storage.googleapis.com/charts", + "targetRevision": "1.21.1" + } + }, + { + "type": "helm", + "details": { + "chart": "istiod", + "repoURL": "https://istio-release.storage.googleapis.com/charts", + "targetRevision": "1.21.1" + } + }, + { + "type": "helm", + "details": { + "chart": "keda", + "repoURL": "https://kedacore.github.io/charts", + "targetRevision": "2.13.2" + } + }, + { + "type": "helm", + "details": { + "chart": "cost-analyzer", + "repoURL": "https://kubecost.github.io/cost-analyzer/", + "targetRevision": "2.1.0" + } + }, + { + "type": "helm", + "details": { + "chart": "tfy-loki", + "repoURL": "https://truefoundry.github.io/infra-charts/", + "targetRevision": "0.1.1" + } + }, + { + "type": "helm", + "details": { + "chart": "tfy-notebook-controller", + "repoURL": "https://truefoundry.github.io/infra-charts/", + "targetRevision": "0.3.7-rc.1" + } + }, + { + "type": "helm", + "details": { + "chart": "kube-prometheus-stack", + "repoURL": "https://prometheus-community.github.io/helm-charts", + "targetRevision": "55.8.1" + } + }, + { + "type": "helm", + "details": { + "chart": "tfy-agent", + "repoURL": "https://truefoundry.github.io/infra-charts/", + "targetRevision": "0.2.22" + } + }, + { + "type": "helm", + "details": { + "chart": "tfy-gpu-operator", + "repoURL": "https://truefoundry.github.io/infra-charts/", + "targetRevision": "0.1.16-rc.5" + } + }, + { + "type": "helm", + "details": { + "chart": "argo-cd", + "repoURL": "https://argoproj.github.io/argo-helm", + "targetRevision": "6.7.10" + } + }, + { + "type": "helm", + "details": { + "chart": "tfy-istio-ingress", + "repoURL": "https://truefoundry.github.io/infra-charts/", + "targetRevision": "0.1.3" + } + }, + { + "type": "image", + "details": { + "registryURL": "quay.io/argoproj/argo-rollouts:v1.6.6" + } + }, + { + "type": "image", + "details": { + "registryURL": "quay.io/argoproj/workflow-controller:v3.5.5" + } + }, + { + "type": "image", + "details": { + "registryURL": "quay.io/argoproj/argocli:v3.5.5" + } + }, + { + "type": "image", + "details": { + "registryURL": "docker.io/grafana/grafana:10.0.3" + } + }, + { + "type": "image", + "details": { + "registryURL": "docker.io/library/busybox:1.31.1" + } + }, + { + "type": "image", + "details": { + "registryURL": "docker.io/bats/bats:v1.4.1" + } + }, + { + "type": "image", + "details": { + "registryURL": "gcr.io/istio-release/pilot:1.21.1-distroless" + } + }, + { + "type": "image", + "details": { + "registryURL": "ghcr.io/kedacore/keda:2.13.1" + } + }, + { + "type": "image", + "details": { + "registryURL": "ghcr.io/kedacore/keda-metrics-apiserver:2.13.1" + } + }, + { + "type": "image", + "details": { + "registryURL": "ghcr.io/kedacore/keda-admission-webhooks:2.13.1" + } + }, + { + "type": "image", + "details": { + "registryURL": "gcr.io/kubecost1/cost-model:prod-2.1.0" + } + }, + { + "type": "image", + "details": { + "registryURL": "gcr.io/kubecost1/frontend:prod-2.1.0" + } + }, + { + "type": "image", + "details": { + "registryURL": "alpine/k8s:1.26.9" + } + }, + { + "type": "image", + "details": { + "registryURL": "docker.io/grafana/promtail:2.8.3" + } + }, + { + "type": "image", + "details": { + "registryURL": "docker.io/grafana/loki:2.8.4" + } + }, + { + "type": "image", + "details": { + "registryURL": "public.ecr.aws/truefoundrycloud/tfy-notebook-controller:6df7e07ca442a53583ce3bcb507f249b15818152" + } + }, + { + "type": "image", + "details": { + "registryURL": "quay.io/prometheus/node-exporter:v1.7.0" + } + }, + { + "type": "image", + "details": { + "registryURL": "registry.k8s.io/kube-state-metrics/kube-state-metrics:v2.10.1" + } + }, + { + "type": "image", + "details": { + "registryURL": "quay.io/prometheus-operator/prometheus-operator:v0.70.0" + } + }, + { + "type": "image", + "details": { + "registryURL": "quay.io/prometheus/prometheus:v2.48.1" + } + }, + { + "type": "image", + "details": { + "registryURL": "registry.k8s.io/ingress-nginx/kube-webhook-certgen:v20221220-controller-v1.5.1-58-g787ea74b6" + } + }, + { + "type": "image", + "details": { + "registryURL": "public.ecr.aws/truefoundrycloud/tfy-agent-proxy:ed48db5daa1b95112f831740ce1bbfb18d5a3872" + } + }, + { + "type": "image", + "details": { + "registryURL": "public.ecr.aws/truefoundrycloud/tfy-agent:a7a0a82ea11054f5f4ff28c4b778d1464173ca66" + } + }, + { + "type": "image", + "details": { + "registryURL": "quay.io/argoproj/argocd:v2.10.6" + } + }, + { + "type": "image", + "details": { + "registryURL": "public.ecr.aws/docker/library/redis:7.2.4-alpine" + } + }, + { + "type": "image", + "details": { + "registryURL": "auto" + } + }, + { + "type": "image", + "details": { + "registryURL": "gcr.io/istio-release/proxyv2:1.21.1-distroless" + } + }, + { + "type": "image", + "details": { + "registryURL": "quay.io/argoproj/argocd:v2.11.3" + } + }, + { + "type": "image", + "details": { + "registryURL": "ghcr.io/kyverno/kyverno:v1.12.4" + } + }, + { + "type": "image", + "details": { + "registryURL": "ghcr.io/kyverno/kyvernopre:v1.12.4" + } + }, + { + "type": "image", + "details": { + "registryURL": "ghcr.io/kyverno/background-controller:v1.12.4" + } + }, + { + "type": "image", + "details": { + "registryURL": "ghcr.io/kyverno/cleanup-controller:v1.12.4" + } + }, + { + "type": "image", + "details": { + "registryURL": "ghcr.io/kyverno/reports-controller:v1.12.4" + } + }, + { + "type": "image", + "details": { + "registryURL": "bitnami/kubectl:1.28.5" + } + }, + { + "type": "image", + "details": { + "registryURL": "busybox:1.35" + } + }, + { + "type": "image", + "details": { + "registryURL": "ghcr.io/kyverno/kyverno-cli:v1.12.4" + } + }, + { + "type": "image", + "details": { + "registryURL": "gcr.io/istio-release/proxyv2:1.21.1-distroless" + } + }, + { + "type": "image", + "details": { + "registryURL": "quay.io/argoproj/argocd:v2.11.3" + } + }, + { + "type": "image", + "details": { + "registryURL": "redis:7.0.14-alpine" + } + } +] \ No newline at end of file diff --git a/charts/tfy-k8s-gcp-gke-standard-inframold/artifacts-manifest.json b/charts/tfy-k8s-gcp-gke-standard-inframold/artifacts-manifest.json new file mode 100644 index 000000000..5700a4fcc --- /dev/null +++ b/charts/tfy-k8s-gcp-gke-standard-inframold/artifacts-manifest.json @@ -0,0 +1,372 @@ +[ + { + "type": "helm", + "details": { + "chart": "argo-rollouts", + "repoURL": "https://argoproj.github.io/argo-helm", + "targetRevision": "2.35.1" + } + }, + { + "type": "helm", + "details": { + "chart": "argo-workflows", + "repoURL": "https://argoproj.github.io/argo-helm", + "targetRevision": "0.41.1" + } + }, + { + "type": "helm", + "details": { + "chart": "tfy-grafana", + "repoURL": "https://truefoundry.github.io/infra-charts/", + "targetRevision": "0.1.4" + } + }, + { + "type": "helm", + "details": { + "chart": "base", + "repoURL": "https://istio-release.storage.googleapis.com/charts", + "targetRevision": "1.21.1" + } + }, + { + "type": "helm", + "details": { + "chart": "istiod", + "repoURL": "https://istio-release.storage.googleapis.com/charts", + "targetRevision": "1.21.1" + } + }, + { + "type": "helm", + "details": { + "chart": "keda", + "repoURL": "https://kedacore.github.io/charts", + "targetRevision": "2.13.2" + } + }, + { + "type": "helm", + "details": { + "chart": "cost-analyzer", + "repoURL": "https://kubecost.github.io/cost-analyzer/", + "targetRevision": "2.1.0" + } + }, + { + "type": "helm", + "details": { + "chart": "tfy-loki", + "repoURL": "https://truefoundry.github.io/infra-charts/", + "targetRevision": "0.1.1" + } + }, + { + "type": "helm", + "details": { + "chart": "tfy-notebook-controller", + "repoURL": "https://truefoundry.github.io/infra-charts/", + "targetRevision": "0.3.7-rc.1" + } + }, + { + "type": "helm", + "details": { + "chart": "kube-prometheus-stack", + "repoURL": "https://prometheus-community.github.io/helm-charts", + "targetRevision": "55.8.1" + } + }, + { + "type": "helm", + "details": { + "chart": "tfy-agent", + "repoURL": "https://truefoundry.github.io/infra-charts/", + "targetRevision": "0.2.22" + } + }, + { + "type": "helm", + "details": { + "chart": "tfy-gpu-operator", + "repoURL": "https://truefoundry.github.io/infra-charts/", + "targetRevision": "0.1.16-rc.5" + } + }, + { + "type": "helm", + "details": { + "chart": "argo-cd", + "repoURL": "https://argoproj.github.io/argo-helm", + "targetRevision": "6.7.10" + } + }, + { + "type": "helm", + "details": { + "chart": "tfy-istio-ingress", + "repoURL": "https://truefoundry.github.io/infra-charts/", + "targetRevision": "0.1.3" + } + }, + { + "type": "image", + "details": { + "registryURL": "quay.io/argoproj/argo-rollouts:v1.6.6" + } + }, + { + "type": "image", + "details": { + "registryURL": "quay.io/argoproj/workflow-controller:v3.5.5" + } + }, + { + "type": "image", + "details": { + "registryURL": "quay.io/argoproj/argocli:v3.5.5" + } + }, + { + "type": "image", + "details": { + "registryURL": "docker.io/grafana/grafana:10.0.3" + } + }, + { + "type": "image", + "details": { + "registryURL": "docker.io/library/busybox:1.31.1" + } + }, + { + "type": "image", + "details": { + "registryURL": "docker.io/bats/bats:v1.4.1" + } + }, + { + "type": "image", + "details": { + "registryURL": "gcr.io/istio-release/pilot:1.21.1-distroless" + } + }, + { + "type": "image", + "details": { + "registryURL": "ghcr.io/kedacore/keda:2.13.1" + } + }, + { + "type": "image", + "details": { + "registryURL": "ghcr.io/kedacore/keda-metrics-apiserver:2.13.1" + } + }, + { + "type": "image", + "details": { + "registryURL": "ghcr.io/kedacore/keda-admission-webhooks:2.13.1" + } + }, + { + "type": "image", + "details": { + "registryURL": "gcr.io/kubecost1/cost-model:prod-2.1.0" + } + }, + { + "type": "image", + "details": { + "registryURL": "gcr.io/kubecost1/frontend:prod-2.1.0" + } + }, + { + "type": "image", + "details": { + "registryURL": "alpine/k8s:1.26.9" + } + }, + { + "type": "image", + "details": { + "registryURL": "docker.io/grafana/promtail:2.8.3" + } + }, + { + "type": "image", + "details": { + "registryURL": "docker.io/grafana/loki:2.8.4" + } + }, + { + "type": "image", + "details": { + "registryURL": "public.ecr.aws/truefoundrycloud/tfy-notebook-controller:6df7e07ca442a53583ce3bcb507f249b15818152" + } + }, + { + "type": "image", + "details": { + "registryURL": "quay.io/prometheus/node-exporter:v1.7.0" + } + }, + { + "type": "image", + "details": { + "registryURL": "registry.k8s.io/kube-state-metrics/kube-state-metrics:v2.10.1" + } + }, + { + "type": "image", + "details": { + "registryURL": "quay.io/prometheus-operator/prometheus-operator:v0.70.0" + } + }, + { + "type": "image", + "details": { + "registryURL": "quay.io/prometheus/prometheus:v2.48.1" + } + }, + { + "type": "image", + "details": { + "registryURL": "registry.k8s.io/ingress-nginx/kube-webhook-certgen:v20221220-controller-v1.5.1-58-g787ea74b6" + } + }, + { + "type": "image", + "details": { + "registryURL": "public.ecr.aws/truefoundrycloud/tfy-agent-proxy:ed48db5daa1b95112f831740ce1bbfb18d5a3872" + } + }, + { + "type": "image", + "details": { + "registryURL": "public.ecr.aws/truefoundrycloud/tfy-agent:a7a0a82ea11054f5f4ff28c4b778d1464173ca66" + } + }, + { + "type": "image", + "details": { + "registryURL": "nvcr.io/nvidia/k8s/dcgm-exporter:3.3.5-3.4.1-ubuntu22.04" + } + }, + { + "type": "image", + "details": { + "registryURL": "gcr.io/google-containers/pause:2.0" + } + }, + { + "type": "image", + "details": { + "registryURL": "cos-nvidia-installer:fixed" + } + }, + { + "type": "image", + "details": { + "registryURL": "gcr.io/gke-release/nvidia-partition-gpu@sha256:e226275da6c45816959fe43cde907ee9a85c6a2aa8a429418a4cadef8ecdb86a" + } + }, + { + "type": "image", + "details": { + "registryURL": "quay.io/argoproj/argocd:v2.10.6" + } + }, + { + "type": "image", + "details": { + "registryURL": "public.ecr.aws/docker/library/redis:7.2.4-alpine" + } + }, + { + "type": "image", + "details": { + "registryURL": "auto" + } + }, + { + "type": "image", + "details": { + "registryURL": "gcr.io/istio-release/proxyv2:1.21.1-distroless" + } + }, + { + "type": "image", + "details": { + "registryURL": "quay.io/argoproj/argocd:v2.11.3" + } + }, + { + "type": "image", + "details": { + "registryURL": "ghcr.io/kyverno/kyverno:v1.12.4" + } + }, + { + "type": "image", + "details": { + "registryURL": "ghcr.io/kyverno/kyvernopre:v1.12.4" + } + }, + { + "type": "image", + "details": { + "registryURL": "ghcr.io/kyverno/background-controller:v1.12.4" + } + }, + { + "type": "image", + "details": { + "registryURL": "ghcr.io/kyverno/cleanup-controller:v1.12.4" + } + }, + { + "type": "image", + "details": { + "registryURL": "ghcr.io/kyverno/reports-controller:v1.12.4" + } + }, + { + "type": "image", + "details": { + "registryURL": "bitnami/kubectl:1.28.5" + } + }, + { + "type": "image", + "details": { + "registryURL": "busybox:1.35" + } + }, + { + "type": "image", + "details": { + "registryURL": "ghcr.io/kyverno/kyverno-cli:v1.12.4" + } + }, + { + "type": "image", + "details": { + "registryURL": "gcr.io/istio-release/proxyv2:1.21.1-distroless" + } + }, + { + "type": "image", + "details": { + "registryURL": "quay.io/argoproj/argocd:v2.11.3" + } + }, + { + "type": "image", + "details": { + "registryURL": "redis:7.0.14-alpine" + } + } +] \ No newline at end of file diff --git a/charts/tfy-k8s-generic-inframold/artifacts-manifest.json b/charts/tfy-k8s-generic-inframold/artifacts-manifest.json new file mode 100644 index 000000000..5815bc50d --- /dev/null +++ b/charts/tfy-k8s-generic-inframold/artifacts-manifest.json @@ -0,0 +1,334 @@ +[ + { + "type": "helm", + "details": { + "chart": "argo-rollouts", + "repoURL": "https://argoproj.github.io/argo-helm", + "targetRevision": "2.35.1" + } + }, + { + "type": "helm", + "details": { + "chart": "argo-workflows", + "repoURL": "https://argoproj.github.io/argo-helm", + "targetRevision": "0.41.1" + } + }, + { + "type": "helm", + "details": { + "chart": "tfy-grafana", + "repoURL": "https://truefoundry.github.io/infra-charts/", + "targetRevision": "0.1.4" + } + }, + { + "type": "helm", + "details": { + "chart": "base", + "repoURL": "https://istio-release.storage.googleapis.com/charts", + "targetRevision": "1.21.1" + } + }, + { + "type": "helm", + "details": { + "chart": "istiod", + "repoURL": "https://istio-release.storage.googleapis.com/charts", + "targetRevision": "1.21.1" + } + }, + { + "type": "helm", + "details": { + "chart": "keda", + "repoURL": "https://kedacore.github.io/charts", + "targetRevision": "2.13.2" + } + }, + { + "type": "helm", + "details": { + "chart": "tfy-loki", + "repoURL": "https://truefoundry.github.io/infra-charts/", + "targetRevision": "0.1.1" + } + }, + { + "type": "helm", + "details": { + "chart": "tfy-notebook-controller", + "repoURL": "https://truefoundry.github.io/infra-charts/", + "targetRevision": "0.3.7-rc.1" + } + }, + { + "type": "helm", + "details": { + "chart": "kube-prometheus-stack", + "repoURL": "https://prometheus-community.github.io/helm-charts", + "targetRevision": "55.8.1" + } + }, + { + "type": "helm", + "details": { + "chart": "tfy-agent", + "repoURL": "https://truefoundry.github.io/infra-charts/", + "targetRevision": "0.2.22" + } + }, + { + "type": "helm", + "details": { + "chart": "tfy-gpu-operator", + "repoURL": "https://truefoundry.github.io/infra-charts/", + "targetRevision": "0.1.16-rc.5" + } + }, + { + "type": "helm", + "details": { + "chart": "argo-cd", + "repoURL": "https://argoproj.github.io/argo-helm", + "targetRevision": "6.7.10" + } + }, + { + "type": "helm", + "details": { + "chart": "tfy-istio-ingress", + "repoURL": "https://truefoundry.github.io/infra-charts/", + "targetRevision": "0.1.3" + } + }, + { + "type": "image", + "details": { + "registryURL": "quay.io/argoproj/argo-rollouts:v1.6.6" + } + }, + { + "type": "image", + "details": { + "registryURL": "quay.io/argoproj/workflow-controller:v3.5.5" + } + }, + { + "type": "image", + "details": { + "registryURL": "quay.io/argoproj/argocli:v3.5.5" + } + }, + { + "type": "image", + "details": { + "registryURL": "docker.io/grafana/grafana:10.0.3" + } + }, + { + "type": "image", + "details": { + "registryURL": "docker.io/library/busybox:1.31.1" + } + }, + { + "type": "image", + "details": { + "registryURL": "docker.io/bats/bats:v1.4.1" + } + }, + { + "type": "image", + "details": { + "registryURL": "gcr.io/istio-release/pilot:1.21.1-distroless" + } + }, + { + "type": "image", + "details": { + "registryURL": "ghcr.io/kedacore/keda:2.13.1" + } + }, + { + "type": "image", + "details": { + "registryURL": "ghcr.io/kedacore/keda-metrics-apiserver:2.13.1" + } + }, + { + "type": "image", + "details": { + "registryURL": "ghcr.io/kedacore/keda-admission-webhooks:2.13.1" + } + }, + { + "type": "image", + "details": { + "registryURL": "docker.io/grafana/promtail:2.8.3" + } + }, + { + "type": "image", + "details": { + "registryURL": "docker.io/grafana/loki:2.8.4" + } + }, + { + "type": "image", + "details": { + "registryURL": "public.ecr.aws/truefoundrycloud/tfy-notebook-controller:6df7e07ca442a53583ce3bcb507f249b15818152" + } + }, + { + "type": "image", + "details": { + "registryURL": "quay.io/prometheus/node-exporter:v1.7.0" + } + }, + { + "type": "image", + "details": { + "registryURL": "registry.k8s.io/kube-state-metrics/kube-state-metrics:v2.10.1" + } + }, + { + "type": "image", + "details": { + "registryURL": "quay.io/prometheus-operator/prometheus-operator:v0.70.0" + } + }, + { + "type": "image", + "details": { + "registryURL": "quay.io/prometheus/prometheus:v2.48.1" + } + }, + { + "type": "image", + "details": { + "registryURL": "registry.k8s.io/ingress-nginx/kube-webhook-certgen:v20221220-controller-v1.5.1-58-g787ea74b6" + } + }, + { + "type": "image", + "details": { + "registryURL": "public.ecr.aws/truefoundrycloud/tfy-agent-proxy:ed48db5daa1b95112f831740ce1bbfb18d5a3872" + } + }, + { + "type": "image", + "details": { + "registryURL": "public.ecr.aws/truefoundrycloud/tfy-agent:a7a0a82ea11054f5f4ff28c4b778d1464173ca66" + } + }, + { + "type": "image", + "details": { + "registryURL": "registry.k8s.io/nfd/node-feature-discovery:v0.15.4" + } + }, + { + "type": "image", + "details": { + "registryURL": "nvcr.io/nvidia/gpu-operator:v24.3.0" + } + }, + { + "type": "image", + "details": { + "registryURL": "quay.io/argoproj/argocd:v2.10.6" + } + }, + { + "type": "image", + "details": { + "registryURL": "public.ecr.aws/docker/library/redis:7.2.4-alpine" + } + }, + { + "type": "image", + "details": { + "registryURL": "auto" + } + }, + { + "type": "image", + "details": { + "registryURL": "gcr.io/istio-release/proxyv2:1.21.1-distroless" + } + }, + { + "type": "image", + "details": { + "registryURL": "quay.io/argoproj/argocd:v2.11.3" + } + }, + { + "type": "image", + "details": { + "registryURL": "ghcr.io/kyverno/kyverno:v1.12.4" + } + }, + { + "type": "image", + "details": { + "registryURL": "ghcr.io/kyverno/kyvernopre:v1.12.4" + } + }, + { + "type": "image", + "details": { + "registryURL": "ghcr.io/kyverno/background-controller:v1.12.4" + } + }, + { + "type": "image", + "details": { + "registryURL": "ghcr.io/kyverno/cleanup-controller:v1.12.4" + } + }, + { + "type": "image", + "details": { + "registryURL": "ghcr.io/kyverno/reports-controller:v1.12.4" + } + }, + { + "type": "image", + "details": { + "registryURL": "bitnami/kubectl:1.28.5" + } + }, + { + "type": "image", + "details": { + "registryURL": "busybox:1.35" + } + }, + { + "type": "image", + "details": { + "registryURL": "ghcr.io/kyverno/kyverno-cli:v1.12.4" + } + }, + { + "type": "image", + "details": { + "registryURL": "gcr.io/istio-release/proxyv2:1.21.1-distroless" + } + }, + { + "type": "image", + "details": { + "registryURL": "quay.io/argoproj/argocd:v2.11.3" + } + }, + { + "type": "image", + "details": { + "registryURL": "redis:7.0.14-alpine" + } + } +] \ No newline at end of file diff --git a/scripts/generate-artifacts-manifest/artifacts_template_generator.py b/scripts/generate-artifacts-manifest/artifacts_template_generator.py new file mode 100644 index 000000000..fb8459864 --- /dev/null +++ b/scripts/generate-artifacts-manifest/artifacts_template_generator.py @@ -0,0 +1,196 @@ +import yaml +import sys +import json +import subprocess +import os +import logging + +# Configure logging +logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s') + +temp_dir = "/tmp/helm_charts" + +# function to run shell commands +def run_command(command): + result = subprocess.run(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True) + if result.returncode != 0: + logging.error(f"Command failed: {command}\n{result.stderr}") + sys.exit(1) + return result.stdout + +# function to make image list unique +def make_image_list_unique(image_list): + unique_images = [] + for image in image_list: + if image not in unique_images: + unique_images.append(image) + return unique_images + +# function to extract chart information from the manifest file +def extract_chart_info(manifest_file): + chart_info_list = [] + + with open(manifest_file, 'r') as f: + manifest = yaml.safe_load_all(f) + + for doc in manifest: + if isinstance(doc, dict) and 'spec' in doc: + source = doc['spec'].get('source', {}) + if source: + chart_info = { + "type": "helm", + "details": { + "chart": source.get('chart', 'Not found'), + "repoURL": source.get('repoURL', 'Not found'), + "targetRevision": source.get('targetRevision', 'Not found'), + "values": source.get('helm', {}).get('values', 'Not found') + } + } + chart_info_list.append(chart_info) + + return chart_info_list + +# function to save chart information to a file +def save_chart_info(chart_info_list, output_file): + with open(output_file, 'w') as f: + json.dump(chart_info_list, f, indent=4) + logging.info(f"Chart information saved to {output_file}") + +# function to process chart information +def process_chart_info(chart_info_list): + chart_detail_list = [] + for chart_info in chart_info_list: + details = chart_info["details"] + chart = details["chart"] + repoURL = details["repoURL"] + targetRevision = details["targetRevision"] + values = details["values"] + + if chart == "aws-load-balancer-controller": + values = values.replace("clusterName: \"\"", "clusterName: \"my-cluster\"") + + run_command(f"helm repo add {chart} {repoURL}") + + values_file = f"{temp_dir}/charts/{chart}-values.yaml" + os.makedirs(os.path.dirname(values_file), exist_ok=True) + with open(values_file, "w") as f: + f.write(values) + + logging.info(f"Generating manifests for {chart}/{chart}...") + run_command(f"helm template {chart}/{chart} --version {targetRevision} -f {values_file} > {temp_dir}/charts/{chart}.yaml") + + images = make_image_list_unique(save_image_info(f"{temp_dir}/charts/{chart}.yaml")) + logging.info(f"Images for {chart}: {images}") + + chart_detail_list.append(images) + + flattened_list = [item for sublist in chart_detail_list for item in sublist] + return flattened_list + +# function to save image information to a file +def save_image_info(manifest_file): + with open(manifest_file, "r") as f: + yaml_content = f.read() + images = extract_images_from_k8s_manifests(yaml_content) + return images + +# function to generate manifests for the chart +def generate_manifests(chart_name, chart_repo_url, chart_version, values_file): + run_command(f"helm repo add {chart_name} {chart_repo_url}") + run_command("helm repo update") + run_command(f"helm search repo {chart_name}/{chart_name}") + + logging.info(f"Downloading the chart {chart_name} version {chart_version} from the repository {chart_repo_url}") + logging.info(f"helm pull {chart_name}/{chart_name} --version {chart_version} --untar --untardir {temp_dir}") + run_command(f"helm pull {chart_name}/{chart_name} --version {chart_version} --untar --untardir {temp_dir}") + + chart_dir = os.path.join(temp_dir, chart_name) + manifest_file = os.path.join(temp_dir, 'generated-manifest.yaml') + logging.info(f"Generating the manifests for the chart {chart_name} using the values file {values_file}") + run_command(f"helm template my-release -f {values_file} {chart_dir} > {manifest_file}") + + return manifest_file + +# function to extract images from Kubernetes manifests +def extract_images_from_k8s_manifests(yaml_content): + resources_with_containers = ['Deployment', 'StatefulSet', 'DaemonSet', 'Job', 'CronJob', 'Pod', 'ReplicaSet'] + try: + manifests = yaml.safe_load_all(yaml_content) + image_info_list = [] + for manifest in manifests: + if manifest is None: + continue + if 'kind' in manifest and 'spec' in manifest: + kind = manifest['kind'] + if kind in ['Alertmanager', 'Prometheus']: + container_image_info = { + "type": "image", + "details": { + "registryURL": manifest['spec']['image'] + } + } + image_info_list.append(container_image_info) + + elif kind in resources_with_containers: + containers = [] + init_containers = [] + if 'template' in manifest['spec']: + containers = manifest['spec']['template']['spec'].get('containers', []) + init_containers = manifest['spec']['template']['spec'].get('initContainers', []) + elif kind == 'CronJob' and 'jobTemplate' in manifest['spec']: + containers = manifest['spec']['jobTemplate']['spec']['template']['spec'].get('containers', []) + init_containers = manifest['spec']['jobTemplate']['spec']['template']['spec'].get('initContainers', []) + else: + containers = manifest['spec'].get('containers', []) + init_containers = manifest['spec'].get('initContainers', []) + + for container in containers + init_containers: + container_image_info = { + "type": "image", + "details": { + "registryURL": container.get('image', '') + } + } + image_info_list.append(container_image_info) + except yaml.YAMLError as e: + logging.error(f"Error parsing YAML: {e}") + return None + + return image_info_list + +def clean_up(temp_dir): + run_command(f"rm -rf {temp_dir}") + +if __name__ == "__main__": + if len(sys.argv) < 6: + print("Usage: python artifacts_template_generator.py ") + sys.exit(1) + + chart_name = sys.argv[1] + chart_repo_url = sys.argv[2] + chart_version = sys.argv[3] + values_file = sys.argv[4] + output_file = sys.argv[5] + extra_file = sys.argv[6] + + manifest_file = generate_manifests(chart_name, chart_repo_url, chart_version, values_file) + + chart_info_list = extract_chart_info(manifest_file) + if chart_info_list: + image_info_list = process_chart_info(chart_info_list) + else: + image_info_list = make_image_list_unique(save_image_info(manifest_file)) + + for chart_info in chart_info_list: + chart_info["details"].pop("values", None) + + chart_info_list.extend(image_info_list) + + if extra_file: + with open(extra_file, 'r') as f: + extra_info = json.load(f) + chart_info_list.extend(extra_info) + + save_chart_info(chart_info_list, output_file) + + clean_up(temp_dir) diff --git a/scripts/generate-artifacts-manifest/extra.json b/scripts/generate-artifacts-manifest/extra.json new file mode 100644 index 000000000..bdcf1a4c1 --- /dev/null +++ b/scripts/generate-artifacts-manifest/extra.json @@ -0,0 +1,80 @@ +[ + { + "type": "image", + "details": { + "registryURL": "gcr.io/istio-release/proxyv2:1.21.1-distroless" + } + }, + { + "type": "image", + "details": { + "registryURL": "quay.io/argoproj/argocd:v2.11.3" + } + }, + { + "type": "image", + "details": { + "registryURL": "ghcr.io/kyverno/kyverno:v1.12.4" + } + }, + { + "type": "image", + "details": { + "registryURL": "ghcr.io/kyverno/kyvernopre:v1.12.4" + } + }, + { + "type": "image", + "details": { + "registryURL": "ghcr.io/kyverno/background-controller:v1.12.4" + } + }, + { + "type": "image", + "details": { + "registryURL": "ghcr.io/kyverno/cleanup-controller:v1.12.4" + } + }, + { + "type": "image", + "details": { + "registryURL": "ghcr.io/kyverno/reports-controller:v1.12.4" + } + }, + { + "type": "image", + "details": { + "registryURL": "bitnami/kubectl:1.28.5" + } + }, + { + "type": "image", + "details": { + "registryURL": "busybox:1.35" + } + }, + { + "type": "image", + "details": { + "registryURL": "ghcr.io/kyverno/kyverno-cli:v1.12.4" + } + }, + { + "type": "image", + "details": { + "registryURL": "gcr.io/istio-release/proxyv2:1.21.1-distroless" + } + }, + { + "type": "image", + "details": { + "registryURL": "quay.io/argoproj/argocd:v2.11.3" + } + }, + { + "type": "image", + "details": { + "registryURL": "redis:7.0.14-alpine" + } +} +] diff --git a/scripts/generate-artifacts-manifest/requirements.txt b/scripts/generate-artifacts-manifest/requirements.txt new file mode 100644 index 000000000..21bf3fdc4 --- /dev/null +++ b/scripts/generate-artifacts-manifest/requirements.txt @@ -0,0 +1,10 @@ +boto3==1.34.144 +botocore==1.34.144 +certifi==2024.6.2 +charset-normalizer==3.3.2 +docker==7.1.0 +docker-image-py==0.1.12 +idna==3.7 +jmespath==1.0.1 +python-dateutil==2.9.0.post0 +PyYAML==6.0.1 diff --git a/scripts/upload-artifacts/README.md b/scripts/upload-artifacts/README.md new file mode 100644 index 000000000..5a5438d80 --- /dev/null +++ b/scripts/upload-artifacts/README.md @@ -0,0 +1,33 @@ +# Uploading artifacts to a private registry + +Deploying Inframold charts from a private registry would require having the necessary artifacts required to successfully deploy the chart to be available in the registry. In order to achieve this, we have an artifact-manifest file which details the required artifacts needed for each Truefoundry chart and a script that makes it easy to deploy these artifacts to your own private registry. The [infra-chart ](https://github.com/truefoundry/infra-charts) repo contains a list of 3rd party chart dependencies alongside Truefoundry helm charts that can be deployed, here is a list of Truefoundry Helm Charts that can be deployed depending on the environment you wish to deploy Truefoundry into; + +- [AWS EKS (tfy-k8s-aws-eks-inframold)](https://github.com/truefoundry/infra-charts/tree/main/charts/tfy-k8s-aws-eks-inframold) +- [Azure AKS (tfy-k8s-azure-aks-inframold)](https://github.com/truefoundry/infra-charts/tree/main/charts/tfy-k8s-azure-aks-inframold) +- [Civo Talos (tfy-k8s-civo-talos-inframold)](https://github.com/truefoundry/infra-charts/tree/main/charts/tfy-k8s-civo-talos-inframold) +- [GCP GKE Autopilot (tfy-k8s-gcp-gke-autopilot-inframold)](https://github.com/truefoundry/infra-charts/tree/main/charts/tfy-k8s-gcp-gke-autopilot-inframold) +- [GCP GKE Standard (tfy-k8s-gcp-gke-standard-inframold)](https://github.com/truefoundry/infra-charts/tree/main/charts/tfy-k8s-gcp-gke-standard-inframold) +- [Generis Kubernetes Cluster (tfy-k8s-generic-inframold)](https://github.com/truefoundry/infra-charts/tree/main/charts/tfy-k8s-generic-inframold) + +## Steps to deploy artifacts to a private registry + +1. Get the necessary artifacts-manifest.json file from the [infra-charts](https://github.com/truefoundry/infra-charts/tree/main/charts/) folder depending on the infrastructure you want to deploy to. +2. Install the python dependencies + ``` + pip install -r requirements.txt + ``` +3. The `upload_artifact.py` is a sample python scripts which handles deployment to JFrog and ECR registries, it takes in the following arguments; + - `artifact_type` - this takes in the artifact type which can be either `image` or `helm` + - `file_path `- this is the location of the artifacts-manifest.json file that contains the artifacts' information. + - `destination_registry` - this is the registry you plan to use in your air-gapped environment. + - `registry_type` the type of registry. The script currently take ecr for AWS registry and jfrog +4. Before uploading images or charts to your registry, make sure you're authenticated. When setting up jfrog, you have to create a token the script will use. Follow this [link](https://jfrog.com/help/r/how-to-generate-an-access-token-video/artifactory-creating-access-tokens-in-artifactory) to generate your token. Once you get the token, pass it in as an environment variable - `JFROG_TOKEN` before running the script. + When deploying to ECR, the following are needed to be passed as environment variables - `AWS_PROFILE` and `AWS_REGION`. + To update your registry with the required images to a jfrog registry, run the following command + ``` + python upload_artifacts.py image artifacts-manifest.json .jfrog.io jfrog + ``` +5. To update your registry with the necessary helm to an ecr registry + ``` + python upload_artifacts.py helm artifacts-manifest.json .dkr.ecr..amazonaws.com ecr + ``` diff --git a/scripts/upload-artifacts/requirements.txt b/scripts/upload-artifacts/requirements.txt new file mode 100644 index 000000000..21bf3fdc4 --- /dev/null +++ b/scripts/upload-artifacts/requirements.txt @@ -0,0 +1,10 @@ +boto3==1.34.144 +botocore==1.34.144 +certifi==2024.6.2 +charset-normalizer==3.3.2 +docker==7.1.0 +docker-image-py==0.1.12 +idna==3.7 +jmespath==1.0.1 +python-dateutil==2.9.0.post0 +PyYAML==6.0.1 diff --git a/scripts/upload-artifacts/upload_artifacts.py b/scripts/upload-artifacts/upload_artifacts.py new file mode 100644 index 000000000..ca2a268d3 --- /dev/null +++ b/scripts/upload-artifacts/upload_artifacts.py @@ -0,0 +1,275 @@ +import docker +import sys +import os +import subprocess +import yaml +import json +import boto3 +import logging +import requests + +from botocore.exceptions import ClientError +from urllib.parse import urlparse +import random + +# Configure logging +logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s') + +# get AWS_PROFILE from environment variable or use default value +AWS_PROFILE = os.getenv('AWS_PROFILE', 'default') + +AWS_REGION = os.getenv('AWS_REGION') + +# get docker image architecture to use from environment variable or use default value +DOCKER_IMAGE_ARCHITECTURE = os.getenv('CLUSTER_ARCHITECTURE', 'linux/amd64') + +tmp_dir = "/tmp/helm_charts" + + +# function to run shell commands +def run_command(command): + logging.info(f"Running command: {command}") + result = subprocess.run(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True) + if result.returncode != 0: + raise RuntimeError(f"Command failed: {command}\n{result.stderr}") + return result.stdout + + +# function to clean up temporary files +def clean_up(temp_dir): + run_command(f"rm -rf {temp_dir}") + + +# generic repo functiion, calls other repos +def create_repository(registry_type, destination_registry, repo_name, package_type): + if registry_type == "ecr": + create_ecr_repository(repo_name) + elif registry_type == "jfrog": + create_jfrog_repository(destination_registry, package_type, "truefoundry") + +# function to create a jfrog artifact repository +def create_jfrog_repository(jfrog_destination_registry, package_type, repo_name): + # get jfrog token + jfrog_token = os.getenv('JFRGO_TOKEN') + + # jfrog doesn't allow multiple layers of repo name + if package_type == "helm": + repo_name = "truefoundryhelm" + package_type = "helmoci" + + if package_type == "image": + package_type = "docker" + + repo_url = f"https://{jfrog_destination_registry}/artifactory/api/repositories/{repo_name}" + + headers = { + "Content-Type": "application/json", + } + + auth = ("", jfrog_token) + + payload = { + "key": repo_name, + "rclass": "local", # repo_type = "local" + "packageType": package_type, # package_type = [docker, helmoci] + } + + response = requests.put(repo_url, auth=auth, headers=headers, data=json.dumps(payload)) + + if response.status_code == 409 or response.status_code == 400: + return "Repository already exists." + elif response.status_code == 201 or response.status_code == 200: + return "Repository created successfully." + else: + return f"Failed to create repository. Status code: {response.status_code}, Response: {response.text}" + + +# function to create ECR repository if it does not exist +def create_ecr_repository(repository_name): + session = boto3.Session(profile_name=AWS_PROFILE) + client = session.client('ecr', region_name=AWS_REGION) + try: + response = client.create_repository(repositoryName=repository_name) + logging.info(f"Successfully created ECR repository: {repository_name}") + return response + except ClientError as e: + if e.response['Error']['Code'] == 'RepositoryAlreadyExistsException': + logging.info(f"{repository_name} repository already exists. Skipping.....") + else: + logging.error(f"Failed to create ECR repository: {repository_name}. Error: {e}") + return None + + +# function to create ECR public repository if it does not exist +def create_public_ecr_repository(repository_name): + session = boto3.Session(profile_name=AWS_PROFILE) + client = session.client('ecr-public', region_name=AWS_REGION) + try: + response = client.create_repository(repositoryName=repository_name) + logging.info(f"Successfully created ECR repository: {repository_name}") + return response + except ClientError as e: + if e.response['Error']['Code'] == 'RepositoryAlreadyExistsException': + logging.info(f"{repository_name} repository already exists. Skipping.....") + else: + logging.error(f"Failed to create ECR repository: {repository_name}. Error: {e}") + return None + + +# function to parse image URL and extract image name and tag +def parse_image_url(image_url, destination_registry): + from docker_image import reference + # Initialize image_name and image_tag + image_name = "" + image_tag = "" + + ref = reference.Reference.parse(image_url) + if not ref['tag']: + image_tag = ":latest" + else: + image_tag = f":{ref['tag']}" + + # if ref['digest']: + # image_tag = f"{image_tag}@{ref['digest']}" + + if ref['name'] is None: + raise ValueError(f"Invalid image URL: {image_url}") + else: + image_split = ref['name'].split('/') + if len(image_split) == 1: + image_name = image_split[0] + else: + if '.' in image_split[0]: + image_name = "/".join(image_split[1:]) + else: + image_name = ref['name'] + + image_name = f"truefoundry/{image_name}" + new_image_url = f"{destination_registry}/{image_name}{image_tag}" + return image_name, new_image_url + + +# function to pull and push images +def pull_and_push_images(image_list, destination_registry, registry_type, artifact_type): + random.shuffle(image_list) + for image in image_list: + + image_url = image["details"]["registryURL"].strip() + if not image_url: + continue + elif "/eks/" in image_url or "/eks-distro/" in image_url: + logging.info(f"Skipping system EKS image: {image_url}") + continue + elif image_url == 'auto': + logging.info(f"Skipping auto") + continue + image_name, new_image_url = parse_image_url(image_url, destination_registry) + # Check if the new_image_url already exists + try: + run_command(f"docker manifest inspect {new_image_url}") + logging.info(f"Image {new_image_url} already exists. Skipping push...") + continue + except Exception as e: + # Image does not exist, proceed with pushing + pass + + run_command(f"docker pull {image_url} --platform {DOCKER_IMAGE_ARCHITECTURE}") + + create_repository(registry_type, destination_registry, image_name, artifact_type) + + run_command(f"docker tag {image_url} {new_image_url}") + + logging.info(f"Pushing image: {new_image_url}") + try: + run_command(f"docker push {new_image_url}") + logging.info(f"Successfully pushed image: {new_image_url}") + except Exception as e: + logging.error(f"Failed to push image: {new_image_url}. Error: {e}") + + +# function to download and push Helm charts +def download_and_push_helm_charts(helm_list, destination_registry, registry_type, artifact_type): + tmp_dir = "/tmp/helm_charts" + if not os.path.exists(tmp_dir): + os.makedirs(tmp_dir) + + for helm in helm_list: + chart = helm["details"]["chart"] + repo_url = helm["details"]["repoURL"] + target_revision = helm["details"]["targetRevision"] + + logging.info(f"Downloading Helm chart: {chart} from {repo_url}") + try: + run_command(f"helm repo add {chart} {repo_url}") + run_command(f"helm pull {chart}/{chart} --version {target_revision}") + logging.info(f"Successfully downloaded Helm chart: {chart}") + except subprocess.CalledProcessError as e: + logging.error(f"Failed to download Helm chart: {chart}. Error: {e}") + continue + + # get registry URL + registry_path = urlparse(repo_url).path.strip('/') + + chart_package = f"{chart}-{target_revision}.tgz" + new_chart_url = f"oci://{destination_registry}/truefoundryhelm/{registry_path}/" + + logging.info(f"Pushing Helm chart: {new_chart_url}") + try: + if registry_path.startswith("public.ecr.aws"): + create_public_ecr_repository(f"truefoundryhelm/{registry_path}/{chart}") + else: + repo_path = f"truefoundryhelm/{registry_path}/{chart}" + create_repository(registry_type, destination_registry, repo_path, "helm") + try: + logging.info( + f"Chart {chart} with version {target_revision} does not exist in the repository. Pushing...") + run_command(f"helm push {chart_package} {new_chart_url}") + except Exception as e: + logging.error(f"Failed to check if chart {chart} with version {target_revision} exists. Error: {e}") + continue + except subprocess.CalledProcessError as e: + logging.error(f"Failed to push Helm chart: {chart_package}. Error: {e}") + + +# function to extract images from Kubernetes manifests +def read_manifest(file_path): + try: + with open(file_path, 'r') as file: + return yaml.safe_load(file) + except Exception as e: + logging.error(f"Error reading manifest file: {e}") + return None + + +# function to process the manifest +def process_manifest(artifact_type, file_path, destination_registry, registry_type): + manifest = read_manifest(file_path) + if manifest is None: + logging.error("Manifest processing aborted due to previous errors") + return + + if artifact_type == "image": + image_list = [item for item in manifest if item["type"] == "image"] + if image_list: + pull_and_push_images(image_list, destination_registry, registry_type, artifact_type) + elif artifact_type == "helm": + helm_list = [item for item in manifest if item["type"] == "helm"] + if helm_list: + download_and_push_helm_charts(helm_list, destination_registry, registry_type, artifact_type) + + +if __name__ == "__main__": + if len(sys.argv) != 5: + print("Usage: python upload_artifacts.py ") + sys.exit(1) + + artifact_type = sys.argv[1] + file_path = sys.argv[2] + destination_registry = sys.argv[3] + registry_type = sys.argv[4] + + if not os.path.isfile(file_path): + logging.error(f"File not found: {file_path}") + sys.exit(1) + + process_manifest(artifact_type, file_path, destination_registry, registry_type)