Revert "fix: allow mapped resources in our terraform provider (#6242)" (#6248)

This reverts commit d5af536ea2.
This commit is contained in:
Marcin Tojek
2023-02-17 12:55:54 +01:00
committed by GitHub
parent a69137b1f7
commit e161c45b47
7 changed files with 317 additions and 841 deletions

View File

@ -90,7 +90,7 @@ func ConvertResourcesAndParameters(modules []*tfjson.StateModule, rawGraph strin
// Indexes Terraform resources by their label.
// The label is what "terraform graph" uses to reference nodes.
tfResourcesByLabel := map[string][]*tfjson.StateResource{}
tfResourceByLabel := map[string]*tfjson.StateResource{}
var findTerraformResources func(mod *tfjson.StateModule)
findTerraformResources = func(mod *tfjson.StateModule) {
for _, module := range mod.ChildModules {
@ -98,10 +98,8 @@ func ConvertResourcesAndParameters(modules []*tfjson.StateModule, rawGraph strin
}
for _, resource := range mod.Resources {
label := convertAddressToLabel(resource.Address)
if tfResourcesByLabel[label] == nil {
tfResourcesByLabel[label] = []*tfjson.StateResource{}
}
tfResourcesByLabel[label] = append(tfResourcesByLabel[label], resource)
// index by label
tfResourceByLabel[label] = resource
}
}
for _, module := range modules {
@ -110,8 +108,7 @@ func ConvertResourcesAndParameters(modules []*tfjson.StateModule, rawGraph strin
// Find all agents!
agentNames := map[string]struct{}{}
for _, tfResources := range tfResourcesByLabel {
for _, tfResource := range tfResources {
for _, tfResource := range tfResourceByLabel {
if tfResource.Type != "coder_agent" {
continue
}
@ -175,7 +172,7 @@ func ConvertResourcesAndParameters(modules []*tfjson.StateModule, rawGraph strin
}
var agentResource *graphResource
for _, resource := range findResourcesInGraph(graph, tfResourcesByLabel, agentNode.Name, 0, true) {
for _, resource := range findResourcesInGraph(graph, tfResourceByLabel, agentNode.Name, 0, true) {
if agentResource == nil {
// Default to the first resource because we have nothing to compare!
agentResource = resource
@ -203,11 +200,9 @@ func ConvertResourcesAndParameters(modules []*tfjson.StateModule, rawGraph strin
agents = append(agents, agent)
resourceAgents[agentResource.Label] = agents
}
}
// Manually associate agents with instance IDs.
for _, resources := range tfResourcesByLabel {
for _, resource := range resources {
for _, resource := range tfResourceByLabel {
if resource.Type != "coder_agent_instance" {
continue
}
@ -247,12 +242,10 @@ func ConvertResourcesAndParameters(modules []*tfjson.StateModule, rawGraph strin
}
}
}
}
// Associate Apps with agents.
appSlugs := make(map[string]struct{})
for _, resources := range tfResourcesByLabel {
for _, resource := range resources {
for _, resource := range tfResourceByLabel {
if resource.Type != "coder_app" {
continue
}
@ -324,7 +317,6 @@ func ConvertResourcesAndParameters(modules []*tfjson.StateModule, rawGraph strin
}
}
}
}
// Associate metadata blocks with resources.
resourceMetadata := map[string][]*proto.Resource_Metadata{}
@ -332,8 +324,7 @@ func ConvertResourcesAndParameters(modules []*tfjson.StateModule, rawGraph strin
resourceIcon := map[string]string{}
resourceCost := map[string]int32{}
for _, resources := range tfResourcesByLabel {
for _, resource := range resources {
for _, resource := range tfResourceByLabel {
if resource.Type != "coder_metadata" {
continue
}
@ -359,7 +350,7 @@ func ConvertResourcesAndParameters(modules []*tfjson.StateModule, rawGraph strin
continue
}
var attachedResource *graphResource
for _, resource := range findResourcesInGraph(graph, tfResourcesByLabel, attachedNode.Name, 0, false) {
for _, resource := range findResourcesInGraph(graph, tfResourceByLabel, attachedNode.Name, 0, false) {
if attachedResource == nil {
// Default to the first resource because we have nothing to compare!
attachedResource = resource
@ -393,10 +384,8 @@ func ConvertResourcesAndParameters(modules []*tfjson.StateModule, rawGraph strin
})
}
}
}
for _, tfResources := range tfResourcesByLabel {
for _, resource := range tfResources {
for _, resource := range tfResourceByLabel {
if resource.Mode == tfjson.DataResourceMode {
continue
}
@ -421,11 +410,9 @@ func ConvertResourcesAndParameters(modules []*tfjson.StateModule, rawGraph strin
InstanceType: applyInstanceType(resource),
})
}
}
parameters := make([]*proto.RichParameter, 0)
for _, tfResources := range tfResourcesByLabel {
for _, resource := range tfResources {
for _, resource := range tfResourceByLabel {
if resource.Type != "coder_parameter" {
continue
}
@ -462,7 +449,6 @@ func ConvertResourcesAndParameters(modules []*tfjson.StateModule, rawGraph strin
}
parameters = append(parameters, protoParam)
}
}
return resources, parameters, nil
}
@ -550,7 +536,7 @@ func applyAutomaticInstanceID(resource *tfjson.StateResource, agents []*proto.Ag
// findResourcesInGraph traverses directionally in a graph until a resource is found,
// then it stores the depth it was found at, and continues working up the tree.
// nolint:revive
func findResourcesInGraph(graph *gographviz.Graph, tfResourcesByLabel map[string][]*tfjson.StateResource, nodeName string, currentDepth uint, up bool) []*graphResource {
func findResourcesInGraph(graph *gographviz.Graph, tfResourceByLabel map[string]*tfjson.StateResource, nodeName string, currentDepth uint, up bool) []*graphResource {
graphResources := make([]*graphResource, 0)
mapping := graph.Edges.DstToSrcs
if !up {
@ -559,18 +545,17 @@ func findResourcesInGraph(graph *gographviz.Graph, tfResourcesByLabel map[string
for destination := range mapping[nodeName] {
destinationNode := graph.Nodes.Lookup[destination]
// Work our way up the tree!
graphResources = append(graphResources, findResourcesInGraph(graph, tfResourcesByLabel, destinationNode.Name, currentDepth+1, up)...)
graphResources = append(graphResources, findResourcesInGraph(graph, tfResourceByLabel, destinationNode.Name, currentDepth+1, up)...)
destinationLabel, exists := destinationNode.Attrs["label"]
if !exists {
continue
}
destinationLabel = strings.Trim(destinationLabel, `"`)
resources, exists := tfResourcesByLabel[destinationLabel]
resource, exists := tfResourceByLabel[destinationLabel]
if !exists {
continue
}
for _, resource := range resources {
// Data sources cannot be associated with agents for now!
if resource.Mode != tfjson.ManagedResourceMode {
continue
@ -584,7 +569,6 @@ func findResourcesInGraph(graph *gographviz.Graph, tfResourcesByLabel map[string
Depth: currentDepth,
})
}
}
return graphResources
}

View File

@ -170,30 +170,6 @@ func TestConvertResources(t *testing.T) {
}},
}},
},
"mapped-apps": {
resources: []*proto.Resource{{
Name: "dev",
Type: "null_resource",
Agents: []*proto.Agent{{
Name: "dev",
OperatingSystem: "linux",
Architecture: "amd64",
Apps: []*proto.App{
{
Slug: "app1",
DisplayName: "app1",
},
{
Slug: "app2",
DisplayName: "app2",
},
},
Auth: &proto.Agent_Token{},
LoginBeforeReady: true,
ConnectionTimeoutSeconds: 120,
}},
}},
},
// Tests fetching metadata about workspace resources.
"resource-metadata": {
resources: []*proto.Resource{{

View File

@ -1,38 +0,0 @@
terraform {
required_providers {
coder = {
source = "coder/coder"
version = "0.6.1"
}
}
}
resource "coder_agent" "dev" {
os = "linux"
arch = "amd64"
}
locals {
apps_map = {
"app1" = {
name = "app1"
}
"app2" = {
name = "app2"
}
}
}
resource "coder_app" "apps" {
for_each = local.apps_map
agent_id = coder_agent.dev.id
slug = each.key
display_name = each.value.name
}
resource "null_resource" "dev" {
depends_on = [
coder_agent.dev
]
}

View File

@ -1,21 +0,0 @@
digraph {
compound = "true"
newrank = "true"
subgraph "root" {
"[root] coder_agent.dev (expand)" [label = "coder_agent.dev", shape = "box"]
"[root] coder_app.apps (expand)" [label = "coder_app.apps", shape = "box"]
"[root] null_resource.dev (expand)" [label = "null_resource.dev", shape = "box"]
"[root] provider[\"registry.terraform.io/coder/coder\"]" [label = "provider[\"registry.terraform.io/coder/coder\"]", shape = "diamond"]
"[root] provider[\"registry.terraform.io/hashicorp/null\"]" [label = "provider[\"registry.terraform.io/hashicorp/null\"]", shape = "diamond"]
"[root] coder_agent.dev (expand)" -> "[root] provider[\"registry.terraform.io/coder/coder\"]"
"[root] coder_app.apps (expand)" -> "[root] coder_agent.dev (expand)"
"[root] coder_app.apps (expand)" -> "[root] local.apps_map (expand)"
"[root] null_resource.dev (expand)" -> "[root] coder_agent.dev (expand)"
"[root] null_resource.dev (expand)" -> "[root] provider[\"registry.terraform.io/hashicorp/null\"]"
"[root] provider[\"registry.terraform.io/coder/coder\"] (close)" -> "[root] coder_app.apps (expand)"
"[root] provider[\"registry.terraform.io/hashicorp/null\"] (close)" -> "[root] null_resource.dev (expand)"
"[root] root" -> "[root] provider[\"registry.terraform.io/coder/coder\"] (close)"
"[root] root" -> "[root] provider[\"registry.terraform.io/hashicorp/null\"] (close)"
}
}

View File

@ -1,298 +0,0 @@
{
"format_version": "1.1",
"terraform_version": "1.3.7",
"planned_values": {
"root_module": {
"resources": [
{
"address": "coder_agent.dev",
"mode": "managed",
"type": "coder_agent",
"name": "dev",
"provider_name": "registry.terraform.io/coder/coder",
"schema_version": 0,
"values": {
"arch": "amd64",
"auth": "token",
"connection_timeout": 120,
"dir": null,
"env": null,
"os": "linux",
"startup_script": null,
"troubleshooting_url": null
},
"sensitive_values": {}
},
{
"address": "coder_app.apps[\"app1\"]",
"mode": "managed",
"type": "coder_app",
"name": "apps",
"index": "app1",
"provider_name": "registry.terraform.io/coder/coder",
"schema_version": 0,
"values": {
"command": null,
"display_name": "app1",
"healthcheck": [],
"icon": null,
"name": null,
"relative_path": null,
"share": "owner",
"slug": "app1",
"subdomain": null,
"url": null
},
"sensitive_values": {
"healthcheck": []
}
},
{
"address": "coder_app.apps[\"app2\"]",
"mode": "managed",
"type": "coder_app",
"name": "apps",
"index": "app2",
"provider_name": "registry.terraform.io/coder/coder",
"schema_version": 0,
"values": {
"command": null,
"display_name": "app2",
"healthcheck": [],
"icon": null,
"name": null,
"relative_path": null,
"share": "owner",
"slug": "app2",
"subdomain": null,
"url": null
},
"sensitive_values": {
"healthcheck": []
}
},
{
"address": "null_resource.dev",
"mode": "managed",
"type": "null_resource",
"name": "dev",
"provider_name": "registry.terraform.io/hashicorp/null",
"schema_version": 0,
"values": {
"triggers": null
},
"sensitive_values": {}
}
]
}
},
"resource_changes": [
{
"address": "coder_agent.dev",
"mode": "managed",
"type": "coder_agent",
"name": "dev",
"provider_name": "registry.terraform.io/coder/coder",
"change": {
"actions": [
"create"
],
"before": null,
"after": {
"arch": "amd64",
"auth": "token",
"connection_timeout": 120,
"dir": null,
"env": null,
"os": "linux",
"startup_script": null,
"troubleshooting_url": null
},
"after_unknown": {
"id": true,
"init_script": true,
"token": true
},
"before_sensitive": false,
"after_sensitive": {
"token": true
}
}
},
{
"address": "coder_app.apps[\"app1\"]",
"mode": "managed",
"type": "coder_app",
"name": "apps",
"index": "app1",
"provider_name": "registry.terraform.io/coder/coder",
"change": {
"actions": [
"create"
],
"before": null,
"after": {
"command": null,
"display_name": "app1",
"healthcheck": [],
"icon": null,
"name": null,
"relative_path": null,
"share": "owner",
"slug": "app1",
"subdomain": null,
"url": null
},
"after_unknown": {
"agent_id": true,
"healthcheck": [],
"id": true
},
"before_sensitive": false,
"after_sensitive": {
"healthcheck": []
}
}
},
{
"address": "coder_app.apps[\"app2\"]",
"mode": "managed",
"type": "coder_app",
"name": "apps",
"index": "app2",
"provider_name": "registry.terraform.io/coder/coder",
"change": {
"actions": [
"create"
],
"before": null,
"after": {
"command": null,
"display_name": "app2",
"healthcheck": [],
"icon": null,
"name": null,
"relative_path": null,
"share": "owner",
"slug": "app2",
"subdomain": null,
"url": null
},
"after_unknown": {
"agent_id": true,
"healthcheck": [],
"id": true
},
"before_sensitive": false,
"after_sensitive": {
"healthcheck": []
}
}
},
{
"address": "null_resource.dev",
"mode": "managed",
"type": "null_resource",
"name": "dev",
"provider_name": "registry.terraform.io/hashicorp/null",
"change": {
"actions": [
"create"
],
"before": null,
"after": {
"triggers": null
},
"after_unknown": {
"id": true
},
"before_sensitive": false,
"after_sensitive": {}
}
}
],
"configuration": {
"provider_config": {
"coder": {
"name": "coder",
"full_name": "registry.terraform.io/coder/coder",
"version_constraint": "0.6.1"
},
"null": {
"name": "null",
"full_name": "registry.terraform.io/hashicorp/null"
}
},
"root_module": {
"resources": [
{
"address": "coder_agent.dev",
"mode": "managed",
"type": "coder_agent",
"name": "dev",
"provider_config_key": "coder",
"expressions": {
"arch": {
"constant_value": "amd64"
},
"os": {
"constant_value": "linux"
}
},
"schema_version": 0
},
{
"address": "coder_app.apps",
"mode": "managed",
"type": "coder_app",
"name": "apps",
"provider_config_key": "coder",
"expressions": {
"agent_id": {
"references": [
"coder_agent.dev.id",
"coder_agent.dev"
]
},
"display_name": {
"references": [
"each.value.name",
"each.value"
]
},
"slug": {
"references": [
"each.key"
]
}
},
"schema_version": 0,
"for_each_expression": {
"references": [
"local.apps_map"
]
}
},
{
"address": "null_resource.dev",
"mode": "managed",
"type": "null_resource",
"name": "dev",
"provider_config_key": "null",
"schema_version": 0,
"depends_on": [
"coder_agent.dev"
]
}
]
}
},
"relevant_attributes": [
{
"resource": "coder_agent.dev",
"attribute": [
"id"
]
}
]
}

View File

@ -1,21 +0,0 @@
digraph {
compound = "true"
newrank = "true"
subgraph "root" {
"[root] coder_agent.dev (expand)" [label = "coder_agent.dev", shape = "box"]
"[root] coder_app.apps (expand)" [label = "coder_app.apps", shape = "box"]
"[root] null_resource.dev (expand)" [label = "null_resource.dev", shape = "box"]
"[root] provider[\"registry.terraform.io/coder/coder\"]" [label = "provider[\"registry.terraform.io/coder/coder\"]", shape = "diamond"]
"[root] provider[\"registry.terraform.io/hashicorp/null\"]" [label = "provider[\"registry.terraform.io/hashicorp/null\"]", shape = "diamond"]
"[root] coder_agent.dev (expand)" -> "[root] provider[\"registry.terraform.io/coder/coder\"]"
"[root] coder_app.apps (expand)" -> "[root] coder_agent.dev (expand)"
"[root] coder_app.apps (expand)" -> "[root] local.apps_map (expand)"
"[root] null_resource.dev (expand)" -> "[root] coder_agent.dev (expand)"
"[root] null_resource.dev (expand)" -> "[root] provider[\"registry.terraform.io/hashicorp/null\"]"
"[root] provider[\"registry.terraform.io/coder/coder\"] (close)" -> "[root] coder_app.apps (expand)"
"[root] provider[\"registry.terraform.io/hashicorp/null\"] (close)" -> "[root] null_resource.dev (expand)"
"[root] root" -> "[root] provider[\"registry.terraform.io/coder/coder\"] (close)"
"[root] root" -> "[root] provider[\"registry.terraform.io/hashicorp/null\"] (close)"
}
}

View File

@ -1,106 +0,0 @@
{
"format_version": "1.0",
"terraform_version": "1.3.7",
"values": {
"root_module": {
"resources": [
{
"address": "coder_agent.dev",
"mode": "managed",
"type": "coder_agent",
"name": "dev",
"provider_name": "registry.terraform.io/coder/coder",
"schema_version": 0,
"values": {
"arch": "amd64",
"auth": "token",
"connection_timeout": 120,
"dir": null,
"env": null,
"id": "9607dca1-bb3e-4606-849c-69d073b3b7d1",
"init_script": "",
"os": "linux",
"startup_script": null,
"token": "47b62747-82ad-4792-960a-e120a88d2bac",
"troubleshooting_url": null
},
"sensitive_values": {}
},
{
"address": "coder_app.apps[\"app1\"]",
"mode": "managed",
"type": "coder_app",
"name": "apps",
"index": "app1",
"provider_name": "registry.terraform.io/coder/coder",
"schema_version": 0,
"values": {
"agent_id": "9607dca1-bb3e-4606-849c-69d073b3b7d1",
"command": null,
"display_name": "app1",
"healthcheck": [],
"icon": null,
"id": "75b7232a-320f-462f-91c0-5542e655dce9",
"name": null,
"relative_path": null,
"share": "owner",
"slug": "app1",
"subdomain": null,
"url": null
},
"sensitive_values": {
"healthcheck": []
},
"depends_on": [
"coder_agent.dev"
]
},
{
"address": "coder_app.apps[\"app2\"]",
"mode": "managed",
"type": "coder_app",
"name": "apps",
"index": "app2",
"provider_name": "registry.terraform.io/coder/coder",
"schema_version": 0,
"values": {
"agent_id": "9607dca1-bb3e-4606-849c-69d073b3b7d1",
"command": null,
"display_name": "app2",
"healthcheck": [],
"icon": null,
"id": "30e8a682-a440-48a8-847d-525baa05783f",
"name": null,
"relative_path": null,
"share": "owner",
"slug": "app2",
"subdomain": null,
"url": null
},
"sensitive_values": {
"healthcheck": []
},
"depends_on": [
"coder_agent.dev"
]
},
{
"address": "null_resource.dev",
"mode": "managed",
"type": "null_resource",
"name": "dev",
"provider_name": "registry.terraform.io/hashicorp/null",
"schema_version": 0,
"values": {
"id": "6276937382685771643",
"triggers": null
},
"sensitive_values": {},
"depends_on": [
"coder_agent.dev"
]
}
]
}
}
}