Skip to content

Commit

Permalink
WIP: call CCP to connect project to cluster on new project creation (#…
Browse files Browse the repository at this point in the history
…4169)

Co-authored-by: sunguroku <[email protected]>
Co-authored-by: porter-internal[bot] <108749831+porter-internal[bot]@users.noreply.github.com>
Co-authored-by: jusrhee <[email protected]>
Co-authored-by: d-g-town <[email protected]>
  • Loading branch information
5 people authored Feb 16, 2024
1 parent 214dba7 commit b059e3e
Show file tree
Hide file tree
Showing 29 changed files with 1,528 additions and 213 deletions.
54 changes: 54 additions & 0 deletions .github/workflows/porter_stack_porter-sandbox.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
"on":
push:
branches:
- master
name: Deploy to porter-sandbox
jobs:
build-go:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: build-go
uses: ./.github/actions/build-go

build-npm:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: build-npm
uses: ./.github/actions/build-npm

porter-deploy:
runs-on: ubuntu-latest
needs: [build-go, build-npm]
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Get Go Binaries
uses: actions/download-artifact@v3
with:
name: go-binaries
path: bin/
- name: Get NPM static files
uses: actions/download-artifact@v3
with:
name: npm-static-files
path: build/
- name: Set Github tag
id: vars
run: echo "sha_short=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT
- name: Setup porter
uses: porter-dev/[email protected]
- name: Deploy stack
timeout-minutes: 30
run: exec porter apply -f ./porter.yaml
env:
PORTER_CLUSTER: "11"
PORTER_HOST: https://dashboard.internal-tools.porter.run
PORTER_PR_NUMBER: ${{ github.event.number }}
PORTER_PROJECT: "8"
PORTER_STACK_NAME: porter-sandbox
PORTER_TAG: ${{ steps.vars.outputs.sha_short }}
PORTER_TOKEN: ${{ secrets.PORTER_STACK_8_11 }}
Empty file removed Procfile
Empty file.
63 changes: 63 additions & 0 deletions api/server/handlers/project/connect.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package project

import (
"net/http"

"connectrpc.com/connect"
porterv1 "github.com/porter-dev/api-contracts/generated/go/porter/v1"

"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/analytics"
"github.com/porter-dev/porter/internal/models"
"github.com/porter-dev/porter/internal/telemetry"
)

// ConnectHandler is the handler for the POST /projects/{project_id}/connect endpoint
type ConnectHandler struct {
handlers.PorterHandlerReadWriter
}

// NewConnectHandler returns a new ConnectHandler
func NewConnectHandler(
config *config.Config,
decoderValidator shared.RequestDecoderValidator,
writer shared.ResultWriter,
) *ConnectHandler {
return &ConnectHandler{
PorterHandlerReadWriter: handlers.NewDefaultPorterHandler(config, decoderValidator, writer),
}
}

// ServeHTTP connects a project to the hosted cluster
func (p *ConnectHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
ctx, span := telemetry.NewSpan(r.Context(), "connect-project-to-hosted")
defer span.End()

user, _ := r.Context().Value(types.UserScope).(*models.User)
proj, _ := r.Context().Value(types.ProjectScope).(*models.Project)

var err error
resp, err := p.Config().ClusterControlPlaneClient.ConnectHostedProject(ctx, connect.NewRequest(&porterv1.ConnectHostedProjectRequest{
ProjectId: int64(proj.ID),
}))
if err != nil {
p.HandleAPIError(w, r, apierrors.NewErrInternal(err))
return
}

if resp == nil || resp.Msg == nil {
err = telemetry.Error(ctx, span, nil, "connect to hosted response is nil")
p.HandleAPIError(w, r, apierrors.NewErrPassThroughToClient(err, http.StatusInternalServerError))
return
}

p.WriteResult(w, r, resp.Msg.ClusterId)

_ = p.Config().AnalyticsClient.Track(analytics.ProjectConnectTrack(&analytics.ProjectCreateDeleteTrackOpts{
ProjectScopedTrackOpts: analytics.GetProjectScopedTrackOpts(user.ID, proj.ID),
}))
}
11 changes: 9 additions & 2 deletions api/server/handlers/project/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ func (p *ProjectCreateHandler) ServeHTTP(w http.ResponseWriter, r *http.Request)
HelmValuesEnabled: false,
MultiCluster: false,
EnableReprovision: false,
EnableSandbox: p.Config().ServerConf.EnableSandbox,
}

var err error
Expand All @@ -56,10 +57,16 @@ func (p *ProjectCreateHandler) ServeHTTP(w http.ResponseWriter, r *http.Request)
return
}

// create onboarding flow set to the first step
step := types.StepConnectSource

if p.Config().ServerConf.EnableSandbox {
step = types.StepCleanUp
}

// create onboarding flow set to the first step. Read in env var
_, err = p.Repo().Onboarding().CreateProjectOnboarding(&models.Onboarding{
ProjectID: proj.ID,
CurrentStep: types.StepConnectSource,
CurrentStep: step,
})

if err != nil {
Expand Down
29 changes: 29 additions & 0 deletions api/server/router/project.go
Original file line number Diff line number Diff line change
Expand Up @@ -1118,6 +1118,35 @@ func getProjectRoutes(
// Router: r,
// })

// POST /api/projects/{project_id}/connect -> project.NewProjectConnectHandler
connectEndpoint := factory.NewAPIEndpoint(
&types.APIRequestMetadata{
Verb: types.APIVerbCreate,
Method: types.HTTPVerbPost,
Path: &types.Path{
Parent: basePath,
RelativePath: relPath + "/connect",
},
Scopes: []types.PermissionScope{
types.UserScope,
types.ProjectScope,
types.SettingsScope,
},
},
)

connectHandler := project.NewConnectHandler(
config,
factory.GetDecoderValidator(),
factory.GetResultWriter(),
)

routes = append(routes, &router.Route{
Endpoint: connectEndpoint,
Handler: connectHandler,
Router: r,
})

// POST /api/projects/{project_id}/policy -> policy.NewPolicyCreateHandler
policyCreateEndpoint := factory.NewAPIEndpoint(
&types.APIRequestMetadata{
Expand Down
4 changes: 4 additions & 0 deletions api/server/shared/config/env/envconfs.go
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,10 @@ type ServerConf struct {

// EnableCAPIProvisioner disables checks for ClusterControlPlaneClient and NATS, if set to true
EnableCAPIProvisioner bool `env:"ENABLE_CAPI_PROVISIONER"`

// EnableSandbox configures the API server to hit the endpoints designed for Porter's sandbox instance
EnableSandbox bool `env:"ENABLE_SANDBOX"`

// NATSUrl is the URL of the NATS cluster. This is required if ENABLE_CAPI_PROVISIONER is true
NATSUrl string `env:"NATS_URL"`

Expand Down
4 changes: 4 additions & 0 deletions api/types/project.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ type ProjectList struct {
EnableReprovision bool `json:"enable_reprovision"`
ValidateApplyV2 bool `json:"validate_apply_v2"`
AdvancedInfraEnabled bool `json:"advanced_infra_enabled"`
SandboxEnabled bool `json:"sandbox_enabled"`
}

// Project type for entries in api responses for everything other than `GET /projects`
Expand Down Expand Up @@ -52,6 +53,7 @@ type Project struct {
ValidateApplyV2 bool `json:"validate_apply_v2"`
ManagedDeploymentTargetsEnabled bool `json:"managed_deployment_targets_enabled"`
AdvancedInfraEnabled bool `json:"advanced_infra_enabled"`
SandboxEnabled bool `json:"sandbox_enabled"`
}

// FeatureFlags is a struct that contains old feature flag representations
Expand Down Expand Up @@ -162,6 +164,8 @@ type StepEnum string
const (
// StepConnectSource is a value describing the current onboarding step as `connect_source` (the first step)
StepConnectSource StepEnum = "connect_source"
// StepCleanUp is a value describing the current onboarding step as `clean_up` (the last step)
StepCleanUp StepEnum = "clean_up"
)

// ConnectedSourceType describes the source of an onboarding
Expand Down
2 changes: 1 addition & 1 deletion dashboard/src/lib/porter-apps/services.ts
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ export function defaultSerialized({
enabled: false,
gpuCoresNvidia: 0,
},
smartOptimization: true,
smartOptimization: false,
};

const defaultAutoscaling: SerializedAutoscaling = {
Expand Down
48 changes: 45 additions & 3 deletions dashboard/src/main/home/Home.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,10 @@ import {
type ProjectListType,
type ProjectType,
} from "shared/types";
import { overrideInfraTabEnabled } from "utils/infrastructure";
import ShowIntercomButton from "components/porter/ShowIntercomButton";

import warning from "../../assets/warning.svg";
import discordLogo from "../../assets/discord.svg";
import AddOnDashboard from "./add-on-dashboard/AddOnDashboard";
import NewAddOnFlow from "./add-on-dashboard/NewAddOnFlow";
Expand Down Expand Up @@ -409,7 +412,22 @@ const Home: React.FC<Props> = (props) => {
>
<ClusterResourcesProvider>
<DeploymentTargetProvider>
<StyledHome>
{currentProject?.sandbox_enabled && (
<GlobalBanner>
<img src={warning} />
Your project is currently in Sandbox mode. Your project will be deleted after one week.
<CTA>
<ShowIntercomButton
alt
message="I would like to eject to my own cloud account"
height="25px"
>
Request ejection
</ShowIntercomButton>
</CTA>
</GlobalBanner>
)}
<StyledHome isHosted={currentProject?.sandbox_enabled ?? false}>
<ModalHandler setRefreshClusters={setForceRefreshClusters} />
{currentOverlay &&
createPortal(
Expand Down Expand Up @@ -655,6 +673,26 @@ const Home: React.FC<Props> = (props) => {

export default withRouter(withAuth(Home));

const GlobalBanner = styled.div`
width: 100vw;
z-index: 999;
position: fixed;
top: 0;
left: 0;
height: 35px;
background: #263061;
display: flex;
align-items: center;
justify-content: center;
font-size: 13px;
font-family: "Work Sans", sans-serif;
> img {
height: 16px;
margin-right: 10px;
}
`;

const ViewWrapper = styled.div`
height: 100%;
width: 100vw;
Expand All @@ -667,17 +705,21 @@ const ViewWrapper = styled.div`
position: relative;
`;

const CTA = styled.div`
margin-left: 30px;
`

const DashboardWrapper = styled.div`
width: 100%;
min-width: 300px;
height: fit-content;
`;

const StyledHome = styled.div`
const StyledHome = styled.div<{ isHosted: boolean }>`
width: 100vw;
height: 100vh;
position: fixed;
top: 0;
top: ${(props) => (props.isHosted ? "35px" : "0")};
left: 0;
margin: 0;
user-select: none;
Expand Down
20 changes: 18 additions & 2 deletions dashboard/src/main/home/add-on-dashboard/AddOnDashboard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import Fieldset from "components/porter/Fieldset";
import ClusterProvisioningPlaceholder from "components/ClusterProvisioningPlaceholder";
import DashboardPlaceholder from "components/porter/DashboardPlaceholder";
import { useAuthState } from "main/auth/context";
import ShowIntercomButton from "components/porter/ShowIntercomButton";

type Props = {
};
Expand Down Expand Up @@ -158,8 +159,23 @@ const AddOnDashboard: React.FC<Props> = ({
{currentCluster?.status === "UPDATING_UNAVAILABLE" ? (
<ClusterProvisioningPlaceholder />
) : (

(addOns.length === 0 || (filteredAddOns.length === 0 && searchValue === "")) ? (
currentProject?.sandbox_enabled ? (
<DashboardPlaceholder>
<Text size={16}>Add-ons are not enabled for sandbox users</Text>
<Spacer y={0.5} />
<Text color={"helper"}>
Eject to your own cloud account to enable Porter add-ons.
</Text>
<Spacer y={1} />
<ShowIntercomButton
alt
message="I would like to eject to my own cloud account"
height="35px"
>
Request ejection
</ShowIntercomButton>
</DashboardPlaceholder>
) : (addOns.length === 0 || (filteredAddOns.length === 0 && searchValue === "")) ? (

isLoading ?
(<Loading offset="-150px" />) : (
Expand Down
1 change: 1 addition & 0 deletions dashboard/src/main/home/app-dashboard/apps/Apps.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,7 @@ const Apps: React.FC = () => {
) : (
<PorterLink to="/apps/new/app">
<Button
disabled={currentProject?.sandbox_enabled && apps.length == 3}
onClick={async () => {
await updateAppStep({ step: "stack-launch-start" });
}}
Expand Down
Loading

0 comments on commit b059e3e

Please sign in to comment.