1
0
Fork 0
mirror of https://github.com/moby/moby.git synced 2022-11-09 12:21:53 -05:00

Merge pull request #1900 from pradipd/overlay_one_endpoint

Tasks connected to a swarm network will have 1 endpoint on windows RS3.
This commit is contained in:
Flavio Crisciani 2017-08-28 09:22:28 -07:00 committed by GitHub
commit a0bdc52fd7
6 changed files with 94 additions and 35 deletions

View file

@ -39,6 +39,11 @@ func (d *driver) Join(nid, eid string, sboxKey string, jinfo driverapi.JoinInfo,
if err := jinfo.AddTableEntry(ovPeerTable, eid, buf); err != nil { if err := jinfo.AddTableEntry(ovPeerTable, eid, buf); err != nil {
logrus.Errorf("overlay: Failed adding table entry to joininfo: %v", err) logrus.Errorf("overlay: Failed adding table entry to joininfo: %v", err)
} }
if ep.disablegateway {
jinfo.DisableGatewayService()
}
return nil return nil
} }

View file

@ -6,7 +6,11 @@ import (
"net" "net"
"github.com/Microsoft/hcsshim" "github.com/Microsoft/hcsshim"
"github.com/docker/docker/pkg/system"
"github.com/docker/libnetwork/driverapi" "github.com/docker/libnetwork/driverapi"
"github.com/docker/libnetwork/drivers/windows"
"github.com/docker/libnetwork/netlabel"
"github.com/docker/libnetwork/types"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
) )
@ -15,12 +19,14 @@ type endpointTable map[string]*endpoint
const overlayEndpointPrefix = "overlay/endpoint" const overlayEndpointPrefix = "overlay/endpoint"
type endpoint struct { type endpoint struct {
id string id string
nid string nid string
profileId string profileID string
remote bool remote bool
mac net.HardwareAddr mac net.HardwareAddr
addr *net.IPNet addr *net.IPNet
disablegateway bool
portMapping []types.PortBinding // Operation port bindings
} }
func validateID(nid, eid string) error { func validateID(nid, eid string) error {
@ -71,7 +77,7 @@ func (n *network) removeEndpointWithAddress(addr *net.IPNet) {
if networkEndpoint != nil { if networkEndpoint != nil {
logrus.Debugf("Removing stale endpoint from HNS") logrus.Debugf("Removing stale endpoint from HNS")
_, err := hcsshim.HNSEndpointRequest("DELETE", networkEndpoint.profileId, "") _, err := hcsshim.HNSEndpointRequest("DELETE", networkEndpoint.profileID, "")
if err != nil { if err != nil {
logrus.Debugf("Failed to delete stale overlay endpoint (%s) from hns", networkEndpoint.id[0:7]) logrus.Debugf("Failed to delete stale overlay endpoint (%s) from hns", networkEndpoint.id[0:7])
@ -96,7 +102,7 @@ func (d *driver) CreateEndpoint(nid, eid string, ifInfo driverapi.InterfaceInfo,
logrus.Debugf("Deleting stale endpoint %s", eid) logrus.Debugf("Deleting stale endpoint %s", eid)
n.deleteEndpoint(eid) n.deleteEndpoint(eid)
_, err := hcsshim.HNSEndpointRequest("DELETE", ep.profileId, "") _, err := hcsshim.HNSEndpointRequest("DELETE", ep.profileID, "")
if err != nil { if err != nil {
return err return err
} }
@ -113,17 +119,19 @@ func (d *driver) CreateEndpoint(nid, eid string, ifInfo driverapi.InterfaceInfo,
return fmt.Errorf("create endpoint was not passed interface IP address") return fmt.Errorf("create endpoint was not passed interface IP address")
} }
if s := n.getSubnetforIP(ep.addr); s == nil { s := n.getSubnetforIP(ep.addr)
return fmt.Errorf("no matching subnet for IP %q in network %q\n", ep.addr, nid) if s == nil {
return fmt.Errorf("no matching subnet for IP %q in network %q", ep.addr, nid)
} }
// Todo: Add port bindings and qos policies here // Todo: Add port bindings and qos policies here
hnsEndpoint := &hcsshim.HNSEndpoint{ hnsEndpoint := &hcsshim.HNSEndpoint{
Name: eid, Name: eid,
VirtualNetwork: n.hnsId, VirtualNetwork: n.hnsID,
IPAddress: ep.addr.IP, IPAddress: ep.addr.IP,
EnableInternalDNS: true, EnableInternalDNS: true,
GatewayAddress: s.gwIP.String(),
} }
if ep.mac != nil { if ep.mac != nil {
@ -141,6 +149,31 @@ func (d *driver) CreateEndpoint(nid, eid string, ifInfo driverapi.InterfaceInfo,
hnsEndpoint.Policies = append(hnsEndpoint.Policies, paPolicy) hnsEndpoint.Policies = append(hnsEndpoint.Policies, paPolicy)
if system.GetOSVersion().Build > 16236 {
natPolicy, err := json.Marshal(hcsshim.PaPolicy{
Type: "OutBoundNAT",
})
if err != nil {
return err
}
hnsEndpoint.Policies = append(hnsEndpoint.Policies, natPolicy)
epConnectivity, err := windows.ParseEndpointConnectivity(epOptions)
if err != nil {
return err
}
pbPolicy, err := windows.ConvertPortBindings(epConnectivity.PortBindings)
if err != nil {
return err
}
hnsEndpoint.Policies = append(hnsEndpoint.Policies, pbPolicy...)
ep.disablegateway = true
}
configurationb, err := json.Marshal(hnsEndpoint) configurationb, err := json.Marshal(hnsEndpoint)
if err != nil { if err != nil {
return err return err
@ -151,7 +184,7 @@ func (d *driver) CreateEndpoint(nid, eid string, ifInfo driverapi.InterfaceInfo,
return err return err
} }
ep.profileId = hnsresponse.Id ep.profileID = hnsresponse.Id
if ep.mac == nil { if ep.mac == nil {
ep.mac, err = net.ParseMAC(hnsresponse.MacAddress) ep.mac, err = net.ParseMAC(hnsresponse.MacAddress)
@ -164,6 +197,12 @@ func (d *driver) CreateEndpoint(nid, eid string, ifInfo driverapi.InterfaceInfo,
} }
} }
ep.portMapping, err = windows.ParsePortBindingPolicies(hnsresponse.Policies)
if err != nil {
hcsshim.HNSEndpointRequest("DELETE", hnsresponse.Id, "")
return err
}
n.addEndpoint(ep) n.addEndpoint(ep)
return nil return nil
@ -186,7 +225,7 @@ func (d *driver) DeleteEndpoint(nid, eid string) error {
n.deleteEndpoint(eid) n.deleteEndpoint(eid)
_, err := hcsshim.HNSEndpointRequest("DELETE", ep.profileId, "") _, err := hcsshim.HNSEndpointRequest("DELETE", ep.profileID, "")
if err != nil { if err != nil {
return err return err
} }
@ -210,7 +249,17 @@ func (d *driver) EndpointOperInfo(nid, eid string) (map[string]interface{}, erro
} }
data := make(map[string]interface{}, 1) data := make(map[string]interface{}, 1)
data["hnsid"] = ep.profileId data["hnsid"] = ep.profileID
data["AllowUnqualifiedDNSQuery"] = true data["AllowUnqualifiedDNSQuery"] = true
if ep.portMapping != nil {
// Return a copy of the operational data
pmc := make([]types.PortBinding, 0, len(ep.portMapping))
for _, pm := range ep.portMapping {
pmc = append(pmc, pm.GetCopy())
}
data[netlabel.PortMap] = pmc
}
return data, nil return data, nil
} }

View file

@ -37,7 +37,7 @@ type subnetJSON struct {
type network struct { type network struct {
id string id string
name string name string
hnsId string hnsID string
providerAddress string providerAddress string
interfaceName string interfaceName string
endpoints endpointTable endpoints endpointTable
@ -108,7 +108,7 @@ func (d *driver) CreateNetwork(id string, option map[string]interface{}, nInfo d
case "com.docker.network.windowsshim.interface": case "com.docker.network.windowsshim.interface":
interfaceName = value interfaceName = value
case "com.docker.network.windowsshim.hnsid": case "com.docker.network.windowsshim.hnsid":
n.hnsId = value n.hnsID = value
case netlabel.OverlayVxlanIDList: case netlabel.OverlayVxlanIDList:
vniStrings := strings.Split(value, ",") vniStrings := strings.Split(value, ",")
for _, vniStr := range vniStrings { for _, vniStr := range vniStrings {
@ -181,7 +181,7 @@ func (d *driver) CreateNetwork(id string, option map[string]interface{}, nInfo d
if err != nil { if err != nil {
d.deleteNetwork(id) d.deleteNetwork(id)
} else { } else {
genData["com.docker.network.windowsshim.hnsid"] = n.hnsId genData["com.docker.network.windowsshim.hnsid"] = n.hnsID
} }
return err return err
@ -197,7 +197,7 @@ func (d *driver) DeleteNetwork(nid string) error {
return types.ForbiddenErrorf("could not find network with id %s", nid) return types.ForbiddenErrorf("could not find network with id %s", nid)
} }
_, err := hcsshim.HNSNetworkRequest("DELETE", n.hnsId, "") _, err := hcsshim.HNSNetworkRequest("DELETE", n.hnsID, "")
if err != nil { if err != nil {
return types.ForbiddenErrorf(err.Error()) return types.ForbiddenErrorf(err.Error())
} }
@ -242,7 +242,7 @@ func (d *driver) network(nid string) *network {
// } // }
// for _, endpoint := range hnsresponse { // for _, endpoint := range hnsresponse {
// if endpoint.VirtualNetwork != n.hnsId { // if endpoint.VirtualNetwork != n.hnsID {
// continue // continue
// } // }
@ -260,7 +260,7 @@ func (d *driver) network(nid string) *network {
func (n *network) convertToOverlayEndpoint(v *hcsshim.HNSEndpoint) *endpoint { func (n *network) convertToOverlayEndpoint(v *hcsshim.HNSEndpoint) *endpoint {
ep := &endpoint{ ep := &endpoint{
id: v.Name, id: v.Name,
profileId: v.Id, profileID: v.Id,
nid: n.id, nid: n.id,
remote: v.IsRemoteEndpoint, remote: v.IsRemoteEndpoint,
} }
@ -311,6 +311,7 @@ func (d *driver) createHnsNetwork(n *network) error {
Type: d.Type(), Type: d.Type(),
Subnets: subnets, Subnets: subnets,
NetworkAdapterName: n.interfaceName, NetworkAdapterName: n.interfaceName,
AutomaticDNS: true,
} }
configurationb, err := json.Marshal(network) configurationb, err := json.Marshal(network)
@ -326,7 +327,7 @@ func (d *driver) createHnsNetwork(n *network) error {
return err return err
} }
n.hnsId = hnsresponse.Id n.hnsID = hnsresponse.Id
n.providerAddress = hnsresponse.ManagementIP n.providerAddress = hnsresponse.ManagementIP
return nil return nil

View file

@ -104,7 +104,7 @@ func (d *driver) restoreHNSNetworks() error {
func (d *driver) convertToOverlayNetwork(v *hcsshim.HNSNetwork) *network { func (d *driver) convertToOverlayNetwork(v *hcsshim.HNSNetwork) *network {
n := &network{ n := &network{
id: v.Name, id: v.Name,
hnsId: v.Id, hnsID: v.Id,
driver: d, driver: d,
endpoints: endpointTable{}, endpoints: endpointTable{},
subnets: []*subnet{}, subnets: []*subnet{},

View file

@ -33,7 +33,7 @@ func (d *driver) peerAdd(nid, eid string, peerIP net.IP, peerIPMask net.IPMask,
hnsEndpoint := &hcsshim.HNSEndpoint{ hnsEndpoint := &hcsshim.HNSEndpoint{
Name: eid, Name: eid,
VirtualNetwork: n.hnsId, VirtualNetwork: n.hnsID,
MacAddress: peerMac.String(), MacAddress: peerMac.String(),
IPAddress: peerIP, IPAddress: peerIP,
IsRemoteEndpoint: true, IsRemoteEndpoint: true,
@ -78,7 +78,7 @@ func (d *driver) peerAdd(nid, eid string, peerIP net.IP, peerIPMask net.IPMask,
nid: nid, nid: nid,
addr: addr, addr: addr,
mac: peerMac, mac: peerMac,
profileId: hnsresponse.Id, profileID: hnsresponse.Id,
remote: true, remote: true,
} }
@ -108,7 +108,7 @@ func (d *driver) peerDelete(nid, eid string, peerIP net.IP, peerIPMask net.IPMas
} }
if updateDb { if updateDb {
_, err := hcsshim.HNSEndpointRequest("DELETE", ep.profileId, "") _, err := hcsshim.HNSEndpointRequest("DELETE", ep.profileID, "")
if err != nil { if err != nil {
return err return err
} }

View file

@ -55,7 +55,8 @@ type endpointOption struct {
DisableICC bool DisableICC bool
} }
type endpointConnectivity struct { // EndpointConnectivity stores the port bindings and exposed ports that the user has specified in epOptions.
type EndpointConnectivity struct {
PortBindings []types.PortBinding PortBindings []types.PortBinding
ExposedPorts []types.TransportPort ExposedPorts []types.TransportPort
} }
@ -67,7 +68,7 @@ type hnsEndpoint struct {
Type string Type string
macAddress net.HardwareAddr macAddress net.HardwareAddr
epOption *endpointOption // User specified parameters epOption *endpointOption // User specified parameters
epConnectivity *endpointConnectivity // User specified parameters epConnectivity *EndpointConnectivity // User specified parameters
portMapping []types.PortBinding // Operation port bindings portMapping []types.PortBinding // Operation port bindings
addr *net.IPNet addr *net.IPNet
gateway net.IP gateway net.IP
@ -95,7 +96,7 @@ const (
errNotFound = "HNS failed with error : The object identifier does not represent a valid object. " errNotFound = "HNS failed with error : The object identifier does not represent a valid object. "
) )
// IsBuiltinWindowsDriver vaidates if network-type is a builtin local-scoped driver // IsBuiltinLocalDriver validates if network-type is a builtin local-scoped driver
func IsBuiltinLocalDriver(networkType string) bool { func IsBuiltinLocalDriver(networkType string) bool {
if "l2bridge" == networkType || "l2tunnel" == networkType || "nat" == networkType || "ics" == networkType || "transparent" == networkType { if "l2bridge" == networkType || "l2tunnel" == networkType || "nat" == networkType || "ics" == networkType || "transparent" == networkType {
return true return true
@ -396,7 +397,8 @@ func convertQosPolicies(qosPolicies []types.QosPolicy) ([]json.RawMessage, error
return qps, nil return qps, nil
} }
func convertPortBindings(portBindings []types.PortBinding) ([]json.RawMessage, error) { // ConvertPortBindings converts PortBindings to JSON for HNS request
func ConvertPortBindings(portBindings []types.PortBinding) ([]json.RawMessage, error) {
var pbs []json.RawMessage var pbs []json.RawMessage
// Enumerate through the port bindings specified by the user and convert // Enumerate through the port bindings specified by the user and convert
@ -431,7 +433,8 @@ func convertPortBindings(portBindings []types.PortBinding) ([]json.RawMessage, e
return pbs, nil return pbs, nil
} }
func parsePortBindingPolicies(policies []json.RawMessage) ([]types.PortBinding, error) { // ParsePortBindingPolicies parses HNS endpoint response message to PortBindings
func ParsePortBindingPolicies(policies []json.RawMessage) ([]types.PortBinding, error) {
var bindings []types.PortBinding var bindings []types.PortBinding
hcsPolicy := &hcsshim.NatPolicy{} hcsPolicy := &hcsshim.NatPolicy{}
@ -505,12 +508,13 @@ func parseEndpointOptions(epOptions map[string]interface{}) (*endpointOption, er
return ec, nil return ec, nil
} }
func parseEndpointConnectivity(epOptions map[string]interface{}) (*endpointConnectivity, error) { // ParseEndpointConnectivity parses options passed to CreateEndpoint, specifically port bindings, and store in a endpointConnectivity object.
func ParseEndpointConnectivity(epOptions map[string]interface{}) (*EndpointConnectivity, error) {
if epOptions == nil { if epOptions == nil {
return nil, nil return nil, nil
} }
ec := &endpointConnectivity{} ec := &EndpointConnectivity{}
if opt, ok := epOptions[netlabel.PortMap]; ok { if opt, ok := epOptions[netlabel.PortMap]; ok {
if bs, ok := opt.([]types.PortBinding); ok { if bs, ok := opt.([]types.PortBinding); ok {
@ -550,7 +554,7 @@ func (d *driver) CreateEndpoint(nid, eid string, ifInfo driverapi.InterfaceInfo,
if err != nil { if err != nil {
return err return err
} }
epConnectivity, err := parseEndpointConnectivity(epOptions) epConnectivity, err := ParseEndpointConnectivity(epOptions)
if err != nil { if err != nil {
return err return err
} }
@ -561,7 +565,7 @@ func (d *driver) CreateEndpoint(nid, eid string, ifInfo driverapi.InterfaceInfo,
endpointStruct.MacAddress = strings.Replace(macAddress.String(), ":", "-", -1) endpointStruct.MacAddress = strings.Replace(macAddress.String(), ":", "-", -1)
} }
endpointStruct.Policies, err = convertPortBindings(epConnectivity.PortBindings) endpointStruct.Policies, err = ConvertPortBindings(epConnectivity.PortBindings)
if err != nil { if err != nil {
return err return err
} }
@ -615,7 +619,7 @@ func (d *driver) CreateEndpoint(nid, eid string, ifInfo driverapi.InterfaceInfo,
endpoint.profileID = hnsresponse.Id endpoint.profileID = hnsresponse.Id
endpoint.epConnectivity = epConnectivity endpoint.epConnectivity = epConnectivity
endpoint.epOption = epOption endpoint.epOption = epOption
endpoint.portMapping, err = parsePortBindingPolicies(hnsresponse.Policies) endpoint.portMapping, err = ParsePortBindingPolicies(hnsresponse.Policies)
if err != nil { if err != nil {
hcsshim.HNSEndpointRequest("DELETE", hnsresponse.Id, "") hcsshim.HNSEndpointRequest("DELETE", hnsresponse.Id, "")