win-bridge: add support for portMappings capability
If the pluging receives portMappings in runtimeConfig, the pluing will add a NAT policy for each port mapping on the generated endpoints. It enables HostPort usage on Windows with win-bridge. Signed-off-by: Vincent Boulineau <vincent.boulineau@datadoghq.com>
This commit is contained in:
parent
f4332fec59
commit
2d2583ee33
@ -20,10 +20,11 @@ import (
|
||||
"fmt"
|
||||
"net"
|
||||
|
||||
"strings"
|
||||
|
||||
"github.com/Microsoft/hcsshim/hcn"
|
||||
"github.com/buger/jsonparser"
|
||||
"github.com/containernetworking/cni/pkg/types"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// NetConf is the CNI spec
|
||||
@ -46,8 +47,16 @@ type RuntimeDNS struct {
|
||||
Search []string `json:"searches,omitempty"`
|
||||
}
|
||||
|
||||
type PortMapEntry struct {
|
||||
HostPort int `json:"hostPort"`
|
||||
ContainerPort int `json:"containerPort"`
|
||||
Protocol string `json:"protocol"`
|
||||
HostIP string `json:"hostIP,omitempty"`
|
||||
}
|
||||
|
||||
type RuntimeConfig struct {
|
||||
DNS RuntimeDNS `json:"dns"`
|
||||
DNS RuntimeDNS `json:"dns"`
|
||||
PortMaps []PortMapEntry `json:"portMappings,omitempty"`
|
||||
}
|
||||
|
||||
type policy struct {
|
||||
@ -207,3 +216,21 @@ func (n *NetConf) ApplyDefaultPAPolicy(paAddress string) {
|
||||
Value: []byte(`{"Type": "PA", "PA": "` + paAddress + `"}`),
|
||||
})
|
||||
}
|
||||
|
||||
// ApplyPortMappingPolicy is used to configure HostPort<>ContainerPort mapping in HNS
|
||||
func (n *NetConf) ApplyPortMappingPolicy(portMappings []PortMapEntry) {
|
||||
if portMappings == nil {
|
||||
return
|
||||
}
|
||||
|
||||
if n.Policies == nil {
|
||||
n.Policies = make([]policy, 0)
|
||||
}
|
||||
|
||||
for _, portMapping := range portMappings {
|
||||
n.Policies = append(n.Policies, policy{
|
||||
Name: "EndpointPolicy",
|
||||
Value: []byte(fmt.Sprintf(`{"Type": "NAT", "InternalPort": %d, "ExternalPort": %d, "Protocol": "%s"}`, portMapping.ContainerPort, portMapping.HostPort, portMapping.Protocol)),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -128,6 +128,53 @@ var _ = Describe("HNS NetConf", func() {
|
||||
})
|
||||
})
|
||||
|
||||
Describe("ApplyPortMappingPolicy", func() {
|
||||
Context("when portMappings not activated", func() {
|
||||
It("does nothing", func() {
|
||||
n := NetConf{}
|
||||
n.ApplyPortMappingPolicy(nil)
|
||||
Expect(n.Policies).Should(BeNil())
|
||||
|
||||
n.ApplyPortMappingPolicy([]PortMapEntry{})
|
||||
Expect(n.Policies).Should(HaveLen(0))
|
||||
})
|
||||
})
|
||||
|
||||
Context("when portMappings is activated", func() {
|
||||
It("creates NAT policies", func() {
|
||||
n := NetConf{}
|
||||
n.ApplyPortMappingPolicy([]PortMapEntry{
|
||||
{
|
||||
ContainerPort: 80,
|
||||
HostPort: 8080,
|
||||
Protocol: "TCP",
|
||||
HostIP: "ignored",
|
||||
},
|
||||
})
|
||||
|
||||
Expect(n.Policies).Should(HaveLen(1))
|
||||
|
||||
policy := n.Policies[0]
|
||||
Expect(policy.Name).Should(Equal("EndpointPolicy"))
|
||||
|
||||
value := make(map[string]interface{})
|
||||
json.Unmarshal(policy.Value, &value)
|
||||
|
||||
Expect(value).Should(HaveKey("Type"))
|
||||
Expect(value["Type"]).Should(Equal("NAT"))
|
||||
|
||||
Expect(value).Should(HaveKey("InternalPort"))
|
||||
Expect(value["InternalPort"]).Should(Equal(float64(80)))
|
||||
|
||||
Expect(value).Should(HaveKey("ExternalPort"))
|
||||
Expect(value["ExternalPort"]).Should(Equal(float64(8080)))
|
||||
|
||||
Expect(value).Should(HaveKey("Protocol"))
|
||||
Expect(value["Protocol"]).Should(Equal("TCP"))
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
Describe("MarshalPolicies", func() {
|
||||
Context("when not set by user", func() {
|
||||
It("sets it by adding a policy", func() {
|
||||
|
@ -35,7 +35,8 @@ With win-bridge plugin, all containers (on the same host) are plugged into an L2
|
||||
],
|
||||
"loopbackDSR": true,
|
||||
"capabilities": {
|
||||
"dns": true
|
||||
"dns": true,
|
||||
"portMappings": true
|
||||
}
|
||||
}
|
||||
```
|
||||
@ -54,4 +55,5 @@ With win-bridge plugin, all containers (on the same host) are plugged into an L2
|
||||
* `HcnPolicyArgs` (list, optional): List of hcn policies to be used (only used when ApiVersion is 2).
|
||||
* `loopbackDSR` (bool, optional): If true, will add a policy to allow the interface to support loopback direct server return.
|
||||
* `capabilities` (dictionary, optional): Runtime capabilities to enable.
|
||||
* `dns` (boolean, optional): If true, will take the dns config supplied by the runtime and override other settings.
|
||||
* `dns` (boolean, optional): If true, will take the dns config supplied by the runtime and override other settings.
|
||||
* `portMappings` (boolean, optional): If true, will handle HostPort<>ContainerPort mapping using NAT HNS Policies
|
@ -86,6 +86,9 @@ func ProcessEndpointArgs(args *skel.CmdArgs, n *NetConf) (*hns.EndpointInfo, err
|
||||
n.ApplyOutboundNatPolicy(n.IPMasqNetwork)
|
||||
}
|
||||
|
||||
// Add HostPort mapping if any present
|
||||
n.ApplyPortMappingPolicy(n.RuntimeConfig.PortMaps)
|
||||
|
||||
epInfo.DNS = n.GetDNS()
|
||||
|
||||
return epInfo, nil
|
||||
@ -107,7 +110,6 @@ func cmdHnsAdd(args *skel.CmdArgs, n *NetConf) (*current.Result, error) {
|
||||
}
|
||||
|
||||
epName := hns.ConstructEndpointName(args.ContainerID, args.Netns, n.Name)
|
||||
|
||||
hnsEndpoint, err := hns.ProvisionEndpoint(epName, hnsNetwork.Id, args.ContainerID, args.Netns, func() (*hcsshim.HNSEndpoint, error) {
|
||||
epInfo, err := ProcessEndpointArgs(args, n)
|
||||
epInfo.NetworkId = hnsNetwork.Id
|
||||
@ -130,7 +132,6 @@ func cmdHnsAdd(args *skel.CmdArgs, n *NetConf) (*current.Result, error) {
|
||||
}
|
||||
|
||||
return result, nil
|
||||
|
||||
}
|
||||
|
||||
func cmdHcnAdd(args *skel.CmdArgs, n *NetConf) (*current.Result, error) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user