Managing users
In this tutorial, you will learn how to use Nickel to manage a list of users and to export it as a YAML file.
Step 1: Install nickel
The first step is to make Nickel available on your system. Please refer to the different installation methods documented in Getting started.
Step 2: Think about the schema
The YAML we want to produce has different fields with different types (lists, booleans and strings). Here is a sample of what we would like:
users:
- name: Aisha
is-admin: true
ssh-keys:
- AAAAApqCA8oKAB5S/47f...... aisha@work
- name: Violet
extra-groups:
- accountingWe can spot fields such as name, ssh-keys, is-admin or
extra-groups. To create a Nickel contract that correctly specifies
the shape of this data, we need to think about the type needed for
each field.
For example, the field name is a string, which translates to String in
Nickel. Meanwhile, ssh-keys must allow multiple keys, so this is a list of
strings, written as Array String. The field is-admin is a boolean, written
as Bool. Finally, extra-groups is a list of group names: we'll use Array
String here as well.
We can also mark fields as optional so we won't have to necessarily provide a
value. In our working example, extra-groups and ssh-keys can be empty, so we
will mark them as optional using the optional keyword.
The field is-admin must always be present in the YAML file, but for most of
our users it will be set to false. Fortunately, we can assign the default
value false to this field, which means we only need to write is-admin = true
when the user is actually an administrator.
Step 3: Write a contract
Create a text file named users-schema.ncl. We will write our contract
defining fields and associated constraints such as a type, marking
the field optional, and a default value if there is one.
Please note that using a contract isn't mandatory per-se to use Nickel, but it will allow you to validate your configuration (See Step 6 for an example), provide in-code information thanks to the LSP, and to document your code at the same time.
{
UserSchema = {
name
| String,
ssh-keys
| Array String
| optional,
is-admin
| Bool
| default
= false,
extra-groups
| Array String
| optional,
},
}Step 4: Write users
Now, create a text file named users.ncl that will import our contract
file created previously. This file will contain the actual data we need
to use.
let { UserSchema, .. } = import "users-schema.ncl" in
{
users | Array UserSchema
= [
{
name = "Alice",
is-admin = true,
extra-groups = ["support"],
ssh-keys = [
"AAAAAe4QAAAAAB5OLAo1...... alice@nixos",
"AAAAA26vx+AqGIPZd/NT...... alice@android",
],
},
{
name = "Bob",
extra-groups = ["pentester"],
},
{
name = "Mallory"
},
{
name = "Grace",
is-admin = true,
extra-groups = ["administrative"],
},
]
}Step 5: Export as YAML
By default, nickel exports data as JSON. But we can change that using
the extra parameter --format yaml to export as YAML.
nickel export --format yaml users.nclgives this result:
---
users:
- extra-groups:
- support
is-admin: true
name: Alice
ssh-keys:
- AAAAAe4QAAAAAB5OLAo1...... alice@nixos
- AAAAA26vx+AqGIPZd/NT...... alice@android
- extra-groups:
- pentester
name: Bob
- name: Mallory
- extra-groups:
- administrative
is-admin: true
name: GraceStep 6: Try to make a mistake
In this extra step, we will make a mistake on purpose in the file
users.ncl and try to export the data as YAML. We will see what happens
when Nickel detects that a value doesn't satisfy a contract.
Edit the file users.ncl and delete the line name = "Alice",. Now
export the file again using nickel export --format yaml users.ncl.
You should see the following error:
$ nickel export --format yaml users.ncl
error: missing definition for `name`
┌─ users-schemas.ncl:4:5
│
4 │ name
│ ^^^^ defined here
│
┌─ users.ncl:4:5
│
4 │ ╭ {
5 │ │ is-admin = true,
6 │ │ extra-groups = ["support"],
7 │ │ ssh-keys = [
· │
10 │ │ ],
11 │ │ },
│ ╰─────^ in this recordThe first part tells us where name was defined as being a requirement. This
points to the definition of name inside UserSchema. As there is no optional
keyword, this field must be set in the final configuration.
The second part tells us that in the first record in the users list, the field
name has no value while it should have one. This is to be expected as we
removed it earlier.
From Nickel 1.5 and higher, if you are using the Nickel Language Server, you should even see this contract violation being reported in your editor as you type.