From bf834b0a7255f25ee904939193f2dd9eabca6a74 Mon Sep 17 00:00:00 2001 From: Jemish Patel Date: Tue, 15 Nov 2022 23:16:01 -0800 Subject: [PATCH 1/3] rename fields - `information` is now `metadata` - `scheduler_replicas` is now `scheduler_count` - `astronomer_variables` is now `environment_variables` - re-order fields in the `deploymentMetadata` and `deploymentConfiguration` structs --- cloud/deployment/inspect/inspect.go | 28 +-- cloud/deployment/inspect/inspect_test.go | 214 +++++++++++------------ 2 files changed, 121 insertions(+), 121 deletions(-) diff --git a/cloud/deployment/inspect/inspect.go b/cloud/deployment/inspect/inspect.go index 5aee50150..4114a162b 100644 --- a/cloud/deployment/inspect/inspect.go +++ b/cloud/deployment/inspect/inspect.go @@ -91,20 +91,20 @@ func getDeploymentInspectInfo(sourceDeployment *astro.Deployment) (map[string]in func getDeploymentConfig(sourceDeployment *astro.Deployment) map[string]interface{} { return map[string]interface{}{ - "name": sourceDeployment.Label, - "description": sourceDeployment.Description, - "cluster_id": sourceDeployment.Cluster.ID, - "runtime_version": sourceDeployment.RuntimeRelease.Version, - "scheduler_au": sourceDeployment.DeploymentSpec.Scheduler.AU, - "scheduler_replicas": sourceDeployment.DeploymentSpec.Scheduler.Replicas, + "name": sourceDeployment.Label, + "description": sourceDeployment.Description, + "cluster_id": sourceDeployment.Cluster.ID, + "runtime_version": sourceDeployment.RuntimeRelease.Version, + "scheduler_au": sourceDeployment.DeploymentSpec.Scheduler.AU, + "scheduler_count": sourceDeployment.DeploymentSpec.Scheduler.Replicas, } } func getAdditional(sourceDeployment *astro.Deployment) map[string]interface{} { return map[string]interface{}{ - "alert_emails": sourceDeployment.AlertEmails, - "worker_queues": getQMap(sourceDeployment.WorkerQueues), - "astronomer_variables": getVariablesMap(sourceDeployment.DeploymentSpec.EnvironmentVariablesObjects), // API only returns values when !EnvironmentVariablesObject.isSecret + "alert_emails": sourceDeployment.AlertEmails, + "worker_queues": getQMap(sourceDeployment.WorkerQueues), + "environment_variables": getVariablesMap(sourceDeployment.DeploymentSpec.EnvironmentVariablesObjects), // API only returns values when !EnvironmentVariablesObject.isSecret } } @@ -188,11 +188,11 @@ func getSpecificField(deploymentMap map[string]interface{}, requestedField strin func getPrintableDeployment(infoMap, configMap, additionalMap map[string]interface{}) map[string]interface{} { printableDeployment := map[string]interface{}{ "deployment": map[string]interface{}{ - "information": infoMap, - "configuration": configMap, - "alert_emails": additionalMap["alert_emails"], - "worker_queues": additionalMap["worker_queues"], - "astronomer_variables": additionalMap["astronomer_variables"], + "metadata": infoMap, + "configuration": configMap, + "alert_emails": additionalMap["alert_emails"], + "worker_queues": additionalMap["worker_queues"], + "environment_variables": additionalMap["environment_variables"], }, } return printableDeployment diff --git a/cloud/deployment/inspect/inspect_test.go b/cloud/deployment/inspect/inspect_test.go index 2e298351b..2f586e9b7 100644 --- a/cloud/deployment/inspect/inspect_test.go +++ b/cloud/deployment/inspect/inspect_test.go @@ -21,29 +21,29 @@ var ( errMarshal = errors.New("test error") ) -type deploymentInfo struct { +type deploymentMetadata struct { DeploymentID string `mapstructure:"deployment_id"` WorkspaceID string `mapstructure:"workspace_id"` ClusterID string `mapstructure:"cluster_id"` - AirflowVersion string `mapstructure:"airflow_version"` ReleaseName string `mapstructure:"release_name"` + AirflowVersion string `mapstructure:"airflow_version"` + Status string `mapstructure:"status"` + CreatedAt time.Time `mapstructure:"created_at"` + UpdatedAt time.Time `mapstructure:"updated_at"` DeploymentURL string `mapstructure:"deployment_url"` WebserverURL string `mapstructure:"webserver_url"` - UpdatedAt time.Time `mapstructure:"updated_at"` - CreatedAt time.Time `mapstructure:"created_at"` - Status string `mapstructure:"status"` } type deploymentConfig struct { - Name string `mapstructure:"name"` - Description string `mapstructure:"description"` - ClusterID string `mapstructure:"cluster_id"` // this is also in deploymentInfo - RunTimeVersion string `mapstructure:"runtime_version"` - SchedulerAU int `mapstructure:"scheduler_au"` - SchedulerReplicas int `mapstructure:"scheduler_replicas"` - AlertEmails []string `mapstructure:"alert_emails"` - WorkerQueues []map[string]interface{} `mapstructure:"worker_queues"` - AstroVariables []map[string]interface{} `mapstructure:"astronomer_variables"` + Name string `mapstructure:"name"` + Description string `mapstructure:"description"` + RunTimeVersion string `mapstructure:"runtime_version"` + SchedulerAU int `mapstructure:"scheduler_au"` + SchedulerCount int `mapstructure:"scheduler_count"` + ClusterID string `mapstructure:"cluster_id"` // this is also in deploymentMetadata + AlertEmails []string `mapstructure:"alert_emails"` + WorkerQueues []map[string]interface{} `mapstructure:"worker_queues"` + AstroVariables []map[string]interface{} `mapstructure:"environment_variables"` } func errReturningYAMLMarshal(v interface{}) ([]byte, error) { @@ -298,11 +298,11 @@ func TestGetDeploymentInspectInfo(t *testing.T) { } t.Run("returns deployment Info for the requested cloud deployment", func(t *testing.T) { - var actualDeploymentInfo deploymentInfo + var actualDeploymentInfo deploymentMetadata testUtil.InitTestConfig(testUtil.CloudPlatform) expectedCloudDomainURL := "cloud.astronomer.io/" + sourceDeployment.Workspace.ID + "/deployments/" + sourceDeployment.ID + "/analytics" - expectedDeploymentInfo := deploymentInfo{ + expectedDeploymentMetadata := deploymentMetadata{ DeploymentID: sourceDeployment.ID, WorkspaceID: sourceDeployment.Workspace.ID, ClusterID: sourceDeployment.Cluster.ID, @@ -318,41 +318,41 @@ func TestGetDeploymentInspectInfo(t *testing.T) { assert.NoError(t, err) err = mapstructure.Decode(rawDeploymentInfo, &actualDeploymentInfo) assert.NoError(t, err) - assert.Equal(t, expectedDeploymentInfo, actualDeploymentInfo) + assert.Equal(t, expectedDeploymentMetadata, actualDeploymentInfo) }) t.Run("returns deployment Info for the requested local deployment", func(t *testing.T) { - var actualDeploymentInfo deploymentInfo + var actualDeploymentInfo deploymentMetadata testUtil.InitTestConfig(testUtil.LocalPlatform) expectedCloudDomainURL := "localhost:5000/" + sourceDeployment.Workspace.ID + "/deployments/" + sourceDeployment.ID + "/analytics" - expectedDeploymentInfo := deploymentInfo{ + expectedDeploymentMetadata := deploymentMetadata{ DeploymentID: sourceDeployment.ID, WorkspaceID: sourceDeployment.Workspace.ID, ClusterID: sourceDeployment.Cluster.ID, - AirflowVersion: sourceDeployment.RuntimeRelease.AirflowVersion, ReleaseName: sourceDeployment.ReleaseName, - DeploymentURL: expectedCloudDomainURL, - WebserverURL: sourceDeployment.DeploymentSpec.Webserver.URL, + AirflowVersion: sourceDeployment.RuntimeRelease.AirflowVersion, + Status: sourceDeployment.Status, CreatedAt: sourceDeployment.CreatedAt, UpdatedAt: sourceDeployment.UpdatedAt, - Status: sourceDeployment.Status, + DeploymentURL: expectedCloudDomainURL, + WebserverURL: sourceDeployment.DeploymentSpec.Webserver.URL, } rawDeploymentInfo, err := getDeploymentInspectInfo(&sourceDeployment) assert.NoError(t, err) err = mapstructure.Decode(rawDeploymentInfo, &actualDeploymentInfo) assert.NoError(t, err) - assert.Equal(t, expectedDeploymentInfo, actualDeploymentInfo) + assert.Equal(t, expectedDeploymentMetadata, actualDeploymentInfo) }) t.Run("returns error if getting context fails", func(t *testing.T) { - var actualDeploymentInfo deploymentInfo + var actualDeploymentInfo deploymentMetadata // get an error from GetCurrentContext() testUtil.InitTestConfig(testUtil.ErrorReturningContext) - expectedDeploymentInfo := deploymentInfo{} + expectedDeploymentMetadata := deploymentMetadata{} rawDeploymentInfo, err := getDeploymentInspectInfo(&sourceDeployment) assert.ErrorContains(t, err, "no context set, have you authenticated to Astro or Astronomer Software? Run astro login and try again") err = mapstructure.Decode(rawDeploymentInfo, &actualDeploymentInfo) assert.NoError(t, err) - assert.Equal(t, expectedDeploymentInfo, actualDeploymentInfo) + assert.Equal(t, expectedDeploymentMetadata, actualDeploymentInfo) }) } @@ -432,15 +432,15 @@ func TestGetDeploymentConfig(t *testing.T) { var actualDeploymentConfig deploymentConfig testUtil.InitTestConfig(testUtil.CloudPlatform) expectedDeploymentConfig := deploymentConfig{ - Name: sourceDeployment.Label, - Description: sourceDeployment.Description, - ClusterID: sourceDeployment.Cluster.ID, - RunTimeVersion: sourceDeployment.RuntimeRelease.Version, - SchedulerAU: sourceDeployment.DeploymentSpec.Scheduler.AU, - SchedulerReplicas: sourceDeployment.DeploymentSpec.Scheduler.Replicas, - AlertEmails: nil, - WorkerQueues: nil, - AstroVariables: nil, + Name: sourceDeployment.Label, + Description: sourceDeployment.Description, + ClusterID: sourceDeployment.Cluster.ID, + RunTimeVersion: sourceDeployment.RuntimeRelease.Version, + SchedulerAU: sourceDeployment.DeploymentSpec.Scheduler.AU, + SchedulerCount: sourceDeployment.DeploymentSpec.Scheduler.Replicas, + AlertEmails: nil, + WorkerQueues: nil, + AstroVariables: nil, } rawDeploymentConfig := getDeploymentConfig(&sourceDeployment) err := mapstructure.Decode(rawDeploymentConfig, &actualDeploymentConfig) @@ -528,11 +528,11 @@ func TestGetPrintableDeployment(t *testing.T) { additional := getAdditional(&sourceDeployment) expectedDeployment := map[string]interface{}{ "deployment": map[string]interface{}{ - "information": info, - "configuration": config, - "alert_emails": additional["alert_emails"], - "worker_queues": additional["worker_queues"], - "astronomer_variables": additional["astronomer_variables"], + "metadata": info, + "configuration": config, + "alert_emails": additional["alert_emails"], + "worker_queues": additional["worker_queues"], + "environment_variables": additional["environment_variables"], }, } actualDeployment := getPrintableDeployment(info, config, additional) @@ -578,13 +578,13 @@ func TestGetAdditional(t *testing.T) { Key: "foo", Value: "bar", IsSecret: false, - UpdatedAt: "NOW", + UpdatedAt: time.Now().String(), }, { Key: "bar", Value: "baz", IsSecret: true, - UpdatedAt: "NOW+1", + UpdatedAt: time.Now().String(), }, }, }, @@ -616,15 +616,15 @@ func TestGetAdditional(t *testing.T) { var actualDeploymentConfig deploymentConfig testUtil.InitTestConfig(testUtil.CloudPlatform) expectedDeploymentConfig := deploymentConfig{ - Name: "", - Description: "", - ClusterID: "", - RunTimeVersion: "", - SchedulerAU: 0, - SchedulerReplicas: 0, - AlertEmails: sourceDeployment.AlertEmails, - WorkerQueues: getQMap(sourceDeployment.WorkerQueues), - AstroVariables: getVariablesMap(sourceDeployment.DeploymentSpec.EnvironmentVariablesObjects), + Name: "", + Description: "", + ClusterID: "", + RunTimeVersion: "", + SchedulerAU: 0, + SchedulerCount: 0, + AlertEmails: sourceDeployment.AlertEmails, + WorkerQueues: getQMap(sourceDeployment.WorkerQueues), + AstroVariables: getVariablesMap(sourceDeployment.DeploymentSpec.EnvironmentVariablesObjects), } rawDeploymentConfig := getAdditional(&sourceDeployment) err := mapstructure.Decode(rawDeploymentConfig, &actualDeploymentConfig) @@ -712,7 +712,7 @@ func TestFormatPrintableDeployment(t *testing.T) { info, _ := getDeploymentInspectInfo(&sourceDeployment) config := getDeploymentConfig(&sourceDeployment) additional := getAdditional(&sourceDeployment) - expectedPrintableDeployment = []byte("\n information:\n") + expectedPrintableDeployment = []byte("\n metadata:\n") actualPrintableDeployment, err := formatPrintableDeployment("", getPrintableDeployment(info, config, additional)) assert.NoError(t, err) assert.Contains(t, string(actualPrintableDeployment), string(expectedPrintableDeployment)) @@ -722,14 +722,14 @@ func TestFormatPrintableDeployment(t *testing.T) { assert.Contains(t, string(actualPrintableDeployment), string(expectedPrintableDeployment)) expectedPrintableDeployment = []byte("\n worker_queues:\n") assert.Contains(t, string(actualPrintableDeployment), string(expectedPrintableDeployment)) - expectedPrintableDeployment = []byte("\n astronomer_variables:\n") + expectedPrintableDeployment = []byte("\n environment_variables:\n") assert.Contains(t, string(actualPrintableDeployment), string(expectedPrintableDeployment)) }) t.Run("returns a json formatted printable deployment", func(t *testing.T) { info, _ := getDeploymentInspectInfo(&sourceDeployment) config := getDeploymentConfig(&sourceDeployment) additional := getAdditional(&sourceDeployment) - expectedPrintableDeployment = []byte(",\n \"information\":") + expectedPrintableDeployment = []byte(",\n \"metadata\":") actualPrintableDeployment, err := formatPrintableDeployment("json", getPrintableDeployment(info, config, additional)) assert.NoError(t, err) assert.Contains(t, string(actualPrintableDeployment), string(expectedPrintableDeployment)) @@ -739,7 +739,7 @@ func TestFormatPrintableDeployment(t *testing.T) { assert.Contains(t, string(actualPrintableDeployment), string(expectedPrintableDeployment)) expectedPrintableDeployment = []byte("\n \"worker_queues\": ") assert.Contains(t, string(actualPrintableDeployment), string(expectedPrintableDeployment)) - expectedPrintableDeployment = []byte("\n \"astronomer_variables\": ") + expectedPrintableDeployment = []byte("\n \"environment_variables\": ") assert.Contains(t, string(actualPrintableDeployment), string(expectedPrintableDeployment)) }) t.Run("returns an error if marshaling yaml fails", func(t *testing.T) { @@ -845,14 +845,14 @@ func TestGetSpecificField(t *testing.T) { config := getDeploymentConfig(&sourceDeployment) additional := getAdditional(&sourceDeployment) t.Run("returns a value if key is found in deployment.information", func(t *testing.T) { - requestedField := "information.workspace_id" + requestedField := "metadata.workspace_id" printableDeployment := map[string]interface{}{ "deployment": map[string]interface{}{ - "information": info, - "configuration": config, - "alert_emails": additional["alert_emails"], - "worker_queues": additional["worker_queues"], - "astronomer_variables": additional["astronomer_variables"], + "metadata": info, + "configuration": config, + "alert_emails": additional["alert_emails"], + "worker_queues": additional["worker_queues"], + "environment_variables": additional["environment_variables"], }, } actual, err := getSpecificField(printableDeployment, requestedField) @@ -860,14 +860,14 @@ func TestGetSpecificField(t *testing.T) { assert.Equal(t, sourceDeployment.Workspace.ID, actual) }) t.Run("returns a value if key is found in deployment.configuration", func(t *testing.T) { - requestedField := "configuration.scheduler_replicas" + requestedField := "configuration.scheduler_count" printableDeployment := map[string]interface{}{ "deployment": map[string]interface{}{ - "information": info, - "configuration": config, - "alert_emails": additional["alert_emails"], - "worker_queues": additional["worker_queues"], - "astronomer_variables": additional["astronomer_variables"], + "metadata": info, + "configuration": config, + "alert_emails": additional["alert_emails"], + "worker_queues": additional["worker_queues"], + "environment_variables": additional["environment_variables"], }, } actual, err := getSpecificField(printableDeployment, requestedField) @@ -878,26 +878,26 @@ func TestGetSpecificField(t *testing.T) { requestedField := "alert_emails" printableDeployment := map[string]interface{}{ "deployment": map[string]interface{}{ - "information": info, - "configuration": config, - "alert_emails": additional["alert_emails"], - "worker_queues": additional["worker_queues"], - "astronomer_variables": additional["astronomer_variables"], + "metadata": info, + "configuration": config, + "alert_emails": additional["alert_emails"], + "worker_queues": additional["worker_queues"], + "environment_variables": additional["environment_variables"], }, } actual, err := getSpecificField(printableDeployment, requestedField) assert.NoError(t, err) assert.Equal(t, sourceDeployment.AlertEmails, actual) }) - t.Run("returns a value if key is astronomer_variables", func(t *testing.T) { - requestedField := "astronomer_variables" + t.Run("returns a value if key is environment_variables", func(t *testing.T) { + requestedField := "environment_variables" printableDeployment := map[string]interface{}{ "deployment": map[string]interface{}{ - "information": info, - "configuration": config, - "alert_emails": additional["alert_emails"], - "worker_queues": additional["worker_queues"], - "astronomer_variables": additional["astronomer_variables"], + "metadata": info, + "configuration": config, + "alert_emails": additional["alert_emails"], + "worker_queues": additional["worker_queues"], + "environment_variables": additional["environment_variables"], }, } actual, err := getSpecificField(printableDeployment, requestedField) @@ -908,26 +908,26 @@ func TestGetSpecificField(t *testing.T) { requestedField := "worker_queues" printableDeployment := map[string]interface{}{ "deployment": map[string]interface{}{ - "information": info, - "configuration": config, - "alert_emails": additional["alert_emails"], - "worker_queues": additional["worker_queues"], - "astronomer_variables": additional["astronomer_variables"], + "metadata": info, + "configuration": config, + "alert_emails": additional["alert_emails"], + "worker_queues": additional["worker_queues"], + "environment_variables": additional["environment_variables"], }, } actual, err := getSpecificField(printableDeployment, requestedField) assert.NoError(t, err) assert.Equal(t, getQMap(sourceDeployment.WorkerQueues), actual) }) - t.Run("returns a value if key is information", func(t *testing.T) { - requestedField := "information" + t.Run("returns a value if key is metadata", func(t *testing.T) { + requestedField := "metadata" printableDeployment := map[string]interface{}{ "deployment": map[string]interface{}{ - "information": info, - "configuration": config, - "alert_emails": additional["alert_emails"], - "worker_queues": additional["worker_queues"], - "astronomer_variables": additional["astronomer_variables"], + "metadata": info, + "configuration": config, + "alert_emails": additional["alert_emails"], + "worker_queues": additional["worker_queues"], + "environment_variables": additional["environment_variables"], }, } actual, err := getSpecificField(printableDeployment, requestedField) @@ -938,11 +938,11 @@ func TestGetSpecificField(t *testing.T) { requestedField := "Configuration.Cluster_ID" printableDeployment := map[string]interface{}{ "deployment": map[string]interface{}{ - "information": info, - "configuration": config, - "alert_emails": additional["alert_emails"], - "worker_queues": additional["worker_queues"], - "astronomer_variables": additional["astronomer_variables"], + "metadata": info, + "configuration": config, + "alert_emails": additional["alert_emails"], + "worker_queues": additional["worker_queues"], + "environment_variables": additional["environment_variables"], }, } actual, err := getSpecificField(printableDeployment, requestedField) @@ -952,11 +952,11 @@ func TestGetSpecificField(t *testing.T) { t.Run("returns error if no value if found", func(t *testing.T) { printableDeployment := map[string]interface{}{ "deployment": map[string]interface{}{ - "information": info, - "configuration": config, - "alert_emails": additional["alert_emails"], - "worker_queues": additional["worker_queues"], - "astronomer_variables": additional["astronomer_variables"], + "metadata": info, + "configuration": config, + "alert_emails": additional["alert_emails"], + "worker_queues": additional["worker_queues"], + "environment_variables": additional["astronomer_variables"], }, } requestedField := "does-not-exist" @@ -967,11 +967,11 @@ func TestGetSpecificField(t *testing.T) { t.Run("returns error if incorrect field is requested", func(t *testing.T) { printableDeployment := map[string]interface{}{ "deployment": map[string]interface{}{ - "information": info, - "configuration": config, - "alert_emails": additional["alert_emails"], - "worker_queues": additional["worker_queues"], - "astronomer_variables": additional["astronomer_variables"], + "metadata": info, + "configuration": config, + "alert_emails": additional["alert_emails"], + "worker_queues": additional["worker_queues"], + "environment_variables": additional["astronomer_variables"], }, } requestedField := "configuration.does-not-exist" From 91ff54f91208d4310191a6f1a1a1e2a0c5ffcaf3 Mon Sep 17 00:00:00 2001 From: Jemish Patel Date: Thu, 17 Nov 2022 16:19:13 -0800 Subject: [PATCH 2/3] apply order to printed deployments - use `mapstructre.Decode()` to convert to struct once to get ordered output --- cloud/deployment/inspect/inspect.go | 68 +++++- cloud/deployment/inspect/inspect_test.go | 268 +++++++++++++++++------ 2 files changed, 262 insertions(+), 74 deletions(-) diff --git a/cloud/deployment/inspect/inspect.go b/cloud/deployment/inspect/inspect.go index 4114a162b..d4e471a3f 100644 --- a/cloud/deployment/inspect/inspect.go +++ b/cloud/deployment/inspect/inspect.go @@ -6,16 +6,70 @@ import ( "fmt" "io" "strings" + "time" + "github.com/mitchellh/mapstructure" "gopkg.in/yaml.v3" "github.com/astronomer/astro-cli/astro-client" "github.com/astronomer/astro-cli/cloud/deployment" ) +type deploymentMetadata struct { + DeploymentID string `mapstructure:"deployment_id" yaml:"deployment_id" json:"deployment_id"` + WorkspaceID string `mapstructure:"workspace_id" yaml:"workspace_id" json:"workspace_id"` + ClusterID string `mapstructure:"cluster_id" yaml:"cluster_id" json:"cluster_id"` + ReleaseName string `mapstructure:"release_name" yaml:"release_name" json:"release_name"` + AirflowVersion string `mapstructure:"airflow_version" yaml:"airflow_version" json:"airflow_version"` + Status string `mapstructure:"status" yaml:"status" json:"status"` + CreatedAt time.Time `mapstructure:"created_at" yaml:"created_at" json:"created_at"` + UpdatedAt time.Time `mapstructure:"updated_at" yaml:"updated_at" json:"updated_at"` + DeploymentURL string `mapstructure:"deployment_url" yaml:"deployment_url" json:"deployment_url"` + WebserverURL string `mapstructure:"webserver_url" yaml:"webserver_url" json:"webserver_url"` +} + +type deploymentConfig struct { + Name string `mapstructure:"name" yaml:"name" json:"name"` + Description string `mapstructure:"description" yaml:"description" json:"description"` + RunTimeVersion string `mapstructure:"runtime_version" yaml:"runtime_version" json:"runtime_version"` + SchedulerAU int `mapstructure:"scheduler_au" yaml:"scheduler_au" json:"scheduler_au"` + SchedulerCount int `mapstructure:"scheduler_count" yaml:"scheduler_count" json:"scheduler_count"` + ClusterID string `mapstructure:"cluster_id" yaml:"cluster_id" json:"cluster_id"` // this is also in deploymentMetadata +} + +type workerq struct { + Name string `mapstructure:"name" yaml:"name" json:"name"` + ID string `mapstructure:"id" yaml:"id" json:"id"` + IsDefault bool `mapstructure:"is_default" yaml:"is_default" json:"is_default"` + MaxWorkerCount int `mapstructure:"max_worker_count" yaml:"max_worker_count" json:"max_worker_count"` + MinWorkerCount int `mapstructure:"min_worker_count" yaml:"min_worker_count" json:"min_worker_count"` + WorkerConcurrency int `mapstructure:"worker_concurrency" yaml:"worker_concurrency" json:"worker_concurrency"` + NodePoolID string `mapstructure:"node_pool_id" yaml:"node_pool_id" json:"node_pool_id"` +} + +type environmentVariable struct { + IsSecret bool `mapstructure:"is_secret" yaml:"is_secret" json:"is_secret"` + Key string `mapstructure:"key" yaml:"key" json:"key"` + UpdatedAt string `mapstructure:"updated_at" yaml:"updated_at" json:"updated_at"` + Value string `mapstructure:"value" yaml:"value" json:"value"` +} + +type orderedPieces struct { + EnvVars []environmentVariable `mapstructure:"environment_variables" yaml:"environment_variables" json:"environment_variables"` + Configuration deploymentConfig `mapstructure:"configuration" yaml:"configuration" json:"configuration"` + WorkerQs []workerq `mapstructure:"worker_queues" yaml:"worker_queues" json:"worker_queues"` + Metadata deploymentMetadata `mapstructure:"metadata" yaml:"metadata" json:"metadata"` + AlertEmails []string `mapstructure:"alert_emails" yaml:"alert_emails" json:"alert_emails"` +} + +type formattedDeployment struct { + Deployment orderedPieces `mapstructure:"deployment" yaml:"deployment" json:"deployment"` +} + var ( jsonMarshal = json.MarshalIndent yamlMarshal = yaml.Marshal + decodeToStruct = mapstructure.Decode errKeyNotFound = errors.New("not found in deployment") ) @@ -141,18 +195,24 @@ func getVariablesMap(sourceDeploymentVars []astro.EnvironmentVariablesObject) [] func formatPrintableDeployment(outputFormat string, printableDeployment map[string]interface{}) ([]byte, error) { var ( - infoToPrint []byte - err error + infoToPrint []byte + err error + formatWithOrder formattedDeployment ) + // use mapstructure to decode to a struct + err = decodeToStruct(printableDeployment, &formatWithOrder) + if err != nil { + return []byte{}, err + } switch outputFormat { case jsonFormat: - if infoToPrint, err = jsonMarshal(printableDeployment, "", " "); err != nil { + if infoToPrint, err = jsonMarshal(formatWithOrder, "", " "); err != nil { return []byte{}, err } default: // always yaml by default - if infoToPrint, err = yamlMarshal(printableDeployment); err != nil { + if infoToPrint, err = yamlMarshal(formatWithOrder); err != nil { return []byte{}, err } } diff --git a/cloud/deployment/inspect/inspect_test.go b/cloud/deployment/inspect/inspect_test.go index 2f586e9b7..7c228384a 100644 --- a/cloud/deployment/inspect/inspect_test.go +++ b/cloud/deployment/inspect/inspect_test.go @@ -2,11 +2,12 @@ package inspect import ( "bytes" + "encoding/json" "errors" "testing" "time" - "github.com/mitchellh/mapstructure" + "gopkg.in/yaml.v3" "github.com/astronomer/astro-cli/astro-client" astro_mocks "github.com/astronomer/astro-cli/astro-client/mocks" @@ -21,31 +22,6 @@ var ( errMarshal = errors.New("test error") ) -type deploymentMetadata struct { - DeploymentID string `mapstructure:"deployment_id"` - WorkspaceID string `mapstructure:"workspace_id"` - ClusterID string `mapstructure:"cluster_id"` - ReleaseName string `mapstructure:"release_name"` - AirflowVersion string `mapstructure:"airflow_version"` - Status string `mapstructure:"status"` - CreatedAt time.Time `mapstructure:"created_at"` - UpdatedAt time.Time `mapstructure:"updated_at"` - DeploymentURL string `mapstructure:"deployment_url"` - WebserverURL string `mapstructure:"webserver_url"` -} - -type deploymentConfig struct { - Name string `mapstructure:"name"` - Description string `mapstructure:"description"` - RunTimeVersion string `mapstructure:"runtime_version"` - SchedulerAU int `mapstructure:"scheduler_au"` - SchedulerCount int `mapstructure:"scheduler_count"` - ClusterID string `mapstructure:"cluster_id"` // this is also in deploymentMetadata - AlertEmails []string `mapstructure:"alert_emails"` - WorkerQueues []map[string]interface{} `mapstructure:"worker_queues"` - AstroVariables []map[string]interface{} `mapstructure:"environment_variables"` -} - func errReturningYAMLMarshal(v interface{}) ([]byte, error) { return []byte{}, errMarshal } @@ -54,6 +30,14 @@ func errReturningJSONMarshal(v interface{}, prefix, indent string) ([]byte, erro return []byte{}, errMarshal } +func errorReturningDecode(input, output interface{}) error { + return errMarshal +} + +func restoreDecode(replace func(input, output interface{}) error) { + decodeToStruct = replace +} + func restoreJSONMarshal(replace func(v interface{}, prefix, indent string) ([]byte, error)) { jsonMarshal = replace } @@ -316,7 +300,7 @@ func TestGetDeploymentInspectInfo(t *testing.T) { } rawDeploymentInfo, err := getDeploymentInspectInfo(&sourceDeployment) assert.NoError(t, err) - err = mapstructure.Decode(rawDeploymentInfo, &actualDeploymentInfo) + err = decodeToStruct(rawDeploymentInfo, &actualDeploymentInfo) assert.NoError(t, err) assert.Equal(t, expectedDeploymentMetadata, actualDeploymentInfo) }) @@ -339,7 +323,7 @@ func TestGetDeploymentInspectInfo(t *testing.T) { } rawDeploymentInfo, err := getDeploymentInspectInfo(&sourceDeployment) assert.NoError(t, err) - err = mapstructure.Decode(rawDeploymentInfo, &actualDeploymentInfo) + err = decodeToStruct(rawDeploymentInfo, &actualDeploymentInfo) assert.NoError(t, err) assert.Equal(t, expectedDeploymentMetadata, actualDeploymentInfo) }) @@ -350,7 +334,7 @@ func TestGetDeploymentInspectInfo(t *testing.T) { expectedDeploymentMetadata := deploymentMetadata{} rawDeploymentInfo, err := getDeploymentInspectInfo(&sourceDeployment) assert.ErrorContains(t, err, "no context set, have you authenticated to Astro or Astronomer Software? Run astro login and try again") - err = mapstructure.Decode(rawDeploymentInfo, &actualDeploymentInfo) + err = decodeToStruct(rawDeploymentInfo, &actualDeploymentInfo) assert.NoError(t, err) assert.Equal(t, expectedDeploymentMetadata, actualDeploymentInfo) }) @@ -438,12 +422,9 @@ func TestGetDeploymentConfig(t *testing.T) { RunTimeVersion: sourceDeployment.RuntimeRelease.Version, SchedulerAU: sourceDeployment.DeploymentSpec.Scheduler.AU, SchedulerCount: sourceDeployment.DeploymentSpec.Scheduler.Replicas, - AlertEmails: nil, - WorkerQueues: nil, - AstroVariables: nil, } rawDeploymentConfig := getDeploymentConfig(&sourceDeployment) - err := mapstructure.Decode(rawDeploymentConfig, &actualDeploymentConfig) + err := decodeToStruct(rawDeploymentConfig, &actualDeploymentConfig) assert.NoError(t, err) assert.Equal(t, expectedDeploymentConfig, actualDeploymentConfig) }) @@ -613,23 +594,20 @@ func TestGetAdditional(t *testing.T) { } t.Run("returns alert emails, queues and variables for the requested deployment", func(t *testing.T) { - var actualDeploymentConfig deploymentConfig + var expectedAdditional, actualAdditional orderedPieces + testUtil.InitTestConfig(testUtil.CloudPlatform) - expectedDeploymentConfig := deploymentConfig{ - Name: "", - Description: "", - ClusterID: "", - RunTimeVersion: "", - SchedulerAU: 0, - SchedulerCount: 0, - AlertEmails: sourceDeployment.AlertEmails, - WorkerQueues: getQMap(sourceDeployment.WorkerQueues), - AstroVariables: getVariablesMap(sourceDeployment.DeploymentSpec.EnvironmentVariablesObjects), + rawExpected := map[string]interface{}{ + "alert_emails": sourceDeployment.AlertEmails, + "worker_queues": getQMap(sourceDeployment.WorkerQueues), + "environment_variables": getVariablesMap(sourceDeployment.DeploymentSpec.EnvironmentVariablesObjects), // API only returns values when !EnvironmentVariablesObject.isSecret } - rawDeploymentConfig := getAdditional(&sourceDeployment) - err := mapstructure.Decode(rawDeploymentConfig, &actualDeploymentConfig) + rawAdditional := getAdditional(&sourceDeployment) + err := decodeToStruct(rawAdditional, &actualAdditional) assert.NoError(t, err) - assert.Equal(t, expectedDeploymentConfig, actualDeploymentConfig) + err = decodeToStruct(rawExpected, &expectedAdditional) + assert.NoError(t, err) + assert.Equal(t, expectedAdditional, actualAdditional) }) } @@ -712,34 +690,184 @@ func TestFormatPrintableDeployment(t *testing.T) { info, _ := getDeploymentInspectInfo(&sourceDeployment) config := getDeploymentConfig(&sourceDeployment) additional := getAdditional(&sourceDeployment) - expectedPrintableDeployment = []byte("\n metadata:\n") - actualPrintableDeployment, err := formatPrintableDeployment("", getPrintableDeployment(info, config, additional)) + + printableDeployment := map[string]interface{}{ + "deployment": map[string]interface{}{ + "metadata": info, + "configuration": config, + "alert_emails": additional["alert_emails"], + "worker_queues": additional["worker_queues"], + "environment_variables": additional["environment_variables"], + }, + } + expectedDeployment := `deployment: + environment_variables: + - is_secret: false + key: foo + updated_at: NOW + value: bar + - is_secret: true + key: bar + updated_at: NOW+1 + value: baz + configuration: + name: test-deployment-label + description: description + runtime_version: 6.0.0 + scheduler_au: 5 + scheduler_count: 3 + cluster_id: cluster-id + worker_queues: + - name: default + id: test-wq-id + is_default: true + max_worker_count: 130 + min_worker_count: 12 + worker_concurrency: 110 + node_pool_id: test-pool-id + - name: test-queue-1 + id: test-wq-id-1 + is_default: false + max_worker_count: 175 + min_worker_count: 8 + worker_concurrency: 150 + node_pool_id: test-pool-id-1 + metadata: + deployment_id: test-deployment-id + workspace_id: test-ws-id + cluster_id: cluster-id + release_name: great-release-name + airflow_version: 2.4.0 + status: UNHEALTHY + created_at: 2022-11-17T13:25:55.275697-08:00 + updated_at: 2022-11-17T13:25:55.275697-08:00 + deployment_url: cloud.astronomer.io/test-ws-id/deployments/test-deployment-id/analytics + webserver_url: some-url + alert_emails: + - email1 + - email2 +` + var orderedAndTaggedDeployment, unorderedDeployment formattedDeployment + actualPrintableDeployment, err := formatPrintableDeployment("", printableDeployment) assert.NoError(t, err) - assert.Contains(t, string(actualPrintableDeployment), string(expectedPrintableDeployment)) - expectedPrintableDeployment = []byte("\n configuration:\n") - assert.Contains(t, string(actualPrintableDeployment), string(expectedPrintableDeployment)) - expectedPrintableDeployment = []byte("\n alert_emails:\n") - assert.Contains(t, string(actualPrintableDeployment), string(expectedPrintableDeployment)) - expectedPrintableDeployment = []byte("\n worker_queues:\n") - assert.Contains(t, string(actualPrintableDeployment), string(expectedPrintableDeployment)) - expectedPrintableDeployment = []byte("\n environment_variables:\n") - assert.Contains(t, string(actualPrintableDeployment), string(expectedPrintableDeployment)) + // testing we get valid yaml + err = yaml.Unmarshal(actualPrintableDeployment, &orderedAndTaggedDeployment) + assert.NoError(t, err) + // update time and create time are not equal here so can not do equality check + assert.NotEqual(t, expectedDeployment, string(actualPrintableDeployment), "tag and order should match") + + unordered, err := yaml.Marshal(printableDeployment) + assert.NoError(t, err) + err = yaml.Unmarshal(unordered, &unorderedDeployment) + assert.NoError(t, err) + // testing the structs are equal regardless of order + assert.Equal(t, orderedAndTaggedDeployment, unorderedDeployment, "structs should match") + // testing the order is not equal + assert.NotEqual(t, string(unordered), string(actualPrintableDeployment), "order should not match") }) t.Run("returns a json formatted printable deployment", func(t *testing.T) { info, _ := getDeploymentInspectInfo(&sourceDeployment) config := getDeploymentConfig(&sourceDeployment) additional := getAdditional(&sourceDeployment) - expectedPrintableDeployment = []byte(",\n \"metadata\":") - actualPrintableDeployment, err := formatPrintableDeployment("json", getPrintableDeployment(info, config, additional)) + printableDeployment := map[string]interface{}{ + "deployment": map[string]interface{}{ + "metadata": info, + "configuration": config, + "alert_emails": additional["alert_emails"], + "worker_queues": additional["worker_queues"], + "environment_variables": additional["environment_variables"], + }, + } + expectedDeployment := `{ + "deployment": { + "environment_variables": [ + { + "is_secret": false, + "key": "foo", + "updated_at": "NOW", + "value": "bar" + }, + { + "is_secret": true, + "key": "bar", + "updated_at": "NOW+1", + "value": "baz" + } + ], + "configuration": { + "name": "test-deployment-label", + "description": "description", + "runtime_version": "6.0.0", + "scheduler_au": 5, + "scheduler_count": 3, + "cluster_id": "cluster-id" + }, + "worker_queues": [ + { + "name": "default", + "id": "test-wq-id", + "is_default": true, + "max_worker_count": 130, + "min_worker_count": 12, + "worker_concurrency": 110, + "node_pool_id": "test-pool-id" + }, + { + "name": "test-queue-1", + "id": "test-wq-id-1", + "is_default": false, + "max_worker_count": 175, + "min_worker_count": 8, + "worker_concurrency": 150, + "node_pool_id": "test-pool-id-1" + } + ], + "metadata": { + "deployment_id": "test-deployment-id", + "workspace_id": "test-ws-id", + "cluster_id": "cluster-id", + "release_name": "great-release-name", + "airflow_version": "2.4.0", + "status": "UNHEALTHY", + "created_at": "2022-11-17T12:26:45.362983-08:00", + "updated_at": "2022-11-17T12:26:45.362983-08:00", + "deployment_url": "cloud.astronomer.io/test-ws-id/deployments/test-deployment-id/analytics", + "webserver_url": "some-url" + }, + "alert_emails": [ + "email1", + "email2" + ] + } +}` + var orderedAndTaggedDeployment, unorderedDeployment formattedDeployment + actualPrintableDeployment, err := formatPrintableDeployment("json", printableDeployment) assert.NoError(t, err) - assert.Contains(t, string(actualPrintableDeployment), string(expectedPrintableDeployment)) - expectedPrintableDeployment = []byte("\n \"configuration\": ") - assert.Contains(t, string(actualPrintableDeployment), string(expectedPrintableDeployment)) - expectedPrintableDeployment = []byte("\n \"alert_emails\": ") - assert.Contains(t, string(actualPrintableDeployment), string(expectedPrintableDeployment)) - expectedPrintableDeployment = []byte("\n \"worker_queues\": ") - assert.Contains(t, string(actualPrintableDeployment), string(expectedPrintableDeployment)) - expectedPrintableDeployment = []byte("\n \"environment_variables\": ") + // testing we get valid json + err = json.Unmarshal(actualPrintableDeployment, &orderedAndTaggedDeployment) + assert.NoError(t, err) + // update time and create time are not equal here so can not do equality check + assert.NotEqual(t, expectedDeployment, string(actualPrintableDeployment), "tag and order should match") + + unordered, err := json.MarshalIndent(printableDeployment, "", " ") + assert.NoError(t, err) + err = json.Unmarshal(unordered, &unorderedDeployment) + assert.NoError(t, err) + // testing the structs are equal regardless of order + assert.Equal(t, orderedAndTaggedDeployment, unorderedDeployment, "structs should match") + // testing the order is not equal + assert.NotEqual(t, string(unordered), string(actualPrintableDeployment), "order should not match") + }) + t.Run("returns an error if decoding to struct fails", func(t *testing.T) { + originalDecode := decodeToStruct + decodeToStruct = errorReturningDecode + defer restoreDecode(originalDecode) + info, _ := getDeploymentInspectInfo(&sourceDeployment) + config := getDeploymentConfig(&sourceDeployment) + additional := getAdditional(&sourceDeployment) + expectedPrintableDeployment = []byte{} + actualPrintableDeployment, err := formatPrintableDeployment("", getPrintableDeployment(info, config, additional)) + assert.ErrorIs(t, err, errMarshal) assert.Contains(t, string(actualPrintableDeployment), string(expectedPrintableDeployment)) }) t.Run("returns an error if marshaling yaml fails", func(t *testing.T) { @@ -844,7 +972,7 @@ func TestGetSpecificField(t *testing.T) { info, _ := getDeploymentInspectInfo(&sourceDeployment) config := getDeploymentConfig(&sourceDeployment) additional := getAdditional(&sourceDeployment) - t.Run("returns a value if key is found in deployment.information", func(t *testing.T) { + t.Run("returns a value if key is found in deployment.metadata", func(t *testing.T) { requestedField := "metadata.workspace_id" printableDeployment := map[string]interface{}{ "deployment": map[string]interface{}{ @@ -949,7 +1077,7 @@ func TestGetSpecificField(t *testing.T) { assert.NoError(t, err) assert.Equal(t, sourceDeployment.Cluster.ID, actual) }) - t.Run("returns error if no value if found", func(t *testing.T) { + t.Run("returns error if no value is found", func(t *testing.T) { printableDeployment := map[string]interface{}{ "deployment": map[string]interface{}{ "metadata": info, From 80f917e972c4eb7fd22c5b14203510fcfd39e669 Mon Sep 17 00:00:00 2001 From: Jemish Patel Date: Thu, 17 Nov 2022 16:47:56 -0800 Subject: [PATCH 3/3] add dag_deploy_enabled to printed deployments - rename `getDeploymentInspectInfo()` o `getDeploymentInfo()` --- cloud/deployment/inspect/inspect.go | 46 ++++++------ cloud/deployment/inspect/inspect_test.go | 92 +++++++++++++----------- 2 files changed, 73 insertions(+), 65 deletions(-) diff --git a/cloud/deployment/inspect/inspect.go b/cloud/deployment/inspect/inspect.go index d4e471a3f..9e0710dff 100644 --- a/cloud/deployment/inspect/inspect.go +++ b/cloud/deployment/inspect/inspect.go @@ -16,16 +16,17 @@ import ( ) type deploymentMetadata struct { - DeploymentID string `mapstructure:"deployment_id" yaml:"deployment_id" json:"deployment_id"` - WorkspaceID string `mapstructure:"workspace_id" yaml:"workspace_id" json:"workspace_id"` - ClusterID string `mapstructure:"cluster_id" yaml:"cluster_id" json:"cluster_id"` - ReleaseName string `mapstructure:"release_name" yaml:"release_name" json:"release_name"` - AirflowVersion string `mapstructure:"airflow_version" yaml:"airflow_version" json:"airflow_version"` - Status string `mapstructure:"status" yaml:"status" json:"status"` - CreatedAt time.Time `mapstructure:"created_at" yaml:"created_at" json:"created_at"` - UpdatedAt time.Time `mapstructure:"updated_at" yaml:"updated_at" json:"updated_at"` - DeploymentURL string `mapstructure:"deployment_url" yaml:"deployment_url" json:"deployment_url"` - WebserverURL string `mapstructure:"webserver_url" yaml:"webserver_url" json:"webserver_url"` + DeploymentID string `mapstructure:"deployment_id" yaml:"deployment_id" json:"deployment_id"` + WorkspaceID string `mapstructure:"workspace_id" yaml:"workspace_id" json:"workspace_id"` + ClusterID string `mapstructure:"cluster_id" yaml:"cluster_id" json:"cluster_id"` + ReleaseName string `mapstructure:"release_name" yaml:"release_name" json:"release_name"` + AirflowVersion string `mapstructure:"airflow_version" yaml:"airflow_version" json:"airflow_version"` + DagDeployEnabled bool `mapstructure:"dag_deploy_enabled" yaml:"dag_deploy_enabled" json:"dag_deploy_enabled"` + Status string `mapstructure:"status" yaml:"status" json:"status"` + CreatedAt time.Time `mapstructure:"created_at" yaml:"created_at" json:"created_at"` + UpdatedAt time.Time `mapstructure:"updated_at" yaml:"updated_at" json:"updated_at"` + DeploymentURL string `mapstructure:"deployment_url" yaml:"deployment_url" json:"deployment_url"` + WebserverURL string `mapstructure:"webserver_url" yaml:"webserver_url" json:"webserver_url"` } type deploymentConfig struct { @@ -91,7 +92,7 @@ func Inspect(wsID, deploymentName, deploymentID, outputFormat string, client ast } // create a map for deployment.information - deploymentInfoMap, err = getDeploymentInspectInfo(&requestedDeployment) + deploymentInfoMap, err = getDeploymentInfo(&requestedDeployment) if err != nil { return err } @@ -119,7 +120,7 @@ func Inspect(wsID, deploymentName, deploymentID, outputFormat string, client ast return nil } -func getDeploymentInspectInfo(sourceDeployment *astro.Deployment) (map[string]interface{}, error) { +func getDeploymentInfo(sourceDeployment *astro.Deployment) (map[string]interface{}, error) { var ( deploymentURL string err error @@ -130,16 +131,17 @@ func getDeploymentInspectInfo(sourceDeployment *astro.Deployment) (map[string]in return nil, err } return map[string]interface{}{ - "deployment_id": sourceDeployment.ID, - "workspace_id": sourceDeployment.Workspace.ID, - "cluster_id": sourceDeployment.Cluster.ID, - "airflow_version": sourceDeployment.RuntimeRelease.AirflowVersion, - "release_name": sourceDeployment.ReleaseName, - "deployment_url": deploymentURL, - "webserver_url": sourceDeployment.DeploymentSpec.Webserver.URL, - "created_at": sourceDeployment.CreatedAt, - "updated_at": sourceDeployment.UpdatedAt, - "status": sourceDeployment.Status, + "deployment_id": sourceDeployment.ID, + "workspace_id": sourceDeployment.Workspace.ID, + "cluster_id": sourceDeployment.Cluster.ID, + "airflow_version": sourceDeployment.RuntimeRelease.AirflowVersion, + "release_name": sourceDeployment.ReleaseName, + "deployment_url": deploymentURL, + "webserver_url": sourceDeployment.DeploymentSpec.Webserver.URL, + "created_at": sourceDeployment.CreatedAt, + "updated_at": sourceDeployment.UpdatedAt, + "status": sourceDeployment.Status, + "dag_deploy_enabled": sourceDeployment.DagDeployEnabled, }, nil } diff --git a/cloud/deployment/inspect/inspect_test.go b/cloud/deployment/inspect/inspect_test.go index 7c228384a..ca5bba108 100644 --- a/cloud/deployment/inspect/inspect_test.go +++ b/cloud/deployment/inspect/inspect_test.go @@ -247,7 +247,8 @@ func TestGetDeploymentInspectInfo(t *testing.T) { }, }, }, - RuntimeRelease: astro.RuntimeRelease{Version: "6.0.0", AirflowVersion: "2.4.0"}, + DagDeployEnabled: true, + RuntimeRelease: astro.RuntimeRelease{Version: "6.0.0", AirflowVersion: "2.4.0"}, DeploymentSpec: astro.DeploymentSpec{ Executor: "CeleryExecutor", Scheduler: astro.Scheduler{ @@ -281,62 +282,64 @@ func TestGetDeploymentInspectInfo(t *testing.T) { Status: "HEALTHY", } - t.Run("returns deployment Info for the requested cloud deployment", func(t *testing.T) { - var actualDeploymentInfo deploymentMetadata + t.Run("returns deployment metadata for the requested cloud deployment", func(t *testing.T) { + var actualDeploymentMeta deploymentMetadata testUtil.InitTestConfig(testUtil.CloudPlatform) expectedCloudDomainURL := "cloud.astronomer.io/" + sourceDeployment.Workspace.ID + "/deployments/" + sourceDeployment.ID + "/analytics" expectedDeploymentMetadata := deploymentMetadata{ - DeploymentID: sourceDeployment.ID, - WorkspaceID: sourceDeployment.Workspace.ID, - ClusterID: sourceDeployment.Cluster.ID, - AirflowVersion: sourceDeployment.RuntimeRelease.AirflowVersion, - ReleaseName: sourceDeployment.ReleaseName, - DeploymentURL: expectedCloudDomainURL, - WebserverURL: sourceDeployment.DeploymentSpec.Webserver.URL, - CreatedAt: sourceDeployment.CreatedAt, - UpdatedAt: sourceDeployment.UpdatedAt, - Status: sourceDeployment.Status, + DeploymentID: sourceDeployment.ID, + WorkspaceID: sourceDeployment.Workspace.ID, + ClusterID: sourceDeployment.Cluster.ID, + AirflowVersion: sourceDeployment.RuntimeRelease.AirflowVersion, + ReleaseName: sourceDeployment.ReleaseName, + DeploymentURL: expectedCloudDomainURL, + WebserverURL: sourceDeployment.DeploymentSpec.Webserver.URL, + CreatedAt: sourceDeployment.CreatedAt, + UpdatedAt: sourceDeployment.UpdatedAt, + Status: sourceDeployment.Status, + DagDeployEnabled: sourceDeployment.DagDeployEnabled, } - rawDeploymentInfo, err := getDeploymentInspectInfo(&sourceDeployment) + rawDeploymentInfo, err := getDeploymentInfo(&sourceDeployment) assert.NoError(t, err) - err = decodeToStruct(rawDeploymentInfo, &actualDeploymentInfo) + err = decodeToStruct(rawDeploymentInfo, &actualDeploymentMeta) assert.NoError(t, err) - assert.Equal(t, expectedDeploymentMetadata, actualDeploymentInfo) + assert.Equal(t, expectedDeploymentMetadata, actualDeploymentMeta) }) - t.Run("returns deployment Info for the requested local deployment", func(t *testing.T) { - var actualDeploymentInfo deploymentMetadata + t.Run("returns deployment metadata for the requested local deployment", func(t *testing.T) { + var actualDeploymentMeta deploymentMetadata testUtil.InitTestConfig(testUtil.LocalPlatform) expectedCloudDomainURL := "localhost:5000/" + sourceDeployment.Workspace.ID + "/deployments/" + sourceDeployment.ID + "/analytics" expectedDeploymentMetadata := deploymentMetadata{ - DeploymentID: sourceDeployment.ID, - WorkspaceID: sourceDeployment.Workspace.ID, - ClusterID: sourceDeployment.Cluster.ID, - ReleaseName: sourceDeployment.ReleaseName, - AirflowVersion: sourceDeployment.RuntimeRelease.AirflowVersion, - Status: sourceDeployment.Status, - CreatedAt: sourceDeployment.CreatedAt, - UpdatedAt: sourceDeployment.UpdatedAt, - DeploymentURL: expectedCloudDomainURL, - WebserverURL: sourceDeployment.DeploymentSpec.Webserver.URL, + DeploymentID: sourceDeployment.ID, + WorkspaceID: sourceDeployment.Workspace.ID, + ClusterID: sourceDeployment.Cluster.ID, + ReleaseName: sourceDeployment.ReleaseName, + AirflowVersion: sourceDeployment.RuntimeRelease.AirflowVersion, + Status: sourceDeployment.Status, + CreatedAt: sourceDeployment.CreatedAt, + UpdatedAt: sourceDeployment.UpdatedAt, + DeploymentURL: expectedCloudDomainURL, + WebserverURL: sourceDeployment.DeploymentSpec.Webserver.URL, + DagDeployEnabled: sourceDeployment.DagDeployEnabled, } - rawDeploymentInfo, err := getDeploymentInspectInfo(&sourceDeployment) + rawDeploymentInfo, err := getDeploymentInfo(&sourceDeployment) assert.NoError(t, err) - err = decodeToStruct(rawDeploymentInfo, &actualDeploymentInfo) + err = decodeToStruct(rawDeploymentInfo, &actualDeploymentMeta) assert.NoError(t, err) - assert.Equal(t, expectedDeploymentMetadata, actualDeploymentInfo) + assert.Equal(t, expectedDeploymentMetadata, actualDeploymentMeta) }) t.Run("returns error if getting context fails", func(t *testing.T) { - var actualDeploymentInfo deploymentMetadata + var actualDeploymentMeta deploymentMetadata // get an error from GetCurrentContext() testUtil.InitTestConfig(testUtil.ErrorReturningContext) expectedDeploymentMetadata := deploymentMetadata{} - rawDeploymentInfo, err := getDeploymentInspectInfo(&sourceDeployment) + rawDeploymentInfo, err := getDeploymentInfo(&sourceDeployment) assert.ErrorContains(t, err, "no context set, have you authenticated to Astro or Astronomer Software? Run astro login and try again") - err = decodeToStruct(rawDeploymentInfo, &actualDeploymentInfo) + err = decodeToStruct(rawDeploymentInfo, &actualDeploymentMeta) assert.NoError(t, err) - assert.Equal(t, expectedDeploymentMetadata, actualDeploymentInfo) + assert.Equal(t, expectedDeploymentMetadata, actualDeploymentMeta) }) } @@ -504,7 +507,7 @@ func TestGetPrintableDeployment(t *testing.T) { Status: "UNHEALTHY", } t.Run("returns a deployment map", func(t *testing.T) { - info, _ := getDeploymentInspectInfo(&sourceDeployment) + info, _ := getDeploymentInfo(&sourceDeployment) config := getDeploymentConfig(&sourceDeployment) additional := getAdditional(&sourceDeployment) expectedDeployment := map[string]interface{}{ @@ -637,7 +640,8 @@ func TestFormatPrintableDeployment(t *testing.T) { }, }, }, - RuntimeRelease: astro.RuntimeRelease{Version: "6.0.0", AirflowVersion: "2.4.0"}, + DagDeployEnabled: true, + RuntimeRelease: astro.RuntimeRelease{Version: "6.0.0", AirflowVersion: "2.4.0"}, DeploymentSpec: astro.DeploymentSpec{ Executor: "CeleryExecutor", Scheduler: astro.Scheduler{ @@ -687,7 +691,7 @@ func TestFormatPrintableDeployment(t *testing.T) { var expectedPrintableDeployment []byte t.Run("returns a yaml formatted printable deployment", func(t *testing.T) { - info, _ := getDeploymentInspectInfo(&sourceDeployment) + info, _ := getDeploymentInfo(&sourceDeployment) config := getDeploymentConfig(&sourceDeployment) additional := getAdditional(&sourceDeployment) @@ -738,6 +742,7 @@ func TestFormatPrintableDeployment(t *testing.T) { cluster_id: cluster-id release_name: great-release-name airflow_version: 2.4.0 + dag_deploy_enabled: true status: UNHEALTHY created_at: 2022-11-17T13:25:55.275697-08:00 updated_at: 2022-11-17T13:25:55.275697-08:00 @@ -766,7 +771,7 @@ func TestFormatPrintableDeployment(t *testing.T) { assert.NotEqual(t, string(unordered), string(actualPrintableDeployment), "order should not match") }) t.Run("returns a json formatted printable deployment", func(t *testing.T) { - info, _ := getDeploymentInspectInfo(&sourceDeployment) + info, _ := getDeploymentInfo(&sourceDeployment) config := getDeploymentConfig(&sourceDeployment) additional := getAdditional(&sourceDeployment) printableDeployment := map[string]interface{}{ @@ -828,6 +833,7 @@ func TestFormatPrintableDeployment(t *testing.T) { "cluster_id": "cluster-id", "release_name": "great-release-name", "airflow_version": "2.4.0", + "dag_deploy_enabled": true, "status": "UNHEALTHY", "created_at": "2022-11-17T12:26:45.362983-08:00", "updated_at": "2022-11-17T12:26:45.362983-08:00", @@ -862,7 +868,7 @@ func TestFormatPrintableDeployment(t *testing.T) { originalDecode := decodeToStruct decodeToStruct = errorReturningDecode defer restoreDecode(originalDecode) - info, _ := getDeploymentInspectInfo(&sourceDeployment) + info, _ := getDeploymentInfo(&sourceDeployment) config := getDeploymentConfig(&sourceDeployment) additional := getAdditional(&sourceDeployment) expectedPrintableDeployment = []byte{} @@ -874,7 +880,7 @@ func TestFormatPrintableDeployment(t *testing.T) { originalMarshal := yamlMarshal yamlMarshal = errReturningYAMLMarshal defer restoreYAMLMarshal(originalMarshal) - info, _ := getDeploymentInspectInfo(&sourceDeployment) + info, _ := getDeploymentInfo(&sourceDeployment) config := getDeploymentConfig(&sourceDeployment) additional := getAdditional(&sourceDeployment) expectedPrintableDeployment = []byte{} @@ -886,7 +892,7 @@ func TestFormatPrintableDeployment(t *testing.T) { originalMarshal := jsonMarshal jsonMarshal = errReturningJSONMarshal defer restoreJSONMarshal(originalMarshal) - info, _ := getDeploymentInspectInfo(&sourceDeployment) + info, _ := getDeploymentInfo(&sourceDeployment) config := getDeploymentConfig(&sourceDeployment) additional := getAdditional(&sourceDeployment) expectedPrintableDeployment = []byte{} @@ -969,7 +975,7 @@ func TestGetSpecificField(t *testing.T) { Status: "UNHEALTHY", } testUtil.InitTestConfig(testUtil.CloudPlatform) - info, _ := getDeploymentInspectInfo(&sourceDeployment) + info, _ := getDeploymentInfo(&sourceDeployment) config := getDeploymentConfig(&sourceDeployment) additional := getAdditional(&sourceDeployment) t.Run("returns a value if key is found in deployment.metadata", func(t *testing.T) {