1package hcsshim
2
3import (
4	"encoding/json"
5	"net"
6
7	"github.com/sirupsen/logrus"
8)
9
10// Subnet is assoicated with a network and represents a list
11// of subnets available to the network
12type Subnet struct {
13	AddressPrefix  string            `json:",omitempty"`
14	GatewayAddress string            `json:",omitempty"`
15	Policies       []json.RawMessage `json:",omitempty"`
16}
17
18// MacPool is assoicated with a network and represents a list
19// of macaddresses available to the network
20type MacPool struct {
21	StartMacAddress string `json:",omitempty"`
22	EndMacAddress   string `json:",omitempty"`
23}
24
25// HNSNetwork represents a network in HNS
26type HNSNetwork struct {
27	Id                   string            `json:"ID,omitempty"`
28	Name                 string            `json:",omitempty"`
29	Type                 string            `json:",omitempty"`
30	NetworkAdapterName   string            `json:",omitempty"`
31	SourceMac            string            `json:",omitempty"`
32	Policies             []json.RawMessage `json:",omitempty"`
33	MacPools             []MacPool         `json:",omitempty"`
34	Subnets              []Subnet          `json:",omitempty"`
35	DNSSuffix            string            `json:",omitempty"`
36	DNSServerList        string            `json:",omitempty"`
37	DNSServerCompartment uint32            `json:",omitempty"`
38	ManagementIP         string            `json:",omitempty"`
39	AutomaticDNS         bool              `json:",omitempty"`
40}
41
42type hnsNetworkResponse struct {
43	Success bool
44	Error   string
45	Output  HNSNetwork
46}
47
48type hnsResponse struct {
49	Success bool
50	Error   string
51	Output  json.RawMessage
52}
53
54// HNSNetworkRequest makes a call into HNS to update/query a single network
55func HNSNetworkRequest(method, path, request string) (*HNSNetwork, error) {
56	var network HNSNetwork
57	err := hnsCall(method, "/networks/"+path, request, &network)
58	if err != nil {
59		return nil, err
60	}
61
62	return &network, nil
63}
64
65// HNSListNetworkRequest makes a HNS call to query the list of available networks
66func HNSListNetworkRequest(method, path, request string) ([]HNSNetwork, error) {
67	var network []HNSNetwork
68	err := hnsCall(method, "/networks/"+path, request, &network)
69	if err != nil {
70		return nil, err
71	}
72
73	return network, nil
74}
75
76// GetHNSNetworkByID
77func GetHNSNetworkByID(networkID string) (*HNSNetwork, error) {
78	return HNSNetworkRequest("GET", networkID, "")
79}
80
81// GetHNSNetworkName filtered by Name
82func GetHNSNetworkByName(networkName string) (*HNSNetwork, error) {
83	hsnnetworks, err := HNSListNetworkRequest("GET", "", "")
84	if err != nil {
85		return nil, err
86	}
87	for _, hnsnetwork := range hsnnetworks {
88		if hnsnetwork.Name == networkName {
89			return &hnsnetwork, nil
90		}
91	}
92	return nil, NetworkNotFoundError{NetworkName: networkName}
93}
94
95// Create Network by sending NetworkRequest to HNS.
96func (network *HNSNetwork) Create() (*HNSNetwork, error) {
97	operation := "Create"
98	title := "HCSShim::HNSNetwork::" + operation
99	logrus.Debugf(title+" id=%s", network.Id)
100
101	jsonString, err := json.Marshal(network)
102	if err != nil {
103		return nil, err
104	}
105	return HNSNetworkRequest("POST", "", string(jsonString))
106}
107
108// Delete Network by sending NetworkRequest to HNS
109func (network *HNSNetwork) Delete() (*HNSNetwork, error) {
110	operation := "Delete"
111	title := "HCSShim::HNSNetwork::" + operation
112	logrus.Debugf(title+" id=%s", network.Id)
113
114	return HNSNetworkRequest("DELETE", network.Id, "")
115}
116
117// Creates an endpoint on the Network.
118func (network *HNSNetwork) NewEndpoint(ipAddress net.IP, macAddress net.HardwareAddr) *HNSEndpoint {
119	return &HNSEndpoint{
120		VirtualNetwork: network.Id,
121		IPAddress:      ipAddress,
122		MacAddress:     string(macAddress),
123	}
124}
125
126func (network *HNSNetwork) CreateEndpoint(endpoint *HNSEndpoint) (*HNSEndpoint, error) {
127	operation := "CreateEndpoint"
128	title := "HCSShim::HNSNetwork::" + operation
129	logrus.Debugf(title+" id=%s, endpointId=%s", network.Id, endpoint.Id)
130
131	endpoint.VirtualNetwork = network.Id
132	return endpoint.Create()
133}
134
135func (network *HNSNetwork) CreateRemoteEndpoint(endpoint *HNSEndpoint) (*HNSEndpoint, error) {
136	operation := "CreateRemoteEndpoint"
137	title := "HCSShim::HNSNetwork::" + operation
138	logrus.Debugf(title+" id=%s", network.Id)
139	endpoint.IsRemoteEndpoint = true
140	return network.CreateEndpoint(endpoint)
141}
142