Skip to content

Commit

Permalink
network: add support for podman network update and --network-dns-server
Browse files Browse the repository at this point in the history
* Add support for `podman network update <>`

```console
network update

Description:
  update networks for containers and pods

Usage:
  podman network update [options] [NAME]

Examples:
  podman network update podman1

Options:
      --add-dns-servers stringArray      add network level nameservers
      --remove-dns-servers stringArray   remove network level nameservers
```

* Add support for `--network-dns-server` to `podman network create`

Extends podman to support recently added features in `netavark` and
`aardvark-dns`

* containers/netavark#497
* containers/aardvark-dns#252
* containers/netavark#503

[NO NEW TESTS NEEDED]
[NO TESTS NEEDED]

Signed-off-by: Aditya R <arajan@redhat.com>
  • Loading branch information
flouthoc committed Dec 11, 2022
1 parent 6f1bc98 commit ceb5943
Show file tree
Hide file tree
Showing 23 changed files with 361 additions and 49 deletions.
19 changes: 12 additions & 7 deletions cmd/podman/networks/create.go
Expand Up @@ -78,6 +78,10 @@ func networkCreateFlags(cmd *cobra.Command) {
_ = cmd.RegisterFlagCompletionFunc(subnetFlagName, completion.AutocompleteNone)

flags.BoolVar(&networkCreateOptions.DisableDNS, "disable-dns", false, "disable dns plugin")

dnsserverFlagName := "network-dns-servers"
flags.StringArrayVar(&networkCreateOptions.NetworkDNSServers, dnsserverFlagName, nil, "network level nameservers")
_ = cmd.RegisterFlagCompletionFunc(dnsserverFlagName, completion.AutocompleteNone)
}
func init() {
registry.Commands = append(registry.Commands, registry.CliCommand{
Expand Down Expand Up @@ -105,13 +109,14 @@ func networkCreate(cmd *cobra.Command, args []string) error {
}

network := types.Network{
Name: name,
Driver: networkCreateOptions.Driver,
Options: networkCreateOptions.Options,
Labels: networkCreateOptions.Labels,
IPv6Enabled: networkCreateOptions.IPv6,
DNSEnabled: !networkCreateOptions.DisableDNS,
Internal: networkCreateOptions.Internal,
Name: name,
Driver: networkCreateOptions.Driver,
Options: networkCreateOptions.Options,
Labels: networkCreateOptions.Labels,
IPv6Enabled: networkCreateOptions.IPv6,
DNSEnabled: !networkCreateOptions.DisableDNS,
NetworkDNSServers: networkCreateOptions.NetworkDNSServers,
Internal: networkCreateOptions.Internal,
}

if cmd.Flags().Changed(ipamDriverFlagName) {
Expand Down
58 changes: 58 additions & 0 deletions cmd/podman/networks/update.go
@@ -0,0 +1,58 @@
package network

import (
"github.com/containers/common/pkg/completion"
"github.com/containers/podman/v4/cmd/podman/registry"
"github.com/containers/podman/v4/pkg/domain/entities"
"github.com/spf13/cobra"
)

var (
networkUpdateDescription = `Update an existing podman network`
networkUpdateCommand = &cobra.Command{
Use: "update [options] [NAME]",
Short: "update an existing podman network",
Long: networkUpdateDescription,
RunE: networkUpdate,
Args: cobra.MaximumNArgs(1),
ValidArgsFunction: completion.AutocompleteNone,
Example: `podman network update podman1`,
}
)

var (
networkUpdateOptions entities.NetworkUpdateOptions
)

func networkUpdateFlags(cmd *cobra.Command) {
flags := cmd.Flags()

addDNSServerFlagName := "add-dns-servers"
flags.StringArrayVar(&networkUpdateOptions.AddDNSServers, addDNSServerFlagName, nil, "add network level nameservers")
removeDNSServerFlagName := "remove-dns-servers"
flags.StringArrayVar(&networkUpdateOptions.RemoveDNSServers, removeDNSServerFlagName, nil, "remove network level nameservers")
_ = cmd.RegisterFlagCompletionFunc(addDNSServerFlagName, completion.AutocompleteNone)
_ = cmd.RegisterFlagCompletionFunc(removeDNSServerFlagName, completion.AutocompleteNone)
}
func init() {
registry.Commands = append(registry.Commands, registry.CliCommand{
Command: networkUpdateCommand,
Parent: networkCmd,
})
networkUpdateFlags(networkUpdateCommand)
}

func networkUpdate(cmd *cobra.Command, args []string) error {
var (
name string
)
if len(args) > 0 {
name = args[0]
}

err := registry.ContainerEngine().NetworkUpdate(registry.Context(), name, networkUpdateOptions)
if err != nil {
return err
}
return nil
}
4 changes: 4 additions & 0 deletions docs/source/markdown/podman-network-create.1.md
Expand Up @@ -68,6 +68,10 @@ Enable IPv6 (Dual Stack) networking. If not subnets are given it will allocate a

Set metadata for a network (e.g., --label mykey=value).

#### **--network-dns-servers**

Set network scoped DNS resolver/nameserver.

#### **--opt**, **-o**=*option*

Set driver specific options.
Expand Down
25 changes: 25 additions & 0 deletions docs/source/markdown/podman-network-update.1.md
@@ -0,0 +1,25 @@
% podman-network-update 1

## NAME
podman\-network-update - Update an existing podman network

## SYNOPSIS
**podman network update** [*options*] [*name*]

## DESCRIPTION
Allows end users to update network scoped DNS resolvers for an existing podman network.

NOTE: Only supported with netavark and aardvark-dns


## OPTIONS
#### **--add-dns-servers**

Accepts array of DNS resolvers and add it to the existing list of resolvers configured for a network.

#### **--remove-dns-servers**

Accepts array of DNS resolvers and removes them from the existing list of resolvers configured for a network.

## SEE ALSO
**[podman(1)](podman.1.md)**, **[podman-network(1)](podman-network.1.md)**, **[podman-network-inspect(1)](podman-network-inspect.1.md)**, **[podman-network-ls(1)](podman-network-ls.1.md)**
1 change: 1 addition & 0 deletions docs/source/markdown/podman-network.1.md
Expand Up @@ -32,6 +32,7 @@ so networks have to be created again after a backend change.
| prune | [podman-network-prune(1)](podman-network-prune.1.md) | Remove all unused networks |
| reload | [podman-network-reload(1)](podman-network-reload.1.md) | Reload network configuration for containers |
| rm | [podman-network-rm(1)](podman-network-rm.1.md) | Remove one or more networks |
| update | [podman-network-upate(1)](podman-network-update.1.md) | Update an existing podman network |

## SEE ALSO
**[podman(1)](podman.1.md)**, **[containers.conf(5)](https://github.com/containers/common/blob/main/docs/containers.conf.5.md)**
4 changes: 3 additions & 1 deletion go.mod
Expand Up @@ -63,7 +63,7 @@ require (
golang.org/x/net v0.2.0
golang.org/x/sync v0.1.0
golang.org/x/sys v0.3.0
golang.org/x/term v0.2.0
golang.org/x/term v0.3.0
golang.org/x/text v0.4.0
google.golang.org/protobuf v1.28.1
gopkg.in/inf.v0 v0.9.1
Expand Down Expand Up @@ -144,3 +144,5 @@ require (
)

replace github.com/opencontainers/runc => github.com/opencontainers/runc v1.1.1-0.20220617142545-8b9452f75cbc

replace github.com/containers/common => github.com/containers/common v0.50.2-0.20221207134111-abc80e8869fe
8 changes: 4 additions & 4 deletions go.sum
Expand Up @@ -264,8 +264,8 @@ github.com/containernetworking/plugins v1.1.1 h1:+AGfFigZ5TiQH00vhR8qPeSatj53eNG
github.com/containernetworking/plugins v1.1.1/go.mod h1:Sr5TH/eBsGLXK/h71HeLfX19sZPp3ry5uHSkI4LPxV8=
github.com/containers/buildah v1.28.1-0.20221130132810-cf661299d14f h1:Nzbda2tG7/aimoKnDxysqFgS1Q/gSsbcn88lFPj9LwY=
github.com/containers/buildah v1.28.1-0.20221130132810-cf661299d14f/go.mod h1:0HcSoS6BHXWzMKqtxY1L0gupebEX33oPC+X62lPi6+c=
github.com/containers/common v0.50.2-0.20221206110749-eb48ebbf8ca9 h1:L54LXA/DGRhp1cDN11HLaXcLCYh/ftqDhKYn9S1uetc=
github.com/containers/common v0.50.2-0.20221206110749-eb48ebbf8ca9/go.mod h1:M1epBsHlUAeySDuMx+HdbvKBVf0odzLciecS5AQa6FA=
github.com/containers/common v0.50.2-0.20221207134111-abc80e8869fe h1:er1CQTQUGGpRJtRK4YfBlDho6vQqkmqjuDUyHrr1aU8=
github.com/containers/common v0.50.2-0.20221207134111-abc80e8869fe/go.mod h1:3HqwsTTisTe3cGGFP5T60AI/+//PaiViD60szELRyxI=
github.com/containers/conmon v2.0.20+incompatible h1:YbCVSFSCqFjjVwHTPINGdMX1F6JXHGTUje2ZYobNrkg=
github.com/containers/conmon v2.0.20+incompatible/go.mod h1:hgwZ2mtuDrppv78a/cOBNiCm6O0UMWGx1mu7P00nu5I=
github.com/containers/image/v5 v5.23.1-0.20221130170538-333c50e3eac8 h1:GLTTwKYkNGDhG3HagLuPvhieu1JEjDs9RsCDr8oJr9s=
Expand Down Expand Up @@ -1236,8 +1236,8 @@ golang.org/x/sys v0.3.0 h1:w8ZOecv6NaNa/zC8944JTU3vz4u6Lagfk4RPQxv92NQ=
golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.2.0 h1:z85xZCsEl7bi/KwbNADeBYoOP0++7W1ipu+aGnpwzRM=
golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
golang.org/x/term v0.3.0 h1:qoo4akIqOcDME5bhc/NgxUdovd6BSS2uMsVjB56q1xI=
golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
Expand Down
25 changes: 25 additions & 0 deletions pkg/api/handlers/libpod/networks.go
Expand Up @@ -44,6 +44,31 @@ func CreateNetwork(w http.ResponseWriter, r *http.Request) {
utils.WriteResponse(w, http.StatusOK, report)
}

func UpdateNetwork(w http.ResponseWriter, r *http.Request) {
if v, err := utils.SupportedVersion(r, ">=4.0.0"); err != nil {
utils.BadRequest(w, "version", v.String(), err)
return
}

runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime)
ic := abi.ContainerEngine{Libpod: runtime}

networkUpdateOptions := entities.NetworkUpdateOptions{}
if err := json.NewDecoder(r.Body).Decode(&networkUpdateOptions); err != nil {
utils.Error(w, http.StatusInternalServerError, fmt.Errorf("failed to decode request JSON payload: %w", err))
return
}

name := utils.GetName(r)

err := ic.NetworkUpdate(r.Context(), name, networkUpdateOptions)
if err != nil {
utils.Error(w, http.StatusInternalServerError, err)
}

utils.WriteResponse(w, http.StatusNoContent, nil)
}

func ListNetworks(w http.ResponseWriter, r *http.Request) {
if v, err := utils.SupportedVersion(r, ">=4.0.0"); err != nil {
utils.BadRequest(w, "version", v.String(), err)
Expand Down
4 changes: 4 additions & 0 deletions pkg/api/handlers/swagger/models.go
Expand Up @@ -44,3 +44,7 @@ type networkDisconnectRequest types.NetworkDisconnect
// Network connect
// swagger:model
type networkConnectRequestLibpod entities.NetworkConnectOptions

// Network update
// swagger:model
type networkUpdateRequestLibpod entities.NetworkUpdateOptions
27 changes: 27 additions & 0 deletions pkg/api/server/register_networks.go
Expand Up @@ -234,6 +234,33 @@ func (s *APIServer) registerNetworkHandlers(r *mux.Router) error {
// 500:
// $ref: "#/responses/internalError"
r.HandleFunc(VersionedPath("/libpod/networks/{name}"), s.APIHandler(libpod.RemoveNetwork)).Methods(http.MethodDelete)
// swagger:operation POST /libpod/networks/{name}/update libpod NetworkUpdateLibpod
// ---
// tags:
// - networks
// summary: Update exisiting podman network
// description: Update exisiting podman network
// produces:
// - application/json
// parameters:
// - in: path
// name: name
// type: string
// required: true
// description: the name of the network
// - in: body
// name: update
// description: attributes for updating a netavark network
// schema:
// $ref: "#/definitions/networkUpdateRequestLibpod"
// responses:
// 200:
// description: OK
// 400:
// $ref: "#/responses/badParamError"
// 500:
// $ref: "#/responses/internalError"
r.HandleFunc(VersionedPath("/libpod/networks/{name}/update"), s.APIHandler(libpod.UpdateNetwork)).Methods(http.MethodPost)
// swagger:operation GET /libpod/networks/{name}/exists libpod NetworkExistsLibpod
// ---
// tags:
Expand Down
19 changes: 19 additions & 0 deletions pkg/bindings/network/network.go
Expand Up @@ -36,6 +36,25 @@ func Create(ctx context.Context, network *types.Network) (types.Network, error)
return report, response.Process(&report)
}

// Updates an existing netavark network config
func Update(ctx context.Context, netName string, options entities.NetworkUpdateOptions) error {
conn, err := bindings.GetClient(ctx)
if err != nil {
return err
}
networkConfig, err := jsoniter.MarshalToString(options)
if err != nil {
return err
}
reader := strings.NewReader(networkConfig)
response, err := conn.DoRequest(ctx, reader, http.MethodPost, "/networks/%s/update", nil, nil, netName)
if err != nil {
return err
}
defer response.Body.Close()
return response.Process(nil)
}

// Inspect returns low level information about a CNI network configuration
func Inspect(ctx context.Context, nameOrID string, _ *InspectOptions) (types.Network, error) {
var net types.Network
Expand Down
1 change: 1 addition & 0 deletions pkg/domain/entities/engine_container.go
Expand Up @@ -64,6 +64,7 @@ type ContainerEngine interface { //nolint:interfacebloat
KubeApply(ctx context.Context, body io.Reader, opts ApplyOptions) error
NetworkConnect(ctx context.Context, networkname string, options NetworkConnectOptions) error
NetworkCreate(ctx context.Context, network types.Network) (*types.Network, error)
NetworkUpdate(ctx context.Context, networkname string, options NetworkUpdateOptions) error
NetworkDisconnect(ctx context.Context, networkname string, options NetworkDisconnectOptions) error
NetworkExists(ctx context.Context, networkname string) (*BoolReport, error)
NetworkInspect(ctx context.Context, namesOrIds []string, options InspectOptions) ([]types.Network, []error, error)
Expand Down
25 changes: 16 additions & 9 deletions pkg/domain/entities/network.go
Expand Up @@ -41,19 +41,26 @@ type NetworkRmReport struct {

// NetworkCreateOptions describes options to create a network
type NetworkCreateOptions struct {
DisableDNS bool
Driver string
Gateways []net.IP
Internal bool
Labels map[string]string
MacVLAN string
Ranges []string
Subnets []string
IPv6 bool
DisableDNS bool
NetworkDNSServers []string
Driver string
Gateways []net.IP
Internal bool
Labels map[string]string
MacVLAN string
Ranges []string
Subnets []string
IPv6 bool
// Mapping of driver options and values.
Options map[string]string
}

// NetworkUpdateOptions describes options to update a network
type NetworkUpdateOptions struct {
AddDNSServers []string `json:"adddnsservers"`
RemoveDNSServers []string `json:"removednsservers"`
}

// NetworkCreateReport describes a created network for the cli
type NetworkCreateReport struct {
Name string
Expand Down
11 changes: 11 additions & 0 deletions pkg/domain/infra/abi/network.go
Expand Up @@ -13,6 +13,17 @@ import (
"github.com/containers/podman/v4/pkg/domain/entities"
)

func (ic *ContainerEngine) NetworkUpdate(ctx context.Context, netName string, options entities.NetworkUpdateOptions) error {
var networkUpdateOptions types.NetworkUpdateOptions
networkUpdateOptions.AddDNSServers = options.AddDNSServers
networkUpdateOptions.RemoveDNSServers = options.RemoveDNSServers
err := ic.Libpod.Network().NetworkUpdate(netName, networkUpdateOptions)
if err != nil {
return err
}
return nil
}

func (ic *ContainerEngine) NetworkList(ctx context.Context, options entities.NetworkListOptions) ([]types.Network, error) {
// dangling filter is not provided by netutil
var wantDangling bool
Expand Down
4 changes: 4 additions & 0 deletions pkg/domain/infra/tunnel/network.go
Expand Up @@ -12,6 +12,10 @@ import (
"github.com/containers/podman/v4/pkg/errorhandling"
)

func (ic *ContainerEngine) NetworkUpdate(ctx context.Context, netName string, options entities.NetworkUpdateOptions) error {
return network.Update(ic.ClientCtx, netName, options)
}

func (ic *ContainerEngine) NetworkList(ctx context.Context, opts entities.NetworkListOptions) ([]types.Network, error) {
options := new(network.ListOptions).WithFilters(opts.Filters)
return network.List(ic.ClientCtx, options)
Expand Down

0 comments on commit ceb5943

Please sign in to comment.