-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #12 from srl-labs/srl-license
srlinux license provisioning via secrets
- Loading branch information
Showing
23 changed files
with
823 additions
and
120 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,3 @@ | ||
|
||
# Binaries for programs and plugins | ||
*.exe | ||
*.exe~ | ||
|
@@ -24,3 +23,5 @@ testbin/* | |
*.swo | ||
*~ | ||
.vscode | ||
|
||
private |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,11 @@ | ||
# SR Linux Controller for KNE | ||
|
||
This is a k8s controller for running and managing SR Linux nodes launched from [openconfig/kne](https://github.com/openconfig/kne) topology. | ||
|
||
## Install | ||
|
||
To install the latest version of this controller on a cluster referenced in `~/.kube/config` issue the following command: | ||
|
||
```bash | ||
# latest version | ||
kubectl apply -k https://github.com/srl-labs/srl-controller/config/default | ||
|
@@ -11,7 +15,8 @@ kubectl apply -k https://github.com/srl-labs/srl-controller/config/default?ref=v | |
``` | ||
|
||
The resources of this controller will be scoped under `srlinux-controller` namespace. | ||
``` | ||
|
||
```text | ||
❯ kubectl get all -n srlinux-controller | ||
NAME READY STATUS RESTARTS AGE | ||
|
@@ -28,91 +33,90 @@ replicaset.apps/srlinux-controller-controller-manager-c7495dcc7 1 1 | |
``` | ||
|
||
### Installing from a repo | ||
|
||
The controller can be installed with make directly from the repo: | ||
``` | ||
|
||
```text | ||
make deploy IMG=ghcr.io/srl-labs/srl-controller:0.3.1 | ||
``` | ||
|
||
Make sure to check which controller versions are [available](https://github.com/srl-labs/srl-controller/pkgs/container/srl-controller/versions) | ||
Make sure to check which controller versions are [available](https://github.com/srl-labs/srl-controller/pkgs/container/srl-controller/versions). | ||
|
||
## Uninstall | ||
|
||
To uninstall the controller from the cluster: | ||
``` | ||
|
||
```text | ||
kubectl delete -k https://github.com/srl-labs/srl-controller/config/default | ||
``` | ||
|
||
## Testing with `kind` | ||
To run this controller in a test cluster deployed with [`kind`](https://kind.sigs.k8s.io/) follow the steps outlined below. | ||
|
||
1. Install `kind` | ||
2. Clone and enter into [openconfig/kne](https://github.com/openconfig/kne) repo. | ||
3. Build the kne cli with | ||
`cd kne_cli && go build -o kne && chmod +x ./kne && mv ./kne /usr/local/bin` | ||
4. deploy kind cluster and the necessary CNI with `kne deploy deploy/kne/kind.yaml` where the path to `kind.yaml` is a relative path from the root of the kne repo. | ||
## Testing with `kne` & `kind` | ||
|
||
This will install the `kind` cluster named `kne` with [`meshnet-cni`](https://github.com/networkop/meshnet-cni) and [`metallb`](https://metallb.universe.tf/). | ||
|
||
A quick test may be performed to verify that SR Linux pods can communicate over the newly deployed cluster: | ||
|
||
```bash | ||
# apply this manifest https://gist.github.com/hellt/43cfade6178be32ea7dfa5cb64715822 | ||
# which has two srlinux pods and two linux pods | ||
kubectl apply -f https://gist.githubusercontent.com/hellt/43cfade6178be32ea7dfa5cb64715822/raw/847a10a57dca996432be7c4a9743c0e0c5b75814/srl.yml | ||
|
||
# once the pods are deployed and running, verify that srlinux pods can reach each other with ssh | ||
# check what IP the srl2 has | ||
kubectl exec -it srl1 -- ip netns exec srbase-mgmt ssh [email protected] | ||
[email protected]'s password: | ||
Last login: Fri Sep 24 13:58:05 2021 from 10.244.0.6 | ||
Using configuration file(s): ['/etc/opt/srlinux/srlinux.rc'] | ||
Welcome to the srlinux CLI. | ||
Type 'help' (and press <ENTER>) if you need any help using this. | ||
--{ [FACTORY] running }--[ ]-- | ||
``` | ||
To run this controller in a test cluster deployed with [`kne`](https://github.com/openconfig/kne) and [`kind`](https://kind.sigs.k8s.io/) follow the steps outlined in the [KNE repository](https://github.com/openconfig/kne/tree/main/docs). | ||
|
||
If all works as expected a [demo topology with three SR Linux nodes](https://github.com/openconfig/kne/blob/main/examples/3node-srl.pb.txt) may be deployed as follows: | ||
Once the kne+kind cluster is created, a [demo topology with two SR Linux nodes](https://github.com/openconfig/kne/blob/db5fe5be01a1b6b65bd79e740e2c819c5aeb50b0/examples/srlinux/2node-srl-with-config.pbtxt) may be deployed as follows: | ||
|
||
```bash | ||
kne create ~/kne/examples/3node-srl.pb.txt | ||
kne create examples/srlinux/2node-srl-with-config.pbtxt | ||
``` | ||
|
||
This will deploy the SR Linux nodes and will create k8s services as per the topology configuration. The services will be exposed via MetalLB and can be queried as: | ||
|
||
``` | ||
```text | ||
❯ kubectl -n 3node-srlinux get svc | ||
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE | ||
service-r1 LoadBalancer 10.96.151.84 172.19.0.50 57400:30006/TCP,443:30004/TCP,22:30005/TCP 6m10s | ||
service-r2 LoadBalancer 10.96.34.36 172.19.0.51 443:30010/TCP,22:30011/TCP,57400:30009/TCP 6m9s | ||
service-r3 LoadBalancer 10.96.159.220 172.19.0.52 443:30015/TCP,22:30016/TCP,57400:30014/TCP 6m9s | ||
``` | ||
|
||
To connect with SSH to the `r1` node, use `ssh [email protected]` command. | ||
|
||
### Loading images to kind cluster | ||
|
||
[Public SR Linux container image](https://github.com/nokia/srlinux-container-image) will be pulled by kind automatically, if Internet access is present. Images which are not available publicy can be uploaded to kind manually: | ||
|
||
```bash | ||
# default kne kind cluster name is `kne` | ||
# which is the last argument in the command | ||
kind load docker-image srlinux:0.0.0-38566 --name kne | ||
``` | ||
|
||
## Using license files | ||
|
||
To remove the packets-per-second limit of a public container image or to launch chassis-based variants of SR Linux (ixr-6e/10e) KNE users should provide a valid license file to the `srl-controller`. | ||
|
||
Navigate to [Using license files](docs/using-licenses.md) document to have a detailed explanation on that topic. | ||
|
||
## Controller operations | ||
|
||
The controller is designed to manage the `Srlinux` custom resource defined with [the following CRD](https://doc.crds.dev/github.com/srl-labs/srl-controller). | ||
|
||
The request to create/delete a resource of kind `Srlinux` is typically coming from `openconfig/kne` topology. | ||
|
||
### Creation | ||
When a request to create an `Srlinux` resource named `r1` in namespace `ns` comes in, the controller's reconcile loop does the following: | ||
|
||
1. Checks if the pods exist within a namespace `ns` with a name `r1` | ||
When a request to create a `Srlinux` resource named `r1` in namespace `ns` comes in, the controller's reconcile loop does the following: | ||
|
||
1. Checks if the pods exist within a namespace `ns` with a name `r1` | ||
2. If the pod hasn't been found, then the controller first ensures that the necessary config maps exist in namespace `ns` and creates them otherwise. | ||
3. When config maps are sorted out, the controller schedules a pod with the name `r1` and requeue the request | ||
4. In a requeue run, the pod is now found and the controller updates the status of `Srlinux` resource with the image name that was used in the pod spec. | ||
|
||
### Deletion | ||
|
||
When a deletion happens on `Srlinux` resource, the reconcile loop does nothing. | ||
|
||
### API access | ||
|
||
This repo contains a clientset for API access to the `Srlinux` custom resource. Check [kne repo](https://github.com/openconfig/kne/blob/fc195a73035bcbf344791979ca3e067be47a249c/topo/node/srl/srl.go#L46) to see how this can be done. | ||
|
||
## Building srl-controller container image | ||
## Building `srl-controller` container image | ||
|
||
To build `srl-controller` container image execute: | ||
|
||
```bash | ||
# don't forget to set the correct tag | ||
make docker-build IMG=ghcr.io/srl-labs/srl-controller:${tag} | ||
``` | ||
|
||
Then upload the image to the registry. | ||
Then upload the image to the registry and update the controller version in [manager/kustomization.yaml](config/manager/kustomization.yaml). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
package v1alpha1 | ||
|
||
import ( | ||
"errors" | ||
"regexp" | ||
"strings" | ||
) | ||
|
||
// ErrVersionParse is an error which is raised when srlinux version is failed to parse. | ||
var ErrVersionParse = errors.New("version parsing failed") | ||
|
||
// SrlVersion represents an sr linux version as a set of fields. | ||
type SrlVersion struct { | ||
Major string `json:"major,omitempty"` | ||
Minor string `json:"minor,omitempty"` | ||
Patch string `json:"patch,omitempty"` | ||
Build string `json:"build,omitempty"` | ||
Commit string `json:"commit,omitempty"` | ||
} | ||
|
||
func parseVersionString(s string) (*SrlVersion, error) { | ||
// for latest or missing tag we consider the version to be an engineering build | ||
// with major = 0 | ||
if strings.ToLower(s) == "latest" || s == "" { | ||
return &SrlVersion{"0", "", "", "", ""}, nil | ||
} | ||
|
||
// https://regex101.com/r/eWS6Ms/1 | ||
re := regexp.MustCompile( | ||
`^v?(?P<major>\d{1,3})\.(?P<minor>\d{1,2})\.?(?P<patch>\d{1,2})?-?(?P<build>\d{1,10})?-?(?P<commit>\S+)?`, | ||
) | ||
|
||
v := re.FindStringSubmatch(s) | ||
if v == nil { | ||
return nil, ErrVersionParse | ||
} | ||
|
||
return &SrlVersion{v[1], v[2], v[3], v[4], v[5]}, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
package v1alpha1 | ||
|
||
import ( | ||
"errors" | ||
"testing" | ||
|
||
"github.com/google/go-cmp/cmp" | ||
) | ||
|
||
func TestParseVersionString(t *testing.T) { | ||
tests := []struct { | ||
desc string | ||
got string | ||
want *SrlVersion | ||
err error | ||
}{ | ||
{ | ||
desc: "maj, minor, patch", | ||
got: "21.6.4", | ||
want: &SrlVersion{"21", "6", "4", "", ""}, | ||
}, | ||
{ | ||
desc: "maj, minor", | ||
got: "21.6", | ||
want: &SrlVersion{"21", "6", "", "", ""}, | ||
}, | ||
{ | ||
desc: "maj, minor and extra string", | ||
got: "21.6-test", | ||
want: &SrlVersion{"21", "6", "", "", "test"}, | ||
}, | ||
{ | ||
desc: "maj, minor, patch and extra string", | ||
got: "21.6.11-test", | ||
want: &SrlVersion{"21", "6", "11", "", "test"}, | ||
}, | ||
{ | ||
desc: "maj, minor, patch, build and extra string", | ||
got: "21.6.11-235-test", | ||
want: &SrlVersion{"21", "6", "11", "235", "test"}, | ||
}, | ||
{ | ||
desc: "maj, minor, patch and build", | ||
got: "21.6.11-235", | ||
want: &SrlVersion{"21", "6", "11", "235", ""}, | ||
}, | ||
{ | ||
desc: "0.0", | ||
got: "0.0", | ||
want: &SrlVersion{"0", "0", "", "", ""}, | ||
}, | ||
{ | ||
desc: "0.0.0", | ||
got: "0.0.0", | ||
want: &SrlVersion{"0", "0", "0", "", ""}, | ||
}, | ||
{ | ||
desc: "0.0.0-34652", | ||
got: "0.0.0-34652", | ||
want: &SrlVersion{"0", "0", "0", "34652", ""}, | ||
}, | ||
{ | ||
desc: "latest", | ||
got: "latest", | ||
want: &SrlVersion{"0", "", "", "", ""}, | ||
}, | ||
{ | ||
desc: "empty", | ||
got: "", | ||
want: &SrlVersion{"0", "", "", "", ""}, | ||
}, | ||
{ | ||
desc: "invalid1", | ||
got: "abcd", | ||
want: nil, | ||
err: ErrVersionParse, | ||
}, | ||
} | ||
|
||
for _, tt := range tests { | ||
t.Run(tt.desc, func(t *testing.T) { | ||
ver, err := parseVersionString(tt.got) | ||
if !errors.Is(err, tt.err) { | ||
t.Fatalf("got error '%v' but expected '%v'", err, tt.err) | ||
} | ||
|
||
if !cmp.Equal(ver, tt.want) { | ||
t.Fatalf( | ||
"%s: actual and expected inputs do not match\nactual: %+v\nexpected:%+v", | ||
tt.desc, | ||
ver, | ||
tt.want, | ||
) | ||
} | ||
}, | ||
) | ||
} | ||
} |
Oops, something went wrong.