Merge branch 'master' into dev-scott

This commit is contained in:
J. Scott Smith
2023-11-06 18:18:15 -08:00
17 changed files with 245 additions and 33 deletions

View File

@@ -109,6 +109,7 @@ export default defineConfig({
integrations: [
starlight({
title: 'grlx Docs',
lastUpdated: true,
description:
'Documentation for grlx. Fleet configuration management that is low overhead, dependency free, and easy to install.',
components: {
@@ -129,16 +130,21 @@ export default defineConfig({
github: 'https://github.com/gogrlx/grlx',
'x.com': 'https://x.com/gogrlx',
discord: 'https://discord.gg/RNsZ3KWjXm',
email: 'mailto:grlx@adatomic.com?subject=Question'
},
sidebar: [
{ label: 'Getting Started', link: '/getting-started' },
{
label: 'Architecture',
autogenerate: { directory: 'architecture' },
},
{
label: 'Ingredients',
autogenerate: { directory: 'ingredients' },
},
{
label: 'Architecture',
autogenerate: { directory: 'architecture' },
label: 'Recipes',
autogenerate: { directory: 'recipes' },
},
],
}),

13
cspell.json Normal file
View File

@@ -0,0 +1,13 @@
{
"version": "0.2",
"language": "en",
"words": [
"grlx",
"FARMERINTERFACE",
"FARMERORGANIZATION",
"NATS",
"FARMERBUSPORT",
"FARMERAPIPORT",
"PUBKEYS",
],
}

View File

@@ -23,7 +23,7 @@
# Equivalent to inputs'.nixpkgs.legacyPackages.hello;
devShells.default = pkgs.mkShell {
nativeBuildInputs = with pkgs; [ nodejs_18 nodePackages_latest.prettier];
nativeBuildInputs = with pkgs; [ nodejs_18 nodePackages_latest.prettier nodePackages_latest.cspell ];
};
};
flake = {

View File

@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:7c0be79de7cde17b03b1e46ef75edb2baebebd32b0605bad3fcb3a2babe924e6
size 68258

View File

@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:852c13313142bfb83fefad5bbabd64f5e9f9eba95ef7bf180553dbe140ba2f24
size 66244

View File

@@ -0,0 +1,16 @@
---
import { Image } from 'astro:assets'
import darkArch from "../assets/grlx-arch-dark.webp"
import lightArch from '../assets/grlx-arch-light.webp'
---
<Image
class="dark:hidden"
src={lightArch}
alt="ADAtomic logo"
/>
<Image
class="hidden dark:inline"
src={darkArch}
alt="ADAtomic logo dark arch"
/>

View File

@@ -1,19 +0,0 @@
---
title: Overview
description: A brief description of the grlx architecture
---
At a high level our architecture looks like the following:
We can boil down the `grlx` into three different parts: the farmer, the sprout, and the CLI.
## Farmer
The farmer is your control server. This has analogs in other similar configuration platforms. In SaltStack, this is your Salt Master, or in Chef, your Chef Server. `grlx` utilizes the farmer for things like authentication, job processing, and [ingredients](/architecture/overview#ingredients).
## Sprout
The sprout is what the farmer manages. This is similar to a Salt Minion in SaltStack or a Chef Client in Chef. Jobs are received from the farmer over the NATS message bus for actions to be performed on the sprout itself.
## CLI
## Ingredients

View File

@@ -0,0 +1,23 @@
---
title: Overview
description: A brief description of the grlx architecture
---
import ArchitectureImage from '../../../components/ArchitectureImage.astro'
At a high level the grlx architecture looks like the following:
<ArchitectureImage />
We can boil down the `grlx` into three different parts: the farmer, the sprout, and the CLI.
## Farmer
The farmer is your management server running the `grlx-farmer` binary. The binary can run as a systemd service or be hosted in a container. This has analogs in other similar configuration platforms such as a Salt Master in SaltStack or a Chef Server in Chef. grlx utilizes the farmer for things like authentication, job processing, and [ingredients](/architecture/overview#ingredients). Additionally, the farmer contains is responsible for holding your [recipes](/architecture/overview#recipes).
## Sprout
The sprout is a managed node running the `grlx-sprout` binary. Sprouts receive commands from the farmer over the NATS message bus. These can be immediate shell commands, or actions that are performed by Ingredients defined in a recipe (e.g. ensure that a file exists, a service is started). Sprouts are similar to a Salt Minion in SaltStack or a Chef Client in Chef. Jobs are received from the farmer over the NATS message bus. Sprouts will then execute the job and report back to the farmer the results of the job.
## CLI
The CLI is a tool used to interact with the farmer and manage sprouts. The CLI is used to accept keys from sprouts and `cook` (run) recipes that are hosted on the farmer. The CLI also contains tools to tail the traffic over the NAT bus, test sprout connections, and run arbitrary commands on sprouts.
## Recipes
Recipes are the core of grlx and are responsible for handling the configuration of your sprouts. Recipes are written with the `.grlx` extension and are a combination of YAML and Go templates. Recipes are stored on the farmer and are executed by the sprouts. Recipes are responsible for defining the [ingredients](/architecture/overview#ingredients) and in what order they are executed. For more information see the [recipes](/recipes) section.

View File

@@ -240,4 +240,7 @@ grlx -T \* cmd run --out json -- uname -a
#### Uninstalling
If you ever need to uninstall `grlx`
If you ever need to uninstall the `grlx-farmer`, you can do so with the following commands:
```bash
curl -L https://bootstrap.grlx.dev/latest/farmer | UNINSTALL=true sudo bash
```

View File

@@ -10,9 +10,19 @@ Runs shell commands against a sprout
|-----------|------|----------|-------------|
| _name_ | string | true | the command to run
| _runas_ | string | false | user who will run this command
| _path_ | string | false | the path to the binary, this is prepended to the name
| _cwd_ | string | false | the directory to run this command
| _env_ | list | false | environmental variables to set like the following: key1=value1
| _timeout_ | string | false | set a timeout for the command using [Go Duration](https://pkg.go.dev/time#ParseDuration)
```yaml
cmd.run:
- name: go version
- runas: super-cool-user
- path: /usr/local/bin
- cwd: /tmp
- env:
- GOOS=linux
- GOARCH=arm64
- timeout: 10s
```

View File

@@ -12,7 +12,7 @@ type FileProvider interface {
Verify(context.Context) (bool, error)
}
```
By default, `grlx` has three built-in providers: local, HTTP, and S3.
By default, `grlx` has two built-in providers: local and HTTP.
## Local
The local provider would be how you would use a file from your host system.
@@ -31,6 +31,3 @@ file.cached:
- source: https://go.dev/dl/go1.21.3.src.tar.gz
- hash: sha256=186f2b6f8c8b704e696821b09ab2041a5c1ee13dcbc3156a13adcf75931ee488
```
## TODO: S3
The S3 allows you to get a file from an S3 compatible bucket.

View File

@@ -12,7 +12,7 @@ Deletes a file or directory
#### Example
```yaml
file.absent:
name: ~/.config/sytemd/user/backup.service
name: ~/.config/systemd/user/backup.service
```
## **file.append**
@@ -61,7 +61,7 @@ Copies content into a given file
#### Example
```yaml
file.content:
- name: /srv/ngnix/nginx.conf
- name: /srv/nginx/nginx.conf
- makdirs: true
- text: |
server {
@@ -106,7 +106,7 @@ file.directory:
- makdirs: false
- user: grlx
- group: grlx
- dir_moode: 755
- dir_mode: 755
- recurse: false
```
@@ -147,3 +147,20 @@ file.symlink:
- name: ~/localbash
- target: /usr/bin/bash
```
## **file.touch**
Performs a `touch` on a file
| parameter | type | required | description |
|-----------|------|----------|-------------|
| _name_ | string | yes | the name/path of the file
| _atime_ | time (RFC339) | no | the access time to set the file to, set to the current time by default
| _mtime_ | time (RFC339) | no | the modified time to set the file to, sets to the current time by default
| _makedirs_ | bool | yes | whether or not to create any provided parent directories, false by default
```yaml
file.touch:
- name: /tmp/parent/new-file
- atime: Mon, 06 Nov 2023 00:00:00 +0000
- mtime: Mon, 06 Nov 2023 00:00:00 +0000
- makedirs: true
```

View File

@@ -0,0 +1,39 @@
---
title: grlx.ingredients.group
desc: An overview of grlx.ingredients.group
---
The group ingredient handles group operations on sprouts.
## **group.absent**
Removes a group
#### Parameters
| parameter | type | required | description |
|-----------|------|----------|-------------|
| _name_ | string | no | The name of the group to remove
```yaml
group.absent:
- name: sprout-group
```
## **group.exists**
Validates if a group exists
#### Parameters
| parameter | type | required | description |
|-----------|------|----------|-------------|
| _name_ | string | yes | The group name to check
```yaml
group.exists:
- name: sprout-group
```
## **group.present**
Creates a group if it does not exist
#### Parameters
| parameter | type | required | description |
|-----------|------|----------|-------------|
| _name_ | string | yes | The name of the group to create
| _gid_ | int | no | The GID of the group to create
```yaml
group.present:
- name: sprout-group
- gid: 1000
```

View File

@@ -2,7 +2,7 @@
title: grlx.ingredients.service.providers
description: grlx built-in service providers
---
grlx has a concept of service providers for different ways to interact with a sprout's various services. This uses a provider interface to keep this extensible and provide a standard way to interact with different service managers. The `go` interface for Service Providers looks like the following:
grlx has a concept of service providers for different ways to interact with a sprout's various services. This uses a provider interface to keep this extensible and provide a standard way to interact with different service managers. The Go interface for Service Providers looks like the following:
```go
type ServiceProvider interface {
Properties() (map[string]interface{}, error)
@@ -30,7 +30,7 @@ type ServiceProvider interface {
By default, grlx only has a `systemd` provider.
## systemd
The local provider would be how you would use a file from your host system.
The [`systemd` provider](/ingredients/service) allows for control over a sprout's `systemd` services.
#### Example
```yaml
service.disabled:

View File

@@ -0,0 +1,51 @@
---
title: grlx.ingredients.user
desc: An overview of grlx.ingredients.user
---
The user ingredient handles user operations on sprouts.
## **user.absent**
Removes a user if it exists
#### Parameters
| parameter | type | required | description |
|-----------|------|----------|-------------|
| _name_ | string | yes | the name of the user to be removed
```yaml
user.absent:
- name: super-sprout
```
## **user.exists**
Validates if a user exists
#### Parameters
| parameter | type | required | description |
|-----------|------|----------|-------------|
| _name_ | string | yes | The username to check
```yaml
user.exists:
- name: sprout-user
```
## **user.present**
Creates a new user if it does not exist
#### Parameters
| parameter | type | required | description |
|-----------|------|----------|-------------|
| _name_ | string | yes | The username of the user
| _uid_ | int | no | The UID assigned to the user
| _gid_ | int | no | The GID to the user
| _groups_ | list, string | no | A list groups the user is part of
| _shell_ | bool | no | The user login shell, false by default
| _home_ | string | no | The path to the user's home directory if one is required
```yaml
user.present:
- name: sprout-user
- uid: 1000
- gid: 1000
- groups:
- wheel
- media
- sudo
- shell: no
- home: /var/sprout-user
```

View File

@@ -0,0 +1,46 @@
---
title: Overview
description: An overview of grlx recipes
---
Recipes are the core of grlx functionality, providing a structured way for developers to deploy actions to sprouts. Recipes are a collection of ingredients which can be executed against a sprout. Recipes must be placed on the farmer at `/srv/grlx/recipes/prod` (with support for other non-prod environments in the future). Furthermore, recipes can utilize [Go's builtin templating engine](https://pkg.go.dev/text/template) to provide dynamic functionality for deployment. Below is a simple example of the makeup of a recipe.
```yaml
include:
- .super-sprout-steps
steps:
{{ if props hostname super-sprout }}
install super-sprout:
file.touch:
- name: ~/super-sprout-config
requisites:
- require: super-sprout-steps-completed
{{ else }}
install normal-sprout:
file.touch:
- name: ~/normal-sprout-config
{{ end }}
```
In this example, an include is created for a `super-sprout-steps.grlx` file. This file would contain a list of steps with a final step `grlx-sprout-steps-completed`. Next we have our list of steps, bounded by Go templates. This template checks the hostname of the sprout and renders the steps to send to the farmer. In this case, if the sprout's hostname is `super-sprout`, then it will render a template that looks like this:
```yaml
include:
- .super-sprout-steps
steps:
install super-sprout:
file.touch:
- name: ~/super-sprout-config
requisites:
- require: super-sprout-steps-completed
```
If the hostname is anything else, the sprout will run:
```yaml
include:
- .super-sprout-steps
steps:
install normal-sprout:
file.touch:
- name: ~/normal-sprout-config
```
It is important to note the requisites listed. This ensures that the step from the include (`super-sprout-steps-completed`) occurs _before_ the `install-super-sprout` step is run.
:::note
Deployment of recipe steps is non-deterministic unless requisites are provided. Otherwise, are steps run as is. If order is important, than order ***must*** be specified.
:::

View File

@@ -1,5 +1,9 @@
.discord-bg .card .icon{
background-color: #7289da;
background-color: #5865F2;
--sl-card-border: #454FBF !important;
}
[data-theme="light"] .hidden{
display: none;
}