Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

fix: Add tests for instance and app association#2198

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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged
kylecarbs merged 1 commit intomainfrominstanceassociation
Jun 9, 2022
Merged
Show file tree
Hide file tree
Changes fromall 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
71 changes: 70 additions & 1 deletionprovisioner/terraform/resources.go
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -120,17 +120,86 @@ func ConvertResources(module *tfjson.StateModule, rawGraph string) ([]*proto.Res
}
}

type appAttributes struct {
AgentID string `mapstructure:"agent_id"`
Name string `mapstructure:"name"`
Icon string `mapstructure:"icon"`
URL string `mapstructure:"url"`
Command string `mapstructure:"command"`
RelativePath bool `mapstructure:"relative_path"`
}
// Associate Apps with agents.
for _, resource := range tfResources {
if resource.Type != "coder_app" {
continue
}
var attrs appAttributes
err = mapstructure.Decode(resource.AttributeValues, &attrs)
if err != nil {
return nil, xerrors.Errorf("decode app attributes: %w", err)
}
if attrs.Name == "" {
// Default to the resource name if none is set!
attrs.Name = resource.Name
}
for _, agent := range agents {
if agent.Id != attrs.AgentID {
continue
}
agent.Apps = append(agent.Apps, &proto.App{
Name: attrs.Name,
Command: attrs.Command,
Url: attrs.URL,
Icon: attrs.Icon,
RelativePath: attrs.RelativePath,
})
}
}

for _, resource := range tfResources {
if resource.Mode == tfjson.DataResourceMode {
continue
}
if resource.Type == "coder_agent" || resource.Type == "coder_agent_instance" || resource.Type == "coder_app" {
continue
}
agents := findAgents(resourceDependencies, agents, convertAddressToLabel(resource.Address))
for _, agent := range agents {
// Didn't use instance identity.
if agent.GetToken() != "" {
continue
}

// These resource types are for automatically associating an instance ID
// with an agent for authentication.
key, isValid := map[string]string{
"google_compute_instance": "instance_id",
"aws_instance": "id",
"azurerm_linux_virtual_machine": "id",
"azurerm_windows_virtual_machine": "id",
}[resource.Type]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

So I'm still pretty noobish when it comes to Terraform, but it seems like we're automatically mapping these resource types forall agents. So for instance if there's both agoogle_compute_instance, and anaws_instance, one would overwrite the other?

I'm sure the above wouldn't be a common use case, but I imagine it would be possible to create a semi-complex Terraform template with multiple providers depending on certain selections? And I imagine this would be a use-case for having multiple agents, are there others?

If my questions make no sense, feel free to disregard 😄

Copy link
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

If my questions make no sense, feel free to disregard 😄

All questions I'm happy to answer!

So for instance if there's both a google_compute_instance, and an aws_instance, one would overwrite the other?

There's a one -> many mapping of resource to agent. If a resource isn't using token authentication, we assume it's using the zero-trust providers we support:*-instance-identity under theauth parameter on an agent. An instance ID can be manually associated with thecoder_agent_instance resource, but we automatically associate it with one of the listed resource types. There isn't an explicit reason we need to do this, and it might end up adding more confusion, so it's not impossible we remove it at some point.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Ok, thanks for clarifying@kylecarbs! I don't think we need to make any changes to it at this point, but good to be aware of it.

if !isValid {
// The resource type doesn't support
// automatically setting the instance ID.
continue
}
instanceIDRaw, valid := resource.AttributeValues[key]
if !valid {
continue
}
instanceID, valid := instanceIDRaw.(string)
if !valid {
continue
}
agent.Auth = &proto.Agent_InstanceId{
InstanceId: instanceID,
}
}

resources = append(resources, &proto.Resource{
Name: resource.Name,
Type: resource.Type,
Agents:findAgents(resourceDependencies,agents, convertAddressToLabel(resource.Address)),
Agents: agents,
})
}

Expand Down
82 changes: 82 additions & 0 deletionsprovisioner/terraform/resources_test.go
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -11,6 +11,7 @@ import (
tfjson "github.com/hashicorp/terraform-json"
"github.com/stretchr/testify/require"

"github.com/coder/coder/cryptorand"
"github.com/coder/coder/provisioner/terraform"
"github.com/coder/coder/provisionersdk/proto"
)
Expand DownExpand Up@@ -74,6 +75,21 @@ func TestConvertResources(t *testing.T) {
Auth: &proto.Agent_Token{},
}},
}},
"multiple-apps": {{
Name: "dev",
Type: "null_resource",
Agents: []*proto.Agent{{
Name: "dev1",
OperatingSystem: "linux",
Architecture: "amd64",
Apps: []*proto.App{{
Name: "app1",
}, {
Name: "app2",
}},
Auth: &proto.Agent_Token{},
}},
}},
} {
folderName := folderName
expected := expected
Expand DownExpand Up@@ -140,3 +156,69 @@ func TestConvertResources(t *testing.T) {
})
}
}

func TestInstanceIDAssociation(t *testing.T) {
t.Parallel()
type tc struct {
Auth string
ResourceType string
InstanceIDKey string
}
for _, tc := range []tc{{
Auth: "google-instance-identity",
ResourceType: "google_compute_instance",
InstanceIDKey: "instance_id",
}, {
Auth: "aws-instance-identity",
ResourceType: "aws_instance",
InstanceIDKey: "id",
}, {
Auth: "azure-instance-identity",
ResourceType: "azurerm_linux_virtual_machine",
InstanceIDKey: "id",
}, {
Auth: "azure-instance-identity",
ResourceType: "azurerm_windows_virtual_machine",
InstanceIDKey: "id",
}} {
tc := tc
t.Run(tc.ResourceType, func(t *testing.T) {
t.Parallel()
instanceID, err := cryptorand.String(12)
require.NoError(t, err)
resources, err := terraform.ConvertResources(&tfjson.StateModule{
Resources: []*tfjson.StateResource{{
Address: "coder_agent.dev",
Type: "coder_agent",
Name: "dev",
AttributeValues: map[string]interface{}{
"arch": "amd64",
"auth": tc.Auth,
},
}, {
Address: tc.ResourceType + ".dev",
Type: tc.ResourceType,
Name: "dev",
DependsOn: []string{"coder_agent.dev"},
AttributeValues: map[string]interface{}{
tc.InstanceIDKey: instanceID,
},
}},
// This is manually created to join the edges.
}, `digraph {
compound = "true"
newrank = "true"
subgraph "root" {
"[root] coder_agent.dev" [label = "coder_agent.dev", shape = "box"]
"[root] `+tc.ResourceType+`.dev" [label = "`+tc.ResourceType+`.dev", shape = "box"]
"[root] `+tc.ResourceType+`.dev" -> "[root] coder_agent.dev"
}
}
`)
require.NoError(t, err)
require.Len(t, resources, 1)
require.Len(t, resources[0].Agents, 1)
require.Equal(t, resources[0].Agents[0].GetInstanceId(), instanceID)
})
}
}
View file
Open in desktop

Some generated files are not rendered by default. Learn more abouthow customized files appear on GitHub.

View file
Open in desktop

Some generated files are not rendered by default. Learn more abouthow customized files appear on GitHub.

View file
Open in desktop

Some generated files are not rendered by default. Learn more abouthow customized files appear on GitHub.

View file
Open in desktop

Some generated files are not rendered by default. Learn more abouthow customized files appear on GitHub.

27 changes: 27 additions & 0 deletionsprovisioner/terraform/testdata/multiple-apps/multiple-apps.tf
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
terraform {
required_providers {
coder = {
source = "coder/coder"
version = "0.4.2"
}
}
}

resource "coder_agent" "dev1" {
os = "linux"
arch = "amd64"
}

resource "coder_app" "app1" {
agent_id = coder_agent.dev1.id
}

resource "coder_app" "app2" {
agent_id = coder_agent.dev1.id
}

resource "null_resource" "dev" {
depends_on = [
coder_agent.dev1
]
}
View file
Open in desktop

Some generated files are not rendered by default. Learn more abouthow customized files appear on GitHub.

Loading

[8]ページ先頭

©2009-2025 Movatter.jp