-
Notifications
You must be signed in to change notification settings - Fork 52
feat(opentofu-agent): add OpenTofu Agent support #1966
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 our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
10f0c83
522e9c8
2bc200c
600ddd8
b9e2ad0
c02ab7a
54834ae
37e4c74
0045661
4e73fc3
220991d
a47e417
278dded
afefea1
5ea42e5
b1e23cb
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -26,6 +26,7 @@ jobs: | |
| agent: | ||
| - docker | ||
| - kubernetes | ||
| - opentofu | ||
| permissions: | ||
| contents: read | ||
| steps: | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -6,6 +6,7 @@ | |
| /out-tsc | ||
| /bazel-out | ||
| hub | ||
| opentofu | ||
|
|
||
| # Node | ||
| /node_modules | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,32 @@ | ||
| FROM golang:1.26 AS builder | ||
| ARG TARGETOS | ||
| ARG TARGETARCH | ||
| ARG VERSION | ||
| ARG COMMIT | ||
|
|
||
| WORKDIR /workspace | ||
| COPY go.mod go.mod | ||
| COPY go.sum go.sum | ||
| RUN go mod download | ||
|
|
||
| COPY api/ api/ | ||
| COPY cmd/agent/opentofu/ cmd/agent/opentofu/ | ||
| # doesn't exist (yet?) | ||
| # COPY pkg/ pkg/ | ||
| COPY internal/ internal/ | ||
| RUN CGO_ENABLED=0 GOOS=${TARGETOS:-linux} GOARCH=${TARGETARCH} \ | ||
| go build -a -o agent \ | ||
| -ldflags="-s -w -X github.com/distr-sh/distr/internal/buildconfig.version=${VERSION:-snapshot} -X github.com/distr-sh/distr/internal/buildconfig.commit=${COMMIT}" \ | ||
| ./cmd/agent/opentofu/ | ||
|
|
||
| FROM alpine:3.21 | ||
| COPY --from=ghcr.io/opentofu/opentofu:1.9 /usr/local/bin/tofu /usr/local/bin/tofu | ||
| WORKDIR / | ||
| COPY --from=builder /workspace/agent . | ||
| RUN addgroup -S agent && adduser -S agent -G agent && \ | ||
| mkdir -p /scratch && chown agent:agent /scratch | ||
| USER agent | ||
| ENV TF_IN_AUTOMATION=1 | ||
| ENV TF_INPUT=0 | ||
| ENV TF_PLUGIN_CACHE_DIR=/scratch/plugin-cache | ||
| ENTRYPOINT ["/agent"] |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,117 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| package main | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "encoding/json" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "errors" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "os" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "path/filepath" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "sync" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "github.com/distr-sh/distr/api" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "github.com/google/uuid" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| type State string | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| StateUnspecified State = "" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| StateInstalling State = "installing" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| StateInstalled State = "installed" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| StateFailed State = "failed" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| type AgentDeployment struct { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ID uuid.UUID `json:"id"` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| RevisionID uuid.UUID `json:"revisionId"` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| TofuConfigURL string `json:"tofuConfigUrl"` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| TofuConfigVersion string `json:"tofuConfigVersion"` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| TofuBackendConfig map[string]string `json:"tofuBackendConfig,omitempty"` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| State State `json:"phase"` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+29
to
+31
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| State State `json:"phase"` | |
| } | |
| State State `json:"state"` | |
| } | |
| type agentDeploymentJSON struct { | |
| ID uuid.UUID `json:"id"` | |
| RevisionID uuid.UUID `json:"revisionId"` | |
| TofuConfigURL string `json:"tofuConfigUrl"` | |
| TofuConfigVersion string `json:"tofuConfigVersion"` | |
| TofuVersion string `json:"tofuVersion,omitempty"` | |
| TofuBackendConfig map[string]string `json:"tofuBackendConfig,omitempty"` | |
| State State `json:"state,omitempty"` | |
| Phase State `json:"phase,omitempty"` | |
| } | |
| func (d AgentDeployment) MarshalJSON() ([]byte, error) { | |
| aux := agentDeploymentJSON{ | |
| ID: d.ID, | |
| RevisionID: d.RevisionID, | |
| TofuConfigURL: d.TofuConfigURL, | |
| TofuConfigVersion: d.TofuConfigVersion, | |
| TofuVersion: d.TofuVersion, | |
| TofuBackendConfig: d.TofuBackendConfig, | |
| State: d.State, | |
| } | |
| return json.Marshal(aux) | |
| } | |
| func (d *AgentDeployment) UnmarshalJSON(data []byte) error { | |
| var aux agentDeploymentJSON | |
| if err := json.Unmarshal(data, &aux); err != nil { | |
| return err | |
| } | |
| d.ID = aux.ID | |
| d.RevisionID = aux.RevisionID | |
| d.TofuConfigURL = aux.TofuConfigURL | |
| d.TofuConfigVersion = aux.TofuConfigVersion | |
| d.TofuVersion = aux.TofuVersion | |
| d.TofuBackendConfig = aux.TofuBackendConfig | |
| if aux.State != StateUnspecified { | |
| d.State = aux.State | |
| } else { | |
| d.State = aux.Phase | |
| } | |
| return nil | |
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This follows the existing Docker agent pattern which also uses json:"phase" for the State field. Keeping it consistent across agents.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| package main | ||
|
|
||
| import ( | ||
| "os" | ||
| "path/filepath" | ||
|
|
||
| "github.com/google/uuid" | ||
| ) | ||
|
|
||
| func ScratchDir() string { | ||
| if dir := os.Getenv("DISTR_AGENT_SCRATCH_DIR"); dir != "" { | ||
| return dir | ||
| } | ||
| return "./scratch" | ||
| } | ||
|
|
||
| func WorkspaceDir(deploymentID uuid.UUID) string { | ||
| return filepath.Join(ScratchDir(), "ws", deploymentID.String()) | ||
| } | ||
|
|
||
| func DeploymentsDir() string { | ||
| return filepath.Join(ScratchDir(), "deployments") | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OpenTofuEnabledis added as a non-pointerboolon the create/update request. For update endpoints this is a backward-compatibility footgun: older clients that don’t send the new field will decode it asfalseand can unintentionally disable the feature. Consider making this field a*bool(apply only when non-nil) or separating create vs update request shapes.