Skip to content

Commit

Permalink
fix use of filepath.Name
Browse files Browse the repository at this point in the history
  • Loading branch information
mildwonkey committed Sep 30, 2024
1 parent c82e399 commit 9448d77
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 10 deletions.
44 changes: 41 additions & 3 deletions docs/reference/domains/file-domain.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
The File domain allows for validation of arbitrary file contents. The file domain can evaluate local files and network files. Files are copied to a temporary directory for evaluation and deleted afterwards.

## Specification
The File domain specification accepts a descriptive name for the file as well as it's path:
The File domain specification accepts a descriptive name for the file as well as it's path. The names must be unique.

```yaml
domain:
Expand All @@ -14,7 +14,7 @@ domain:
```
## Supported File Types
The file domain use's OPA's [conftest](https://conftest.dev) to parse files into a json-compatible format for validations. Both OPA and kyverno (using [kyverno-json](https://kyverno.github.io/kyverno-json/latest/)) can validate files parsed by the file domain.
The file domain use's OPA's [conftest](https://conftest.dev) to parse files into a json-compatible format for validations. Both OPA and kyverno (using [kyverno-json](https://kyverno.github.io/kyverno-json/latest/)) can validate files parsed by the file domain.
The file domain supports the following file formats for validation:
* CUE
Expand All @@ -34,4 +34,42 @@ The file domain supports the following file formats for validation:
* TOML
* VCL
* XML
* YAML
* YAML
## Validations
When writing validations against files, the filepath Name must be included as the top-level key in the validation, in this example below `check`:

```yaml
metadata:
name: check-grafana-protocol
uuid: ad38ef57-99f6-4ac6-862e-e0bc9f55eebe
domain:
type: file
file-spec:
filepaths:
- name: 'grafana'
path: 'custom.ini'
provider:
type: kyverno
kyverno-spec:
policy:
apiVersion: json.kyverno.io/v1alpha1
kind: ValidatingPolicy
metadata:
name: grafana-config
spec:
rules:
- name: protocol-is-https
assert:
all:
- check:
grafana:
server:
protocol: https
```

```grafana.ini
[server]
# Protocol (http, https, socket)
protocol = http
```
19 changes: 16 additions & 3 deletions src/pkg/domains/files/files.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,25 @@ func (d Domain) GetResources() (types.DomainResources, error) {
// removed.
defer os.RemoveAll(dst)

// make a map of rel filepaths to the user-supplied name, so we can re-key the DomainResources later on.
filenames := make(map[string]string, len(d.Spec.Filepaths))

// Copy files to a temporary location
for _, path := range d.Spec.Filepaths {
bytes, err := network.Fetch(path.Path)
if err != nil {
return nil, fmt.Errorf("error getting source files: %w", err)
}
os.WriteFile(filepath.Join(dst, path.Name), bytes, 0666)

// We'll just use the filename when writing the file so it's easier to reference later
relname := filepath.Base(path.Path)

err = os.WriteFile(filepath.Join(dst, relname), bytes, 0666)
if err != nil {
return nil, fmt.Errorf("error writing local files: %w", err)
}
// and save this info for later
filenames[relname] = path.Name
}

// get a list of all the files we just downloaded in the temporary directory
Expand All @@ -56,14 +68,15 @@ func (d Domain) GetResources() (types.DomainResources, error) {
return nil, err
}

// clean up the resources so it's just using the filename
// clean up the resources so it's using the filepath.Name as the map key,
// istead of the file path.src/pkg/domains/files/files.go
drs := make(types.DomainResources, len(config))
for k, v := range config {
rel, err := filepath.Rel(dst, k)
if err != nil {
return nil, fmt.Errorf("error determining relative file path: %w", err)
}
drs[rel] = v
drs[filenames[rel]] = v
}
return drs, nil
}
Expand Down
12 changes: 8 additions & 4 deletions src/pkg/domains/files/files_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,19 @@ func TestGetResource(t *testing.T) {
d := Domain{Spec: &Spec{Filepaths: []FileInfo{
{Name: "foo.yaml", Path: "testdata/foo.yaml"},
{Name: "bar.json", Path: "testdata/bar.json"},
{Name: "arbitraryname", Path: "testdata/nested-directory/baz.hcl2"},
}}}

resources, err := d.GetResources()
require.NoError(t, err)
if diff := cmp.Diff(resources, types.DomainResources{"bar.json": map[string]interface{}{"cat": "Cheetarah"}, "foo.yaml": "cat = Li Shou"}); diff != "" {
if diff := cmp.Diff(resources, types.DomainResources{
"bar.json": map[string]interface{}{"cat": "Cheetarah"},
"foo.yaml": "cat = Li Shou",
"arbitraryname": map[string]any{
"resource": map[string]any{"catname": map[string]any{"blackcat": map[string]any{"name": "robin"}}},
},
}); diff != "" {
t.Fatalf("wrong result:\n%s\n", diff)
}
})

//remote files
// TODO
}
3 changes: 3 additions & 0 deletions src/pkg/domains/files/testdata/nested-directory/baz.hcl2
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
resource "catname" "blackcat" {
name = "robin"
}

0 comments on commit 9448d77

Please sign in to comment.