Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: document sdk helpers #774

Merged
merged 25 commits into from
May 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
220a88f
added sdk and helpers files
schaeferka Apr 26, 2024
82c3742
updated docs file structure for helpers and sdk
schaeferka Apr 26, 2024
f83e17a
split actions info into mutate/validate/reconcile/watch
schaeferka Apr 26, 2024
e279e54
updated reconcile.md
schaeferka Apr 26, 2024
7face3b
updated watch.md
schaeferka Apr 26, 2024
581e88d
updated validate.md
schaeferka Apr 26, 2024
b4ad032
Merge branch 'main' of github.com:defenseunicorns/pepr
schaeferka Apr 26, 2024
8b97eba
updated sdk.md file layout
schaeferka May 1, 2024
a41abca
updated containers section of sdk.md
schaeferka May 1, 2024
e6b216f
updated containers section of sdk.md
schaeferka May 1, 2024
3327afe
updated containers section of sdk.md
schaeferka May 1, 2024
df008f3
updated containers section of sdk.md
schaeferka May 1, 2024
fc7091b
updated containers section of sdk.md
schaeferka May 1, 2024
9c30074
updated sdk.md content
schaeferka May 1, 2024
e772720
Merge branch 'main' of github.com:defenseunicorns/pepr
schaeferka May 1, 2024
94b0c1c
fixed formatting in pepr-cli
schaeferka May 1, 2024
37fc69e
updated getOwnerRefFrom
schaeferka May 1, 2024
4fc864e
updated sdk.md to remove type casting
schaeferka May 1, 2024
fb139c6
updated link to sdk.md in mutate.md
schaeferka May 1, 2024
fdb3acf
updated mutate helpers in mutate.md
schaeferka May 1, 2024
796fb2f
Update docs/030_user-guide/015_sdk.md
schaeferka May 2, 2024
2b8991d
Update docs/030_user-guide/015_sdk.md
schaeferka May 2, 2024
ef97646
Update docs/030_user-guide/015_sdk.md
schaeferka May 2, 2024
8c39574
Update docs/030_user-guide/030_actions/020_validate.md
schaeferka May 2, 2024
7adfdd8
Merge branch 'main' into 751-document-sdk-helpers
schaeferka May 2, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 1 addition & 12 deletions docs/030_user-guide/010_pepr-cli.md
Original file line number Diff line number Diff line change
@@ -1,22 +1,11 @@
# Pepr CLI

- [Pepr CLI](#pepr-cli)
- [`npx pepr init`](#npx-pepr-init)
- [`npx pepr update`](#npx-pepr-update)
- [`npx pepr dev`](#npx-pepr-dev)
- [`npx pepr deploy`](#npx-pepr-deploy)
- [`npx pepr monitor`](#npx-pepr-monitor)
- [`npx pepr uuid`](#npx-pepr-uuid)
- [`npx pepr build`](#npx-pepr-build)
- [`npx pepr kfc`](#npx-pepr-kfc)

## `npx pepr init`

Initialize a new Pepr Module.

**Options:**


- `--skip-post-init` - Skip npm install, git init and VSCode launch

---
Expand All @@ -27,7 +16,6 @@ Update the current Pepr Module to the latest SDK version. This command is not re

**Options:**


- `--skip-template-update` - Skip updating the template files

---
Expand Down Expand Up @@ -97,6 +85,7 @@ Create a [zarf.yaml](https://zarf.dev) and K8s manifest for the current module.
- `-v, --version <version>. Example: '0.27.3'` - The version of the Pepr image to use in the deployment manifests.

## `npx pepr kfc`

Execute a `kubernetes-fluent-client` command. This command is a wrapper around `kubernetes-fluent-client`.

Usage:
Expand Down
93 changes: 93 additions & 0 deletions docs/030_user-guide/015_sdk.md
schaeferka marked this conversation as resolved.
Show resolved Hide resolved
schaeferka marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
# Pepr SDK

## `containers`

Returns list of all containers in a pod. Accepts the following parameters:

- **@param peprValidationRequest** The request/pod to get the containers from
- **@param containerType** The type of container to get

**Usage:**

**_Get all containers_**

```typescript
let result = containers(peprValidationRequest)
```

**_Get only the standard containers_**

```typescript
let result = containers(peprValidationRequest, "containers")
```

**_Get only the init containers_**

```typescript
let result = containers(peprValidationRequest, "initContainers")
```

**_Get only the ephemeral containers_**

```typescript
let result = containers(peprValidationRequest, "ephemeralContainers")
```

---

## `getOwnerRefFrom`

Returns the owner reference for a Kubernetes resource. Accepts the following parameters:

- **@param kubernetesResource: GenericKind** The Kubernetes resource to get the owner reference for

**Usage:**

```typescript
const ownerRef = getOwnerRefFrom(kubernetesResource);

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you're missing the backticks to close the typescript block here. 🤔

---

## `writeEvent`

Write a K8s event for a CRD. Accepts the following parameters:

- **@param kubernetesResource: GenericKind** The Kubernetes resource to write the event for
- **@param event** The event to write, should contain a human-readable message for the event
- **@param eventType** The type of event to write, for example "Warning"
- **@param eventReason** The reason for the event, for example "ReconciliationFailed"
- **@param reportingComponent** The component that is reporting the event, for example "uds.dev/operator"
- **@param reportingInstance** The instance of the component that is reporting the event, for example process.env.HOSTNAME

**Usage:**

```typescript
writeEvent(
kubernetesResource,
event,
"Warning",
"ReconciliationFailed",
"uds.dev/operator",
process.env.HOSTNAME,
);
```

---

## `sanitizeResourceName`

Returns a sanitized resource name to make the given name a valid Kubernetes resource name. Accepts the following parameter:

- **@param resourceName** The name of the resource to sanitize

**Usage:**

```typescript
const sanitizedResourceName = sanitizeResourceName(resourceName)
```

---

## See Also

Looking for information on the Pepr mutate helpers? See [Helpers](./030_actions/010_mutate.md) for information on helpers for mutate actions.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Looking for information on the Pepr mutate helpers? See [Helpers](./030_actions/010_mutate.md) for information on helpers for mutate actions.
Looking for information on the Pepr mutate helpers? See [Mutate Helpers](./030_actions/010_mutate.md#mutate-helpers) for information on those.

I'm not 100% on the link-anchor syntax -- worth testing, for sure -- but I think something like this might work better cuz it takes a reader directly to the appropriate section of the target page, no?

83 changes: 83 additions & 0 deletions docs/030_user-guide/030_actions/010_mutate.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
# Mutate

Mutating admission webhooks are invoked first and can modify objects sent to the API server to enforce custom defaults. After an object is sent to Pepr's Mutating Admission Webhook, Pepr will [annotate the object](https://github.com/defenseunicorns/pepr/blob/f01f5eeda16c13ecd0d51b26b8a16ed7e4c1b080/src/lib/mutate-processor.ts#L64) to indicate the status.

After a successful mutation of an object in a module with UUID static-test, and capability name hello-pepr, expect to see this annotation: `static-test.pepr.dev/hello-pepr: succeeded`.

## Mutate Helpers

### `SetLabel`

`SetLabel` is used to set a lable on a Kubernetes object as part of a Pepr Mutate action.

For example, to add a label when a ConfigMap is created:

```typescript
When(a.ConfigMap)
.IsCreated()
.Mutate(request => {
request
// Here we are adding a label to the ConfigMap.
.SetLabel("pepr", "was-here")

// Note that we are not returning anything here. This is because Pepr is tracking the changes in each action automatically.
});
```

### `RemoveLabel`

`RemoveLabel` is used to remove a label on a Kubernetes object as part of a Pepr Mutate action.

For example, to remove a label when a ConfigMap is updated:

```typescript
When(a.ConfigMap)
.IsCreated()
.Mutate(request => {
request
// Here we are removing a label from the ConfigMap.
.RemoveLabel("remove-me")

// Note that we are not returning anything here. This is because Pepr is tracking the changes in each action automatically.
});
```

### `SetAnnotation`

`SetAnnotation` is used to set an annotation on a Kubernetes object as part of a Pepr Mutate action.

For example, to add an annotation when a ConfigMap is created:

```typescript
When(a.ConfigMap)
.IsCreated()
.Mutate(request => {
request
// Here we are adding an annotation to the ConfigMap.
.SetAnnotation("pepr.dev", "annotations-work-too");

// Note that we are not returning anything here. This is because Pepr is tracking the changes in each action automatically.
});
```

### `RemoveAnnotation`

`RemoveAnnotation` is used to remove an annotation on a Kubernetes object as part of a Pepr Mutate action.

For example, to remove an annotation when a ConfigMap is updated:

```typescript
When(a.ConfigMap)
.IsUpdated()
.Mutate(request => {
request
// Here we are removing an annotation from the ConfigMap.
.RemoveAnnotation("remove-me");

// Note that we are not returning anything here. This is because Pepr is tracking the changes in each action automatically.
});
```

## See Also

See also [SDK](../130_sdk.md) for information on the Pepr SDK.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
See also [SDK](../130_sdk.md) for information on the Pepr SDK.
Looking for some more generic helpers? Check out the [Module Author SDK](../130_sdk.md) for information on other things that Pepr can help with.

Not 100% on the wording, but something like this would set reader expectation a bit better cuz it set context on the SDK as being "more generic helpers". Kinda hard to tell what "the Pepr SDK" is / how it would be relevant, otherwise.

5 changes: 5 additions & 0 deletions docs/030_user-guide/030_actions/020_validate.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Validate

After the Mutation phase comes the Validation phase where the validating admission webhooks are invoked and can reject requests to enforce custom policies.

Validate does not annotate the objects that are allowed into the cluster, but the validation webhook can be audited with `npx pepr monitor`. Read the [monitoring docs](https://docs.pepr.dev/main/best-practices/#monitoring) for more information.
3 changes: 3 additions & 0 deletions docs/030_user-guide/030_actions/030_reconcile.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Reconcile

Reconcile functions the same as Watch but is tailored for building Kubernetes Controllers and Operators because it processes callback operations in a [Queue](https://github.com/defenseunicorns/pepr/blob/f01f5eeda16c13ecd0d51b26b8a16ed7e4c1b080/src/lib/watch-processor.ts#L86), guaranteeing ordered and synchronous processing of events, even when the system may be under heavy load.
3 changes: 3 additions & 0 deletions docs/030_user-guide/030_actions/040_watch.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Watch

[Kubernetes](https://kubernetes.io/docs/reference/using-api/api-concepts) supports efficient change notifications on resources via watches. Pepr uses the Watch action for monitoring resources that previously existed in the cluster and for performing long-running asynchronous events upon receiving change notifications on resources, as watches are not limited by [timeouts](https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/#timeouts).
Original file line number Diff line number Diff line change
@@ -1,13 +1,7 @@
# Actions

- [Overview](#overview)
- [Mutate](#mutate)
- [Validate](#validate)
- [Watch](#watch)
- [Reconcile](#reconcile)

## Overview

## Overview

An action is a discrete set of behaviors defined in a single function that acts on a given Kubernetes GroupVersionKind (GVK) passed in during the admission controller lifecycle. Actions are the atomic operations that are performed on Kubernetes resources by Pepr.

For example, an action could be responsible for adding a specific label to a Kubernetes resource, or for modifying a specific field in a resource's metadata. Actions can be grouped together within a Capability to provide a more comprehensive set of operations that can be performed on Kubernetes resources.
Expand Down Expand Up @@ -83,40 +77,40 @@ When(WebApp)
.IsCreatedOrUpdated()
.Validate(validator)
.Reconcile(async instance => {

const { namespace, name, generation } = instance.metadata;

if (!instance.metadata?.namespace) {
Log.error(instance, `Invalid WebApp definition`);
return;
}

const isPending = instance.status?.phase === Phase.Pending;
const isCurrentGeneration = generation === instance.status?.observedGeneration;

if (isPending || isCurrentGeneration) {
Log.debug(instance, `Skipping pending or completed instance`);
return;
}

Log.debug(instance, `Processing instance ${namespace}/${name}`);


try {
// Set Status to pending
await updateStatus(instance, { phase: Phase.Pending });

// Deploy Deployment, ConfigMap, Service, ServiceAccount, and RBAC based on instance
await Deploy(instance);

// Set Status to ready
await updateStatus(instance, {
phase: Phase.Ready,
observedGeneration: instance.metadata.generation,
});
} catch (e) {
Log.error(e, `Error configuring for ${namespace}/${name}`);

// Set Status to failed
void updateStatus(instance, {
phase: Phase.Failed,
Expand All @@ -125,23 +119,3 @@ When(WebApp)
}
});
```

## Mutate

Mutating admission webhooks are invoked first and can modify objects sent to the API server to enforce custom defaults. After an object is sent to Pepr's Mutating Admission Webhook, Pepr will [annotate the object](https://github.com/defenseunicorns/pepr/blob/f01f5eeda16c13ecd0d51b26b8a16ed7e4c1b080/src/lib/mutate-processor.ts#L64) to indicate the status.

After a successful mutation of an object in a module with UUID static-test, and capability name hello-pepr, expect to see this annotation: `static-test.pepr.dev/hello-pepr: succeeded`.

## Validate

After the Mutation phase, after all object modifications are complete, and after the incoming object is validated by the API server, validating admission webhooks are invoked and can reject requests to enforce custom policies.

Validate does not annotate the objects that are allowed into the cluster, but the validation webhook can be audited with `npx pepr monitor`. Read the [monitoring docs](https://docs.pepr.dev/main/best-practices/#monitoring) for more information.

## Watch

[Kubernetes](https://kubernetes.io/docs/reference/using-api/api-concepts) supports efficient change notifications on resources via watches. Pepr uses the Watch action for monitoring resources that previously existed in the cluster and for performing long-running asynchronous events upon receiving change notifications on resources, as watches are not limited by [timeouts](https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/#timeouts).

## Reconcile

Reconcile functions the same as Watch but is tailored for building Kubernetes Controllers and Operators because it processes callback operations in a [Queue](https://github.com/defenseunicorns/pepr/blob/f01f5eeda16c13ecd0d51b26b8a16ed7e4c1b080/src/lib/watch-processor.ts#L86), guaranteeing ordered and synchronous processing of events, even when the system may be under heavy load.
Loading