-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: basic CLI implementation (#15)
* feat: basic CLI implementation * docs: update README.md with install instructions * fix: address code review comments
- Loading branch information
1 parent
744da10
commit ef18cf2
Showing
14 changed files
with
428 additions
and
30 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 |
---|---|---|
@@ -0,0 +1,4 @@ | ||
--- | ||
rules: | ||
- description: The AGE key used as part of the testdata | ||
match: age1yt3tfqlfrwdwx0z0ynwplcr6qxcxfaqycuprpmy89nr83ltx74tqdpszlw |
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,49 @@ | ||
# sops-check | ||
|
||
We are following a design-first approach, please take a look at [the design document](docs/design.md) and we are happy to hear your thoughts about it. | ||
[![Build Status](https://github.com/Bonial-International-GmbH/sops-check/actions/workflows/ci.yml/badge.svg)](https://github.com/Bonial-International-GmbH/sops-check/actions/workflows/ci.yml) | ||
|
||
WIP | ||
> [!NOTE] | ||
> This project is still in an early development stage and a lot of the desired | ||
> features are not implemented yet. | ||
Check SOPS files for correct and compliant usage without decrypting them to | ||
ensure that all SOPS files are configured in the desired fashion. The goal is | ||
to provide a security linter that safeguards the security of the data protected | ||
by the SOPS files against common mistakes and against malicious configurations. | ||
|
||
We are following a design-first approach, please take a look at [the design | ||
document](docs/design.md). We are happy to hear your thoughts about it. | ||
|
||
## Installation | ||
|
||
The simplest way is to install the latest version via: | ||
|
||
```sh | ||
go install github.com/Bonial-International-GmbH/sops-check@latest | ||
``` | ||
|
||
Finally, consult the help for usage instructions: | ||
|
||
```sh | ||
sops-check --help | ||
``` | ||
|
||
## Development | ||
|
||
Run the tests: | ||
|
||
```sh | ||
make coverage | ||
``` | ||
|
||
Lint the codebase: | ||
|
||
```sh | ||
make lint | ||
``` | ||
|
||
Build locally: | ||
|
||
```sh | ||
make build | ||
``` |
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,50 @@ | ||
package cli | ||
|
||
import "github.com/alecthomas/kingpin/v2" | ||
|
||
// Version is the current version of the app, generated at build time. | ||
var Version = "unknown" | ||
|
||
// Args are configuration options parsed from CLI args. | ||
type Args struct { | ||
// CheckPath is the filesystem path to search for SOPS files. | ||
CheckPath string | ||
// ConfigPath is the path of the sops-check configuration file. | ||
ConfigPath string | ||
} | ||
|
||
// Defaults apply to arguments not provided explicitly. | ||
var Defaults = &Args{ | ||
CheckPath: ".", | ||
ConfigPath: ".sops-check.yaml", | ||
} | ||
|
||
// ParseArgs parses arguments from the command line. | ||
func ParseArgs(commandLine []string) (*Args, error) { | ||
args := &Args{} | ||
|
||
app := kingpin.New( | ||
"sops-check", | ||
"A tool that looks for SOPS files within a directory tree and ensures they are configured in the desired fashion.", | ||
) | ||
app.Version(Version) | ||
app.DefaultEnvars() | ||
|
||
// Flags. | ||
app.HelpFlag.Short('h') | ||
app.Flag("config", "Path to the sops-check configuration file."). | ||
Short('c'). | ||
Default(Defaults.ConfigPath). | ||
StringVar(&args.ConfigPath) | ||
|
||
// Positional arguments. | ||
app.Arg("path", "Directory to run the checks in. If omitted, checks are run in the current working directory."). | ||
Default(Defaults.CheckPath). | ||
StringVar(&args.CheckPath) | ||
|
||
if _, err := app.Parse(commandLine); err != nil { | ||
return nil, err | ||
} | ||
|
||
return args, nil | ||
} |
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,39 @@ | ||
package cli | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/stretchr/testify/assert" | ||
"github.com/stretchr/testify/require" | ||
) | ||
|
||
func TestParseArgs(t *testing.T) { | ||
t.Run("no args", func(t *testing.T) { | ||
args, err := ParseArgs(nil) | ||
require.NoError(t, err) | ||
|
||
expected := &Args{ | ||
ConfigPath: Defaults.ConfigPath, | ||
CheckPath: Defaults.CheckPath, | ||
} | ||
|
||
assert.Equal(t, expected, args) | ||
}) | ||
|
||
t.Run("args", func(t *testing.T) { | ||
args, err := ParseArgs([]string{"--config", "the-config.yaml"}) | ||
require.NoError(t, err) | ||
|
||
expected := &Args{ | ||
ConfigPath: "the-config.yaml", | ||
CheckPath: Defaults.CheckPath, | ||
} | ||
|
||
assert.Equal(t, expected, args) | ||
}) | ||
|
||
t.Run("invalid args", func(t *testing.T) { | ||
_, err := ParseArgs([]string{"--nonexistent"}) | ||
require.Error(t, err) | ||
}) | ||
} |
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,31 @@ | ||
package stringutils | ||
|
||
import "strings" | ||
|
||
// Indent indents a string by `count` spaces. | ||
func Indent(s string, count int, indentFirst bool) string { | ||
if count == 0 || s == "" { | ||
return s | ||
} | ||
|
||
var sb strings.Builder | ||
|
||
lines := strings.SplitAfter(s, "\n") | ||
|
||
if len(lines[len(lines)-1]) == 0 { | ||
lines = lines[:len(lines)-1] | ||
} | ||
|
||
indent := strings.Repeat(" ", count) | ||
|
||
for i, line := range lines { | ||
if line != "\n" && line != "\r\n" && (i != 0 || indentFirst) { | ||
// Only indent non-empty lines. | ||
sb.WriteString(indent) | ||
} | ||
|
||
sb.WriteString(line) | ||
} | ||
|
||
return sb.String() | ||
} |
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,50 @@ | ||
package stringutils | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/stretchr/testify/assert" | ||
) | ||
|
||
func TestIndent(t *testing.T) { | ||
t.Run("no indent", func(t *testing.T) { | ||
assert.Equal(t, "foo", Indent("foo", 0, true)) | ||
}) | ||
|
||
t.Run("empty string", func(t *testing.T) { | ||
assert.Equal(t, "", Indent("", 2, true)) | ||
}) | ||
|
||
t.Run("multiline string", func(t *testing.T) { | ||
given := `foo | ||
bar | ||
baz` | ||
expected := ` foo | ||
bar | ||
baz` | ||
|
||
assert.Equal(t, expected, Indent(given, 2, true)) | ||
}) | ||
|
||
t.Run("skip indent first", func(t *testing.T) { | ||
given := `foo | ||
bar | ||
baz` | ||
expected := `foo | ||
bar | ||
baz` | ||
|
||
assert.Equal(t, expected, Indent(given, 2, false)) | ||
}) | ||
|
||
t.Run("trailing newline", func(t *testing.T) { | ||
given := "foo\nbar\n" | ||
expected := " foo\n bar\n" | ||
|
||
assert.Equal(t, expected, Indent(given, 2, true)) | ||
}) | ||
} |
Oops, something went wrong.