Skip to content

Commit 0f03a98

Browse files
FloSch62hellt
andauthored
Add custom owner support for lab resources (#2553)
* Add custom owner support for lab resources * format * use existing group checking func --------- Co-authored-by: Roman Dodin <[email protected]>
1 parent 6e909a6 commit 0f03a98

File tree

6 files changed

+82
-7
lines changed

6 files changed

+82
-7
lines changed

clab/clab.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"fmt"
1111
"io/fs"
1212
"os"
13+
"os/user"
1314
"path/filepath"
1415
"strings"
1516
"sync"
@@ -59,6 +60,27 @@ type CLab struct {
5960
// checkBindsPaths toggle enables or disables binds paths checks
6061
// when set to true, bind sources are verified to exist on the host.
6162
checkBindsPaths bool
63+
// customOwner is the user-specified owner label for the lab
64+
customOwner string
65+
}
66+
67+
// WithLabOwner sets the owner label for all nodes in the lab.
68+
// Only users in the clab_admins group can set a custom owner.
69+
func WithLabOwner(owner string) ClabOption {
70+
return func(c *CLab) error {
71+
currentUser, err := user.Current()
72+
if err != nil {
73+
log.Warn("Failed to get current user when trying to set the custom lab owner", "error", err)
74+
return nil
75+
}
76+
77+
if isClabAdmin, err := utils.UserInUnixGroup(currentUser.Username, "clab_admins"); err == nil && isClabAdmin {
78+
c.customOwner = owner
79+
} else if owner != "" {
80+
log.Warn("Only users in clab_admins group can set custom owner. Using current user as owner.")
81+
}
82+
return nil
83+
}
6284
}
6385

6486
type ClabOption func(c *CLab) error

clab/config.go

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -550,6 +550,8 @@ func (c *CLab) HasKind(k string) bool {
550550
return false
551551
}
552552

553+
// addDefaultLabels adds default labels to node's config struct.
554+
// Update the addDefaultLabels function in clab/config.go
553555
// addDefaultLabels adds default labels to node's config struct.
554556
func (c *CLab) addDefaultLabels(n nodes.Node) {
555557
cfg := n.Config()
@@ -565,9 +567,14 @@ func (c *CLab) addDefaultLabels(n nodes.Node) {
565567
cfg.Labels[labels.NodeGroup] = cfg.Group
566568
cfg.Labels[labels.NodeLabDir] = cfg.LabDir
567569
cfg.Labels[labels.TopoFile] = c.TopoPaths.TopologyFilenameAbsPath()
568-
owner := os.Getenv("SUDO_USER")
570+
571+
// Use custom owner if set, otherwise use current user
572+
owner := c.customOwner
569573
if owner == "" {
570-
owner = os.Getenv("USER")
574+
owner = os.Getenv("SUDO_USER")
575+
if owner == "" {
576+
owner = os.Getenv("USER")
577+
}
571578
}
572579
cfg.Labels[labels.Owner] = owner
573580
}

cmd/deploy.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,9 @@ var deployFormat string
4747
// skipLabDirFileACLs skips provisioning of extended File ACLs for the Lab directory.
4848
var skipLabDirFileACLs bool
4949

50+
// labOwner flag for setting the owner label.
51+
var labOwner string
52+
5053
// deployCmd represents the deploy command.
5154
var deployCmd = &cobra.Command{
5255
Use: "deploy",
@@ -76,6 +79,8 @@ func init() {
7679
"comma separated list of nodes to include")
7780
deployCmd.Flags().BoolVarP(&skipLabDirFileACLs, "skip-labdir-acl", "", false,
7881
"skip the lab directory extended ACLs provisioning")
82+
deployCmd.Flags().StringVarP(&labOwner, "owner", "", "",
83+
"lab owner name (only for users in clab_admins group)")
7984
}
8085

8186
// deployFn function runs deploy sub command.
@@ -89,6 +94,11 @@ func deployFn(_ *cobra.Command, _ []string) error {
8994

9095
setupCTRLCHandler(cancel)
9196

97+
// Check for owner from environment (set by generate command)
98+
if labOwner == "" && os.Getenv("CLAB_OWNER") != "" {
99+
labOwner = os.Getenv("CLAB_OWNER")
100+
}
101+
92102
opts := []clab.ClabOption{
93103
clab.WithTimeout(common.Timeout),
94104
clab.WithTopoPath(common.Topo, common.VarsFile),
@@ -108,6 +118,9 @@ func deployFn(_ *cobra.Command, _ []string) error {
108118
if common.Name != "" {
109119
opts = append(opts, clab.WithLabName(common.Name))
110120
}
121+
if labOwner != "" {
122+
opts = append(opts, clab.WithLabOwner(labOwner))
123+
}
111124
if mgmtNetName != "" {
112125
opts = append(opts, clab.WithManagementNetworkName(mgmtNetName))
113126
}

cmd/generate.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"errors"
99
"fmt"
1010
"net"
11+
"os"
1112
"strconv"
1213
"strings"
1314

@@ -103,6 +104,13 @@ var generateCmd = &cobra.Command{
103104
}
104105
}
105106
common.Topo = file
107+
108+
// Pass owner to deploy command if specified
109+
if labOwner != "" {
110+
// This will be picked up by the deploy command
111+
os.Setenv("CLAB_OWNER", labOwner)
112+
}
113+
106114
return deployCmd.RunE(deployCmd, nil)
107115
}
108116
if file == "" {
@@ -148,6 +156,9 @@ func init() {
148156
"deploy a fabric based on the generated topology file")
149157
generateCmd.Flags().UintVarP(&maxWorkers, "max-workers", "", 0,
150158
"limit the maximum number of workers creating nodes and virtual wires")
159+
// Add the owner flag to generate command
160+
generateCmd.Flags().StringVarP(&labOwner, "owner", "", "",
161+
"lab owner name (only for users in clab_admins group)")
151162
}
152163

153164
func generateTopologyConfig(name, network, ipv4range, ipv6range string,

docs/cmd/deploy.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,17 @@ The extended File ACLs are provisioned for the lab directory by default, unless
143143

144144
While this is useful in most cases, sometimes extended File ACLs might prevent your lab from working, especially when your lab directory end up being mounted from the network filesystem (NFS, CIFS, etc.). In such cases, you can use this flag to skip the ACL provisioning.
145145

146+
#### owner
147+
148+
The local `--owner` flag allows you to specify a custom owner for the lab. This value will be applied as the owner label for all nodes in the lab.
149+
150+
This flag is designed for multi-user environments where you need to track ownership of lab resources. Only users who are members of the `clab_admins` group can set a custom owner. If a non-admin user attempts to set an owner, the flag will be ignored with a warning, and the current user will be used as the owner instead.
151+
152+
Example:
153+
```bash
154+
containerlab deploy -t mylab.clab.yml --owner alice
155+
```
156+
146157
### Environment variables
147158

148159
#### `CLAB_RUNTIME`

docs/cmd/generate.md

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ It is assumed, that the interconnection between the tiers is done in a full-mesh
1818

1919
#### name
2020

21-
With the global `--name | -n` flag a user sets the name of the lab that will be generated.
21+
With the global `--name` flag a user sets the name of the lab that will be generated.
2222

2323
#### nodes
2424
The user configures the CLOS fabric topology by using the `--nodes` flag. The flag value is a comma separated list of CLOS tiers where each tier is defined by the number of nodes, its kind and type. Multiple `--node` flags can be specified.
@@ -42,19 +42,19 @@ For example the following value will generate a 3-tier CLOS fabric of cEOS nodes
4242

4343
```bash
4444
# cEOS fabric
45-
containerlab gen -n 3tier --kind ceos --nodes 4,2,1
45+
containerlab gen --name 3tier --kind ceos --nodes 4,2,1
4646

4747
# since SR Linux kind is assumed by default
4848
# SRL fabric command is even shorter
49-
containerlab gen -n 3tier --nodes 4,2,1
49+
containerlab gen --name 3tier --nodes 4,2,1
5050
```
5151

5252
#### image
5353
Use `--image` flag to specify the container image that should be used by a given kind.
5454

5555
The value of this flag follows the `kind=image` pattern. For example, to set the container image `ceos:4.32.0F` for the `ceos` kind the flag will be: `--image ceos=ceos:4.32.0F`.
5656

57-
To set images for multiple kinds repeat the flag: `--image srl=srlinux:latest --image ceos=ceos:4.32.0F` or use the comma separated form: `--image srl=srlinux:latest,ceos=ceos:latest`
57+
To set images for multiple kinds repeat the flag: `--image srl=ghcr.io/nokia/srlinux:latest --image ceos=ceos:4.32.0F` or use the comma separated form: `--image srl=ghcr.io/nokia/srlinux:latest,ceos=ceos:latest`
5858

5959
If the kind information is not provided in the `image` flag, the kind value will be taken from the `--kind` flag.
6060

@@ -96,6 +96,17 @@ Default: `clab`.
9696
#### ipv4-subnet | ipv6-subnet
9797
With `--ipv4-subnet` and `ipv6-subnet` it's possible to change the address ranges of the management network. Nodes will receive IP addresses from these ranges if they are configured with DHCP.
9898

99+
#### owner
100+
101+
With `--owner` flag you can specify a custom owner for the lab. This value will be applied as the owner label for all nodes in the lab.
102+
103+
This flag is designed for multi-user environments where you need to track ownership of lab resources. Only users who are members of the `clab_admins` group can set a custom owner. If a non-admin user attempts to set an owner, the flag will be ignored with a warning, and the current user will be used as the owner instead.
104+
105+
Example:
106+
```bash
107+
containerlab generate --name 3tier --nodes 8,4,2 --owner bob --deploy
108+
```
109+
99110
### Examples
100111

101112
#### Generate topology for a 3-tier CLOS network
@@ -105,7 +116,7 @@ Generate and deploy a lab topology for 3-tier CLOS network with 8 leafs, 4 spine
105116
The `srl` kind in the image and license flags can be omitted, as it is implied by default
106117

107118
```bash
108-
containerlab generate --name 3tier --image srl=srlinux:latest \
119+
containerlab generate --name 3tier --image srl=ghcr.io/nokia/srlinux:latest \
109120
--license srl=license.key \
110121
--nodes 8,4,2 --deploy
111122
```

0 commit comments

Comments
 (0)