diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 64fe45d..e7d4f49 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -28,7 +28,7 @@ jobs: name: Set up Go uses: actions/setup-go@v2 with: - go-version: 1.14 + go-version: 1.16 - name: Import GPG key id: import_gpg diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..5175336 --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,41 @@ +name: test +on: + pull_request: + paths-ignore: + - 'README.md' + push: + paths-ignore: + - 'README.md' +jobs: + golangci: + name: lint + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: golangci-lint + uses: golangci/golangci-lint-action@v2 + with: + version: v1.41 + check: + runs-on: ubuntu-latest + steps: + - name: Setup Go + uses: actions/setup-go@v2 + with: + go-version: 1.16 + - name: Checkout + uses: actions/checkout@v2 + + - name: Get dependencies + run: go mod download + + - name: Check mod + run: make check-mod + + - name: Check doc + run: make check-docs + + - name: Test + run: make test + +# todo: add acceptance tests diff --git a/Makefile b/Makefile index 86c3d9f..fe2f8e3 100644 --- a/Makefile +++ b/Makefile @@ -7,8 +7,8 @@ help: .PHONY: vendor vendor: go.sum ## vendor dependencies - @GO111MODULE=on go mod vendor - @GO111MODULE=on go mod tidy + @go mod vendor + @go mod tidy .PHONY: lint lint: ## run linter @@ -38,3 +38,7 @@ check-docs: docs ## check that docs have been generated check-mod: ## check go.mod is up-to-date @go mod tidy @git diff --exit-code -- go.mod go.sum + +.PHONY: install +install: + @go build -o ~/.terraform.d/plugins/registry.terraform.io/hirosassa/looker/${VERSION}/darwin_amd64/terraform-provider-looker diff --git a/README.MD b/README.md similarity index 78% rename from README.MD rename to README.md index da4a2ad..91b77c5 100644 --- a/README.MD +++ b/README.md @@ -12,8 +12,8 @@ You can use [Explicit Provider Source Locations](https://www.terraform.io/upgrad terraform { required_providers { looker = { - source = "DevotedHealth/looker" - version = "0.1.0" + source = "hirosassa/looker" + version = "0.3.0" } } } @@ -21,4 +21,4 @@ terraform { ## Usage -In-depth docs are available [on the Terraform registry](https://registry.terraform.io/providers/DevotedHealth/looker/latest). +In-depth docs are available [on the Terraform registry](https://registry.terraform.io/providers/hirosassa/looker/latest). diff --git a/VERSION b/VERSION index 341cf11..0d91a54 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.2.0 \ No newline at end of file +0.3.0 diff --git a/docs/resources/group_membership.md b/docs/resources/group_membership.md new file mode 100644 index 0000000..962d835 --- /dev/null +++ b/docs/resources/group_membership.md @@ -0,0 +1,34 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "looker_group_membership Resource - terraform-provider-looker" +subcategory: "" +description: |- + +--- + +# looker_group_membership (Resource) + + + +## Example Usage + +```terraform +resource "looker_group_membership" "group_membership" { + group_id = looker_group.group.id + user_id = looker_user.user.id +} +``` + + +## Schema + +### Required + +- **group_id** (String) +- **user_id** (String) + +### Optional + +- **id** (String) The ID of this resource. + + diff --git a/examples/resources/looker_group_membership/resource.tf b/examples/resources/looker_group_membership/resource.tf new file mode 100644 index 0000000..9e72abd --- /dev/null +++ b/examples/resources/looker_group_membership/resource.tf @@ -0,0 +1,4 @@ +resource "looker_group_membership" "group_membership" { + group_id = looker_group.group.id + user_id = looker_user.user.id +} diff --git a/go.mod b/go.mod index f9a4106..792d318 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ -module github.com/DevotedHealth/terraform-provider-looker +module github.com/hirosassa/terraform-provider-looker -go 1.15 +go 1.16 require ( github.com/aws/aws-sdk-go v1.34.28 // indirect @@ -9,6 +9,9 @@ require ( github.com/looker-open-source/sdk-codegen/go v0.0.1 github.com/mitchellh/mapstructure v1.3.3 // indirect github.com/smartystreets/goconvey v1.6.4 // indirect - golang.org/x/text v0.3.5 // indirect + github.com/stretchr/testify v1.6.1 + golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d // indirect + golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c // indirect + golang.org/x/tools v0.1.5 // indirect gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 // indirect ) diff --git a/go.sum b/go.sum index fde766d..4f04b01 100644 --- a/go.sum +++ b/go.sum @@ -44,10 +44,8 @@ github.com/agext/levenshtein v1.2.1/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki github.com/agext/levenshtein v1.2.2 h1:0S/Yg6LYmFJ5stwQeRp6EeOcCbj7xiqQSdNelsXvaqE= github.com/agext/levenshtein v1.2.2/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558= github.com/agl/ed25519 v0.0.0-20170116200512-5312a6153412/go.mod h1:WPjqKcmVOxf0XSf3YxCJs6N6AOSrOx3obionmG7T0y0= -github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7 h1:uSoVVbwJiQipAclBbw+8quDsfcvFjOpI5iCf4p/cqCs= github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7/go.mod h1:6zEj6s6u/ghQa61ZWa/C2Aw3RkjiTBOix7dkqa1VLIs= github.com/andybalholm/crlf v0.0.0-20171020200849-670099aa064f/go.mod h1:k8feO4+kXDxro6ErPXBRTJ/ro2mf0SsFG8s7doP9kJE= -github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239 h1:kFOfPq6dUM1hTo4JG6LR5AXSUEsOjtdm0kw0FtQtMJA= github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= github.com/apparentlymart/go-cidr v1.0.1 h1:NmIwLZ/KdsjIUlhf+/Np40atNXm/+lZ5txfTJ/SpF+U= github.com/apparentlymart/go-cidr v1.0.1/go.mod h1:EBcsNrHc3zQeuaeCeCtQruQm+n9/YjEn/vI25Lg7Gwc= @@ -60,7 +58,6 @@ github.com/apparentlymart/go-textseg/v12 v12.0.0 h1:bNEQyAGak9tojivJNkoqWErVCQbj github.com/apparentlymart/go-textseg/v12 v12.0.0/go.mod h1:S/4uRK2UtaQttw1GenVJEynmyUenKwP++x/+DdGV/Ec= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310 h1:BUAU3CGlLvorLI26FmByPp2eC2qla6E1Tw+scpcg/to= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= -github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= github.com/aws/aws-sdk-go v1.15.78/go.mod h1:E3/ieXAlvM0XWO57iftYVDLLvQ824smPP3ATZkfNZeM= github.com/aws/aws-sdk-go v1.25.3/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= @@ -89,15 +86,12 @@ github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1m github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= -github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568 h1:BHsljHzVlRcyQhjrss6TZTdY2VfCqZPbv5k3iBFa2ZQ= github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= -github.com/gliderlabs/ssh v0.2.2 h1:6zsha5zo/TWhRhwqCD3+EarCAgZ2yN28ipRnGPnwkI0= github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= github.com/go-git/gcfg v1.5.0 h1:Q5ViNfGF8zFgyJWPqYwA7qGFoMTEiBmdlkcfRmpIMa4= github.com/go-git/gcfg v1.5.0/go.mod h1:5m20vg6GwYabIxaOonVkTdrILxQMpEShl1xiMF4ua+E= github.com/go-git/go-billy/v5 v5.0.0 h1:7NQHvd9FVid8VL4qVUMm8XifBK+2xCoZ2lSk0agRrHM= github.com/go-git/go-billy/v5 v5.0.0/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0= -github.com/go-git/go-git-fixtures/v4 v4.0.1 h1:q+IFMfLx200Q3scvt2hN79JsEzy4AmBTp/pqnefH+Bc= github.com/go-git/go-git-fixtures/v4 v4.0.1/go.mod h1:m+ICp2rF3jDhFgEZ/8yziagdT1C+ZpZcrJjappBCDSw= github.com/go-git/go-git/v5 v5.1.0 h1:HxJn9g/E7eYvKW3Fm7Jt4ee8LXfPOm/H1cdDu8vEssk= github.com/go-git/go-git/v5 v5.1.0/go.mod h1:ZKfuPUoY1ZqIG4QG9BDBh3G4gLM5zvPuSJAozQrZuyM= @@ -289,7 +283,6 @@ github.com/oklog/run v1.0.0 h1:Ru7dDtJNOyC66gQ5dQmaCa0qIsAUFY3sFpK1Xk8igrw= github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= @@ -326,6 +319,7 @@ github.com/xanzy/ssh-agent v0.2.1/go.mod h1:mLlQY/MoOhWBj+gOGMQkOeiEvkx+8pJSI+0B github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/zclconf/go-cty v1.2.0/go.mod h1:hOPWgoHbaTUnI5k4D2ld+GRpFJSCe6bCM7m1q/N4PQ8= github.com/zclconf/go-cty v1.2.1/go.mod h1:hOPWgoHbaTUnI5k4D2ld+GRpFJSCe6bCM7m1q/N4PQ8= github.com/zclconf/go-cty v1.7.1 h1:AvsC01GMhMLFL8CgEYdHGM+yLnnDOwhPAYcgTkeF0Gw= @@ -377,8 +371,9 @@ golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.2 h1:Gz96sIWK3OalVv/I/qNygP42zyoKp3xptRVCWRFEBvo= +golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20180530234432-1e491301e022/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180811021610-c39426892332/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -405,8 +400,10 @@ golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/ golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20200707034311-ab3426394381 h1:VXak5I6aEWmAXeQjA+QSZzlgNrpq9mjcfDemuexIKsU= golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d h1:20cMwl2fHAzkJMEA+8J4JgqBQcQGzbisXo31MIeenXI= +golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -421,6 +418,7 @@ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -450,15 +448,21 @@ golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200523222454-059865788121 h1:rITEj+UZHYC927n8GT97eC3zrpzXdb/voyeOuVKS46o= golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c h1:F1jZWGFhYfh0Ci55sIpILtKKK8p3i2/krTr0H1rg74I= +golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/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= -golang.org/x/text v0.3.5 h1:i6eZZ+zk0SOf0xgBpEpPD18qWcJda6q1sxt3S0kzyUQ= -golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -500,12 +504,14 @@ golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roY golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200713011307-fd294ab11aed h1:+qzWo37K31KxduIYaBeMqJ8MUOyTayOQKpH9aDPLMSY= golang.org/x/tools v0.0.0-20200713011307-fd294ab11aed/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.1.5 h1:ouewzE6p+/VEB31YYnTbEJdi8pFqKp4P4n85vwo3DHA= +golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= 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 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= diff --git a/main.go b/main.go index 8cbd929..015d5f2 100644 --- a/main.go +++ b/main.go @@ -1,8 +1,8 @@ package main import ( - "github.com/DevotedHealth/terraform-provider-looker/pkg/looker" "github.com/hashicorp/terraform-plugin-sdk/v2/plugin" + "github.com/hirosassa/terraform-provider-looker/pkg/looker" ) func main() { diff --git a/pkg/looker/provider.go b/pkg/looker/provider.go index 528b547..df34827 100644 --- a/pkg/looker/provider.go +++ b/pkg/looker/provider.go @@ -48,14 +48,15 @@ func Provider() *schema.Provider { }, }, ResourcesMap: map[string]*schema.Resource{ - "looker_user": resourceUser(), - "looker_user_roles": resourceUserRoles(), - "looker_permission_set": resourcePermissionSet(), - "looker_model_set": resourceModelSet(), - "looker_group": resourceGroup(), - "looker_role": resourceRole(), - "looker_role_groups": resourceRoleGroups(), - "looker_user_attribute": resourceUserAttribute(), + "looker_user": resourceUser(), + "looker_user_roles": resourceUserRoles(), + "looker_permission_set": resourcePermissionSet(), + "looker_model_set": resourceModelSet(), + "looker_group": resourceGroup(), + "looker_group_membership": resourceGroupMembership(), + "looker_role": resourceRole(), + "looker_role_groups": resourceRoleGroups(), + "looker_user_attribute": resourceUserAttribute(), }, ConfigureFunc: providerConfigure, diff --git a/pkg/looker/resource_group_membership.go b/pkg/looker/resource_group_membership.go new file mode 100644 index 0000000..30a3df4 --- /dev/null +++ b/pkg/looker/resource_group_membership.go @@ -0,0 +1,154 @@ +package looker + +import ( + "strconv" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + apiclient "github.com/looker-open-source/sdk-codegen/go/sdk/v4" +) + +func resourceGroupMembership() *schema.Resource { + return &schema.Resource{ + Create: resourceGroupMembershipCreate, + Read: resourceGroupMembershipRead, + Update: resourceGroupMembershipUpdate, + Delete: resourceGroupMembershipDelete, + Importer: &schema.ResourceImporter{ + State: resourceGroupMembershipImport, + }, + + Schema: map[string]*schema.Schema{ + "group_id": { + Type: schema.TypeString, + Required: true, + }, + "user_id": { + Type: schema.TypeString, + Required: true, + }, + }, + } +} + +func resourceGroupMembershipCreate(d *schema.ResourceData, m interface{}) error { + client := m.(*apiclient.LookerSDK) + + groupIDString := d.Get("group_id").(string) + + groupID, err := strconv.ParseInt(groupIDString, 10, 64) + if err != nil { + return err + } + + userIDString := d.Get("user_id").(string) + + userID, err := strconv.ParseInt(userIDString, 10, 64) + if err != nil { + return err + } + + body := apiclient.GroupIdForGroupUserInclusion{ + UserId: &userID, + } + + _, err = client.AddGroupUser(groupID, body, nil) + if err != nil { + return err + } + + d.SetId(buildTwoPartID(&groupIDString, &userIDString)) + + return resourceGroupMembershipRead(d, m) +} + +func resourceGroupMembershipRead(d *schema.ResourceData, m interface{}) error { + client := m.(*apiclient.LookerSDK) + + id := d.Id() + groupID, userID, err := groupIDAndUserIDFromID(id) + if err != nil { + return err + } + + req := apiclient.RequestAllGroupUsers{ + GroupId: groupID, + } + + users, err := client.AllGroupUsers(req, nil) // todo: imeplement paging + if err != nil { + return err + } + + if err = d.Set("group_id", strconv.Itoa(int(groupID))); err != nil { + return err + } + + if isContained(users, userID) { + if err = d.Set("user_id", strconv.Itoa(int(userID))); err != nil { + return err + } + } else { + if err = d.Set("user_id", ""); err != nil { + return err + } + } + + return nil +} + +func resourceGroupMembershipUpdate(d *schema.ResourceData, m interface{}) error { + // there's no update in this resource + return resourceGroupMembershipCreate(d, m) +} + +func resourceGroupMembershipDelete(d *schema.ResourceData, m interface{}) error { + client := m.(*apiclient.LookerSDK) + + id := d.Id() + groupID, userID, err := groupIDAndUserIDFromID(id) + if err != nil { + return err + } + + err = client.DeleteGroupUser(groupID, userID, nil) + if err != nil { + return err + } + + return resourceGroupMembershipRead(d, m) +} + +func resourceGroupMembershipImport(d *schema.ResourceData, m interface{}) ([]*schema.ResourceData, error) { + if err := resourceGroupMembershipRead(d, m); err != nil { + return nil, err + } + return []*schema.ResourceData{d}, nil +} + +func isContained(users []apiclient.User, userID int64) bool { + for _, user := range users { + if user.Id == &userID { + return true + } + } + return false +} + +func groupIDAndUserIDFromID(id string) (int64, int64, error) { + groupIDString, userIDString, err := parseTwoPartID(id) + if err != nil { + return 0, 0, err + } + + groupID, err := strconv.ParseInt(groupIDString, 10, 64) + if err != nil { + return 0, 0, err + } + + userID, err := strconv.ParseInt(userIDString, 10, 64) + if err != nil { + return 0, 0, err + } + + return groupID, userID, err +} diff --git a/pkg/looker/resource_group_membership_test.go b/pkg/looker/resource_group_membership_test.go new file mode 100644 index 0000000..3be155b --- /dev/null +++ b/pkg/looker/resource_group_membership_test.go @@ -0,0 +1,43 @@ +package looker + +import ( + "fmt" + "strings" + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" +) + +func TestAcc_GroupMembership(t *testing.T) { + name1 := strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha)) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: providers(), + Steps: []resource.TestStep{ + { + Config: groupMembershipConfig(name1), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("looker_group_membership.test", "group_id", "1"), + resource.TestCheckResourceAttr("looker_group_membership.test", "user_id", "1"), + ), + }, + }, + }) +} + +func groupMembershipConfig(name string) string { + return fmt.Sprintf(` + resource "looker_group" "test" { + name = "%s" + } + resource "looker_user" "test" { + name = "%s" + } + resource "looker_group_membership" "test" { + group_id = looker_group.test.id + user_id = looker_user.test.id + } + `, name, name) +} diff --git a/pkg/looker/util.go b/pkg/looker/util.go new file mode 100644 index 0000000..2f15019 --- /dev/null +++ b/pkg/looker/util.go @@ -0,0 +1,23 @@ +package looker + +import ( + "fmt" + "strings" +) + +// format the strings into an id `a:b` +// this function borrowed from https://github.com/gitlabhq/terraform-provider-gitlab +func buildTwoPartID(a, b *string) string { + return fmt.Sprintf("%s:%s", *a, *b) +} + +// return the pieces of id `a:b` as a, b +// this function borrowed from https://github.com/gitlabhq/terraform-provider-gitlab +func parseTwoPartID(id string) (string, string, error) { + parts := strings.SplitN(id, ":", 2) + if len(parts) != 2 { + return "", "", fmt.Errorf("Unexpected ID format (%q). Expected project:key", id) + } + + return parts[0], parts[1], nil +} diff --git a/pkg/looker/util_test.go b/pkg/looker/util_test.go new file mode 100644 index 0000000..ea473fd --- /dev/null +++ b/pkg/looker/util_test.go @@ -0,0 +1,86 @@ +package looker + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestBuildTwoPartID(t *testing.T) { + tests := map[string]struct { + a string + b string + wantRes string + }{ + "normal string": { + a: "abc", + b: "def", + wantRes: "abc:def", + }, + "both empty string": { + a: "", + b: "", + wantRes: ":", + }, + "first string is empty": { + a: "", + b: "def", + wantRes: ":def", + }, + } + + for key, tt := range tests { + t.Run(key, func(t *testing.T) { + actual := buildTwoPartID(&tt.a, &tt.b) + assert.Equal(t, tt.wantRes, actual) + }) + } +} + +func TestParseTwoPartID(t *testing.T) { + tests := map[string]struct { + id string + wantRes1 string + wantRes2 string + wantErr bool + }{ + "normal input": { + id: "123:456", + wantRes1: "123", + wantRes2: "456", + wantErr: false, + }, + "no colon contained": { + id: "123456", + wantRes1: "", + wantRes2: "", + wantErr: true, + }, + "first part only": { + id: "123:", + wantRes1: "123", + wantRes2: "", + wantErr: false, + }, + "second part only": { + id: ":456", + wantRes1: "", + wantRes2: "456", + wantErr: false, + }, + } + + for key, tt := range tests { + t.Run(key, func(t *testing.T) { + a := assert.New(t) + actualRes1, actualRes2, actualErr := parseTwoPartID(tt.id) + if tt.wantErr { + a.Error(actualErr) + } else { + a.NoError(actualErr) + a.Equal(tt.wantRes1, actualRes1) + a.Equal(tt.wantRes2, actualRes2) + } + }) + } +}