From 647633beddf8b29b98b478b2aabc29a643e9f47c Mon Sep 17 00:00:00 2001 From: Tomer Heber Date: Mon, 11 Apr 2022 09:29:49 -0500 Subject: [PATCH 1/3] Chore: don't sleep during acceptance tests (#329) --- env0/resource_environment.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/env0/resource_environment.go b/env0/resource_environment.go index 59912a3d..4b021d8b 100644 --- a/env0/resource_environment.go +++ b/env0/resource_environment.go @@ -5,6 +5,7 @@ import ( "errors" "fmt" "log" + "os" "regexp" "time" @@ -730,7 +731,10 @@ func waitForDeployment(deploymentLogId string, apiClient client.ApiClientInterfa "QUEUED", "WAITING_FOR_USER": log.Println("[INFO] Deployment not yet done deploying. Got status ", deployment.Status) - time.Sleep(deploymentStatusWaitPollInterval * time.Second) + // TF_ACC is set during acceptance tests. Don't pause during accpetance tests. + if value, present := os.LookupEnv("TF_ACC"); !present || value != "1" { + time.Sleep(deploymentStatusWaitPollInterval * time.Second) + } case "SUCCESS", "SKIPPED": log.Println("[INFO] Deployment done deploying! Got status ", deployment.Status) From 3b5f4e99a0833f6dd6d57158671483e4a19d87d8 Mon Sep 17 00:00:00 2001 From: Tomer Heber Date: Mon, 11 Apr 2022 10:31:38 -0500 Subject: [PATCH 2/3] Feat: add support for agent settings (#325) * Feat: add support for agent settings * changed name of variable. added a test for drift * added another small use-case --- env0/provider.go | 1 + env0/resource_agent_project_assignment.go | 196 +++++++++++++++ .../resource_agent_project_assignment_test.go | 230 ++++++++++++++++++ go.mod | 2 +- go.sum | 12 +- 5 files changed, 437 insertions(+), 4 deletions(-) create mode 100644 env0/resource_agent_project_assignment.go create mode 100644 env0/resource_agent_project_assignment_test.go diff --git a/env0/provider.go b/env0/provider.go index 18c63b50..fdcd6c69 100644 --- a/env0/provider.go +++ b/env0/provider.go @@ -89,6 +89,7 @@ func Provider(version string) plugin.ProviderFunc { "env0_git_token": resourceGitToken(), "env0_api_key": resourceApiKey(), "env0_organization_policy": resourceOrganizationPolicy(), + "env0_agent_project_assignment": resourceAgentProjectAssignment(), }, } diff --git a/env0/resource_agent_project_assignment.go b/env0/resource_agent_project_assignment.go new file mode 100644 index 00000000..46309bfc --- /dev/null +++ b/env0/resource_agent_project_assignment.go @@ -0,0 +1,196 @@ +package env0 + +import ( + "context" + "fmt" + "log" + "strings" + "sync" + + "github.com/env0/terraform-provider-env0/client" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +// Updating an agent project assignment overrides all project organization assignments. +// Therefore, must extract all existing assignments and append/remove the created/deleted assignment. +// Since Terraform may run the assignments in parallel a mutex is required. +var apaLock sync.Mutex + +// id is _ + +type AgentProjectAssignment struct { + AgentId string `json:"agent_id"` + ProjectId string `json:"project_id"` +} + +func GetAgentProjectAssignmentId(agentId string, projectId string) string { + return agentId + "_" + projectId +} + +func (a *AgentProjectAssignment) GetId() string { + return GetAgentProjectAssignmentId(a.AgentId, a.ProjectId) +} + +func resourceAgentProjectAssignment() *schema.Resource { + return &schema.Resource{ + CreateContext: resourceAgentProjectAssignmentCreate, + ReadContext: resourceAgentProjectAssignmentRead, + DeleteContext: resourceAgentProjectAssignmentDelete, + + Importer: &schema.ResourceImporter{StateContext: resourceAgentProjectAssignmentImport}, + + Schema: map[string]*schema.Schema{ + "agent_id": { + Type: schema.TypeString, + Description: "id of the agent", + Required: true, + ForceNew: true, + }, + "project_id": { + Type: schema.TypeString, + Description: "id of the project", + Required: true, + ForceNew: true, + }, + }, + } +} + +func resourceAgentProjectAssignmentCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + var newAssignment AgentProjectAssignment + if err := readResourceData(&newAssignment, d); err != nil { + return diag.Errorf("schema resource data deserialization failed: %v", err) + } + + apaLock.Lock() + defer apaLock.Unlock() + + apiClient := meta.(client.ApiClientInterface) + assignments, err := apiClient.ProjectsAgentsAssignments() + if err != nil { + return diag.Errorf("could not get project-agent assignments: %v", err) + } + + for projectId, agentId := range assignments.ProjectsAgents { + if projectId == newAssignment.ProjectId && agentId == newAssignment.AgentId { + return diag.Errorf("assignment for project id %v and agent id %v already exist", projectId, agentId) + } + } + + assignments.ProjectsAgents[newAssignment.ProjectId] = newAssignment.AgentId + + if _, err := apiClient.AssignAgentsToProjects(assignments.ProjectsAgents); err != nil { + return diag.Errorf("could not update project-agent assignments: %v", err) + } + + d.SetId(newAssignment.GetId()) + + return nil +} + +func resourceAgentProjectAssignmentRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + apiClient := meta.(client.ApiClientInterface) + + apaLock.Lock() + defer apaLock.Unlock() + + assignments, err := apiClient.ProjectsAgentsAssignments() + if err != nil { + return diag.Errorf("could not get project-agent assignments: %v", err) + } + + var assignment *AgentProjectAssignment + for projectId, agentId := range assignments.ProjectsAgents { + if d.Id() == GetAgentProjectAssignmentId(agentId.(string), projectId) { + assignment = &AgentProjectAssignment{ + AgentId: agentId.(string), + ProjectId: projectId, + } + break + } + } + + if assignment == nil { + log.Printf("[WARN] Drift Detected: Terraform will remove %s from state", d.Id()) + d.SetId("") + return nil + } + + if err := writeResourceData(assignment, d); err != nil { + diag.Errorf("schema resource data serialization failed: %v", err) + } + + return nil +} + +func resourceAgentProjectAssignmentDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + projectId := d.Get("project_id").(string) + agentId := d.Get("agent_id").(string) + + apaLock.Lock() + defer apaLock.Unlock() + + apiClient := meta.(client.ApiClientInterface) + + assignments, err := apiClient.ProjectsAgentsAssignments() + if err != nil { + return diag.Errorf("could not get project-agent assignments: %v", err) + } + + newAssignments := make(map[string]interface{}) + + // Remove from the assignments the deleted assignment. + for projectIdOther, agentIdOther := range assignments.ProjectsAgents { + if projectId != projectIdOther || agentId != agentIdOther { + newAssignments[projectIdOther] = agentIdOther + } + } + + if _, err := apiClient.AssignAgentsToProjects(newAssignments); err != nil { + return diag.Errorf("could not update project-agent assignments: %v", err) + } + + return nil +} + +func resourceAgentProjectAssignmentImport(ctx context.Context, d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { + splitAgentProject := strings.Split(d.Id(), "_") + if len(splitAgentProject) != 2 { + return nil, fmt.Errorf("the id %v is invalid must be _", d.Id()) + } + + agentId := splitAgentProject[0] + projectId := splitAgentProject[1] + + apaLock.Lock() + defer apaLock.Unlock() + + apiClient := meta.(client.ApiClientInterface) + + assignments, err := apiClient.ProjectsAgentsAssignments() + if err != nil { + return nil, err + } + + var assignment *AgentProjectAssignment + for projectIdOther, agentIdOther := range assignments.ProjectsAgents { + if projectIdOther == projectId && agentIdOther == agentId { + assignment = &AgentProjectAssignment{ + AgentId: agentId, + ProjectId: projectId, + } + break + } + } + + if assignment == nil { + return nil, fmt.Errorf("assignment with id %v not found", d.Id()) + } + + if err := writeResourceData(assignment, d); err != nil { + diag.Errorf("schema resource data serialization failed: %v", err) + } + + return []*schema.ResourceData{d}, nil +} diff --git a/env0/resource_agent_project_assignment_test.go b/env0/resource_agent_project_assignment_test.go new file mode 100644 index 00000000..2de6a8e7 --- /dev/null +++ b/env0/resource_agent_project_assignment_test.go @@ -0,0 +1,230 @@ +package env0 + +import ( + "fmt" + "regexp" + "testing" + + "github.com/env0/terraform-provider-env0/client" + "github.com/golang/mock/gomock" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" +) + +func TestUnitAgentProjectAssignmentResource(t *testing.T) { + + // helper functions that receives a variadic list of key value items and returns a ProjectsAgentsAssignments instance. + + GenerateProjectsAgentsAssignmentsMap := func(items ...string) map[string]interface{} { + res := make(map[string]interface{}) + + for i := 0; i < len(items)-1; i += 2 { + res[items[i]] = items[i+1] + } + + return res + } + + GenerateProjectsAgentsAssignments := func(items ...string) *client.ProjectsAgentsAssignments { + return &client.ProjectsAgentsAssignments{ + ProjectsAgents: GenerateProjectsAgentsAssignmentsMap(items...), + } + } + + resourceType := "env0_agent_project_assignment" + resourceName := "test" + accessor := resourceAccessor(resourceType, resourceName) + + projectId := "pid" + agentId := "aid" + + t.Run("Create assignment", func(t *testing.T) { + testCase := resource.TestCase{ + Steps: []resource.TestStep{ + { + Config: resourceConfigCreate(resourceType, resourceName, map[string]interface{}{ + "project_id": projectId, + "agent_id": agentId, + }), + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr(accessor, "id", agentId+"_"+projectId), + resource.TestCheckResourceAttr(accessor, "project_id", projectId), + resource.TestCheckResourceAttr(accessor, "agent_id", agentId), + ), + }, + { + Config: resourceConfigCreate(resourceType, resourceName, map[string]interface{}{ + "project_id": projectId, + "agent_id": agentId, + }), + }, + }, + } + + runUnitTest(t, testCase, func(mock *client.MockApiClientInterface) { + gomock.InOrder( + mock.EXPECT().ProjectsAgentsAssignments().Times(1).Return(GenerateProjectsAgentsAssignments("p111", "a222"), nil), + mock.EXPECT().AssignAgentsToProjects(GenerateProjectsAgentsAssignmentsMap( + "p111", + "a222", + projectId, + agentId, + )).Times(1).Return(nil, nil), + mock.EXPECT().ProjectsAgentsAssignments().Times(4).Return(GenerateProjectsAgentsAssignments("p111", "a222", projectId, agentId), nil), + mock.EXPECT().AssignAgentsToProjects(GenerateProjectsAgentsAssignmentsMap( + "p111", + "a222", + )).Times(1).Return(nil, nil), + ) + }) + }) + + t.Run("Create assignment with Drift", func(t *testing.T) { + testCase := resource.TestCase{ + Steps: []resource.TestStep{ + { + Config: resourceConfigCreate(resourceType, resourceName, map[string]interface{}{ + "project_id": projectId, + "agent_id": agentId, + }), + ExpectNonEmptyPlan: true, + }, + { + Config: resourceConfigCreate(resourceType, resourceName, map[string]interface{}{ + "project_id": projectId, + "agent_id": agentId, + }), + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr(accessor, "id", agentId+"_"+projectId), + resource.TestCheckResourceAttr(accessor, "project_id", projectId), + resource.TestCheckResourceAttr(accessor, "agent_id", agentId), + ), + PlanOnly: true, + ExpectNonEmptyPlan: true, + }, + }, + } + + runUnitTest(t, testCase, func(mock *client.MockApiClientInterface) { + gomock.InOrder( + mock.EXPECT().ProjectsAgentsAssignments().Times(1).Return(GenerateProjectsAgentsAssignments(), nil), + mock.EXPECT().AssignAgentsToProjects(GenerateProjectsAgentsAssignmentsMap(projectId, agentId)), + mock.EXPECT().ProjectsAgentsAssignments().Times(1).Return(GenerateProjectsAgentsAssignments(), nil), + ) + }) + }) + + t.Run("Assignment already exist", func(t *testing.T) { + testCase := resource.TestCase{ + Steps: []resource.TestStep{ + { + Config: resourceConfigCreate(resourceType, resourceName, map[string]interface{}{ + "project_id": projectId, + "agent_id": agentId, + }), + ExpectError: regexp.MustCompile(fmt.Sprintf("assignment for project id %v and agent id %v already exist", projectId, agentId)), + }, + }, + } + + runUnitTest(t, testCase, func(mock *client.MockApiClientInterface) { + gomock.InOrder( + mock.EXPECT().ProjectsAgentsAssignments().Times(1).Return(GenerateProjectsAgentsAssignments("p111", "a222", projectId, agentId), nil), + ) + }) + }) + + t.Run("Import Assignment", func(t *testing.T) { + testCase := resource.TestCase{ + Steps: []resource.TestStep{ + { + Config: resourceConfigCreate(resourceType, resourceName, map[string]interface{}{ + "project_id": projectId, + "agent_id": agentId, + }), + }, + { + ResourceName: resourceType + "." + resourceName, + ImportState: true, + ImportStateId: agentId + "_" + projectId, + ImportStateVerify: true, + }, + }, + } + + runUnitTest(t, testCase, func(mock *client.MockApiClientInterface) { + gomock.InOrder( + mock.EXPECT().ProjectsAgentsAssignments().Times(1).Return(GenerateProjectsAgentsAssignments(), nil), + mock.EXPECT().AssignAgentsToProjects(GenerateProjectsAgentsAssignmentsMap( + projectId, + agentId, + )).Times(1).Return(nil, nil), + mock.EXPECT().ProjectsAgentsAssignments().Times(4).Return(GenerateProjectsAgentsAssignments(projectId, agentId), nil), + mock.EXPECT().AssignAgentsToProjects(GenerateProjectsAgentsAssignmentsMap()).Times(1).Return(nil, nil), + ) + }) + }) + + t.Run("Import Assignment with invalid id", func(t *testing.T) { + testCase := resource.TestCase{ + Steps: []resource.TestStep{ + { + Config: resourceConfigCreate(resourceType, resourceName, map[string]interface{}{ + "project_id": projectId, + "agent_id": agentId, + }), + }, + { + ResourceName: resourceType + "." + resourceName, + ImportState: true, + ImportStateId: "invalid", + ImportStateVerify: true, + ExpectError: regexp.MustCompile("the id invalid is invalid must be _"), + }, + }, + } + + runUnitTest(t, testCase, func(mock *client.MockApiClientInterface) { + gomock.InOrder( + mock.EXPECT().ProjectsAgentsAssignments().Times(1).Return(GenerateProjectsAgentsAssignments(), nil), + mock.EXPECT().AssignAgentsToProjects(GenerateProjectsAgentsAssignmentsMap( + projectId, + agentId, + )).Times(1).Return(nil, nil), + mock.EXPECT().ProjectsAgentsAssignments().Times(2).Return(GenerateProjectsAgentsAssignments(projectId, agentId), nil), + mock.EXPECT().AssignAgentsToProjects(GenerateProjectsAgentsAssignmentsMap()).Times(1).Return(nil, nil), + ) + }) + }) + + t.Run("Import Assignment id not found", func(t *testing.T) { + testCase := resource.TestCase{ + Steps: []resource.TestStep{ + { + Config: resourceConfigCreate(resourceType, resourceName, map[string]interface{}{ + "project_id": projectId, + "agent_id": agentId, + }), + }, + { + ResourceName: resourceType + "." + resourceName, + ImportState: true, + ImportStateId: "pid22_aid22", + ImportStateVerify: true, + ExpectError: regexp.MustCompile("assignment with id pid22_aid22 not found"), + }, + }, + } + + runUnitTest(t, testCase, func(mock *client.MockApiClientInterface) { + gomock.InOrder( + mock.EXPECT().ProjectsAgentsAssignments().Times(1).Return(GenerateProjectsAgentsAssignments(), nil), + mock.EXPECT().AssignAgentsToProjects(GenerateProjectsAgentsAssignmentsMap( + projectId, + agentId, + )).Times(1).Return(nil, nil), + mock.EXPECT().ProjectsAgentsAssignments().Times(3).Return(GenerateProjectsAgentsAssignments(projectId, agentId), nil), + mock.EXPECT().AssignAgentsToProjects(GenerateProjectsAgentsAssignmentsMap()).Times(1).Return(nil, nil), + ) + }) + }) +} diff --git a/go.mod b/go.mod index 0a184dca..ede4b717 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.16 // please change also in repo secrets require ( github.com/adhocore/gronx v0.2.6 github.com/go-resty/resty/v2 v2.6.0 - github.com/golang/mock v1.4.3 + github.com/golang/mock v1.6.0 github.com/google/uuid v1.2.0 github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320 github.com/hashicorp/terraform-plugin-docs v0.5.1 diff --git a/go.sum b/go.sum index 4aff95f3..7af653c4 100644 --- a/go.sum +++ b/go.sum @@ -128,8 +128,9 @@ github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfb github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.3 h1:GV+pQPG/EUUbkh47niozDcADz6go/dUwhVzdUQHIVRw= github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= +github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= github.com/golang/protobuf v1.1.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -365,6 +366,7 @@ github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/zclconf/go-cty v1.2.0/go.mod h1:hOPWgoHbaTUnI5k4D2ld+GRpFJSCe6bCM7m1q/N4PQ8= github.com/zclconf/go-cty v1.2.1/go.mod h1:hOPWgoHbaTUnI5k4D2ld+GRpFJSCe6bCM7m1q/N4PQ8= github.com/zclconf/go-cty v1.9.1/go.mod h1:vVKLxnk3puL4qRAv72AO+W99LUD4da90g3uUAzyuvAk= @@ -419,8 +421,9 @@ golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.2 h1:Gz96sIWK3OalVv/I/qNygP42zyoKp3xptRVCWRFEBvo= +golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20180530234432-1e491301e022/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180811021610-c39426892332/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -471,6 +474,7 @@ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -514,6 +518,7 @@ golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210502180810-71e4cd670f79/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6 h1:foEbQz/B0Oz6YIqu/69kfXPYeFQAuuMYFkjaqXzl5Wo= golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -567,8 +572,9 @@ golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roY golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200713011307-fd294ab11aed/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e h1:4nW4NLDYnU28ojHaHO8OVxFHk/aQ33U01a9cjED+pzE= golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.1 h1:wGiQel/hW0NnEkJUk8lbzkX2gFJU6PFxf1v5OlCfuOs= +golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= From 69f0510a0f4bf69d7874dff8668b440bd872520c Mon Sep 17 00:00:00 2001 From: update generated docs action Date: Mon, 11 Apr 2022 15:32:38 +0000 Subject: [PATCH 3/3] Update docs --- docs/resources/agent_project_assignment.md | 27 ++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 docs/resources/agent_project_assignment.md diff --git a/docs/resources/agent_project_assignment.md b/docs/resources/agent_project_assignment.md new file mode 100644 index 00000000..c1423be6 --- /dev/null +++ b/docs/resources/agent_project_assignment.md @@ -0,0 +1,27 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "env0_agent_project_assignment Resource - terraform-provider-env0" +subcategory: "" +description: |- + +--- + +# env0_agent_project_assignment (Resource) + + + + + + +## Schema + +### Required + +- **agent_id** (String) id of the agent +- **project_id** (String) id of the project + +### Optional + +- **id** (String) The ID of this resource. + +