Skip to content

Address sets for nftables and OVN #1728

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 24 commits into from
Apr 5, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
053e8fe
incusd/network/ovn: Add plumbing for state through OVN ACL functions
stgraber Mar 25, 2025
95a1d2c
api: network_address_set
Mar 11, 2025
e86caf4
doc: Add documentation for network address sets
Mar 12, 2025
ff99d8c
shared/api: Add network address sets
Mar 12, 2025
c7ada67
shared/api/lifecycle: Add events for network address sets
Mar 12, 2025
1ea766c
incusd/auth: Add network address sets
Mar 12, 2025
c5b3e34
incusd/auth/openfga: Rebuild model
Mar 12, 2025
f5ee6b1
incusd/network/ovn: Add GetAddressSet
Mar 12, 2025
38622e4
incusd/network/ovn: Add address set support
Mar 12, 2025
5082c24
incusd/network/bridge: Add address set support
Mar 12, 2025
090cfaa
incusd/db/cluster: Add network_address_sets tables
Mar 12, 2025
53c3c8e
incusd/db: Add network address set functions
Mar 12, 2025
b97b015
incusd/network/acl: Add address set support
Mar 12, 2025
61ef663
incusd/lifecycle: Add network address set events
Mar 12, 2025
b768dfd
incusd/firewall: Add address set support
Mar 12, 2025
c959687
incusd/projects: Clear address sets on delete
Mar 12, 2025
97348db
incusd/network/address-set: Add new API
Mar 12, 2025
067a228
incusd/device/nic/ovn: Handle address set when cleaing ACLs
Mar 25, 2025
8eed850
client: Add network address set functions
Mar 11, 2025
251d559
incus: Add network address-set sub-command
Mar 12, 2025
6f154c3
i18n: Update translation templates
Mar 11, 2025
3bd2375
tests: Add tests for address sets
Mar 12, 2025
1f136dc
doc/rest-api: Refresh swagger YAML
Mar 11, 2025
af2a1e3
doc: Update configs
stgraber Mar 23, 2025
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
135 changes: 135 additions & 0 deletions client/incus_network_address_sets.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
package incus

import (
"fmt"
"net/url"

"github.com/lxc/incus/v6/shared/api"
)

// GetNetworkAddressSetNames returns a list of network address set names.
func (r *ProtocolIncus) GetNetworkAddressSetNames() ([]string, error) {
if !r.HasExtension("network_address_set") {
return nil, fmt.Errorf(`The server is missing the required "network_address_set" API extension`)
}

// Fetch the raw URL values.
urls := []string{}
baseURL := "/network-address-sets"
_, err := r.queryStruct("GET", baseURL, nil, "", &urls)
if err != nil {
return nil, err
}

// Parse it.
return urlsToResourceNames(baseURL, urls...)
}

// GetNetworkAddressSets returns a list of network address set structs.
func (r *ProtocolIncus) GetNetworkAddressSets() ([]api.NetworkAddressSet, error) {
if !r.HasExtension("network_address_set") {
return nil, fmt.Errorf(`The server is missing the required "network_address_set" API extension`)
}

addressSets := []api.NetworkAddressSet{}

// Fetch the raw value.
_, err := r.queryStruct("GET", "/network-address-sets?recursion=1", nil, "", &addressSets)
if err != nil {
return nil, err
}

return addressSets, nil
}

// GetNetworkAddressSetsAllProjects returns a list of network address set structs across all projects.
func (r *ProtocolIncus) GetNetworkAddressSetsAllProjects() ([]api.NetworkAddressSet, error) {
if !r.HasExtension("network_address_sets_all_projects") {
return nil, fmt.Errorf(`The server is missing the required "network_address_sets_all_projects" API extension`)
}

addressSets := []api.NetworkAddressSet{}
_, err := r.queryStruct("GET", "/network-address-sets?recursion=1&all-projects=true", nil, "", &addressSets)
if err != nil {
return nil, err
}

return addressSets, nil
}

// GetNetworkAddressSet returns a network address set entry for the provided name.
func (r *ProtocolIncus) GetNetworkAddressSet(name string) (*api.NetworkAddressSet, string, error) {
if !r.HasExtension("network_address_set") {
return nil, "", fmt.Errorf(`The server is missing the required "network_address_set" API extension`)
}

addrSet := api.NetworkAddressSet{}

// Fetch the raw value.
etag, err := r.queryStruct("GET", fmt.Sprintf("/network-address-sets/%s", url.PathEscape(name)), nil, "", &addrSet)
if err != nil {
return nil, "", err
}

return &addrSet, etag, nil
}

// CreateNetworkAddressSet defines a new network address set using the provided struct.
func (r *ProtocolIncus) CreateNetworkAddressSet(as api.NetworkAddressSetsPost) error {
if !r.HasExtension("network_address_set") {
return fmt.Errorf(`The server is missing the required "network_address_set" API extension`)
}

// Send the request.
_, _, err := r.query("POST", "/network-address-sets", as, "")
if err != nil {
return err
}

return nil
}

// UpdateNetworkAddressSet updates the network address set to match the provided struct.
func (r *ProtocolIncus) UpdateNetworkAddressSet(name string, as api.NetworkAddressSetPut, ETag string) error {
if !r.HasExtension("network_address_set") {
return fmt.Errorf(`The server is missing the required "network_address_set" API extension`)
}

// Send the request.
_, _, err := r.query("PUT", fmt.Sprintf("/network-address-sets/%s", url.PathEscape(name)), as, ETag)
if err != nil {
return err
}

return nil
}

// RenameNetworkAddressSet renames an existing network address set entry.
func (r *ProtocolIncus) RenameNetworkAddressSet(name string, as api.NetworkAddressSetPost) error {
if !r.HasExtension("network_address_set") {
return fmt.Errorf(`The server is missing the required "network_address_set" API extension`)
}

// Send the request.
_, _, err := r.query("POST", fmt.Sprintf("/network-address-sets/%s", url.PathEscape(name)), as, "")
if err != nil {
return err
}

return nil
}

// DeleteNetworkAddressSet deletes an existing network address set.
func (r *ProtocolIncus) DeleteNetworkAddressSet(name string) error {
if !r.HasExtension("network_address_set") {
return fmt.Errorf(`The server is missing the required "network_address_set" API extension`)
}

// Send the request.
_, _, err := r.query("DELETE", fmt.Sprintf("/network-address-sets/%s", url.PathEscape(name)), nil, "")
if err != nil {
return err
}

return nil
}
10 changes: 10 additions & 0 deletions client/interfaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,16 @@ type InstanceServer interface {
RenameNetworkACL(name string, acl api.NetworkACLPost) (err error)
DeleteNetworkACL(name string) (err error)

// Network address set functions ("network_address_set" API extension)
GetNetworkAddressSetNames() (names []string, err error)
GetNetworkAddressSets() (AddressSets []api.NetworkAddressSet, err error)
GetNetworkAddressSetsAllProjects() (AddressSets []api.NetworkAddressSet, err error)
GetNetworkAddressSet(name string) (AddressSet *api.NetworkAddressSet, ETag string, err error)
CreateNetworkAddressSet(AddressSet api.NetworkAddressSetsPost) (err error)
UpdateNetworkAddressSet(name string, AddressSet api.NetworkAddressSetPut, ETag string) (err error)
RenameNetworkAddressSet(name string, AddressSet api.NetworkAddressSetPost) (err error)
DeleteNetworkAddressSet(name string) (err error)

// Network allocations functions ("network_allocations" API extension)
GetNetworkAllocations() (allocations []api.NetworkAllocations, err error)
GetNetworkAllocationsAllProjects() (allocations []api.NetworkAllocations, err error)
Expand Down
63 changes: 63 additions & 0 deletions cmd/incus/completion.go
Original file line number Diff line number Diff line change
Expand Up @@ -501,6 +501,69 @@ func (g *cmdGlobal) cmpNetworkACLRuleProperties() ([]string, cobra.ShellCompDire
return results, cobra.ShellCompDirectiveNoSpace
}

func (g *cmdGlobal) cmpNetworkAddressSets(toComplete string) ([]string, cobra.ShellCompDirective) {
results := []string{}
cmpDirectives := cobra.ShellCompDirectiveNoFileComp

resources, _ := g.parseServers(toComplete)

if len(resources) <= 0 {
return nil, cobra.ShellCompDirectiveError
}

resource := resources[0]

// Get the network address set names from the server.
addrSets, err := resource.server.GetNetworkAddressSetNames()
if err != nil {
return nil, cobra.ShellCompDirectiveError
}

for _, addrSet := range addrSets {
var name string
if resource.remote == g.conf.DefaultRemote && !strings.Contains(toComplete, g.conf.DefaultRemote) {
name = addrSet
} else {
name = fmt.Sprintf("%s:%s", resource.remote, addrSet)
}

results = append(results, name)
}

// Also suggest remotes if no ":" in toComplete.
if !strings.Contains(toComplete, ":") {
remotes, directives := g.cmpRemotes(toComplete, false)
results = append(results, remotes...)
cmpDirectives |= directives
}

return results, cmpDirectives
}

func (g *cmdGlobal) cmpNetworkAddressSetConfigs(addressSetName string) ([]string, cobra.ShellCompDirective) {
// Parse remote
resources, err := g.parseServers(addressSetName)
if err != nil || len(resources) == 0 {
return nil, cobra.ShellCompDirectiveError
}

resource := resources[0]
client := resource.server

// Get the network address set.
addrSet, _, err := client.GetNetworkAddressSet(resource.name)
if err != nil {
return nil, cobra.ShellCompDirectiveError
}

var results []string
for k := range addrSet.Config {
results = append(results, k)
}

return results, cobra.ShellCompDirectiveNoFileComp
}

func (g *cmdGlobal) cmpNetworkForwardConfigs(networkName string, listenAddress string) ([]string, cobra.ShellCompDirective) {
// Parse remote
resources, err := g.parseServers(networkName)
Expand Down
4 changes: 4 additions & 0 deletions cmd/incus/network.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,10 @@ func (c *cmdNetwork) Command() *cobra.Command {
networkACLCmd := cmdNetworkACL{global: c.global}
cmd.AddCommand(networkACLCmd.Command())

// Address set
networkAddressSetCmd := cmdNetworkAddressSet{global: c.global}
cmd.AddCommand(networkAddressSetCmd.Command())

// Forward
networkForwardCmd := cmdNetworkForward{global: c.global}
cmd.AddCommand(networkForwardCmd.Command())
Expand Down
Loading