diff --git a/Documentation/ptp.md b/Documentation/ptp.md index acde8515..a7867109 100644 --- a/Documentation/ptp.md +++ b/Documentation/ptp.md @@ -15,10 +15,9 @@ The traffic of the container interface will be routed through the interface of t "type": "host-local", "subnet": "10.1.1.0/24" }, - "dns": [ - "8.8.8.8", - "8.8.4.4" - ] + "dns": { + "nameservers": [ "10.1.1.1", "8.8.8.8" ] + } } ## Network configuration reference @@ -28,4 +27,4 @@ The traffic of the container interface will be routed through the interface of t * `ipMasq` (boolean, optional): set up IP Masquerade on the host for traffic originating from this network and destined outside of it. Defaults to false. * `mtu` (integer, optional): explicitly set MTU to the specified value. Defaults to value chosen by the kernel. * `ipam` (dictionary, required): IPAM configuration to be used for this network. -* `dns` (string array, optional): name servers to return as is in the [Result](/SPEC.md#result). Defaults to empty list. +* `dns` (dictionary, optional): DNS information to return as described in the [Result](/SPEC.md#result). diff --git a/SPEC.md b/SPEC.md index 71ac15f7..f71e7a6b 100644 --- a/SPEC.md +++ b/SPEC.md @@ -50,7 +50,7 @@ The operations that the CNI plugin needs to support are: - **Name of the interface inside the container**. This is the name that should be assigned to the interface created inside the container (network namespace); consequently it must comply with the standard Linux restrictions on interface names. - Result: - **IPs assigned to the interface**. This is either an IPv4 address, an IPv6 address, or both. - - **List of DNS nameservers**. This is a priority-ordered list of IPv4 and IPv6 addresses of DNS nameservers. + - **DNS information**. Dictionary that includes DNS information for nameservers, domain, search domains and options. - Delete container from network - Parameters: @@ -91,16 +91,20 @@ Success is indicated by a return code of zero and the following JSON printed to "gateway": , (optional) "routes": (optional) }, - "dns": (optional) + "dns": { + "nameservers": (optional) + "domain": (optional) + "search": (optional) + "options": (optional) + } } ``` `cniVersion` specifies a [Semantic Version 2.0](http://semver.org) of CNI specification used by the plugin. -The "dns" field contains a list of a priority-ordered list of DNS nameservers that this network is aware of. -Each entry in the list is a string containing either an IPv4 or an IPv6 address. -Typically this value would just be the value returned by the IPAM plugin. -It is outside the scope of this specification how the container runtime uses the list of DNS nameservers from each of the networks to provide name resolution services to the container. -Examples of how this list could be used include generating an `/etc/resolv.conf` file to be injected into the container filesystem or running a DNS forwarder on the host. +`dns` field contains a dictionary consisting of common DNS information that this network is aware of. +The result is returned in the same format as specified in the [configuration](#network-configuration). +The specification does not declare how this information must be processed by CNI consumers. +Examples include generating an `/etc/resolv.conf` file to be injected into the container filesystem or running a DNS forwarder on the host. Errors are indicated by a non-zero return code and the following JSON being printed to stdout: ``` @@ -130,6 +134,11 @@ The network configuration is described in JSON form. The configuration can be st - `routes` (list): List of subnets (in CIDR notation) that the CNI plugin should ensure are reachable by routing them through the network. Each entry is a dictionary containing: - `dst` (string): subnet in CIDR notation - `gw` (string): IP address of the gateway to use. If not specified, the default gateway for the subnet is assumed (as determined by the IPAM plugin). +- `dns`: Dictionary with DNS specific values: + - `nameservers` (list of strings): list of a priority-ordered list of DNS nameservers that this network is aware of. Each entry in the list is a string containing either an IPv4 or an IPv6 address. + - `domain` (string): the local domain used for short hostname lookups. + - `search` (list of strings): list of priority ordered search domains for short hostname lookups. Will be preferred over `domain` by most resolvers. + - `options` (list of strings): list of options that can be passed to the resolver ### Example configurations @@ -145,6 +154,9 @@ The network configuration is described in JSON form. The configuration can be st // ipam specific "subnet": "10.1.0.0/16", "gateway": "10.1.0.1" + }, + "dns": { + "nameservers": [ "10.1.0.1" ] } } ``` @@ -173,6 +185,9 @@ The network configuration is described in JSON form. The configuration can be st "ipam": { "type": "dhcp", "routes": [ { "dst": "10.0.0.0/8", "gw": "10.0.0.1" } ] + }, + "dns": { + "nameservers": [ "10.0.0.1" ] } } ``` @@ -203,7 +218,12 @@ Success is indicated by a zero return code and the following JSON being printed "gateway": , (optional) "routes": (optional) }, - "dns": (optional) + "dns": { + "nameservers": (optional) + "domain": (optional) + "search": (optional) + "options": (optional) + } } ``` @@ -216,9 +236,12 @@ Each route entry is a dictionary with the following fields: - `dst` (string): Destination subnet specified in CIDR notation. - `gw` (string): IP of the gateway. If omitted, a default gateway is assumed (as determined by the CNI plugin). -The "dns" field contains a list of a priority-ordered list of DNS nameservers that this network is aware of. -Each entry in the list is a string containing either an IPv4 or an IPv6 address. -See [CNI Plugin Result](#result) section for details. +The "dns" field contains a dictionary consisting of common DNS information. +- `nameservers` (list of strings): list of a priority-ordered list of DNS nameservers that this network is aware of. Each entry in the list is a string containing either an IPv4 or an IPv6 address. +- `domain` (string): the local domain used for short hostname lookups. +- `search` (list of strings): list of priority ordered search domains for short hostname lookups. Will be preferred over `domain` by most resolvers. +- `options` (list of strings): list of options that can be passed to the resolver +See [CNI Plugin Result](#result) section for more information. Errors and logs are communicated in the same way as the CNI plugin. See [CNI Plugin Result](#result) section for details. diff --git a/pkg/types/types.go b/pkg/types/types.go index e5558be4..6ae4a644 100644 --- a/pkg/types/types.go +++ b/pkg/types/types.go @@ -61,13 +61,14 @@ type NetConf struct { IPAM struct { Type string `json:"type,omitempty"` } `json:"ipam,omitempty"` + DNS DNS `json:"dns"` } // Result is what gets returned from the plugin (via stdout) to the caller type Result struct { IP4 *IPConfig `json:"ip4,omitempty"` IP6 *IPConfig `json:"ip6,omitempty"` - DNS []string `json:"dns,omitempty"` + DNS DNS `json:"dns,omitempty"` } func (r *Result) Print() error { @@ -81,6 +82,14 @@ type IPConfig struct { Routes []Route } +// DNS contains values interesting for DNS resolvers +type DNS struct { + Nameservers []string `json:"nameservers,omitempty"` + Domain string `json:"domain,omitempty"` + Search []string `json:"search,omitempty"` + Options []string `json:"options,omitempty"` +} + type Route struct { Dst net.IPNet GW net.IP diff --git a/plugins/main/bridge/bridge.go b/plugins/main/bridge/bridge.go index c4d8594d..49c0aa5d 100644 --- a/plugins/main/bridge/bridge.go +++ b/plugins/main/bridge/bridge.go @@ -35,11 +35,10 @@ const defaultBrName = "cni0" type NetConf struct { types.NetConf - BrName string `json:"bridge"` - IsGW bool `json:"isGateway"` - IPMasq bool `json:"ipMasq"` - MTU int `json:"mtu"` - DNS []string `json:"dns"` + BrName string `json:"bridge"` + IsGW bool `json:"isGateway"` + IPMasq bool `json:"ipMasq"` + MTU int `json:"mtu"` } func init() { diff --git a/plugins/main/ipvlan/ipvlan.go b/plugins/main/ipvlan/ipvlan.go index 36977356..85919772 100644 --- a/plugins/main/ipvlan/ipvlan.go +++ b/plugins/main/ipvlan/ipvlan.go @@ -31,10 +31,9 @@ import ( type NetConf struct { types.NetConf - Master string `json:"master"` - Mode string `json:"mode"` - MTU int `json:"mtu"` - DNS []string `json:"dns"` + Master string `json:"master"` + Mode string `json:"mode"` + MTU int `json:"mtu"` } func init() { diff --git a/plugins/main/macvlan/macvlan.go b/plugins/main/macvlan/macvlan.go index 812d91f4..f6891a34 100644 --- a/plugins/main/macvlan/macvlan.go +++ b/plugins/main/macvlan/macvlan.go @@ -31,10 +31,9 @@ import ( type NetConf struct { types.NetConf - Master string `json:"master"` - Mode string `json:"mode"` - MTU int `json:"mtu"` - DNS []string `json:"dns"` + Master string `json:"master"` + Mode string `json:"mode"` + MTU int `json:"mtu"` } func init() { diff --git a/plugins/main/ptp/ptp.go b/plugins/main/ptp/ptp.go index a51b42fc..3cb8f643 100644 --- a/plugins/main/ptp/ptp.go +++ b/plugins/main/ptp/ptp.go @@ -41,9 +41,8 @@ func init() { type NetConf struct { types.NetConf - IPMasq bool `json:"ipMasq"` - MTU int `json:"mtu"` - DNS []string `json:"dns"` + IPMasq bool `json:"ipMasq"` + MTU int `json:"mtu"` } func setupContainerVeth(netns, ifName string, mtu int, pr *types.Result) (string, error) {