Skip to content

Commit

Permalink
feat(Deployments): support ParameterOpenAPISchema
Browse files Browse the repository at this point in the history
Adds support for the ParameterOpenAPISchema for the Deployment resource.

Related to #238

Related to https://linear.app/prefect/issue/PLA-185/support-for-deployments-resource
  • Loading branch information
mitchnielsen committed Sep 19, 2024
1 parent d6cafda commit 1c4629f
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 8 deletions.
1 change: 1 addition & 0 deletions docs/resources/deployment.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ resource "prefect_deployment" "deployment" {
- `entrypoint` (String) The path to the entrypoint for the workflow, relative to the path.
- `job_variables` (String) Overrides for the flow's infrastructure configuration.
- `manifest_path` (String) The path to the flow's manifest file, relative to the chosen storage.
- `parameter_openapi_schema` (String) The parameter schema of the flow, including defaults.
- `parameters` (String) Parameters for flow runs scheduled by the deployment.
- `path` (String) The path to the working directory for the workflow, relative to remote storage or an absolute path.
- `paused` (Boolean) Whether or not the deployment is paused.
Expand Down
6 changes: 6 additions & 0 deletions examples/resources/prefect_deployment/resource.tf
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,12 @@ resource "prefect_deployment" "deployment" {
"some-parameter" : "some-value",
"some-parameter2" : "some-value2"
})
parameter_openapi_schema = jsonencode({
"type" : "object",
"properties" : {
"some-parameter" : { "type" : "string" }
}
})
path = "./foo/bar"
paused = false
version = "v1.1.1"
Expand Down
2 changes: 2 additions & 0 deletions internal/api/deployments.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ type Deployment struct {
JobVariables map[string]interface{} `json:"job_variables,omitempty"`
ManifestPath string `json:"manifest_path,omitempty"`
Name string `json:"name"`
ParameterOpenAPISchema map[string]interface{} `json:"parameter_openapi_schema,omitempty"`
Parameters map[string]interface{} `json:"parameters,omitempty"`
Path string `json:"path"`
Paused bool `json:"paused"`
Expand All @@ -46,6 +47,7 @@ type DeploymentCreate struct {
JobVariables map[string]interface{} `json:"job_variables,omitempty"`
ManifestPath string `json:"manifest_path,omitempty"`
Name string `json:"name"`
ParameterOpenAPISchema map[string]interface{} `json:"parameter_openapi_schema,omitempty"`
Parameters map[string]interface{} `json:"parameters,omitempty"`
Path string `json:"path,omitempty"`
Paused bool `json:"paused,omitempty"`
Expand Down
34 changes: 34 additions & 0 deletions internal/provider/resources/deployment.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ type DeploymentResourceModel struct {
JobVariables jsontypes.Normalized `tfsdk:"job_variables"`
ManifestPath types.String `tfsdk:"manifest_path"`
Name types.String `tfsdk:"name"`
ParameterOpenAPISchema jsontypes.Normalized `tfsdk:"parameter_openapi_schema"`
Parameters jsontypes.Normalized `tfsdk:"parameters"`
Path types.String `tfsdk:"path"`
Paused types.Bool `tfsdk:"paused"`
Expand Down Expand Up @@ -231,6 +232,12 @@ func (r *DeploymentResource) Schema(_ context.Context, _ resource.SchemaRequest,
Computed: true,
CustomType: jsontypes.NormalizedType{},
},
"parameter_openapi_schema": schema.StringAttribute{
Description: "The parameter schema of the flow, including defaults.",
Optional: true,
Computed: true,
CustomType: jsontypes.NormalizedType{},
},
},
}
}
Expand Down Expand Up @@ -298,6 +305,12 @@ func (r *DeploymentResource) Create(ctx context.Context, req resource.CreateRequ
return
}

var parameterOpenAPISchema map[string]interface{}
resp.Diagnostics.Append(plan.ParameterOpenAPISchema.Unmarshal(&parameterOpenAPISchema)...)
if resp.Diagnostics.HasError() {
return
}

deployment, err := client.Create(ctx, api.DeploymentCreate{
Description: plan.Description.ValueString(),
EnforceParameterSchema: plan.EnforceParameterSchema.ValueBool(),
Expand All @@ -313,6 +326,7 @@ func (r *DeploymentResource) Create(ctx context.Context, req resource.CreateRequ
Version: plan.Version.ValueString(),
WorkPoolName: plan.WorkPoolName.ValueString(),
WorkQueueName: plan.WorkQueueName.ValueString(),
ParameterOpenAPISchema: parameterOpenAPISchema,
})
if err != nil {
resp.Diagnostics.AddError(
Expand Down Expand Up @@ -397,6 +411,12 @@ func (r *DeploymentResource) Read(ctx context.Context, req resource.ReadRequest,
}
model.JobVariables = jsontypes.NewNormalizedValue(string(jobVariablesByteSlice))

parameterOpenAPISchemaByteSlice, err := json.Marshal(deployment.ParameterOpenAPISchema)
if err != nil {
resp.Diagnostics.Append(helpers.SerializeDataErrorDiagnostic("parameter_openapi_schema", "Deployment parameter OpenAPI schema", err))
}
model.ParameterOpenAPISchema = jsontypes.NewNormalizedValue(string(parameterOpenAPISchemaByteSlice))

resp.Diagnostics.Append(resp.State.Set(ctx, &model)...)
if resp.Diagnostics.HasError() {
return
Expand Down Expand Up @@ -449,6 +469,12 @@ func (r *DeploymentResource) Update(ctx context.Context, req resource.UpdateRequ
return
}

var parameterOpenAPISchema map[string]interface{}
resp.Diagnostics.Append(model.ParameterOpenAPISchema.Unmarshal(&parameterOpenAPISchema)...)
if resp.Diagnostics.HasError() {
return
}

payload := api.DeploymentUpdate{
Description: model.Description.ValueString(),
EnforceParameterSchema: model.EnforceParameterSchema.ValueBool(),
Expand Down Expand Up @@ -505,6 +531,14 @@ func (r *DeploymentResource) Update(ctx context.Context, req resource.UpdateRequ
}
model.JobVariables = jsontypes.NewNormalizedValue(string(jobVariablesByteSlice))

parameterOpenAPISchemaByteSlice, err := json.Marshal(deployment.ParameterOpenAPISchema)
if err != nil {
resp.Diagnostics.Append(helpers.SerializeDataErrorDiagnostic("parameter_openapi_schema", "Deployment parameter OpenAPI schema", err))

return
}
model.ParameterOpenAPISchema = jsontypes.NewNormalizedValue(string(parameterOpenAPISchemaByteSlice))

resp.Diagnostics.Append(resp.State.Set(ctx, &model)...)
if resp.Diagnostics.HasError() {
return
Expand Down
37 changes: 29 additions & 8 deletions internal/provider/resources/deployment_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@ package resources_test

import (
"context"
"encoding/json"
"fmt"
"strconv"
"strings"
"testing"

"github.com/google/uuid"
Expand Down Expand Up @@ -32,6 +34,7 @@ type deploymentConfig struct {
Version string
WorkPoolName string
WorkQueueName string
ParameterOpenAPISchema string

FlowName string
}
Expand Down Expand Up @@ -68,6 +71,7 @@ resource "prefect_deployment" "{{.DeploymentName}}" {
version = "{{.Version}}"
work_pool_name = "{{.WorkPoolName}}"
work_queue_name = "{{.WorkQueueName}}"
parameter_openapi_schema = jsonencode({{.ParameterOpenAPISchema}})
workspace_id = data.prefect_workspace.evergreen.id
depends_on = [prefect_flow.{{.FlowName}}]
Expand All @@ -82,6 +86,10 @@ func TestAccResource_deployment(t *testing.T) {
deploymentName := testutils.NewRandomPrefixedString()
flowName := testutils.NewRandomPrefixedString()

parameterOpenAPISchema := `{"type": "object", "properties": {"some-parameter": {"type": "string"}}}`
var parameterOpenAPISchemaMap map[string]interface{}
_ = json.Unmarshal([]byte(parameterOpenAPISchema), &parameterOpenAPISchemaMap)

cfgCreate := deploymentConfig{
DeploymentName: deploymentName,
FlowName: flowName,
Expand All @@ -100,6 +108,7 @@ func TestAccResource_deployment(t *testing.T) {
Version: "v1.1.1",
WorkPoolName: "evergreen-pool",
WorkQueueName: "evergreen-queue",
ParameterOpenAPISchema: parameterOpenAPISchema,
}

cfgUpdate := deploymentConfig{
Expand Down Expand Up @@ -140,6 +149,9 @@ func TestAccResource_deployment(t *testing.T) {
//
// Tags: []string{"test1", "test3"}
Tags: cfgCreate.Tags,

// ParameterOpenAPISchema is not settable via the Update method.
ParameterOpenAPISchema: cfgCreate.ParameterOpenAPISchema,
}

var deployment api.Deployment
Expand All @@ -152,8 +164,12 @@ func TestAccResource_deployment(t *testing.T) {
// Check creation + existence of the deployment resource
Config: fixtureAccDeployment(cfgCreate),
Check: resource.ComposeAggregateTestCheckFunc(
resource.TestCheckResourceAttr(cfgCreate.DeploymentResourceName, "name", cfgCreate.DeploymentName),
resource.TestCheckResourceAttr(cfgCreate.DeploymentResourceName, "description", cfgCreate.Description),
testAccCheckDeploymentExists(cfgCreate.DeploymentResourceName, cfgCreate.WorkspaceResourceName, &deployment),
testAccCheckDeploymentValues(&deployment, expectedDeploymentValues{
name: cfgCreate.DeploymentName,
description: cfgCreate.Description,
parameterOpenapiSchema: parameterOpenAPISchemaMap,
}),
resource.TestCheckResourceAttr(cfgCreate.DeploymentResourceName, "enforce_parameter_schema", strconv.FormatBool(cfgCreate.EnforceParameterSchema)),
resource.TestCheckResourceAttr(cfgCreate.DeploymentResourceName, "entrypoint", cfgCreate.Entrypoint),
resource.TestCheckResourceAttr(cfgCreate.DeploymentResourceName, "job_variables", cfgCreate.JobVariables),
Expand All @@ -175,11 +191,10 @@ func TestAccResource_deployment(t *testing.T) {
Check: resource.ComposeAggregateTestCheckFunc(
testAccCheckDeploymentExists(cfgUpdate.DeploymentResourceName, cfgUpdate.WorkspaceResourceName, &deployment),
testAccCheckDeploymentValues(&deployment, expectedDeploymentValues{
name: cfgUpdate.DeploymentName,
description: cfgUpdate.Description,
name: cfgUpdate.DeploymentName,
description: cfgUpdate.Description,
parameterOpenapiSchema: parameterOpenAPISchemaMap,
}),
resource.TestCheckResourceAttr(cfgUpdate.DeploymentResourceName, "name", cfgUpdate.DeploymentName),
resource.TestCheckResourceAttr(cfgUpdate.DeploymentResourceName, "description", cfgUpdate.Description),
resource.TestCheckResourceAttr(cfgUpdate.DeploymentResourceName, "enforce_parameter_schema", strconv.FormatBool(cfgUpdate.EnforceParameterSchema)),
resource.TestCheckResourceAttr(cfgUpdate.DeploymentResourceName, "entrypoint", cfgUpdate.Entrypoint),
resource.TestCheckResourceAttr(cfgCreate.DeploymentResourceName, "job_variables", cfgUpdate.JobVariables),
Expand Down Expand Up @@ -243,8 +258,9 @@ func testAccCheckDeploymentExists(deploymentResourceName string, workspaceResour
}

type expectedDeploymentValues struct {
name string
description string
name string
description string
parameterOpenapiSchema map[string]interface{}
}

// testAccCheckDeploymentValues is a Custom Check Function that
Expand All @@ -258,6 +274,11 @@ func testAccCheckDeploymentValues(fetchedDeployment *api.Deployment, expectedVal
return fmt.Errorf("Expected deployment description to be %s, got %s", expectedValues.description, fetchedDeployment.Description)
}

equal, diffs := helpers.ObjectsEqual(expectedValues.parameterOpenapiSchema, fetchedDeployment.ParameterOpenAPISchema)
if !equal {
return fmt.Errorf("Found unexpected differences in deployment parameter_openapi_schema: %s", strings.Join(diffs, "\n"))
}

return nil
}
}

0 comments on commit 1c4629f

Please sign in to comment.