pepr 0.14.2 → 0.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +51 -18
- package/dist/controller.js +1 -1
- package/dist/lib/assets/deploy.d.ts.map +1 -1
- package/dist/lib/assets/index.d.ts +1 -1
- package/dist/lib/assets/index.d.ts.map +1 -1
- package/dist/lib/assets/rbac.d.ts +2 -1
- package/dist/lib/assets/rbac.d.ts.map +1 -1
- package/dist/lib/assets/yaml.d.ts +1 -1
- package/dist/lib/assets/yaml.d.ts.map +1 -1
- package/dist/lib/helpers.d.ts +11 -0
- package/dist/lib/helpers.d.ts.map +1 -0
- package/package.json +9 -9
- package/src/lib/assets/deploy.ts +4 -3
- package/src/lib/assets/index.ts +2 -2
- package/src/lib/assets/rbac.ts +27 -11
- package/src/lib/assets/yaml.ts +2 -2
- package/src/lib/helpers.ts +39 -0
- package/src/templates/capabilities/hello-pepr.ts +16 -11
- package/website/.linkinator.config.json +8 -0
- package/website/.markdownlint.json +6 -0
- package/website/.prettierignore +12 -0
- package/website/LICENSE +201 -0
- package/website/README.md +50 -0
- package/website/archetypes/default.md +6 -0
- package/website/assets/img/doug.svg +345 -0
- package/website/assets/img/pepr.svg +212 -0
- package/website/assets/scss/_styles_project.scss +3 -0
- package/website/assets/scss/_variables_project.scss +1 -0
- package/website/content/en/docs/_index.md +9 -0
- package/website/content/en/docs/cli.md +64 -0
- package/website/content/en/docs/codeSample.txt +31 -0
- package/website/content/en/docs/concepts.md +238 -0
- package/website/content/en/docs/customresources.md +167 -0
- package/website/content/en/docs/diagrams.txt +18 -0
- package/website/content/en/docs/metrics.md +74 -0
- package/website/content/en/docs/rbac.md +153 -0
- package/website/content/en/docs/webassembly.md +189 -0
- package/website/go.mod +8 -0
- package/website/go.sum +4 -0
- package/website/package-lock.json +3907 -0
- package/website/package.json +30 -0
- package/website/renovate.json +16 -0
- package/website/static/favicons/android-144x144.png +0 -0
- package/website/static/favicons/android-192x192.png +0 -0
- package/website/static/favicons/android-36x36.png +0 -0
- package/website/static/favicons/android-48x48.png +0 -0
- package/website/static/favicons/android-72x72.png +0 -0
- package/website/static/favicons/android-96x96.png +0 -0
- package/website/static/favicons/android-chrome-192x192.png +0 -0
- package/website/static/favicons/android-chrome-512x512.png +0 -0
- package/website/static/favicons/android-chrome-maskable-192x192.png +0 -0
- package/website/static/favicons/android-chrome-maskable-512x512.png +0 -0
- package/website/static/favicons/apple-touch-icon-180x180.png +0 -0
- package/website/static/favicons/apple-touch-icon.png +0 -0
- package/website/static/favicons/favicon-16x16.png +0 -0
- package/website/static/favicons/favicon-32x32.png +0 -0
- package/website/static/favicons/favicon.ico +0 -0
- package/website/static/img/how-to-use.png +0 -0
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Custom Resources
|
|
3
|
+
linkTitle: Custom Resources
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
# Importing Custom Resources
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
The [Kubernetes Fluent Client](https://github.com/defenseunicorns/kubernetes-fluent-client) supports the creation of TypeScript typings directly from Kubernetes Custom Resource Definitions (CRDs). The files it generates can be directly incorporated into Pepr capabilities and provide a way to work with strongly-typed CRDs.
|
|
11
|
+
|
|
12
|
+
For example (below), Istio CRDs can be imported and used as though they were intrinsic Kubernetes resources.
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
## Generating TypeScript Types from CRDs
|
|
16
|
+
|
|
17
|
+
Using the kubernetes-fluent-client to produce a new type looks like this:
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
npx kubernetes-fluent-client crd [source] [directory]
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
The `crd` command expects a `[source]`, which can be a URL or local file containing the `CustomResourceDefinition(s)`, and a `[directory]` where the generated code will live.
|
|
24
|
+
|
|
25
|
+
The following example creates types for the Istio CRDs:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
user@workstation$ npx kubernetes-fluent-client crd https://raw.githubusercontent.com/istio/istio/master/manifests/charts/base/crds/crd-all.gen.yaml crds
|
|
29
|
+
|
|
30
|
+
Attempting to load https://raw.githubusercontent.com/istio/istio/master/manifests/charts/base/crds/crd-all.gen.yaml as a URL
|
|
31
|
+
|
|
32
|
+
- Generating extensions.istio.io/v1alpha1 types for WasmPlugin
|
|
33
|
+
- Generating networking.istio.io/v1alpha3 types for DestinationRule
|
|
34
|
+
- Generating networking.istio.io/v1beta1 types for DestinationRule
|
|
35
|
+
- Generating networking.istio.io/v1alpha3 types for EnvoyFilter
|
|
36
|
+
- Generating networking.istio.io/v1alpha3 types for Gateway
|
|
37
|
+
- Generating networking.istio.io/v1beta1 types for Gateway
|
|
38
|
+
- Generating networking.istio.io/v1beta1 types for ProxyConfig
|
|
39
|
+
- Generating networking.istio.io/v1alpha3 types for ServiceEntry
|
|
40
|
+
- Generating networking.istio.io/v1beta1 types for ServiceEntry
|
|
41
|
+
- Generating networking.istio.io/v1alpha3 types for Sidecar
|
|
42
|
+
- Generating networking.istio.io/v1beta1 types for Sidecar
|
|
43
|
+
- Generating networking.istio.io/v1alpha3 types for VirtualService
|
|
44
|
+
- Generating networking.istio.io/v1beta1 types for VirtualService
|
|
45
|
+
- Generating networking.istio.io/v1alpha3 types for WorkloadEntry
|
|
46
|
+
- Generating networking.istio.io/v1beta1 types for WorkloadEntry
|
|
47
|
+
- Generating networking.istio.io/v1alpha3 types for WorkloadGroup
|
|
48
|
+
- Generating networking.istio.io/v1beta1 types for WorkloadGroup
|
|
49
|
+
- Generating security.istio.io/v1 types for AuthorizationPolicy
|
|
50
|
+
- Generating security.istio.io/v1beta1 types for AuthorizationPolicy
|
|
51
|
+
- Generating security.istio.io/v1beta1 types for PeerAuthentication
|
|
52
|
+
- Generating security.istio.io/v1 types for RequestAuthentication
|
|
53
|
+
- Generating security.istio.io/v1beta1 types for RequestAuthentication
|
|
54
|
+
- Generating telemetry.istio.io/v1alpha1 types for Telemetry
|
|
55
|
+
|
|
56
|
+
✅ Generated 23 files in the istio directory
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Observe that the `kubernetes-fluent-client` has produced the TypeScript types within the `crds` directory. These types can now be utilized in the Pepr module.
|
|
60
|
+
|
|
61
|
+
```typescript
|
|
62
|
+
user@workstation$ cat crds/proxyconfig-v1beta1.ts
|
|
63
|
+
// This file is auto-generated by kubernetes-fluent-client, do not edit manually
|
|
64
|
+
|
|
65
|
+
import { GenericKind, RegisterKind } from "kubernetes-fluent-client";
|
|
66
|
+
|
|
67
|
+
export class ProxyConfig extends GenericKind {
|
|
68
|
+
/**
|
|
69
|
+
* Provides configuration for individual workloads. See more details at:
|
|
70
|
+
* https://istio.io/docs/reference/config/networking/proxy-config.html
|
|
71
|
+
*/
|
|
72
|
+
spec?: Spec;
|
|
73
|
+
status?: { [key: string]: any };
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Provides configuration for individual workloads. See more details at:
|
|
78
|
+
* https://istio.io/docs/reference/config/networking/proxy-config.html
|
|
79
|
+
*/
|
|
80
|
+
export interface Spec {
|
|
81
|
+
/**
|
|
82
|
+
* The number of worker threads to run.
|
|
83
|
+
*/
|
|
84
|
+
concurrency?: number;
|
|
85
|
+
/**
|
|
86
|
+
* Additional environment variables for the proxy.
|
|
87
|
+
*/
|
|
88
|
+
environmentVariables?: { [key: string]: string };
|
|
89
|
+
/**
|
|
90
|
+
* Specifies the details of the proxy image.
|
|
91
|
+
*/
|
|
92
|
+
image?: Image;
|
|
93
|
+
/**
|
|
94
|
+
* Optional.
|
|
95
|
+
*/
|
|
96
|
+
selector?: Selector;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Specifies the details of the proxy image.
|
|
101
|
+
*/
|
|
102
|
+
export interface Image {
|
|
103
|
+
/**
|
|
104
|
+
* The image type of the image.
|
|
105
|
+
*/
|
|
106
|
+
imageType?: string;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Optional.
|
|
111
|
+
*/
|
|
112
|
+
export interface Selector {
|
|
113
|
+
/**
|
|
114
|
+
* One or more labels that indicate a specific set of pods/VMs on which a policy should be
|
|
115
|
+
* applied.
|
|
116
|
+
*/
|
|
117
|
+
matchLabels?: { [key: string]: string };
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
RegisterKind(ProxyConfig, {
|
|
121
|
+
group: "networking.istio.io",
|
|
122
|
+
version: "v1beta1",
|
|
123
|
+
kind: "ProxyConfig",
|
|
124
|
+
});
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
## Using new types
|
|
128
|
+
|
|
129
|
+
The generated types can be imported into Pepr directly, _there is no additional logic needed to make them to work_.
|
|
130
|
+
|
|
131
|
+
```typescript
|
|
132
|
+
import { Capability, K8s, Log, a, kind } from "pepr";
|
|
133
|
+
|
|
134
|
+
import { Gateway } from "../crds/gateway-v1beta1";
|
|
135
|
+
import {
|
|
136
|
+
PurpleDestination,
|
|
137
|
+
VirtualService,
|
|
138
|
+
} from "../crds/virtualservice-v1beta1";
|
|
139
|
+
|
|
140
|
+
export const IstioVirtualService = new Capability({
|
|
141
|
+
name: "istio-virtual-service",
|
|
142
|
+
description: "Generate Istio VirtualService resources",
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
// Use the 'When' function to create a new action
|
|
146
|
+
const { When, Store } = IstioVirtualService;
|
|
147
|
+
|
|
148
|
+
// Define the configuration keys
|
|
149
|
+
enum config {
|
|
150
|
+
Gateway = "uds/istio-gateway",
|
|
151
|
+
Host = "uds/istio-host",
|
|
152
|
+
Port = "uds/istio-port",
|
|
153
|
+
Domain = "uds/istio-domain",
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// Define the valid gateway names
|
|
157
|
+
const validGateway = ["admin", "tenant", "passthrough"];
|
|
158
|
+
|
|
159
|
+
// Watch Gateways to get the HTTPS domain for each gateway
|
|
160
|
+
When(Gateway)
|
|
161
|
+
.IsCreatedOrUpdated()
|
|
162
|
+
.WithLabel(config.Domain)
|
|
163
|
+
.Watch(vs => {
|
|
164
|
+
// Store the domain for the gateway
|
|
165
|
+
Store.setItem(vs.metadata.name, vs.metadata.labels[config.Domain]);
|
|
166
|
+
});
|
|
167
|
+
```
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Mermaid Diagram Samples
|
|
3
|
+
description: Mermaid
|
|
4
|
+
---
|
|
5
|
+
<!--
|
|
6
|
+
In certain instances a markdown viewer may not display due to
|
|
7
|
+
the '---' frontmatter block above. If you're one of those edge
|
|
8
|
+
cases enclose the frontmatter at the top of this file entirely
|
|
9
|
+
within a comment block just like this comment.
|
|
10
|
+
-->
|
|
11
|
+
|
|
12
|
+
```mermaid
|
|
13
|
+
graph TD
|
|
14
|
+
Start --> Need{"Hugo version >= 0.93.0"}
|
|
15
|
+
Need -- No --> Off["Set params.mermaid.enable = true"]
|
|
16
|
+
Off --> Author
|
|
17
|
+
Need -- Yes --> Author[Insert mermaid codeblock]
|
|
18
|
+
```
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Metrics
|
|
3
|
+
linkTitle: Metrics
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# `/metrics` Endpoint Documentation
|
|
7
|
+
|
|
8
|
+
The `/metrics` endpoint provides metrics for the application that are collected via the `MetricsCollector` class. It uses the `prom-client` library and performance hooks from Node.js to gather and expose the metrics data in a format that can be scraped by Prometheus.
|
|
9
|
+
|
|
10
|
+
## Metrics Exposed
|
|
11
|
+
|
|
12
|
+
The `MetricsCollector` exposes the following metrics:
|
|
13
|
+
|
|
14
|
+
- `pepr_errors`: A counter that increments when an error event occurs in the application.
|
|
15
|
+
- `pepr_alerts`: A counter that increments when an alert event is triggered in the application.
|
|
16
|
+
- `pepr_Mutate`: A summary that provides the observed durations of mutation events in the application.
|
|
17
|
+
- `pepr_Validate`: A summary that provides the observed durations of validation events in the application.
|
|
18
|
+
|
|
19
|
+
## API Details
|
|
20
|
+
|
|
21
|
+
**Method:** GET
|
|
22
|
+
|
|
23
|
+
**URL:** `/metrics`
|
|
24
|
+
|
|
25
|
+
**Response Type:** text/plain
|
|
26
|
+
|
|
27
|
+
**Status Codes:**
|
|
28
|
+
- 200 OK: On success, returns the current metrics from the application.
|
|
29
|
+
|
|
30
|
+
**Response Body:**
|
|
31
|
+
The response body is a plain text representation of the metrics data, according to the Prometheus exposition formats. It includes the metrics mentioned above.
|
|
32
|
+
|
|
33
|
+
## Examples
|
|
34
|
+
|
|
35
|
+
### Request
|
|
36
|
+
|
|
37
|
+
```plaintext
|
|
38
|
+
GET /metrics
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### Response
|
|
42
|
+
```plaintext
|
|
43
|
+
`# HELP pepr_errors Mutation/Validate errors encountered
|
|
44
|
+
# TYPE pepr_errors counter
|
|
45
|
+
pepr_errors 5
|
|
46
|
+
|
|
47
|
+
# HELP pepr_alerts Mutation/Validate bad api token received
|
|
48
|
+
# TYPE pepr_alerts counter
|
|
49
|
+
pepr_alerts 10
|
|
50
|
+
|
|
51
|
+
# HELP pepr_Mutate Mutation operation summary
|
|
52
|
+
# TYPE pepr_Mutate summary
|
|
53
|
+
pepr_Mutate{quantile="0.01"} 100.60707900021225
|
|
54
|
+
pepr_Mutate{quantile="0.05"} 100.60707900021225
|
|
55
|
+
pepr_Mutate{quantile="0.5"} 100.60707900021225
|
|
56
|
+
pepr_Mutate{quantile="0.9"} 100.60707900021225
|
|
57
|
+
pepr_Mutate{quantile="0.95"} 100.60707900021225
|
|
58
|
+
pepr_Mutate{quantile="0.99"} 100.60707900021225
|
|
59
|
+
pepr_Mutate{quantile="0.999"} 100.60707900021225
|
|
60
|
+
pepr_Mutate_sum 100.60707900021225
|
|
61
|
+
pepr_Mutate_count 1
|
|
62
|
+
|
|
63
|
+
# HELP pepr_Validate Validation operation summary
|
|
64
|
+
# TYPE pepr_Validate summary
|
|
65
|
+
pepr_Validate{quantile="0.01"} 201.19413900002837
|
|
66
|
+
pepr_Validate{quantile="0.05"} 201.19413900002837
|
|
67
|
+
pepr_Validate{quantile="0.5"} 201.2137690000236
|
|
68
|
+
pepr_Validate{quantile="0.9"} 201.23339900001884
|
|
69
|
+
pepr_Validate{quantile="0.95"} 201.23339900001884
|
|
70
|
+
pepr_Validate{quantile="0.99"} 201.23339900001884
|
|
71
|
+
pepr_Validate{quantile="0.999"} 201.23339900001884
|
|
72
|
+
pepr_Validate_sum 402.4275380000472
|
|
73
|
+
pepr_Validate_count 2
|
|
74
|
+
```
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: RBAC
|
|
3
|
+
linkTitle: RBAC
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# RBAC Modes
|
|
7
|
+
|
|
8
|
+
During the build phase of Pepr (`npx pepr build --rbac-mode [admin|scoped]`), you have the option to specify the desired RBAC mode through specific flags. This allows fine-tuning the level of access granted based on requirements and preferences.
|
|
9
|
+
|
|
10
|
+
## Modes
|
|
11
|
+
|
|
12
|
+
**admin**
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
npx pepr build --rbac-mode admin
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
**Description:** The service account is given cluster-admin permissions, granting it full, unrestricted access across the entire cluster. This can be useful for administrative tasks where broad permissions are necessary. However, use this mode with caution, as it can pose security risks if misused. This is the default mode.
|
|
19
|
+
|
|
20
|
+
**scoped**
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
npx pepr build --rbac-mode scoped
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
**Description:** The service account is provided just enough permissions to perform its required tasks, and no more. This mode is recommended for most use cases as it limits potential attack vectors and aligns with best practices in security. _The admission controller's primary mutating or validating action doesn't require a ClusterRole (as the request is not persisted or executed while passing through admission control), if you have a use case where the admission controller's logic involves reading other Kubernetes resources or taking additional actions beyond just validating, mutating, or watching the incoming request, appropriate RBAC settings should be reflected in the ClusterRole. See how in [Updating the ClusterRole](#updating-the-clusterrole)._
|
|
27
|
+
|
|
28
|
+
## Debugging RBAC Issues
|
|
29
|
+
|
|
30
|
+
If encountering unexpected behaviors in Pepr while running in scoped mode, check to see if they are related to RBAC.
|
|
31
|
+
|
|
32
|
+
1. Check Deployment logs for RBAC errors:
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
kubectl logs -n pepr-system -l app | jq
|
|
36
|
+
|
|
37
|
+
# example output
|
|
38
|
+
{
|
|
39
|
+
"level": 50,
|
|
40
|
+
"time": 1697983053758,
|
|
41
|
+
"pid": 16,
|
|
42
|
+
"hostname": "pepr-static-test-watcher-745d65857d-pndg7",
|
|
43
|
+
"data": {
|
|
44
|
+
"kind": "Status",
|
|
45
|
+
"apiVersion": "v1",
|
|
46
|
+
"metadata": {},
|
|
47
|
+
"status": "Failure",
|
|
48
|
+
"message": "configmaps \"pepr-ssa-demo\" is forbidden: User \"system:serviceaccount:pepr-system:pepr-static-test\" cannot patch resource \"configmaps\" in API group \"\" in the namespace \"pepr-demo-2\"",
|
|
49
|
+
"reason": "Forbidden",
|
|
50
|
+
"details": {
|
|
51
|
+
"name": "pepr-ssa-demo",
|
|
52
|
+
"kind": "configmaps"
|
|
53
|
+
},
|
|
54
|
+
"code": 403
|
|
55
|
+
},
|
|
56
|
+
"ok": false,
|
|
57
|
+
"status": 403,
|
|
58
|
+
"statusText": "Forbidden",
|
|
59
|
+
"msg": "Dooes the ServiceAccount permissions to CREATE and PATCH this ConfigMap?"
|
|
60
|
+
}
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
2. Verify ServiceAccount Permissions with `kubectl auth can-i`
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
SA=$(kubectl get deploy -n pepr-system -o=jsonpath='{range .items[0]}{.spec.template.spec.serviceAccountName}{"\n"}{end}')
|
|
67
|
+
|
|
68
|
+
# Can i create configmaps as the service account in pepr-demo-2?
|
|
69
|
+
kubectl auth can-i create cm --as=system:serviceaccount:pepr-system:$SA -n pepr-demo-2
|
|
70
|
+
|
|
71
|
+
# example output: no
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
3. Describe the ClusterRole
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
SA=$(kubectl get deploy -n pepr-system -o=jsonpath='{range .items[0]}{.spec.template.spec.serviceAccountName}{"\n"}{end}')
|
|
78
|
+
|
|
79
|
+
kubectl describe clusterrole $SA
|
|
80
|
+
|
|
81
|
+
# example output:
|
|
82
|
+
Name: pepr-static-test
|
|
83
|
+
Labels: <none>
|
|
84
|
+
Annotations: <none>
|
|
85
|
+
PolicyRule:
|
|
86
|
+
Resources Non-Resource URLs Resource Names Verbs
|
|
87
|
+
--------- ----------------- -------------- -----
|
|
88
|
+
peprstores.pepr.dev [] [] [create delete get list patch update watch]
|
|
89
|
+
configmaps [] [] [watch]
|
|
90
|
+
namespaces [] [] [watch]
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
## Updating the ClusterRole
|
|
94
|
+
|
|
95
|
+
As discussed in the [Modes](#modes) section, the admission controller's primary mutating or validating action doesn't require a ClusterRole (as the request is not persisted or executed while passing through admission control), if you have a use case where the admission controller's logic involves reading other Kubernetes resources or taking additional actions beyond just validating, mutating, or watching the incoming request, appropriate RBAC settings should be reflected in the ClusterRole.
|
|
96
|
+
|
|
97
|
+
Step 1: Figure out the desired permissions. (`kubectl create clusterrole --help` is a good place to start figuring out the syntax)
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
kubectl create clusterrole configMapApplier --verb=create,patch --resource=configmap --dry-run=client -oyaml
|
|
101
|
+
|
|
102
|
+
# example output
|
|
103
|
+
apiVersion: rbac.authorization.k8s.io/v1
|
|
104
|
+
kind: ClusterRole
|
|
105
|
+
metadata:
|
|
106
|
+
creationTimestamp: null
|
|
107
|
+
name: configMapApplier
|
|
108
|
+
rules:
|
|
109
|
+
- apiGroups:
|
|
110
|
+
- ""
|
|
111
|
+
resources:
|
|
112
|
+
- configmaps
|
|
113
|
+
verbs:
|
|
114
|
+
- create
|
|
115
|
+
- patch
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
Step 2: Update the ClusterRole in the `dist` folder.
|
|
119
|
+
|
|
120
|
+
```yaml
|
|
121
|
+
...
|
|
122
|
+
apiVersion: rbac.authorization.k8s.io/v1
|
|
123
|
+
kind: ClusterRole
|
|
124
|
+
metadata:
|
|
125
|
+
name: pepr-static-test
|
|
126
|
+
rules:
|
|
127
|
+
- apiGroups:
|
|
128
|
+
- pepr.dev
|
|
129
|
+
resources:
|
|
130
|
+
- peprstores
|
|
131
|
+
verbs:
|
|
132
|
+
- create
|
|
133
|
+
- get
|
|
134
|
+
- patch
|
|
135
|
+
- watch
|
|
136
|
+
- apiGroups:
|
|
137
|
+
- ''
|
|
138
|
+
resources:
|
|
139
|
+
- namespaces
|
|
140
|
+
verbs:
|
|
141
|
+
- watch
|
|
142
|
+
- apiGroups:
|
|
143
|
+
- ''
|
|
144
|
+
resources:
|
|
145
|
+
- configmaps
|
|
146
|
+
verbs:
|
|
147
|
+
- watch
|
|
148
|
+
- create # New
|
|
149
|
+
- patch # New
|
|
150
|
+
...
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
Step 3: Apply the updated configuration
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: WebAssembly
|
|
3
|
+
linkTitle: WebAssembly
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# WASM Support: Running WebAssembly in Pepr Guide
|
|
7
|
+
|
|
8
|
+
Pepr fully supports WebAssembly. Depending on the language used to generate the WASM, certain files can be too large to fit into a `Secret` or `ConfigMap`. Due to this limitation, users have the ability to incorporate `*.wasm` and any other essential files during the build phase, which are then embedded into the Pepr Controller container. This is achieved through adding an array of files to the `includedFiles` section under `pepr` in the `package.json`.
|
|
9
|
+
|
|
10
|
+
> **NOTE -** In order to instantiate the WebAsembly module in TypeScript, you need the WebAssembly type. This is accomplished through add the "DOM" to the `lib` array in the `compilerOptions` section of the `tsconfig.json`. Ex: `"lib": ["ES2022", "DOM"]`. Be aware that adding the DOM will add a lot of extra types to your project and your developer experience will be impacted in terms of the intellisense.
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
## High-Level Overview
|
|
14
|
+
|
|
15
|
+
WASM support is achieved through adding files as layers atop the Pepr controller image, these files are then able to be read by the individual capabilities. The key components of WASM support are:
|
|
16
|
+
|
|
17
|
+
- Add files to the **base** of the Pepr module.
|
|
18
|
+
- Reference the files in the `includedFiles` section of the `pepr` block of the `package.json`
|
|
19
|
+
- Run `npx pepr build` with the `-r ` option specifying registry info. Ex: `npx pepr build -r docker.io/cmwylie19`
|
|
20
|
+
- Pepr builds and pushes a custom image that is used in the `Deployment`.
|
|
21
|
+
|
|
22
|
+
## Using WASM Support
|
|
23
|
+
|
|
24
|
+
### Creating a WASM Module in Go
|
|
25
|
+
|
|
26
|
+
Create a simple Go function that you want to call from your Pepr module
|
|
27
|
+
|
|
28
|
+
```go
|
|
29
|
+
package main
|
|
30
|
+
|
|
31
|
+
import (
|
|
32
|
+
"fmt"
|
|
33
|
+
"syscall/js"
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
func concats(this js.Value, args []js.Value) interface{} {
|
|
37
|
+
fmt.Println("PeprWASM!")
|
|
38
|
+
stringOne := args[0].String()
|
|
39
|
+
stringTwo := args[1].String()
|
|
40
|
+
return fmt.Sprintf("%s%s", stringOne, stringTwo)
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
func main() {
|
|
44
|
+
done := make(chan struct{}, 0)
|
|
45
|
+
js.Global().Set("concats", js.FuncOf(concats))
|
|
46
|
+
<-done
|
|
47
|
+
}
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Compile it to a wasm target and move it to your Pepr module
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
GOOS=js GOARCH=wasm go build -o main.wasm
|
|
54
|
+
cp main.wasm $YOUR_PEPR_MODULE/
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Copy the `wasm_exec.js` from `GOROOT` to your Pepr Module
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
cp "$(go env GOROOT)/misc/wasm/wasm_exec.js" $YOUR_PEPR_MODULE/
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Update the polyfill to add `globalThis.crypto` in the `wasm_exec.js` since we are not running in the browser. This is needed directly under: `(() => {`
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
```javascript
|
|
67
|
+
// Initialize the polyfill
|
|
68
|
+
if (typeof globalThis.crypto === 'undefined') {
|
|
69
|
+
globalThis.crypto = {
|
|
70
|
+
getRandomValues: (array) => {
|
|
71
|
+
for (let i = 0; i < array.length; i++) {
|
|
72
|
+
array[i] = Math.floor(Math.random() * 256);
|
|
73
|
+
}
|
|
74
|
+
},
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
### Configure Pepr to use WASM
|
|
81
|
+
|
|
82
|
+
After adding the files to the root of the Pepr module, reference those files in the `package.json`:
|
|
83
|
+
|
|
84
|
+
```json
|
|
85
|
+
{
|
|
86
|
+
"name": "pepr-test-module",
|
|
87
|
+
"version": "0.0.1",
|
|
88
|
+
"description": "A test module for Pepr",
|
|
89
|
+
"keywords": [
|
|
90
|
+
"pepr",
|
|
91
|
+
"k8s",
|
|
92
|
+
"policy-engine",
|
|
93
|
+
"pepr-module",
|
|
94
|
+
"security"
|
|
95
|
+
],
|
|
96
|
+
"engines": {
|
|
97
|
+
"node": ">=18.0.0"
|
|
98
|
+
},
|
|
99
|
+
"pepr": {
|
|
100
|
+
"name": "pepr-test-module",
|
|
101
|
+
"uuid": "static-test",
|
|
102
|
+
"onError": "ignore",
|
|
103
|
+
"alwaysIgnore": {
|
|
104
|
+
"namespaces": [],
|
|
105
|
+
"labels": []
|
|
106
|
+
},
|
|
107
|
+
"includedFiles":[
|
|
108
|
+
"main.wasm",
|
|
109
|
+
"wasm_exec.js"
|
|
110
|
+
]
|
|
111
|
+
},
|
|
112
|
+
...
|
|
113
|
+
}
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
Update the `tsconfig.json` to add "DOM" to the `compilerOptions` lib:
|
|
117
|
+
|
|
118
|
+
```json
|
|
119
|
+
{
|
|
120
|
+
"compilerOptions": {
|
|
121
|
+
"allowSyntheticDefaultImports": true,
|
|
122
|
+
"declaration": true,
|
|
123
|
+
"declarationMap": true,
|
|
124
|
+
"emitDeclarationOnly": true,
|
|
125
|
+
"esModuleInterop": true,
|
|
126
|
+
"lib": [
|
|
127
|
+
"ES2022",
|
|
128
|
+
"DOM" // <- Add this
|
|
129
|
+
],
|
|
130
|
+
"module": "CommonJS",
|
|
131
|
+
"moduleResolution": "node",
|
|
132
|
+
"outDir": "dist",
|
|
133
|
+
"resolveJsonModule": true,
|
|
134
|
+
"rootDir": ".",
|
|
135
|
+
"strict": false,
|
|
136
|
+
"target": "ES2022",
|
|
137
|
+
"useUnknownInCatchVariables": false
|
|
138
|
+
},
|
|
139
|
+
"include": [
|
|
140
|
+
"**/*.ts"
|
|
141
|
+
]
|
|
142
|
+
}
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
### Call WASM functions from TypeScript
|
|
146
|
+
|
|
147
|
+
Import the `wasm_exec.js` in the `pepr.ts`
|
|
148
|
+
|
|
149
|
+
```javascript
|
|
150
|
+
import "./wasm_exec.js";
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
Create a helper function to load the wasm file in a capability and call it during an event of your choice
|
|
154
|
+
|
|
155
|
+
```typescript
|
|
156
|
+
async function callWASM(a,b) {
|
|
157
|
+
const go = new globalThis.Go();
|
|
158
|
+
|
|
159
|
+
const wasmData = readFileSync("main.wasm");
|
|
160
|
+
var concated: string;
|
|
161
|
+
|
|
162
|
+
await WebAssembly.instantiate(wasmData, go.importObject).then(wasmModule => {
|
|
163
|
+
go.run(wasmModule.instance);
|
|
164
|
+
|
|
165
|
+
concated = global.concats(a,b);
|
|
166
|
+
});
|
|
167
|
+
return concated;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
When(a.Pod)
|
|
171
|
+
.IsCreated()
|
|
172
|
+
.Mutate(async pod => {
|
|
173
|
+
try {
|
|
174
|
+
let label_value = await callWASM("loves","wasm")
|
|
175
|
+
pod.SetLabel("pepr",label_value)
|
|
176
|
+
}
|
|
177
|
+
catch(err) {
|
|
178
|
+
Log.error(err);
|
|
179
|
+
}
|
|
180
|
+
});
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
### Run Pepr Build
|
|
184
|
+
|
|
185
|
+
Build your Pepr module with the registry specified.
|
|
186
|
+
|
|
187
|
+
```bash
|
|
188
|
+
npx pepr build -r docker.io/defenseunicorns
|
|
189
|
+
```
|
package/website/go.mod
ADDED
package/website/go.sum
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
github.com/defenseunicorns/defense-unicorns-hugo-theme v0.3.9 h1:o2ptq0ozp8x5R61Ik0E08YI3VEBjJGwUvKs8sRleUC8=
|
|
2
|
+
github.com/defenseunicorns/defense-unicorns-hugo-theme v0.3.9/go.mod h1:qOBlMoMnovWO8PwmHAlpR7WfPLOJiiq4+XIrVblRb8g=
|
|
3
|
+
github.com/defenseunicorns/defense-unicorns-hugo-theme/dependencies v0.3.9 h1:nz4Aiu+ISXKESXgTjPyDyR9L708XjszH6lnQAGFAAVI=
|
|
4
|
+
github.com/defenseunicorns/defense-unicorns-hugo-theme/dependencies v0.3.9/go.mod h1:zQT7gnRyPnVCNxREasYkyewPJLhemxlOGZhbu+9mcfQ=
|