// Copyright 2024 The Devstar Authors. All rights reserved. // SPDX-License-Identifier: MIT package appstore import ( "context" k8s "code.gitea.io/gitea/modules/k8s" applicationv1 "code.gitea.io/gitea/modules/k8s/api/application/v1" "code.gitea.io/gitea/modules/k8s/application" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) // K8sManager handles Kubernetes-specific application operations type K8sManager struct { ctx context.Context } // NewK8sManager creates a new Kubernetes manager func NewK8sManager(ctx context.Context) *K8sManager { return &K8sManager{ ctx: ctx, } } // InstallAppToKubernetes installs an application to a Kubernetes cluster func (km *K8sManager) InstallAppToKubernetes(app *App, kubeconfig []byte, contextName string) error { // Validate that the app supports Kubernetes deployment if app.Deploy.Type != "kubernetes" && app.DeploymentType != "kubernetes" && app.DeploymentType != "both" { return &AppStoreError{ Code: "DEPLOYMENT_TYPE_ERROR", Message: "Application does not support Kubernetes deployment", } } // Get Kubernetes client k8sClient, err := k8s.GetKubernetesClient(km.ctx, kubeconfig, contextName) if err != nil { return &AppStoreError{ Code: "KUBERNETES_CLIENT_ERROR", Message: "Failed to create Kubernetes client", Details: err.Error(), } } // Build Kubernetes create options createOptions, err := BuildK8sCreateOptions(app) if err != nil { return &AppStoreError{ Code: "KUBERNETES_OPTIONS_ERROR", Message: "Failed to build Kubernetes create options", Details: err.Error(), } } // Create the application in Kubernetes _, err = application.CreateApplication(km.ctx, k8sClient, createOptions) if err != nil { return &AppStoreError{ Code: "KUBERNETES_CREATE_ERROR", Message: "Failed to create application in Kubernetes", Details: err.Error(), } } return nil } // UninstallAppFromKubernetes uninstalls an application from a Kubernetes cluster func (km *K8sManager) UninstallAppFromKubernetes(app *App, kubeconfig []byte, contextName string) error { // Validate that the app supports Kubernetes deployment if app.Deploy.Type != "kubernetes" && app.DeploymentType != "kubernetes" && app.DeploymentType != "both" { return &AppStoreError{ Code: "DEPLOYMENT_TYPE_ERROR", Message: "Application does not support Kubernetes deployment", } } // Get Kubernetes client k8sClient, err := k8s.GetKubernetesClient(km.ctx, kubeconfig, contextName) if err != nil { return &AppStoreError{ Code: "KUBERNETES_CLIENT_ERROR", Message: "Failed to create Kubernetes client", Details: err.Error(), } } // Build Kubernetes delete options deleteOptions, err := BuildK8sDeleteOptions(app, "") if err != nil { return &AppStoreError{ Code: "KUBERNETES_OPTIONS_ERROR", Message: "Failed to build Kubernetes delete options", Details: err.Error(), } } // Delete the application from Kubernetes err = application.DeleteApplication(km.ctx, k8sClient, deleteOptions) if err != nil { return &AppStoreError{ Code: "KUBERNETES_DELETE_ERROR", Message: "Failed to delete application from Kubernetes", Details: err.Error(), } } return nil } // GetAppFromKubernetes gets an application from a Kubernetes cluster func (km *K8sManager) GetAppFromKubernetes(app *App, kubeconfig []byte, contextName string) (interface{}, error) { // Validate that the app supports Kubernetes deployment if app.Deploy.Type != "kubernetes" && app.DeploymentType != "kubernetes" && app.DeploymentType != "both" { return nil, &AppStoreError{ Code: "DEPLOYMENT_TYPE_ERROR", Message: "Application does not support Kubernetes deployment", } } // Get Kubernetes client k8sClient, err := k8s.GetKubernetesClient(km.ctx, kubeconfig, contextName) if err != nil { return nil, &AppStoreError{ Code: "KUBERNETES_CLIENT_ERROR", Message: "Failed to create Kubernetes client", Details: err.Error(), } } // Build Kubernetes get options getOptions, err := BuildK8sGetOptions(app, "", false) if err != nil { return nil, &AppStoreError{ Code: "KUBERNETES_OPTIONS_ERROR", Message: "Failed to build Kubernetes get options", Details: err.Error(), } } // Get the application from Kubernetes return application.GetApplication(km.ctx, k8sClient, getOptions) } // ListAppsFromKubernetes lists applications from a Kubernetes cluster func (km *K8sManager) ListAppsFromKubernetes(app *App, kubeconfig []byte, contextName string) (*applicationv1.ApplicationList, error) { // Validate that the app supports Kubernetes deployment if app.Deploy.Type != "kubernetes" && app.DeploymentType != "kubernetes" && app.DeploymentType != "both" { return nil, &AppStoreError{ Code: "DEPLOYMENT_TYPE_ERROR", Message: "Application does not support Kubernetes deployment", } } // Get Kubernetes client k8sClient, err := k8s.GetKubernetesClient(km.ctx, kubeconfig, contextName) if err != nil { return nil, &AppStoreError{ Code: "KUBERNETES_CLIENT_ERROR", Message: "Failed to create Kubernetes client", Details: err.Error(), } } // Build Kubernetes list options listOptions, err := BuildK8sListOptions("", metav1.ListOptions{}) if err != nil { return nil, &AppStoreError{ Code: "KUBERNETES_OPTIONS_ERROR", Message: "Failed to build Kubernetes list options", Details: err.Error(), } } // List applications from Kubernetes return application.ListApplications(km.ctx, k8sClient, listOptions) } // UpdateAppInKubernetes updates an application in a Kubernetes cluster func (km *K8sManager) UpdateAppInKubernetes(app *App, kubeconfig []byte, contextName string) error { // Validate that the app supports Kubernetes deployment if app.Deploy.Type != "kubernetes" && app.DeploymentType != "kubernetes" && app.DeploymentType != "both" { return &AppStoreError{ Code: "DEPLOYMENT_TYPE_ERROR", Message: "Application does not support Kubernetes deployment", } } // Get Kubernetes client k8sClient, err := k8s.GetKubernetesClient(km.ctx, kubeconfig, contextName) if err != nil { return &AppStoreError{ Code: "KUBERNETES_CLIENT_ERROR", Message: "Failed to create Kubernetes client", Details: err.Error(), } } // Build Kubernetes update options updateOptions, err := BuildK8sUpdateOptions(app, "", nil) if err != nil { return &AppStoreError{ Code: "KUBERNETES_OPTIONS_ERROR", Message: "Failed to build Kubernetes update options", Details: err.Error(), } } // Update the application in Kubernetes _, err = application.UpdateApplication(km.ctx, k8sClient, updateOptions) if err != nil { return &AppStoreError{ Code: "KUBERNETES_UPDATE_ERROR", Message: "Failed to update application in Kubernetes", Details: err.Error(), } } return nil }