Przeglądaj źródła

add cluster-level setting to enable preview envs

Mohammed Nafees 3 lat temu
rodzic
commit
8ae3d7bfef

+ 4 - 0
api/server/handlers/cluster/update.go

@@ -65,6 +65,10 @@ func (c *ClusterUpdateHandler) ServeHTTP(w http.ResponseWriter, r *http.Request)
 		cluster.AgentIntegrationEnabled = *request.AgentIntegrationEnabled
 	}
 
+	if request.PreviewEnvsEnabled != nil {
+		cluster.PreviewEnvsEnabled = *request.PreviewEnvsEnabled
+	}
+
 	if request.Name != "" && cluster.Name != request.Name {
 		cluster.Name = request.Name
 	}

+ 5 - 0
api/types/cluster.go

@@ -35,6 +35,9 @@ type Cluster struct {
 
 	// (optional) The aws cluster id, if available
 	AWSClusterID string `json:"aws_cluster_id,omitempty"`
+
+	// Whether preview environments is enabled on this cluster
+	PreviewEnvsEnabled bool `json:"preview_envs_enabled"`
 }
 
 type ClusterCandidate struct {
@@ -273,6 +276,8 @@ type UpdateClusterRequest struct {
 	AWSClusterID string `json:"aws_cluster_id"`
 
 	AgentIntegrationEnabled *bool `json:"agent_integration_enabled"`
+
+	PreviewEnvsEnabled *bool `json:"preview_envs_enabled"`
 }
 
 type ListClusterResponse []*Cluster

+ 51 - 0
dashboard/src/main/home/cluster-dashboard/dashboard/ClusterSettings.tsx

@@ -32,6 +32,10 @@ const ClusterSettings: React.FC = () => {
     currentCluster.agent_integration_enabled
   );
   const [agentLoading, setAgentLoading] = useState(false);
+  const [enablePreviewEnvs, setEnablePreviewEnvs] = useState(
+    currentCluster.preview_envs_enabled
+  );
+  const [previewEnvsLoading, setPreviewEnvsLoading] = useState(false);
 
   let rotateCredentials = () => {
     api
@@ -99,6 +103,29 @@ const ClusterSettings: React.FC = () => {
       });
   };
 
+  let updatePreviewEnvironmentsEnabled = () => {
+    setPreviewEnvsLoading(true);
+
+    api
+      .updateCluster(
+        "<token>",
+        {
+          preview_envs_enabled: enablePreviewEnvs,
+        },
+        {
+          project_id: currentProject.id,
+          cluster_id: currentCluster.id,
+        }
+      )
+      .then(({ data }) => {
+        setCurrentCluster(data);
+        setPreviewEnvsLoading(false);
+      })
+      .catch(() => {
+        setPreviewEnvsLoading(false);
+      });
+  };
+
   let helperText = (
     <Helper>
       Delete this cluster and underlying infrastructure. To ensure that
@@ -233,6 +260,28 @@ const ClusterSettings: React.FC = () => {
     enableAgentIntegration = <Loading />;
   }
 
+  let enablePreviewEnvironments = null;
+
+  if (currentProject.preview_envs_enabled) {
+    if (previewEnvsLoading) {
+      enablePreviewEnvironments = <Loading />;
+    } else {
+      enablePreviewEnvironments = (
+        <div>
+          <Heading>Enable Preview Environments</Heading>
+          <CheckboxRow
+            label={"Create preview environments on this cluster"}
+            toggle={() => setEnablePreviewEnvs(!enablePreviewEnvs)}
+            checked={enablePreviewEnvs}
+          />
+          <Button color="#616FEEcc" onClick={updatePreviewEnvironmentsEnabled}>
+            Save
+          </Button>
+        </div>
+      );
+    }
+  }
+
   if (capabilities.version == "production") {
     enableAgentIntegration = null;
   }
@@ -251,6 +300,8 @@ const ClusterSettings: React.FC = () => {
       <StyledSettingsSection>
         {enableAgentIntegration}
         <DarkMatter />
+        {enablePreviewEnvironments}
+        <DarkMatter />
         {keyRotationSection}
         <DarkMatter />
         {renameClusterSection}

+ 1 - 1
dashboard/src/main/home/sidebar/ClusterSection.tsx

@@ -106,7 +106,7 @@ export const ClusterSection: React.FC<Props> = ({
               Stacks
             </NavButton>
           ) : null}
-          {currentProject?.preview_envs_enabled && (
+          {currentCluster?.preview_envs_enabled && (
             <NavButton
               path="/preview-environments"
               targetClusterName={cluster?.name}

+ 1 - 0
dashboard/src/shared/api.tsx

@@ -102,6 +102,7 @@ const updateCluster = baseApi<
     name?: string;
     aws_cluster_id?: string;
     agent_integration_enabled?: boolean;
+    preview_envs_enabled?: boolean;
   },
   {
     project_id: number;

+ 1 - 0
dashboard/src/shared/types.tsx

@@ -10,6 +10,7 @@ export interface ClusterType {
   service?: string;
   aws_integration_id?: number;
   aws_cluster_id?: string;
+  preview_envs_enabled?: boolean;
 }
 
 export interface DetailedClusterType extends ClusterType {

+ 3 - 0
internal/models/cluster.go

@@ -58,6 +58,8 @@ type Cluster struct {
 
 	NotificationsDisabled bool `json:"notifications_disabled"`
 
+	PreviewEnvsEnabled bool
+
 	AWSClusterID string
 
 	// ------------------------------------------------------------------
@@ -107,6 +109,7 @@ func (c *Cluster) ToClusterType() *types.Cluster {
 		InfraID:                 c.InfraID,
 		AWSIntegrationID:        c.AWSIntegrationID,
 		AWSClusterID:            c.AWSClusterID,
+		PreviewEnvsEnabled:      c.PreviewEnvsEnabled,
 	}
 }
 

+ 10 - 2
internal/models/environment.go

@@ -1,6 +1,7 @@
 package models
 
 import (
+	"github.com/mitchellh/mapstructure"
 	"github.com/porter-dev/porter/api/types"
 	"gorm.io/gorm"
 )
@@ -31,7 +32,7 @@ type Environment struct {
 }
 
 func (e *Environment) ToEnvironmentType() *types.Environment {
-	return &types.Environment{
+	env := &types.Environment{
 		ID:                e.Model.ID,
 		ProjectID:         e.ProjectID,
 		ClusterID:         e.ClusterID,
@@ -39,11 +40,18 @@ func (e *Environment) ToEnvironmentType() *types.Environment {
 		GitRepoOwner:      e.GitRepoOwner,
 		GitRepoName:       e.GitRepoName,
 
-		NewCommentsDisabled: e.NewCommentsDisabled,
+		NewCommentsDisabled:  e.NewCommentsDisabled,
+		CustomNamespace:      e.CustomNamespace,
+		NamespaceAnnotations: make(map[string]string),
 
 		Name: e.Name,
 		Mode: e.Mode,
 	}
+
+	// FIXME: should not ignore the error here
+	mapstructure.Decode(e.NamespaceAnnotations, &env.NamespaceAnnotations)
+
+	return env
 }
 
 type Deployment struct {

+ 15 - 0
internal/repository/gorm/cluster.go

@@ -1,6 +1,8 @@
 package gorm
 
 import (
+	"fmt"
+
 	"github.com/porter-dev/porter/internal/encryption"
 	"github.com/porter-dev/porter/internal/models"
 	"github.com/porter-dev/porter/internal/repository"
@@ -250,6 +252,19 @@ func (repo *ClusterRepository) UpdateCluster(
 		return nil, err
 	}
 
+	if cluster.PreviewEnvsEnabled {
+		// this should only work if the corresponding project has preview environments enabled
+		project := &models.Project{}
+
+		if err := repo.db.Where("id = ?", cluster.ProjectID).First(project).Error; err != nil {
+			return nil, fmt.Errorf("error fetching details about cluster's project: %w", err)
+		}
+
+		if !project.PreviewEnvsEnabled {
+			cluster.PreviewEnvsEnabled = false
+		}
+	}
+
 	if err := repo.db.Save(cluster).Error; err != nil {
 		return nil, err
 	}