@@ -2,16 +2,16 @@ package provider
2
2
3
3
import (
4
4
"context"
5
+ "crypto/sha256"
6
+ "encoding/hex"
5
7
"fmt"
6
- "os"
7
8
"path/filepath"
8
9
"reflect"
9
10
"strings"
10
11
11
- "github.com/hashicorp/terraform-plugin-log/tflog"
12
-
13
12
"github.com/google/uuid"
14
13
"github.com/hashicorp/go-cty/cty"
14
+ "github.com/hashicorp/terraform-plugin-log/tflog"
15
15
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
16
16
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
17
17
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
@@ -26,50 +26,34 @@ func agentResource() *schema.Resource {
26
26
27
27
Description : "Use this resource to associate an agent." ,
28
28
CreateContext : func (ctx context.Context , resourceData * schema.ResourceData , i interface {}) diag.Diagnostics {
29
- // This should be a real authentication token!
30
- resourceData .SetId (uuid . NewString () )
29
+ agentID := uuid . NewString ()
30
+ resourceData .SetId (agentID )
31
31
32
- // CODER_RUNNING_WORKSPACE_AGENT_TOKEN is *only* used for prebuilds. We pass it down when we want to rebuild a prebuilt workspace
33
- // but not generate a new agent token. The provisionerdserver will retrieve this token and push it down to
34
- // here where it will be reused.
35
- // Context: the agent token is often used in immutable attributes of workspace resource (e.g. VM/container)
36
- // to initialize the agent, so if that value changes it will necessitate a replacement of that resource, thus
37
- // obviating the whole point of the prebuild.
38
- //
39
- // The default path is for a new token to be generated on each new resource creation.
40
- // TODO: add logging when the running token is actually used.
41
- var token string
32
+ // Most of the time, we will generate a new token for the agent.
33
+ // In the case of a prebuilt workspace being claimed, we will override with
34
+ // an existing token provided below.
35
+ token := uuid .NewString ()
42
36
37
+ // If isPrebuild is true, then this workspace was built by the prebuilds system.
38
+ // This does not determine whether the workspace has been claimed by a user.
39
+ // At this point, it may or may not have been claimed.
43
40
isPrebuild := helpers .OptionalEnv (IsPrebuildEnvironmentVariable ()) == "true"
44
- if ! isPrebuild {
45
- token = os .Getenv (RunningAgentTokenEnvironmentVariable ())
46
- }
47
-
48
- allEnv := make (map [string ]interface {})
49
- for _ , v := range os .Environ () {
50
- split := strings .Split (v , "=" )
51
- var key , val string
52
- if len (split ) > 0 {
53
- key = split [0 ]
54
- }
55
- if len (split ) > 1 {
56
- val = split [1 ]
57
- }
58
-
59
- allEnv [key ] = val
41
+ // existingToken should only have been set if isPrebuild is true, because we only
42
+ // reuse the token when a prebuilt workspace is being claimed.
43
+ existingToken := helpers .OptionalEnv (RunningAgentTokenEnvironmentVariable (agentID ))
44
+ logFields := map [string ]interface {}{
45
+ "agent_id" : agentID ,
46
+ "is_prebuild" : isPrebuild ,
47
+ "token_provided" : existingToken != "" ,
60
48
}
61
-
62
- allEnv ["is_prebuild" ] = fmt .Sprintf ("%v" , isPrebuild )
63
-
64
- if token == "" {
65
- token = uuid .NewString ()
66
- if ! isPrebuild {
67
- tflog .Warn (ctx , "NOT USING EXISTING AGENT TOKEN" , allEnv )
68
- }
49
+ if isPrebuild && existingToken != "" {
50
+ // check if a token was already generated for this agent.
51
+ // If so, this workspace is in the process of being claimed
52
+ // and we should reuse the token. If not, we use a new token as usual.
53
+ tflog .Info (ctx , "using provided agent token for prebuild" , logFields )
54
+ token = existingToken
69
55
} else {
70
- if ! isPrebuild {
71
- tflog .Info (ctx , "IS USING EXISTING AGENT TOKEN" , allEnv )
72
- }
56
+ tflog .Info (ctx , "using a new agent token" , logFields )
73
57
}
74
58
75
59
err := resourceData .Set ("token" , token )
@@ -517,6 +501,15 @@ func updateInitScript(resourceData *schema.ResourceData, i interface{}) diag.Dia
517
501
return nil
518
502
}
519
503
520
- func RunningAgentTokenEnvironmentVariable () string {
521
- return "CODER_RUNNING_WORKSPACE_AGENT_TOKEN"
504
+ // RunningAgentTokenEnvironmentVariable returns the name of the environment variable
505
+ // that contains the token for the running agent. This is used for prebuilds, where
506
+ // we want to reuse the same token for the next iteration of a workspace agent before
507
+ // and after the workspace was claimed by a user.
508
+ //
509
+ // agentID is unused for now, but will be used as soon as we support multiple agents.
510
+ func RunningAgentTokenEnvironmentVariable (agentID string ) string {
511
+ agentID = "" // remove this once we need to support multiple agents per prebuilt workspace.
512
+
513
+ sum := sha256 .Sum256 ([]byte (agentID ))
514
+ return "CODER_RUNNING_WORKSPACE_AGENT_TOKEN_" + hex .EncodeToString (sum [:])
522
515
}
0 commit comments