Procházet zdrojové kódy

Validate porter yaml before retrieving on the backend and invalidate old porter yaml versions

Feroze Mohideen před 2 roky
rodič
revize
e973093648

+ 37 - 8
api/server/handlers/gitinstallation/get_porter_yaml.go

@@ -8,11 +8,14 @@ import (
 	"github.com/google/go-github/v41/github"
 	"github.com/porter-dev/porter/api/server/authz"
 	"github.com/porter-dev/porter/api/server/handlers"
+	"github.com/porter-dev/porter/api/server/handlers/porter_app"
 	"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/commonutils"
 	"github.com/porter-dev/porter/api/server/shared/config"
 	"github.com/porter-dev/porter/api/types"
+	"github.com/porter-dev/porter/internal/telemetry"
+	"gopkg.in/yaml.v2"
 )
 
 type GithubGetPorterYamlHandler struct {
@@ -31,29 +34,36 @@ func NewGithubGetPorterYamlHandler(
 }
 
 func (c *GithubGetPorterYamlHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
+	ctx, span := telemetry.NewSpan(r.Context(), "serve-get-porter-yaml")
+	defer span.End()
 	request := &types.GetPorterYamlRequest{}
-
 	ok := c.DecodeAndValidate(w, r, request)
-
 	if !ok {
+		err := telemetry.Error(ctx, span, nil, "invalid request body")
+		c.HandleAPIError(w, r, apierrors.NewErrPassThroughToClient(err, http.StatusBadRequest))
 		return
 	}
 
-	owner, name, ok := commonutils.GetOwnerAndNameParams(c, w, r)
+	telemetry.WithAttributes(span, telemetry.AttributeKV{Key: "path", Value: request.Path})
 
+	owner, name, ok := commonutils.GetOwnerAndNameParams(c, w, r)
 	if !ok {
+		err := telemetry.Error(ctx, span, nil, "unable to get owner and name")
+		c.HandleAPIError(w, r, apierrors.NewErrPassThroughToClient(err, http.StatusBadRequest))
 		return
 	}
 
 	branch, ok := commonutils.GetBranchParam(c, w, r)
-
 	if !ok {
+		err := telemetry.Error(ctx, span, nil, "unable to get branch")
+		c.HandleAPIError(w, r, apierrors.NewErrPassThroughToClient(err, http.StatusBadRequest))
 		return
 	}
 
 	client, err := GetGithubAppClientFromRequest(c.Config(), r)
 	if err != nil {
-		c.HandleAPIError(w, r, apierrors.NewErrInternal(err))
+		err = telemetry.Error(ctx, span, err, "unable to get github app client")
+		c.HandleAPIError(w, r, apierrors.NewErrPassThroughToClient(err, http.StatusInternalServerError))
 		return
 	}
 
@@ -67,16 +77,35 @@ func (c *GithubGetPorterYamlHandler) ServeHTTP(w http.ResponseWriter, r *http.Re
 		},
 	)
 	if err != nil {
-		http.NotFound(w, r)
+		err = telemetry.Error(ctx, span, err, "unable to get contents")
+		c.HandleAPIError(w, r, apierrors.NewErrPassThroughToClient(err, http.StatusInternalServerError))
 		return
 	}
 
 	fileData, err := resp.GetContent()
 	if err != nil {
-		c.HandleAPIError(w, r, apierrors.NewErrInternal(err))
+		err = telemetry.Error(ctx, span, err, "unable to get file data")
+		c.HandleAPIError(w, r, apierrors.NewErrPassThroughToClient(err, http.StatusInternalServerError))
 		return
 	}
-	data := b64.StdEncoding.EncodeToString([]byte(fileData))
 
+	parsed := &porter_app.PorterStackYAML{}
+	err = yaml.Unmarshal([]byte(fileData), parsed)
+	if err != nil {
+		err = telemetry.Error(ctx, span, err, "invalid porter yaml format")
+		c.HandleAPIError(w, r, apierrors.NewErrPassThroughToClient(err, http.StatusBadRequest))
+		return
+	}
+	// backwards compatibility so that old porter yamls are no longer valid
+	if parsed.Version != nil {
+		version := *parsed.Version
+		if version != "v1stack" {
+			err = telemetry.Error(ctx, span, nil, "porter YAML version is not supported")
+			c.HandleAPIError(w, r, apierrors.NewErrPassThroughToClient(err, http.StatusBadRequest))
+			return
+		}
+	}
+
+	data := b64.StdEncoding.EncodeToString([]byte(fileData))
 	c.WriteResult(w, r, data)
 }

+ 3 - 3
dashboard/src/components/repo-selector/DetectContentsList.tsx

@@ -189,7 +189,7 @@ const DetectContentsList: React.FC<PropsType> = (props) => {
         );
         return res;
       } catch (err) {
-        console.log(err);
+        // console.log(err);
       }
     } else if (actionConfig.kind === "gitlab") {
       try {
@@ -591,7 +591,7 @@ const Item = styled.div`
   font-size: 13px;
   border-bottom: 1px solid
     ${(props: { lastItem: boolean; isSelected?: boolean }) =>
-      props.lastItem ? "#00000000" : "#606166"};
+    props.lastItem ? "#00000000" : "#606166"};
   color: #ffffff;
   user-select: none;
   align-items: center;
@@ -622,7 +622,7 @@ const FileItem = styled(Item)`
     props.isADocker ? "#fff" : "#ffffff55"};
   :hover {
     background: ${(props: { isADocker?: boolean }) =>
-      props.isADocker ? "#ffffff22" : "#ffffff11"};
+    props.isADocker ? "#ffffff22" : "#ffffff11"};
   }
 `;
 

+ 1 - 1
dashboard/src/main/home/app-dashboard/expanded-app/ExpandedApp.tsx

@@ -1010,7 +1010,7 @@ const ExpandedApp: React.FC<Props> = ({ ...props }) => {
                     shouldUpdate={
                       appData.chart.latest_version &&
                       appData.chart.latest_version !==
-                        appData.chart.chart.metadata.version
+                      appData.chart.chart.metadata.version
                     }
                     latestVersion={appData.chart.latest_version}
                     upgradeVersion={appUpgradeVersion}

+ 0 - 3
dashboard/src/main/home/app-dashboard/expanded-app/activity-feed/events/DeployEventCard.tsx

@@ -23,9 +23,6 @@ type Props = {
 };
 
 const DeployEventCard: React.FC<Props> = ({ event, appData }) => {
-  const [showModal, setShowModal] = useState<boolean>(false);
-  const [modalContent, setModalContent] = useState<React.ReactNode>(null);
-
   const renderStatusText = (event: PorterAppEvent) => {
     switch (event.status) {
       case "SUCCESS":