Enterprise and Community Users can Write Sketches

Overview

This page describes how to create a Design Center sketch from a basic CFEngine agent bundle. In effect the sketch is a wrapper, taking parameters from the Design Center API or the CFEngine Enterprise Mission Portal, and passing them down to the agent bundle.

The Bundle

The bundle we will wrap with a sketch is a simple use of the users promise type:

```cf3 bundle agent ensure_users(users, group, homedir, shell) { users: “$(users)” -> {“PCI-DSS-2”, “Baseline_developers23”} policy => “present”, home_dir => “$(homedir)/$(users)”, group_primary => $(group), shell => $(shell), handle => “ensure_user_setup”, home_bundle => setup_home_dir($(users), $(homedir)); }

bundle agent setup_home_dir(user, group, homedir) { files: “$(homedir)/$(user)/.” create => “true”; } ```

If you don’t understand what it does, please look at [Tutorials][Tutorials] and the CFEngine [Guide][] to learn more about CFEngine’s policy language, syntax, and operation. We will not worry about the internals except to apply namespaces and testing guards.

The sketch.json Metadata

The first step is to define the sketch metadata. This is the annoying administrivia that makes a package system such as Design Center useful. Simply take an existing sketch.json file such as the one below and modify it:

``` { manifest: { “main.cf”: { description: “main file” }, “README.md”: { documentation: true }, },

metadata:
{
    name: "System::Users",
    description: "Configure users with parameters",
    version: "1.00",
    license: "MIT",
    tags: [ "cfdc", "users", "enterprise_compatible", "enterprise_3_6" ],
    authors: [ "Ted Zlatanov <tzz@lifelogs.com>" ],
    depends: { "CFEngine::sketch_template": {}, cfengine: { version: "3.6.0" }, os: [{ "linux": "Linux", "solaris": "Solaris", "aix": "AIX", "windows": "Windows" }] }
},

api:
{
    // this is the name of the bundle!
    ensure_users:
    [
        { type: "bundle_options", name: "Ensure the users exist as specified" },
        { type: "environment", name: "runenv", },
        { type: "metadata", name: "mymetadata", },
        { type: "list", name: "users", validation: "LIST_OF_STRING_NONEMPTY", description: "User names to add (separate by commas)" },
        { type: "string", name: "group", validation: "STRING_NONEMPTY", description: "Primary user group" },
        { type: "string", name: "homedir", default: "/home", validation: "PATH_ABSOLUTE_UNIX_OR_WINDOWS", description: "Location of the user's home directory" },
        { type: "string", name: "shell", default: "/bin/bash", choice: [ "/bin/sh", "/bin/bash", "/bin/csh", "/bin/tcsh", "/bin/zsh" ], description: "User shell" },
    ],
},

namespace: "cfdc_users",

interface: [ "main.cf" ], } ```

main.cf: The Converted Bundle

Now main.cf will start with the original bundle, but we’ll modify it.

```cf3 body file control { namespace => “cfdc_users”; }

bundle agent ensure_users(runenv, metadata, users, group, homedir, shell) { #@include “REPO/sketch_template/standard.inc” users: !dc_test:: “$(users)” -> {“PCI-DSS-2”, “Baseline_developers23”} policy => “present”, home_dir => “$(homedir)/$(users)”, group_primary => $(group), shell => $(shell), handle => “ensure_user_setup”, home_bundle => setup_home_dir($(users), $(homedir));

reports: dc_verbose.dc_test:: “$(dcbundle): simulating user = $(users) with group $(group), home dir $(homedir) and shell $(shell)”; dc_verbose.!dc_test:: “$(dcbundle): ensuring user = $(users) with group $(group), home dir $(homedir) and shell $(shell)”; }

bundle agent setup_home_dir(user, group, homedir) { files: “$(homedir)/$(user)/.” create => “true”; } ```

Package The Sketch

This part is really too easy. We should make it harder so you have something to complain about!

There are two steps:

cp -rp /var/cfengine/share/*Base/sketches/sketch_template /my/repo/sketches/ /var/cfengine/design-center/bin/cf-sketch --make_cfsketches --inputs /my/repo --is=/my/repo/sketches/cfsketches.json /var/cfengine/design-center/bin/cf-sketch --make_readme --is=/my/repo/sketches/cfsketches.json /var/cfengine/design-center/bin/cf-sketch --install-all --is=/my/repo/sketches/cfsketches.json --inputs=/var/cfengine/design-center

See [Maintaining your own sketch repository][Maintaining your own sketch repository] for these exact commands to run, with a longer explanation for each one.

You’re Done!

That’s all there is to writing a sketch. You should now look at [sketchify - Write A New Sketch From An Existing Bundle][sketchify - Write A New Sketch From An Existing Bundle] for a guide to using the sketchify tool. See [Maintaining your own sketch repository][Maintaining your own sketch repository] to find out how to create your own sketch repository and install sketches from it.

Your users can then use the sketch you’ve written as described in [Deploy your first Policy][Deploy your first Policy].