From 7840e0bfe16f8b2ea4b94e895e94c9d6e19e3d66 Mon Sep 17 00:00:00 2001 From: Prabhat Khera <91852476+prabhat-org@users.noreply.github.com> Date: Mon, 16 Oct 2023 14:08:06 +1300 Subject: [PATCH] feature(kubernetes): stack name made optional & add toggle to disable stack in kubernetes [EE-6170] (#10436) --- .../test_data/output_24_to_latest.json | 3 + api/http/handler/settings/settings_public.go | 3 + api/http/handler/settings/settings_update.go | 10 ++- .../handler/stacks/create_kubernetes_stack.go | 10 +-- .../handler/stacks/update_kubernetes_stack.go | 13 +++ api/portainer.go | 6 ++ .../applicationsDatatable.html | 5 +- .../applicationsDatatable.js | 1 + .../helm-templates.controller.js | 5 +- app/kubernetes/converters/daemonSet.js | 4 +- app/kubernetes/converters/deployment.js | 4 +- app/kubernetes/converters/statefulSet.js | 4 +- app/kubernetes/react/components/index.ts | 9 ++ app/kubernetes/services/applicationService.js | 10 ++- .../views/applications/applications.html | 1 + .../applications/applicationsController.js | 3 + .../create/createApplication.html | 54 +++++++++++- .../create/createApplicationController.js | 12 ++- app/kubernetes/views/deploy/deploy.html | 15 +++- .../views/deploy/deployController.js | 10 ++- app/portainer/services/api/stackService.js | 3 +- .../DeployView/StackName/StackName.tsx | 84 +++++++++++++++++++ .../DetailsView/ApplicationSummaryWidget.tsx | 25 ++++-- .../environments/environment.service/index.ts | 15 ++++ .../DeploymentOptionsSection.tsx | 19 +++++ .../KubeSettingsPanel/KubeSettingsPanel.tsx | 18 ++-- .../SettingsView/KubeSettingsPanel/types.ts | 1 + .../KubeSettingsPanel/validation.ts | 1 + app/react/portainer/settings/types.ts | 4 +- 29 files changed, 305 insertions(+), 47 deletions(-) create mode 100644 app/react/kubernetes/DeployView/StackName/StackName.tsx diff --git a/api/datastore/test_data/output_24_to_latest.json b/api/datastore/test_data/output_24_to_latest.json index 8ada67237..d10397ad5 100644 --- a/api/datastore/test_data/output_24_to_latest.json +++ b/api/datastore/test_data/output_24_to_latest.json @@ -602,6 +602,9 @@ "EnableTelemetry": true, "EnforceEdgeID": false, "FeatureFlagSettings": null, + "GlobalDeploymentOptions": { + "hideStacksFunctionality": false + }, "HelmRepositoryURL": "https://charts.bitnami.com/bitnami", "InternalAuthSettings": { "RequiredPasswordLength": 12 diff --git a/api/http/handler/settings/settings_public.go b/api/http/handler/settings/settings_public.go index 6301f8c63..fd45748b2 100644 --- a/api/http/handler/settings/settings_public.go +++ b/api/http/handler/settings/settings_public.go @@ -17,6 +17,8 @@ type publicSettingsResponse struct { AuthenticationMethod portainer.AuthenticationMethod `json:"AuthenticationMethod" example:"1"` // The minimum required length for a password of any user when using internal auth mode RequiredPasswordLength int `json:"RequiredPasswordLength" example:"1"` + // Deployment options for encouraging deployment as code + GlobalDeploymentOptions portainer.GlobalDeploymentOptions `json:"GlobalDeploymentOptions"` // Show the Kompose build option (discontinued in 2.18) ShowKomposeBuildOption bool `json:"ShowKomposeBuildOption" example:"false"` // Whether edge compute features are enabled @@ -78,6 +80,7 @@ func generatePublicSettings(appSettings *portainer.Settings) *publicSettingsResp AuthenticationMethod: appSettings.AuthenticationMethod, RequiredPasswordLength: appSettings.InternalAuthSettings.RequiredPasswordLength, EnableEdgeComputeFeatures: appSettings.EnableEdgeComputeFeatures, + GlobalDeploymentOptions: appSettings.GlobalDeploymentOptions, ShowKomposeBuildOption: appSettings.ShowKomposeBuildOption, EnableTelemetry: appSettings.EnableTelemetry, KubeconfigExpiry: appSettings.KubeconfigExpiry, diff --git a/api/http/handler/settings/settings_update.go b/api/http/handler/settings/settings_update.go index 51f1f8e09..574050c4d 100644 --- a/api/http/handler/settings/settings_update.go +++ b/api/http/handler/settings/settings_update.go @@ -32,8 +32,9 @@ type settingsUpdatePayload struct { SnapshotInterval *string `example:"5m"` // URL to the templates that will be displayed in the UI when navigating to App Templates TemplatesURL *string `example:"https://raw.githubusercontent.com/portainer/templates/master/templates.json"` - // The default check in interval for edge agent (in seconds) - EdgeAgentCheckinInterval *int `example:"5"` + // Deployment options for encouraging deployment as code + GlobalDeploymentOptions *portainer.GlobalDeploymentOptions // The default check in interval for edge agent (in seconds) + EdgeAgentCheckinInterval *int `example:"5"` // Show the Kompose build option (discontinued in 2.18) ShowKomposeBuildOption *bool `json:"ShowKomposeBuildOption" example:"false"` // Whether edge compute features are enabled @@ -159,6 +160,11 @@ func (handler *Handler) updateSettings(tx dataservices.DataStoreTx, payload sett settings.TemplatesURL = *payload.TemplatesURL } + // update the global deployment options, and the environment deployment options if they have changed + if payload.GlobalDeploymentOptions != nil { + settings.GlobalDeploymentOptions = *payload.GlobalDeploymentOptions + } + if payload.ShowKomposeBuildOption != nil { settings.ShowKomposeBuildOption = *payload.ShowKomposeBuildOption } diff --git a/api/http/handler/stacks/create_kubernetes_stack.go b/api/http/handler/stacks/create_kubernetes_stack.go index 979bff0ce..201ae3e68 100644 --- a/api/http/handler/stacks/create_kubernetes_stack.go +++ b/api/http/handler/stacks/create_kubernetes_stack.go @@ -94,9 +94,7 @@ func (payload *kubernetesStringDeploymentPayload) Validate(r *http.Request) erro if govalidator.IsNull(payload.StackFileContent) { return errors.New("Invalid stack file content") } - if govalidator.IsNull(payload.StackName) { - return errors.New("Invalid stack name") - } + return nil } @@ -113,9 +111,6 @@ func (payload *kubernetesGitDeploymentPayload) Validate(r *http.Request) error { if err := update.ValidateAutoUpdateSettings(payload.AutoUpdate); err != nil { return err } - if govalidator.IsNull(payload.StackName) { - return errors.New("Invalid stack name") - } return nil } @@ -123,9 +118,6 @@ func (payload *kubernetesManifestURLDeploymentPayload) Validate(r *http.Request) if govalidator.IsNull(payload.ManifestURL) || !govalidator.IsURL(payload.ManifestURL) { return errors.New("Invalid manifest URL") } - if govalidator.IsNull(payload.StackName) { - return errors.New("Invalid stack name") - } return nil } diff --git a/api/http/handler/stacks/update_kubernetes_stack.go b/api/http/handler/stacks/update_kubernetes_stack.go index f167ebc1e..5920144e0 100644 --- a/api/http/handler/stacks/update_kubernetes_stack.go +++ b/api/http/handler/stacks/update_kubernetes_stack.go @@ -24,6 +24,8 @@ import ( type kubernetesFileStackUpdatePayload struct { StackFileContent string + // Name of the stack + StackName string } type kubernetesGitStackUpdatePayload struct { @@ -39,6 +41,9 @@ func (payload *kubernetesFileStackUpdatePayload) Validate(r *http.Request) error if govalidator.IsNull(payload.StackFileContent) { return errors.New("Invalid stack file content") } + if govalidator.IsNull(payload.StackName) { + return errors.New("Invalid stack name") + } return nil } @@ -114,6 +119,14 @@ func (handler *Handler) updateKubernetesStack(r *http.Request, stack *portainer. return httperror.InternalServerError("Failed to persist deployment file in a temp directory", err) } + if payload.StackName != stack.Name { + stack.Name = payload.StackName + err := handler.DataStore.Stack().Update(stack.ID, stack) + if err != nil { + return httperror.InternalServerError("Failed to update stack name", err) + } + } + // Refresh ECR registry secret if needed // RefreshEcrSecret method checks if the namespace has any ECR registry // otherwise return nil diff --git a/api/portainer.go b/api/portainer.go index 873bde1c3..f0bf53aae 100644 --- a/api/portainer.go +++ b/api/portainer.go @@ -933,6 +933,10 @@ type ( RetryInterval int } + GlobalDeploymentOptions struct { + HideStacksFunctionality bool `json:"hideStacksFunctionality" example:"false"` + } + // Settings represents the application settings Settings struct { // URL to a logo that will be displayed on the login page as well as on top of the sidebar. Will use default Portainer logo when value is empty string @@ -951,6 +955,8 @@ type ( SnapshotInterval string `json:"SnapshotInterval" example:"5m"` // URL to the templates that will be displayed in the UI when navigating to App Templates TemplatesURL string `json:"TemplatesURL" example:"https://raw.githubusercontent.com/portainer/templates/master/templates.json"` + // Deployment options for encouraging git ops workflows + GlobalDeploymentOptions GlobalDeploymentOptions `json:"GlobalDeploymentOptions"` // The default check in interval for edge agent (in seconds) EdgeAgentCheckinInterval int `json:"EdgeAgentCheckinInterval" example:"5"` // Show the Kompose build option (discontinued in 2.18) diff --git a/app/kubernetes/components/datatables/applications-datatable/applicationsDatatable.html b/app/kubernetes/components/datatables/applications-datatable/applicationsDatatable.html index 13bec8dc9..6bbe34867 100644 --- a/app/kubernetes/components/datatables/applications-datatable/applicationsDatatable.html +++ b/app/kubernetes/components/datatables/applications-datatable/applicationsDatatable.html @@ -172,7 +172,7 @@ ng-click="$ctrl.changeOrderBy('Name')" > -