Explorar el Código

Merge branch 'master' into staging

Stefan McShane hace 3 años
padre
commit
75e8dc1ac5

+ 8 - 1
.github/workflows/build-dev-cli.yaml

@@ -20,12 +20,19 @@ jobs:
         id: login-ecr
         run: |
           aws ecr-public get-login-password --region us-east-1 | docker login --username AWS --password-stdin public.ecr.aws/o1j4x7p4
+      - name: Login to GHCR
+        id: login-ghcr
+        run: echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u ${{ github.actor }} --password-stdin
       - name: Build
         run: |
           DOCKER_BUILDKIT=1 docker build . \
             -t public.ecr.aws/o1j4x7p4/porter-cli:dev \
             -f ./services/porter_cli_container/dev.Dockerfile \
             --build-arg SENTRY_DSN=${{ secrets.SENTRY_DSN }}
-      - name: Push
+      - name: Push to ECR public
         run: |
           docker push public.ecr.aws/o1j4x7p4/porter-cli:dev
+      - name: Push to GHCR
+        run: |
+          docker tag public.ecr.aws/o1j4x7p4/porter-cli:dev ghcr.io/porter-dev/porter/porter-cli:dev
+          docker push ghcr.io/porter-dev/porter/porter-cli:dev

+ 3 - 3
.github/workflows/porter_preview_env.yml

@@ -26,10 +26,10 @@ jobs:
       uses: actions/checkout@v2.3.4
     - name: Create Porter preview env
       timeout-minutes: 30
-      uses: porter-dev/porter-preview-action@v0.2.1
+      uses: porter-dev/porter-preview-action@dev
       with:
         action_id: ${{ github.run_id }}
-        cluster: "2481"
+        cluster: "2489"
         host: https://dashboard.getporter.dev
         installation_id: "18533943"
         namespace: pr-${{ github.event.inputs.pr_number }}-porter
@@ -40,6 +40,6 @@ jobs:
         project: "6680"
         repo_name: porter
         repo_owner: porter-dev
-        token: ${{ secrets.PORTER_PREVIEW_6680_2481 }}
+        token: ${{ secrets.PORTER_PREVIEW_6680_2489 }}
     concurrency:
       group: ${{ github.workflow }}-${{ github.event.inputs.pr_number }}

+ 12 - 4
.github/workflows/prerelease.yaml

@@ -457,6 +457,9 @@ jobs:
         id: login-ecr
         run: |
           aws ecr-public get-login-password --region us-east-1 | docker login --username AWS --password-stdin public.ecr.aws/o1j4x7p4
+      - name: Login to GHCR
+        id: login-ghcr
+        run: echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u ${{ github.actor }} --password-stdin
       - name: Build
         run: |
           docker build ./services/porter_cli_container \
@@ -464,9 +467,12 @@ jobs:
             -f ./services/porter_cli_container/Dockerfile \
             --build-arg VERSION=${{steps.tag_name.outputs.tag}} \
             --build-arg SENTRY_DSN=${{secrets.SENTRY_DSN}}
-      - name: Push
+      - name: Push to ECR public
+        run: docker push public.ecr.aws/o1j4x7p4/porter-cli:${{steps.tag_name.outputs.tag}}
+      - name: Push to GHCR
         run: |
-          docker push public.ecr.aws/o1j4x7p4/porter-cli:${{steps.tag_name.outputs.tag}}
+          docker tag public.ecr.aws/o1j4x7p4/porter-cli:${{steps.tag_name.outputs.tag}} ghcr.io/porter-dev/porter/porter-cli:${{steps.tag_name.outputs.tag}}
+          docker push ghcr.io/porter-dev/porter/porter-cli:${{steps.tag_name.outputs.tag}}
   update-porter-update-action:
     name: Update porter-update-action
     runs-on: ubuntu-latest
@@ -490,7 +496,8 @@ jobs:
           git checkout -B "${{steps.tag_name.outputs.tag}}"
 
           cat >Dockerfile <<EOL
-          FROM public.ecr.aws/o1j4x7p4/porter-cli:${{steps.tag_name.outputs.tag}}
+          FROM ghcr.io/porter-dev/porter/porter-cli:${{steps.tag_name.outputs.tag}}
+          LABEL org.opencontainers.image.source="https://github.com/porter-dev/porter"
 
           COPY entrypoint.sh /action/
 
@@ -528,7 +535,8 @@ jobs:
           git checkout -B "${{steps.tag_name.outputs.tag}}"
 
           cat >Dockerfile <<EOL
-          FROM public.ecr.aws/o1j4x7p4/porter-cli:${{steps.tag_name.outputs.tag}}
+          FROM ghcr.io/porter-dev/porter/porter-cli:${{steps.tag_name.outputs.tag}}
+          LABEL org.opencontainers.image.source="https://github.com/porter-dev/porter"
 
           COPY entrypoint.sh /action/
 

+ 7 - 0
.github/workflows/release.yaml

@@ -58,11 +58,18 @@ jobs:
         id: login-ecr
         run: |
           aws ecr-public get-login-password --region us-east-1 | docker login --username AWS --password-stdin public.ecr.aws/o1j4x7p4
+      - name: Login to GHCR
+        id: login-ghcr
+        run: echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u ${{ github.actor }} --password-stdin
       - name: Pull versioned CLI image and push to latest
         run: |
           docker pull public.ecr.aws/o1j4x7p4/porter-cli:${{steps.tag_name.outputs.tag}}
           docker tag public.ecr.aws/o1j4x7p4/porter-cli:${{steps.tag_name.outputs.tag}} public.ecr.aws/o1j4x7p4/porter-cli:latest
           docker push public.ecr.aws/o1j4x7p4/porter-cli:latest
+
+          docker pull ghcr.io/porter-dev/porter/porter-cli:${{steps.tag_name.outputs.tag}}
+          docker tag ghcr.io/porter-dev/porter/porter-cli:${{steps.tag_name.outputs.tag}} ghcr.io/porter-dev/porter/porter-cli:latest
+          docker push ghcr.io/porter-dev/porter/porter-cli:latest
   update-homebrew-repo:
     name: Update the Homebrew repo with the new CLI version
     runs-on: ubuntu-latest

+ 0 - 1
README.md

@@ -30,7 +30,6 @@ Porter brings the simplicity of a traditional PaaS to your own cloud provider wh
 - One-click provisioning of a Kubernetes cluster in your own cloud console
   - ✅ AWS
   - ✅ GCP
-  - ✅ Digital Ocean
 - Simple deploy of any public or private Docker image
 - Auto CI/CD with [buildpacks](https://buildpacks.io) for non-Dockerized apps
 - Heroku-like GUI to monitor application status, logs, and history

+ 20 - 0
api/server/handlers/helmrepo/update.go

@@ -59,6 +59,26 @@ func (p *HelmRepoUpdateHandler) ServeHTTP(w http.ResponseWriter, r *http.Request
 		return
 	}
 
+	if request.BasicIntegrationID != 0 &&
+		helmRepo.BasicAuthIntegrationID != 0 &&
+		request.BasicIntegrationID != helmRepo.BasicAuthIntegrationID {
+		bi, err := p.Repo().BasicIntegration().ReadBasicIntegration(proj.ID, helmRepo.BasicAuthIntegrationID)
+
+		if err != nil {
+			if !errors.Is(err, gorm.ErrRecordNotFound) {
+				p.HandleAPIError(w, r, apierrors.NewErrInternal(err))
+				return
+			}
+		} else {
+			_, err = p.Repo().BasicIntegration().DeleteBasicIntegration(bi)
+
+			if err != nil {
+				p.HandleAPIError(w, r, apierrors.NewErrInternal(err))
+				return
+			}
+		}
+	}
+
 	// if a basic integration is specified, verify that it exists in the project
 	if request.BasicIntegrationID != 0 {
 		_, err := p.Repo().BasicIntegration().ReadBasicIntegration(proj.ID, request.BasicIntegrationID)

+ 6 - 274
cli/cmd/portforward.go

@@ -1,288 +1,20 @@
 package cmd
 
 import (
-	"context"
 	"fmt"
-	"net/http"
-	"net/url"
-	"os"
-	"os/signal"
-	"strconv"
-	"strings"
-	"time"
 
-	"github.com/briandowns/spinner"
-	api "github.com/porter-dev/porter/api/client"
-	"github.com/porter-dev/porter/api/types"
-	"github.com/porter-dev/porter/cli/cmd/utils"
+	"github.com/fatih/color"
 	"github.com/spf13/cobra"
-	corev1 "k8s.io/api/core/v1"
-	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
-	"k8s.io/apimachinery/pkg/runtime"
-	"k8s.io/apimachinery/pkg/runtime/schema"
-	"k8s.io/apimachinery/pkg/util/sets"
-	"k8s.io/client-go/rest"
-	"k8s.io/client-go/tools/clientcmd"
-	"k8s.io/client-go/tools/portforward"
-	"k8s.io/client-go/transport/spdy"
-	"k8s.io/kubectl/pkg/util"
 )
 
-var address []string
-
 var portForwardCmd = &cobra.Command{
-	Use:   "port-forward [release] [LOCAL_PORT:]REMOTE_PORT [...[LOCAL_PORT_N:]REMOTE_PORT_N]",
-	Short: "Forward one or more local ports to a pod of a release",
-	Args:  cobra.MinimumNArgs(2),
-	Run: func(cmd *cobra.Command, args []string) {
-		err := checkLoginAndRun(args, portForward)
-
-		if err != nil {
-			os.Exit(1)
-		}
-	},
+	Use: "port-forward [release] [LOCAL_PORT:]REMOTE_PORT [...[LOCAL_PORT_N:]REMOTE_PORT_N]",
+	Deprecated: fmt.Sprintf("please use the %s command instead.",
+		color.New(color.FgYellow, color.Bold).Sprintf("porter kubectl -- port-forward"),
+	),
+	DisableFlagParsing: true,
 }
 
 func init() {
-	portForwardCmd.PersistentFlags().StringVar(
-		&namespace,
-		"namespace",
-		"default",
-		"namespace of the release whose pod you want to port-forward to",
-	)
-
-	portForwardCmd.Flags().StringSliceVar(
-		&address,
-		"address",
-		[]string{"localhost"},
-		"Addresses to listen on (comma separated). Only accepts IP addresses or localhost as a value. "+
-			"When localhost is supplied, kubectl will try  to bind on both 127.0.0.1 and ::1 and will fail "+
-			"if neither of these addresses are available to bind.")
-
 	rootCmd.AddCommand(portForwardCmd)
 }
-
-func forwardPorts(
-	method string,
-	url *url.URL,
-	kubeConfig *rest.Config,
-	address, ports []string,
-	stopChan <-chan struct{},
-	readyChan chan struct{},
-) error {
-	transport, upgrader, err := spdy.RoundTripperFor(kubeConfig)
-
-	if err != nil {
-		return err
-	}
-
-	dialer := spdy.NewDialer(upgrader, &http.Client{Transport: transport}, method, url)
-	fw, err := portforward.NewOnAddresses(
-		dialer, address, ports, stopChan, readyChan, os.Stdout, os.Stderr)
-
-	if err != nil {
-		return err
-	}
-
-	return fw.ForwardPorts()
-}
-
-// splitPort splits port string which is in form of [LOCAL PORT]:REMOTE PORT
-// and returns local and remote ports separately
-func splitPort(port string) (local, remote string) {
-	parts := strings.Split(port, ":")
-	if len(parts) == 2 {
-		return parts[0], parts[1]
-	}
-
-	return parts[0], parts[0]
-}
-
-func portForward(user *types.GetAuthenticatedUserResponse, client *api.Client, args []string) error {
-	var err error
-	var pod corev1.Pod
-
-	s := spinner.New(spinner.CharSets[9], 100*time.Millisecond)
-	s.Color("cyan")
-	s.Suffix = fmt.Sprintf(" Loading list of pods for %s", args[0])
-	s.Start()
-
-	podsResp, err := client.GetK8sAllPods(context.Background(), cliConf.Project, cliConf.Cluster, namespace, args[0])
-
-	s.Stop()
-
-	if err != nil {
-		return err
-	}
-
-	pods := *podsResp
-
-	if len(pods) > 1 {
-		selectedPod, err := utils.PromptSelect("Select a pod to port-forward", func() []string {
-			var names []string
-
-			for i, pod := range pods {
-				names = append(names, fmt.Sprintf("%d - %s", (i+1), pod.Name))
-			}
-
-			return names
-		}())
-
-		if err != nil {
-			return err
-		}
-
-		podIdxStr := strings.Split(selectedPod, " - ")[0]
-
-		podIdx, err := strconv.Atoi(podIdxStr)
-
-		if err != nil {
-			return err
-		}
-
-		pod = pods[podIdx-1]
-	} else {
-		pod = pods[0]
-	}
-
-	kubeResp, err := client.GetKubeconfig(context.Background(), cliConf.Project, cliConf.Cluster, cliConf.Kubeconfig)
-
-	if err != nil {
-		return err
-	}
-
-	kubeBytes := kubeResp.Kubeconfig
-
-	cmdConf, err := clientcmd.NewClientConfigFromBytes(kubeBytes)
-
-	if err != nil {
-		return err
-	}
-
-	restConf, err := cmdConf.ClientConfig()
-
-	if err != nil {
-		return err
-	}
-
-	restConf.GroupVersion = &schema.GroupVersion{
-		Group:   "api",
-		Version: "v1",
-	}
-
-	restConf.NegotiatedSerializer = runtime.NewSimpleNegotiatedSerializer(runtime.SerializerInfo{})
-
-	restClient, err := rest.RESTClientFor(restConf)
-
-	if err != nil {
-		return err
-	}
-
-	err = checkUDPPortInPod(args[1:], &pod)
-
-	if err != nil {
-		return err
-	}
-
-	ports, err := convertPodNamedPortToNumber(args[1:], pod)
-
-	if err != nil {
-		return err
-	}
-
-	stopChannel := make(chan struct{}, 1)
-	readyChannel := make(chan struct{})
-
-	signals := make(chan os.Signal, 1)
-	signal.Notify(signals, os.Interrupt)
-	defer signal.Stop(signals)
-
-	go func() {
-		<-signals
-		if stopChannel != nil {
-			close(stopChannel)
-		}
-	}()
-
-	req := restClient.Post().
-		Resource("pods").
-		Namespace(namespace).
-		Name(pod.Name).
-		SubResource("portforward")
-
-	return forwardPorts("POST", req.URL(), restConf, address, ports, stopChannel, readyChannel)
-}
-
-func checkUDPPortInPod(ports []string, pod *corev1.Pod) error {
-	udpPorts := sets.NewInt()
-	tcpPorts := sets.NewInt()
-	for _, ct := range pod.Spec.Containers {
-		for _, ctPort := range ct.Ports {
-			portNum := int(ctPort.ContainerPort)
-			switch ctPort.Protocol {
-			case corev1.ProtocolUDP:
-				udpPorts.Insert(portNum)
-			case corev1.ProtocolTCP:
-				tcpPorts.Insert(portNum)
-			}
-		}
-	}
-	return checkUDPPorts(udpPorts.Difference(tcpPorts), ports, pod)
-}
-
-func checkUDPPorts(udpOnlyPorts sets.Int, ports []string, obj metav1.Object) error {
-	for _, port := range ports {
-		_, remotePort := splitPort(port)
-		portNum, err := strconv.Atoi(remotePort)
-		if err != nil {
-			switch v := obj.(type) {
-			case *corev1.Service:
-				svcPort, err := util.LookupServicePortNumberByName(*v, remotePort)
-				if err != nil {
-					return err
-				}
-				portNum = int(svcPort)
-
-			case *corev1.Pod:
-				ctPort, err := util.LookupContainerPortNumberByName(*v, remotePort)
-				if err != nil {
-					return err
-				}
-				portNum = int(ctPort)
-
-			default:
-				return fmt.Errorf("unknown object: %v", obj)
-			}
-		}
-		if udpOnlyPorts.Has(portNum) {
-			return fmt.Errorf("UDP protocol is not supported for %s", remotePort)
-		}
-	}
-	return nil
-}
-
-func convertPodNamedPortToNumber(ports []string, pod corev1.Pod) ([]string, error) {
-	var converted []string
-	for _, port := range ports {
-		localPort, remotePort := splitPort(port)
-
-		containerPortStr := remotePort
-		_, err := strconv.Atoi(remotePort)
-		if err != nil {
-			containerPort, err := util.LookupContainerPortNumberByName(pod, remotePort)
-			if err != nil {
-				return nil, err
-			}
-
-			containerPortStr = strconv.Itoa(int(containerPort))
-		}
-
-		if localPort != remotePort {
-			converted = append(converted, fmt.Sprintf("%s:%s", localPort, containerPortStr))
-		} else {
-			converted = append(converted, containerPortStr)
-		}
-	}
-
-	return converted, nil
-}

+ 1 - 1
cli/cmd/preview/v2beta1/app_resource.go

@@ -48,7 +48,7 @@ func (a *AppResource) getV1Resource(b *Build) (*types.Resource, error) {
 	config := &preview.ApplicationConfig{}
 
 	config.Build.Method = "registry"
-	config.Build.Image = fmt.Sprintf("\"{ .%s.image }\"", b.GetName())
+	config.Build.Image = fmt.Sprintf("{ .%s.image }", b.GetName())
 	config.Build.Env = b.GetRawEnv()
 	config.Values = a.HelmValues
 

+ 1 - 1
cli/cmd/preview/v2beta1/build.go

@@ -172,7 +172,7 @@ func (b *Build) getV1BuildImage() (*types.Resource, error) {
 func (b *Build) getV1PushImage() (*types.Resource, error) {
 	config := &preview.PushDriverConfig{}
 
-	config.Push.Image = fmt.Sprintf("\"{ .%s-build-image.image }\"", b.GetName())
+	config.Push.Image = fmt.Sprintf("{ .%s-build-image.image }", b.GetName())
 
 	rawConfig := make(map[string]any)
 

+ 1 - 0
cmd/provisioner/main.go

@@ -49,6 +49,7 @@ func main() {
 
 	if config.RedisConf.Enabled {
 		redis, err := adapter.NewRedisClient(config.RedisConf)
+		defer redis.Close()
 
 		if err != nil {
 			config.Logger.Fatal().Err(err).Msg("redis connection failed")

+ 0 - 15
dashboard/package-lock.json

@@ -3737,16 +3737,6 @@
       "resolved": "https://registry.npmjs.org/clsx/-/clsx-1.1.1.tgz",
       "integrity": "sha512-6/bPho624p3S2pMyvP5kKBPXnI3ufHLObBFCfgx+LkeR5lg2XYy2hqZqUf45ypD8COn2bhgGJSUE+l5dhNBieA=="
     },
-    "cohere-js": {
-      "version": "1.0.19",
-      "resolved": "https://registry.npmjs.org/cohere-js/-/cohere-js-1.0.19.tgz",
-      "integrity": "sha512-2XVX2LUKHjbJ4GCsnizXnAVHZfq9RM1RmHl8zE4G2ORdXmDpzSx5i0UIj/0GZ3AwjKIlYsrGA4kdCGT+WapjPQ=="
-    },
-    "cohere-sentry": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/cohere-sentry/-/cohere-sentry-1.0.1.tgz",
-      "integrity": "sha512-OHdKcc8LED8X/JQKlMD0Zapb4rcOkPu0m11+okHouMDep1/MvyOG4JXcK4Mo3sabJT65yozc9Uo+nJfSWzaFcg=="
-    },
     "collection-visit": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz",
@@ -5789,11 +5779,6 @@
       "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz",
       "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw=="
     },
-    "highlight.run": {
-      "version": "1.7.5",
-      "resolved": "https://registry.npmjs.org/highlight.run/-/highlight.run-1.7.5.tgz",
-      "integrity": "sha512-Kens7xbGJE/vZ21z+wVcdbdzn6bsFJD+gMh942cG/1ewgdWp5JmGqIiO33aJWyzEcXj0dBE8gQUi6Ql+9jSNUQ=="
-    },
     "history": {
       "version": "4.10.1",
       "resolved": "https://registry.npmjs.org/history/-/history-4.10.1.tgz",

+ 0 - 3
dashboard/package.json

@@ -27,8 +27,6 @@
     "brace": "^0.11.1",
     "chroma-js": "^2.4.2",
     "clipboard": "^2.0.8",
-    "cohere-js": "^1.0.19",
-    "cohere-sentry": "^1.0.1",
     "color": "^4.2.3",
     "core-js": "^3.16.1",
     "cron-parser": "^4.3.0",
@@ -39,7 +37,6 @@
     "dayjs": "^1.11.5",
     "dotenv": "^8.2.0",
     "fuse.js": "^6.6.2",
-    "highlight.run": "^1.4.5",
     "ini": ">=1.3.6",
     "js-base64": "^3.6.0",
     "js-yaml": "^4.1.0",

+ 6 - 4
dashboard/src/components/porter-form/field-components/KeyValueArray.tsx

@@ -32,14 +32,17 @@ const KeyValueArray: React.FC<Props> = (props) => {
     props.id,
     {
       initState: () => {
-        let values = props.value[0];
+        let values = {}
+        if (props?.value?.length > 0) {
+          values = props.value[0]
+        }
         const normalValues = Object.entries(values?.normal || {});
         values = omit(values, ["normal", "synced", "build"]);
         return {
           values: hasSetValue(props)
             ? ([...Object.entries(values), ...normalValues]?.map(([k, v]) => {
-                return { key: k, value: v };
-              }) as any[])
+              return { key: k, value: v };
+            }) as any[])
             : [],
           showEnvModal: false,
           showEditorModal: false,
@@ -112,7 +115,6 @@ const KeyValueArray: React.FC<Props> = (props) => {
     }
   }, [
     props.injectedProps,
-    props.value[0],
     variables?.clusterId,
     variables?.namespace,
     currentProject?.id,

+ 0 - 5
dashboard/src/index.tsx

@@ -3,7 +3,6 @@ import "regenerator-runtime/runtime";
 
 import * as React from "react";
 import * as ReactDOM from "react-dom";
-import Cohere from "cohere-js";
 import App from "./App";
 import { SetupSentry } from "shared/error_handling/sentry/setup";
 import { EnableErrorHandling } from "shared/error_handling/window_error_handling";
@@ -14,10 +13,6 @@ declare global {
   }
 }
 
-if (process.env.ENABLE_COHERE && process.env.COHERE_API_KEY) {
-  Cohere.init(process.env.COHERE_API_KEY);
-}
-
 if (process.env.ENABLE_SENTRY) {
   SetupSentry();
 }

+ 0 - 8
dashboard/src/main/Main.tsx

@@ -3,7 +3,6 @@ import { Route, Redirect, Switch } from "react-router-dom";
 
 import api from "shared/api";
 import { Context } from "shared/Context";
-import Cohere from "cohere-js";
 import ResetPasswordInit from "./auth/ResetPasswordInit";
 import ResetPasswordFinalize from "./auth/ResetPasswordFinalize";
 import Login from "./auth/Login";
@@ -42,13 +41,6 @@ export default class Main extends Component<PropsType, StateType> {
       .checkAuth("", {}, {})
       .then((res) => {
         if (res && res?.data) {
-          if (process.env.ENABLE_COHERE) {
-            Cohere.identify(res?.data?.id, {
-              displayName: res?.data?.email,
-              email: res?.data?.email,
-            });
-          }
-
           setUser(res?.data?.id, res?.data?.email);
           this.setState({
             isLoggedIn: true,

+ 0 - 10
dashboard/src/main/home/Home.tsx

@@ -3,7 +3,6 @@ import { Route, RouteComponentProps, Switch, withRouter } from "react-router";
 import styled from "styled-components";
 
 import api from "shared/api";
-import { H } from "highlight.run";
 import { Context } from "shared/Context";
 import { PorterUrl, pushFiltered, pushQueryParams } from "shared/routing";
 import { ClusterType, ProjectType } from "shared/types";
@@ -159,15 +158,6 @@ class Home extends Component<PropsType, StateType> {
 
     let { user } = this.context;
 
-    // Initialize Highlight
-    if (
-      window.location.href.includes("dashboard.getporter.dev") &&
-      !user.email.includes("@getporter.dev")
-    ) {
-      H.init("y2d13lgr");
-      H.identify(user.email, { id: user.id });
-    }
-
     // Handle redirect from DO
     let queryString = window.location.search;
     let urlParams = new URLSearchParams(queryString);

+ 0 - 12
dashboard/src/main/home/onboarding/steps/ProvisionResources/ProvisionResources.tsx

@@ -2,7 +2,6 @@ import Helper from "components/form-components/Helper";
 import SaveButton from "components/SaveButton";
 import TitleSection from "components/TitleSection";
 import React, { useEffect, useMemo, useState } from "react";
-import Cohere from "cohere-js";
 import { useParams } from "react-router";
 import styled from "styled-components";
 import ProviderSelector, {
@@ -217,9 +216,6 @@ const ProvisionResources: React.FC<{}> = () => {
     if (typeof infraStatus.hasError !== "boolean") return;
 
     if (infraStatus.hasError) {
-      Cohere.widget("show");
-      Cohere.widget("expand");
-
       const cause = new Error(
         JSON.stringify({
           description: infraStatus.description,
@@ -233,17 +229,9 @@ const ProvisionResources: React.FC<{}> = () => {
           { cause }
         )
       );
-    } else {
-      Cohere.widget("hide");
     }
   }, [infraStatus]);
 
-  useEffect(() => {
-    return () => {
-      Cohere.widget("hide");
-    };
-  }, []);
-
   const Content = () => {
     switch (step) {
       case "credentials":

+ 8 - 25
dashboard/src/shared/error_handling/logger.ts

@@ -1,5 +1,4 @@
 import * as Sentry from "@sentry/react";
-import Cohere from "cohere-js";
 import { isEmpty } from "lodash";
 
 type LogFunction = (error: Error, tags?: { [key: string]: string }) => void;
@@ -16,32 +15,16 @@ const logFunctionBuilder: LogFunctionBuilder = (scope, severity) => (
   error,
   tags
 ) => {
-  if (process.env.ENABLE_COHERE) {
-    Cohere.getSessionUrl((sessionUrl) => {
-      Sentry.withScope((sentryScope) => {
-        sentryScope.setTag("scope", scope);
-        sentryScope.setTag("cohere_link", sessionUrl);
-        sentryScope.setLevel(severity);
+  Sentry.withScope((sentryScope) => {
+    sentryScope.setTag("scope", scope);
+    sentryScope.setLevel(severity);
 
-        if (!isEmpty(tags)) {
-          sentryScope.setTags(tags);
-        }
+    if (!isEmpty(tags)) {
+      sentryScope.setTags(tags);
+    }
 
-        Sentry.captureException(error);
-      });
-    });
-  } else {
-    Sentry.withScope((sentryScope) => {
-      sentryScope.setTag("scope", scope);
-      sentryScope.setLevel(severity);
-
-      if (!isEmpty(tags)) {
-        sentryScope.setTags(tags);
-      }
-
-      Sentry.captureException(error);
-    });
-  }
+    Sentry.captureException(error);
+  });
 };
 
 function buildLogger(scope: string = "global") {

+ 1 - 24
dashboard/src/shared/error_handling/sentry/setup.ts

@@ -1,13 +1,8 @@
 import * as Sentry from "@sentry/react";
 import { Integrations } from "@sentry/tracing";
-import Cohere from "cohere-js";
-import CohereSentry from "cohere-sentry";
 
 const SENTRY_DSN = process.env.SENTRY_DSN;
 const SENTRY_ENV = process.env.SENTRY_ENV || "development";
-const COHERE_INTEGRATION = process.env.ENABLE_COHERE
-  ? [new CohereSentry()]
-  : [];
 
 export const SetupSentry = () => {
   if (!SENTRY_DSN) {
@@ -15,27 +10,9 @@ export const SetupSentry = () => {
   }
   Sentry.init({
     dsn: SENTRY_DSN,
-    integrations: [new Integrations.BrowserTracing(), ...COHERE_INTEGRATION],
+    integrations: [new Integrations.BrowserTracing()],
     environment: SENTRY_ENV,
     // Check out https://docs.sentry.io/platforms/javascript/guides/react/configuration/sampling/ for a more refined sample rate
     tracesSampleRate: 1,
   });
-
-  if (process.env.ENABLE_COHERE) {
-    const sessionUrlListener = (sessionUrl: string) => {
-      Sentry.configureScope((scope) => {
-        scope.addEventProcessor((event) => {
-          event.tags = {
-            ...event.tags,
-            cohere_link: `${sessionUrl}${
-              event.timestamp ? `?ts=${event.timestamp * 1000}` : ""
-            }`,
-          };
-
-          return event;
-        });
-      });
-    };
-    Cohere.addSessionUrlListener(sessionUrlListener);
-  }
 };

+ 5 - 14
docker/Dockerfile

@@ -7,6 +7,8 @@ WORKDIR /porter
 
 RUN apk update && apk add --no-cache gcc musl-dev git protoc
 
+ARG CGO_ENABLED=0
+
 COPY go.mod go.sum ./
 COPY /cmd ./cmd
 COPY /internal ./internal
@@ -18,33 +20,22 @@ COPY /pkg ./pkg
 RUN go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.26
 RUN go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.1
 
-RUN --mount=type=cache,target=$GOPATH/pkg/mod \
-    go mod download
+RUN go mod download
 
 # Go build environment
 # --------------------
 FROM base AS build-go
 
 ARG version=production
-
+ARG CGO_ENABLED=0
 
 # build proto files
 RUN sh ./scripts/build/proto.sh
 
-RUN --mount=type=cache,target=/root/.cache/go-build \
-    --mount=type=cache,target=$GOPATH/pkg/mod \
-    go build -ldflags="-w -s -X 'main.Version=${version}'" -a -o ./bin/app ./cmd/app && \
+RUN go build -ldflags="-w -s -X 'main.Version=${version}'" -a -o ./bin/app ./cmd/app && \
     go build -ldflags '-w -s' -a -o ./bin/migrate ./cmd/migrate && \
     go build -ldflags '-w -s' -a -o ./bin/ready ./cmd/ready
 
-# Go test environment
-# -------------------
-FROM base AS porter-test
-
-RUN --mount=type=cache,target=/root/.cache/go-build \
-    --mount=type=cache,target=$GOPATH/pkg/mod \
-    go test ./...
-
 # Webpack build environment
 # -------------------------
 FROM node:16 as build-webpack

+ 9 - 1
docs/getting-started/aws.md

@@ -126,6 +126,7 @@ Copy and paste the below JSON to the field.
         "eks:ListNodegroups",
         "eks:UpdateNodegroupConfig",
         "eks:UpdateNodegroupVersion",
+        "eks:AssociateEncryptionConfig",
         "iam:AddRoleToInstanceProfile",
         "iam:AttachRolePolicy",
         "iam:CreateInstanceProfile",
@@ -171,7 +172,14 @@ Copy and paste the below JSON to the field.
         "kms:Get*",
         "kms:ListAliases",
         "kms:ListResourceTags",
-        "kms:ScheduleKeyDeletion"
+        "kms:ScheduleKeyDeletion",
+        "kms:TagResource",
+<<<<<<< Updated upstream
+        "kms:UntagResource"
+=======
+        "kms:UntagResource",
+        "kms:EnableKeyRotation"
+>>>>>>> Stashed changes
       ],
       "Resource": "*"
     }

+ 6 - 0
go.work

@@ -0,0 +1,6 @@
+go 1.19
+
+use (
+	.
+	./services/cli_install_script_container
+)

+ 15 - 0
go.work.sum

@@ -0,0 +1,15 @@
+cloud.google.com/go/compute v1.12.1/go.mod h1:e8yNOBcBONZU1vJKCvCoDw/4JQsA0dpM4x/6PIIOocU=
+cloud.google.com/go/compute/metadata v0.2.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k=
+github.com/Masterminds/sprig v2.22.0+incompatible h1:z4yfnGrZ7netVz+0EDJ0Wi+5VZCSYp4Z0m2dk6cEM60=
+github.com/containerd/stargz-snapshotter v0.11.3 h1:D3PoF563XmOBdtfx2G6AkhbHueqwIVPBFn2mrsWLa3w=
+github.com/emicklei/go-restful v2.9.5+incompatible h1:spTtZBk5DYEvbxMVutUuTyh1Ao2r4iyvLdACqsl/Ljk=
+github.com/go-redis/redis v6.15.8+incompatible h1:BKZuG6mCnRj5AOaWJXoCgf6rqTYnYJLe4en2hxT7r9o=
+github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
+github.com/jackc/chunkreader v1.0.0 h1:4s39bBR8ByfqH+DKm8rQA3E1LHZWB9XWcrz8fqaZbe0=
+github.com/jackc/pgproto3 v1.1.0 h1:FYYE4yRw+AgI8wXIinMlNjBbp/UitDJwfj5LqqewP1A=
+github.com/tchap/go-patricia v2.2.6+incompatible h1:JvoDL7JSoIP2HDE8AbDH3zC8QBPxmzYe32HHy5yQ+Ck=
+golang.org/x/net v0.0.0-20221014081412-f15817d10f9b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
+golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE=
+golang.org/x/oauth2 v0.0.0-20221014153046-6fdb5e3db783/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg=
+golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=

+ 11 - 4
porter.yaml

@@ -5,7 +5,6 @@ builds:
   method: docker
   dockerfile: ./docker/Dockerfile
   env:
-    raw: {}
     import_from:
       - default/base-env
 
@@ -16,9 +15,11 @@ apps:
   helm_chart:
     name: web
   build_ref: porter
-  helm_values: # refer https://github.com/porter-dev/porter-charts/blob/master/applications/web/values.yaml
+  helm_values:
+    ingress:
+      enabled: true
     container:
-      command: 
+      port: 8080
     resources:
       requests:
         cpu: 400m
@@ -27,4 +28,10 @@ apps:
 addons:
 - name: postgres
   helm_chart:
-    name: postgres
+    name: postgresql
+  helm_values:
+    image:
+      tag: 15-debian-11
+    postgresqlUsername: postgres
+    postgresqlPassword: postgres
+    postgresqlDatabase: postgres

+ 1 - 0
services/cli_install_script_container/Dockerfile

@@ -3,6 +3,7 @@ FROM golang:1.18-alpine
 WORKDIR /app
 COPY . .
 
+RUN go mod download
 RUN go build -o serve main.go
 
 ENTRYPOINT [ "./serve" ]

+ 13 - 0
services/cli_install_script_container/go.mod

@@ -0,0 +1,13 @@
+module github.com/porter-dev/porter/services/cli_install_script_container
+
+go 1.19
+
+require (
+	github.com/golang/protobuf v1.3.2 // indirect
+	github.com/google/go-github/v50 v50.0.0 // indirect
+	github.com/google/go-querystring v1.1.0 // indirect
+	golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 // indirect
+	golang.org/x/net v0.0.0-20210226172049-e18ecbb05110 // indirect
+	golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be // indirect
+	google.golang.org/appengine v1.6.7 // indirect
+)

+ 28 - 0
services/cli_install_script_container/go.sum

@@ -0,0 +1,28 @@
+github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
+github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs=
+github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
+github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-github v17.0.0+incompatible h1:N0LgJ1j65A7kfXrZnUDaYCs/Sf4rEjNlfyDHW9dolSY=
+github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ=
+github.com/google/go-github/v50 v50.0.0 h1:gdO1AeuSZZK4iYWwVbjni7zg8PIQhp7QfmPunr016Jk=
+github.com/google/go-github/v50 v50.0.0/go.mod h1:Ev4Tre8QoKiolvbpOSG3FIi4Mlon3S2Nt9W5JYqKiwA=
+github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
+github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU=
+golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 h1:HWj/xjIHfjYU5nVXpTM0s39J9CbLn7Cc5a7IC5rwsMQ=
+golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
+golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
+golang.org/x/net v0.0.0-20210226172049-e18ecbb05110 h1:qWPm9rbaAMKs8Bq/9LRpbMqxWRVUAQwMI9fVrssnTfw=
+golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
+golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be h1:vEDujvNQGv4jgYKudGeI/+DAX4Jffq6hpD55MmoEvKs=
+golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
+golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
+golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
+golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=
+google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=

+ 1 - 1
services/cli_install_script_container/install.sh

@@ -14,7 +14,7 @@ download_and_install() {
 
     echo "[INFO] Since the Porter CLI gets installed in /usr/local/bin, you may be asked to input your password."
 
-    curl -L $(curl -s https://api.github.com/repos/porter-dev/porter/releases/latest | grep "browser_download_url.*/porter_.*_${osname}_x86_64\.zip" | cut -d ":" -f 2,3 | tr -d \") --output porter.zip
+    curl -L https://github.com/porter-dev/porter/releases/download/{{ .TagName }}/porter_{{ .TagName }}_${osname}_x86_64.zip --output porter.zip
     unzip -a porter.zip
     rm porter.zip
 

+ 44 - 5
services/cli_install_script_container/main.go

@@ -1,21 +1,60 @@
 package main
 
 import (
+	"context"
 	"fmt"
-	"io/ioutil"
 	"net/http"
 	"os"
+	"text/template"
+
+	"github.com/google/go-github/v50/github"
 )
 
+type Tag struct {
+	TagName string
+}
+
+func getLatestCLIRelease() (string, error) {
+	client := github.NewClient(nil)
+
+	rel, _, err := client.Repositories.GetLatestRelease(context.Background(), "porter-dev", "porter")
+
+	if err != nil {
+		return "", err
+	}
+
+	return rel.GetTagName(), nil
+}
+
 func serve(w http.ResponseWriter, req *http.Request) {
-	contents, err := ioutil.ReadFile("install.sh")
+	latestTag, err := getLatestCLIRelease()
+
+	if err != nil {
+		w.WriteHeader(http.StatusInternalServerError)
+		return
+	}
+
+	contents, err := os.ReadFile("install.sh")
+
+	if err != nil {
+		w.WriteHeader(http.StatusInternalServerError)
+		return
+	}
+
+	tmpl, err := template.New("install").Parse(string(contents))
+
 	if err != nil {
 		w.WriteHeader(http.StatusInternalServerError)
 		return
 	}
-	w.WriteHeader(http.StatusOK)
-	w.Header().Add("Content-Type", "text/plain")
-	w.Write(contents)
+
+	err = tmpl.Execute(w, Tag{TagName: latestTag})
+
+	if err != nil {
+		w.WriteHeader(http.StatusInternalServerError)
+	} else {
+		w.Header().Add("Content-Type", "text/plain")
+	}
 }
 
 func main() {

+ 1 - 1
services/porter_cli_container/dev.Dockerfile

@@ -22,7 +22,7 @@ RUN --mount=type=cache,target=$GOPATH/pkg/mod \
 # --------------------
 FROM base AS build-go
 
-ARG version=dev
+ARG SENTRY_DSN
 
 RUN make build-cli-dev