This is the multi-page printable view of this section. Click here to print.

Return to the regular view of this page.

Documentation

Kuesta is a cloud-native network configuration framework, enabling operators Infrastructure-as-Code of network equipments. It consists of CUE-based data mapper and some Kubernetes custom operators for GitOps, and provides us a rich network abstraction and automation.

1 - Getting Started

Get started with Kuesta.

This tutorial shows you how to

  1. Create a local Kubernetes cluster.
  2. Install Kuesta.
  3. Run device emulator.
  4. Create new service and configure the device emulators by GitOps.

Prerequisites

  1. Install golang (v1.20.4+) to use controller-tools.
  2. Install docker (v20.10.24+) to use cluster in kind.
  3. Install kind (v0.12.0+) to set up local Kubernetes cluster.
  4. Install kubectl (v1.25.4+) to run commands against Kubernetes clusters.
  5. Install cue (v0.4.x) to run Kuesta installation script.
  6. Install gnmic (v0.26.0+) to perform gNMI request to kuesta server.

Create a local Kubernetes cluster

Create a local Kubernetes cluster with kind.

kind create cluster

You can check that the cluster was successfully created by running:

kubectl cluster-info

Then you will see an output similar to the following that confirms your local cluster is running:

Kubernetes control plane is running at https://127.0.0.1:52096
CoreDNS is running at https://127.0.0.1:52096/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy

To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.

Set up GitHub source repositories for testing

To configure network devices using Kuesta’s GitOps, you need to set up 2 GitHub repositories. One is for the configuration source repository, and the other is for the update history of network devices’ actual configuration status. You can easily set up these repositories using Kuesta Example repository as a template. Repository must consist of lower case alphanumeric characters, ‘-’ or ‘.’, and must start and end with an alphanumeric character.

Run the following 2 times to create the repository pair:

  1. Click Use this template button of Kuesta Example repository.

  2. Select a name for your new repository and click Create repository from template. You can choose either public or private whichever you prefer.

Install Kuesta and sample resources

To install Kuesta and sample resources like device drivers and emulators, just run cue script:

git clone https://github.com/nttcom/kuesta.git
cd kuesta/tool/install
cue install

Provide required parameters according to the instructions: The GitHub repository for config GitHub repository for status should specify each of the two Github repositories for verification that you have created.

GitHub repository for config: https://github.com/<your_org>/<your_config_repo>
GitHub repository for status: https://github.com/<your_org>/<your_status_repo>
GitHub username: <your_username>
GitHub private access token: <your_private_access_token>
Are these git repositories private? (yes|no): yes
Do you need sample driver and emulator for trial?: (yes|no) yes

---
GitHub Config Repository: https://github.com/<your_org>/<your_config_repo>
GitHub Status Repository: https://github.com/<your_org>/<your_status_repo>
GitHub Username: <your_username>
GitHub Access Token: ***
Use Private Repo: true

Image Registry: ghcr.io/nttcom/kuesta
Version: latest
Deploy sample driver and emulator: true
---

Continue? (yes|no) yes

For Kuesta to perform git-push and create pull-request, you need to prepare a GitHub personal access token (PAT) and provide it in the installation(classic is recommended). Since PAT provided here is stored only in Secret resources on your local Kubernetes cluster, you can remove them safely and completely by cleaning up your local cluster.

After running an installation script, you can see what is installed by running kubectl commands:

1: Custom Resource Definitions(CRDs):

kubectl get customresourcedefinitions.apiextensions.k8s.io
NAME                                        CREATED AT
buckets.source.toolkit.fluxcd.io            2023-01-10T06:31:20Z
certificaterequests.cert-manager.io         2023-01-10T06:31:19Z
certificates.cert-manager.io                2023-01-10T06:31:19Z
challenges.acme.cert-manager.io             2023-01-10T06:31:19Z
clusterissuers.cert-manager.io              2023-01-10T06:31:19Z
devicerollouts.kuesta.hrk091.dev            2023-01-10T06:43:30Z
gitrepositories.source.toolkit.fluxcd.io    2023-01-10T06:31:20Z
helmcharts.source.toolkit.fluxcd.io         2023-01-10T06:31:20Z
helmrepositories.source.toolkit.fluxcd.io   2023-01-10T06:31:20Z
issuers.cert-manager.io                     2023-01-10T06:31:19Z
ocdemoes.kuesta.hrk091.dev                  2023-01-10T06:43:36Z
ocirepositories.source.toolkit.fluxcd.io    2023-01-10T06:31:20Z
orders.acme.cert-manager.io                 2023-01-10T06:31:19Z

Some CRDs belonging to kuesta.hrk091.dev, source.toolkit.fluxcd.io, cert-manager.io are installed.

2: Pods:

kubectl get pods -A | grep -v 'kube-system'
NAMESPACE                NAME                                                  READY   STATUS    RESTARTS   AGE
cert-manager             cert-manager-7475574-t7qlm                            1/1     Running   0          12m
cert-manager             cert-manager-cainjector-d5dc6cd7f-wbh6r               1/1     Running   0          12m
cert-manager             cert-manager-webhook-6868bd8b7-kc85s                  1/1     Running   0          12m
device-operator-system   device-operator-controller-manager-5d8648469b-57x4l   2/2     Running   0          11s
flux-system              source-controller-7ff779586b-wsgf7                    1/1     Running   0          12m
kuesta-getting-started   gnmi-fake-oc01-79d4d679b4-tvm78                       1/1     Running   0          10s
kuesta-getting-started   gnmi-fake-oc02-69d9cc664d-56bsz                       1/1     Running   0          10s
kuesta-getting-started   subscriber-oc01                                       1/1     Running   0          9s
kuesta-getting-started   subscriber-oc02                                       1/1     Running   0          9s
kuesta-system            kuesta-aggregator-7586999c47-jj7m4                    1/1     Running   0          27s
kuesta-system            kuesta-server-85fc4f8646-kq72c                        1/1     Running   0          27s
local-path-storage       local-path-provisioner-9cd9bd544-lk9w9                1/1     Running   0          16m
provisioner-system       provisioner-controller-manager-7675d487c8-w6f7x       1/2     Running   0          17s

When all pods show Running status, you are ready to continue.

Kuesta core services are deployed in the following namespaces:

  • kuesta-system
    • Kuesta Server which provides core features and serves API.
  • provisioner-system
    • Kubernetes custom operator used for GitOps and multi-device transaction management.
  • flux-system
    • Flux source-controller and Custom Resources to integrate with manifest sources.
  • cert-manager
    • Act as a private CA and issue certificates for mTLS.

The resources for this getting-started are deployed as well in the following namespaces:

  • device-operator-system
    • Kubernetes custom operator as a device driver to configure device emulator.
  • kuesta-getting-started
    • Device emulators for this getting started, and Kubernetes custom resources to trigger device configuration.

Following 2 pods are device emulators which can be configured by OpenConfig over gNMI, named oc01 and oc02.

kuesta-getting-started   gnmi-fake-oc01-79d4d679b4-tvm78                       1/1     Running   0          10s
kuesta-getting-started   gnmi-fake-oc02-69d9cc664d-56bsz                       1/1     Running   0          10s

If you want to check what configurations are stored in these emulators, you can easily do it by port-forwarding and requesting to these emulator pods as follows:

# Get oc01 emulator's configuration
kubectl -n kuesta-getting-started port-forward svc/gnmi-fake-oc01 9339:9339
gnmic -a :9339 -u admin -p admin get --path "" --encoding JSON --skip-verify

Request Service configuration and run GitOps

A Service is a abstracted high-level model of the network configuration, and you can configure multiple devices by creating/updating Services.

In the sample repository there is a sample Service named oc-circuit, you can try it as a demonstration. Service is written by CUE. For example, oc-circuit service is as follows:

package oc_circuit

import (
	ocdemo "github.com/hrk091/kuesta-testdata/pkg/ocdemo"
)

#Input: {
	// kuesta:"key=1"
	vlanID: uint32
	endpoints: [...{
		device: string
		port:   uint32
	}]
}

#Template: {
	input: #Input

	output: devices: {
		for _, ep in input.endpoints {
			"\(ep.device)": config: {
				ocdemo.#Device

				let _portName = "Ethernet\(ep.port)"
				Interface: "\(_portName)": SubInterface: "\(input.vlanID)": {
					Ifindex:     ep.port
					Index:       input.vlanID
					Name:        "\(_portName).\(input.vlanID)"
					AdminStatus: 1
					OperStatus:  1
				}

				Vlan: "\(input.vlanID)": {
					VlanId: input.vlanID
					Name:   "VLAN\(input.vlanID)"
					Status: ocdemo.#Vlan_Status_ACTIVE
					Tpid:   ocdemo.#OpenconfigVlanTypes_TPID_TYPES_UNSET
				}
			}
		}
	}
}

The oc-circuit Service will conduct mapping from #Template.input (Service config) to the #Template.output (multiple network device configs) as defined in #Template, then it will generate simple vlan and vlan sub-interface configurations. To use oc-circuit Service, you need to provide vlanID and multiple device ports according to the #Input type definition.

You can create the oc-circuit Service by the following steps:

1: Create a request json file named oc-circuit-vlan100.json with the following content:

{
    "vlanID": 100,
    "endpoints": [
        {
            "device": "oc01",
            "port": 1
        },
        {
            "device": "oc02",
            "port": 1
        }
    ]
}

When using the http interface, please create the following JSON instead of the above JSON. (Specify the path of the service in “path” and the value of the service to be submitted in “value.)

{
    "path": "/services/oc_circuit/100",
    "value": {
        "vlanID": 100,
        "endpoints": [
            {
                "device": "oc01",
                "port": 1
            },
            {
                "device": "oc02",
                "port": 1
            }
        ]
    }
}

This sample Service requests both oc01 and oc02 device emulators to create a VLAN sub-interface with vlanID=100 on port 1.

2: Port-forward to the kuesta-server Pod running on your local Kubernetes.

kubectl -n kuesta-system port-forward svc/kuesta-server 9339:9339

If the http interface is used, the following is the case.

kubectl -n kuesta-system port-forward svc/kuesta-server 8080:8080

3: Send gNMI set request to kuesta-server using gnmic.

gnmic -a :9339 -u dummy -p dummy set --replace-path "/services/service[kind=oc_circuit][vlanID=100]" --encoding JSON --insecure --replace-file oc-circuit-vlan100.json

If you use the http interface, send the following POST Request to the Questa server using curl.

curl -X POST -H "Content-Type: application/json" -d @oc-circuit-vlan100.json http://localhost:8080/set

4: Check the PullRequest(PR) in your configuration repository on GitHub web console. Access PR list then you will find the PR which titles as [kuesta] Automated PR. You can see what services and devices are configured by this PR on the PR comment, and their details from the Files changed tab.

5: Before merging PR branch, it is better to monitor DeviceRollout resource, which conducts a device configuration rollout. Run monitor with kubectl:

kubectl -n kuesta-getting-started get devicerollouts.kuesta.hrk091.dev -w

If you see there is one DeviceRollout resource and its STATUS is Completed, you are ready to run GitOps delivery procedure.

NAME              PHASE     STATUS
kuesta-testdata   Healthy   Completed

6: Merge the PR on GitHub web console, and go to the terminal where DeviceRollout monitor running. In one minute, you will see DeviceRollout status changes to Running, then changes back to Completed again.

NAME              PHASE     STATUS
kuesta-testdata   Healthy   Completed
kuesta-testdata   Healthy   Completed
kuesta-testdata   Healthy   Running
kuesta-testdata   Healthy   Running
kuesta-testdata   Healthy   Running
kuesta-testdata   Healthy   Completed

7: Check the updated device configuration. Get entire device config by sending gNMI get request to kuesta-server with gnmic:

gnmic -a :9339 -u admin -p admin get --path "/devices/device[name=oc01]" --path "/devices/device[name=oc02]" --encoding JSON --insecure

If you use the http interface, send the following POST Request to the Questa server using curl.

curl -X POST -H "Content-Type: application/json" -d '{"paths": ["/devices/oc01", "/devices/oc02"]}'  http://localhost:8080/get

The output displays the gNMI response payload like:

[
  {
    "source": ":9339",
    "timestamp": 1673360105000000000,
    "time": "2023-01-10T23:15:05+09:00",
    "updates": [
      {
        "Path": "devices/device[name=oc01]",
        "values": {
          "devices/device": {
            "Interface": {
              "Ethernet1": {
                "AdminStatus": 1,
                "Description": "awesome interface!!",
                "Enabled": false,
                "Mtu": 9000,
                "Name": "Ethernet1",
                "OperStatus": 1,
                "Subinterface": {
                  "100": {
                    "AdminStatus": 1,
                    "Ifindex": 1,
                    "Index": 100,
                    "Name": "Ethernet1.100",
                    "OperStatus": 1
                  },
                  ...
                },
                ...
              },
              ...
            },
            "Vlan": {
              "100": {
                "Member": [],
                "Name": "VLAN100",
                "Status": 1,
                "Tpid": 0,
                "VlanId": 100
              },
              ...

The response when using the http interface is as follows.

[
    {
        "Interface": {
            "Ethernet1": {
                "AdminStatus": 1,
                "Description": "",
                "Enabled": false,
                "Mtu": 9000,
                "Name": "Ethernet1",
                "OperStatus": 1,
                "SubInterface": {
                    "100": {
                        "AdminStatus": 1,
                        "Ifindex": 1,
                        "Index": 100,
                        "Name": "Ethernet1.100",
                        "OperStatus": 1
                    }
                },
                "Subinterface": {},
                "Type": 80
            },
            "Ethernet2": {
                "AdminStatus": 1,
                "Description": "",
                "Enabled": false,
                "Mtu": 9000,
                "Name": "Ethernet2",
                "OperStatus": 1,
                "Subinterface": {},
                "Type": 80
            },
            "Ethernet3": {
                "AdminStatus": 1,
                "Description": "",
                "Enabled": false,
                "Mtu": 9000,
                "Name": "Ethernet3",
                "OperStatus": 1,
                "Subinterface": {},
                "Type": 80
            }
        },
        "Vlan": {
            "100": {
                "Member": [],
                "Name": "VLAN100",
                "Status": 1,
                "Tpid": 0,
                "VlanId": 100
            }
        }
    },
    {
        "Interface": {
            "Ethernet1": {
                "AdminStatus": 1,
                "Description": "",
                "Enabled": false,
                "Mtu": 9000,
                "Name": "Ethernet1",
                "OperStatus": 1,
                "SubInterface": {
                    "100": {
                        "AdminStatus": 1,
                        "Ifindex": 1,
                        "Index": 100,
                        "Name": "Ethernet1.100",
                        "OperStatus": 1
                    }
                },
                "Subinterface": {},
                "Type": 80
            },
            "Ethernet2": {
                "AdminStatus": 1,
                "Description": "",
                "Enabled": false,
                "Mtu": 9000,
                "Name": "Ethernet2",
                "OperStatus": 1,
                "Subinterface": {},
                "Type": 80
            },
            "Ethernet3": {
                "AdminStatus": 1,
                "Description": "",
                "Enabled": false,
                "Mtu": 9000,
                "Name": "Ethernet3",
                "OperStatus": 1,
                "Subinterface": {},
                "Type": 80
            }
        },
        "Vlan": {
            "100": {
                "Member": [],
                "Name": "VLAN100",
                "Status": 1,
                "Tpid": 0,
                "VlanId": 100
            }
        }
    }
]

You will find that vlan and vlan sub-interfaces of both devices oc01 and oc02 are configured correctly as implemented in the oc-circuit service model. In addition, these device config changes are committed and pushed to your status repository, you can find these device config updates from the main branch head.

Clean up

To delete the local cluster you created for this getting-started, just run:

kind delete cluster

Do not forget to remove your PAT to access your private repository if no longer needed.

2 - Installation

Instructions to install Kuesta components.

Information in this section helps you to install Kuesta to your Kubernetes cluster.

Before you begin

You must have a Kubernetes cluster running version 1.24 or later.

If you don’t have a cluster, you can create local one for testing with kind. Install kind and create a cluster by running kind create cluster. This will create a cluster running locally, with RBAC enabled and your user granted the cluster-admin role.

Prerequisites

  1. Install kubectl to run commands against Kubernetes clusters.
  2. Install cue to run Kuesta installation script.

Installing Kuesta on Kubernetes

To install Kuesta components, just run cue script:

git clone https://github.com/nttcom/kuesta.git
cd kuesta/tool/install
cue install

If you want to install a specific release version or install from the other container image registry, use version and imageRegistry tag:

cue -t imageRegistry=<your_image_registry> -t version=<your_version> install

Provide required parameters according to the instructions:

GitHub repository for config: https://github.com/<your_org>/<your_config_repo>
GitHub repository for status: https://github.com/<your_org>/<your_status_repo>
GitHub username: <your_username>
GitHub private access token: <your_private_access_token>
Are these git repositories private? (yes|no): yes
Do you need sample driver and emulator for trial?: (yes|no) yes

---
GitHub Config Repository: https://github.com/<your_org>/<your_config_repo>
GitHub Status Repository: https://github.com/<your_org>/<your_status_repo>
GitHub Username: <your_username>
GitHub Access Token: ***
Use Private Repo: true

Image Registry: ghcr.io/nttcom/kuesta
Version: latest
Deploy sample driver and emulator: true
---

Continue? (yes|no) yes

For Kuesta to perform git-push and create pull-request, you need to prepare a GitHub personal access token (PAT) and provide it in the installation. PAT provided here is stored in a Secret named kuesta-system/kuesta-secrets for kuesta-server to operator git clone, pull, push and create PullRequest.

You can also use this PAT when you set up GitRepository to watch your private repository via Git over HTTPS, to grant Flux source-controller to conduct git operations with your private repository.

Configuring GitOps with Flux source-controller

To set up GitOps using Flux source-controller, you need to create GitRepository to define the IaC manifest source. The following is the example of a GitRepository, that is created in the getting-started tutorial.

apiVersion: source.toolkit.fluxcd.io/v1beta2
kind: GitRepository
metadata:
  name: kuesta-testdata
  namespace: kuesta-getting-started
spec:
  interval: 1m0s
  url: https://github.com/hrk091/kuesta-testdata
  ref:
    branch: main
  secretRef:
    name: kuesta-testdata-secret
  timeout: 60s

You can get more detail from the FluxCD documentation.

In Kuesta, once you create the GitRepository, Kuesta’s source-watcher controller detects it and creates the corresponding DeviceRollout. DeviceRollout is a custom resource responsible for multi-device transaction management. The DeviceRollout created in the getting-started tutorial is as follows:

apiVersion: kuesta.hrk091.dev/v1alpha1
kind: DeviceRollout
metadata:
  name: kuesta-testdata
  namespace: kuesta-getting-started
spec:
  deviceConfigMap:
    oc01:
      checksum: 1524caf17ec4c133f6f275326a6c9742a0155007f8eaa28ea601ce7ac39c0566
      gitRevision: main/30746f9beb48d237b6c0e0357708b3ed1f95cd1b
    oc02:
      checksum: 0b03381195ba613e0dd20e5d2683711e9d6082f0634bee7c54014de2eadf0fc9
      gitRevision: main/30746f9beb48d237b6c0e0357708b3ed1f95cd1b
status:
  desiredDeviceConfigMap:
    oc01:
      checksum: 1524caf17ec4c133f6f275326a6c9742a0155007f8eaa28ea601ce7ac39c0566
      gitRevision: main/30746f9beb48d237b6c0e0357708b3ed1f95cd1b
    oc02:
      checksum: 0b03381195ba613e0dd20e5d2683711e9d6082f0634bee7c54014de2eadf0fc9
      gitRevision: main/30746f9beb48d237b6c0e0357708b3ed1f95cd1b
  deviceStatusMap:
    oc01: Completed
    oc02: Completed
  phase: Healthy
  status: Completed      

The lifecycle of DeviceRollout resource is completely automated, you don’t need to touch it at all.

Installing Device Driver and configuring Device Custom Resource

The following instructions are just for the sample Kubernetes Custom Operator that is used in the getting-started tutorial. The details will be different depending on the target devices you want to configure by Kuesta and your Kubernetes custom operator to configure them.

To configure the devices which supports OpenConfig over gNMI, you can use the sample Kubernetes custom operator developed at kuesta/device-operator. This sample Kubernetes custom operator is specialized to configure OpenConfig devices which support basic YANG sets, you can extend this custom operator by adding any YANG modules which is written in OpenConfig style.

You can install this sample Kubernetes custom operator either using make command or using kubectl/kustomize directly, but the fastest way is using the Kuesta installation script. It uses kustomize internally by creating kustomize overlay directory named getting-started, you can start with it to customize your setup.

To install the sample Kubernetes custom operator using getting-started overlay directory, run the following:

export IMG=ghcr.io/nttcom/kuesta/device-operator:latest
export KUSTOMIZE_ROOT=overlays/getting-started
make deploy

To configure devices from Kuesta, you also need to create custom resources for each device in addition to the Kubernetes custom operator. In the getting-started tutorial, following OcDemo custom resource is created for oc01 gNMI emulator.

apiVersion: kuesta.hrk091.dev/v1alpha1
kind: OcDemo
metadata:
  name: oc01
  namespace: kuesta-getting-started
spec:
  address: gnmi-fake-oc01.kuesta-getting-started
  port: 9339
  rolloutRef: kuesta-testdata
  tls:
    secretName: oc01-cert
    skipVerify: true

OcDemo defines a connection parameters to access the configuration target device, address, port, username/password, and TLS settings. .spec.rolloutRef is also a required field to specify DeviceRollout to subscribe to the device configuration changes given by Flux source-controller GitOps. For more information, run kubectl explain ocdemo.spec.

3 - Concepts

Learn more about the core concepts of Kuesta.

Network Configuration as Code with CUE

Kuesta supports creating an abstracted high-level configuration layer to expose easy high-level data model and API. The configuration data models of the network devices have lots of networking capabilities therefore are too much detailed and complicated, they are not suitable for the resource model of the Infrastructure as Code. To provide a data model which can represent the user intent easily, an abstracted high-level data model is required to hide the complicated actual device configurations. In addition, the high-level data model which effects multiple network device configs is needed for domain-wide abstraction such as E2E connectivity.

These high-level data model abstraction causes the additional complexity of the high-to-low data mapping logic. The relations between the high-level model and the low-level actual device configs are many-to-many, we need to consider performing data composition in addition to high-to-low data mapping without data loss, conflicts, and type constraint violation. A simple text-templating approach using Python/Jinja is not enough to solve this complex problem.

Kuesta uses CUE as a programming language of high-to-low data mapping logic. CUE is a configuration language specialized in data unification and validation, and is well-suited for the above usecase for the following reasons:

  • CUE enables us to unify multiple document-tree in the arbitrary layer. CUE is designed to ensure combining CUE values in any order always gives the same result (associative, commutative, and idempotent).
  • CUE merges types and values into a single concept. Even types and constraints are the kind of value, the only difference between them is that they do not have concrete value. Due to this novel approach, we can declare constraints and schema simply and efficiently in the configuration data itself.
  • CUE is highly programmable and supports software coding practices like templating and modularization. We can take the same advantages as if we use general-purpose language.

To learn more about CUE, see “cuelang.org”.

GitOps

Kuesta provides GitOps for network configuration. It aims to describe the entire network configuration declaratively and version controlled in a Git repository, as a Single Source of Truth(SSoT). The configuration process is totally automated so that the deployed network configuration matches the state specified in a repository. All you have to do to switch the network configuration or rollback is to change the Git branch HEAD to the revision you want to deploy.

Kuesta selects Pull-based approach for the following reasons:

  • To detect the configuration drift between the desired config in the configuration repository and the actual config stored in devices, whenever the device config is updated.
  • To ensure that the entire network configuration stored at the SSoT git repository is deployed to the devices with the prepared deploy pipeline, without inserting any configuration changes.
  • To avoid aggregating all device credentials and providing them to the single god-mode configuration system. Device credentials are stored as the Kubernetes Secret resource, and you can integrate with public clouds’ SecretManager to manage these credentials more securely using OSS tools like ExternalSecrets Operator.

For more information about GitOps, take a look at “What is GitOps?”.

Kubernetes Custom Operator

Kuesta uses the Kubernetes reconciliation loop and the operator pattern as an engine of Infrastructure as Code. Kubernetes is a well-known container orchestration tool, but it can be extended to automate deploying any external resources including network devices. Kuesta consists of multiple Kubernetes custom operators to perform GitOps, distributed transaction coordinator, and the driver to configure the network devices.

You can extend Kuesta to support new vendors’ devices or new versions by implementing Kubernetes custom operator for them as a device driver.

The components of Kuesta

Kuesta consists of the following components:

  • kuesta-server is the core api-server of Kuesta. It exposes gNMI to integrate with the external 3rd-party system, performs high-to-low data mapping and data composition, and creates new git-commit and PullRequest for GitOps.

  • kuesta-aggregator aggregates the actual device config changes and creates a new git-commit to persist the config change history.

  • FluxCD source-controller detects manifest changes of the specified Git repository at GitRepository Kubernetes custom resource.

  • kuesta-provisioner consists of the gitrepository-watcher controller and DeviceRollout Kubernetes custom resource. gitrepository-watcher watches GitRepository status to detect the manifest changes and updates DeviceRollout status to running when change is detected, which triggers the device config update transaction.

To configure network devices using Kuesta, you must prepare your own Kubernetes custom operator to configure your target devices. It is recommended to use kubebuilder which is the powerful framework to build your Kubernetes custom operator. You can also start from device-operator used at the “Getting started”, the sample Kubernetes custom operator designed to configure OpenConfig/gNMI device. It is built using kubebuilder.

4 - Guides

Guides to help you complete a specific goal.

Work in progress.

5 - CLI

Instructions of Command-Line Interface.

Kuesta supports IaC configuration update via both gNMI and kuesta CLI. kuesta CLI helps you when you would like to manage your configuration repository manually using kuesta, or integrate with CI like GitHub Actions or GitHub Apps.

Installation

Download kuesta CLI as a tarball from the kuesta Releases page. After downloading the tarball, extract it to your PATH:

# Replace YOUR-DOWNLOADED-FILE with the file path of your own.
sudo tar xvzf YOUR-DOWNLOADED-FILE -C /usr/local/bin/ kuesta

Build from source

If you would like to build kuesta from the source, set up your Go environment using Go 1.18 or higher, and run the following:

git clone https://github.com/nttcom/kuesta.git
cd kuesta
go build -o kuesta main.go

Then move built binary to your PATH.

Usage

You can perform an IaC configuration update without using kuesta-server by the following steps:

1: Clone the GitHub Repository you want to use as the configuration manifest source.

2: Update service configs.

3: Add these updated services to git Index.

4: Run kuesta service apply to perform data mapping from the service config to the device config as follows:

kuesta service apply -p=<path_to_config_repo_root>

Data mapping from the service config to the device config will be performed only for git-staged services, all unstaged changes will be skipped.

5: Run kuesta git commit to create git PullRequest on your configuration manifest repository. If authentication to git provider is required, use --git-token command flag or KUESTA_GIT_TOKEN environment value to provide GitHub private access token.

kuesta git commit -p <path_to_config_repo_root> -r <config_repo_url> 

For more information about available commands and flags, run kuesta help.

6 - Reference

Further documentation on Kuesta.

7 - Contribution Guidelines

How to contribute to Kuesta

Kuesta is an open source project and we love getting patches and contributions to make Kuesta and its docs even better.

Contributing to Kuesta

Creating PullRequest

All submissions, including submissions by project members, require review. We use GitHub PullRequest for this purpose. Consult GitHub Help for more information on using pull requests.

Creating issues

If you have found something that isn’t working the way you’d expect, but you’re not sure how to fix it yourself, please create an issue.

How to run the test suites

To run the whole test suites of all kuesta components:

make test-all

To run the specified component test suites only, run the following at the top of the component dir:

make test

For lint, install golangci-lint in advance, then run at the top of kuesta repo:

make lint-all

If you want to run Kuesta locally, see “Installtaion” page.