Преглед изворни кода

Revert "Implement stack and stack source config name update"

Porter Support пре 3 година
родитељ
комит
73d7b4a8b8

+ 2 - 11
api/server/handlers/stack/create.go

@@ -261,21 +261,12 @@ func getSourceConfigModels(sourceConfigs []*types.CreateStackSourceConfigRequest
 				return nil, err
 			}
 
-			newSourceConfig := &models.StackSourceConfig{
+			res = append(res, models.StackSourceConfig{
 				UID:          uid,
 				Name:         sourceConfig.Name,
 				ImageRepoURI: sourceConfig.ImageRepoURI,
 				ImageTag:     sourceConfig.ImageTag,
-			}
-
-			// If the source config had a source config ID then we need to copy it over
-			if sourceConfig.StableSourceConfigID != "" {
-				newSourceConfig.StableSourceConfigID = sourceConfig.StableSourceConfigID
-			} else {
-				newSourceConfig.StableSourceConfigID = string(uid)
-			}
-
-			res = append(res, *newSourceConfig)
+			})
 		}
 	}
 

+ 0 - 64
api/server/handlers/stack/update_stack.go

@@ -1,64 +0,0 @@
-package stack
-
-import (
-	"fmt"
-	"net/http"
-
-	"github.com/porter-dev/porter/api/server/handlers"
-	"github.com/porter-dev/porter/api/server/shared"
-	"github.com/porter-dev/porter/api/server/shared/apierrors"
-	"github.com/porter-dev/porter/api/server/shared/config"
-	"github.com/porter-dev/porter/api/types"
-	"github.com/porter-dev/porter/internal/models"
-)
-
-type StackUpdateStack struct {
-	handlers.PorterHandlerReadWriter
-}
-
-func NewStackUpdateStackHandler(
-	config *config.Config,
-	reader shared.RequestDecoderValidator,
-	writer shared.ResultWriter,
-) *StackUpdateStack {
-	return &StackUpdateStack{
-		PorterHandlerReadWriter: handlers.NewDefaultPorterHandler(config, reader, writer),
-	}
-}
-
-func (p *StackUpdateStack) ServeHTTP(w http.ResponseWriter, r *http.Request) {
-	proj, _ := r.Context().Value(types.ProjectScope).(*models.Project)
-	stack, _ := r.Context().Value(types.StackScope).(*models.Stack)
-
-	req := &types.UpdateStackRequest{}
-
-	if ok := p.DecodeAndValidate(w, r, req); !ok {
-		return
-	}
-
-	if len(stack.Revisions) == 0 {
-		p.HandleAPIError(w, r, apierrors.NewErrPassThroughToClient(
-			fmt.Errorf("no stack revisions exist"), http.StatusBadRequest,
-		))
-		return
-	}
-
-	stack, err := p.Repo().Stack().ReadStackByID(proj.ID, stack.ID)
-
-	if err != nil {
-		p.HandleAPIError(w, r, apierrors.NewErrInternal(err))
-		return
-	}
-
-	// Update stack name
-	stack.Name = req.Name
-
-	newStack, err := p.Repo().Stack().UpdateStack(stack)
-
-	if err != nil {
-		p.HandleAPIError(w, r, apierrors.NewErrInternal(err))
-		return
-	}
-
-	p.WriteResult(w, r, newStack)
-}

+ 1 - 57
api/server/router/v1/stack.go

@@ -9,7 +9,7 @@ import (
 	"github.com/porter-dev/porter/api/types"
 )
 
-// swagger:parameters getStack deleteStack putStackSource rollbackStack listStackRevisions addApplication addEnvGroup updateStack
+// swagger:parameters getStack deleteStack putStackSource rollbackStack listStackRevisions addApplication addEnvGroup
 type stackPathParams struct {
 	// The project id
 	// in: path
@@ -820,61 +820,5 @@ func getV1StackRoutes(
 		Router:   r,
 	})
 
-	// PATCH /api/v1/projects/{project_id}/clusters/{cluster_id}/namespaces/{namespace}/stacks/{stack_id} -> stack.NewStackUpdateStackHandler
-	// swagger:operation PATCH /api/v1/projects/{project_id}/clusters/{cluster_id}/namespaces/{namespace}/stacks/{stack_id} updateStack
-	//
-	// Updates a stack. Currently the only value available to update is the stack name.
-	//
-	// ---
-	// produces:
-	// - application/json
-	// summary: Update Stack
-	// tags:
-	// - Stacks
-	// parameters:
-	//   - name: project_id
-	//   - name: cluster_id
-	//   - name: namespace
-	//   - name: stack_id
-	//   - in: body
-	//     name: UpdateStack
-	//     description: The stack to update
-	//     schema:
-	//       $ref: '#/definitions/UpdateStackRequest'
-	// responses:
-	//   '200':
-	//     description: Successfully updated the stack
-	//   '403':
-	//     description: Forbidden
-	updateStackEndpoint := factory.NewAPIEndpoint(
-		&types.APIRequestMetadata{
-			Verb:   types.APIVerbUpdate,
-			Method: types.HTTPVerbPatch,
-			Path: &types.Path{
-				Parent:       basePath,
-				RelativePath: relPath + "/{stack_id}",
-			},
-			Scopes: []types.PermissionScope{
-				types.UserScope,
-				types.ProjectScope,
-				types.ClusterScope,
-				types.NamespaceScope,
-				types.StackScope,
-			},
-		},
-	)
-
-	updateStackHandler := stack.NewStackUpdateStackHandler(
-		config,
-		factory.GetDecoderValidator(),
-		factory.GetResultWriter(),
-	)
-
-	routes = append(routes, &router.Route{
-		Endpoint: updateStackEndpoint,
-		Handler:  updateStackHandler,
-		Router:   r,
-	})
-
 	return routes, newPath
 }

+ 0 - 10
api/types/stacks.go

@@ -63,11 +63,6 @@ type CreateStackAppResourceRequest struct {
 	SourceConfigName string `json:"source_config_name" form:"required"`
 }
 
-// swagger:model
-type UpdateStackRequest struct {
-	Name string `json:"name" form:"required"`
-}
-
 // swagger:model
 type Stack struct {
 	// The time that the stack was initially created
@@ -226,9 +221,6 @@ type StackSourceConfig struct {
 
 	// If this field is empty, the resource is deployed directly from the image repo uri
 	StackSourceConfigBuild *StackSourceConfigBuild `json:"build,omitempty"`
-
-	// Unique ID to identify between revisions
-	StableSourceConfigID string `json:"stable_source_config_id"`
 }
 
 // swagger:model
@@ -262,8 +254,6 @@ type CreateStackSourceConfigRequest struct {
 	// required: true
 	ImageTag string `json:"image_tag" form:"required"`
 
-	StableSourceConfigID string `json:"source_config_id,omitempty"`
-
 	// If this field is empty, the resource is deployed directly from the image repo uri
 	StackSourceConfigBuild *StackSourceConfigBuild `json:"build,omitempty"`
 }

+ 1 - 5
dashboard/src/main/home/cluster-dashboard/stacks/ExpandedStack/ExpandedStack.tsx

@@ -218,11 +218,7 @@ const ExpandedStack = () => {
             component: (
               <>
                 <Gap></Gap>
-                <Settings
-                  stack={stack}
-                  onDelete={handleDelete}
-                  onUpdate={refreshStack}
-                />
+                <Settings stackName={stack.name} onDelete={handleDelete} />
               </>
             ),
           },

+ 72 - 111
dashboard/src/main/home/cluster-dashboard/stacks/ExpandedStack/_SourceConfig.tsx

@@ -1,9 +1,11 @@
+import { Tooltip } from "@material-ui/core";
+import ImageSelector from "components/image-selector/ImageSelector";
 import SaveButton from "components/SaveButton";
-import React, { useContext, useReducer, useRef, useState } from "react";
+import React, { useContext, useMemo, useState } from "react";
 import api from "shared/api";
 import { Context } from "shared/Context";
 import styled from "styled-components";
-import { FullStackRevision, SourceConfig } from "../types";
+import { AppResource, FullStackRevision, SourceConfig, Stack } from "../types";
 import SourceEditorDocker from "./components/SourceEditorDocker";
 
 const _SourceConfig = ({
@@ -62,13 +64,39 @@ const _SourceConfig = ({
   return (
     <SourceConfigStyles.Wrapper>
       {revision.source_configs.map((sourceConfig) => {
+        const apps = getAppsFromSourceConfig(revision.resources, sourceConfig);
+
+        const appList = formatAppList(apps, 2);
         return (
-          <SourceConfigItem
-            sourceConfig={sourceConfig}
-            key={sourceConfig.id}
-            handleChange={handleChange}
-            disabled={readOnly || buttonStatus === "loading"}
-          />
+          <SourceConfigStyles.ItemContainer>
+            {appList.hiddenApps?.length ? (
+              <Tooltip
+                title={
+                  <>
+                    {appList.hiddenApps.map((appName) => (
+                      <SourceConfigStyles.TooltipItem>
+                        {appName}
+                      </SourceConfigStyles.TooltipItem>
+                    ))}
+                  </>
+                }
+                placement={"bottom-end"}
+              >
+                <SourceConfigStyles.ItemTitle>
+                  Used by {appList.value}
+                </SourceConfigStyles.ItemTitle>
+              </Tooltip>
+            ) : (
+              <SourceConfigStyles.ItemTitle>
+                Used by {appList.value}
+              </SourceConfigStyles.ItemTitle>
+            )}
+            <SourceEditorDocker
+              sourceConfig={sourceConfig}
+              onChange={handleChange}
+              readOnly={readOnly || buttonStatus === "loading"}
+            />
+          </SourceConfigStyles.ItemContainer>
         );
       })}
       {readOnly ? null : (
@@ -89,6 +117,41 @@ const _SourceConfig = ({
 
 export default _SourceConfig;
 
+const getAppsFromSourceConfig = (
+  apps: AppResource[],
+  sourceConfig: SourceConfig
+) => {
+  return apps.filter((app) => {
+    return app.stack_source_config.id === sourceConfig.id;
+  });
+};
+
+const formatAppList = (apps: AppResource[], limit: number = 3) => {
+  if (apps.length <= limit) {
+    const formatter = new Intl.ListFormat("en", {
+      style: "long",
+      type: "conjunction",
+    });
+    return {
+      value: formatter.format(apps.map((app) => app.name)),
+      hiddenApps: [],
+    };
+  }
+
+  const hiddenApps = [...apps]
+    .splice(limit, apps.length)
+    .map((app) => app.name);
+
+  return {
+    value: apps
+      .map((app) => app.name)
+      .splice(0, limit)
+      .join(", ")
+      .concat(` and ${apps.length - limit} more`),
+    hiddenApps,
+  };
+};
+
 const SourceConfigStyles = {
   Wrapper: styled.div`
     margin-top: 30px;
@@ -101,17 +164,8 @@ const SourceConfigStyles = {
   `,
   ItemTitle: styled.div`
     font-size: 16px;
+    width: fit-content;
     font-weight: 500;
-
-    display: flex;
-    align-items: center;
-    justify-content: space-between;
-    gap: 10px;
-    > span {
-      overflow-x: hidden;
-      text-overflow: ellipsis;
-      white-space: nowrap;
-    }
   `,
   TooltipItem: styled.div`
     font-size: 14px;
@@ -125,96 +179,3 @@ const SourceConfigStyles = {
     z-index: unset;
   `,
 };
-
-const SourceConfigItem = ({
-  sourceConfig,
-  handleChange,
-  disabled,
-}: {
-  sourceConfig: SourceConfig;
-  handleChange: (sourceConfig: SourceConfig) => void;
-  disabled: boolean;
-}) => {
-  const [editNameMode, toggleEditNameMode] = useReducer((prev) => !prev, false);
-  const prevName = useRef(sourceConfig.name);
-  const [name, setName] = useState(sourceConfig.name);
-
-  const handleNameChange = (newName: string) => {
-    setName(newName);
-    handleChange({ ...sourceConfig, name: newName });
-  };
-
-  const handleNameChangeCancel = () => {
-    setName(prevName.current);
-    handleChange({ ...sourceConfig, name: prevName.current });
-    toggleEditNameMode();
-  };
-
-  return (
-    <SourceConfigStyles.ItemContainer>
-      {editNameMode && !disabled ? (
-        <>
-          <SourceConfigStyles.ItemTitle>
-            <PlainTextInput
-              value={name}
-              onChange={(e) => handleNameChange(e.target.value)}
-              type="text"
-              disabled={disabled}
-            />
-            <EditButton onClick={handleNameChangeCancel}>
-              <i className="material-icons-outlined">close</i>
-            </EditButton>
-          </SourceConfigStyles.ItemTitle>
-        </>
-      ) : (
-        <SourceConfigStyles.ItemTitle>
-          <span>{name}</span>
-
-          {sourceConfig.stable_source_config_id && (
-            <EditButton
-              onClick={toggleEditNameMode}
-              disabled={!sourceConfig.stable_source_config_id}
-            >
-              <i className="material-icons-outlined">edit</i>
-            </EditButton>
-          )}
-        </SourceConfigStyles.ItemTitle>
-      )}
-
-      <SourceEditorDocker
-        sourceConfig={sourceConfig}
-        onChange={handleChange}
-        readOnly={disabled}
-      />
-    </SourceConfigStyles.ItemContainer>
-  );
-};
-
-const EditButton = styled.button`
-  outline: none;
-  cursor: pointer;
-  color: white;
-  border: 1px solid rgba(255, 255, 255, 0.333);
-  background: rgba(255, 255, 255, 0.067);
-  height: 35px;
-  width: 35px;
-  border-radius: 24px;
-  display: flex;
-  align-items: center;
-  justify-content: center;
-  > i {
-    font-size: 20px;
-  }
-`;
-
-const PlainTextInput = styled.input`
-  outline: none;
-  border: 1px solid #ffffff55;
-  border-radius: 3px;
-  font-size: 13px;
-  background: #ffffff11;
-  width: 100%;
-  color: white;
-  padding: 5px 10px;
-  height: 35px;
-`;

+ 5 - 67
dashboard/src/main/home/cluster-dashboard/stacks/ExpandedStack/components/Settings.tsx

@@ -1,30 +1,16 @@
 import Heading from "components/form-components/Heading";
-import Helper from "components/form-components/Helper";
-import InputRow from "components/form-components/InputRow";
-import React, { useContext, useState } from "react";
-import api from "shared/api";
+import React, { useContext } from "react";
 import { Context } from "shared/Context";
 import styled from "styled-components";
-import { SubmitButton } from "../../launch/components/styles";
-import { Stack } from "../../types";
 
 const Settings = ({
-  stack,
+  stackName,
   onDelete,
-  onUpdate,
 }: {
-  stack: Stack;
+  stackName: string;
   onDelete: () => void;
-  onUpdate: () => Promise<void>;
 }) => {
-  const {
-    currentCluster,
-    currentProject,
-    setCurrentOverlay,
-    setCurrentError,
-  } = useContext(Context);
-  const [stackName, setStackName] = useState(stack.name);
-  const [buttonStatus, setButtonStatus] = useState("");
+  const { setCurrentOverlay } = useContext(Context);
 
   const handleDelete = () => {
     setCurrentOverlay({
@@ -36,54 +22,10 @@ const Settings = ({
       onNo: () => setCurrentOverlay(null),
     });
   };
-
-  const handleStackNameChange = async () => {
-    setButtonStatus("loading");
-    try {
-      await api.updateStack(
-        "<token>",
-        {
-          name: stackName,
-        },
-        {
-          project_id: currentProject.id,
-          cluster_id: currentCluster.id,
-          stack_id: stack.id,
-          namespace: stack.namespace,
-        }
-      );
-      await onUpdate();
-      setButtonStatus("successful");
-    } catch (err) {
-      setCurrentError(err);
-      setButtonStatus("Couldn't update the stack name. Try again later.");
-    }
-  };
-
   return (
     <Wrapper>
       <StyledSettingsSection>
-        <Heading>Update Stack name</Heading>
-
-        <InputRow
-          label="Stack name"
-          value={stackName}
-          setValue={setStackName as any}
-          type="text"
-          width="300px"
-        />
-        <SaveButton
-          text="Update"
-          onClick={handleStackNameChange}
-          disabled={stackName === stack.name}
-          makeFlush
-          clearPosition
-          statusPosition="right"
-          status={buttonStatus}
-        ></SaveButton>
-
-        <Heading>Additional Settings</Heading>
-
+        <Heading>Settings</Heading>
         <Button color="#b91133" onClick={handleDelete}>
           Delete stack
         </Button>
@@ -94,10 +36,6 @@ const Settings = ({
 
 export default Settings;
 
-const SaveButton = styled(SubmitButton)`
-  justify-content: flex-start;
-`;
-
 const Wrapper = styled.div`
   width: 100%;
   padding-bottom: 65px;

+ 3 - 21
dashboard/src/main/home/cluster-dashboard/stacks/launch/SelectSource.tsx

@@ -8,11 +8,10 @@ import Helper from "components/form-components/Helper";
 import Heading from "components/form-components/Heading";
 import styled from "styled-components";
 import TitleSection from "components/TitleSection";
-import InputRow from "components/form-components/InputRow";
 
 const SelectSource = () => {
   const { addSourceConfig } = useContext(StacksLaunchContext);
-  const [sourceName, setSourceName] = useState("");
+
   const [imageUrl, setImageUrl] = useState("");
   const [imageTag, setImageTag] = useState("");
   const { pushFiltered } = useRouting();
@@ -22,8 +21,7 @@ const SelectSource = () => {
       return;
     }
 
-    const newSource: CreateStackBody["source_configs"][0] = {
-      name: sourceName,
+    const newSource: Omit<CreateStackBody["source_configs"][0], "name"> = {
       image_repo_uri: imageUrl,
       image_tag: imageTag,
     };
@@ -41,23 +39,11 @@ const SelectSource = () => {
         New Application Stack
       </TitleSection>
       <Heading>Stack Source</Heading>
-
-      <Br />
-      <InputRowWrapper>
-        <InputRow
-          label="Source Name"
-          value={sourceName}
-          setValue={(val) => setSourceName(val as string)}
-          type="text"
-          width="100%"
-          placeholder="Leave empty for auto-generated source config name"
-        />
-      </InputRowWrapper>
-
       <Helper>
         Specify a source to deploy all stack applications from:
         <Required>*</Required>
       </Helper>
+      <Br />
       <ImageSelector
         selectedImageUrl={imageUrl}
         setSelectedImageUrl={setImageUrl}
@@ -100,7 +86,3 @@ const Polymer = styled.div`
     margin-right: 18px;
   }
 `;
-
-const InputRowWrapper = styled.div`
-  width: 60%;
-`;

+ 7 - 5
dashboard/src/main/home/cluster-dashboard/stacks/launch/Store.tsx

@@ -11,7 +11,9 @@ export type StacksLaunchContextType = {
   setStackName: (name: string) => void;
   setStackNamespace: (namespace: string) => void;
 
-  addSourceConfig: (sourceConfig: CreateStackBody["source_configs"][0]) => void;
+  addSourceConfig: (
+    sourceConfig: Omit<CreateStackBody["source_configs"][0], "name">
+  ) => void;
 
   addAppResource: (
     appResource: CreateStackBody["app_resources"][0],
@@ -40,7 +42,9 @@ const defaultValues: StacksLaunchContextType = {
   setStackName: (name: string) => {},
   setStackNamespace: (namespace: string) => {},
 
-  addSourceConfig: (sourceConfig: CreateStackBody["source_configs"][0]) => {},
+  addSourceConfig: (
+    sourceConfig: Omit<CreateStackBody["source_configs"][0], "name">
+  ) => {},
 
   addAppResource: (appResource: CreateStackBody["app_resources"][0]) => {},
 
@@ -92,9 +96,7 @@ const StacksLaunchContextProvider: React.FC<{}> = ({ children }) => {
       source_configs: [
         ...prev.source_configs,
         {
-          name:
-            sourceConfig.name ||
-            newSourceConfigName(prev.source_configs.length),
+          name: newSourceConfigName(prev.source_configs.length),
           ...sourceConfig,
         },
       ],

+ 0 - 2
dashboard/src/main/home/cluster-dashboard/stacks/types.ts

@@ -90,8 +90,6 @@ export type SourceConfig = {
   stack_id: string;
   stack_revision_id: number;
 
-  stable_source_config_id: string;
-
   build?: {
     method: "pack" | "docker";
     folder_path: string;

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

@@ -2145,22 +2145,6 @@ const removeStackEnvGroup = baseApi<
     `/api/v1/projects/${project_id}/clusters/${cluster_id}/namespaces/${namespace}/stacks/${stack_id}/remove_env_group/${env_group_name}`
 );
 
-const updateStack = baseApi<
-  {
-    name: string;
-  },
-  {
-    project_id: number;
-    cluster_id: number;
-    namespace: string;
-    stack_id: string;
-  }
->(
-  "PATCH",
-  ({ project_id, cluster_id, namespace, stack_id }) =>
-    `/api/v1/projects/${project_id}/clusters/${cluster_id}/namespaces/${namespace}/stacks/${stack_id}`
-);
-
 const getGithubStatus = baseApi<{}, {}>("GET", ({}) => `/api/status/github`);
 
 // Bundle export to allow default api import (api.<method> is more readable)
@@ -2362,7 +2346,6 @@ export default {
   removeStackAppResource,
   addStackEnvGroup,
   removeStackEnvGroup,
-  updateStack,
 
   // STATUS
   getGithubStatus,

+ 8 - 13
internal/models/stack.go

@@ -160,10 +160,6 @@ func (s StackResource) ToStackResource(stackID string, stackRevisionID uint, sou
 type StackSourceConfig struct {
 	gorm.Model
 
-	// A unique identifier for this source config, this will allow us identify a same source config
-	// across multiple revisions and updates. This is not the same as the UID or ID which are updated over revisions.
-	StableSourceConfigID string
-
 	StackRevisionID uint
 
 	Name string
@@ -179,15 +175,14 @@ type StackSourceConfig struct {
 
 func (s StackSourceConfig) ToStackSourceConfigType(stackID string, stackRevisionID uint) *types.StackSourceConfig {
 	return &types.StackSourceConfig{
-		CreatedAt:            s.CreatedAt,
-		UpdatedAt:            s.UpdatedAt,
-		StackID:              stackID,
-		StackRevisionID:      stackRevisionID,
-		Name:                 s.Name,
-		ID:                   s.UID,
-		ImageRepoURI:         s.ImageRepoURI,
-		ImageTag:             s.ImageTag,
-		StableSourceConfigID: s.StableSourceConfigID,
+		CreatedAt:       s.CreatedAt,
+		UpdatedAt:       s.UpdatedAt,
+		StackID:         stackID,
+		StackRevisionID: stackRevisionID,
+		Name:            s.Name,
+		ID:              s.UID,
+		ImageRepoURI:    s.ImageRepoURI,
+		ImageTag:        s.ImageTag,
 	}
 }
 

+ 0 - 8
internal/repository/gorm/stack.go

@@ -118,14 +118,6 @@ func (repo *StackRepository) DeleteStack(stack *models.Stack) (*models.Stack, er
 	return stack, nil
 }
 
-func (repo *StackRepository) UpdateStack(stack *models.Stack) (*models.Stack, error) {
-	if err := repo.db.Save(stack).Error; err != nil {
-		return nil, err
-	}
-
-	return stack, nil
-}
-
 func (repo *StackRepository) UpdateStackRevision(revision *models.StackRevision) (*models.StackRevision, error) {
 	if err := repo.db.Save(revision).Error; err != nil {
 		return nil, err

+ 0 - 1
internal/repository/stack.go

@@ -10,7 +10,6 @@ type StackRepository interface {
 	ListStacks(projectID uint, clusterID uint, namespace string) ([]*models.Stack, error)
 	DeleteStack(stack *models.Stack) (*models.Stack, error)
 
-	UpdateStack(stack *models.Stack) (*models.Stack, error)
 	UpdateStackRevision(revision *models.StackRevision) (*models.StackRevision, error)
 	ReadStackRevision(stackRevisionID uint) (*models.StackRevision, error)
 	ReadStackRevisionByNumber(stackID uint, revisionNumber uint) (*models.StackRevision, error)

+ 0 - 4
internal/repository/test/stack.go

@@ -35,10 +35,6 @@ func (repo *StackRepository) DeleteStack(stack *models.Stack) (*models.Stack, er
 	panic("unimplemented")
 }
 
-func (repo *StackRepository) UpdateStack(stack *models.Stack) (*models.Stack, error) {
-	panic("unimplemented")
-}
-
 func (repo *StackRepository) UpdateStackRevision(revision *models.StackRevision) (*models.StackRevision, error) {
 	panic("unimplemented")
 }

+ 1 - 1
internal/stacks/helpers.go

@@ -52,7 +52,7 @@ func CloneAppResources(
 			if prevSourceConfig.UID == appResource.StackSourceConfigUID {
 				// find the corresponding new source config
 				for _, newSourceConfig := range newSourceConfigs {
-					if newSourceConfig.StableSourceConfigID == prevSourceConfig.StableSourceConfigID {
+					if newSourceConfig.Name == prevSourceConfig.Name {
 						linkedSourceConfigUID = newSourceConfig.UID
 					}
 				}