|
@@ -36,11 +36,20 @@ type networkConfiguration struct {
|
|
RDID string
|
|
RDID string
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+// endpointConfiguration represents the user specified configuration for the sandbox endpoint
|
|
|
|
+type endpointConfiguration struct {
|
|
|
|
+ MacAddress net.HardwareAddr
|
|
|
|
+ PortBindings []types.PortBinding
|
|
|
|
+ ExposedPorts []types.TransportPort
|
|
|
|
+}
|
|
|
|
+
|
|
type hnsEndpoint struct {
|
|
type hnsEndpoint struct {
|
|
- id string
|
|
|
|
- profileID string
|
|
|
|
- macAddress net.HardwareAddr
|
|
|
|
- addr *net.IPNet
|
|
|
|
|
|
+ id string
|
|
|
|
+ profileID string
|
|
|
|
+ macAddress net.HardwareAddr
|
|
|
|
+ config *endpointConfiguration // User specified parameters
|
|
|
|
+ portMapping []types.PortBinding // Operation port bindings
|
|
|
|
+ addr *net.IPNet
|
|
}
|
|
}
|
|
|
|
|
|
type hnsNetwork struct {
|
|
type hnsNetwork struct {
|
|
@@ -58,7 +67,7 @@ type driver struct {
|
|
}
|
|
}
|
|
|
|
|
|
func isValidNetworkType(networkType string) bool {
|
|
func isValidNetworkType(networkType string) bool {
|
|
- if "L2Bridge" == networkType || "L2Tunnel" == networkType || "NAT" == networkType || "Transparent" == networkType {
|
|
|
|
|
|
+ if "l2bridge" == networkType || "l2tunnel" == networkType || "nat" == networkType || "transparent" == networkType {
|
|
return true
|
|
return true
|
|
}
|
|
}
|
|
|
|
|
|
@@ -276,6 +285,64 @@ func convertPortBindings(portBindings []types.PortBinding) ([]json.RawMessage, e
|
|
return pbs, nil
|
|
return pbs, nil
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+func parsePortBindingPolicies(policies []json.RawMessage) ([]types.PortBinding, error) {
|
|
|
|
+ var bindings []types.PortBinding
|
|
|
|
+ hcsPolicy := &hcsshim.NatPolicy{}
|
|
|
|
+
|
|
|
|
+ for _, elem := range policies {
|
|
|
|
+
|
|
|
|
+ if err := json.Unmarshal([]byte(elem), &hcsPolicy); err != nil || hcsPolicy.Type != "NAT" {
|
|
|
|
+ continue
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ binding := types.PortBinding{
|
|
|
|
+ HostPort: hcsPolicy.ExternalPort,
|
|
|
|
+ HostPortEnd: hcsPolicy.ExternalPort,
|
|
|
|
+ Port: hcsPolicy.InternalPort,
|
|
|
|
+ Proto: types.ParseProtocol(hcsPolicy.Protocol),
|
|
|
|
+ HostIP: net.IPv4(0, 0, 0, 0),
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ bindings = append(bindings, binding)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return bindings, nil
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+func parseEndpointOptions(epOptions map[string]interface{}) (*endpointConfiguration, error) {
|
|
|
|
+ if epOptions == nil {
|
|
|
|
+ return nil, nil
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ ec := &endpointConfiguration{}
|
|
|
|
+
|
|
|
|
+ if opt, ok := epOptions[netlabel.MacAddress]; ok {
|
|
|
|
+ if mac, ok := opt.(net.HardwareAddr); ok {
|
|
|
|
+ ec.MacAddress = mac
|
|
|
|
+ } else {
|
|
|
|
+ return nil, fmt.Errorf("Invalid endpoint configuration")
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if opt, ok := epOptions[netlabel.PortMap]; ok {
|
|
|
|
+ if bs, ok := opt.([]types.PortBinding); ok {
|
|
|
|
+ ec.PortBindings = bs
|
|
|
|
+ } else {
|
|
|
|
+ return nil, fmt.Errorf("Invalid endpoint configuration")
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if opt, ok := epOptions[netlabel.ExposedPorts]; ok {
|
|
|
|
+ if ports, ok := opt.([]types.TransportPort); ok {
|
|
|
|
+ ec.ExposedPorts = ports
|
|
|
|
+ } else {
|
|
|
|
+ return nil, fmt.Errorf("Invalid endpoint configuration")
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return ec, nil
|
|
|
|
+}
|
|
|
|
+
|
|
func (d *driver) CreateEndpoint(nid, eid string, ifInfo driverapi.InterfaceInfo, epOptions map[string]interface{}) error {
|
|
func (d *driver) CreateEndpoint(nid, eid string, ifInfo driverapi.InterfaceInfo, epOptions map[string]interface{}) error {
|
|
n, err := d.getNetwork(nid)
|
|
n, err := d.getNetwork(nid)
|
|
if err != nil {
|
|
if err != nil {
|
|
@@ -292,16 +359,16 @@ func (d *driver) CreateEndpoint(nid, eid string, ifInfo driverapi.InterfaceInfo,
|
|
VirtualNetwork: n.config.HnsID,
|
|
VirtualNetwork: n.config.HnsID,
|
|
}
|
|
}
|
|
|
|
|
|
- // Convert the port mapping for the network
|
|
|
|
- if opt, ok := epOptions[netlabel.PortMap]; ok {
|
|
|
|
- if bs, ok := opt.([]types.PortBinding); ok {
|
|
|
|
- endpointStruct.Policies, err = convertPortBindings(bs)
|
|
|
|
- if err != nil {
|
|
|
|
- return err
|
|
|
|
- }
|
|
|
|
- } else {
|
|
|
|
- return fmt.Errorf("Invalid endpoint configuration for endpoint id%s", eid)
|
|
|
|
- }
|
|
|
|
|
|
+ ec, err := parseEndpointOptions(epOptions)
|
|
|
|
+
|
|
|
|
+ if err != nil {
|
|
|
|
+ return err
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ endpointStruct.Policies, err = convertPortBindings(ec.PortBindings)
|
|
|
|
+
|
|
|
|
+ if err != nil {
|
|
|
|
+ return err
|
|
}
|
|
}
|
|
|
|
|
|
configurationb, err := json.Marshal(endpointStruct)
|
|
configurationb, err := json.Marshal(endpointStruct)
|
|
@@ -325,7 +392,16 @@ func (d *driver) CreateEndpoint(nid, eid string, ifInfo driverapi.InterfaceInfo,
|
|
addr: &net.IPNet{IP: hnsresponse.IPAddress, Mask: hnsresponse.IPAddress.DefaultMask()},
|
|
addr: &net.IPNet{IP: hnsresponse.IPAddress, Mask: hnsresponse.IPAddress.DefaultMask()},
|
|
macAddress: mac,
|
|
macAddress: mac,
|
|
}
|
|
}
|
|
|
|
+
|
|
endpoint.profileID = hnsresponse.Id
|
|
endpoint.profileID = hnsresponse.Id
|
|
|
|
+ endpoint.config = ec
|
|
|
|
+ endpoint.portMapping, err = parsePortBindingPolicies(hnsresponse.Policies)
|
|
|
|
+
|
|
|
|
+ if err != nil {
|
|
|
|
+ hcsshim.HNSEndpointRequest("DELETE", hnsresponse.Id, "")
|
|
|
|
+ return err
|
|
|
|
+ }
|
|
|
|
+
|
|
n.Lock()
|
|
n.Lock()
|
|
n.endpoints[eid] = endpoint
|
|
n.endpoints[eid] = endpoint
|
|
n.Unlock()
|
|
n.Unlock()
|
|
@@ -365,13 +441,34 @@ func (d *driver) EndpointOperInfo(nid, eid string) (map[string]interface{}, erro
|
|
return nil, err
|
|
return nil, err
|
|
}
|
|
}
|
|
|
|
|
|
- endpoint, err := network.getEndpoint(eid)
|
|
|
|
|
|
+ ep, err := network.getEndpoint(eid)
|
|
if err != nil {
|
|
if err != nil {
|
|
return nil, err
|
|
return nil, err
|
|
}
|
|
}
|
|
|
|
|
|
data := make(map[string]interface{}, 1)
|
|
data := make(map[string]interface{}, 1)
|
|
- data["hnsid"] = endpoint.profileID
|
|
|
|
|
|
+ data["hnsid"] = ep.profileID
|
|
|
|
+ if ep.config.ExposedPorts != nil {
|
|
|
|
+ // Return a copy of the config data
|
|
|
|
+ epc := make([]types.TransportPort, 0, len(ep.config.ExposedPorts))
|
|
|
|
+ for _, tp := range ep.config.ExposedPorts {
|
|
|
|
+ epc = append(epc, tp.GetCopy())
|
|
|
|
+ }
|
|
|
|
+ data[netlabel.ExposedPorts] = epc
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ 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
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if len(ep.macAddress) != 0 {
|
|
|
|
+ data[netlabel.MacAddress] = ep.macAddress
|
|
|
|
+ }
|
|
return data, nil
|
|
return data, nil
|
|
}
|
|
}
|
|
|
|
|