这是indexloc提供的服务,不要输入任何密码
Skip to content

Support updating of existing alias resources #301

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 28, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 14 additions & 13 deletions client/alias.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,23 +7,24 @@ import (
"github.com/hashicorp/terraform-plugin-log/tflog"
)

// CreateAliasRequest defines the request the Vercel API expects in order to create an alias.
type CreateAliasRequest struct {
Alias string `json:"alias"`
// UpsertAliasRequest defines the request the Vercel API expects in order to create an alias.
type UpsertAliasRequest struct {
Alias string `json:"alias"`
DeploymentID string `json:"-"`
TeamID string `json:"-"`
}

// The create Alias endpoint does not return the full AliasResponse, only the UID and Alias.
type createAliasResponse struct {
UID string `json:"uid"`
Alias string `json:"alias"`
TeamID string `json:"-"`
UID string `json:"uid"`
Alias string `json:"alias"`
}

// CreateAlias creates an alias within Vercel.
func (c *Client) CreateAlias(ctx context.Context, request CreateAliasRequest, deploymentID string, teamID string) (r AliasResponse, err error) {
url := fmt.Sprintf("%s/v2/deployments/%s/aliases", c.baseURL, deploymentID)
if c.teamID(teamID) != "" {
url = fmt.Sprintf("%s?teamId=%s", url, c.teamID(teamID))
// UpsertAlias creates an alias within Vercel.
func (c *Client) UpsertAlias(ctx context.Context, request UpsertAliasRequest) (r AliasResponse, err error) {
url := fmt.Sprintf("%s/v2/deployments/%s/aliases", c.baseURL, request.DeploymentID)
if c.teamID(request.TeamID) != "" {
url = fmt.Sprintf("%s?teamId=%s", url, c.teamID(request.TeamID))
}
payload := string(mustMarshal(request))

Expand All @@ -45,8 +46,8 @@ func (c *Client) CreateAlias(ctx context.Context, request CreateAliasRequest, de
return AliasResponse{
UID: aliasResponse.UID,
Alias: aliasResponse.Alias,
DeploymentID: deploymentID,
TeamID: c.teamID(teamID),
DeploymentID: request.DeploymentID,
TeamID: c.teamID(request.TeamID),
}, nil
}

Expand Down
57 changes: 44 additions & 13 deletions vercel/resource_alias.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,14 +58,12 @@ Provides an Alias resource.
An Alias allows a ` + "`vercel_deployment` to be accessed through a different URL.",
Attributes: map[string]schema.Attribute{
"alias": schema.StringAttribute{
Description: "The Alias we want to assign to the deployment defined in the URL.",
Required: true,
PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()},
Description: "The Alias we want to assign to the deployment defined in the URL.",
Required: true,
},
"deployment_id": schema.StringAttribute{
Description: "The id of the Deployment the Alias should be associated with.",
Required: true,
PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()},
Description: "The id of the Deployment the Alias should be associated with.",
Required: true,
},
"team_id": schema.StringAttribute{
Optional: true,
Expand Down Expand Up @@ -110,9 +108,12 @@ func (r *aliasResource) Create(ctx context.Context, req resource.CreateRequest,
return
}

out, err := r.client.CreateAlias(ctx, client.CreateAliasRequest{
Alias: plan.Alias.ValueString(),
}, plan.DeploymentID.ValueString(), plan.TeamID.ValueString())
// Use the update function to create and update aliases, as the API is an upsert
out, err := r.client.UpsertAlias(ctx, client.UpsertAliasRequest{
Alias: plan.Alias.ValueString(),
DeploymentID: plan.DeploymentID.ValueString(),
TeamID: plan.TeamID.ValueString(),
})
if err != nil {
resp.Diagnostics.AddError(
"Error creating alias",
Expand Down Expand Up @@ -176,11 +177,41 @@ func (r *aliasResource) Read(ctx context.Context, req resource.ReadRequest, resp
}

// Update updates the Alias state.
// The Vercel API for creating an alias is an upsert. We can simply call the create method again to update.
func (r *aliasResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {
resp.Diagnostics.AddError(
"Updating an Alias is not supported",
"Updating an Alias is not supported",
)
var plan Alias
diags := req.Plan.Get(ctx, &plan)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return
}

// Use the update function to create and update aliases, as the API is an upsert
out, err := r.client.UpsertAlias(ctx, client.UpsertAliasRequest{
Alias: plan.Alias.ValueString(),
DeploymentID: plan.DeploymentID.ValueString(),
TeamID: plan.TeamID.ValueString(),
})
if err != nil {
resp.Diagnostics.AddError(
"Error updating alias",
fmt.Sprintf("Could not update alias %s, unexpected error: %s", plan.Alias.ValueString(), err.Error()),
)
return
}

result := convertResponseToAlias(out, plan)
tflog.Info(ctx, "updated alias", map[string]any{
"team_id": plan.TeamID.ValueString(),
"deployment_id": plan.DeploymentID.ValueString(),
"alias_id": result.ID.ValueString(),
})

diags = resp.State.Set(ctx, result)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return
}
}

// Delete deletes an Alias.
Expand Down
34 changes: 34 additions & 0 deletions vercel/resource_alias_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,15 @@ func TestAcc_AliasResource(t *testing.T) {
resource.TestCheckResourceAttrSet("vercel_alias.test", "deployment_id"),
),
},
{
Config: testAccAliasResourceConfigUpdated(name, teamIDConfig()),
Check: resource.ComposeAggregateTestCheckFunc(
testCheckAliasExists(testTeam(), fmt.Sprintf("test-acc-%s.vercel.app", name)),
resource.TestCheckResourceAttr("vercel_alias.test", "alias", fmt.Sprintf("test-acc-%s.vercel.app", name)),
resource.TestCheckResourceAttrSet("vercel_alias.test", "id"),
resource.TestCheckResourceAttrSet("vercel_alias.test", "deployment_id"),
),
},
},
})
}
Expand Down Expand Up @@ -85,3 +94,28 @@ resource "vercel_alias" "test" {
}
`, name, team, testGithubRepo())
}

func testAccAliasResourceConfigUpdated(name, team string) string {
return fmt.Sprintf(`
resource "vercel_project" "test" {
name = "test-acc-%[1]s"
%[2]s
git_repository = {
type = "github"
repo = "%[3]s"
}
}

resource "vercel_deployment" "test_two" {
project_id = vercel_project.test.id
ref = "main"
%[2]s
}

resource "vercel_alias" "test" {
alias = "test-acc-%[1]s.vercel.app"
deployment_id = vercel_deployment.test_two.id
%[2]s
}
`, name, team, testGithubRepo())
}
Loading