Jelajahi Sumber

apply for jobs in the works

Mohammed Nafees 3 tahun lalu
induk
melakukan
c5c03e8d62
5 mengubah file dengan 192 tambahan dan 21 penghapusan
  1. 48 13
      cli/cmd/preview/v2/apply.go
  2. 120 7
      cli/cmd/preview/v2/default_driver.go
  3. 21 0
      cli/cmd/preview/v2/types.go
  4. 1 1
      go.mod
  5. 2 0
      go.sum

+ 48 - 13
cli/cmd/preview/v2/apply.go

@@ -55,6 +55,36 @@ func NewApplier(client *api.Client, raw []byte, namespace string) (*PreviewAppli
 }
 
 func (a *PreviewApplier) Apply() error {
+	// check if the namespace exists in the current project-cluster pair
+	//
+	// this is a sanity check to ensure that the user does not see any internal
+	// errors that are caused by the namespace not existing
+	nsList, err := a.apiClient.GetK8sNamespaces(
+		context.Background(),
+		config.GetCLIConfig().Project,
+		config.GetCLIConfig().Cluster,
+	)
+
+	if err != nil {
+		return fmt.Errorf("error listing namespaces for project '%d', cluster '%d': %w",
+			config.GetCLIConfig().Project, config.GetCLIConfig().Cluster, err)
+	}
+
+	namespaces := *nsList
+	nsFound := false
+
+	for _, ns := range namespaces {
+		if ns.Name == a.namespace {
+			nsFound = true
+			break
+		}
+	}
+
+	if !nsFound {
+		return fmt.Errorf("namespace '%s' does not exist in project '%d', cluster '%d'",
+			a.namespace, config.GetCLIConfig().Project, config.GetCLIConfig().Cluster)
+	}
+
 	color.New(color.FgBlue).Printf("[porter.yaml v2] Applying preview environments with the following attributes:\n"+
 		"\tHost: %s\n\tProject ID: %d\n\tCluster ID: %d\n\tNamespace: %s\n",
 		config.GetCLIConfig().Host,
@@ -63,26 +93,31 @@ func (a *PreviewApplier) Apply() error {
 		a.namespace,
 	) // FIXME: use a scoped logger
 
-	err := a.readOSEnv()
+	// err := a.readOSEnv()
 
-	if err != nil {
-		return err
-	}
+	// if err != nil {
+	// 	return err
+	// }
 
-	err = a.processVariables()
+	// err = a.processVariables()
 
-	if err != nil {
-		return err
-	}
+	// if err != nil {
+	// 	return err
+	// }
 
-	err = a.processEnvGroups()
+	// err = a.processEnvGroups()
 
-	if err != nil {
-		return err
-	}
+	// if err != nil {
+	// 	return err
+	// }
 
 	w := worker.NewWorker()
-	w.RegisterDriver("default", NewDefaultDriver())
+	w.RegisterDriver("default", &DefaultDriver{
+		Vars:      a.variablesMap,
+		Env:       a.osEnv,
+		APIClient: a.apiClient,
+		Namespace: a.namespace,
+	})
 	w.SetDefaultDriver("default")
 
 	return w.Apply(a.parsed.PorterYAML)

+ 120 - 7
cli/cmd/preview/v2/default_driver.go

@@ -1,26 +1,139 @@
 package v2
 
-import "github.com/porter-dev/switchboard/v2/pkg/types"
+import (
+	"context"
+	"fmt"
+
+	api "github.com/porter-dev/porter/api/client"
+	"github.com/porter-dev/porter/cli/cmd/config"
+	"github.com/porter-dev/switchboard/v2/pkg/types"
+)
 
 type DefaultDriver struct {
+	Vars      map[string]string
+	Env       map[string]string
+	Builds    []*types.Build
+	APIClient *api.Client
+	Namespace string
 }
 
-func NewDefaultDriver() *DefaultDriver {
-	return &DefaultDriver{}
+func (d *DefaultDriver) PreApply(resource *types.YAMLNode[*types.Resource]) error {
+	return nil
 }
 
-func (d *DefaultDriver) PreApply(resource *types.Resource) error {
+func (d *DefaultDriver) Apply(resource *types.YAMLNode[*types.Resource]) error {
+	if isPorterApp(resource) {
+		return d.applyPorterApp(resource)
+	}
+
+	// everything else is an addon
+	return d.applyAddon(resource)
+}
+
+func (d *DefaultDriver) PostApply(resource *types.YAMLNode[*types.Resource]) error {
 	return nil
 }
 
-func (d *DefaultDriver) Apply(resource *types.Resource) error {
+func (d *DefaultDriver) OnError(resource *types.YAMLNode[*types.Resource], err error) {
+
+}
+
+func isPorterApp(resource *types.YAMLNode[*types.Resource]) bool {
+	if resource.GetValue().ChartURL.GetValue() == "https://charts.getporter.dev" &&
+		(resource.GetValue().Type.GetValue() == "web" ||
+			resource.GetValue().Type.GetValue() == "worker" ||
+			resource.GetValue().Type.GetValue() == "job") {
+		return true
+	}
+
+	return false
+}
+
+func (d *DefaultDriver) applyPorterApp(resource *types.YAMLNode[*types.Resource]) error {
+	appBuild := &porterAppBuild{}
+	appDeploy := &porterAppDeploy{}
+	buildNode := resource.GetValue().Build.GetRawYAMLNode()
+	deployNode := resource.GetValue().Deploy.GetRawYAMLNode()
+
+	err := buildNode.Decode(appBuild)
+
+	if err != nil {
+		return err // FIXME: descriptive error
+	}
+
+	err = deployNode.Decode(appDeploy)
+
+	if err != nil {
+		return err // FIXME: descriptive error
+	}
+
+	if resource.GetValue().Type.GetValue() == "job" {
+		jobConfig := &porterJob{}
+		jobNode := resource.GetRawYAMLNode()
+
+		err := jobNode.Decode(jobConfig)
+
+		if err != nil {
+			return err // FIXME: descriptive error
+		}
+
+		return d.applyJob(resource, appBuild, appDeploy, jobConfig, d.Builds)
+	}
+
 	return nil
 }
 
-func (d *DefaultDriver) PostApply(resource *types.Resource) error {
+func (d *DefaultDriver) applyAddon(resource *types.YAMLNode[*types.Resource]) error {
 	return nil
 }
 
-func (d *DefaultDriver) OnError(resource *types.Resource, err error) {
+func (d *DefaultDriver) applyJob(
+	resource *types.YAMLNode[*types.Resource],
+	appBuild *porterAppBuild,
+	appDeploy *porterAppDeploy,
+	jobConfig *porterJob,
+	builds []*types.Build,
+) error {
+	if jobConfig.Once {
+		// let us check if the job has already been created
+		_, err := d.APIClient.GetRelease(
+			context.Background(),
+			config.GetCLIConfig().Project,
+			config.GetCLIConfig().Cluster,
+			d.Namespace,
+			resource.GetValue().Name.GetValue(),
+		)
 
+		if err == nil {
+			// job already exists
+			return nil
+		}
+	}
+
+	var buildConfig *types.Build
+
+	if appBuild.Ref != "" {
+		for _, b := range builds {
+			if b.Name.GetValue() == appBuild.Ref {
+				buildConfig = b
+				break
+			}
+		}
+
+		if buildConfig == nil {
+			// this should not happen
+			return fmt.Errorf("internal error: please let the Porter team know about this and quote the following "+
+				"error:\n-----\nERROR: invalid build ref given for app '%s'", resource.GetValue().Name.GetValue())
+		}
+	} else {
+		buildConfig = appBuild.Build
+	}
+
+	if buildConfig == nil {
+		// this should not happen
+		return fmt.Errorf("internal error: please let the Porter team know about this and quote the following "+
+			"error:\n-----\nERROR: neither build ref nor build body given for app '%s'", resource.GetValue().Name.GetValue())
+	}
+
+	return nil
 }

+ 21 - 0
cli/cmd/preview/v2/types.go

@@ -0,0 +1,21 @@
+package v2
+
+import "github.com/porter-dev/switchboard/v2/pkg/types"
+
+type porterAppBuild struct {
+	*types.Build `yaml:",inline"`
+	Ref          string
+}
+
+type porterAppDeploy struct {
+	Env       map[string]string `yaml:"env" mapstructure:"env"`
+	EnvGroups []string          `yaml:"env_groups" mapstructure:"env_groups"`
+	Command   string            `yaml:"command" mapstructure:"command"`
+	CPU       string            `yaml:"cpu" mapstructure:"cpu"`
+	Memory    string            `yaml:"memory" mapstructure:"memory"`
+}
+
+type porterJob struct {
+	Once bool
+	Wait bool
+}

+ 1 - 1
go.mod

@@ -118,7 +118,7 @@ require (
 	github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
 	github.com/open-policy-agent/opa v0.44.0 // indirect
 	github.com/pkg/browser v0.0.0-20210115035449-ce105d075bb4 // indirect
-	github.com/porter-dev/switchboard/v2 v2.0.0-20221028153033-aaeedd2d3fd6 // indirect
+	github.com/porter-dev/switchboard/v2 v2.0.0-20221028173223-eb997250587e // indirect
 	github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect
 	github.com/santhosh-tekuri/jsonschema v1.2.4 // indirect
 	github.com/santhosh-tekuri/jsonschema/v5 v5.0.2 // indirect

+ 2 - 0
go.sum

@@ -1737,6 +1737,8 @@ github.com/porter-dev/switchboard/v2 v2.0.0-20221027201656-c94bb98e5398 h1:OIi1h
 github.com/porter-dev/switchboard/v2 v2.0.0-20221027201656-c94bb98e5398/go.mod h1:I/oKy2BmfIVtirJXM28W76Yqih0lR8EiaZ4lE5E5lY0=
 github.com/porter-dev/switchboard/v2 v2.0.0-20221028153033-aaeedd2d3fd6 h1:lHCsfpQcrXqjHDXtQA5TXHwlarI8z1keDDrJtYef30Q=
 github.com/porter-dev/switchboard/v2 v2.0.0-20221028153033-aaeedd2d3fd6/go.mod h1:I/oKy2BmfIVtirJXM28W76Yqih0lR8EiaZ4lE5E5lY0=
+github.com/porter-dev/switchboard/v2 v2.0.0-20221028173223-eb997250587e h1:LAaLwk/lMhTxJ55Xc5Pw/dMDyRTPhliWAI8K6SvgBWI=
+github.com/porter-dev/switchboard/v2 v2.0.0-20221028173223-eb997250587e/go.mod h1:I/oKy2BmfIVtirJXM28W76Yqih0lR8EiaZ4lE5E5lY0=
 github.com/porter-dev/switchboard/v2 v2.0.0 h1:mg4c6mMHFNFBgprcac7ZcPxTPJeqZtfmH1O6pPt1h3U=
 github.com/porter-dev/switchboard/v2 v2.0.0/go.mod h1:I/oKy2BmfIVtirJXM28W76Yqih0lR8EiaZ4lE5E5lY0=
 github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=