-
Notifications
You must be signed in to change notification settings - Fork 367
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
cmd: Add
--init
for installing plugins automatically (#1119)
- Loading branch information
Showing
33 changed files
with
1,597 additions
and
77 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,3 +2,4 @@ | |
/vendor | ||
/dist | ||
tflint-ruleset-* | ||
!tflint-ruleset-*/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
package cmd | ||
|
||
import ( | ||
"fmt" | ||
"os" | ||
|
||
"github.com/fatih/color" | ||
tfplugin "github.com/terraform-linters/tflint/plugin" | ||
"github.com/terraform-linters/tflint/tflint" | ||
) | ||
|
||
func (cli *CLI) init(opts Options) int { | ||
cfg, err := tflint.LoadConfig(opts.Config) | ||
if err != nil { | ||
cli.formatter.Print(tflint.Issues{}, tflint.NewContextError("Failed to load TFLint config", err), map[string][]byte{}) | ||
return ExitCodeError | ||
} | ||
|
||
for _, pluginCfg := range cfg.Plugins { | ||
installCfg := tfplugin.NewInstallConfig(pluginCfg) | ||
|
||
// If version or source is not set, you need to install it manually | ||
if installCfg.ManuallyInstalled() { | ||
continue | ||
} | ||
|
||
_, err := tfplugin.FindPluginPath(installCfg) | ||
if os.IsNotExist(err) { | ||
fmt.Fprintf(cli.outStream, "Installing `%s` plugin...\n", pluginCfg.Name) | ||
|
||
sigchecker := tfplugin.NewSignatureChecker(installCfg) | ||
if !sigchecker.HasSigningKey() { | ||
color.New(color.FgYellow).Fprintln(cli.outStream, "No signing key configured. Set `signing_key` to verify that the release is signed by the plugin developer") | ||
} | ||
|
||
_, err = installCfg.Install() | ||
if err != nil { | ||
cli.formatter.Print(tflint.Issues{}, tflint.NewContextError("Failed to install a plugin", err), map[string][]byte{}) | ||
return ExitCodeError | ||
} | ||
|
||
fmt.Fprintf(cli.outStream, "Installed `%s` (source: %s, version: %s)\n", pluginCfg.Name, pluginCfg.Source, pluginCfg.Version) | ||
continue | ||
} | ||
|
||
if err != nil { | ||
cli.formatter.Print(tflint.Issues{}, tflint.NewContextError("Failed to find a plugin", err), map[string][]byte{}) | ||
return ExitCodeError | ||
} | ||
|
||
fmt.Fprintf(cli.outStream, "Plugin `%s` is already installed\n", pluginCfg.Name) | ||
} | ||
|
||
return ExitCodeOK | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,59 @@ | ||
# Writing Plugins | ||
|
||
If you want to add or change rules, you need to write plugins. When changing plugins, refer to the repository of each plugin and refer to how to build and install. | ||
If you want to add custom rules, you can write ruleset plugins. | ||
|
||
If you want to create a new plugin, please refer to [tflint-ruleset-template](https://github.com/terraform-linters/tflint-ruleset-template). The plugin can use [tflint-plugin-sdk](https://github.com/terraform-linters/tflint-plugin-sdk) to communicate with the host process. You can easily create a new repository from "Use this template". | ||
## Overview | ||
|
||
Plugins are independent binaries and use [go-plugin](https://github.com/hashicorp/go-plugin) to communicate with TFLint over RPC. TFLint executes the binary when the plugin is enabled, and the plugin process must act as an RPC server for TFLint. | ||
|
||
If you want to create a new plugin, [The template repository](https://github.com/terraform-linters/tflint-ruleset-template) is available to satisfy these specification. You can create your own repository from "Use this template" and easily add rules based on some reference rules. | ||
|
||
The template repository uses the [SDK](https://github.com/terraform-linters/tflint-plugin-sdk) that wraps the go-plugin for communication with TFLint. See also the [Architecture](https://github.com/terraform-linters/tflint-plugin-sdk#architecture) section for the architecture of the plugin system. | ||
|
||
## 1. Creating a repository from the template | ||
|
||
Visit [tflint-ruleset-template](https://github.com/terraform-linters/tflint-ruleset-template) and click the "Use this template" button. Repository name must be `tflint-ruleset-*`. | ||
|
||
## 2. Building and installing the plugin | ||
|
||
The created repository can be installed locally with `make install`. Enable the plugin as follows and verify that the installed plugin works. | ||
|
||
```hcl | ||
plugin "template" { | ||
enabled = true | ||
} | ||
``` | ||
|
||
```console | ||
$ make install | ||
go build | ||
mkdir -p ~/.tflint.d/plugins | ||
mv ./tflint-ruleset-template ~/.tflint.d/plugins | ||
$ tflint -v | ||
TFLint version 0.28.1 | ||
+ ruleset.template (0.1.0) | ||
``` | ||
|
||
## 3. Changing/Adding the rules | ||
|
||
Rename the ruleset and add/edit rules. After making changes, you can check the behavior with `make install`. See also the [tflint-plugin-sdk API reference](https://pkg.go.dev/github.com/terraform-linters/tflint-plugin-sdk) for communication with the host process. | ||
|
||
## 4. Creating a GitHub Release | ||
|
||
You can build and install your own ruleset locally as described above, but you can also install it automatically with `tflint --init`. | ||
|
||
The requirements to support automatic installation are as follows: | ||
|
||
- The built plugin binaries must be published on GitHub Release | ||
- The release must be tagged with a name like `v1.1.1` | ||
- The release must contain an asset with a name like `tflint-ruleset-{name}_{GOOS}_{GOARCH}.zip` | ||
- The zip file must contain a binary named `tflint-ruleset-{name}` (`tflint-ruleset-{name}.exe` in Windows) | ||
- The release must contain a checksum file for the zip file with the name `checksums.txt` | ||
- The checksum file must contain a sha256 hash and filename | ||
|
||
When signing a release, the release must additionally meet the following requirements: | ||
|
||
- The release must contain a signature file for the checksum file with the name `checksums.txt.sig` | ||
- The signature file must be binary OpenPGP format | ||
|
||
Releases that meet these requirements can be easily created by following the GoReleaser config in the template repository. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
# Configuring Plugins | ||
|
||
You can extend TFLint by installing any plugin. Declare plugins you want to use in the config file as follows: | ||
|
||
```hcl | ||
plugin "foo" { | ||
enabled = true | ||
version = "0.1.0" | ||
source = "github.com/org/tflint-ruleset-foo" | ||
signing_key = <<-KEY | ||
-----BEGIN PGP PUBLIC KEY BLOCK----- | ||
mQINBFzpPOMBEADOat4P4z0jvXaYdhfy+UcGivb2XYgGSPQycTgeW1YuGLYdfrwz | ||
9okJj9pMMWgt/HpW8WrJOLv7fGecFT3eIVGDOzyT8j2GIRJdXjv8ZbZIn1Q+1V72 | ||
AkqlyThflWOZf8GFrOw+UAR1OASzR00EDxC9BqWtW5YZYfwFUQnmhxU+9Cd92e6i | ||
... | ||
KEY | ||
} | ||
``` | ||
|
||
After declaring the `version` and `source`, `tflint --init` can automatically install the plugin. | ||
|
||
```console | ||
$ tflint --init | ||
Installing `foo` plugin... | ||
Installed `foo` (source: github.com/org/tflint-ruleset-foo, version: 0.1.0) | ||
$ tflint -v | ||
TFLint version 0.28.1 | ||
+ ruleset.foo (0.1.0) | ||
``` | ||
|
||
See also [Configuring TFLint](config.md) for the config file schema. | ||
|
||
## Attributes | ||
|
||
This section describes the attributes reserved by TFLint. Except for these, each plugin can extend the schema by defining any attributes/blocks. See the documentation for each plugin for details. | ||
|
||
### `enabled` (required) | ||
|
||
Enable the plugin. If set to false, the rules will not be used even if the plugin is installed. | ||
|
||
### `source` | ||
|
||
The source URL to install the plugin. Must be in the format `github.com/org/repo`. | ||
|
||
### `version` | ||
|
||
Plugin version. Do not prefix with "v". This attribute cannot be omitted when the `source` is set. Version constraints (like `>= 0.3`) are not supported. | ||
|
||
### `signing_key` | ||
|
||
Plugin developer's PGP public signing key. When this attribute is set, TFLint will automatically verify the signature of the checksum file downloaded from GitHub. It is recommended to set it to prevent supply chain attacks. | ||
|
||
Plugins under the terraform-linters organization (AWS/GCP/Azure ruleset plugins) can use the built-in signing key, so this attribute can be omitted. | ||
|
||
## Compatibility Notice | ||
|
||
AWS plugin is bundled with the TFLint binary for backward compatibility, so you can use it without installing it separately. And it is automatically enabled when your Terraform configuration requires AWS provider. | ||
|
||
## Advanced Usage | ||
|
||
You can also install the plugin manually. This is mainly useful for plugin development and for plugins that are not published on GitHub. In that case, omit the `source` and `version` attributes. | ||
|
||
```hcl | ||
plugin "foo" { | ||
enabled = true | ||
} | ||
``` | ||
|
||
When the plugin is enabled, TFLint invokes the `tflint-ruleset-<NAME>` (`tflint-ruleset-<NAME>.exe` on Windows) binary in the `~/.tflint.d/plugins` (or `./.tflint.d/plugins`) directory. So you should move the binary into the directory in advance. | ||
|
||
You can also change the plugin directory with the `TFLINT_PLUGIN_DIR` environment variable. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.