@@ -36,11 +36,20 @@ type networkConfiguration struct {
3636 RDID string
3737}
3838
39+ // endpointConfiguration represents the user specified configuration for the sandbox endpoint
40+ type endpointConfiguration struct {
41+ MacAddress net.HardwareAddr
42+ PortBindings []types.PortBinding
43+ ExposedPorts []types.TransportPort
44+ }
45+
3946type hnsEndpoint struct {
40- id string
41- profileID string
42- macAddress net.HardwareAddr
43- addr * net.IPNet
47+ id string
48+ profileID string
49+ macAddress net.HardwareAddr
50+ config * endpointConfiguration // User specified parameters
51+ portMapping []types.PortBinding // Operation port bindings
52+ addr * net.IPNet
4453}
4554
4655type hnsNetwork struct {
@@ -58,7 +67,7 @@ type driver struct {
5867}
5968
6069func isValidNetworkType (networkType string ) bool {
61- if "L2Bridge " == networkType || "L2Tunnel " == networkType || "NAT " == networkType || "Transparent " == networkType {
70+ if "l2bridge " == networkType || "l2tunnel " == networkType || "nat " == networkType || "transparent " == networkType {
6271 return true
6372 }
6473
@@ -276,6 +285,64 @@ func convertPortBindings(portBindings []types.PortBinding) ([]json.RawMessage, e
276285 return pbs , nil
277286}
278287
288+ func parsePortBindingPolicies (policies []json.RawMessage ) ([]types.PortBinding , error ) {
289+ var bindings []types.PortBinding
290+ hcsPolicy := & hcsshim.NatPolicy {}
291+
292+ for _ , elem := range policies {
293+
294+ if err := json .Unmarshal ([]byte (elem ), & hcsPolicy ); err != nil || hcsPolicy .Type != "NAT" {
295+ continue
296+ }
297+
298+ binding := types.PortBinding {
299+ HostPort : hcsPolicy .ExternalPort ,
300+ HostPortEnd : hcsPolicy .ExternalPort ,
301+ Port : hcsPolicy .InternalPort ,
302+ Proto : types .ParseProtocol (hcsPolicy .Protocol ),
303+ HostIP : net .IPv4 (0 , 0 , 0 , 0 ),
304+ }
305+
306+ bindings = append (bindings , binding )
307+ }
308+
309+ return bindings , nil
310+ }
311+
312+ func parseEndpointOptions (epOptions map [string ]interface {}) (* endpointConfiguration , error ) {
313+ if epOptions == nil {
314+ return nil , nil
315+ }
316+
317+ ec := & endpointConfiguration {}
318+
319+ if opt , ok := epOptions [netlabel .MacAddress ]; ok {
320+ if mac , ok := opt .(net.HardwareAddr ); ok {
321+ ec .MacAddress = mac
322+ } else {
323+ return nil , fmt .Errorf ("Invalid endpoint configuration" )
324+ }
325+ }
326+
327+ if opt , ok := epOptions [netlabel .PortMap ]; ok {
328+ if bs , ok := opt .([]types.PortBinding ); ok {
329+ ec .PortBindings = bs
330+ } else {
331+ return nil , fmt .Errorf ("Invalid endpoint configuration" )
332+ }
333+ }
334+
335+ if opt , ok := epOptions [netlabel .ExposedPorts ]; ok {
336+ if ports , ok := opt .([]types.TransportPort ); ok {
337+ ec .ExposedPorts = ports
338+ } else {
339+ return nil , fmt .Errorf ("Invalid endpoint configuration" )
340+ }
341+ }
342+
343+ return ec , nil
344+ }
345+
279346func (d * driver ) CreateEndpoint (nid , eid string , ifInfo driverapi.InterfaceInfo , epOptions map [string ]interface {}) error {
280347 n , err := d .getNetwork (nid )
281348 if err != nil {
@@ -292,16 +359,16 @@ func (d *driver) CreateEndpoint(nid, eid string, ifInfo driverapi.InterfaceInfo,
292359 VirtualNetwork : n .config .HnsID ,
293360 }
294361
295- // Convert the port mapping for the network
296- if opt , ok := epOptions [ netlabel . PortMap ]; ok {
297- if bs , ok := opt .([]types. PortBinding ); ok {
298- endpointStruct . Policies , err = convertPortBindings ( bs )
299- if err != nil {
300- return err
301- }
302- } else {
303- return fmt . Errorf ( "Invalid endpoint configuration for endpoint id%s" , eid )
304- }
362+ ec , err := parseEndpointOptions ( epOptions )
363+
364+ if err != nil {
365+ return err
366+ }
367+
368+ endpointStruct . Policies , err = convertPortBindings ( ec . PortBindings )
369+
370+ if err != nil {
371+ return err
305372 }
306373
307374 configurationb , err := json .Marshal (endpointStruct )
@@ -325,7 +392,16 @@ func (d *driver) CreateEndpoint(nid, eid string, ifInfo driverapi.InterfaceInfo,
325392 addr : & net.IPNet {IP : hnsresponse .IPAddress , Mask : hnsresponse .IPAddress .DefaultMask ()},
326393 macAddress : mac ,
327394 }
395+
328396 endpoint .profileID = hnsresponse .Id
397+ endpoint .config = ec
398+ endpoint .portMapping , err = parsePortBindingPolicies (hnsresponse .Policies )
399+
400+ if err != nil {
401+ hcsshim .HNSEndpointRequest ("DELETE" , hnsresponse .Id , "" )
402+ return err
403+ }
404+
329405 n .Lock ()
330406 n .endpoints [eid ] = endpoint
331407 n .Unlock ()
@@ -365,13 +441,34 @@ func (d *driver) EndpointOperInfo(nid, eid string) (map[string]interface{}, erro
365441 return nil , err
366442 }
367443
368- endpoint , err := network .getEndpoint (eid )
444+ ep , err := network .getEndpoint (eid )
369445 if err != nil {
370446 return nil , err
371447 }
372448
373449 data := make (map [string ]interface {}, 1 )
374- data ["hnsid" ] = endpoint .profileID
450+ data ["hnsid" ] = ep .profileID
451+ if ep .config .ExposedPorts != nil {
452+ // Return a copy of the config data
453+ epc := make ([]types.TransportPort , 0 , len (ep .config .ExposedPorts ))
454+ for _ , tp := range ep .config .ExposedPorts {
455+ epc = append (epc , tp .GetCopy ())
456+ }
457+ data [netlabel .ExposedPorts ] = epc
458+ }
459+
460+ if ep .portMapping != nil {
461+ // Return a copy of the operational data
462+ pmc := make ([]types.PortBinding , 0 , len (ep .portMapping ))
463+ for _ , pm := range ep .portMapping {
464+ pmc = append (pmc , pm .GetCopy ())
465+ }
466+ data [netlabel .PortMap ] = pmc
467+ }
468+
469+ if len (ep .macAddress ) != 0 {
470+ data [netlabel .MacAddress ] = ep .macAddress
471+ }
375472 return data , nil
376473}
377474
0 commit comments