Skip to content

Commit e4f354b

Browse files
Improve provisioners and patchers docs (#190)
Signed-off-by: Mathieu Benoit <mathieu-benoit@hotmail.fr>
1 parent 7198787 commit e4f354b

5 files changed

Lines changed: 369 additions & 17 deletions

File tree

.gitignore

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ package-lock.json
66
.cspell/
77
.vscode/ltex.dictionary.en-US.txt
88
./static/_pagefind
9-
.score-compose/state.yaml
10-
.score-compose/zz-default.provisioners.yaml
11-
.score-compose/mounts/routing-QXKXWL/nginx.conf
9+
.score-compose/
1210
compose.yaml
11+
.score-k8s/
12+
manifests.yaml

content/en/docs/score implementation/score-compose/patch-templates.md

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,26 @@ aliases:
88
- /docs/reference/score-cli/score-compose/patch-templates
99
---
1010

11-
Since `score-compose` version [`0.27.0`](https://github.com/score-spec/score-compose/releases/tag/0.27.0), as Platform Engineers you can override or patch the default Workload manifests generated by `score-compose generate`. Seemlessly for your Developers, by using `score-compose init --patch-templates`.
11+
## Overview
1212

13-
Each template file is evaluated as a Golang text/template and should output a yaml/json encoded array of patches. Each patch is an object with required `op` (`set` or `delete`), `patch` (a dot-separated json path), a `value` if the `op` == `set`, and an optional `description` for showing in the logs.
13+
A common requirement is for Platform Engineers to slightly modify or adjust the output of the conversion process, and this seemlessly for their Developers. This can be done by providing one or more patching templates at `init` time. These patching templates generate JSON patches which are applied on top of the output compose file, just before being written. Patching templates have access to the current compose spec as `.Compose`, the map of workload name to Score Spec as `.Workloads`, and can use any functions from [`Masterminds/sprig`](https://github.com/Masterminds/sprig).
1414

15-
For example, to inject more security for each Workload you can use this template [`score-compose/unprivileged.tpl`](https://raw.githubusercontent.com/score-spec/community-patchers/refs/heads/main/score-compose/unprivileged.tpl):
15+
In this way, you can extend the behavior of the `score-compose` implementation.
16+
17+
Each template file is evaluated as a Golang text/template and should output a yaml/json encoded array of patches. Each patch is an object with required `op` (`set` or `delete`), `patch` (a dot-separated json path, use backslash to escape), a `value` if the `op` is `set`, and an optional `description` for showing in the logs.
18+
19+
Example of paths:
20+
21+
```yaml
22+
services.some\.thing # patches the some.thing service
23+
services.foo.ports.0 # modifies the first item in the ports array
24+
services.foo.ports.-1 # adds to the end of the ports array
25+
something.:0000.xyz # patches the xyz item in the "0000" item of something (: escapes a numeric index)
26+
```
27+
28+
## Example
29+
30+
Here is a concrete example showing how to inject more security for each Workload by using this template [`score-compose/unprivileged.tpl`](https://raw.githubusercontent.com/score-spec/community-patchers/refs/heads/main/score-compose/unprivileged.tpl):
1631

1732
```yaml
1833
{{ range $name, $spec := .Workloads }}
@@ -30,16 +45,22 @@ For example, to inject more security for each Workload you can use this template
3045
{{ end }}
3146
```
3247

33-
You can run this command to use this patch template:
48+
## Use a patch template
49+
50+
Run this command to import this patch template:
3451

3552
```bash
3653
score-compose init --patch-templates https://raw.githubusercontent.com/score-spec/community-patchers/refs/heads/main/score-compose/unprivileged.tpl
3754
```
3855

39-
And then the `generate` command will use it for the generated `compose.yaml` file:
56+
Run the `generate` command:
4057

4158
```bash
4259
score-compose generate score.yaml
4360
```
4461

62+
And then see that this patch template was applied on the final generated `compose.yaml` file.
63+
64+
## Write your own patch template
65+
4566
A list of patch templates shared by the community can be found [here](https://github.com/score-spec/community-patchers). Users are encouraged to use them and contribute to this growing list of patch templates.

content/en/docs/score implementation/score-compose/resources-provisioners.md

Lines changed: 106 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,15 @@ aliases:
99
- /docs/reference/score-cli/score-compose/resources
1010
---
1111

12-
`score-compose` comes with out-of-the-box support of the following provisioners, that you can list with this command `score-compose provisioners list`:
12+
Resource provisioners are the way for Platform Engineers to write concrete implementations of resource types that Developers can use in their Score file in the [`resources` section](/docs/score-specification/score-spec-reference/#resources-definition).
13+
14+
With the `score-compose init` command, a `.score-compose/zz-default.provisioners.yaml` file is created, which is a YAML file holding the definition of the [built-in provisioners](#default-provisioners).
15+
16+
When running `score-compose generate`, all `*.provisioners.yaml` files are loaded in lexicographic order from the `.score-compose` directory. This allows projects to include their own custom provisioners that extend or override the defaults.
17+
18+
To list the provisioners available from the `.score-compose` directory, run the `score-compose provisioners list` command.
19+
20+
## Default provisioners
1321

1422
| Type | Class | Params | Output | Description |
1523
| ------------------- | ----- | ---------------------- | ---------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------- |
@@ -30,7 +38,7 @@ aliases:
3038

3139
The source code of these provisioners implementations can be found in the [`score-compose`'s default provisioners file](https://github.com/score-spec/score-compose/blob/main/internal/command/default.provisioners.yaml).
3240

33-
Users are encouraged to write their own custom provisioners to support new resource types or to modify the default implementations above. Learn how to do that with this example [here](https://score.dev/blog/writing-a-custom-score-compose-provisioner-for-apache-kafka/).
41+
## Community provisioners
3442

3543
A list of provisioners authored and shared by the community can also be found [here](https://github.com/score-spec/community-provisioners). Users are encouraged to use them and contribute to this growing list of community provisioners:
3644

@@ -44,3 +52,99 @@ A list of provisioners authored and shared by the community can also be found [h
4452
| `environment` | (any) | (none) | (none) | Loads environment variables from a local `.env` file. |
4553
| `horizontal-pod-autoscaler` | (any) | (none) | (none) | Generates an empty object because HPA is not supported in Docker Compose. |
4654
| `service` | (any) | (none) | `name` | Outputs the name of the Workload dependency if it exists in the list of Workloads. |
55+
56+
## Install provisioner files
57+
58+
To easily install provisioners, `score-compose` provides the `--provisioners` flag with the `init` command, which downloads the provisioner file via a URL and installs it with the highest priority.
59+
60+
For example, when running the following, the provisioners file B will be matched before A because B was installed after A:
61+
62+
```bash
63+
score-compose init --provisioners https://example.com/provisioner-A.yaml --provisionerss https://example.com/provisioner-B.yaml
64+
```
65+
66+
The provisioners can be loaded from the following kinds of urls:
67+
68+
- HTTP: `http://host/file`
69+
- HTTPS: `https://host/file`
70+
- Git (SSH): `git-ssh://git@host/repo.git/file`
71+
- Git (HTTPS): `git-https://host/repo.git/file`
72+
- OCI: `oci://[registry/][namespace/]repository[:tag|@digest][#file]`
73+
- Local File: `/path/to/local/file`
74+
- Stdin: `-` (read from standard input)
75+
76+
This is commonly used to import custom provisioners or common provisioners used by your team or organization and supported by your platform.
77+
78+
## Write your own provisioners
79+
80+
Users are encouraged to write their own custom provisioners to support new resource types or to modify the default implementations.
81+
82+
Each entry in the file has the following common fields, other fields may also exist for specific provisioner types.
83+
84+
```yaml
85+
- uri: <provisioner uri>
86+
type: <resource type>
87+
class: <optional resource class>
88+
id: <optional resource id>
89+
description: <optional description>
90+
```
91+
92+
The `uri` of each provisioner is a combination of its implementation (either [`template://`](#the-template-provisioner) or [`cmd://`](#the-cmd-provisioner)) and a unique identifier. Provisioners are matched in first-match order when loading the provisioner files lexicographically, so any custom provisioner files are matched first before `zz-default.provisioners.yaml`.
93+
94+
### The `template://` provisioner
95+
96+
Most built in provisioners are implemented as a series of Go templates using the template provisioner. The implementation can be found [here](https://github.com/score-spec/score-compose/blob/main/internal/provisioners/templateprov/template.go). The Go template engine is [text/template](https://pkg.go.dev/text/template).
97+
98+
The following extra fields can be configured as required on each instance of this provisioner:
99+
100+
| Field | Type | Comment |
101+
| ------------------ | ------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
102+
| `init` | String, Go template | A Go template for a valid YAML dictionary. The values here will be provided to the next templates as the `.Init` state. |
103+
| `state` | String, Go template | A Go template for a valid YAML dictionary. The values here will be persisted into the state file and made available to future executions and are provided to the next templates as the `.State` state. |
104+
| `shared` | String, Go template | A Go template for a valid YAML dictionary. The values here will be _merged_ using a JSON-patch mechanism with the current shared state across all resources and made available to future executions through `.Shared` state. |
105+
| `outputs` | String, Go template | A Go template for a valid YAML dictionary. The values here are the outputs of the resource that can be accessed through `${resources.*}` placeholder resolution. |
106+
| `directories` | String, Go template | A Go template for a valid YAML dictionary. Each path -> bool mapping will create (true) or delete (false) a directory relative to the mounts directory. |
107+
| `files` | String, Go template | A Go template for a valid YAML dictionary. Each path -> string\|null will create a relative file (string) or delete it (null) relative to the mounts directory. |
108+
| `networks` | String, Go template | A Go template for a valid set of named Compose [Networks](https://github.com/compose-spec/compose-spec/blob/master/06-networks.md). These will be added to the output project. |
109+
| `volumes` | String, Go template | A Go template for a valid set of named Compose [Volumes](https://github.com/compose-spec/compose-spec/blob/master/07-volumes.md). |
110+
| `services` | String, Go template | A Go template for a valid set of named Compose [Services](https://github.com/compose-spec/compose-spec/blob/master/05-services.md). |
111+
| `info_logs` | String, Go template | A Go template for informational messages for the user which may help connecting or testing the provisioned resource. |
112+
| `supported_params` | List of String | A list of parameters that the provisioner expects to be passed in. |
113+
| `expected_outputs` | List of String | A list of expected outputs that the provisioner should return. |
114+
115+
Each template has access to the [Sprig](http://masterminds.github.io/sprig/) functions library and executes with access to the following structure:
116+
117+
```go
118+
type Data struct {
119+
Uid string
120+
Type string
121+
Class string
122+
Id string
123+
Params map[string]interface{}
124+
Metadata map[string]interface{}
125+
Init map[string]interface{}
126+
State map[string]interface{}
127+
Shared map[string]interface{}
128+
WorkloadServices map[string]NetworkService
129+
ComposeProjectName string
130+
MountsDirectory string
131+
}
132+
```
133+
134+
### The `cmd://` provisioner
135+
136+
The command provisioner implementation can be used to execute an external binary or script to provision the resource. The provision IO structures are serialised to json and send on standard-input to the new process, any stdout content is decoded as json and is used as the outputs of the provisioner.
137+
138+
The `uri` of the provisioner encodes the binary to be executed:
139+
140+
- `cmd://python` will execute the `python` binary on the PATH
141+
- `cmd://../my-script` will execute `../my-script`
142+
- `cmd://./my-script` will execute `my-script` in the current directory
143+
- and `cmd://~/my-script` will execute the `my-script` binary in the home directory
144+
145+
Additional arguments can be provided via the `args` configuration key, for example a basic provisioner can be created using python inline scripts:
146+
147+
```yaml
148+
- uri: "cmd://python"
149+
args: ["-c", "print({\"resource_outputs\":{}})"]
150+
```

content/en/docs/score implementation/score-k8s/patch-templates.md

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,26 @@ aliases:
88
- /docs/reference/score-cli/score-k8s/patch-templates
99
---
1010

11-
Since `score-k8s` version [`0.4.0`](https://github.com/score-spec/score-k8s/releases/tag/0.4.0), as Platform Engineers you can override or patch the default Workload manifests generated by `score-k8s generate`. Seemlessly for your Developers, by using `score-k8s init --patch-templates`.
11+
## Overview
1212

13-
Each template file is evaluated as a Golang text/template and should output a yaml/json encoded array of patches. Each patch is an object with required `op` (`set` or `delete`), `patch` (a dot-separated json path), a `value` if the `op` == `set`, and an optional `description` for showing in the logs. The template has access to `.Manifests` and `.Workloads`.
13+
A common requirement is for Platform Engineers to slightly modify or adjust the output of the conversion process, and this seemlessly for their Developers. This can be done by providing one or more patching templates at `init` time. These patching templates generate JSON patches which are applied on top of the output manifests file, just before being written. Patching templates have access to the current manifests spec as `.Manifests`, the map of workload name to Score Spec as `.Workloads`, the optional name of the namespace in Kubernetes `.Namespace`, and can use any functions from [`Masterminds/sprig`](https://github.com/Masterminds/sprig).
1414

15-
For example, to inject more security for each Workload you can use this template [`score-k8s/unprivileged.tpl`](https://raw.githubusercontent.com/score-spec/community-patchers/refs/heads/main/score-k8s/unprivileged.tpl):
15+
In this way, you can extend the behavior of the `score-k8s` implementation.
16+
17+
Each template file is evaluated as a Golang text/template and should output a yaml/json encoded array of patches. Each patch is an object with required `op` (`set` or `delete`), `patch` (a dot-separated json path, use backslash to escape), a `value` if the `op` is `set`, and an optional `description` for showing in the logs.
18+
19+
Example of paths:
20+
21+
```yaml
22+
services.some\.thing # patches the some.thing service
23+
services.foo.ports.0 # modifies the first item in the ports array
24+
services.foo.ports.-1 # adds to the end of the ports array
25+
something.:0000.xyz # patches the xyz item in the "0000" item of something (: escapes a numeric index)
26+
```
27+
28+
## Example
29+
30+
Here is a concrete example showing how to inject more security for each Workload by using this template [`score-k8s/unprivileged.tpl`](https://raw.githubusercontent.com/score-spec/community-patchers/refs/heads/main/score-k8s/unprivileged.tpl):
1631

1732
```yaml
1833
{{ range $i, $m := .Manifests }}
@@ -44,16 +59,22 @@ For example, to inject more security for each Workload you can use this template
4459
{{ end }}
4560
```
4661

47-
You can run this command to use this patch template:
62+
## Use a patch template
63+
64+
Run this command to import this patch template:
4865

4966
```bash
5067
score-k8s init --patch-templates https://raw.githubusercontent.com/score-spec/community-patchers/refs/heads/main/score-k8s/unprivileged.tpl
5168
```
5269

53-
And then the `generate` command will use it for the generated `manifests.yaml` file:
70+
Run the `generate` command:
5471

5572
```bash
5673
score-k8s generate score.yaml
5774
```
5875

76+
And then see that this patch template was applied on the final generated `manifests.yaml` file.
77+
78+
## Write your own patch template
79+
5980
A list of patch templates shared by the community can be found [here](https://github.com/score-spec/community-patchers). Users are encouraged to use them and contribute to this growing list of patch templates.

0 commit comments

Comments
 (0)