Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions cmd/admin/v2/commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ func AddCmds(cmd *cobra.Command, c *config.Config) {
adminCmd.AddCommand(newAuditCmd(c))
adminCmd.AddCommand(newComponentCmd(c))
adminCmd.AddCommand(newImageCmd(c))
adminCmd.AddCommand(newIPCmd(c))
adminCmd.AddCommand(newNetworkCmd(c))
adminCmd.AddCommand(newPartitionCmd(c))
adminCmd.AddCommand(newProjectCmd(c))
Expand Down
136 changes: 136 additions & 0 deletions cmd/admin/v2/ip.go
Comment thread
Gerrit91 marked this conversation as resolved.
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
package v2

import (
"fmt"

adminv2 "github.com/metal-stack/api/go/metalstack/admin/v2"
apiv2 "github.com/metal-stack/api/go/metalstack/api/v2"
"github.com/metal-stack/cli/cmd/config"
"github.com/metal-stack/cli/cmd/sorters"
"github.com/metal-stack/cli/pkg/helpers"
"github.com/metal-stack/metal-lib/pkg/genericcli"
"github.com/metal-stack/metal-lib/pkg/genericcli/printers"
"github.com/metal-stack/metal-lib/pkg/pointer"
"github.com/spf13/cobra"
"github.com/spf13/viper"
)

type ip struct {
c *config.Config
}

func newIPCmd(c *config.Config) *cobra.Command {
w := &ip{
c: c,
}

cmdsConfig := &genericcli.CmdsConfig[any, any, *apiv2.IP]{
BinaryName: config.BinaryName,
GenericCLI: genericcli.NewGenericCLI(w).WithFS(c.Fs),
Singular: "ip",
Plural: "ips",
Description: "an ip address of metal-stack.io",
Sorter: sorters.IPSorter(),
DescribePrinter: func() printers.Printer { return c.DescribePrinter },
ListPrinter: func() printers.Printer { return c.ListPrinter },
ListCmdMutateFn: func(cmd *cobra.Command) {
cmd.Flags().String("ip", "", "ip which should be listed")
cmd.Flags().String("uuid", "", "allocation uuid of ip which should be listed")
cmd.Flags().String("project", "", "project from where ips should be listed")
cmd.Flags().String("name", "", "name from ips which should be listed")
cmd.Flags().String("network", "", "network from where ips should be listed")
cmd.Flags().String("machine", "", "machine where ips are attached to")
cmd.Flags().StringSlice("labels", nil, "lists only ips with the given labels")
cmd.Flags().String("addressfamily", "", "addressfamily of ips which should be listed")
cmd.Flags().String("type", "", "type of ips which should be listed")

genericcli.Must(cmd.RegisterFlagCompletionFunc("project", c.Completion.Project))
genericcli.Must(cmd.RegisterFlagCompletionFunc("network", c.Completion.Network))
genericcli.Must(cmd.RegisterFlagCompletionFunc("machine", c.Completion.Machine))
genericcli.Must(cmd.RegisterFlagCompletionFunc("addressfamily", c.Completion.AddressFamily))
genericcli.Must(cmd.RegisterFlagCompletionFunc("type", c.Completion.IPType))

},
ValidArgsFn: c.Completion.Ip,
OnlyCmds: map[genericcli.DefaultCmd]bool{
genericcli.ListCmd: true,
genericcli.DescribeCmd: true,
},
}

return genericcli.NewCmds(cmdsConfig)
}

func (c *ip) Create(_ any) (*apiv2.IP, error) {
panic("unimplemented")
}

func (c *ip) Delete(id string) (*apiv2.IP, error) {
panic("unimplemented")
}

func (c *ip) Get(id string) (*apiv2.IP, error) {
ctx, cancel := c.c.NewRequestContext()
defer cancel()

resp, err := c.c.Client.Adminv2().IP().List(ctx, &adminv2.IPServiceListRequest{
Query: &apiv2.IPQuery{
Ip: &id,
},
})
if err != nil {
return nil, err
}
switch len(resp.Ips) {
case 0:
return nil, fmt.Errorf("no ip found for ip:%s", id)
case 1:
return resp.Ips[0], nil
default:
return nil, fmt.Errorf("more than one ip found for ip:%s", id)
}
}

func (c *ip) List() ([]*apiv2.IP, error) {
ctx, cancel := c.c.NewRequestContext()
defer cancel()

var labels *apiv2.Labels
if labelSlice := viper.GetStringSlice("labels"); len(labelSlice) > 0 {
var err error

labels, err = helpers.LabelsFromSlice(labelSlice)
if err != nil {
return nil, err
}
}

resp, err := c.c.Client.Adminv2().IP().List(ctx, &adminv2.IPServiceListRequest{
Query: &apiv2.IPQuery{
Ip: pointer.PointerOrNil(viper.GetString("ip")),
Uuid: pointer.PointerOrNil(viper.GetString("uuid")),
Network: pointer.PointerOrNil(viper.GetString("network")),
Project: pointer.PointerOrNil(viper.GetString("project")),
Name: pointer.PointerOrNil(viper.GetString("name")),
Machine: pointer.PointerOrNil(viper.GetString("machine")),
ParentPrefixCidr: pointer.PointerOrNil(viper.GetString("parent-prefix")),
Labels: labels,
Type: helpers.IPTypeToType(viper.GetString("type")),
AddressFamily: helpers.IPAddressFamilyToType(viper.GetString("addressfamily")),
Namespace: pointer.PointerOrNil(viper.GetString("namespace")),
},
})
if err != nil {
return nil, err
}

return resp.Ips, nil
}

func (c *ip) Update(_ any) (*apiv2.IP, error) {
panic("unimplemented")
}

func (c *ip) Convert(r *apiv2.IP) (string, any, any, error) {
panic("unimplemented")
}
14 changes: 14 additions & 0 deletions cmd/completion/ip.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,17 @@ func (c *Completion) AddressFamily(cmd *cobra.Command, args []string, toComplete

return afs, cobra.ShellCompDirectiveNoFileComp
}
func (c *Completion) IPType(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
var afs []string
for _, af := range []apiv2.IPType{
apiv2.IPType_IP_TYPE_STATIC,
apiv2.IPType_IP_TYPE_EPHEMERAL} {
stringValue, err := enum.GetStringValue(af)
if err != nil {
return nil, cobra.ShellCompDirectiveError
}
afs = append(afs, *stringValue)
}

return afs, cobra.ShellCompDirectiveNoFileComp
}
25 changes: 25 additions & 0 deletions cmd/completion/machine.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package completion

import (
adminv2 "github.com/metal-stack/api/go/metalstack/admin/v2"
"github.com/spf13/cobra"
)

func (c *Completion) Machine(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
req := &adminv2.MachineServiceListRequest{}
resp, err := c.Client.Adminv2().Machine().List(cmd.Context(), req)
if err != nil {
return nil, cobra.ShellCompDirectiveError
}
var names []string
for _, m := range resp.Machines {
var hostname string
if m.Allocation != nil {
hostname = m.Allocation.Hostname
names = append(names, m.Uuid+"\t"+hostname)
} else {
names = append(names, m.Uuid)
}
}
return names, cobra.ShellCompDirectiveNoFileComp
}
4 changes: 2 additions & 2 deletions cmd/tableprinters/ip.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import (
func (t *TablePrinter) IPTable(data []*apiv2.IP, wide bool) ([]string, [][]string, error) {
var (
rows [][]string
header = []string{"IP", "Project", "ID", "Type", "Name", "Attached Service"}
header = []string{"IP", "Project", "ID", "Network", "Type", "Name", "Attached Service"}
)

if wide {
Expand All @@ -33,7 +33,7 @@ func (t *TablePrinter) IPTable(data []*apiv2.IP, wide bool) ([]string, [][]strin
if wide {
rows = append(rows, []string{ip.Ip, ip.Project, ip.Uuid, pointer.SafeDeref(t), ip.Name, ip.Description, strings.Join(labels, "\n")})
} else {
rows = append(rows, []string{ip.Ip, ip.Project, ip.Uuid, pointer.SafeDeref(t), ip.Name, attachedService})
rows = append(rows, []string{ip.Ip, ip.Project, ip.Uuid, ip.Network, pointer.SafeDeref(t), ip.Name, attachedService})
}
}

Expand Down
1 change: 1 addition & 0 deletions docs/admin/metalctlv2_admin.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ these commands utilize the admin api, which can only be accessed by metal-stack
* [metalctlv2 admin audit](metalctlv2_admin_audit.md) - manage audit entities
* [metalctlv2 admin component](metalctlv2_admin_component.md) - manage component entities
* [metalctlv2 admin image](metalctlv2_admin_image.md) - manage image entities
* [metalctlv2 admin ip](metalctlv2_admin_ip.md) - manage ip entities
* [metalctlv2 admin network](metalctlv2_admin_network.md) - manage network entities
* [metalctlv2 admin partition](metalctlv2_admin_partition.md) - manage partition entities
* [metalctlv2 admin project](metalctlv2_admin_project.md) - manage project entities
Expand Down
33 changes: 33 additions & 0 deletions docs/admin/metalctlv2_admin_ip.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
## metalctlv2 admin ip

manage ip entities

### Synopsis

an ip address of metal-stack.io

### Options

```
-h, --help help for ip
```

### Options inherited from parent commands

```
--api-token string the token used for api requests
--api-url string the url to the metal-stack.io api
-c, --config string alternative config file path, (default is ~/.metal-stack/config.yaml)
--debug debug output
--force-color force colored output even without tty
-o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
--template string output template for template output-format, go template format. For property names inspect the output of -o json or -o yaml for reference.
--timeout duration request timeout used for api requests
```

### SEE ALSO

* [metalctlv2 admin](metalctlv2_admin.md) - admin commands
* [metalctlv2 admin ip describe](metalctlv2_admin_ip_describe.md) - describes the ip
* [metalctlv2 admin ip list](metalctlv2_admin_ip_list.md) - list all ips

31 changes: 31 additions & 0 deletions docs/admin/metalctlv2_admin_ip_describe.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
## metalctlv2 admin ip describe

describes the ip

```
metalctlv2 admin ip describe <id> [flags]
```

### Options

```
-h, --help help for describe
```

### Options inherited from parent commands

```
--api-token string the token used for api requests
--api-url string the url to the metal-stack.io api
-c, --config string alternative config file path, (default is ~/.metal-stack/config.yaml)
--debug debug output
--force-color force colored output even without tty
-o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
--template string output template for template output-format, go template format. For property names inspect the output of -o json or -o yaml for reference.
--timeout duration request timeout used for api requests
```

### SEE ALSO

* [metalctlv2 admin ip](metalctlv2_admin_ip.md) - manage ip entities

41 changes: 41 additions & 0 deletions docs/admin/metalctlv2_admin_ip_list.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
## metalctlv2 admin ip list

list all ips

```
metalctlv2 admin ip list [flags]
```

### Options

```
--addressfamily string addressfamily of ips which should be listed
-h, --help help for list
--ip string ip which should be listed
--labels strings lists only ips with the given labels
--machine string machine where ips are attached to
--name string name from ips which should be listed
--network string network from where ips should be listed
--project string project from where ips should be listed
--sort-by strings sort by (comma separated) column(s), sort direction can be changed by appending :asc or :desc behind the column identifier. possible values: ip|name|network|project|type|uuid
--type string type of ips which should be listed
--uuid string allocation uuid of ip which should be listed
```

### Options inherited from parent commands

```
--api-token string the token used for api requests
--api-url string the url to the metal-stack.io api
-c, --config string alternative config file path, (default is ~/.metal-stack/config.yaml)
--debug debug output
--force-color force colored output even without tty
-o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
--template string output template for template output-format, go template format. For property names inspect the output of -o json or -o yaml for reference.
--timeout duration request timeout used for api requests
```

### SEE ALSO

* [metalctlv2 admin ip](metalctlv2_admin_ip.md) - manage ip entities

26 changes: 13 additions & 13 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module github.com/metal-stack/cli

go 1.26.0
go 1.26.5

require (
connectrpc.com/connect v1.20.0
Expand All @@ -10,20 +10,20 @@ require (
github.com/google/go-cmp v0.7.0
github.com/google/uuid v1.6.0
github.com/metal-stack/api v0.4.4
github.com/metal-stack/metal-lib v0.26.1
github.com/metal-stack/metal-lib v0.26.2
github.com/metal-stack/v v1.0.3
github.com/spf13/afero v1.15.0
github.com/spf13/cobra v1.10.2
github.com/spf13/viper v1.21.0
github.com/stretchr/testify v1.11.1
google.golang.org/grpc v1.82.1
google.golang.org/protobuf v1.36.12-0.20260120151049-f2248ac996af
google.golang.org/grpc v1.83.0
google.golang.org/protobuf v1.36.12
sigs.k8s.io/yaml v1.6.0
)

require (
buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.36.11-20260709200747-435963d16310.1 // indirect
buf.build/go/protovalidate v1.2.0 // indirect
buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.36.12-20260709200747-435963d16310.1 // indirect
buf.build/go/protovalidate v1.3.0 // indirect
buf.build/go/protoyaml v0.7.0 // indirect
cel.dev/expr v0.25.2 // indirect
github.com/antlr4-go/antlr/v4 v4.13.1 // indirect
Expand All @@ -40,9 +40,9 @@ require (
github.com/goccy/go-json v0.10.6 // indirect
github.com/goccy/go-yaml v1.19.2 // indirect
github.com/golang-jwt/jwt/v5 v5.3.1 // indirect
github.com/google/cel-go v0.30.0 // indirect
github.com/google/cel-go v0.31.0 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/klauspost/compress v1.19.1 // indirect
github.com/klauspost/compress v1.19.2 // indirect
github.com/klauspost/connect-compress/v2 v2.1.1 // indirect
github.com/mattn/go-colorable v0.1.15 // indirect
github.com/mattn/go-isatty v0.0.24 // indirect
Expand All @@ -63,12 +63,12 @@ require (
github.com/subosito/gotenv v1.6.0 // indirect
go.yaml.in/yaml/v2 v2.4.4 // indirect
go.yaml.in/yaml/v3 v3.0.5 // indirect
golang.org/x/exp v0.0.0-20260727155853-b88d891fe743 // indirect
golang.org/x/net v0.57.0 // indirect
golang.org/x/exp v0.0.0-20260812173653-3d80eb74bc5b // indirect
golang.org/x/net v0.58.0 // indirect
golang.org/x/sys v0.47.0 // indirect
golang.org/x/text v0.40.0 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20260727163830-6c54dddc4772 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20260727163830-6c54dddc4772 // indirect
golang.org/x/text v0.41.0 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20260810153831-ec0a7760b754 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20260810153831-ec0a7760b754 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
k8s.io/apimachinery v0.36.3 // indirect
Expand Down
Loading
Loading