Skip to content

Commit

Permalink
Merge branch 'master' into tests-audit
Browse files Browse the repository at this point in the history
Signed-off-by: Sertac Ozercan <[email protected]>
  • Loading branch information
sozercan committed Jan 3, 2023
2 parents c0919a4 + bed335f commit b0bc681
Show file tree
Hide file tree
Showing 12 changed files with 125 additions and 15 deletions.
2 changes: 1 addition & 1 deletion cmd/build/helmify/static/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ _See [Exempting Namespaces](https://open-policy-agent.github.io/gatekeeper/websi
| crds.securityContext | Security context applied to the container | `{ "allowPrivilegeEscalation": false, "capabilities": "drop": [all], "readOnlyRootFilesystem": true, "runAsGroup": 65532, "runAsNonRoot": true, "runAsUser": 65532 }` |
| auditInterval | The frequency with which audit is run | `60` |
| constraintViolationsLimit | The maximum # of audit violations reported on a constraint | `20` |
| auditFromCache | Take the roster of resources to audit from the OPA cache | `false` |
| auditFromCache | Take the roster of resources to audit from the audit cache | `false` |
| auditChunkSize | Chunk size for listing cluster resources for audit (alpha feature) | `500` |
| auditMatchKindOnly | Only check resources of the kinds specified in all constraints defined in the cluster. | `false` |
| disableValidatingWebhook | Disable the validating webhook | `false` |
Expand Down
2 changes: 1 addition & 1 deletion manifest_staging/charts/gatekeeper/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ _See [Exempting Namespaces](https://open-policy-agent.github.io/gatekeeper/websi
| crds.securityContext | Security context applied to the container | `{ "allowPrivilegeEscalation": false, "capabilities": "drop": [all], "readOnlyRootFilesystem": true, "runAsGroup": 65532, "runAsNonRoot": true, "runAsUser": 65532 }` |
| auditInterval | The frequency with which audit is run | `60` |
| constraintViolationsLimit | The maximum # of audit violations reported on a constraint | `20` |
| auditFromCache | Take the roster of resources to audit from the OPA cache | `false` |
| auditFromCache | Take the roster of resources to audit from the audit cache | `false` |
| auditChunkSize | Chunk size for listing cluster resources for audit (alpha feature) | `500` |
| auditMatchKindOnly | Only check resources of the kinds specified in all constraints defined in the cluster. | `false` |
| disableValidatingWebhook | Disable the validating webhook | `false` |
Expand Down
2 changes: 1 addition & 1 deletion pkg/audit/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ func (am *Manager) audit(ctx context.Context) error {
am.log.Info("Auditing from cache")
res, errs := am.auditFromCache(ctx)

am.log.Info("Audit opa.Audit() results", "violations", len(res))
am.log.Info("Audit from cache results", "violations", len(res))
for _, err := range errs {
am.log.Error(err, "Auditing")
}
Expand Down
110 changes: 110 additions & 0 deletions pkg/audit/manager_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package audit

import (
"os"
"reflect"
"testing"

Expand Down Expand Up @@ -221,3 +222,112 @@ func Test_getViolationRef(t *testing.T) {
})
}
}

func Test_getFilesFromDir(t *testing.T) {
// Test case 1: directory does not exist
am := Manager{}
_, err := am.getFilesFromDir("/does/not/exist", 10)
if err == nil {
t.Errorf("Expected error when directory does not exist, got nil")
}

// Test case 2: directory exists and is empty
emptyDir, err := os.MkdirTemp("", "empty-dir")
if err != nil {
t.Errorf("Failed to create temporary directory: %v", err)
}
defer os.RemoveAll(emptyDir)
files, err := am.getFilesFromDir(emptyDir, 10)
if err != nil {
t.Errorf("Unexpected error when directory is empty: %v", err)
}
if len(files) != 0 {
t.Errorf("Expected 0 files when directory is empty, got %d", len(files))
}

// Test case 3: directory exists and has some files
tempDir, err := os.MkdirTemp("", "temp-dir")
if err != nil {
t.Errorf("Failed to create temporary directory: %v", err)
}
defer os.RemoveAll(tempDir)
for i := 0; i < 15; i++ {
file, err := os.CreateTemp(tempDir, "test-file-*.txt")
if err != nil {
t.Errorf("Failed to create temporary file: %v", err)
}
file.Close()
}
files, err = am.getFilesFromDir(tempDir, 10)
if err != nil {
t.Errorf("Unexpected error when directory has files: %v", err)
}
if len(files) != 15 {
t.Errorf("Expected 15 files when directory has 15 files, got %d", len(files))
}
}

func Test_removeAllFromDir(t *testing.T) {
// Test case 1: directory does not exist
am := Manager{}
err := am.removeAllFromDir("/does/not/exist", 10)
if err == nil {
t.Errorf("Expected error when directory does not exist, got nil")
}

// Test case 2: directory exists and is empty
emptyDir, err := os.MkdirTemp("", "empty-dir")
if err != nil {
t.Errorf("Failed to create temporary directory: %v", err)
}
defer os.RemoveAll(emptyDir)
err = am.removeAllFromDir(emptyDir, 10)
if err != nil {
t.Errorf("Unexpected error when directory is empty: %v", err)
}

// Test case 3: directory exists and has some files
tempDir, err := os.MkdirTemp("", "temp-dir")
if err != nil {
t.Errorf("Failed to create temporary directory: %v", err)
}
defer os.RemoveAll(tempDir)
for i := 0; i < 15; i++ {
file, err := os.CreateTemp(tempDir, "test-file-*.txt")
if err != nil {
t.Errorf("Failed to create temporary file: %v", err)
}
file.Close()
}
err = am.removeAllFromDir(tempDir, 10)
if err != nil {
t.Errorf("Unexpected error when removing files from directory: %v", err)
}
files, err := am.getFilesFromDir(tempDir, 10)
if err != nil {
t.Errorf("Unexpected error when checking if directory is empty: %v", err)
}
if len(files) != 0 {
t.Errorf("Expected 0 files when all files have been removed, got %d", len(files))
}
}

func Test_readUnstructured(t *testing.T) {
// Test case 1: invalid JSON
am := Manager{}
_, err := am.readUnstructured([]byte("invalid json"))
if err == nil {
t.Errorf("Expected error when input is invalid JSON, got nil")
}

// Test case 2: valid JSON
jsonBytes := []byte(`{"apiVersion":"v1","kind":"Namespace","metadata":{"name":"my-namespace"}}
`)
u, err := am.readUnstructured(jsonBytes)
if err != nil {
t.Errorf("Unexpected error when input is valid JSON: %v", err)
}
if u.GetName() != "my-namespace" {
t.Errorf("Expected name to be 'my-namespace', got %s", u.GetName())
}
}
2 changes: 1 addition & 1 deletion website/docs/audit.md
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ number of instances to run, please refer to [operations audit](operations.md#aud
medium: Memory
```
By default, audit will request each resource from the Kubernetes API during each audit cycle. To rely on the OPA cache instead, use the flag `--audit-from-cache=true`. Note that this requires replication of Kubernetes resources into OPA before they can be evaluated against the enforced policies. Refer to the [Replicating data](sync.md) section for more information.
By default, audit will request each resource from the Kubernetes API during each audit cycle. To rely on the audit informer cache instead, use the flag `--audit-from-cache=true`. Note that this requires replication of Kubernetes resources into the audit cache before they can be evaluated against the enforced policies. Refer to the [Replicating data](sync.md) section for more information.

### Audit using kinds specified in the constraints only

Expand Down
4 changes: 2 additions & 2 deletions website/docs/sync.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ title: Replicating Data
Some constraints are impossible to write without access to more state than just the object under test. For example, it is impossible to know if an ingress's hostname is unique among all ingresses unless a rule has access to all other ingresses. To make such rules possible, we enable syncing of data into OPA.

The [audit](audit.md) feature does not require replication by default. However, when the ``audit-from-cache`` flag is set to true, the OPA cache will be used as the source-of-truth for audit queries; thus, an object must first be cached before it can be audited for constraint violations.
The [audit](audit.md) feature does not require replication by default. However, when the ``audit-from-cache`` flag is set to true, the audit informer cache will be used as the source-of-truth for audit queries; thus, an object must first be cached before it can be audited for constraint violations.

Kubernetes data can be replicated into OPA via the sync config resource. Currently resources defined in `syncOnly` will be synced into OPA. Updating `syncOnly` should dynamically update what objects are synced. Below is an example:
Kubernetes data can be replicated into the audit cache via the sync config resource. Currently resources defined in `syncOnly` will be synced into OPA. Updating `syncOnly` should dynamically update what objects are synced. Below is an example:

```yaml
apiVersion: config.gatekeeper.sh/v1alpha1
Expand Down
2 changes: 1 addition & 1 deletion website/versioned_docs/version-v3.10.x/audit.md
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ number of instances to run, please refer to [operations audit](operations.md#aud
medium: Memory
```
By default, audit will request each resource from the Kubernetes API during each audit cycle. To rely on the OPA cache instead, use the flag `--audit-from-cache=true`. Note that this requires replication of Kubernetes resources into OPA before they can be evaluated against the enforced policies. Refer to the [Replicating data](sync.md) section for more information.
By default, audit will request each resource from the Kubernetes API during each audit cycle. To rely on the audit informer cache instead, use the flag `--audit-from-cache=true`. Note that this requires replication of Kubernetes resources into the audit cache before they can be evaluated against the enforced policies. Refer to the [Replicating data](sync.md) section for more information.

### Audit using kinds specified in the constraints only

Expand Down
4 changes: 2 additions & 2 deletions website/versioned_docs/version-v3.10.x/sync.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ title: Replicating Data
Some constraints are impossible to write without access to more state than just the object under test. For example, it is impossible to know if an ingress's hostname is unique among all ingresses unless a rule has access to all other ingresses. To make such rules possible, we enable syncing of data into OPA.

The [audit](audit.md) feature does not require replication by default. However, when the ``audit-from-cache`` flag is set to true, the OPA cache will be used as the source-of-truth for audit queries; thus, an object must first be cached before it can be audited for constraint violations.
The [audit](audit.md) feature does not require replication by default. However, when the ``audit-from-cache`` flag is set to true, the audit informer cache will be used as the source-of-truth for audit queries; thus, an object must first be cached before it can be audited for constraint violations.

Kubernetes data can be replicated into OPA via the sync config resource. Currently resources defined in `syncOnly` will be synced into OPA. Updating `syncOnly` should dynamically update what objects are synced. Below is an example:
Kubernetes data can be replicated into the audit cache via the sync config resource. Currently resources defined in `syncOnly` will be synced into OPA. Updating `syncOnly` should dynamically update what objects are synced. Below is an example:

```yaml
apiVersion: config.gatekeeper.sh/v1alpha1
Expand Down
2 changes: 1 addition & 1 deletion website/versioned_docs/version-v3.8.x/audit.md
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ number of instances to run, please refer to [operations audit](operations.md#aud
medium: Memory
```
By default, audit will request each resource from the Kubernetes API during each audit cycle. To rely on the OPA cache instead, use the flag `--audit-from-cache=true`. Note that this requires replication of Kubernetes resources into OPA before they can be evaluated against the enforced policies. Refer to the [Replicating data](sync.md) section for more information.
By default, audit will request each resource from the Kubernetes API during each audit cycle. To rely on the audit informer cache instead, use the flag `--audit-from-cache=true`. Note that this requires replication of Kubernetes resources into the audit cache before they can be evaluated against the enforced policies. Refer to the [Replicating data](sync.md) section for more information.

### Audit using kinds specified in the constraints only

Expand Down
4 changes: 2 additions & 2 deletions website/versioned_docs/version-v3.8.x/sync.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ title: Replicating Data
Some constraints are impossible to write without access to more state than just the object under test. For example, it is impossible to know if an ingress's hostname is unique among all ingresses unless a rule has access to all other ingresses. To make such rules possible, we enable syncing of data into OPA.

The [audit](audit.md) feature does not require replication by default. However, when the ``audit-from-cache`` flag is set to true, the OPA cache will be used as the source-of-truth for audit queries; thus, an object must first be cached before it can be audited for constraint violations.
The [audit](audit.md) feature does not require replication by default. However, when the ``audit-from-cache`` flag is set to true, the audit informer cache will be used as the source-of-truth for audit queries; thus, an object must first be cached before it can be audited for constraint violations.

Kubernetes data can be replicated into OPA via the sync config resource. Currently resources defined in `syncOnly` will be synced into OPA. Updating `syncOnly` should dynamically update what objects are synced. Below is an example:
Kubernetes data can be replicated into the audit cache via the sync config resource. Currently resources defined in `syncOnly` will be synced into OPA. Updating `syncOnly` should dynamically update what objects are synced. Below is an example:

```yaml
apiVersion: config.gatekeeper.sh/v1alpha1
Expand Down
2 changes: 1 addition & 1 deletion website/versioned_docs/version-v3.9.x/audit.md
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ number of instances to run, please refer to [operations audit](operations.md#aud
medium: Memory
```
By default, audit will request each resource from the Kubernetes API during each audit cycle. To rely on the OPA cache instead, use the flag `--audit-from-cache=true`. Note that this requires replication of Kubernetes resources into OPA before they can be evaluated against the enforced policies. Refer to the [Replicating data](sync.md) section for more information.
By default, audit will request each resource from the Kubernetes API during each audit cycle. To rely on the audit informer cache instead, use the flag `--audit-from-cache=true`. Note that this requires replication of Kubernetes resources into the audit cache before they can be evaluated against the enforced policies. Refer to the [Replicating data](sync.md) section for more information.

### Audit using kinds specified in the constraints only

Expand Down
4 changes: 2 additions & 2 deletions website/versioned_docs/version-v3.9.x/sync.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ title: Replicating Data
Some constraints are impossible to write without access to more state than just the object under test. For example, it is impossible to know if an ingress's hostname is unique among all ingresses unless a rule has access to all other ingresses. To make such rules possible, we enable syncing of data into OPA.

The [audit](audit.md) feature does not require replication by default. However, when the ``audit-from-cache`` flag is set to true, the OPA cache will be used as the source-of-truth for audit queries; thus, an object must first be cached before it can be audited for constraint violations.
The [audit](audit.md) feature does not require replication by default. However, when the ``audit-from-cache`` flag is set to true, the audit informer cache will be used as the source-of-truth for audit queries; thus, an object must first be cached before it can be audited for constraint violations.

Kubernetes data can be replicated into OPA via the sync config resource. Currently resources defined in `syncOnly` will be synced into OPA. Updating `syncOnly` should dynamically update what objects are synced. Below is an example:
Kubernetes data can be replicated into the audit cache via the sync config resource. Currently resources defined in `syncOnly` will be synced into OPA. Updating `syncOnly` should dynamically update what objects are synced. Below is an example:

```yaml
apiVersion: config.gatekeeper.sh/v1alpha1
Expand Down

0 comments on commit b0bc681

Please sign in to comment.