├── .github
├── CODEOWNERS
└── workflows
│ └── main.yml
├── .gitignore
├── .pre-commit-config.yaml
├── CHANGELOG.md
├── CONTRIBUTING.md
├── LICENSE
├── Makefile
├── README.md
├── README.tfdoc.hcl
├── examples
├── README.md
└── organization
│ ├── README.md
│ ├── main.tf
│ └── provider.tf
├── go.mod
├── go.sum
├── main.tf
├── outputs.tf
├── test
├── README.md
├── github_organization_test.go
└── organization
│ ├── main.tf
│ ├── outputs.tf
│ ├── provider.tf
│ └── variables.tf
├── variables.tf
└── versions.tf
/.github/CODEOWNERS:
--------------------------------------------------------------------------------
1 | * @mariux @mineiros-io/terraform-service-catalog
2 |
--------------------------------------------------------------------------------
/.github/workflows/main.yml:
--------------------------------------------------------------------------------
1 | name: CI/CD Pipeline
2 |
3 | on:
4 | push:
5 | branches:
6 | - main
7 | pull_request:
8 | branches:
9 | - main
10 |
11 | concurrency:
12 | group: terraform-github-organization
13 | cancel-in-progress: false
14 |
15 | jobs:
16 | pre-commit:
17 | runs-on: ubuntu-latest
18 | name: Static Analysis
19 | steps:
20 | - name: Checkout
21 | uses: actions/checkout@v2
22 |
23 | - name: Run pre-commit
24 | run: make test/docker/pre-commit
25 |
26 | unit-tests:
27 | needs: pre-commit
28 | runs-on: ubuntu-latest
29 | name: Unit Tests
30 | steps:
31 | - name: Checkout
32 | uses: actions/checkout@v2
33 |
34 | - name: Check for Terraform file changes
35 | uses: getsentry/paths-filter@v2
36 | id: changes
37 | with:
38 | token: ${{ github.token }}
39 | filters: |
40 | terraform:
41 | - '**/*.tf'
42 | - '**/*.go'
43 | - 'go.mod'
44 | - 'go.sum'
45 |
46 | - name: Run Unit Tests
47 | if: steps.changes.outputs.terraform == 'true'
48 | run: make test/docker/unit-tests
49 | env:
50 | GITHUB_OWNER: ${{ secrets.TEST_GITHUB_ORGANIZATION }}
51 | GITHUB_TOKEN: ${{ secrets.TEST_GITHUB_TOKEN }}
52 |
53 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Local .terraform directories
2 | **/.terraform/*
3 |
4 | # Lock file
5 | .terraform.lock.hcl
6 |
7 | # .tfstate files
8 | *.tfstate
9 | *.tfstate.*
10 |
11 | # Crash log files
12 | crash.log
13 |
14 | # Ignore any .tfvars files that are generated automatically for each Terraform run. Most
15 | # .tfvars files are managed as part of configuration and so should be included in
16 | # version control.
17 | #
18 | # example.tfvars
19 |
20 | # Ignore override files as they are usually used to override resources locally and so
21 | # are not checked in
22 | override.tf
23 | override.tf.json
24 | *_override.tf
25 | *_override.tf.json
26 |
27 | # Include override files you do wish to add to version control using negated pattern
28 | #
29 | # !example_override.tf
30 |
31 | # Include tfplan files to ignore the plan output of command: terraform plan -out=tfplan
32 | # example: *tfplan*
33 |
34 | # Go best practices dictate that libraries should not include the vendor directory
35 | vendor
36 |
37 | # IntelliJ files
38 | .idea_modules
39 | *.iml
40 | *.iws
41 | *.ipr
42 | .idea/
43 | build/
44 | */build/
45 | out/
46 | .DS_STORE
47 |
48 | # local env
49 | .env
50 |
--------------------------------------------------------------------------------
/.pre-commit-config.yaml:
--------------------------------------------------------------------------------
1 | repos:
2 | - repo: https://github.com/mineiros-io/pre-commit-hooks
3 | rev: v0.4.1
4 | hooks:
5 | - id: terraform-fmt
6 | - id: terraform-validate
7 | exclude: ^examples|.terraform/
8 | - id: tflint
9 | - id: phony-targets
10 | - id: terradoc-validate
11 | - id: golangci-lint
12 | - id: terradoc-fmt
13 | - id: terradoc-generate
14 | # - id: terramate-generate
15 | - id: markdown-link-check
16 | args: ['-p'] # When adding the -p flag, markdown-link-check will always with an exit code 0, even if dead links are found
17 | verbose: true # Forces the output of the hook to be printed even when the hook passes.
18 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Changelog
2 |
3 | All notable changes to this project will be documented in this file.
4 |
5 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6 | and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7 |
8 | ## [Unreleased]
9 |
10 | ## [0.9.0]
11 |
12 | ### BREAKING CHANGES
13 |
14 | - Drop support for Terraform GitHub Provider `4.x`
15 | - Require Terraform GitHub Provider version `5.3` and above to support `github_organization_settings` resource
16 |
17 | ### Added
18 |
19 | - Add support for organization settings by implementing the `github_organization_settings` resource
20 |
21 | ## [0.8.0]
22 |
23 | ### Added
24 |
25 | - Add support for Terraform GitHub Provider version `5.x`
26 |
27 | ## [0.7.0]
28 |
29 | ### BREAKING CHANGES
30 |
31 | We dropped support for Terraform pre 1.0 and GitHub Terraform Provider pre 4.0.
32 | In addition we changed to the `integrations/github` official GitHub Terraform Provider.
33 | This needs migration actions if you already used this module with the `hashicorp/github` provider and want to upgrade.
34 |
35 | #### Migration from previous versions
36 |
37 | To migrate from a previous version, please ensure that you are using the
38 | `integrations/github` official GitHub Terraform Provider.
39 |
40 | ```hcl
41 | terraform {
42 | required_version = "~> 1.0"
43 |
44 | required_providers {
45 | github = {
46 | source = "integrations/github"
47 | version = "~> 4.0"
48 | }
49 | }
50 | }
51 | ```
52 |
53 | Once you've updated the provider, a manual state migration is required to
54 | migrate existing resources to the new provider.
55 | The following command will replace the provider in the state.
56 |
57 | ```bash
58 | terraform state replace-provider registry.terraform.io/hashicorp/github registry.terraform.io/integrations/github
59 | ```
60 |
61 | After you've migrated the state, please run
62 | `terrafrm init` to apply the changes to the resources.
63 |
64 | ### Added
65 |
66 | - Add support for Official GitHub Terraform Provider `integrations/github`
67 |
68 | ### Removed
69 |
70 | - Removed support for Terraform < 1.0
71 | - Removed support for GitHub Provider < 4.0
72 | - Removed compatibility to Hashicorp GitHub Terraform Provider `hashicorp/github`
73 |
74 | ## [0.6.0]
75 |
76 | ### Added
77 |
78 | - Add support for Terraform `v1`
79 |
80 | ## [0.5.0]
81 |
82 | ### Added
83 |
84 | - Add support for Terraform `v0.15`
85 |
86 | ## [0.4.1]
87 |
88 | ### Added
89 |
90 | - Add safeguard to validate if a GitHub user exists before trying to add it to the organization
91 |
92 | ## [0.4.0]
93 |
94 | ### Added
95 |
96 | - Add support for Github Provider `v4`
97 |
98 | ## [0.3.0]
99 |
100 | ### Added
101 |
102 | - Add support for Terraform `v0.14`
103 |
104 | ## [0.2.0]
105 |
106 | ### Added
107 |
108 | - Add support for Terraform `v0.13`
109 | - Add support for Terraform Github Provider `v3`
110 | - Prepare support for Terraform `v0.14` (needs terraform `v0.12.20` or above)
111 |
112 | ## [0.1.4] - 2020-06-23
113 |
114 | ### Added
115 |
116 | - Add `CHANGELOG.md`.
117 |
118 | ### Changed
119 |
120 | - Switch CI from SemaphoreCI to GitHub Actions.
121 |
122 | ## [0.1.3] - 2020-05-13
123 |
124 | ### Added
125 |
126 | - Work around a terraform issue in `module_depends_on` argument.
127 |
128 | ## [0.1.2] - 2020-05-05
129 |
130 | ### Change
131 |
132 | - New format for README.md and LICENSE.
133 | - Bump pre-commit hooks to `v0.1.4` and add new hooks.
134 | - Bump build-tools to `v0.5.3`
135 |
136 | ## [0.1.1] - 2020-04-18
137 |
138 | ### Added
139 |
140 | - Introduce new variables `all_members_team_name` and `all_members_team_visibility`
141 | for adding the possibility to create a team which contains all members of your organization.
142 |
143 | ## [0.1.0] - 2020-03-03
144 |
145 | ### Added
146 |
147 | - Added some more documentation.
148 | - Pre-commit hooks upgrade.
149 |
150 | ### Changed
151 |
152 | - Add variables and outputs to the existing example.
153 |
154 | ## [0.0.2] - 2020-01-12
155 |
156 | ### Added
157 |
158 | - Added pre-commit hooks.
159 | - Added automated unit tests.
160 | - Added CI configuration.
161 | - Added admins for adding members with admins/owner role.
162 | - Added projects to outputs.
163 |
164 | ### Changed
165 |
166 | - Changed members from complex object to list of usernames for adding normal members.
167 |
168 | ## [0.0.1] - 2020-01-06
169 |
170 | ### Added
171 |
172 | - This is the initial release of our GitHub Organization module with support
173 | for managing GitHub Organizations, Members and Blocked Users.
174 |
175 | [unreleased]: https://github.com/mineiros-io/terraform-github-organization/compare/v0.9.0...HEAD
176 | [0.9.0]: https://github.com/mineiros-io/terraform-github-organization/compare/v0.8.0...v0.9.0
177 | [0.8.0]: https://github.com/mineiros-io/terraform-github-organization/compare/v0.7.0...v0.8.0
178 | [0.7.0]: https://github.com/mineiros-io/terraform-github-organization/compare/v0.6.0...v0.7.0
179 | [0.6.0]: https://github.com/mineiros-io/terraform-github-organization/compare/v0.5.0...v0.6.0
180 | [0.5.0]: https://github.com/mineiros-io/terraform-github-organization/compare/v0.4.1...v0.5.0
181 | [0.4.1]: https://github.com/mineiros-io/terraform-github-organization/compare/v0.4.0...v0.4.1
182 | [0.4.0]: https://github.com/mineiros-io/terraform-github-organization/compare/v0.3.0...v0.4.0
183 | [0.3.0]: https://github.com/mineiros-io/terraform-github-organization/compare/v0.2.0...v0.3.0
184 | [0.2.0]: https://github.com/mineiros-io/terraform-github-organization/compare/v0.1.4...v0.2.0
185 | [0.1.4]: https://github.com/mineiros-io/terraform-github-organization/compare/v0.1.3...v0.1.4
186 | [0.1.3]: https://github.com/mineiros-io/terraform-github-organization/compare/v0.1.2...v0.1.3
187 | [0.1.2]: https://github.com/mineiros-io/terraform-github-organization/compare/v0.1.1...v0.1.2
188 | [0.1.1]: https://github.com/mineiros-io/terraform-github-organization/compare/v0.1.0...v0.1.1
189 | [0.1.0]: https://github.com/mineiros-io/terraform-github-organization/compare/v0.0.2...v0.1.0
190 | [0.0.2]: https://github.com/mineiros-io/terraform-github-organization/compare/v0.0.1...v0.0.2
191 | [0.0.1]: https://github.com/mineiros-io/terraform-github-organization/releases/tag/v0.0.1
192 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contribution Guidelines
2 |
3 | First and foremost, we’d like to express our gratitude to you for taking the time to contribute.
4 | We welcome and appreciate any and all contributions via
5 | [Pull Requests] along the [GitHub Flow].
6 |
7 | 1. [Open a GitHub issue](#open-a-github-issue)
8 | 2. [Fork the repository on GitHub](#fork-the-repository-on-github)
9 | 3. [Install the pre-commit hooks](#install-the-pre-commit-hooks)
10 | 4. [Update the documentation](#update-the-documentation)
11 | 5. [Update the tests](#update-the-tests)
12 | 6. [Update the code](#update-the-code)
13 | 7. [Create a pull request](#create-a-pull-request)
14 | 8. [Merge and release](#merge-and-release)
15 |
16 | ## Open a GitHub issue
17 |
18 | For bug reports or requests, please submit your issue in the appropriate repository.
19 |
20 | We advise that you open an issue and ask the
21 | [CODEOWNERS] and community prior to starting a contribution.
22 | This is your chance to ask questions and receive feedback before
23 | writing (potentially wrong) code. We value the direct contact with our community
24 | a lot, so don't hesitate to ask any questions.
25 |
26 | ## Fork the repository on GitHub
27 |
28 | [Fork] the repository into your own GitHub account and [create a new branch] as
29 | described in the [GitHub Flow].
30 |
31 | ## Install the pre-commit hooks
32 |
33 | If the repository you're working on ships with a
34 | [`.pre-commit-config.yaml`][pre-commit-file],
35 | make sure the necessary hooks have been installed before you begin working
36 | (e.g. a `pre-commit install`).
37 |
38 | ## Update the documentation
39 |
40 | We encourage you to update the documentation before writing any code (please see
41 | [Readme Driven Development]. This ensures the
42 | documentation stays up to date and allows you to think through the problem fully before you begin implementing any
43 | changes.
44 |
45 | ## Update the tests
46 |
47 | We also recommend updating the automated tests before updating any code
48 | (see [Test Driven Development](https://en.wikipedia.org/wiki/Test-driven_development)).
49 |
50 | That means that you should add or update a test case, run all tests and verify
51 | that the new test fails with a clear error message and then start implementing
52 | the code changes to get that test to pass.
53 |
54 | The test folder in every repository will have documentation on how to run the
55 | tests locally.
56 |
57 | ## Update the code
58 |
59 | At this point, make your code changes and constantly test again your new test case to make sure that everything working
60 | properly. Do [commit] early and often and make useful commit messages.
61 |
62 | If a backwards incompatible change cannot be avoided, please make sure to call that out when you submit a pull request,
63 | explaining why the change is absolutely necessary.
64 |
65 | ## Create a pull request
66 |
67 | [Create a pull request] with your changes.
68 | Please make sure to include the following:
69 |
70 | 1. A description of the change, including a link to your GitHub issue.
71 | 1. Any notes on backwards incompatibility or downtime.
72 |
73 | ## Merge and release
74 |
75 | The [CODEOWNERS] of the repository will review your code and provide feedback.
76 | If everything looks good, they will merge the code and release a new version while following the principles of [Semantic Versioning (SemVer)].
77 |
78 |
79 |
80 | [Pull Requests]: https://github.com/mineiros-io/terraform-github-organization/pulls
81 | [pre-commit-file]: https://github.com/mineiros-io/terraform-github-organization/blob/main/.pre-commit-config.yaml
82 |
83 | [Github Flow]: https://guides.github.com/introduction/flow/
84 | [CODEOWNERS]: https://help.github.com/en/github/creating-cloning-and-archiving-repositories/about-code-owners
85 | [Fork]: https://help.github.com/en/github/getting-started-with-github/fork-a-repo
86 | [create a new branch]: https://guides.github.com/introduction/flow/
87 | [Readme Driven Development]: https://tom.preston-werner.com/2010/08/23/readme-driven-development.html
88 | [commit]: https://help.github.com/en/desktop/contributing-to-projects/committing-and-reviewing-changes-to-your-project
89 | [create a pull request]: https://help.github.com/articles/creating-a-pull-request/
90 | [Semantic Versioning (SemVer)]: https://semver.org/
91 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "[]"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright [2020] [Mineiros GmbH]
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | # Set default shell to bash
2 | SHELL := /bin/bash -o pipefail
3 |
4 | BUILD_TOOLS_VERSION ?= v0.15.2
5 | BUILD_TOOLS_DOCKER_REPO ?= mineiros/build-tools
6 | BUILD_TOOLS_DOCKER_IMAGE ?= ${BUILD_TOOLS_DOCKER_REPO}:${BUILD_TOOLS_VERSION}
7 |
8 | # Some CI providers such as GitHub Actions, CircleCI, and TravisCI are setting
9 | # the CI environment variable to a non-empty value by default to indicate that
10 | # the current workflow is running in a Continuous Integration environment.
11 | #
12 | # If TF_IN_AUTOMATION is set to any non-empty value, Terraform adjusts its
13 | # output to avoid suggesting specific commands to run next.
14 | # https://www.terraform.io/docs/commands/environment-variables.html#tf_in_automation
15 | #
16 | # We are using GNU style quiet commands to disable set V to non-empty e.g. V=1
17 | # https://www.gnu.org/software/automake/manual/html_node/Debugging-Make-Rules.html
18 | #
19 | ifdef CI
20 | TF_IN_AUTOMATION ?= yes
21 | export TF_IN_AUTOMATION
22 |
23 | V ?= 1
24 | endif
25 |
26 | ifndef NOCOLOR
27 | GREEN := $(shell tput -Txterm setaf 2)
28 | YELLOW := $(shell tput -Txterm setaf 3)
29 | WHITE := $(shell tput -Txterm setaf 7)
30 | RESET := $(shell tput -Txterm sgr0)
31 | endif
32 |
33 | GIT_TOPLEVEl = $(shell git rev-parse --show-toplevel)
34 |
35 | # Generic docker run flags
36 | DOCKER_RUN_FLAGS += -v ${GIT_TOPLEVEl}:/build
37 | DOCKER_RUN_FLAGS += --rm
38 | DOCKER_RUN_FLAGS += -e TF_IN_AUTOMATION
39 | # If TF_VERSION is defined, TFSwitch will switch to the desired version on
40 | # container startup. If TF_VERSION is omitted, the default version installed
41 | # inside the docker image will be used.
42 | DOCKER_RUN_FLAGS += -e TF_VERSION
43 |
44 | # If SSH_AUTH_SOCK is set, we forward the SSH agent of the host system into
45 | # the docker container. This is useful when working with private repositories
46 | # and dependencies that might need to be cloned inside the container (e.g.
47 | # private Terraform modules).
48 | ifdef SSH_AUTH_SOCK
49 | DOCKER_SSH_FLAGS += -e SSH_AUTH_SOCK=/ssh-agent
50 | DOCKER_SSH_FLAGS += -v ${SSH_AUTH_SOCK}:/ssh-agent
51 | endif
52 |
53 | # If AWS_ACCESS_KEY_ID is defined, we are likely running inside an AWS provider
54 | # module. To enable AWS authentication inside the docker container, we inject
55 | # the relevant environment variables.
56 | ifdef AWS_ACCESS_KEY_ID
57 | DOCKER_AWS_FLAGS += -e AWS_ACCESS_KEY_ID
58 | DOCKER_AWS_FLAGS += -e AWS_SECRET_ACCESS_KEY
59 | DOCKER_AWS_FLAGS += -e AWS_SESSION_TOKEN
60 | endif
61 |
62 | # If GOOGLE_CREDENTIALS is defined, we are likely running inside a GCP provider
63 | # module. To enable GCP authentication inside the docker container, we inject
64 | # the relevant environment variables (service-account key file).
65 | ifdef GOOGLE_CREDENTIALS
66 | DOCKER_GCP_FLAGS += -e GOOGLE_CREDENTIALS
67 | DOCKER_GCP_FLAGS += -e TEST_GCP_PROJECT
68 | DOCKER_GCP_FLAGS += -e TEST_GCP_ORG_DOMAIN
69 | endif
70 |
71 | # If GITHUB_OWNER is defined, we are likely running inside a GitHub provider
72 | # module. To enable GitHub authentication inside the docker container,
73 | # we inject the relevant environment variables.
74 | ifdef GITHUB_OWNER
75 | DOCKER_GITHUB_FLAGS += -e GITHUB_TOKEN
76 | DOCKER_GITHUB_FLAGS += -e GITHUB_OWNER
77 | endif
78 |
79 | .PHONY: default
80 | default: help
81 |
82 | # Not exposed as a callable target by `make help`, since this is a one-time shot to simplify the development of this module.
83 | .PHONY: template/adjust
84 | template/adjust: FILTER = -path ./.git -prune -a -type f -o -type f -not -name Makefile
85 | template/adjust:
86 | @find . $(FILTER) -exec sed -i -e "s,terraform-module-template,$${PWD##*/},g" {} \;
87 |
88 | ## Run pre-commit hooks inside a build-tools docker container.
89 | .PHONY: test/docker/pre-commit
90 | test/docker/pre-commit: DOCKER_FLAGS += ${DOCKER_SSH_FLAGS}
91 | test/docker/pre-commit: DOCKER_FLAGS += -e NOCOLOR=1
92 | test/docker/pre-commit:
93 | $(call docker-run,make test/pre-commit)
94 |
95 | ## Run all Go tests inside a build-tools docker container. This is complementary to running 'go test ./test/...'.
96 | .PHONY: test/docker/unit-tests
97 | test/docker/unit-tests: DOCKER_FLAGS += ${DOCKER_SSH_FLAGS}
98 | test/docker/unit-tests: DOCKER_FLAGS += ${DOCKER_GITHUB_FLAGS}
99 | test/docker/unit-tests: DOCKER_FLAGS += ${DOCKER_AWS_FLAGS}
100 | test/docker/unit-tests: DOCKER_FLAGS += ${DOCKER_GCP_FLAGS}
101 | test/docker/unit-tests: DOCKER_FLAGS += $(shell env | grep ^TF_VAR_ | cut -d = -f 1 | xargs -i printf ' -e {}')
102 | test/docker/unit-tests: DOCKER_FLAGS += -e TF_DATA_DIR=.terratest
103 | test/docker/unit-tests: DOCKER_FLAGS += -e NOCOLOR=1
104 | test/docker/unit-tests: TEST ?= "TestUnit"
105 | test/docker/unit-tests:
106 | @echo "${YELLOW}[TEST] ${GREEN}Start Running Go Tests in Docker Container.${RESET}"
107 | $(call docker-run,make test/unit-tests)
108 |
109 | ## Run pre-commit hooks.
110 | .PHONY: test/pre-commit
111 | test/pre-commit: DOCKER_FLAGS += ${DOCKER_SSH_FLAGS}
112 | test/pre-commit:
113 | $(call quiet-command,pre-commit run -a)
114 |
115 | ## Run all unit tests.
116 | .PHONY: test/docker/unit-tests
117 | test/unit-tests: TEST ?= "TestUnit"
118 | test/unit-tests:
119 | @echo "${YELLOW}[TEST] ${GREEN}Start Running unit tests.${RESET}"
120 | $(call quiet-command,cd test ; go test -v -count 1 -timeout 45m -parallel 128 -run $(TEST))
121 |
122 | ## Generate README.md with Terradoc
123 | .PHONY: terradoc
124 | terradoc:
125 | $(call quiet-command,terradoc generate -o README.md README.tfdoc.hcl)
126 |
127 | ## Generate shared configuration for tests
128 | .PHONY: terramate
129 | terramate:
130 | $(call quiet-command,terramate generate)
131 |
132 | ## Clean up cache and temporary files
133 | .PHONY: clean
134 | clean:
135 | $(call rm-command,.terraform)
136 | $(call rm-command,.terratest)
137 | $(call rm-command,.terraform.lock.hcl)
138 | $(call rm-command,*.tfplan)
139 | $(call rm-command,*/*/.terraform)
140 | $(call rm-command,*/*/.terratest)
141 | $(call rm-command,*/*/*.tfplan)
142 | $(call rm-command,*/*/.terraform.lock.hcl)
143 |
144 | ## Display help for all targets
145 | .PHONY: help
146 | help:
147 | @awk '/^.PHONY: / { \
148 | msg = match(lastLine, /^## /); \
149 | if (msg) { \
150 | cmd = substr($$0, 9, 100); \
151 | msg = substr(lastLine, 4, 1000); \
152 | printf " ${GREEN}%-30s${RESET} %s\n", cmd, msg; \
153 | } \
154 | } \
155 | { lastLine = $$0 }' $(MAKEFILE_LIST)
156 |
157 | # Define helper functions
158 | DOCKER_FLAGS += ${DOCKER_RUN_FLAGS}
159 | DOCKER_RUN_CMD = docker run ${DOCKER_FLAGS} ${BUILD_TOOLS_DOCKER_IMAGE}
160 |
161 | quiet-command = $(if ${V},${1},$(if ${2},@echo ${2} && ${1}, @${1}))
162 | docker-run = $(call quiet-command,${DOCKER_RUN_CMD} ${1} | cat,"${YELLOW}[DOCKER RUN] ${GREEN}${1}${RESET}")
163 | rm-command = $(call quiet-command,rm -rf ${1},"${YELLOW}[CLEAN] ${GREEN}${1}${RESET}")
164 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | [
](https://mineiros.io/?ref=terraform-github-organization)
2 |
3 | [](https://github.com/mineiros-io/terraform-github-organization/actions)
4 | [](https://github.com/mineiros-io/terraform-github-organization/releases)
5 | [](https://github.com/hashicorp/terraform/releases)
6 | [](https://github.com/terraform-providers/terraform-provider-github/releases)
7 | [](https://join.slack.com/t/mineiros-community/shared_invite/zt-ehidestg-aLGoIENLVs6tvwJ11w9WGg)
8 |
9 | # terraform-github-organization
10 |
11 | A [Terraform] module that acts as a wrapper around the Terraform
12 | [GitHub provider](https://www.terraform.io/docs/providers/github/index.html) and offers a more convenient and tested way
13 | to manage GitHub Organizations following best practices.
14 |
15 | **_This module supports Terraform v1.x and is compatible with the Official Terraform GitHub Provider v5.x from `integrations/github`._**
16 |
17 | **Attention: This module is incompatible with the Hashicorp GitHub Provider! The latest version of this module supporting `hashicorp/github` provider is `~> 0.6.0`**
18 |
19 |
20 | - [GitHub as Code](#github-as-code)
21 | - [Module Features](#module-features)
22 | - [Getting Started](#getting-started)
23 | - [Module Argument Reference](#module-argument-reference)
24 | - [Top-level Arguments](#top-level-arguments)
25 | - [Module Outputs](#module-outputs)
26 | - [External Documentation](#external-documentation)
27 | - [Terraform Github Provider Documentation:](#terraform-github-provider-documentation)
28 | - [Module Versioning](#module-versioning)
29 | - [Backwards compatibility in `0.0.z` and `0.y.z` version](#backwards-compatibility-in-00z-and-0yz-version)
30 | - [About Mineiros](#about-mineiros)
31 | - [Reporting Issues](#reporting-issues)
32 | - [Contributing](#contributing)
33 | - [Makefile Targets](#makefile-targets)
34 | - [License](#license)
35 |
36 | ## GitHub as Code
37 |
38 | [GitHub as Code][github-as-code] is a commercial solution built on top of
39 | our open-source Terraform modules for GitHub. It helps our customers to
40 | manage their GitHub organization more efficiently by enabling anyone in
41 | their organization to **self-service** manage **on- and offboarding of users**,
42 | **repositories**, and settings such as **branch protections**, **secrets**, and more
43 | through code. GitHub as Code comes with **pre-configured GitHub Actions
44 | pipelines** for **change pre-view in Pull Requests**, **fully automated
45 | rollouts** and **rollbacks**. It's a comprehensive, ready-to-use blueprint
46 | maintained by our team of platform engineering experts and saves
47 | companies such as yours tons of time by building on top of a pre-configured
48 | solution instead of building and maintaining it yourself.
49 |
50 | For details please see [https://mineiros.io/github-as-code][github-as-code].
51 |
52 | ## Module Features
53 |
54 | - **Standard Module Features**:
55 | Organization Members,
56 | Organization Owners (Admins),
57 | Organization Projects,
58 | Blocked Users,
59 | Manage Organization Settings
60 |
61 |
62 | - **Extended Module Features**:
63 | Change organization member roles without removing and re-inviting users,
64 | Rename projects without recreating (when providing unique ids),
65 | No need to import members/admins on first run,
66 | Create an all member team that contains every member of your organization
67 |
68 | ## Getting Started
69 |
70 | To quickly start managing your GitHub Organization with Terraform:
71 |
72 | ```hcl
73 | module "organization" {
74 | source = "mineiros-io/organization/github"
75 | version = "~> 0.9.0"
76 |
77 | all_members_team_name = "Mineiros"
78 |
79 | settings = {
80 | billing_email = "hello@mineiros.io"
81 | company = "Mineiros"
82 | blog = "https://blog.mineiros.io"
83 | email = "hello@mineiros.io"
84 | twitter_username = "mineirosio"
85 | location = "Berlin"
86 | name = "Terraform Tests"
87 | description = "This Organization is just used to run some Terraform tests for https://github.com/mineiros-io"
88 | has_organization_projects = true
89 | has_repository_projects = true
90 | default_repository_permission = "read"
91 | members_can_create_repositories = false
92 | members_can_create_public_repositories = false
93 | members_can_create_private_repositories = false
94 | members_can_create_internal_repositories = false
95 | members_can_create_pages = false
96 | members_can_create_public_pages = false
97 | members_can_create_private_pages = false
98 | members_can_fork_private_repositories = false
99 | web_commit_signoff_required = false
100 | advanced_security_enabled_for_new_repositories = false
101 | dependabot_alerts_enabled_for_new_repositories = false
102 | dependabot_security_updates_enabled_for_new_repositories = false
103 | dependency_graph_enabled_for_new_repositories = false
104 | secret_scanning_enabled_for_new_repositories = false
105 | secret_scanning_push_protection_enabled_for_new_repositories = false
106 | }
107 |
108 |
109 | members = [
110 | "a-user",
111 | "b-user",
112 | ]
113 |
114 | admins = [
115 | "a-admin",
116 | ]
117 |
118 | blocked_users = [
119 | "blocked-user",
120 | "another-blocked-user",
121 | ]
122 |
123 | projects = [
124 | {
125 | id = "project-a"
126 | name = "A Great Project"
127 | body = "This is a project created by Terraform"
128 | }
129 | ]
130 | }
131 |
132 | provider "github" {}
133 |
134 | terraform {
135 | required_version = "~> 1.0"
136 |
137 | required_providers {
138 | github = {
139 | source = "integrations/github"
140 | version = "~> 4.0"
141 | }
142 | }
143 | }
144 | ```
145 |
146 | ## Module Argument Reference
147 |
148 | See [variables.tf] and [examples/] for details and use-cases.
149 |
150 | ### Top-level Arguments
151 |
152 | - [**`settings`**](#var-settings): *(Optional `object(settings)`)*
153 |
154 | A map of settings for the GitHub organization.
155 |
156 | Default is `{"fixed_response":{"content_type":"plain/text","message_body":"Nothing to see here!","status_code":418}}`.
157 |
158 | The `settings` object accepts the following attributes:
159 |
160 | - [**`billing_email`**](#attr-settings-billing_email): *(**Required** `string`)*
161 |
162 | The billing email address for the organization.
163 |
164 | - [**`email`**](#attr-settings-email): *(Optional `string`)*
165 |
166 | The email address for the organization.
167 |
168 | - [**`name`**](#attr-settings-name): *(Optional `string`)*
169 |
170 | The name for the organization.
171 |
172 | - [**`description`**](#attr-settings-description): *(Optional `string`)*
173 |
174 | The description for the organization.
175 |
176 | - [**`company_name`**](#attr-settings-company_name): *(Optional `string`)*
177 |
178 | The company name for the organization.
179 |
180 | - [**`blog`**](#attr-settings-blog): *(Optional `string`)*
181 |
182 | The blog URL for the organization.
183 |
184 | - [**`twitter_username`**](#attr-settings-twitter_username): *(Optional `string`)*
185 |
186 | The Twitter username for the organization.
187 |
188 | - [**`location`**](#attr-settings-location): *(Optional `string`)*
189 |
190 | The location for the organization.
191 |
192 | - [**`has_organization_projects`**](#attr-settings-has_organization_projects): *(Optional `bool`)*
193 |
194 | Whether or not organization projects are enabled for the organization.
195 |
196 | Default is `true`.
197 |
198 | - [**`has_repository_projects`**](#attr-settings-has_repository_projects): *(Optional `bool`)*
199 |
200 | Whether or not repository projects are enabled for the organization.
201 |
202 | Default is `true`.
203 |
204 | - [**`default_repository_permission`**](#attr-settings-default_repository_permission): *(Optional `string`)*
205 |
206 | The default permission for organization members to create new repositories.
207 | Can be one of `read`, `write`, `admin`, or `none`.
208 |
209 | - [**`members_can_create_repositories`**](#attr-settings-members_can_create_repositories): *(Optional `bool`)*
210 |
211 | Whether or not organization members can create new repositories.
212 |
213 | Default is `false`.
214 |
215 | - [**`members_can_create_public_repositories`**](#attr-settings-members_can_create_public_repositories): *(Optional `bool`)*
216 |
217 | Whether or not organization members can create new public repositories.
218 |
219 | Default is `true`.
220 |
221 | - [**`members_can_create_private_repositories`**](#attr-settings-members_can_create_private_repositories): *(Optional `bool`)*
222 |
223 | Whether or not organization members can create new private repositories.
224 |
225 | Default is `false`.
226 |
227 | - [**`members_can_create_internal_repositories`**](#attr-settings-members_can_create_internal_repositories): *(Optional `bool`)*
228 |
229 | Whether or not organization members can create new internal repositories. For Enterprise Organizations only.
230 |
231 | Default is `false`.
232 |
233 | - [**`members_can_create_pages`**](#attr-settings-members_can_create_pages): *(Optional `bool`)*
234 |
235 | Whether or not organization members can create new pages.
236 |
237 | Default is `false`.
238 |
239 | - [**`members_can_create_public_pages`**](#attr-settings-members_can_create_public_pages): *(Optional `bool`)*
240 |
241 | Whether or not organization members can create new public pages.
242 |
243 | Default is `false`.
244 |
245 | - [**`members_can_fork_private_repositories`**](#attr-settings-members_can_fork_private_repositories): *(Optional `bool`)*
246 |
247 | Whether or not organization members can fork private repositories.
248 |
249 | Default is `false`.
250 |
251 | - [**`web_commit_signoff_required`**](#attr-settings-web_commit_signoff_required): *(Optional `bool`)*
252 |
253 | Whether or not commit signatures are required for commits to the organization.
254 |
255 | Default is `false`.
256 |
257 | - [**`advanced_security_enabled_for_new_repositories`**](#attr-settings-advanced_security_enabled_for_new_repositories): *(Optional `bool`)*
258 |
259 | Whether or not advanced security is enabled for new repositories.
260 |
261 | Default is `false`.
262 |
263 | - [**`dependabot_alerts_enabled_for_new_repositories`**](#attr-settings-dependabot_alerts_enabled_for_new_repositories): *(Optional `bool`)*
264 |
265 | Whether or not dependabot alerts are enabled for new repositories.
266 |
267 | Default is `false`.
268 |
269 | - [**`dependabot_security_updates_enabled_for_new_repositories`**](#attr-settings-dependabot_security_updates_enabled_for_new_repositories): *(Optional `bool`)*
270 |
271 | Whether or not dependabot security updates are enabled for new repositories.
272 |
273 | Default is `false`.
274 |
275 | - [**`dependency_graph_enabled_for_new_repositories`**](#attr-settings-dependency_graph_enabled_for_new_repositories): *(Optional `bool`)*
276 |
277 | Whether or not dependency graph is enabled for new repositories.
278 |
279 | Default is `false`.
280 |
281 | - [**`secret_scanning_enabled_for_new_repositories`**](#attr-settings-secret_scanning_enabled_for_new_repositories): *(Optional `bool`)*
282 |
283 | Whether or not secret scanning is enabled for new repositories.
284 |
285 | Default is `false`.
286 |
287 | - [**`secret_scanning_push_protection_enabled_for_new_repositories`**](#attr-settings-secret_scanning_push_protection_enabled_for_new_repositories): *(Optional `bool`)*
288 |
289 | Whether or not secret scanning push protection is enabled for new repositories.
290 |
291 | Default is `false`.
292 |
293 | - [**`blocked_users`**](#var-blocked_users): *(Optional `set(string)`)*
294 |
295 | A list of usernames to be blocked from a GitHub organization.
296 |
297 | Default is `[]`.
298 |
299 | Example:
300 |
301 | ```hcl
302 | blocked_users = [
303 | "blocked-user"
304 | ]
305 | ```
306 |
307 | - [**`members`**](#var-members): *(Optional `set(string)`)*
308 |
309 | A list of users to be added to your organization with member role.
310 | When applied, an invitation will be sent to the user to become part of the organization.
311 | When destroyed, either the invitation will be cancelled or the user will be removed.
312 |
313 | Default is `[]`.
314 |
315 | Example:
316 |
317 | ```hcl
318 | members = [
319 | "admin",
320 | "another-admin"
321 | ]
322 | ```
323 |
324 | - [**`admins`**](#var-admins): *(Optional `set(string)`)*
325 |
326 | A list of users to be added to your organization with admin role.
327 | When applied, an invitation will be sent to the user to become part of the organization.
328 | When destroyed, either the invitation will be cancelled or the user will be removed.
329 |
330 | Default is `[]`.
331 |
332 | Example:
333 |
334 | ```hcl
335 | admins = [
336 | "admin",
337 | "another-admin"
338 | ]
339 | ```
340 |
341 | - [**`projects`**](#var-projects): *(Optional `list(project)`)*
342 |
343 | Create and manage projects for the GitHub organization.
344 |
345 | Default is `[]`.
346 |
347 | Example:
348 |
349 | ```hcl
350 | projects = [
351 | {
352 | name = "Test Project"
353 | body = "This is a test project created by Terraform"
354 | },
355 | {
356 | name = "Test Project without a body"
357 | }
358 | ]
359 | ```
360 |
361 | - [**`all_members_team_name`**](#var-all_members_team_name): *(Optional `string`)*
362 |
363 | The name of the team that contains all members of the organization.
364 |
365 | - [**`all_members_team_visibility`**](#var-all_members_team_visibility): *(Optional `string`)*
366 |
367 | The level of privacy for the team. Must be one of `secret` or `closed`.
368 |
369 | Default is `"secret"`.
370 |
371 | - [**`catch_non_existing_members`**](#var-catch_non_existing_members): *(Optional `bool`)*
372 |
373 | Validates if the list of GitHub users are existing users on every run. Use carefully as it will trigger one additional API call for every given user on every iteration.
374 |
375 | Default is `false`.
376 |
377 | ## Module Outputs
378 |
379 | The following attributes are exported by the module:
380 |
381 | - [**`blocked_users`**](#output-blocked_users): *(`set(string)`)*
382 |
383 | A list of `github_organization_block` resource objects
384 | that describe all users that are blocked by the organization.
385 |
386 | - [**`memberships`**](#output-memberships): *(`list(membership)`)*
387 |
388 | A list of `github_membership` resource objects that describe
389 | all members of the organization.
390 |
391 | - [**`projects`**](#output-projects): *(`list(project)`)*
392 |
393 | A list of `github_organization_project` resource objects that
394 | describe all projects of the organization.
395 |
396 | - [**`all_members_team`**](#output-all_members_team): *(`object(all_members_team)`)*
397 |
398 | The outputs of the all members team that contains all members of your organization.
399 |
400 | - [**`settings`**](#output-settings): *(`object(all_members_team)`)*
401 |
402 | The outputs of the organization settings.
403 |
404 | ## External Documentation
405 |
406 | ### Terraform Github Provider Documentation:
407 |
408 | - https://www.terraform.io/docs/providers/github/index.html
409 |
410 | ## Module Versioning
411 |
412 | This Module follows the principles of [Semantic Versioning (SemVer)].
413 |
414 | Given a version number `MAJOR.MINOR.PATCH`, we increment the:
415 |
416 | 1. `MAJOR` version when we make incompatible changes,
417 | 2. `MINOR` version when we add functionality in a backwards compatible manner, and
418 | 3. `PATCH` version when we make backwards compatible bug fixes.
419 |
420 | ### Backwards compatibility in `0.0.z` and `0.y.z` version
421 |
422 | - Backwards compatibility in versions `0.0.z` is **not guaranteed** when `z` is increased. (Initial development)
423 | - Backwards compatibility in versions `0.y.z` is **not guaranteed** when `y` is increased. (Pre-release)
424 |
425 | ## About Mineiros
426 |
427 | Mineiros is a [DevOps as a Service][homepage] company based in Berlin, Germany.
428 | We offer commercial support for all of our projects and encourage you to reach out
429 | if you have any questions or need help. Feel free to send us an email at [hello@mineiros.io] or join our [Community Slack channel][slack].
430 |
431 | We can also help you with:
432 |
433 | - Terraform modules for all types of infrastructure such as VPCs, Docker clusters, databases, logging and monitoring, CI, etc.
434 | - Consulting & training on AWS, Terraform and DevOps
435 |
436 | ## Reporting Issues
437 |
438 | We use GitHub [Issues] to track community reported issues and missing features.
439 |
440 | ## Contributing
441 |
442 | Contributions are always encouraged and welcome! For the process of accepting changes, we use
443 | [Pull Requests]. If you'd like more information, please see our [Contribution Guidelines].
444 |
445 | ## Makefile Targets
446 |
447 | This repository comes with a handy [Makefile].
448 | Run `make help` to see details on each available target.
449 |
450 | ## License
451 |
452 | [![license][badge-license]][apache20]
453 |
454 | This module is licensed under the Apache License Version 2.0, January 2004.
455 | Please see [LICENSE] for full details.
456 |
457 | Copyright © 2021-2022 [Mineiros GmbH][homepage]
458 |
459 |
460 |
461 |
462 | [homepage]: https://mineiros.io/?ref=terraform-github-organization
463 | [github-as-code]: https://mineiros.io/github-as-code?ref=terraform-github-organization
464 | [hello@mineiros.io]: mailto:hello@mineiros.io
465 | [badge-build]: https://github.com/mineiros-io/terraform-github-organization/workflows/CI/CD%20Pipeline/badge.svg
466 | [badge-semver]: https://img.shields.io/github/v/tag/mineiros-io/terraform-github-organization.svg?label=latest&sort=semver
467 | [badge-license]: https://img.shields.io/badge/license-Apache%202.0-brightgreen.svg
468 | [badge-terraform]: https://img.shields.io/badge/terraform-1.x-623CE4.svg?logo=terraform
469 | [badge-slack]: https://img.shields.io/badge/slack-@mineiros--community-f32752.svg?logo=slack
470 | [build-status]: https://github.com/mineiros-io/terraform-github-organization/actions
471 | [releases-github]: https://github.com/mineiros-io/terraform-github-organization/releases
472 | [badge-tf-gh]: https://img.shields.io/badge/GH-4.x-F8991D.svg?logo=terraform
473 | [releases-github-provider]: https://github.com/terraform-providers/terraform-provider-github/releases
474 | [releases-terraform]: https://github.com/hashicorp/terraform/releases
475 | [apache20]: https://opensource.org/licenses/Apache-2.0
476 | [slack]: https://join.slack.com/t/mineiros-community/shared_invite/zt-ehidestg-aLGoIENLVs6tvwJ11w9WGg
477 | [terraform]: https://www.terraform.io
478 | [aws]: https://aws.amazon.com/
479 | [semantic versioning (semver)]: https://semver.org/
480 | [examples/example/main.tf]: https://github.com/mineiros-io/terraform-github-organization/blob/main/examples/example/main.tf
481 | [variables.tf]: https://github.com/mineiros-io/terraform-github-organization/blob/main/variables.tf
482 | [examples/]: https://github.com/mineiros-io/terraform-github-organization/blob/main/examples
483 | [issues]: https://github.com/mineiros-io/terraform-github-organization/issues
484 | [license]: https://github.com/mineiros-io/terraform-github-organization/blob/main/LICENSE
485 | [makefile]: https://github.com/mineiros-io/terraform-github-organization/blob/main/Makefile
486 | [pull requests]: https://github.com/mineiros-io/terraform-github-organization/pulls
487 | [contribution guidelines]: https://github.com/mineiros-io/terraform-github-organization/blob/main/CONTRIBUTING.md
488 |
--------------------------------------------------------------------------------
/README.tfdoc.hcl:
--------------------------------------------------------------------------------
1 | header {
2 | image = "https://raw.githubusercontent.com/mineiros-io/brand/3bffd30e8bdbbde32c143e2650b2faa55f1df3ea/mineiros-primary-logo.svg"
3 | url = "https://mineiros.io/?ref=terraform-github-organization"
4 |
5 | badge "build" {
6 | image = "https://github.com/mineiros-io/terraform-github-organization/workflows/CI/CD%20Pipeline/badge.svg"
7 | url = "https://github.com/mineiros-io/terraform-github-organization/actions"
8 | text = "Build Status"
9 | }
10 |
11 | badge "semver" {
12 | image = "https://img.shields.io/github/v/tag/mineiros-io/terraform-github-organization.svg?label=latest&sort=semver"
13 | url = "https://github.com/mineiros-io/terraform-github-organization/releases"
14 | text = "GitHub tag (latest SemVer)"
15 | }
16 |
17 | badge "terraform" {
18 | image = "https://img.shields.io/badge/terraform-1.x-623CE4.svg?logo=terraform"
19 | url = "https://github.com/hashicorp/terraform/releases"
20 | text = "Terraform Version"
21 | }
22 |
23 | badge "tf-gh" {
24 | image = "https://img.shields.io/badge/GH-5.x-F8991D.svg?logo=terraform"
25 | url = "https://github.com/terraform-providers/terraform-provider-github/releases"
26 | text = "Github Provider Version"
27 | }
28 |
29 | badge "slack" {
30 | image = "https://img.shields.io/badge/slack-@mineiros--community-f32752.svg?logo=slack"
31 | url = "https://join.slack.com/t/mineiros-community/shared_invite/zt-ehidestg-aLGoIENLVs6tvwJ11w9WGg"
32 | text = "Join Slack"
33 | }
34 | }
35 |
36 | section {
37 | title = "terraform-github-organization"
38 | toc = true
39 | content = <<-END
40 | A [Terraform] module that acts as a wrapper around the Terraform
41 | [GitHub provider](https://www.terraform.io/docs/providers/github/index.html) and offers a more convenient and tested way
42 | to manage GitHub Organizations following best practices.
43 |
44 | **_This module supports Terraform v1.x and is compatible with the Official Terraform GitHub Provider v5.x from `integrations/github`._**
45 |
46 | **Attention: This module is incompatible with the Hashicorp GitHub Provider! The latest version of this module supporting `hashicorp/github` provider is `~> 0.6.0`**
47 | END
48 |
49 | section {
50 | title = "GitHub as Code"
51 | content = <<-END
52 | [GitHub as Code][github-as-code] is a commercial solution built on top of
53 | our open-source Terraform modules for GitHub. It helps our customers to
54 | manage their GitHub organization more efficiently by enabling anyone in
55 | their organization to **self-service** manage **on- and offboarding of users**,
56 | **repositories**, and settings such as **branch protections**, **secrets**, and more
57 | through code. GitHub as Code comes with **pre-configured GitHub Actions
58 | pipelines** for **change pre-view in Pull Requests**, **fully automated
59 | rollouts** and **rollbacks**. It's a comprehensive, ready-to-use blueprint
60 | maintained by our team of platform engineering experts and saves
61 | companies such as yours tons of time by building on top of a pre-configured
62 | solution instead of building and maintaining it yourself.
63 |
64 | For details please see [https://mineiros.io/github-as-code][github-as-code].
65 | END
66 | }
67 |
68 | section {
69 | title = "Module Features"
70 | content = <<-END
71 | - **Standard Module Features**:
72 | Organization Members,
73 | Organization Owners (Admins),
74 | Organization Projects,
75 | Blocked Users,
76 | Manage Organization Settings
77 |
78 |
79 | - **Extended Module Features**:
80 | Change organization member roles without removing and re-inviting users,
81 | Rename projects without recreating (when providing unique ids),
82 | No need to import members/admins on first run,
83 | Create an all member team that contains every member of your organization
84 | END
85 | }
86 |
87 | section {
88 | title = "Getting Started"
89 | content = <<-END
90 | To quickly start managing your GitHub Organization with Terraform:
91 |
92 | ```hcl
93 | module "organization" {
94 | source = "mineiros-io/organization/github"
95 | version = "~> 0.9.0"
96 |
97 | all_members_team_name = "Mineiros"
98 |
99 | settings = {
100 | billing_email = "hello@mineiros.io"
101 | company = "Mineiros"
102 | blog = "https://blog.mineiros.io"
103 | email = "hello@mineiros.io"
104 | twitter_username = "mineirosio"
105 | location = "Berlin"
106 | name = "Terraform Tests"
107 | description = "This Organization is just used to run some Terraform tests for https://github.com/mineiros-io"
108 | has_organization_projects = true
109 | has_repository_projects = true
110 | default_repository_permission = "read"
111 | members_can_create_repositories = false
112 | members_can_create_public_repositories = false
113 | members_can_create_private_repositories = false
114 | members_can_create_internal_repositories = false
115 | members_can_create_pages = false
116 | members_can_create_public_pages = false
117 | members_can_create_private_pages = false
118 | members_can_fork_private_repositories = false
119 | web_commit_signoff_required = false
120 | advanced_security_enabled_for_new_repositories = false
121 | dependabot_alerts_enabled_for_new_repositories = false
122 | dependabot_security_updates_enabled_for_new_repositories = false
123 | dependency_graph_enabled_for_new_repositories = false
124 | secret_scanning_enabled_for_new_repositories = false
125 | secret_scanning_push_protection_enabled_for_new_repositories = false
126 | }
127 |
128 |
129 | members = [
130 | "a-user",
131 | "b-user",
132 | ]
133 |
134 | admins = [
135 | "a-admin",
136 | ]
137 |
138 | blocked_users = [
139 | "blocked-user",
140 | "another-blocked-user",
141 | ]
142 |
143 | projects = [
144 | {
145 | id = "project-a"
146 | name = "A Great Project"
147 | body = "This is a project created by Terraform"
148 | }
149 | ]
150 | }
151 |
152 | provider "github" {}
153 |
154 | terraform {
155 | required_version = "~> 1.0"
156 |
157 | required_providers {
158 | github = {
159 | source = "integrations/github"
160 | version = "~> 4.0"
161 | }
162 | }
163 | }
164 | ```
165 | END
166 | }
167 |
168 | section {
169 | title = "Module Argument Reference"
170 | content = <<-END
171 | See [variables.tf] and [examples/] for details and use-cases.
172 | END
173 |
174 | section {
175 | title = "Top-level Arguments"
176 |
177 | variable "settings" {
178 | type = object(settings)
179 | default = {
180 | fixed_response = {
181 | content_type = "plain/text"
182 | message_body = "Nothing to see here!"
183 | status_code = 418
184 | }
185 | }
186 | description = <<-END
187 | A map of settings for the GitHub organization.
188 | END
189 |
190 |
191 | attribute "billing_email" {
192 | type = string
193 | required = true
194 | description = <<-END
195 | The billing email address for the organization.
196 | END
197 | }
198 |
199 | attribute "email" {
200 | type = string
201 | description = <<-END
202 | The email address for the organization.
203 | END
204 | }
205 |
206 | attribute "name" {
207 | type = string
208 | description = <<-END
209 | The name for the organization.
210 | END
211 | }
212 |
213 | attribute "description" {
214 | type = string
215 | description = <<-END
216 | The description for the organization.
217 | END
218 | }
219 |
220 | attribute "company_name" {
221 | type = string
222 | description = <<-END
223 | The company name for the organization.
224 | END
225 | }
226 |
227 | attribute "blog" {
228 | type = string
229 | description = <<-END
230 | The blog URL for the organization.
231 | END
232 | }
233 |
234 | attribute "twitter_username" {
235 | type = string
236 | description = <<-END
237 | The Twitter username for the organization.
238 | END
239 | }
240 |
241 | attribute "location" {
242 | type = string
243 | description = <<-END
244 | The location for the organization.
245 | END
246 | }
247 |
248 | attribute "has_organization_projects" {
249 | type = bool
250 | default = true
251 | description = <<-END
252 | Whether or not organization projects are enabled for the organization.
253 | END
254 | }
255 |
256 | attribute "has_repository_projects" {
257 | type = bool
258 | default = true
259 | description = <<-END
260 | Whether or not repository projects are enabled for the organization.
261 | END
262 | }
263 |
264 | attribute "default_repository_permission" {
265 | type = string
266 | description = <<-END
267 | The default permission for organization members to create new repositories.
268 | Can be one of `read`, `write`, `admin`, or `none`.
269 | END
270 | }
271 |
272 | attribute "members_can_create_repositories" {
273 | type = bool
274 | default = false
275 | description = <<-END
276 | Whether or not organization members can create new repositories.
277 | END
278 | }
279 |
280 | attribute "members_can_create_public_repositories" {
281 | type = bool
282 | default = true
283 | description = <<-END
284 | Whether or not organization members can create new public repositories.
285 | END
286 | }
287 |
288 | attribute "members_can_create_private_repositories" {
289 | type = bool
290 | default = false
291 | description = <<-END
292 | Whether or not organization members can create new private repositories.
293 | END
294 | }
295 |
296 | attribute "members_can_create_internal_repositories" {
297 | type = bool
298 | default = false
299 | description = <<-END
300 | Whether or not organization members can create new internal repositories. For Enterprise Organizations only.
301 | END
302 | }
303 |
304 | attribute "members_can_create_pages" {
305 | type = bool
306 | default = false
307 | description = <<-END
308 | Whether or not organization members can create new pages.
309 | END
310 | }
311 |
312 | attribute "members_can_create_public_pages" {
313 | type = bool
314 | default = false
315 | description = <<-END
316 | Whether or not organization members can create new public pages.
317 | END
318 | }
319 |
320 | attribute "members_can_fork_private_repositories" {
321 | type = bool
322 | default = false
323 | description = <<-END
324 | Whether or not organization members can fork private repositories.
325 | END
326 | }
327 |
328 | attribute "web_commit_signoff_required" {
329 | type = bool
330 | default = false
331 | description = <<-END
332 | Whether or not commit signatures are required for commits to the organization.
333 | END
334 | }
335 |
336 | attribute "advanced_security_enabled_for_new_repositories" {
337 | type = bool
338 | default = false
339 | description = <<-END
340 | Whether or not advanced security is enabled for new repositories.
341 | END
342 | }
343 |
344 | attribute "dependabot_alerts_enabled_for_new_repositories" {
345 | type = bool
346 | default = false
347 | description = <<-END
348 | Whether or not dependabot alerts are enabled for new repositories.
349 | END
350 | }
351 |
352 | attribute "dependabot_security_updates_enabled_for_new_repositories" {
353 | type = bool
354 | default = false
355 | description = <<-END
356 | Whether or not dependabot security updates are enabled for new repositories.
357 | END
358 | }
359 |
360 | attribute "dependency_graph_enabled_for_new_repositories" {
361 | type = bool
362 | default = false
363 | description = <<-END
364 | Whether or not dependency graph is enabled for new repositories.
365 | END
366 | }
367 |
368 | attribute "secret_scanning_enabled_for_new_repositories" {
369 | type = bool
370 | default = false
371 | description = <<-END
372 | Whether or not secret scanning is enabled for new repositories.
373 | END
374 | }
375 |
376 | attribute "secret_scanning_push_protection_enabled_for_new_repositories" {
377 | type = bool
378 | default = false
379 | description = <<-END
380 | Whether or not secret scanning push protection is enabled for new repositories.
381 | END
382 | }
383 | }
384 |
385 | variable "blocked_users" {
386 | type = set(string)
387 | default = []
388 | description = <<-END
389 | A list of usernames to be blocked from a GitHub organization.
390 | END
391 | readme_example = <<-END
392 | blocked_users = [
393 | "blocked-user"
394 | ]
395 | END
396 | }
397 |
398 | variable "members" {
399 | type = set(string)
400 | default = []
401 | description = <<-END
402 | A list of users to be added to your organization with member role.
403 | When applied, an invitation will be sent to the user to become part of the organization.
404 | When destroyed, either the invitation will be cancelled or the user will be removed.
405 | END
406 | readme_example = <<-END
407 | members = [
408 | "admin",
409 | "another-admin"
410 | ]
411 | END
412 | }
413 |
414 | variable "admins" {
415 | type = set(string)
416 | default = []
417 | description = <<-END
418 | A list of users to be added to your organization with admin role.
419 | When applied, an invitation will be sent to the user to become part of the organization.
420 | When destroyed, either the invitation will be cancelled or the user will be removed.
421 | END
422 | readme_example = <<-END
423 | admins = [
424 | "admin",
425 | "another-admin"
426 | ]
427 | END
428 | }
429 |
430 | variable "projects" {
431 | type = list(project)
432 | default = []
433 | description = <<-END
434 | Create and manage projects for the GitHub organization.
435 | END
436 | readme_example = <<-END
437 | projects = [
438 | {
439 | name = "Test Project"
440 | body = "This is a test project created by Terraform"
441 | },
442 | {
443 | name = "Test Project without a body"
444 | }
445 | ]
446 | END
447 | }
448 |
449 | variable "all_members_team_name" {
450 | type = string
451 | description = <<-END
452 | The name of the team that contains all members of the organization.
453 | END
454 | }
455 |
456 | variable "all_members_team_visibility" {
457 | type = string
458 | default = "secret"
459 | description = <<-END
460 | The level of privacy for the team. Must be one of `secret` or `closed`.
461 | END
462 | }
463 |
464 | variable "catch_non_existing_members" {
465 | type = bool
466 | default = false
467 | description = <<-END
468 | Validates if the list of GitHub users are existing users on every run. Use carefully as it will trigger one additional API call for every given user on every iteration.
469 | END
470 | }
471 | }
472 | }
473 |
474 | section {
475 | title = "Module Outputs"
476 | content = <<-END
477 | The following attributes are exported by the module:
478 | END
479 |
480 | output "blocked_users" {
481 | type = set(string)
482 | description = <<-END
483 | A list of `github_organization_block` resource objects
484 | that describe all users that are blocked by the organization.
485 | END
486 | }
487 |
488 | output "memberships" {
489 | type = list(membership)
490 | description = <<-END
491 | A list of `github_membership` resource objects that describe
492 | all members of the organization.
493 | END
494 | }
495 |
496 | output "projects" {
497 | type = list(project)
498 | description = <<-END
499 | A list of `github_organization_project` resource objects that
500 | describe all projects of the organization.
501 | END
502 | }
503 |
504 | output "all_members_team" {
505 | type = object(all_members_team)
506 | description = <<-END
507 | The outputs of the all members team that contains all members of your organization.
508 | END
509 | }
510 |
511 | output "settings" {
512 | type = object(all_members_team)
513 | description = <<-END
514 | The outputs of the organization settings.
515 | END
516 | }
517 | }
518 |
519 | section {
520 | title = "External Documentation"
521 |
522 | section {
523 | title = "Terraform Github Provider Documentation:"
524 | content = <<-END
525 | - https://www.terraform.io/docs/providers/github/index.html
526 | END
527 | }
528 | }
529 |
530 | section {
531 | title = "Module Versioning"
532 | content = <<-END
533 | This Module follows the principles of [Semantic Versioning (SemVer)].
534 |
535 | Given a version number `MAJOR.MINOR.PATCH`, we increment the:
536 |
537 | 1. `MAJOR` version when we make incompatible changes,
538 | 2. `MINOR` version when we add functionality in a backwards compatible manner, and
539 | 3. `PATCH` version when we make backwards compatible bug fixes.
540 | END
541 |
542 | section {
543 | title = "Backwards compatibility in `0.0.z` and `0.y.z` version"
544 | content = <<-END
545 | - Backwards compatibility in versions `0.0.z` is **not guaranteed** when `z` is increased. (Initial development)
546 | - Backwards compatibility in versions `0.y.z` is **not guaranteed** when `y` is increased. (Pre-release)
547 | END
548 | }
549 | }
550 |
551 | section {
552 | title = "About Mineiros"
553 | content = <<-END
554 | Mineiros is a [DevOps as a Service][homepage] company based in Berlin, Germany.
555 | We offer commercial support for all of our projects and encourage you to reach out
556 | if you have any questions or need help. Feel free to send us an email at [hello@mineiros.io] or join our [Community Slack channel][slack].
557 |
558 | We can also help you with:
559 |
560 | - Terraform modules for all types of infrastructure such as VPCs, Docker clusters, databases, logging and monitoring, CI, etc.
561 | - Consulting & training on AWS, Terraform and DevOps
562 | END
563 | }
564 |
565 | section {
566 | title = "Reporting Issues"
567 | content = <<-END
568 | We use GitHub [Issues] to track community reported issues and missing features.
569 | END
570 | }
571 |
572 | section {
573 | title = "Contributing"
574 | content = <<-END
575 | Contributions are always encouraged and welcome! For the process of accepting changes, we use
576 | [Pull Requests]. If you'd like more information, please see our [Contribution Guidelines].
577 | END
578 | }
579 |
580 | section {
581 | title = "Makefile Targets"
582 | content = <<-END
583 | This repository comes with a handy [Makefile].
584 | Run `make help` to see details on each available target.
585 | END
586 | }
587 |
588 | section {
589 | title = "License"
590 | content = <<-END
591 | [![license][badge-license]][apache20]
592 |
593 | This module is licensed under the Apache License Version 2.0, January 2004.
594 | Please see [LICENSE] for full details.
595 |
596 | Copyright © 2021-2022 [Mineiros GmbH][homepage]
597 | END
598 | }
599 | }
600 |
601 | references {
602 | ref "homepage" {
603 | value = "https://mineiros.io/?ref=terraform-github-organization"
604 | }
605 | ref "github-as-code" {
606 | value = "https://mineiros.io/github-as-code?ref=terraform-github-organization"
607 | }
608 | ref "hello@mineiros.io" {
609 | value = "mailto:hello@mineiros.io"
610 | }
611 | ref "badge-build" {
612 | value = "https://github.com/mineiros-io/terraform-github-organization/workflows/CI/CD%20Pipeline/badge.svg"
613 | }
614 | ref "badge-semver" {
615 | value = "https://img.shields.io/github/v/tag/mineiros-io/terraform-github-organization.svg?label=latest&sort=semver"
616 | }
617 | ref "badge-license" {
618 | value = "https://img.shields.io/badge/license-Apache%202.0-brightgreen.svg"
619 | }
620 | ref "badge-terraform" {
621 | value = "https://img.shields.io/badge/terraform-1.x-623CE4.svg?logo=terraform"
622 | }
623 | ref "badge-slack" {
624 | value = "https://img.shields.io/badge/slack-@mineiros--community-f32752.svg?logo=slack"
625 | }
626 | ref "build-status" {
627 | value = "https://github.com/mineiros-io/terraform-github-organization/actions"
628 | }
629 | ref "releases-github" {
630 | value = "https://github.com/mineiros-io/terraform-github-organization/releases"
631 | }
632 | ref "badge-tf-gh" {
633 | value = "https://img.shields.io/badge/GH-4.x-F8991D.svg?logo=terraform"
634 | }
635 | ref "releases-github-provider" {
636 | value = "https://github.com/terraform-providers/terraform-provider-github/releases"
637 | }
638 | ref "releases-terraform" {
639 | value = "https://github.com/hashicorp/terraform/releases"
640 | }
641 | ref "apache20" {
642 | value = "https://opensource.org/licenses/Apache-2.0"
643 | }
644 | ref "slack" {
645 | value = "https://join.slack.com/t/mineiros-community/shared_invite/zt-ehidestg-aLGoIENLVs6tvwJ11w9WGg"
646 | }
647 | ref "terraform" {
648 | value = "https://www.terraform.io"
649 | }
650 | ref "aws" {
651 | value = "https://aws.amazon.com/"
652 | }
653 | ref "semantic versioning (semver)" {
654 | value = "https://semver.org/"
655 | }
656 | ref "examples/example/main.tf" {
657 | value = "https://github.com/mineiros-io/terraform-github-organization/blob/main/examples/example/main.tf"
658 | }
659 | ref "variables.tf" {
660 | value = "https://github.com/mineiros-io/terraform-github-organization/blob/main/variables.tf"
661 | }
662 | ref "examples/" {
663 | value = "https://github.com/mineiros-io/terraform-github-organization/blob/main/examples"
664 | }
665 | ref "issues" {
666 | value = "https://github.com/mineiros-io/terraform-github-organization/issues"
667 | }
668 | ref "license" {
669 | value = "https://github.com/mineiros-io/terraform-github-organization/blob/main/LICENSE"
670 | }
671 | ref "makefile" {
672 | value = "https://github.com/mineiros-io/terraform-github-organization/blob/main/Makefile"
673 | }
674 | ref "pull requests" {
675 | value = "https://github.com/mineiros-io/terraform-github-organization/pulls"
676 | }
677 | ref "contribution guidelines" {
678 | value = "https://github.com/mineiros-io/terraform-github-organization/blob/main/CONTRIBUTING.md"
679 | }
680 | }
681 |
--------------------------------------------------------------------------------
/examples/README.md:
--------------------------------------------------------------------------------
1 | [
][homepage]
2 |
3 | [![GitHub tag (latest SemVer)][badge-semver]][releases-github]
4 | [![license][badge-license]][apache20]
5 | [![Terraform Version][badge-terraform]][releases-terraform]
6 | [![Join Slack][badge-slack]][slack]
7 |
8 | # Examples for using this Mineiros module
9 |
10 | - [organization/] Create a public repository on github and set it up with access and webhooks.
11 |
12 |
13 | [organization/]: https://github.com/mineiros-io/terraform-github-organization/blob/main/examples/organization
14 |
15 | [homepage]: https://mineiros.io/?ref=terraform-github-organization
16 |
17 | [badge-license]: https://img.shields.io/badge/license-Apache%202.0-brightgreen.svg
18 | [badge-terraform]: https://img.shields.io/badge/terraform-1.x-623CE4.svg?logo=terraform
19 | [badge-slack]: https://img.shields.io/badge/slack-@mineiros--community-f32752.svg?logo=slack
20 | [badge-semver]: https://img.shields.io/github/v/tag/mineiros-io/terraform-github-organization.svg?label=latest&sort=semver
21 |
22 | [releases-github]: https://github.com/mineiros-io/terraform-github-organization/releases
23 | [releases-terraform]: https://github.com/hashicorp/terraform/releases
24 | [apache20]: https://opensource.org/licenses/Apache-2.0
25 | [slack]: https://join.slack.com/t/mineiros-community/shared_invite/zt-ehidestg-aLGoIENLVs6tvwJ11w9WGg
26 |
--------------------------------------------------------------------------------
/examples/organization/README.md:
--------------------------------------------------------------------------------
1 | [
][homepage]
2 |
3 | [![license][badge-license]][apache20]
4 | [![Terraform Version][badge-terraform]][releases-terraform]
5 | [![Join Slack][badge-slack]][slack]
6 |
7 | # Create a public repository on Github
8 |
9 | ## Usage
10 |
11 | The code in [main.tf] defines the following code to manage an organization
12 | and setting it up with members and admins and also creating an all-users team.
13 | In Addition it blocks two random users and sets up two projects.
14 |
15 | ```hcl
16 | module "organization" {
17 | source = "mineiros-io/organization/github"
18 | version = "~> 0.7.0"
19 |
20 | all_members_team_name = "everyone"
21 | all_members_team_visibility = "closed"
22 |
23 | members = [
24 | "terraform-test-user-1",
25 | "terraform-test-user-2",
26 | ]
27 |
28 | admins = [
29 | "terraform-test-admin",
30 | ]
31 |
32 | # randomly chosen users, sorry for blocking you guys!
33 | blocked_users = [
34 | "Testuser1",
35 | "Testuser2",
36 | ]
37 |
38 | projects = [
39 | {
40 | name = "Test Project"
41 | body = "This is a test project created by Terraform"
42 | },
43 | {
44 | name = "Test Project without a body"
45 | }
46 | ]
47 | }
48 | ```
49 |
50 | ## Running the example
51 |
52 | ### Cloning the repository
53 |
54 | ```bash
55 | git clone https://github.com/mineiros-io/terraform-github-organization.git
56 | cd terraform-github-organization/examples/organization
57 | ```
58 |
59 | ### Initializing Terraform
60 |
61 | Run `terraform init` to initialize the example and download providers and the module.
62 |
63 | ### Planning the example
64 |
65 | Run `terraform plan` to see a plan of the changes.
66 |
67 | ### Applying the example
68 |
69 | Run `terraform apply` to create the resources.
70 | You will see a plan of the changes and Terraform will prompt you for approval to actually apply the changes.
71 |
72 | ### Destroying the example
73 |
74 | Run `terraform destroy` to destroy all resources again.
75 |
76 |
77 |
78 | [main.tf]: https://github.com/mineiros-io/terraform-github-organization/blob/main/examples/organization/main.tf
79 |
80 | [homepage]: https://mineiros.io/?ref=terraform-github-organization
81 |
82 | [badge-license]: https://img.shields.io/badge/license-Apache%202.0-brightgreen.svg
83 | [badge-terraform]: https://img.shields.io/badge/terraform-1.x%20|0.15%20|0.14%20|%200.13%20|%200.12.20+-623CE4.svg?logo=terraform
84 | [badge-slack]: https://img.shields.io/badge/slack-@mineiros--community-f32752.svg?logo=slack
85 |
86 | [releases-terraform]: https://github.com/hashicorp/terraform/releases
87 | [apache20]: https://opensource.org/licenses/Apache-2.0
88 | [slack]: https://join.slack.com/t/mineiros-community/shared_invite/zt-ehidestg-aLGoIENLVs6tvwJ11w9WGg
89 |
--------------------------------------------------------------------------------
/examples/organization/main.tf:
--------------------------------------------------------------------------------
1 | # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2 | # MANAGE A GITHUB ORGANIZATION
3 | # - manage blocked users
4 | # - manage projects
5 | # - manage memberships ( admins and members )
6 | # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
7 |
8 | # ---------------------------------------------------------------------------------------------------------------------
9 | # ENVIRONMENT VARIABLES:
10 | # ---------------------------------------------------------------------------------------------------------------------
11 | # You can provide your credentials via the
12 | # GITHUB_TOKEN and
13 | # GITHUB_OWNER, environment variables,
14 | # representing your Access Token and the organization, respectively.
15 | # ---------------------------------------------------------------------------------------------------------------------
16 |
17 | # ---------------------------------------------------------------------------------------------------------------------
18 | # EXAMPLE PROVIDER CONFIGURATION
19 | # ---------------------------------------------------------------------------------------------------------------------
20 |
21 | module "organization" {
22 | source = "mineiros-io/organization/github"
23 | version = "~> 0.9.0"
24 |
25 | all_members_team_name = "everyone"
26 | all_members_team_visibility = "closed"
27 |
28 | members = [
29 | "terraform-test-user-1",
30 | "terraform-test-user-2",
31 | ]
32 |
33 | admins = [
34 | "terraform-test-admin",
35 | ]
36 |
37 | # randomly chosen users, sorry for blocking you guys!
38 | blocked_users = [
39 | "Testuser1",
40 | "Testuser2",
41 | ]
42 |
43 | projects = [
44 | {
45 | name = "Test Project"
46 | body = "This is a test project created by Terraform"
47 | },
48 | {
49 | name = "Test Project without a body"
50 | }
51 | ]
52 | }
53 |
--------------------------------------------------------------------------------
/examples/organization/provider.tf:
--------------------------------------------------------------------------------
1 | provider "github" {}
2 |
3 | terraform {
4 | required_version = "~> 1.0"
5 |
6 | required_providers {
7 | github = {
8 | source = "integrations/github"
9 | version = "~> 5.3"
10 | }
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/go.mod:
--------------------------------------------------------------------------------
1 | module github.com/mineiros-io/terraform-github-organization/v2
2 |
3 | go 1.13
4 |
5 | require github.com/gruntwork-io/terratest v0.30.0
6 |
--------------------------------------------------------------------------------
/go.sum:
--------------------------------------------------------------------------------
1 | cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
2 | cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
3 | cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
4 | cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU=
5 | cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=
6 | cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc=
7 | cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0=
8 | cloud.google.com/go v0.51.0/go.mod h1:hWtGJ6gnXH+KgDv+V0zFGDvpi07n3z8ZNj3T1RW0Gcw=
9 | cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
10 | cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
11 | cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
12 | cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
13 | dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
14 | github.com/Azure/azure-sdk-for-go v32.5.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
15 | github.com/Azure/azure-sdk-for-go v35.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
16 | github.com/Azure/azure-sdk-for-go v38.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
17 | github.com/Azure/azure-sdk-for-go v38.1.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
18 | github.com/Azure/azure-sdk-for-go v46.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
19 | github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8=
20 | github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24=
21 | github.com/Azure/go-autorest/autorest v0.9.0/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI=
22 | github.com/Azure/go-autorest/autorest v0.9.1/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI=
23 | github.com/Azure/go-autorest/autorest v0.9.3/go.mod h1:GsRuLYvwzLjjjRoWEIyMUaYq8GNUx2nRB378IPt/1p0=
24 | github.com/Azure/go-autorest/autorest v0.11.0/go.mod h1:JFgpikqFJ/MleTTxwepExTKnFUKKszPS8UavbQYUMuw=
25 | github.com/Azure/go-autorest/autorest v0.11.5/go.mod h1:foo3aIXRQ90zFve3r0QiDsrjGDUwWhKl0ZOQy1CT14k=
26 | github.com/Azure/go-autorest/autorest/adal v0.5.0/go.mod h1:8Z9fGy2MpX0PvDjB1pEgQTmVqjGhiHBW7RJJEciWzS0=
27 | github.com/Azure/go-autorest/autorest/adal v0.6.0/go.mod h1:Z6vX6WXXuyieHAXwMj0S6HY6e6wcHn37qQMBQlvY3lc=
28 | github.com/Azure/go-autorest/autorest/adal v0.8.0/go.mod h1:Z6vX6WXXuyieHAXwMj0S6HY6e6wcHn37qQMBQlvY3lc=
29 | github.com/Azure/go-autorest/autorest/adal v0.8.1/go.mod h1:ZjhuQClTqx435SRJ2iMlOxPYt3d2C/T/7TiQCVZSn3Q=
30 | github.com/Azure/go-autorest/autorest/adal v0.9.0/go.mod h1:/c022QCutn2P7uY+/oQWWNcK9YU+MH96NgK+jErpbcg=
31 | github.com/Azure/go-autorest/autorest/adal v0.9.2/go.mod h1:/3SMAM86bP6wC9Ev35peQDUeqFZBMH07vvUOmg4z/fE=
32 | github.com/Azure/go-autorest/autorest/azure/auth v0.3.0/go.mod h1:CI4BQYBct8NS7BXNBBX+RchsFsUu5+oz+OSyR/ZIi7U=
33 | github.com/Azure/go-autorest/autorest/azure/auth v0.4.2/go.mod h1:90gmfKdlmKgfjUpnCEpOJzsUEjrWDSLwHIG73tSXddM=
34 | github.com/Azure/go-autorest/autorest/azure/auth v0.5.1/go.mod h1:ea90/jvmnAwDrSooLH4sRIehEPtG/EPUXavDh31MnA4=
35 | github.com/Azure/go-autorest/autorest/azure/cli v0.3.0/go.mod h1:rNYMNAefZMRowqCV0cVhr/YDW5dD7afFq9nXAXL4ykE=
36 | github.com/Azure/go-autorest/autorest/azure/cli v0.3.1/go.mod h1:ZG5p860J94/0kI9mNJVoIoLgXcirM2gF5i2kWloofxw=
37 | github.com/Azure/go-autorest/autorest/azure/cli v0.4.0/go.mod h1:JljT387FplPzBA31vUcvsetLKF3pec5bdAxjVU4kI2s=
38 | github.com/Azure/go-autorest/autorest/date v0.1.0/go.mod h1:plvfp3oPSKwf2DNjlBjWF/7vwR+cUD/ELuzDCXwHUVA=
39 | github.com/Azure/go-autorest/autorest/date v0.2.0/go.mod h1:vcORJHLJEh643/Ioh9+vPmf1Ij9AEBM5FuBIXLmIy0g=
40 | github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74=
41 | github.com/Azure/go-autorest/autorest/mocks v0.1.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0=
42 | github.com/Azure/go-autorest/autorest/mocks v0.2.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0=
43 | github.com/Azure/go-autorest/autorest/mocks v0.3.0/go.mod h1:a8FDP3DYzQ4RYfVAxAN3SVSiiO77gL2j2ronKKP0syM=
44 | github.com/Azure/go-autorest/autorest/mocks v0.4.0/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k=
45 | github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k=
46 | github.com/Azure/go-autorest/autorest/to v0.2.0/go.mod h1:GunWKJp1AEqgMaGLV+iocmRAJWqST1wQYhyyjXJ3SJc=
47 | github.com/Azure/go-autorest/autorest/to v0.3.0/go.mod h1:MgwOyqaIuKdG4TL/2ywSsIWKAfJfgHDo8ObuUk3t5sA=
48 | github.com/Azure/go-autorest/autorest/validation v0.1.0/go.mod h1:Ha3z/SqBeaalWQvokg3NZAlQTalVMtOIAs1aGK7G6u8=
49 | github.com/Azure/go-autorest/autorest/validation v0.2.0/go.mod h1:3EEqHnBxQGHXRYq3HT1WyXAvT7LLY3tl70hw6tQIbjI=
50 | github.com/Azure/go-autorest/autorest/validation v0.3.0/go.mod h1:yhLgjC0Wda5DYXl6JAsWyUe4KVNffhoDhG0zVzUMo3E=
51 | github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6LSNgds39diKLz7Vrc=
52 | github.com/Azure/go-autorest/logger v0.2.0/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8=
53 | github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk=
54 | github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU=
55 | github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
56 | github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
57 | github.com/GoogleCloudPlatform/k8s-cloud-provider v0.0.0-20190822182118-27a4ced34534/go.mod h1:iroGtC8B3tQiqtds1l+mgk/BBOrxbqjH+eUfFQYRc14=
58 | github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y=
59 | github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA=
60 | github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ=
61 | github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
62 | github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
63 | github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
64 | github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
65 | github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
66 | github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
67 | github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
68 | github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU=
69 | github.com/aws/aws-sdk-go v1.16.26/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
70 | github.com/aws/aws-sdk-go v1.23.8/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
71 | github.com/aws/aws-sdk-go v1.27.1/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
72 | github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
73 | github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
74 | github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
75 | github.com/blang/semver v3.5.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
76 | github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8=
77 | github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
78 | github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
79 | github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
80 | github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
81 | github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
82 | github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8=
83 | github.com/containerd/containerd v1.3.0/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
84 | github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
85 | github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk=
86 | github.com/coreos/go-oidc v2.1.0+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc=
87 | github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
88 | github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
89 | github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
90 | github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
91 | github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
92 | github.com/coreos/pkg v0.0.0-20180108230652-97fdf19511ea/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
93 | github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
94 | github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
95 | github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
96 | github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
97 | github.com/davecgh/go-spew v0.0.0-20151105211317-5215b55f46b2/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
98 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
99 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
100 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
101 | github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
102 | github.com/dimchansky/utfbom v1.1.0/go.mod h1:rO41eb7gLfo8SF1jd9F8HplJm1Fewwi4mQvIirEdv+8=
103 | github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E=
104 | github.com/docker/cli v0.0.0-20191017083524-a8ff7f821017/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
105 | github.com/docker/cli v0.0.0-20200109221225-a4f60165b7a3/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
106 | github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
107 | github.com/docker/docker v0.7.3-0.20190327010347-be7ac8be2ae0/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
108 | github.com/docker/docker v1.4.2-0.20190924003213-a8608b5b67c7/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
109 | github.com/docker/docker-credential-helpers v0.6.3/go.mod h1:WRaJzqw3CTB9bk10avuGsjVBZsD05qeibJ1/TYlvc0Y=
110 | github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec=
111 | github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
112 | github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM=
113 | github.com/docker/spdystream v0.0.0-20181023171402-6480d4af844c/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM=
114 | github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE=
115 | github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
116 | github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
117 | github.com/elazarl/goproxy v0.0.0-20170405201442-c4fc26588b6e/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc=
118 | github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc=
119 | github.com/elazarl/goproxy v0.0.0-20190911111923-ecfe977594f1/go.mod h1:Ro8st/ElPeALwNFlcTpWmkr6IoMFfkjXAvTHpevnDsM=
120 | github.com/elazarl/goproxy/ext v0.0.0-20190711103511-473e67f1d7d2/go.mod h1:gNh8nYJoAm43RfaxurUnxr+N1PwuFV3ZMl/efxlIlY8=
121 | github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
122 | github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
123 | github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
124 | github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
125 | github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
126 | github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
127 | github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU=
128 | github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
129 | github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
130 | github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
131 | github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q=
132 | github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q=
133 | github.com/go-errors/errors v1.0.2-0.20180813162953-d98b870cc4e0/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q=
134 | github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
135 | github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
136 | github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
137 | github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas=
138 | github.com/go-openapi/jsonpointer v0.0.0-20160704185906-46af16f9f7b1/go.mod h1:+35s3my2LFTysnkMfxsJBAMHj/DoqoB9knIWoYG/Vk0=
139 | github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg=
140 | github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
141 | github.com/go-openapi/jsonreference v0.0.0-20160704190145-13c6e3589ad9/go.mod h1:W3Z9FmVs9qj+KR4zFKmDPGiLdk1D9Rlm7cyMvf57TTg=
142 | github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc=
143 | github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8=
144 | github.com/go-openapi/spec v0.0.0-20160808142527-6aced65f8501/go.mod h1:J8+jY1nAiCcj+friV/PDoE1/3eeccG9LYBs0tYvLOWc=
145 | github.com/go-openapi/spec v0.19.3/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo=
146 | github.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87/go.mod h1:DXUve3Dpr1UfpPtxFw+EFuQ41HhCWZfha5jSVRG7C7I=
147 | github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
148 | github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
149 | github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
150 | github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
151 | github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
152 | github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
153 | github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
154 | github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
155 | github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
156 | github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
157 | github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
158 | github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
159 | github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
160 | github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
161 | github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
162 | github.com/golang/protobuf v0.0.0-20161109072736-4bd1920723d7/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
163 | github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
164 | github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
165 | github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
166 | github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
167 | github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
168 | github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
169 | github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
170 | github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
171 | github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
172 | github.com/google/go-containerregistry v0.0.0-20200110202235-f4fb41bf00a3/go.mod h1:2wIuQute9+hhWqvL3vEI7YB0EKluF4WcPzI1eAliazk=
173 | github.com/google/gofuzz v0.0.0-20161122191042-44d81051d367/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI=
174 | github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
175 | github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
176 | github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
177 | github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
178 | github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
179 | github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
180 | github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
181 | github.com/google/uuid v0.0.0-20161128191214-064e2069ce9c/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
182 | github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
183 | github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
184 | github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
185 | github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
186 | github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY=
187 | github.com/googleapis/gnostic v0.1.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY=
188 | github.com/googleapis/gnostic v0.2.2/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY=
189 | github.com/googleapis/gnostic v0.3.1/go.mod h1:on+2t9HRStVgn95RSsFWFz+6Q0Snyqv1awfrALZdbtU=
190 | github.com/gophercloud/gophercloud v0.1.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8=
191 | github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
192 | github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
193 | github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
194 | github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
195 | github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
196 | github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
197 | github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
198 | github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
199 | github.com/gruntwork-io/gruntwork-cli v0.5.1/go.mod h1:IBX21bESC1/LGoV7jhXKUnTQTZgQ6dYRsoj/VqxUSZQ=
200 | github.com/gruntwork-io/gruntwork-cli v0.7.0/go.mod h1:jp6Z7NcLF2avpY8v71fBx6hds9eOFPELSuD/VPv7w00=
201 | github.com/gruntwork-io/terratest v0.23.0 h1:JmGeqO0r5zRLAV55T67NEmPZArz9lN3RKd0moAKhIT4=
202 | github.com/gruntwork-io/terratest v0.23.0/go.mod h1:+fVff0FQYuRzCF3LKpKF9ac+4w384LDcwLZt7O/KmEE=
203 | github.com/gruntwork-io/terratest v0.24.2 h1:ZL7s7ZaVPRds+HqtPFh8gXjFVpKRNAAbwyVPYx3lH50=
204 | github.com/gruntwork-io/terratest v0.24.2/go.mod h1:0MCPUGIgQaAXOmw0qRLqyIXs8q6yoNPB3aZt4SkdH0M=
205 | github.com/gruntwork-io/terratest v0.25.0 h1:4Sz8q5DVEqeCC+eAfN+apL/PnqsmurGsn+fGRnZGeKU=
206 | github.com/gruntwork-io/terratest v0.25.0/go.mod h1:0MCPUGIgQaAXOmw0qRLqyIXs8q6yoNPB3aZt4SkdH0M=
207 | github.com/gruntwork-io/terratest v0.30.0 h1:1USVQG4Rg7Fp5WLuTjgU6kt+o7GM0ZcllYcsKXGv7nI=
208 | github.com/gruntwork-io/terratest v0.30.0/go.mod h1:7dNmTD2zDKUEVqfmvcUU5c9mZi+986mcXNzhzqPYPg8=
209 | github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
210 | github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
211 | github.com/hashicorp/golang-lru v0.5.3/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
212 | github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
213 | github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
214 | github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
215 | github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
216 | github.com/imdario/mergo v0.3.7/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
217 | github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
218 | github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
219 | github.com/joefitzgerald/rainbow-reporter v0.1.0/go.mod h1:481CNgqmVHQZzdIbN52CupLJyoVwB10FQ/IQlF1pdL8=
220 | github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
221 | github.com/json-iterator/go v0.0.0-20180612202835-f2b4162afba3/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
222 | github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
223 | github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
224 | github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
225 | github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
226 | github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
227 | github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
228 | github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
229 | github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
230 | github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
231 | github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
232 | github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
233 | github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
234 | github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
235 | github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
236 | github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA=
237 | github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
238 | github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
239 | github.com/magiconair/properties v1.8.1 h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzRKO2BQ4=
240 | github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
241 | github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
242 | github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
243 | github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
244 | github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs=
245 | github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
246 | github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
247 | github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
248 | github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
249 | github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE=
250 | github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
251 | github.com/mattn/go-zglob v0.0.1/go.mod h1:9fxibJccNxU2cnpIKLRRFA7zX7qhkJIQWBb449FYHOo=
252 | github.com/mattn/go-zglob v0.0.2-0.20190814121620-e3c945676326/go.mod h1:9fxibJccNxU2cnpIKLRRFA7zX7qhkJIQWBb449FYHOo=
253 | github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
254 | github.com/maxbrunsfeld/counterfeiter/v6 v6.2.2/go.mod h1:eD9eIE7cdwcMi9rYluz88Jz2VyhSmden33/aXg4oVIY=
255 | github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
256 | github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
257 | github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
258 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
259 | github.com/modern-go/reflect2 v0.0.0-20180320133207-05fbef0ca5da/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
260 | github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
261 | github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
262 | github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=
263 | github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
264 | github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
265 | github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
266 | github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw=
267 | github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
268 | github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
269 | github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
270 | github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
271 | github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
272 | github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
273 | github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
274 | github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
275 | github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
276 | github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
277 | github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
278 | github.com/oracle/oci-go-sdk v7.1.0+incompatible/go.mod h1:VQb79nF8Z2cwLkLS35ukwStZIg5F66tcBccjip/j888=
279 | github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
280 | github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
281 | github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
282 | github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
283 | github.com/pkg/errors v0.9.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
284 | github.com/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
285 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
286 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
287 | github.com/pquerna/cachecontrol v0.0.0-20171018203845-0dec1b30a021/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA=
288 | github.com/pquerna/otp v1.2.0/go.mod h1:dkJfzwRKNiegxyNb54X/3fLwhCynbMspSyWKnvi1AEg=
289 | github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
290 | github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
291 | github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
292 | github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
293 | github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
294 | github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
295 | github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
296 | github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
297 | github.com/remyoudompheng/bigfft v0.0.0-20170806203942-52369c62f446/go.mod h1:uYEyJGbgTkfkS4+E/PavXkNJcbFIpEtjt2B0KDQ5+9M=
298 | github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
299 | github.com/rogpeppe/go-charset v0.0.0-20180617210344-2471d30d28b4/go.mod h1:qgYeAmZ5ZIpBWTGllZSQnw97Dj+woV0toclVaRGI8pc=
300 | github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
301 | github.com/rubiojr/go-vhd v0.0.0-20160810183302-0bfd3b39853c/go.mod h1:DM5xW0nvfNNm2uytzsvhI3OnX8uzaRAg8UX/CnDqbto=
302 | github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
303 | github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
304 | github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
305 | github.com/sclevine/spec v1.2.0/go.mod h1:W4J29eT/Kzv7/b9IWLB055Z+qvVC9vt0Arko24q7p+U=
306 | github.com/shopspring/decimal v0.0.0-20200105231215-408a2507e114/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
307 | github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
308 | github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
309 | github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
310 | github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
311 | github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
312 | github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
313 | github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
314 | github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
315 | github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
316 | github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
317 | github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
318 | github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
319 | github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
320 | github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
321 | github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
322 | github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
323 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
324 | github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
325 | github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
326 | github.com/stretchr/testify v0.0.0-20151208002404-e3a8ff8ce365/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
327 | github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
328 | github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
329 | github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
330 | github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
331 | github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
332 | github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
333 | github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
334 | github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
335 | github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
336 | github.com/vdemeester/k8s-pkg-credentialprovider v0.0.0-20200107171650-7c61ffa44238/go.mod h1:JwQJCMWpUDqjZrB5jpw0f5VbN7U95zxFy1ZDpoEarGo=
337 | github.com/vmware/govmomi v0.20.3/go.mod h1:URlwyTFZX72RmxtxuaFL2Uj3fD1JTvZdx59bHWk6aFU=
338 | github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
339 | github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
340 | go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
341 | go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg=
342 | go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
343 | go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
344 | go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
345 | go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
346 | go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
347 | go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
348 | golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
349 | golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
350 | golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
351 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
352 | golang.org/x/crypto v0.0.0-20190418165655-df01cb2cc480/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
353 | golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
354 | golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
355 | golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
356 | golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586 h1:7KByu05hhLed2MO29w7p1XfZvZ13m8mub3shuVftRs0=
357 | golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
358 | golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
359 | golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
360 | golang.org/x/crypto v0.0.0-20200109152110-61a87790db17 h1:nVJ3guKA9qdkEQ3TUdXI9QSINo2CUPM/cySEvw2w8I0=
361 | golang.org/x/crypto v0.0.0-20200109152110-61a87790db17/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
362 | golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
363 | golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI=
364 | golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
365 | golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
366 | golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
367 | golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
368 | golang.org/x/exp v0.0.0-20190312203227-4b39c73a6495/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
369 | golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
370 | golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek=
371 | golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
372 | golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
373 | golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
374 | golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
375 | golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
376 | golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
377 | golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
378 | golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
379 | golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
380 | golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
381 | golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
382 | golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
383 | golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
384 | golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
385 | golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
386 | golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
387 | golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
388 | golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
389 | golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
390 | golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
391 | golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
392 | golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
393 | golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
394 | golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
395 | golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
396 | golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
397 | golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
398 | golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
399 | golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
400 | golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
401 | golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
402 | golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7 h1:fHDIZ2oxGnUZRN6WgWFCbYBjH9uqVPRCUVUDhs0wnbA=
403 | golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
404 | golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
405 | golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
406 | golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553 h1:efeOvDhwQ29Dj3SdAV/MJf8oukgn+8D8WgaCaRMchF8=
407 | golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
408 | golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
409 | golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
410 | golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
411 | golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
412 | golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
413 | golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
414 | golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
415 | golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
416 | golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
417 | golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
418 | golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
419 | golang.org/x/sys v0.0.0-20170830134202-bb24a47a89ea/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
420 | golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
421 | golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
422 | golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
423 | golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
424 | golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
425 | golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
426 | golang.org/x/sys v0.0.0-20190209173611-3b5209105503/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
427 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
428 | golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
429 | golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
430 | golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
431 | golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
432 | golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
433 | golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
434 | golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
435 | golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
436 | golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
437 | golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
438 | golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
439 | golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
440 | golang.org/x/sys v0.0.0-20191010194322-b09406accb47/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
441 | golang.org/x/sys v0.0.0-20191022100944-742c48ecaeb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
442 | golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
443 | golang.org/x/sys v0.0.0-20191110163157-d32e6e3b99c4 h1:Hynbrlo6LbYI3H1IqXpkVDOcX/3HiPdhVEuyj5a59RM=
444 | golang.org/x/sys v0.0.0-20191110163157-d32e6e3b99c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
445 | golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
446 | golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
447 | golang.org/x/sys v0.0.0-20200107162124-548cf772de50 h1:YvQ10rzcqWXLlJZ3XCUoO25savxmscf4+SC+ZqiCHhA=
448 | golang.org/x/sys v0.0.0-20200107162124-548cf772de50/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
449 | golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
450 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
451 | golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
452 | golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
453 | golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
454 | golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
455 | golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
456 | golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
457 | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
458 | golang.org/x/tools v0.0.0-20181011042414-1f849cf54d09/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
459 | golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
460 | golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
461 | golang.org/x/tools v0.0.0-20190206041539-40960b6deb8e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
462 | golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
463 | golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
464 | golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
465 | golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
466 | golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
467 | golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
468 | golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
469 | golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
470 | golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
471 | golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
472 | golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
473 | golang.org/x/tools v0.0.0-20190706070813-72ffa07ba3db/go.mod h1:jcCCGcm9btYwXyDqrUWc6MKQKKGJCWEQ3AfLSRIbEuI=
474 | golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
475 | golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
476 | golang.org/x/tools v0.0.0-20190920225731-5eefd052ad72/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
477 | golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
478 | golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
479 | golang.org/x/tools v0.0.0-20191205215504-7b8c8591a921/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
480 | golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
481 | golang.org/x/tools v0.0.0-20200113040837-eac381796e91/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
482 | golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
483 | golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
484 | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
485 | gonum.org/v1/gonum v0.0.0-20190331200053-3d26580ed485/go.mod h1:2ltnJ7xHfj0zHS40VVPYEAAMTa3ZGguvHGBSJeRWqE0=
486 | gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw=
487 | gonum.org/v1/netlib v0.0.0-20190331212654-76723241ea4e/go.mod h1:kS+toOQn6AQKjmKJ7gzohV1XkqsFehRA2FbsbkopSuQ=
488 | google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
489 | google.golang.org/api v0.6.1-0.20190607001116-5213b8090861/go.mod h1:btoxGiFvQNVUZQ8W08zLtrVS08CNpINPEfxXxgJL1Q4=
490 | google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
491 | google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
492 | google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
493 | google.golang.org/api v0.9.1-0.20190821000710-329ecc3c9c34/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
494 | google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
495 | google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
496 | google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
497 | google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
498 | google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
499 | google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
500 | google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
501 | google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
502 | google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
503 | google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
504 | google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
505 | google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
506 | google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
507 | google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
508 | google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
509 | google.golang.org/genproto v0.0.0-20200108215221-bd8f9a0ef82f/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
510 | google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
511 | google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
512 | google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
513 | google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
514 | google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
515 | google.golang.org/grpc v1.24.0/go.mod h1:XDChyiUovWa60DnaeDeZmSW86xtLtjtZbwvSiRnRtcA=
516 | google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
517 | gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
518 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
519 | gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
520 | gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
521 | gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
522 | gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
523 | gopkg.in/gcfg.v1 v1.2.0/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o=
524 | gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
525 | gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k=
526 | gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
527 | gopkg.in/square/go-jose.v2 v2.2.2/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
528 | gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
529 | gopkg.in/warnings.v0 v0.1.1/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=
530 | gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
531 | gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
532 | gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
533 | gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
534 | gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I=
535 | gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
536 | gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
537 | gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
538 | gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
539 | honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
540 | honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
541 | honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
542 | honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
543 | honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
544 | k8s.io/api v0.0.0-20181110191121-a33c8200050f/go.mod h1:iuAfoD4hCxJ8Onx9kaTIt30j7jUFS00AXQi6QMi99vA=
545 | k8s.io/api v0.17.0/go.mod h1:npsyOePkeP0CPwyGfXDHxvypiYMJxBWAMpQxCaJ4ZxI=
546 | k8s.io/api v0.18.3/go.mod h1:UOaMwERbqJMfeeeHc8XJKawj4P9TgDRnViIqqBeH2QA=
547 | k8s.io/apimachinery v0.0.0-20190704094520-6f131bee5e2c/go.mod h1:ccL7Eh7zubPUSh9A3USN90/OzHNSVN6zxzde07TDCL0=
548 | k8s.io/apimachinery v0.17.0/go.mod h1:b9qmWdKlLuU9EBh+06BtLcSf/Mu89rWL33naRxs1uZg=
549 | k8s.io/apimachinery v0.18.3/go.mod h1:OaXp26zu/5J7p0f92ASynJa1pZo06YlV9fG7BoWbCko=
550 | k8s.io/apiserver v0.17.0/go.mod h1:ABM+9x/prjINN6iiffRVNCBR2Wk7uY4z+EtEGZD48cg=
551 | k8s.io/client-go v0.0.0-20190704095228-386e588352a4/go.mod h1:7vJpHMYJwNQCWgzmNV+VYUl1zCObLyodBc8nIyt8L5s=
552 | k8s.io/client-go v0.17.0/go.mod h1:TYgR6EUHs6k45hb6KWjVD6jFZvJV4gHDikv/It0xz+k=
553 | k8s.io/client-go v0.18.3/go.mod h1:4a/dpQEvzAhT1BbuWW09qvIaGw6Gbu1gZYiQZIi1DMw=
554 | k8s.io/cloud-provider v0.17.0/go.mod h1:Ze4c3w2C0bRsjkBUoHpFi+qWe3ob1wI2/7cUn+YQIDE=
555 | k8s.io/code-generator v0.0.0-20191121015212-c4c8f8345c7e/go.mod h1:DVmfPQgxQENqDIzVR2ddLXMH34qeszkKSdH/N+s+38s=
556 | k8s.io/component-base v0.17.0/go.mod h1:rKuRAokNMY2nn2A6LP/MiwpoaMRHpfRnrPaUJJj1Yoc=
557 | k8s.io/csi-translation-lib v0.17.0/go.mod h1:HEF7MEz7pOLJCnxabi45IPkhSsE/KmxPQksuCrHKWls=
558 | k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
559 | k8s.io/gengo v0.0.0-20190822140433-26a664648505/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
560 | k8s.io/klog v0.0.0-20181102134211-b9b56d5dfc92/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk=
561 | k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk=
562 | k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I=
563 | k8s.io/kube-openapi v0.0.0-20191107075043-30be4d16710a/go.mod h1:1TqjTSzOxsLGIKfj0lK8EeCP7K1iUG65v09OM0/WG5E=
564 | k8s.io/kube-openapi v0.0.0-20200410145947-61e04a5be9a6/go.mod h1:GRQhZsXIAJ1xR0C9bd8UpWHZ5plfAS9fzPjJuQ6JL3E=
565 | k8s.io/kubernetes v1.11.10/go.mod h1:ocZa8+6APFNC2tX1DZASIbocyYT5jHzqFVsY5aoB7Jk=
566 | k8s.io/legacy-cloud-providers v0.17.0/go.mod h1:DdzaepJ3RtRy+e5YhNtrCYwlgyK87j/5+Yfp0L9Syp8=
567 | k8s.io/utils v0.0.0-20191114184206-e782cd3c129f/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew=
568 | k8s.io/utils v0.0.0-20200324210504-a9aa75ae1b89/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew=
569 | modernc.org/cc v1.0.0/go.mod h1:1Sk4//wdnYJiUIxnW8ddKpaOJCF37yAdqYnkxUpaYxw=
570 | modernc.org/golex v1.0.0/go.mod h1:b/QX9oBD/LhixY6NDh+IdGv17hgB+51fET1i2kPSmvk=
571 | modernc.org/mathutil v1.0.0/go.mod h1:wU0vUrJsVWBZ4P6e7xtFJEhFSNsfRLJ8H458uRjg03k=
572 | modernc.org/strutil v1.0.0/go.mod h1:lstksw84oURvj9y3tn8lGvRxyRC1S2+g5uuIzNfIOBs=
573 | modernc.org/xc v1.0.0/go.mod h1:mRNCo0bvLjGhHO9WsyuKVU4q0ceiDDDoEeWDJHrNx8I=
574 | rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
575 | sigs.k8s.io/structured-merge-diff v0.0.0-20190525122527-15d366b2352e/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI=
576 | sigs.k8s.io/structured-merge-diff v1.0.1-0.20191108220359-b1b620dd3f06/go.mod h1:/ULNhyfzRopfcjskuui0cTITekDduZ7ycKN3oUT9R18=
577 | sigs.k8s.io/structured-merge-diff/v3 v3.0.0-20200116222232-67a7b8c61874/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw=
578 | sigs.k8s.io/structured-merge-diff/v3 v3.0.0/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw=
579 | sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
580 | sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc=
581 |
--------------------------------------------------------------------------------
/main.tf:
--------------------------------------------------------------------------------
1 | # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2 | # MANAGE A GITHUB ORGANIZATION
3 | # - manage memberships ( admins and members )
4 | # - manage blocked users
5 | # - manage projects
6 | # - create the team "all" that contains every member of the organization
7 | # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
8 |
9 | locals {
10 | admins = { for i in var.admins : lower(i) => "admin" }
11 | members = { for i in var.members : lower(i) => "member" }
12 | memberships = merge(local.admins, local.members)
13 | }
14 |
15 | # Safeguard for validating if a GitHub user exists on `terraform plan`
16 | data "github_user" "user" {
17 | for_each = var.catch_non_existing_members ? local.memberships : {}
18 |
19 | username = each.key
20 | }
21 |
22 | resource "github_membership" "membership" {
23 | for_each = local.memberships
24 |
25 | username = each.key
26 | role = each.value
27 | }
28 |
29 | resource "github_organization_block" "blocked_user" {
30 | for_each = var.blocked_users
31 |
32 | username = each.value
33 | }
34 |
35 | locals {
36 | projects = { for p in var.projects : lookup(p, "id", lower(p.name)) => merge({
37 | body = null
38 | }, p) }
39 | }
40 |
41 | resource "github_organization_project" "project" {
42 | for_each = local.projects
43 |
44 | name = each.value.name
45 | body = each.value.body
46 | }
47 |
48 | resource "github_team" "all" {
49 | count = var.all_members_team_name != null ? 1 : 0
50 |
51 | name = var.all_members_team_name
52 | description = "This teams contains all members of our organization."
53 | privacy = var.all_members_team_visibility
54 | }
55 |
56 | resource "github_team_membership" "all" {
57 | for_each = var.all_members_team_name != null ? local.memberships : {}
58 |
59 | team_id = github_team.all[0].id
60 | username = each.key
61 | role = "member"
62 | }
63 |
64 | resource "github_organization_settings" "settings" {
65 | count = length(var.settings) > 0 ? 1 : 0
66 |
67 | billing_email = var.settings.billing_email
68 | company = try(var.settings.company, null)
69 | blog = try(var.settings.blog, null)
70 | email = try(var.settings.email, null)
71 | twitter_username = try(var.settings.twitter_username, null)
72 | location = try(var.settings.location, null)
73 | name = try(var.settings.name, null)
74 | description = try(var.settings.description, null)
75 | has_organization_projects = try(var.settings.has_organization_projects, true)
76 | has_repository_projects = try(var.settings.has_repository_projects, true)
77 | default_repository_permission = try(var.settings.default_repository_permission, "read")
78 | members_can_create_repositories = try(var.settings.members_can_create_repositories, false)
79 | members_can_create_public_repositories = try(var.settings.members_can_create_public_repositories, false)
80 | members_can_create_private_repositories = try(var.settings.members_can_create_private_repositories, false)
81 | members_can_create_internal_repositories = try(var.settings.members_can_create_internal_repositories, false)
82 | members_can_create_pages = try(var.settings.members_can_create_pages, false)
83 | members_can_create_public_pages = try(var.settings.members_can_create_public_pages, false)
84 | members_can_create_private_pages = try(var.settings.members_can_create_private_pages, false)
85 | members_can_fork_private_repositories = try(var.settings.members_can_fork_private_repositories, false)
86 | web_commit_signoff_required = try(var.settings.web_commit_signoff_required, false)
87 | advanced_security_enabled_for_new_repositories = try(var.settings.advanced_security_enabled_for_new_repositories, false)
88 | dependabot_alerts_enabled_for_new_repositories = try(var.settings.dependabot_alerts_enabled_for_new_repositories, false)
89 | dependabot_security_updates_enabled_for_new_repositories = try(var.settings.advanced_security_enabled_for_new_repositories, false)
90 | dependency_graph_enabled_for_new_repositories = try(var.settings.dependency_graph_enabled_for_new_repositories, false)
91 | secret_scanning_enabled_for_new_repositories = try(var.settings.secret_scanning_enabled_for_new_repositories, false)
92 | secret_scanning_push_protection_enabled_for_new_repositories = try(var.settings.secret_scanning_push_protection_enabled_for_new_repositories, false)
93 | }
94 |
--------------------------------------------------------------------------------
/outputs.tf:
--------------------------------------------------------------------------------
1 | # ------------------------------------------------------------------------------
2 | # OUTPUT CALCULATED VARIABLES (prefer full objects)
3 | # ------------------------------------------------------------------------------
4 |
5 | output "all_members_team" {
6 | description = "The outputs of the all members team that contains all members of your organization."
7 | value = try(github_team.all[0], {})
8 | }
9 |
10 | # ------------------------------------------------------------------------------
11 | # OUTPUT ALL RESOURCES AS FULL OBJECTS
12 | # ------------------------------------------------------------------------------
13 |
14 | output "blocked_users" {
15 | description = "The list of users that are blocked by the organiation."
16 | value = github_organization_block.blocked_user
17 | }
18 |
19 | output "memberships" {
20 | description = "A map of members and admins keyed by username."
21 | value = github_membership.membership
22 | }
23 |
24 | output "projects" {
25 | description = "A map of projects keyed by the id (default: project name)."
26 | value = github_organization_project.project
27 | }
28 |
29 | output "settings" {
30 | description = "The outputs of the organization settings."
31 | value = try(github_organization_settings.settings[0], {})
32 | }
33 |
34 | # ------------------------------------------------------------------------------
35 | # OUTPUT ALL INPUT VARIABLES
36 | # ------------------------------------------------------------------------------
37 |
38 | # ------------------------------------------------------------------------------
39 | # OUTPUT MODULE CONFIGURATION
40 | # ------------------------------------------------------------------------------
41 |
--------------------------------------------------------------------------------
/test/README.md:
--------------------------------------------------------------------------------
1 | [
][homepage]
2 |
3 | [![license][badge-license]][apache20]
4 | [![Terraform Version][badge-terraform]][releases-terraform]
5 | [![Join Slack][badge-slack]][slack]
6 |
7 | # Tests
8 |
9 | This directory contains a number of automated tests that cover the functionality
10 | of the modules that ship with this repository.
11 |
12 | ## Introduction
13 |
14 | We are using [Terratest] for automated tests that are located in the
15 | [`test/` directory][Testdirectory]. Terratest deploys _real_ infrastructure
16 | (e.g., servers) in a _real_ environment (e.g., AWS).
17 |
18 | The basic usage pattern for writing automated tests with Terratest is to:
19 |
20 | 1. Write tests using Go's built-in [package testing]: you create a file ending
21 | in `_test.go` and run tests with the `go test` command.
22 | 2. Use Terratest to execute your _real_ IaC tools (e.g., Terraform, Packer, etc.)
23 | to deploy _real_ infrastructure (e.g., servers) in a _real_ environment (e.g., AWS).
24 | 3. Validate that the infrastructure works correctly in that environment by
25 | making HTTP requests, API calls, SSH connections, etc.
26 | 4. Undeploy everything at the end of the test.
27 |
28 | **Note #1**: Many of these tests create real resources in an AWS account.
29 | That means they cost money to run, especially if you don't clean up after
30 | yourself. Please be considerate of the resources you create and take extra care
31 | to clean everything up when you're done!
32 |
33 | **Note #2**: Never hit `CTRL + C` or cancel a build once tests are running or
34 | the cleanup tasks won't run!
35 |
36 | **Note #3**: We set `-timeout 45m` on all tests not because they necessarily
37 | take 45 minutes, but because Go has a default test timeout of 10 minutes, after
38 | which it does a `SIGQUIT`, preventing the tests from properly cleaning up after
39 | themselves. Therefore, we set a timeout of 45 minutes to make sure all tests
40 | have enough time to finish and cleanup.
41 |
42 | ## How to run the tests
43 |
44 | This repository comes with a [Makefile], that helps you to run the
45 | tests in a convenient way.
46 | Alternatively, you can also run the tests without Docker.
47 |
48 | ### Run the tests with Docker
49 |
50 | 1. Install [Docker]
51 | 2. Set your AWS credentials as environment variables: `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`
52 | 3. Run `make docker-run-tests`
53 |
54 | ### Run the tests without Docker
55 |
56 | 1. Install the latest version of [Go].
57 | 2. Install [Terraform].
58 | 3. Set your AWS credentials as environment variables: `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`
59 | 4. Install go dependencies: `go mod download`
60 | 5. Run all tests: `go test -v -count 1 -timeout 45m -parallel 128 ./test/...`
61 | 6. Run a specific test: `go test -count 1 -v -timeout 45m -parallel 128 test/example_test.go`
62 |
63 |
64 |
65 | [Makefile]: https://github.com/mineiros-io/terraform-github-organization/blob/main/Makefile
66 | [Testdirectory]: https://github.com/mineiros-io/terraform-github-organization/tree/main/test
67 |
68 | [homepage]: https://mineiros.io/?ref=terraform-github-organization
69 | [Terratest]: https://github.com/gruntwork-io/terratest
70 | [package testing]: https://golang.org/pkg/testing/
71 | [Docker]: https://docs.docker.com/get-started/
72 | [Go]: https://golang.org/
73 | [Terraform]: https://www.terraform.io/downloads.html
74 | [badge-license]: https://img.shields.io/badge/license-Apache%202.0-brightgreen.svg
75 | [badge-terraform]: https://img.shields.io/badge/terraform-1.x%20|0.15%20|0.14%20|%200.13%20|%200.12.20+-623CE4.svg?logo=terraform
76 | [badge-slack]: https://img.shields.io/badge/slack-@mineiros--community-f32752.svg?logo=slack
77 |
78 | [releases-terraform]: https://github.com/hashicorp/terraform/releases
79 | [apache20]: https://opensource.org/licenses/Apache-2.0
80 | [slack]: https://join.slack.com/t/mineiros-community/shared_invite/zt-ehidestg-aLGoIENLVs6tvwJ11w9WGg
81 |
--------------------------------------------------------------------------------
/test/github_organization_test.go:
--------------------------------------------------------------------------------
1 | package test
2 |
3 | import (
4 | "fmt"
5 | "os"
6 | "testing"
7 |
8 | "github.com/gruntwork-io/terratest/modules/random"
9 |
10 | "github.com/gruntwork-io/terratest/modules/terraform"
11 | )
12 |
13 | var githubOrganization, githubToken string
14 |
15 | func init() {
16 | githubOrganization = os.Getenv("GITHUB_OWNER")
17 | githubToken = os.Getenv("GITHUB_TOKEN")
18 |
19 | if githubOrganization == "" {
20 | panic("Please set a github organization using the GITHUB_OWNER environment variable.")
21 | }
22 |
23 | if githubToken == "" {
24 | panic("Please set a github token using the GITHUB_TOKEN environment variable.")
25 | }
26 | }
27 |
28 | func TestGithubOrganization(t *testing.T) {
29 | t.Parallel()
30 |
31 | expectedProjects := []interface{}{
32 | map[string]interface{}{
33 | "name": fmt.Sprintf("test-project-%s", random.UniqueId()),
34 | "body": "This is a test project created by Terraform",
35 | },
36 | map[string]interface{}{
37 | "name": fmt.Sprintf("test-project-%s", random.UniqueId()),
38 | },
39 | }
40 |
41 | expectedBlockedUsers := []string{
42 | "Testuser1",
43 | "Testuser2",
44 | }
45 |
46 | expectedAdmins := []string{
47 | "terraform-test-admin",
48 | }
49 |
50 | expectedMembers := []string{
51 | "terraform-test-user-1",
52 | "terraform-test-user-2",
53 | }
54 |
55 | terraformOptions := &terraform.Options{
56 | // The path to where your Terraform code is located
57 | TerraformDir: "organization",
58 | Upgrade: true,
59 | Vars: map[string]interface{}{
60 | "blocked_users": expectedBlockedUsers,
61 | "admins": expectedAdmins,
62 | "members": expectedMembers,
63 | "projects": expectedProjects,
64 | },
65 | }
66 |
67 | // At the end of the test, run `terraform destroy` to clean up any resources that were created
68 | defer terraform.Destroy(t, terraformOptions)
69 |
70 | // This will run `terraform init` and `terraform apply` and fail the test if there are any errors
71 | terraform.InitAndApply(t, terraformOptions)
72 |
73 | }
74 |
--------------------------------------------------------------------------------
/test/organization/main.tf:
--------------------------------------------------------------------------------
1 | # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2 | # MANAGE A GITHUB ORGANIZATION
3 | # - manage blocked users
4 | # - manage projects
5 | # - manage memberships ( admins and members )
6 | # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
7 |
8 | module "organization" {
9 | source = "../.."
10 |
11 | all_members_team_name = var.all_members_team_name
12 | all_members_team_visibility = "closed"
13 | members = var.members
14 | admins = var.admins
15 | blocked_users = var.blocked_users
16 | projects = var.projects
17 | settings = var.settings
18 | }
19 |
--------------------------------------------------------------------------------
/test/organization/outputs.tf:
--------------------------------------------------------------------------------
1 | output "all_outputs" {
2 | description = "All outputs exposed by this module."
3 | value = module.organization
4 | }
5 |
6 | output "blocked_users" {
7 | description = "A list of users that are blocked by the organiation."
8 | value = module.organization.blocked_users
9 | }
10 |
11 | output "memberships" {
12 | description = "A map of members and admins keyed by username."
13 | value = module.organization.memberships
14 | }
15 |
16 | output "projects" {
17 | description = "A map of projects keyed by the id (default: project name)."
18 | value = module.organization.projects
19 | }
20 |
21 |
--------------------------------------------------------------------------------
/test/organization/provider.tf:
--------------------------------------------------------------------------------
1 | provider "github" {}
2 |
3 | terraform {
4 | required_version = "~> 1.0"
5 |
6 | required_providers {
7 | github = {
8 | source = "integrations/github"
9 | version = "~> 5.0"
10 | }
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/test/organization/variables.tf:
--------------------------------------------------------------------------------
1 | # ---------------------------------------------------------------------------------------------------------------------
2 | # REQUIRED VARIABLES
3 | # These variables must be set when using this module.
4 | # ---------------------------------------------------------------------------------------------------------------------
5 |
6 | # ---------------------------------------------------------------------------------------------------------------------
7 | # OPTIONAL VARIABLES
8 | # These variables have defaults, but may be overridden.
9 | # ---------------------------------------------------------------------------------------------------------------------
10 |
11 | variable "admins" {
12 | description = "A list of admins to add to the organization."
13 | type = set(string)
14 | default = [
15 | "terraform-test-admin",
16 | ]
17 | }
18 |
19 | variable "all_members_team_name" {
20 | description = "The name of the team that contains all members of the organization."
21 | type = string
22 | default = "everyone"
23 | }
24 |
25 | variable "all_members_team_visibility" {
26 | description = "The level of privacy for the team. Must be one of `secret` or `closed`."
27 | type = string
28 | default = "secret"
29 | }
30 |
31 | variable "blocked_users" {
32 | description = "A list of users that should be blocked by the organization."
33 | type = set(string)
34 |
35 | # randomly chosen users, sorry for blocking you guys!
36 | default = [
37 | "Testuser1",
38 | "Testuser2",
39 | ]
40 | }
41 |
42 | variable "members" {
43 | description = "A list of members to add to the organization."
44 | type = set(string)
45 | default = [
46 | "terraform-test-user-1",
47 | "terraform-test-user-2",
48 | ]
49 | }
50 |
51 | variable "projects" {
52 | description = "A list of projects to add to the organization."
53 | type = any
54 | default = [
55 | {
56 | name = "Test Project"
57 | body = "This is a test project created by Terraform"
58 | },
59 | {
60 | name = "Test Project without a body"
61 | }
62 | ]
63 | }
64 |
65 | variable "settings" {
66 | description = "A map of settings to apply to the organization."
67 | type = any
68 | default = {
69 | billing_email = "hello@mineiros.io"
70 | company = "Mineiros"
71 | blog = "https://blog.mineiros.io"
72 | email = "hello@mineiros.io"
73 | twitter_username = "mineirosio"
74 | location = "Berlin"
75 | name = "Terraform Tests"
76 | description = "This Organization is just used to run some Terraform tests for https://github.com/mineiros-io"
77 | has_organization_projects = true
78 | has_repository_projects = true
79 | default_repository_permission = "read"
80 | members_can_create_repositories = false
81 | members_can_create_public_repositories = false
82 | members_can_create_private_repositories = false
83 | members_can_create_internal_repositories = false
84 | members_can_create_pages = false
85 | members_can_create_public_pages = false
86 | members_can_create_private_pages = false
87 | members_can_fork_private_repositories = false
88 | web_commit_signoff_required = false
89 | advanced_security_enabled_for_new_repositories = false
90 | dependabot_alerts_enabled_for_new_repositories = false
91 | dependabot_security_updates_enabled_for_new_repositories = false
92 | dependency_graph_enabled_for_new_repositories = false
93 | secret_scanning_enabled_for_new_repositories = false
94 | secret_scanning_push_protection_enabled_for_new_repositories = false
95 | }
96 | }
97 |
--------------------------------------------------------------------------------
/variables.tf:
--------------------------------------------------------------------------------
1 | # ---------------------------------------------------------------------------------------------------------------------
2 | # REQUIRED VARIABLES
3 | # These variables must be set when using this module.
4 | # ---------------------------------------------------------------------------------------------------------------------
5 |
6 | # ---------------------------------------------------------------------------------------------------------------------
7 | # OPTIONAL VARIABLES
8 | # These variables have defaults, but may be overridden.
9 | # ---------------------------------------------------------------------------------------------------------------------
10 |
11 | variable "all_members_team_name" {
12 | description = "(Optional) The name of the team that contains all members of the organization."
13 | type = string
14 | default = null
15 | }
16 |
17 | variable "all_members_team_visibility" {
18 | description = "(Optional) The level of privacy for the team. Must be one of 'secret' or 'closed'."
19 | type = string
20 | default = "secret"
21 | }
22 |
23 | variable "catch_non_existing_members" {
24 | description = "(Optional) Validates if the list of GitHub users are existing users on every run. Use carefully as it will trigger one additional API call for every given user on every iteration. Default is 'false'"
25 | type = bool
26 | default = false
27 | }
28 |
29 | variable "blocked_users" {
30 | description = "(Optional) A list of usernames to be blocked from a GitHub organization."
31 | type = set(string)
32 |
33 | #
34 | # Example:
35 | #
36 | # blocked_users = [
37 | # "blocked-user"
38 | # ]
39 | #
40 |
41 | default = []
42 | }
43 |
44 | variable "members" {
45 | type = set(string)
46 | description = "(Optional) A list of users to be added to your organization with member role. When applied, an invitation will be sent to the user to become part of the organization. When destroyed, either the invitation will be cancelled or the user will be removed."
47 |
48 | #
49 | # Example:
50 | #
51 | # members = [
52 | # "admin",
53 | # "another-admin"
54 | # ]
55 | #
56 |
57 | default = []
58 | }
59 |
60 | variable "admins" {
61 | type = set(string)
62 | description = "(Optional) A list of users to be added to your organization with admin role. When applied, an invitation will be sent to the user to become part of the organization. When destroyed, either the invitation will be cancelled or the user will be removed."
63 |
64 | #
65 | # Example:
66 | #
67 | # admins = [
68 | # "admin",
69 | # "another-admin"
70 | # ]
71 | #
72 |
73 | default = []
74 | }
75 |
76 | variable "projects" {
77 | type = any
78 |
79 | # We can't use a detailed type specification due to a terraform limitation. However, this might be changed in a future
80 | # Terraform version. See https://github.com/hashicorp/terraform/issues/19898 and https://github.com/hashicorp/terraform/issues/22449
81 | #
82 | # type = list(object({
83 | # name = string
84 | # body = optional(string)
85 | # }))
86 |
87 | description = "(Optional) Create and manage projects for the GitHub organization."
88 |
89 | #
90 | # Example:
91 | #
92 | # projects = [
93 | # {
94 | # name = "Test Project"
95 | # body = "This is a test project created by Terraform"
96 | # },
97 | # {
98 | # name = "Test Project without a body"
99 | # }
100 | # ]
101 | #
102 |
103 | default = []
104 | }
105 |
106 | variable "settings" {
107 | type = any
108 | description = "A map of settings for the GitHub organization."
109 | #
110 | # Example
111 | # settings = {
112 | # billing_email = "hello@mineiros.io"
113 | # company = "Mineiros"
114 | # blog = "https://blog.mineiros.io"
115 | # email = "hello@mineiros.io"
116 | # twitter_username = "mineirosio"
117 | # location = "Berlin"
118 | # name = "Terraform Tests"
119 | # description = "This Organization is just used to run some Terraform tests for https://github.com/mineiros-io"
120 | # has_organization_projects = true
121 | # has_repository_projects = true
122 | # default_repository_permission = "read"
123 | # members_can_create_repositories = false
124 | # members_can_create_public_repositories = false
125 | # members_can_create_private_repositories = false
126 | # members_can_create_internal_repositories = false
127 | # members_can_create_pages = false
128 | # members_can_create_public_pages = false
129 | # members_can_create_private_pages = false
130 | # members_can_fork_private_repositories = false
131 | # web_commit_signoff_required = false
132 | # advanced_security_enabled_for_new_repositories = false
133 | # dependabot_alerts_enabled_for_new_repositories = false
134 | # dependabot_security_updates_enabled_for_new_repositories = false
135 | # dependency_graph_enabled_for_new_repositories = false
136 | # secret_scanning_enabled_for_new_repositories = false
137 | # secret_scanning_push_protection_enabled_for_new_repositories = false
138 | # }
139 | #
140 |
141 | default = {}
142 | }
143 |
--------------------------------------------------------------------------------
/versions.tf:
--------------------------------------------------------------------------------
1 | # ---------------------------------------------------------------------------------------------------------------------
2 | # SET TERRAFORM AND PROVIDER REQUIREMENTS FOR RUNNING THIS MODULE
3 | # ---------------------------------------------------------------------------------------------------------------------
4 |
5 | terraform {
6 | required_version = "~> 1.0"
7 |
8 | required_providers {
9 | github = {
10 | source = "integrations/github"
11 | version = "~> 5.3"
12 | }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------