diff --git a/client/environment_variable_create.go b/client/environment_variable_create.go index c01e23cb..d1d59d53 100644 --- a/client/environment_variable_create.go +++ b/client/environment_variable_create.go @@ -11,14 +11,18 @@ import ( // CreateEnvironmentVariableRequest defines the information that needs to be passed to Vercel in order to // create an environment variable. -type CreateEnvironmentVariableRequest struct { +type EnvironmentVariableRequest struct { Key string `json:"key"` Value string `json:"value"` Target []string `json:"target"` GitBranch *string `json:"gitBranch,omitempty"` Type string `json:"type"` - ProjectID string `json:"-"` - TeamID string `json:"-"` +} + +type CreateEnvironmentVariableRequest struct { + EnvironmentVariable EnvironmentVariableRequest + ProjectID string + TeamID string } // CreateEnvironmentVariable will create a brand new environment variable if one does not exist. @@ -27,7 +31,7 @@ func (c *Client) CreateEnvironmentVariable(ctx context.Context, request CreateEn if c.teamID(request.TeamID) != "" { url = fmt.Sprintf("%s?teamId=%s", url, c.teamID(request.TeamID)) } - payload := string(mustMarshal(request)) + payload := string(mustMarshal(request.EnvironmentVariable)) req, err := http.NewRequestWithContext( ctx, "POST", @@ -44,7 +48,37 @@ func (c *Client) CreateEnvironmentVariable(ctx context.Context, request CreateEn }) err = c.doRequest(req, &e) // The API response returns an encrypted environment variable, but we want to return the decrypted version. - e.Value = request.Value + e.Value = request.EnvironmentVariable.Value e.TeamID = c.teamID(request.TeamID) return e, err } + +type CreateEnvironmentVariablesRequest struct { + EnvironmentVariables []EnvironmentVariableRequest + ProjectID string + TeamID string +} + +func (c *Client) CreateEnvironmentVariables(ctx context.Context, request CreateEnvironmentVariablesRequest) error { + url := fmt.Sprintf("%s/v9/projects/%s/env", c.baseURL, request.ProjectID) + if c.teamID(request.TeamID) != "" { + url = fmt.Sprintf("%s?teamId=%s", url, c.teamID(request.TeamID)) + } + payload := string(mustMarshal(request.EnvironmentVariables)) + req, err := http.NewRequestWithContext( + ctx, + "POST", + url, + strings.NewReader(payload), + ) + if err != nil { + return err + } + + tflog.Trace(ctx, "creating environment variable", map[string]interface{}{ + "url": url, + "payload": payload, + }) + err = c.doRequest(req, nil) + return err +} diff --git a/vercel/resource_project.go b/vercel/resource_project.go index a0c2b7d0..d78bae09 100644 --- a/vercel/resource_project.go +++ b/vercel/resource_project.go @@ -410,28 +410,34 @@ func (r *projectResource) Update(ctx context.Context, req resource.UpdateRequest "environment_id": v.ID.ValueString(), }) } + + var items []client.EnvironmentVariableRequest for _, v := range toCreate { - result, err := r.client.CreateEnvironmentVariable( - ctx, - v.toCreateEnvironmentVariableRequest(plan.ID.ValueString(), plan.TeamID.ValueString()), + items = append(items, v.toEnvironmentVariableRequest()) + } + + err = r.client.CreateEnvironmentVariables( + ctx, + client.CreateEnvironmentVariablesRequest{ + ProjectID: plan.ID.ValueString(), + TeamID: plan.TeamID.ValueString(), + EnvironmentVariables: items, + }, + ) + if err != nil { + resp.Diagnostics.AddError( + "Error updating project", + fmt.Sprintf( + "Could not upsert environment variables for project %s, unexpected error: %s", + plan.ID.ValueString(), + err, + ), ) - if err != nil { - resp.Diagnostics.AddError( - "Error updating project", - fmt.Sprintf( - "Could not upsert environment variable %s (%s), unexpected error: %s", - v.Key.ValueString(), - v.ID.ValueString(), - err, - ), - ) - } - tflog.Trace(ctx, "upserted environment variable", map[string]interface{}{ - "team_id": plan.TeamID.ValueString(), - "project_id": plan.ID.ValueString(), - "environment_id": result.ID, - }) } + tflog.Trace(ctx, "upserted environment variables", map[string]interface{}{ + "team_id": plan.TeamID.ValueString(), + "project_id": plan.ID.ValueString(), + }) out, err := r.client.UpdateProject(ctx, state.ID.ValueString(), state.TeamID.ValueString(), plan.toUpdateProjectRequest(state.Name.ValueString()), !plan.Environment.IsNull()) if err != nil { diff --git a/vercel/resource_project_environment_variable_model.go b/vercel/resource_project_environment_variable_model.go index 8e4dbfdb..5751b354 100644 --- a/vercel/resource_project_environment_variable_model.go +++ b/vercel/resource_project_environment_variable_model.go @@ -22,11 +22,13 @@ func (e *ProjectEnvironmentVariable) toCreateEnvironmentVariableRequest() client target = append(target, t.ValueString()) } return client.CreateEnvironmentVariableRequest{ - Key: e.Key.ValueString(), - Value: e.Value.ValueString(), - Target: target, - GitBranch: toStrPointer(e.GitBranch), - Type: "encrypted", + EnvironmentVariable: client.EnvironmentVariableRequest{ + Key: e.Key.ValueString(), + Value: e.Value.ValueString(), + Target: target, + GitBranch: toStrPointer(e.GitBranch), + Type: "encrypted", + }, ProjectID: e.ProjectID.ValueString(), TeamID: e.TeamID.ValueString(), } diff --git a/vercel/resource_project_model.go b/vercel/resource_project_model.go index 699d549c..5b995a96 100644 --- a/vercel/resource_project_model.go +++ b/vercel/resource_project_model.go @@ -106,19 +106,17 @@ type EnvironmentItem struct { ID types.String `tfsdk:"id"` } -func (e *EnvironmentItem) toCreateEnvironmentVariableRequest(projectID, teamID string) client.CreateEnvironmentVariableRequest { +func (e *EnvironmentItem) toEnvironmentVariableRequest() client.EnvironmentVariableRequest { var target []string for _, t := range e.Target { target = append(target, t.ValueString()) } - return client.CreateEnvironmentVariableRequest{ + return client.EnvironmentVariableRequest{ Key: e.Key.ValueString(), Value: e.Value.ValueString(), Target: target, GitBranch: toStrPointer(e.GitBranch), Type: "encrypted", - ProjectID: projectID, - TeamID: teamID, } }