diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index efbf664..6ce06ed 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -6,10 +6,12 @@ name: Tests on: pull_request: paths-ignore: - - 'README.md' + - "README.md" push: + branches: + - main paths-ignore: - - 'README.md' + - "README.md" # Testing only needs permissions to read the repository contents. permissions: @@ -25,7 +27,7 @@ jobs: - uses: actions/checkout@v4 - uses: actions/setup-go@v5 with: - go-version-file: 'go.mod' + go-version-file: "go.mod" cache: true - run: go mod download - run: go build -v . @@ -40,7 +42,7 @@ jobs: - uses: actions/checkout@v4 - uses: actions/setup-go@v5 with: - go-version-file: 'go.mod' + go-version-file: "go.mod" cache: true - run: go generate ./... - name: git diff @@ -59,20 +61,21 @@ jobs: matrix: # list whatever Terraform versions here you would like to support terraform: - - '1.0.*' - - '1.1.*' - - '1.2.*' - - '1.3.*' - - '1.4.*' + - "1.0.*" + - "1.1.*" + - "1.2.*" + - "1.3.*" + - "1.4.*" - "1.5.*" - "1.6.*" - "1.7.*" - "1.8.*" + - "1.9.*" steps: - uses: actions/checkout@v4 - uses: actions/setup-go@v5 with: - go-version-file: 'go.mod' + go-version-file: "go.mod" cache: true - uses: hashicorp/setup-terraform@v3 with: @@ -84,7 +87,6 @@ jobs: run: go test -v -cover ./internal/provider/ timeout-minutes: 10 - lint: name: Lint runs-on: ubuntu-latest @@ -98,7 +100,7 @@ jobs: - uses: hashicorp/setup-terraform@v3 with: - terraform_version: "1.8.*" + terraform_version: "1.9.*" terraform_wrapper: false - name: Check out code into the Go module directory diff --git a/go.mod b/go.mod index cfaade0..74566c7 100644 --- a/go.mod +++ b/go.mod @@ -1,13 +1,18 @@ module github.com/coder/terraform-provider-coderd -go 1.22.3 +go 1.22.4 + +toolchain go1.22.5 require ( + cdr.dev/slog v1.6.2-0.20240126064726-20367d4aede6 github.com/coder/coder/v2 v2.12.3 github.com/docker/docker v26.1.4+incompatible github.com/docker/go-connections v0.4.0 + github.com/google/uuid v1.6.0 github.com/hashicorp/terraform-plugin-docs v0.19.4 github.com/hashicorp/terraform-plugin-framework v1.10.0 + github.com/hashicorp/terraform-plugin-framework-validators v0.13.0 github.com/hashicorp/terraform-plugin-go v0.23.0 github.com/hashicorp/terraform-plugin-log v0.9.0 github.com/hashicorp/terraform-plugin-testing v1.8.0 @@ -15,7 +20,6 @@ require ( ) require ( - cdr.dev/slog v1.6.2-0.20240126064726-20367d4aede6 // indirect github.com/BurntSushi/toml v1.2.1 // indirect github.com/DataDog/appsec-internal-go v1.5.0 // indirect github.com/DataDog/datadog-agent/pkg/obfuscate v0.48.0 // indirect @@ -43,7 +47,7 @@ require ( github.com/cloudflare/circl v1.3.7 // indirect github.com/coder/pretty v0.0.0-20230908205945-e89ba86370e0 // indirect github.com/coder/serpent v0.7.0 // indirect - github.com/coder/terraform-provider-coder v0.22.0 // indirect + github.com/coder/terraform-provider-coder v0.23.0 // indirect github.com/containerd/log v0.1.0 // indirect github.com/coreos/go-oidc/v3 v3.10.0 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect @@ -61,7 +65,6 @@ require ( github.com/golang/protobuf v1.5.4 // indirect github.com/google/go-cmp v0.6.0 // indirect github.com/google/pprof v0.0.0-20230817174616-7a8ec2ada47b // indirect - github.com/google/uuid v1.6.0 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 // indirect github.com/hashicorp/cli v1.1.6 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect @@ -74,18 +77,17 @@ require ( github.com/hashicorp/go-uuid v1.0.3 // indirect github.com/hashicorp/go-version v1.7.0 // indirect github.com/hashicorp/hc-install v0.7.0 // indirect - github.com/hashicorp/hcl/v2 v2.20.1 // indirect + github.com/hashicorp/hcl/v2 v2.21.0 // indirect github.com/hashicorp/logutils v1.0.0 // indirect github.com/hashicorp/terraform-exec v0.21.0 // indirect github.com/hashicorp/terraform-json v0.22.1 // indirect - github.com/hashicorp/terraform-plugin-framework-validators v0.13.0 // indirect github.com/hashicorp/terraform-plugin-sdk/v2 v2.33.0 // indirect github.com/hashicorp/terraform-registry-address v0.2.3 // indirect github.com/hashicorp/terraform-svchost v0.1.1 // indirect github.com/hashicorp/yamux v0.1.1 // indirect github.com/huandu/xstrings v1.3.3 // indirect github.com/imdario/mergo v0.3.15 // indirect - github.com/klauspost/compress v1.17.7 // indirect + github.com/klauspost/compress v1.17.9 // indirect github.com/lucasb-eyer/go-colorful v1.2.0 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect @@ -121,7 +123,7 @@ require ( github.com/spf13/cast v1.6.0 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/tinylib/msgp v1.1.8 // indirect - github.com/valyala/fasthttp v1.54.0 // indirect + github.com/valyala/fasthttp v1.55.0 // indirect github.com/vmihailenco/msgpack v4.0.4+incompatible // indirect github.com/vmihailenco/msgpack/v5 v5.4.1 // indirect github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect @@ -141,21 +143,21 @@ require ( go.opentelemetry.io/otel/trace v1.27.0 // indirect go.opentelemetry.io/proto/otlp v1.2.0 // indirect go.uber.org/atomic v1.11.0 // indirect - golang.org/x/crypto v0.23.0 // indirect + golang.org/x/crypto v0.24.0 // indirect golang.org/x/exp v0.0.0-20240222234643-814bf88cf225 // indirect - golang.org/x/mod v0.17.0 // indirect - golang.org/x/net v0.25.0 // indirect + golang.org/x/mod v0.18.0 // indirect + golang.org/x/net v0.26.0 // indirect golang.org/x/oauth2 v0.20.0 // indirect golang.org/x/sync v0.7.0 // indirect - golang.org/x/sys v0.20.0 // indirect - golang.org/x/term v0.20.0 // indirect - golang.org/x/text v0.15.0 // indirect + golang.org/x/sys v0.21.0 // indirect + golang.org/x/term v0.21.0 // indirect + golang.org/x/text v0.16.0 // indirect golang.org/x/time v0.5.0 // indirect - golang.org/x/tools v0.21.0 // indirect + golang.org/x/tools v0.22.0 // indirect golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 // indirect google.golang.org/appengine v1.6.8 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20240520151616-dc85e6b867a5 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240515191416-fc5f0ca64291 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240521202816-d264139d666e // indirect google.golang.org/grpc v1.64.0 // indirect google.golang.org/protobuf v1.34.1 // indirect gopkg.in/DataDog/dd-trace-go.v1 v1.64.0 // indirect diff --git a/go.sum b/go.sum index c97b82c..b4c948b 100644 --- a/go.sum +++ b/go.sum @@ -87,8 +87,8 @@ github.com/coder/pretty v0.0.0-20230908205945-e89ba86370e0 h1:3A0ES21Ke+FxEM8CXx github.com/coder/pretty v0.0.0-20230908205945-e89ba86370e0/go.mod h1:5UuS2Ts+nTToAMeOjNlnHFkPahrtDkmpydBen/3wgZc= github.com/coder/serpent v0.7.0 h1:zGpD2GlF3lKIVkMjNGKbkip88qzd5r/TRcc30X/SrT0= github.com/coder/serpent v0.7.0/go.mod h1:REkJ5ZFHQUWFTPLExhXYZ1CaHFjxvGNRlLXLdsI08YA= -github.com/coder/terraform-provider-coder v0.22.0 h1:L72WFa9/6sc/nnXENPS8LpWi/2NBV+DRUW0WT//pEaU= -github.com/coder/terraform-provider-coder v0.22.0/go.mod h1:wMun9UZ9HT2CzF6qPPBup1odzBpVUc0/xSFoXgdI3tk= +github.com/coder/terraform-provider-coder v0.23.0 h1:DuNLWxhnGlXyG0g+OCAZRI6xd8+bJjIEnE4F3hYgA4E= +github.com/coder/terraform-provider-coder v0.23.0/go.mod h1:wMun9UZ9HT2CzF6qPPBup1odzBpVUc0/xSFoXgdI3tk= github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I= github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo= github.com/coreos/go-oidc/v3 v3.10.0 h1:tDnXHnLyiTVyT/2zLDGj09pFPkhND8Gl8lnTRhoEaJU= @@ -225,8 +225,8 @@ github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKe github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/hc-install v0.7.0 h1:Uu9edVqjKQxxuD28mR5TikkKDd/p55S8vzPC1659aBk= github.com/hashicorp/hc-install v0.7.0/go.mod h1:ELmmzZlGnEcqoUMKUuykHaPCIR1sYLYX+KSggWSKZuA= -github.com/hashicorp/hcl/v2 v2.20.1 h1:M6hgdyz7HYt1UN9e61j+qKJBqR3orTWbI1HKBJEdxtc= -github.com/hashicorp/hcl/v2 v2.20.1/go.mod h1:TZDqQ4kNKCbh1iJp99FdPiUaVDDUPivbqxZulxDYqL4= +github.com/hashicorp/hcl/v2 v2.21.0 h1:lve4q/o/2rqwYOgUg3y3V2YPyD1/zkCLGjIV74Jit14= +github.com/hashicorp/hcl/v2 v2.21.0/go.mod h1:62ZYHrXgPoX8xBnzl8QzbWq4dyDsDtfCRgIq1rbJEvA= github.com/hashicorp/logutils v1.0.0 h1:dLEQVugN8vlakKOUE3ihGLTZJRB4j+M2cdTm/ORI65Y= github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= github.com/hashicorp/terraform-exec v0.21.0 h1:uNkLAe95ey5Uux6KJdua6+cv8asgILFVWkd/RG0D2XQ= @@ -235,8 +235,6 @@ github.com/hashicorp/terraform-json v0.22.1 h1:xft84GZR0QzjPVWs4lRUwvTcPnegqlyS7 github.com/hashicorp/terraform-json v0.22.1/go.mod h1:JbWSQCLFSXFFhg42T7l9iJwdGXBYV8fmmD6o/ML4p3A= github.com/hashicorp/terraform-plugin-docs v0.19.4 h1:G3Bgo7J22OMtegIgn8Cd/CaSeyEljqjH3G39w28JK4c= github.com/hashicorp/terraform-plugin-docs v0.19.4/go.mod h1:4pLASsatTmRynVzsjEhbXZ6s7xBlUw/2Kt0zfrq8HxA= -github.com/hashicorp/terraform-plugin-framework v1.9.0 h1:caLcDoxiRucNi2hk8+j3kJwkKfvHznubyFsJMWfZqKU= -github.com/hashicorp/terraform-plugin-framework v1.9.0/go.mod h1:qBXLDn69kM97NNVi/MQ9qgd1uWWsVftGSnygYG1tImM= github.com/hashicorp/terraform-plugin-framework v1.10.0 h1:xXhICE2Fns1RYZxEQebwkB2+kXouLC932Li9qelozrc= github.com/hashicorp/terraform-plugin-framework v1.10.0/go.mod h1:qBXLDn69kM97NNVi/MQ9qgd1uWWsVftGSnygYG1tImM= github.com/hashicorp/terraform-plugin-framework-validators v0.13.0 h1:bxZfGo9DIUoLLtHMElsu+zwqI4IsMZQBRRy4iLzZJ8E= @@ -276,8 +274,8 @@ github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= -github.com/klauspost/compress v1.17.7 h1:ehO88t2UGzQK66LMdE8tibEd1ErmzZjNEqWkjLAKQQg= -github.com/klauspost/compress v1.17.7/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= +github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA= +github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg= github.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= @@ -425,8 +423,8 @@ github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4d github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= -github.com/valyala/fasthttp v1.54.0 h1:cCL+ZZR3z3HPLMVfEYVUMtJqVaui0+gu7Lx63unHwS0= -github.com/valyala/fasthttp v1.54.0/go.mod h1:6dt4/8olwq9QARP/TDuPmWyWcl4byhpvTJ4AAtcz+QM= +github.com/valyala/fasthttp v1.55.0 h1:Zkefzgt6a7+bVKHnu/YaYSOPfNYNisSVBo/unVCf8k8= +github.com/valyala/fasthttp v1.55.0/go.mod h1:NkY9JtkrpPKmgwV3HTaS2HWaJss9RSIsRVfcxxoHiOM= github.com/vmihailenco/msgpack v3.3.3+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk= github.com/vmihailenco/msgpack v4.0.4+incompatible h1:dSLoQfGFAo3F6OoNhwUmLwVgaUXK79GlxNBwueZn0xI= github.com/vmihailenco/msgpack v4.0.4+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk= @@ -450,8 +448,8 @@ github.com/yuin/goldmark-meta v1.1.0 h1:pWw+JLHGZe8Rk0EGsMVssiNb/AaPMHfSRszZeUei github.com/yuin/goldmark-meta v1.1.0/go.mod h1:U4spWENafuA7Zyg+Lj5RqK/MF+ovMYtBvXi1lBb2VP0= github.com/zclconf/go-cty v1.14.4 h1:uXXczd9QDGsgu0i/QFR/hzI5NYCHLf6NQw/atrbnhq8= github.com/zclconf/go-cty v1.14.4/go.mod h1:VvMs5i0vgZdhYawQNq5kePSpLAoz8u1xvZgrPIxfnZE= -github.com/zclconf/go-cty-debug v0.0.0-20191215020915-b22d67c1ba0b h1:FosyBZYxY34Wul7O/MSKey3txpPYyCqVO5ZyceuQJEI= -github.com/zclconf/go-cty-debug v0.0.0-20191215020915-b22d67c1ba0b/go.mod h1:ZRKQfBXbGkpdV6QMzT3rU1kSTAnfu1dO8dPKjYprgj8= +github.com/zclconf/go-cty-debug v0.0.0-20240509010212-0d6042c53940 h1:4r45xpDWB6ZMSMNJFMOjqrGHynW3DIBuR2H9j0ug+Mo= +github.com/zclconf/go-cty-debug v0.0.0-20240509010212-0d6042c53940/go.mod h1:CmBdvvj3nqzfzJ6nTCIwDTPZ56aVGvDrmztiO5g3qrM= github.com/zeebo/assert v1.3.0 h1:g7C04CbJuIDKNPFHmsk4hwZDO5O+kntRxzaUoNXj+IQ= github.com/zeebo/assert v1.3.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0= github.com/zeebo/errs v1.3.0 h1:hmiaKqgYZzcVgRL1Vkc1Mn2914BbzB0IBxs+ebeutGs= @@ -496,8 +494,8 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= -golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI= -golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= +golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI= +golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM= golang.org/x/exp v0.0.0-20240222234643-814bf88cf225 h1:LfspQV/FYTatPTr/3HzIcmiUFH7PGP+OQ6mgDYo3yuQ= golang.org/x/exp v0.0.0-20240222234643-814bf88cf225/go.mod h1:CxmFvTBINI24O/j8iY7H1xHzx2i4OsyguNBmN/uPtqc= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= @@ -505,8 +503,8 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA= -golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.18.0 h1:5+9lSbEzPSdWkH32vYPBwEpX8KwDbM52Ud9xBUvNlb0= +golang.org/x/mod v0.18.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -517,8 +515,8 @@ golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= -golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac= -golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= +golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ= +golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= golang.org/x/oauth2 v0.20.0 h1:4mQdhULixXKP1rwYBW0vAijoXnkTG0BLCDRzfe1idMo= golang.org/x/oauth2 v0.20.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -552,15 +550,15 @@ golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= -golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= +golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA= -golang.org/x/term v0.20.0 h1:VnkxpohqXaOBYJtBmEppKUG6mXpi+4O6purfc2+sMhw= -golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY= +golang.org/x/term v0.21.0 h1:WVXCp+/EBEHOj53Rvu+7KiT/iElMrO8ACK16SMZ3jaA= +golang.org/x/term v0.21.0/go.mod h1:ooXLefLobQVslOqselCNF4SxFAaoS6KujMbsGzSDmX0= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= @@ -568,8 +566,8 @@ golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk= -golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= +golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= @@ -580,8 +578,8 @@ golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.4.0/go.mod h1:UE5sM2OK9E/d67R0ANs2xJizIymRP5gJU295PvKXxjQ= -golang.org/x/tools v0.21.0 h1:qc0xYgIbsSDt9EyWz05J5wfa7LOVW0YTLOXrqdLAWIw= -golang.org/x/tools v0.21.0/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= +golang.org/x/tools v0.22.0 h1:gqSGLZqv+AI9lIQzniJ0nZDRG5GBPsSi+DRNHWNz6yA= +golang.org/x/tools v0.22.0/go.mod h1:aCwcsjqvq7Yqt6TNyX7QMU2enbQ/Gt0bo6krSeEri+c= 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= @@ -595,8 +593,8 @@ google.golang.org/genproto v0.0.0-20240401170217-c3f982113cda h1:wu/KJm9KJwpfHWh google.golang.org/genproto v0.0.0-20240401170217-c3f982113cda/go.mod h1:g2LLCvCeCSir/JJSWosk19BR4NVxGqHUC6rxIRsd7Aw= google.golang.org/genproto/googleapis/api v0.0.0-20240520151616-dc85e6b867a5 h1:P8OJ/WCl/Xo4E4zoe4/bifHpSmmKwARqyqE4nW6J2GQ= google.golang.org/genproto/googleapis/api v0.0.0-20240520151616-dc85e6b867a5/go.mod h1:RGnPtTG7r4i8sPlNyDeikXF99hMM+hN6QMm4ooG9g2g= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240515191416-fc5f0ca64291 h1:AgADTJarZTBqgjiUzRgfaBchgYB3/WFTC80GPwsMcRI= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240515191416-fc5f0ca64291/go.mod h1:EfXuqaE1J41VCDicxHzUDm+8rk+7ZdXzHV0IhO/I6s0= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240521202816-d264139d666e h1:Elxv5MwEkCI9f5SkoL6afed6NTdxaGoAo39eANBwHL8= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240521202816-d264139d666e/go.mod h1:EfXuqaE1J41VCDicxHzUDm+8rk+7ZdXzHV0IhO/I6s0= google.golang.org/grpc v1.64.0 h1:KH3VH9y/MgNQg1dE7b3XfVK0GsPSIzJwdF617gUSbvY= google.golang.org/grpc v1.64.0/go.mod h1:oxjF8E3FBnjp+/gVFYdWacaLDx9na1aqy9oovLpxQYg= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= diff --git a/integration/integration.go b/integration/integration.go new file mode 100644 index 0000000..08ea4ed --- /dev/null +++ b/integration/integration.go @@ -0,0 +1,120 @@ +package integration + +import ( + "context" + "fmt" + "io" + "net" + "net/url" + "os" + "testing" + "time" + + "github.com/coder/coder/v2/codersdk" + "github.com/docker/docker/api/types/container" + "github.com/docker/docker/api/types/image" + "github.com/docker/docker/client" + "github.com/docker/go-connections/nat" + + "github.com/stretchr/testify/require" +) + +func StartCoder(ctx context.Context, t *testing.T, name string) *codersdk.Client { + coderImg := os.Getenv("CODER_IMAGE") + if coderImg == "" { + coderImg = "ghcr.io/coder/coder" + } + + coderVersion := os.Getenv("CODER_VERSION") + if coderVersion == "" { + coderVersion = "latest" + } + + t.Logf("using coder image %s:%s", coderImg, coderVersion) + + cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation()) + require.NoError(t, err, "init docker client") + + p := randomPort(t) + t.Logf("random port is %d", p) + // Stand up a temporary Coder instance + puller, err := cli.ImagePull(ctx, coderImg+":"+coderVersion, image.PullOptions{}) + require.NoError(t, err, "pull coder image") + defer puller.Close() + _, err = io.Copy(os.Stderr, puller) + require.NoError(t, err, "pull coder image") + ctr, err := cli.ContainerCreate(ctx, &container.Config{ + Image: coderImg + ":" + coderVersion, + Env: []string{ + "CODER_HTTP_ADDRESS=0.0.0.0:3000", // Listen on all interfaces inside the container + "CODER_ACCESS_URL=http://localhost:3000", // Set explicitly to avoid creating try.coder.app URLs. + "CODER_IN_MEMORY=true", // We don't necessarily care about real persistence here. + "CODER_TELEMETRY_ENABLE=false", // Avoid creating noise. + }, + Labels: map[string]string{}, + ExposedPorts: map[nat.Port]struct{}{nat.Port("3000/tcp"): {}}, + }, &container.HostConfig{ + PortBindings: map[nat.Port][]nat.PortBinding{ + nat.Port("3000/tcp"): {{HostIP: "127.0.0.1", HostPort: fmt.Sprintf("%d", p)}}, + }, + }, nil, nil, "terraform-provider-coderd-"+name) + require.NoError(t, err, "create test deployment") + + t.Logf("created container %s\n", ctr.ID) + t.Cleanup(func() { // Make sure we clean up after ourselves. + // TODO: also have this execute if you Ctrl+C! + t.Logf("stopping container %s\n", ctr.ID) + _ = cli.ContainerRemove(ctx, ctr.ID, container.RemoveOptions{ + Force: true, + }) + }) + + err = cli.ContainerStart(ctx, ctr.ID, container.StartOptions{}) + require.NoError(t, err, "start container") + t.Logf("started container %s\n", ctr.ID) + + // nolint:gosec // For testing only. + var ( + testEmail = "testing@coder.com" + testPassword = "InsecurePassw0rd!" + testUsername = "testing" + ) + + // Perform first time setup + coderURL, err := url.Parse(fmt.Sprintf("http://localhost:%d", p)) + require.NoError(t, err, "parse coder URL") + client := codersdk.New(coderURL) + // Wait for container to come up + require.Eventually(t, func() bool { + _, err := client.BuildInfo(ctx) + if err != nil { + t.Logf("not ready yet: %s", err.Error()) + } + return err == nil + }, 10*time.Second, time.Second, "coder failed to become ready in time") + _, err = client.CreateFirstUser(ctx, codersdk.CreateFirstUserRequest{ + Email: testEmail, + Username: testUsername, + Password: testPassword, + }) + require.NoError(t, err, "create first user") + resp, err := client.LoginWithPassword(ctx, codersdk.LoginWithPasswordRequest{ + Email: testEmail, + Password: testPassword, + }) + require.NoError(t, err, "login to coder instance with password") + client.SetSessionToken(resp.SessionToken) + return client +} + +// randomPort is a helper function to find a free random port. +// Note that the OS may reallocate the port very quickly, so +// this is not _guaranteed_. +func randomPort(t *testing.T) int { + random, err := net.Listen("tcp", "127.0.0.1:0") + require.NoError(t, err, "failed to listen on localhost") + _ = random.Close() + tcpAddr, valid := random.Addr().(*net.TCPAddr) + require.True(t, valid, "random port address is not a *net.TCPAddr?!") + return tcpAddr.Port +} diff --git a/integration/integration_test.go b/integration/integration_test.go index a038274..ade6886 100644 --- a/integration/integration_test.go +++ b/integration/integration_test.go @@ -4,9 +4,6 @@ import ( "bytes" "context" "fmt" - "io" - "net" - "net/url" "os" "os/exec" "path/filepath" @@ -15,10 +12,6 @@ import ( "time" "github.com/coder/coder/v2/codersdk" - "github.com/docker/docker/api/types/container" - "github.com/docker/docker/api/types/image" - "github.com/docker/docker/client" - "github.com/docker/go-connections/nat" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -83,7 +76,7 @@ func TestIntegration(t *testing.T) { }, } { t.Run(tt.name, func(t *testing.T) { - client := startCoder(ctx, t, tt.name) + client := StartCoder(ctx, t, tt.name) wd, err := os.Getwd() require.NoError(t, err) srcDir := filepath.Join(wd, tt.name) @@ -136,103 +129,3 @@ dev_overrides { }) return tfrcPath } - -func startCoder(ctx context.Context, t *testing.T, name string) *codersdk.Client { - coderImg := os.Getenv("CODER_IMAGE") - if coderImg == "" { - coderImg = "ghcr.io/coder/coder" - } - - coderVersion := os.Getenv("CODER_VERSION") - if coderVersion == "" { - coderVersion = "latest" - } - - t.Logf("using coder image %s:%s", coderImg, coderVersion) - - cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation()) - require.NoError(t, err, "init docker client") - - p := randomPort(t) - t.Logf("random port is %d", p) - // Stand up a temporary Coder instance - puller, err := cli.ImagePull(ctx, coderImg+":"+coderVersion, image.PullOptions{}) - require.NoError(t, err, "pull coder image") - defer puller.Close() - _, err = io.Copy(os.Stderr, puller) - require.NoError(t, err, "pull coder image") - ctr, err := cli.ContainerCreate(ctx, &container.Config{ - Image: coderImg + ":" + coderVersion, - Env: []string{ - "CODER_HTTP_ADDRESS=0.0.0.0:3000", // Listen on all interfaces inside the container - "CODER_ACCESS_URL=http://localhost:3000", // Set explicitly to avoid creating try.coder.app URLs. - "CODER_IN_MEMORY=true", // We don't necessarily care about real persistence here. - "CODER_TELEMETRY_ENABLE=false", // Avoid creating noise. - }, - Labels: map[string]string{}, - ExposedPorts: map[nat.Port]struct{}{nat.Port("3000/tcp"): {}}, - }, &container.HostConfig{ - PortBindings: map[nat.Port][]nat.PortBinding{ - nat.Port("3000/tcp"): {{HostIP: "127.0.0.1", HostPort: fmt.Sprintf("%d", p)}}, - }, - }, nil, nil, "terraform-provider-coderd-"+name) - require.NoError(t, err, "create test deployment") - - t.Logf("created container %s\n", ctr.ID) - t.Cleanup(func() { // Make sure we clean up after ourselves. - // TODO: also have this execute if you Ctrl+C! - t.Logf("stopping container %s\n", ctr.ID) - _ = cli.ContainerRemove(ctx, ctr.ID, container.RemoveOptions{ - Force: true, - }) - }) - - err = cli.ContainerStart(ctx, ctr.ID, container.StartOptions{}) - require.NoError(t, err, "start container") - t.Logf("started container %s\n", ctr.ID) - - // nolint:gosec // For testing only. - var ( - testEmail = "testing@coder.com" - testPassword = "InsecurePassw0rd!" - testUsername = "testing" - ) - - // Perform first time setup - coderURL, err := url.Parse(fmt.Sprintf("http://localhost:%d", p)) - require.NoError(t, err, "parse coder URL") - client := codersdk.New(coderURL) - // Wait for container to come up - require.Eventually(t, func() bool { - _, err := client.BuildInfo(ctx) - if err != nil { - t.Logf("not ready yet: %s", err.Error()) - } - return err == nil - }, 10*time.Second, time.Second, "coder failed to become ready in time") - _, err = client.CreateFirstUser(ctx, codersdk.CreateFirstUserRequest{ - Email: testEmail, - Username: testUsername, - Password: testPassword, - }) - require.NoError(t, err, "create first user") - resp, err := client.LoginWithPassword(ctx, codersdk.LoginWithPasswordRequest{ - Email: testEmail, - Password: testPassword, - }) - require.NoError(t, err, "login to coder instance with password") - client.SetSessionToken(resp.SessionToken) - return client -} - -// randomPort is a helper function to find a free random port. -// Note that the OS may reallocate the port very quickly, so -// this is not _guaranteed_. -func randomPort(t *testing.T) int { - random, err := net.Listen("tcp", "127.0.0.1:0") - require.NoError(t, err, "failed to listen on localhost") - _ = random.Close() - tcpAddr, valid := random.Addr().(*net.TCPAddr) - require.True(t, valid, "random port address is not a *net.TCPAddr?!") - return tcpAddr.Port -} diff --git a/internal/provider/user_resource_test.go b/internal/provider/user_resource_test.go index eaf720c..54e2b1e 100644 --- a/internal/provider/user_resource_test.go +++ b/internal/provider/user_resource_test.go @@ -3,30 +3,44 @@ package provider -/* import ( + "context" "fmt" "strings" "testing" + "text/template" + "github.com/coder/terraform-provider-coderd/integration" "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/stretchr/testify/require" ) func TestAccUserResource(t *testing.T) { + ctx := context.Background() + client := integration.StartCoder(ctx, t, "user_acc") + + cfg1 := testAccUserResourceConfig{ + URL: client.URL.String(), + Token: client.SessionToken(), + Username: PtrTo("example"), + Name: PtrTo("Example User"), + Email: PtrTo("example@coder.com"), + Roles: PtrTo([]string{"owner", "auditor"}), + LoginType: PtrTo("password"), + Password: PtrTo("SomeSecurePassword!"), + } + + cfg2 := cfg1 + cfg2.Username = PtrTo("exampleNew") + cfg2.Name = PtrTo("Example User New") + resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, ProtoV6ProviderFactories: testAccProtoV6ProviderFactories, Steps: []resource.TestStep{ // Create and Read testing { - Config: testAccUserResourceConfig{ - Username: "example", - Name: "Example User", - Email: "example@coder.com", - Roles: []string{"owner", "auditor"}, - LoginType: "password", - Password: "SomeSecurePassword!", - }.String(), + Config: cfg1.String(t), Check: resource.ComposeAggregateTestCheckFunc( resource.TestCheckResourceAttr("coderd_user.test", "username", "example"), resource.TestCheckResourceAttr("coderd_user.test", "name", "Example User"), @@ -44,22 +58,12 @@ func TestAccUserResource(t *testing.T) { ResourceName: "coderd_user.test", ImportState: true, ImportStateVerify: true, - // This is not normally necessary, but is here because this - // example code does not have an actual upstream service. - // Once the Read method is able to refresh information from - // the upstream service, this can be removed. - ImportStateVerifyIgnore: []string{"configurable_attribute", "defaulted", "password"}, + // We can't pull the password from the API. + ImportStateVerifyIgnore: []string{"password"}, }, // Update and Read testing { - Config: testAccUserResourceConfig{ - Username: "exampleNew", - Name: "Example User New", - Email: "example@coder.com", - Roles: []string{"owner", "auditor"}, - LoginType: "password", - Password: "SomeSecurePassword!", - }.String(), + Config: cfg2.String(t), Check: resource.ComposeAggregateTestCheckFunc( resource.TestCheckResourceAttr("coderd_user.test", "username", "exampleNew"), resource.TestCheckResourceAttr("coderd_user.test", "name", "Example User New"), @@ -71,40 +75,78 @@ func TestAccUserResource(t *testing.T) { } type testAccUserResourceConfig struct { - Username string - Name string - Email string - Roles []string - LoginType string - Password string - Suspended bool + URL string + Token string + + Username *string + Name *string + Email *string + Roles *[]string + LoginType *string + Password *string + Suspended *bool } -func (c testAccUserResourceConfig) String() string { - sb := strings.Builder{} - sb.WriteString(`resource "coderd_user" "test" {` + "\n") - sb.WriteString(fmt.Sprintf(" username = %q\n", c.Username)) - if c.Name != "" { - sb.WriteString(fmt.Sprintf(" name = %q\n", c.Name)) - } - sb.WriteString(fmt.Sprintf(" email = %q\n", c.Email)) - if len(c.Roles) > 0 { - rolesQuoted := make([]string, len(c.Roles)) - for i, role := range c.Roles { - rolesQuoted[i] = fmt.Sprintf("%q", role) - } - sb.WriteString(fmt.Sprintf(" roles = [%s]\n", strings.Join(rolesQuoted, ", "))) - } - if c.LoginType != "" { - sb.WriteString(fmt.Sprintf(" login_type = %q\n", c.LoginType)) - } - if c.Password != "" { - sb.WriteString(fmt.Sprintf(" password = %q\n", c.Password)) - } - if c.Suspended { - sb.WriteString(" suspended = true\n") +func (c testAccUserResourceConfig) String(t *testing.T) string { + tpl := ` +provider coderd { + url = "{{.URL}}" + token = "{{.Token}}" +} + +resource "coderd_user" "test" { + username = {{orNull .Username}} + name = {{orNull .Name}} + email = {{orNull .Email}} + roles = {{orNull .Roles}} + login_type = {{orNull .LoginType}} + password = {{orNull .Password}} + suspended = {{orNull .Suspended}} +} +` + // Define template functions + funcMap := template.FuncMap{ + "orNull": func(v interface{}) string { + if v == nil { + return "null" + } + switch value := v.(type) { + case *string: + if value == nil { + return "null" + } + return fmt.Sprintf("%q", *value) + case *bool: + if value == nil { + return "null" + } + return fmt.Sprintf(`%t`, *value) + case *[]string: + if value == nil { + return "null" + } + var result string + for i, role := range *value { + if i > 0 { + result += ", " + } + result += fmt.Sprintf("%q", role) + } + return fmt.Sprintf("[%s]", result) + + default: + require.NoError(t, fmt.Errorf("unknown type in template: %T", value)) + return "" + } + }, } - sb.WriteString(`}`) - return sb.String() + + buf := strings.Builder{} + tmpl, err := template.New("test").Funcs(funcMap).Parse(tpl) + require.NoError(t, err) + + err = tmpl.Execute(&buf, c) + require.NoError(t, err) + + return buf.String() } -*/ diff --git a/internal/provider/util.go b/internal/provider/util.go new file mode 100644 index 0000000..c9fbc9f --- /dev/null +++ b/internal/provider/util.go @@ -0,0 +1,5 @@ +package provider + +func PtrTo[T any](v T) *T { + return &v +}
Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.
Alternative Proxies: