hnsV2.go 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  1. // +build windows
  2. /*
  3. Copyright 2018 The Kubernetes Authors.
  4. Licensed under the Apache License, Version 2.0 (the "License");
  5. you may not use this file except in compliance with the License.
  6. You may obtain a copy of the License at
  7. http://www.apache.org/licenses/LICENSE-2.0
  8. Unless required by applicable law or agreed to in writing, software
  9. distributed under the License is distributed on an "AS IS" BASIS,
  10. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  11. See the License for the specific language governing permissions and
  12. limitations under the License.
  13. */
  14. package winkernel
  15. import (
  16. "encoding/json"
  17. "fmt"
  18. "github.com/Microsoft/hcsshim/hcn"
  19. "k8s.io/klog"
  20. "strings"
  21. )
  22. type hnsV2 struct{}
  23. func (hns hnsV2) getNetworkByName(name string) (*hnsNetworkInfo, error) {
  24. hnsnetwork, err := hcn.GetNetworkByName(name)
  25. if err != nil {
  26. klog.Errorf("%v", err)
  27. return nil, err
  28. }
  29. var remoteSubnets []*remoteSubnetInfo
  30. for _, policy := range hnsnetwork.Policies {
  31. if policy.Type == hcn.RemoteSubnetRoute {
  32. policySettings := hcn.RemoteSubnetRoutePolicySetting{}
  33. err = json.Unmarshal(policy.Settings, &policySettings)
  34. if err != nil {
  35. return nil, fmt.Errorf("Failed to unmarshal Remote Subnet policy settings")
  36. }
  37. rs := &remoteSubnetInfo{
  38. destinationPrefix: policySettings.DestinationPrefix,
  39. isolationID: policySettings.IsolationId,
  40. providerAddress: policySettings.ProviderAddress,
  41. drMacAddress: policySettings.DistributedRouterMacAddress,
  42. }
  43. remoteSubnets = append(remoteSubnets, rs)
  44. }
  45. }
  46. return &hnsNetworkInfo{
  47. id: hnsnetwork.Id,
  48. name: hnsnetwork.Name,
  49. networkType: string(hnsnetwork.Type),
  50. remoteSubnets: remoteSubnets,
  51. }, nil
  52. }
  53. func (hns hnsV2) getEndpointByID(id string) (*endpointsInfo, error) {
  54. hnsendpoint, err := hcn.GetEndpointByID(id)
  55. if err != nil {
  56. return nil, err
  57. }
  58. return &endpointsInfo{ //TODO: fill out PA
  59. ip: hnsendpoint.IpConfigurations[0].IpAddress,
  60. isLocal: uint32(hnsendpoint.Flags&hcn.EndpointFlagsRemoteEndpoint) == 0, //TODO: Change isLocal to isRemote
  61. macAddress: hnsendpoint.MacAddress,
  62. hnsID: hnsendpoint.Id,
  63. hns: hns,
  64. }, nil
  65. }
  66. func (hns hnsV2) getEndpointByIpAddress(ip string, networkName string) (*endpointsInfo, error) {
  67. hnsnetwork, err := hcn.GetNetworkByName(networkName)
  68. if err != nil {
  69. klog.Errorf("%v", err)
  70. return nil, err
  71. }
  72. endpoints, err := hcn.ListEndpoints()
  73. if err != nil {
  74. return nil, fmt.Errorf("Failed to list endpoints: %v", err)
  75. }
  76. for _, endpoint := range endpoints {
  77. equal := false
  78. if endpoint.IpConfigurations != nil && len(endpoint.IpConfigurations) > 0 {
  79. equal = endpoint.IpConfigurations[0].IpAddress == ip
  80. }
  81. if equal && strings.EqualFold(endpoint.HostComputeNetwork, hnsnetwork.Id) {
  82. return &endpointsInfo{
  83. ip: endpoint.IpConfigurations[0].IpAddress,
  84. isLocal: uint32(endpoint.Flags&hcn.EndpointFlagsRemoteEndpoint) == 0, //TODO: Change isLocal to isRemote
  85. macAddress: endpoint.MacAddress,
  86. hnsID: endpoint.Id,
  87. hns: hns,
  88. }, nil
  89. }
  90. }
  91. return nil, fmt.Errorf("Endpoint %v not found on network %s", ip, networkName)
  92. }
  93. func (hns hnsV2) createEndpoint(ep *endpointsInfo, networkName string) (*endpointsInfo, error) {
  94. hnsNetwork, err := hcn.GetNetworkByName(networkName)
  95. if err != nil {
  96. return nil, err
  97. }
  98. var flags hcn.EndpointFlags
  99. if !ep.isLocal {
  100. flags |= hcn.EndpointFlagsRemoteEndpoint
  101. }
  102. ipConfig := &hcn.IpConfig{
  103. IpAddress: ep.ip,
  104. }
  105. hnsEndpoint := &hcn.HostComputeEndpoint{
  106. IpConfigurations: []hcn.IpConfig{*ipConfig},
  107. MacAddress: ep.macAddress,
  108. Flags: flags,
  109. SchemaVersion: hcn.SchemaVersion{
  110. Major: 2,
  111. Minor: 0,
  112. },
  113. }
  114. var createdEndpoint *hcn.HostComputeEndpoint
  115. if !ep.isLocal {
  116. if len(ep.providerAddress) != 0 {
  117. policySettings := hcn.ProviderAddressEndpointPolicySetting{
  118. ProviderAddress: ep.providerAddress,
  119. }
  120. policySettingsJson, err := json.Marshal(policySettings)
  121. if err != nil {
  122. return nil, fmt.Errorf("PA Policy creation failed: %v", err)
  123. }
  124. paPolicy := hcn.EndpointPolicy{
  125. Type: hcn.NetworkProviderAddress,
  126. Settings: policySettingsJson,
  127. }
  128. hnsEndpoint.Policies = append(hnsEndpoint.Policies, paPolicy)
  129. }
  130. createdEndpoint, err = hnsNetwork.CreateRemoteEndpoint(hnsEndpoint)
  131. if err != nil {
  132. return nil, err
  133. }
  134. } else {
  135. createdEndpoint, err = hnsNetwork.CreateEndpoint(hnsEndpoint)
  136. if err != nil {
  137. return nil, err
  138. }
  139. }
  140. return &endpointsInfo{
  141. ip: createdEndpoint.IpConfigurations[0].IpAddress,
  142. isLocal: uint32(createdEndpoint.Flags&hcn.EndpointFlagsRemoteEndpoint) == 0,
  143. macAddress: createdEndpoint.MacAddress,
  144. hnsID: createdEndpoint.Id,
  145. providerAddress: ep.providerAddress, //TODO get from createdEndpoint
  146. hns: hns,
  147. }, nil
  148. }
  149. func (hns hnsV2) deleteEndpoint(hnsID string) error {
  150. hnsendpoint, err := hcn.GetEndpointByID(hnsID)
  151. if err != nil {
  152. return err
  153. }
  154. err = hnsendpoint.Delete()
  155. if err == nil {
  156. klog.V(3).Infof("Remote endpoint resource deleted id %s", hnsID)
  157. }
  158. return err
  159. }
  160. func (hns hnsV2) getLoadBalancer(endpoints []endpointsInfo, flags loadBalancerFlags, sourceVip string, vip string, protocol uint16, internalPort uint16, externalPort uint16) (*loadBalancerInfo, error) {
  161. plists, err := hcn.ListLoadBalancers()
  162. if err != nil {
  163. return nil, err
  164. }
  165. for _, plist := range plists {
  166. if len(plist.HostComputeEndpoints) != len(endpoints) {
  167. continue
  168. }
  169. // Validate if input meets any of the policy lists
  170. lbPortMapping := plist.PortMappings[0]
  171. if lbPortMapping.Protocol == uint32(protocol) && lbPortMapping.InternalPort == internalPort && lbPortMapping.ExternalPort == externalPort && (lbPortMapping.Flags&1 != 0) == flags.isILB {
  172. if len(vip) > 0 {
  173. if len(plist.FrontendVIPs) == 0 || plist.FrontendVIPs[0] != vip {
  174. continue
  175. }
  176. } else if len(plist.FrontendVIPs) != 0 {
  177. continue
  178. }
  179. LogJson(plist, "Found existing Hns loadbalancer policy resource", 1)
  180. return &loadBalancerInfo{
  181. hnsID: plist.Id,
  182. }, nil
  183. }
  184. }
  185. var hnsEndpoints []hcn.HostComputeEndpoint
  186. for _, ep := range endpoints {
  187. endpoint, err := hcn.GetEndpointByID(ep.hnsID)
  188. if err != nil {
  189. return nil, err
  190. }
  191. hnsEndpoints = append(hnsEndpoints, *endpoint)
  192. }
  193. vips := []string{}
  194. if len(vip) > 0 {
  195. vips = append(vips, vip)
  196. }
  197. lbPortMappingFlags := hcn.LoadBalancerPortMappingFlagsNone
  198. if flags.isILB {
  199. lbPortMappingFlags |= hcn.LoadBalancerPortMappingFlagsILB
  200. }
  201. if flags.useMUX {
  202. lbPortMappingFlags |= hcn.LoadBalancerPortMappingFlagsUseMux
  203. }
  204. if flags.preserveDIP {
  205. lbPortMappingFlags |= hcn.LoadBalancerPortMappingFlagsPreserveDIP
  206. }
  207. if flags.localRoutedVIP {
  208. lbPortMappingFlags |= hcn.LoadBalancerPortMappingFlagsLocalRoutedVIP
  209. }
  210. lbFlags := hcn.LoadBalancerFlagsNone
  211. if flags.isDSR {
  212. lbFlags |= hcn.LoadBalancerFlagsDSR
  213. }
  214. lb, err := hcn.AddLoadBalancer(
  215. hnsEndpoints,
  216. lbFlags,
  217. lbPortMappingFlags,
  218. sourceVip,
  219. vips,
  220. protocol,
  221. internalPort,
  222. externalPort,
  223. )
  224. if err != nil {
  225. return nil, err
  226. }
  227. LogJson(lb, "Hns loadbalancer policy resource", 1)
  228. return &loadBalancerInfo{
  229. hnsID: lb.Id,
  230. }, err
  231. }
  232. func (hns hnsV2) deleteLoadBalancer(hnsID string) error {
  233. lb, err := hcn.GetLoadBalancerByID(hnsID)
  234. if err != nil {
  235. // Return silently
  236. return nil
  237. }
  238. err = lb.Delete()
  239. return err
  240. }