package resolver // This file will be automatically regenerated based on the schema, any resolver implementations // will be copied through when generating and any unknown code will be moved to the end. // Code generated by github.com/99designs/gqlgen version v0.17.45 import ( "context" "errors" "fmt" "edge-infra.dev/pkg/edge/api/apierror" "edge-infra.dev/pkg/edge/api/graph/mapper" "edge-infra.dev/pkg/edge/api/graph/model" "edge-infra.dev/pkg/edge/api/utils" "edge-infra.dev/pkg/edge/constants" "k8s.io/apimachinery/pkg/util/validation" ) // CreateHelmRelease is the resolver for the createHelmRelease field. func (r *mutationResolver) CreateHelmRelease(ctx context.Context, payload model.HelmReleasePayload) (bool, error) { errors := validation.IsDNS1123Label(payload.Name) if len(errors) > 0 { return false, fmt.Errorf("invalid name for helm resource: %s, errors: %v", payload.Name, errors) } errors = validation.IsDNS1123Label(payload.Namespace) if len(errors) > 0 { return false, fmt.Errorf("invalid namespace for helm resource: %s, errors: %v", payload.Namespace, errors) } var ( cluster *model.Cluster projectID string err error ) switch { case !utils.IsNullOrEmpty(payload.ClusterEdgeID): cluster, err = r.StoreClusterService.GetCluster(ctx, *payload.ClusterEdgeID) if err != nil { return false, err } projectID = cluster.ProjectID case !utils.IsNullOrEmpty(payload.BannerEdgeID): projectID, err = r.BannerService.GetBannerProjectID(ctx, *payload.BannerEdgeID) if err != nil { return false, fmt.Errorf("failed to get banner for workload: %w", err) } default: return false, apierror.New("please provide bannerEdgeId or clusterEdgeId") } valid, err := r.HelmService.ValidateHelmConfigAgainstSchema(ctx, payload.ConfigValues, projectID, payload.HelmChart, payload.Version, payload.Secret) if !valid { return false, fmt.Errorf("error validating config value against schema: %s", err) } err = r.HelmService.CreateHelmReleaseSQL(ctx, payload, cluster) if err != nil { return false, err } return true, err } // DeleteHelmRelease is the resolver for the deleteHelmRelease field. func (r *mutationResolver) DeleteHelmRelease(ctx context.Context, helmEdgeID *string, name *string, clusterEdgeID *string) (bool, error) { if !utils.IsNullOrEmpty(helmEdgeID) { err := r.HelmService.SoftDeleteHelmReleaseSQL(ctx, helmEdgeID, name, clusterEdgeID) if err != nil { return false, err } } else { hasClusterInfo := !utils.IsNullOrEmpty(name) && !utils.IsNullOrEmpty(clusterEdgeID) if hasClusterInfo { matchedWorkloads, err := r.HelmService.GetHelmWorkloadsByName(ctx, *clusterEdgeID, *name) if err != nil || len(matchedWorkloads) == 0 { return false, fmt.Errorf("there was an issue finding workload for deletion") } if len(matchedWorkloads) == 1 { err := r.HelmService.SoftDeleteHelmReleaseSQL(ctx, &matchedWorkloads[0].HelmEdgeID, &matchedWorkloads[0].Name, &matchedWorkloads[0].ClusterEdgeID) if err != nil { return false, err } } else { return false, fmt.Errorf("multiple matching workload(s) found, please use helmEdgeId instead") } } else { return false, fmt.Errorf("please provide a helmEdgeId or clusterEdgeId and workload name") } } return true, nil } // CreateOrUpdateBannerHelmRepository is the resolver for the createOrUpdateBannerHelmRepository field. func (r *mutationResolver) CreateOrUpdateBannerHelmRepository(ctx context.Context, name string, bannerEdgeID string, url string, secret *string) (bool, error) { errors := validation.IsDNS1123Label(name) if len(errors) > 0 { return false, fmt.Errorf("invalid name for helm repository: %s, errors: %v", name, errors) } projectID, err := r.BannerService.GetBannerProjectID(ctx, bannerEdgeID) if err != nil { return false, err } err = r.HelmService.CreateBannerHelmRepository(ctx, name, url, secret, projectID) if err != nil { return false, err } return true, nil } // CreateHelmRepository is the resolver for the createHelmRepository field. func (r *mutationResolver) CreateHelmRepository(ctx context.Context, name string, bannerEdgeID string, url string, username *string, password *string) (bool, error) { if _, reserved := constants.PlatformHelmRepositories[name]; reserved { return false, fmt.Errorf("the name %s is an edge reserved name. please use another", name) } errors := validation.IsDNS1123Label(name) if len(errors) > 0 { return false, fmt.Errorf("invalid name for helm repository: %s, errors: %v", name, errors) } if username != nil && password == nil { return false, fmt.Errorf("password cannot be empty when username is provided") } if password != nil && username == nil { return false, fmt.Errorf("username cannot be empty when password is provided") } if username == nil && password == nil { username = new(string) password = new(string) } index, err := r.HelmService.GetHelmRepositoryIndex(url, *username, *password) if index == nil { return false, fmt.Errorf("invalid helm repository, missing index.yaml") } if err != nil { return false, fmt.Errorf("invalid helm repository, invalid index.yaml file") } projectID, err := r.BannerService.GetBannerProjectID(ctx, bannerEdgeID) if err != nil { return false, err } defaultWorkload := string(constants.TenantNamespaceSelector) _, err = r.CreateOrUpdateSecretManagerSecret(ctx, name, bannerEdgeID, constants.DefaultOwnerFilter, mapper.ToHelmRepositoryKeyValues(name, url, username, password), &defaultWorkload, constants.HelmRepositorySecretType) if err != nil { return false, err } externalSecrets, err := r.HelmService.GenerateHelmReleaseExternalSecrets(ctx, projectID, mapper.HelmReleaseNamespace, []string{name}) if err != nil { return false, err } if err = r.HelmService.SendExternalSecretToChariot(ctx, projectID, "", externalSecrets); err != nil { return false, err } err = r.HelmService.CreateBannerHelmRepository(ctx, name, url, &name, projectID) if err != nil { return false, err } return true, nil } // DeleteHelmRepository is the resolver for the deleteHelmRepository field. func (r *mutationResolver) DeleteHelmRepository(ctx context.Context, name string, bannerEdgeID string) (bool, error) { if _, reserved := constants.PlatformHelmRepositories[name]; reserved { return false, fmt.Errorf("the name %s is an edge reserved name. please use another", name) } projectID, err := r.BannerService.GetBannerProjectID(ctx, bannerEdgeID) if err != nil { return false, err } err = r.HelmService.DeleteHelmRepo(ctx, name, projectID, bannerEdgeID) if err != nil { return false, err } return r.GCPService.DeleteSecret(ctx, name, projectID) } // DeleteBannerHelmRepository is the resolver for the deleteBannerHelmRepository field. func (r *mutationResolver) DeleteBannerHelmRepository(ctx context.Context, name string, bannerEdgeID string) (bool, error) { return r.DeleteHelmRepository(ctx, name, bannerEdgeID) } // UpdateHelmRelease is the resolver for the updateHelmRelease field. func (r *mutationResolver) UpdateHelmRelease(ctx context.Context, helmEdgeID *string, helmReleaseName *string, clusterEdgeID *string, version *string, configValues *string, injectConfigmaps []model.InjectableConfigmaps, secrets []string, labelEdgeIds []string) (bool, error) { var helmEdgeIDToUpdate string switch { case !utils.IsNullOrEmpty(helmEdgeID): helmEdgeIDToUpdate = utils.CheckString(helmEdgeID) case !utils.IsNullOrEmpty(helmReleaseName) && !utils.IsNullOrEmpty(clusterEdgeID): matchedWorkloads, err := r.HelmService.GetHelmWorkloadsByName(ctx, *clusterEdgeID, *helmReleaseName) if err != nil || len(matchedWorkloads) == 0 { return false, fmt.Errorf("there was an issue finding workload for update") } if len(matchedWorkloads) == 1 { helmEdgeIDToUpdate = utils.CheckString(&matchedWorkloads[0].HelmEdgeID) } else { return false, fmt.Errorf("multiple matching workload(s) found, please use helmEdgeId instead") } default: return false, fmt.Errorf("please provide a helmEdgeId or helmReleaseName and clusterEdgeId") } helmWorkload, err := r.HelmService.GetHelmWorkloadSQL(ctx, helmEdgeIDToUpdate) if err != nil { return false, fmt.Errorf("failed to get helm workload: %s", err) } projectID, err := r.BannerService.GetBannerProjectID(ctx, helmWorkload.BannerEdgeID) if err != nil { return false, fmt.Errorf("failed to get banner project ID: %s", err) } // validate config value against repo validation schema for ncr-charts newVersion := helmWorkload.HelmChartVersion if version != nil { newVersion = *version } newConfigValues := helmWorkload.ConfigValues if configValues != nil { newConfigValues = configValues } valid, err := r.HelmService.ValidateHelmConfigAgainstSchema(ctx, newConfigValues, projectID, helmWorkload.HelmChart, newVersion, helmWorkload.HelmRepoSecret) if !valid { return false, fmt.Errorf("error validating config value against schema: %s", err) } if secrets != nil { // Validating array of secret names user input for i := range secrets { if secrets[i] == "" { // If user passes in an empty list // Cleanse all secrets currently existed currentSecretsToDelete, err := r.HelmService.GetSecretsByHelmEdgeID(ctx, helmEdgeIDToUpdate) if err != nil { return false, err } if currentSecretsToDelete != nil { _, errDeleteSecrets := r.HelmService.DeleteHelmSecrets(ctx, helmEdgeIDToUpdate, currentSecretsToDelete) if errDeleteSecrets != nil { return false, fmt.Errorf("failed to delete helm secrets") } } err = r.HelmService.UpdateHelmReleaseSQL(ctx, helmEdgeIDToUpdate, newVersion, newConfigValues, injectConfigmaps) if err != nil { return false, err } return true, err } // If not empty, validate if secret exist on GCP _, errSecrets := r.GCPService.GetSecrets(ctx, &secrets[i], nil, nil, false, projectID) if errSecrets != nil { return false, fmt.Errorf("invalid secrets") } } // Get list of current secret currentSecretsToDelete, err := r.HelmService.GetSecretsByHelmEdgeID(ctx, helmEdgeIDToUpdate) if err != nil { return false, err } // Delete list of current secret if currentSecretsToDelete != nil { _, errDeleteSecrets := r.HelmService.DeleteHelmSecrets(ctx, helmEdgeIDToUpdate, currentSecretsToDelete) if errDeleteSecrets != nil { return false, fmt.Errorf("Failed to delete helm secrets") } // Add list of new secret _, errAddSecrets := r.HelmService.AddHelmSecrets(ctx, helmEdgeIDToUpdate, secrets) if errAddSecrets != nil { return false, fmt.Errorf("failed to add helm secrets") } } } // Update labels if labelEdgeIds != nil { _, errDelete := r.HelmService.DeleteWorkloadLabels(ctx, helmEdgeIDToUpdate) if errDelete != nil { return false, fmt.Errorf("failed to delete labels from workload") } if len(labelEdgeIds) > 0 { _, errAdd := r.HelmService.AddWorkloadLabels(ctx, helmEdgeIDToUpdate, labelEdgeIds) if errAdd != nil { return false, fmt.Errorf("failed to add labels from workload: err: %w", errAdd) } } } // Update Helm Release on DB err = r.HelmService.UpdateHelmReleaseSQL(ctx, helmEdgeIDToUpdate, newVersion, newConfigValues, injectConfigmaps) if err != nil { return false, err } return true, nil } // ValidateHelmConfig is the resolver for the validateHelmConfig field. func (r *mutationResolver) ValidateHelmConfig(ctx context.Context, payload model.ValidateHelmConfigParams) (bool, error) { projectID, err := r.BannerService.GetBannerProjectID(ctx, payload.BannerEdgeID) if err != nil { return false, err } config, err := r.HelmService.GetDefaultConfigSchema(ctx, payload.ChartName, payload.SecretName, payload.ChartVersion, projectID) if err != nil { return false, apierror.New(apierror.HelmChartError).AddGenericErrorExtension(apierror.DetailedHelmError, err) } if config == nil { return false, apierror.New(apierror.HelmChartError).AddGenericErrorExtension(apierror.DetailedHelmError, err) } if config.ConfigSchema == nil { return false, apierror.New("No schema available for chart").AddGenericErrorExtension(apierror.DetailedHelmError, err) } return r.HelmService.ValidateHelmConfig(payload.HelmConfig, *config.ConfigSchema) } // AddWorkloadLabel is the resolver for the addWorkloadLabel field. func (r *mutationResolver) AddWorkloadLabel(ctx context.Context, workloadLabelParameters model.WorkloadLabelInput) (bool, error) { return r.HelmService.AddWorkloadLabel(ctx, workloadLabelParameters.HelmEdgeID, workloadLabelParameters.LabelEdgeID) } // AddWorkloadLabels is the resolver for the addWorkloadLabels field. func (r *mutationResolver) AddWorkloadLabels(ctx context.Context, helmEdgeID string, labelEdgeIds []string) (bool, error) { return r.HelmService.AddWorkloadLabels(ctx, helmEdgeID, labelEdgeIds) } // DeleteWorkloadLabel is the resolver for the deleteWorkloadLabel field. func (r *mutationResolver) DeleteWorkloadLabel(ctx context.Context, workloadLabelParameters model.WorkloadLabelInput) (bool, error) { // Case 1: Delete this label from any workload currently using it if only labelID provided if workloadLabelParameters.HelmEdgeID == "" && workloadLabelParameters.LabelEdgeID != "" { _, errDeleteWithLabel := r.HelmService.DeleteWorkloadLabelByLabelEdgeID(ctx, workloadLabelParameters.LabelEdgeID) if errDeleteWithLabel != nil { return false, fmt.Errorf("failed to delete labels from workload with label id") } return true, nil } // Case 2: Delete all labels from this workload if only helm edge id provided if workloadLabelParameters.HelmEdgeID != "" && workloadLabelParameters.LabelEdgeID == "" { // Delete labels _, errDeleteWithHelmID := r.HelmService.DeleteWorkloadLabels(ctx, workloadLabelParameters.HelmEdgeID) if errDeleteWithHelmID != nil { return false, fmt.Errorf("failed to delete labels from workload with helm id") } // Case 3: Delete label } else { _, errDelete := r.HelmService.DeleteWorkloadLabel(ctx, workloadLabelParameters.HelmEdgeID, workloadLabelParameters.LabelEdgeID) if errDelete != nil { return false, fmt.Errorf("failed to delete labels from workload") } } return true, nil } // HelmChartVersion is the resolver for the helmChartVersion field. func (r *queryResolver) HelmChartVersion(ctx context.Context, name string, secretName string, bannerEdgeID string) (*model.HelmChartResponse, error) { projectID, err := r.BannerService.GetBannerProjectID(ctx, bannerEdgeID) if err != nil { return nil, err } chartVersion, err := r.HelmService.GetHelmChartVersion(ctx, name, secretName, projectID) if err != nil { return nil, apierror.New(apierror.HelmChartError).AddGenericErrorExtension(apierror.DetailedHelmError, err) } return chartVersion, nil } // DefaultSchemaConfig is the resolver for the defaultSchemaConfig field. func (r *queryResolver) DefaultSchemaConfig(ctx context.Context, params model.HelmConfigSchemaParams) (*model.HelmConfig, error) { projectID, err := r.BannerService.GetBannerProjectID(ctx, params.BannerEdgeID) if err != nil { return nil, err } config, err := r.HelmService.GetDefaultConfigSchema(ctx, params.ChartName, params.SecretName, params.ChartVersion, projectID) if err != nil { return nil, apierror.New(apierror.HelmChartError).AddGenericErrorExtension(apierror.DetailedHelmError, err) } return config, nil } // HelmReleases is the resolver for the helmReleases field. func (r *queryResolver) HelmReleases(ctx context.Context, clusterEdgeID string) ([]*model.HelmRelease, error) { return nil, errors.New("helmReleases query is deprecated. use helmWorkloads instead") } // HelmReleasesStatus is the resolver for the helmReleasesStatus field. func (r *queryResolver) HelmReleasesStatus(ctx context.Context, clusterEdgeID string) ([]*model.HelmReleaseStatus, error) { cluster, err := r.StoreClusterService.GetCluster(ctx, clusterEdgeID) if err != nil { return nil, err } return r.HelmService.GetHelmReleasesStatus(ctx, cluster) } // HelmWorkloads is the resolver for the helmWorkloads field. func (r *queryResolver) HelmWorkloads(ctx context.Context, clusterEdgeID *string, bannerEdgeID *string) ([]*model.HelmWorkload, error) { return r.HelmService.GetHelmWorkloads(ctx, clusterEdgeID, bannerEdgeID, true) } // HelmWorkload is the resolver for the helmWorkload field. func (r *queryResolver) HelmWorkload(ctx context.Context, helmEdgeID string, clusterEdgeID string) (*model.HelmWorkload, error) { return r.HelmService.GetHelmWorkload(ctx, helmEdgeID, clusterEdgeID) } // HelmCharts is the resolver for the helmCharts field. func (r *queryResolver) HelmCharts(ctx context.Context, secretName string, bannerEdgeID string) ([]*model.HelmChart, error) { projectID, err := r.BannerService.GetBannerProjectID(ctx, bannerEdgeID) if err != nil { return nil, err } charts, err := r.HelmService.GetHelmCharts(ctx, secretName, projectID) if err != nil { return nil, apierror.New(apierror.HelmChartError).AddGenericErrorExtension(apierror.DetailedHelmError, err) } return charts, err } // HelmRepositories is the resolver for the helmRepositories field. func (r *queryResolver) HelmRepositories(ctx context.Context, bannerEdgeID string) ([]*model.HelmRepository, error) { defaultOwnerFilter := constants.DefaultOwnerFilter helmRepoType := constants.HelmRepositorySecretType projectID, err := r.BannerService.GetBannerProjectID(ctx, bannerEdgeID) if err != nil { return nil, err } helmRepoSecrets, err := r.GCPService.GetSecrets(ctx, nil, &defaultOwnerFilter, &helmRepoType, true, projectID) if err != nil { return nil, apierror.New(apierror.HelmChartError).AddGenericErrorExtension(apierror.DetailedHelmError, err) } return mapper.ToHelmRepositoriesModels(helmRepoSecrets), nil } // HelmRepositoryInfo is the resolver for the helmRepositoryInfo field. func (r *queryResolver) HelmRepositoryInfo(ctx context.Context, params model.HelmConfigSchemaParams) (*model.HelmRepositoryInfo, error) { projectID, err := r.BannerService.GetBannerProjectID(ctx, params.BannerEdgeID) if err != nil { return nil, err } repoInfo, err := r.HelmService.GetHelmRepositoryInfo(ctx, params, projectID) if err != nil { return nil, apierror.New(apierror.HelmChartError).AddGenericErrorExtension(apierror.DetailedHelmError, err) } return repoInfo, nil }