Kubernetes integration with OpenStack networking
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

base.py 29KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852
  1. # Copyright (c) 2016 Mirantis, Inc.
  2. # All Rights Reserved.
  3. #
  4. # Licensed under the Apache License, Version 2.0 (the "License"); you may
  5. # not use this file except in compliance with the License. You may obtain
  6. # a copy of the License at
  7. #
  8. # http://www.apache.org/licenses/LICENSE-2.0
  9. #
  10. # Unless required by applicable law or agreed to in writing, software
  11. # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  12. # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  13. # License for the specific language governing permissions and limitations
  14. # under the License.
  15. import abc
  16. import six
  17. from kuryr.lib._i18n import _
  18. from stevedore import driver as stv_driver
  19. from kuryr_kubernetes import config
  20. _DRIVER_NAMESPACE_BASE = 'kuryr_kubernetes.controller.drivers'
  21. _DRIVER_MANAGERS = {}
  22. _MULTI_VIF_DRIVERS = []
  23. class DriverBase(object):
  24. """Base class for controller drivers.
  25. Subclasses must define an *ALIAS* attribute that is used to find a driver
  26. implementation by `get_instance` class method which utilises
  27. `stevedore.driver.DriverManager` with the namespace set to
  28. 'kuryr_kubernetes.controller.drivers.*ALIAS*' and the name of
  29. the driver determined from the '[kubernetes]/*ALIAS*_driver' configuration
  30. parameter.
  31. Usage example:
  32. @six.add_metaclass(abc.ABCMeta)
  33. class SomeDriverInterface(DriverBase):
  34. ALIAS = 'driver_alias'
  35. @abc.abstractmethod
  36. def some_method(self):
  37. pass
  38. driver = SomeDriverInterface.get_instance()
  39. driver.some_method()
  40. """
  41. @classmethod
  42. def get_instance(cls, specific_driver=None, scope='default'):
  43. """Get an implementing driver instance.
  44. :param specific_driver: Loads a specific driver instead of using conf.
  45. Uses separate manager entry so that loading of
  46. default/other drivers is not affected.
  47. :param scope: Loads the driver in the given scope (if independent
  48. instances of a driver are required)
  49. """
  50. alias = cls.ALIAS
  51. if specific_driver:
  52. driver_key = '{}:{}:{}'.format(alias, specific_driver, scope)
  53. else:
  54. driver_key = '{}:_from_cfg:{}'.format(alias, scope)
  55. try:
  56. manager = _DRIVER_MANAGERS[driver_key]
  57. except KeyError:
  58. driver_name = (specific_driver or
  59. config.CONF.kubernetes[alias + '_driver'])
  60. manager = stv_driver.DriverManager(
  61. namespace="%s.%s" % (_DRIVER_NAMESPACE_BASE, alias),
  62. name=driver_name,
  63. invoke_on_load=True)
  64. _DRIVER_MANAGERS[driver_key] = manager
  65. driver = manager.driver
  66. if not isinstance(driver, cls):
  67. raise TypeError(_("Invalid %(alias)r driver type: %(driver)s, "
  68. "must be a subclass of %(type)s") % {
  69. 'alias': alias,
  70. 'driver': driver.__class__.__name__,
  71. 'type': cls})
  72. return driver
  73. def __str__(self):
  74. return self.__class__.__name__
  75. @six.add_metaclass(abc.ABCMeta)
  76. class PodProjectDriver(DriverBase):
  77. """Provides an OpenStack project ID for Kubernetes Pod ports."""
  78. ALIAS = 'pod_project'
  79. @abc.abstractmethod
  80. def get_project(self, pod):
  81. """Get an OpenStack project ID for Kubernetes Pod ports.
  82. :param pod: dict containing Kubernetes Pod object
  83. :return: project ID
  84. """
  85. raise NotImplementedError()
  86. @six.add_metaclass(abc.ABCMeta)
  87. class ServiceProjectDriver(DriverBase):
  88. """Provides an OpenStack project ID for Kubernetes Services."""
  89. ALIAS = 'service_project'
  90. @abc.abstractmethod
  91. def get_project(self, service):
  92. """Get an OpenStack project ID for Kubernetes Service.
  93. :param service: dict containing Kubernetes Service object
  94. :return: project ID
  95. """
  96. raise NotImplementedError()
  97. @six.add_metaclass(abc.ABCMeta)
  98. class NamespaceProjectDriver(DriverBase):
  99. """Provides an OpenStack project ID for Kubernetes Namespace."""
  100. ALIAS = 'namespace_project'
  101. @abc.abstractmethod
  102. def get_project(self, namespace):
  103. """Get an OpenStack project ID for Kubernetes Namespace.
  104. :param service: dict containing Kubernetes Namespace object
  105. :return: project ID
  106. """
  107. raise NotImplementedError()
  108. @six.add_metaclass(abc.ABCMeta)
  109. class PodSubnetsDriver(DriverBase):
  110. """Provides subnets for Kubernetes Pods."""
  111. ALIAS = 'pod_subnets'
  112. @abc.abstractmethod
  113. def get_subnets(self, pod, project_id):
  114. """Get subnets for Pod.
  115. :param pod: dict containing Kubernetes Pod object
  116. :param project_id: OpenStack project ID
  117. :return: dict containing the mapping 'subnet_id' -> 'network' for all
  118. the subnets we want to create ports on, where 'network' is an
  119. `os_vif.network.Network` object containing a single
  120. `os_vif.subnet.Subnet` object corresponding to the 'subnet_id'
  121. """
  122. raise NotImplementedError()
  123. def create_namespace_network(self, namespace, project_id):
  124. """Create network resources for a namespace.
  125. :param namespace: string with the namespace name
  126. :param project_id: OpenStack project ID
  127. :return: dict with the keys and values for the CRD spec, such as
  128. routerId or subnetId
  129. """
  130. raise NotImplementedError()
  131. def delete_namespace_subnet(self, kuryr_net_crd):
  132. """Delete network resources associated to a namespace.
  133. :param kuryr_net_crd: kuryrnet CRD obj dict that contains Neutron's
  134. network resources associated to a namespace
  135. """
  136. raise NotImplementedError()
  137. def rollback_network_resources(self, crd_spec, namespace):
  138. """Rollback created network resources for a namespace.
  139. :param crd_spec: dict with the keys and values for the CRD spec, such
  140. as routerId or subnetId
  141. :param namespace: name of the Kubernetes namespace object
  142. """
  143. raise NotImplementedError()
  144. @six.add_metaclass(abc.ABCMeta)
  145. class ServiceSubnetsDriver(DriverBase):
  146. """Provides subnets for Kubernetes Services."""
  147. ALIAS = 'service_subnets'
  148. @abc.abstractmethod
  149. def get_subnets(self, service, project_id):
  150. """Get subnets for Service.
  151. :param service: dict containing Kubernetes Pod object
  152. :param project_id: OpenStack project ID
  153. :return: dict containing the mapping 'subnet_id' -> 'network' for all
  154. the subnets we want to create ports on, where 'network' is an
  155. `os_vif.network.Network` object containing a single
  156. `os_vif.subnet.Subnet` object corresponding to the 'subnet_id'
  157. """
  158. raise NotImplementedError()
  159. @six.add_metaclass(abc.ABCMeta)
  160. class PodSecurityGroupsDriver(DriverBase):
  161. """Provides security groups for Kubernetes Pods."""
  162. ALIAS = 'pod_security_groups'
  163. @abc.abstractmethod
  164. def get_security_groups(self, pod, project_id):
  165. """Get a list of security groups' IDs for Pod.
  166. :param pod: dict containing Kubernetes Pod object
  167. :param project_id: OpenStack project ID
  168. :return: list containing security groups' IDs
  169. """
  170. raise NotImplementedError()
  171. def create_namespace_sg(self, namespace, project_id, crd_spec):
  172. """Create security group resources for a namespace.
  173. :param namespace: string with the namespace name
  174. :param project_id: OpenStack project ID
  175. :param crd_spec: dict with the keys and values for the CRD spec, such
  176. as subnetId or subnetCIDR
  177. :return: dict with the keys and values for the CRD spec, such as sgId.
  178. If no security group need to be created for the namespace, it
  179. should return an empty dict
  180. """
  181. raise NotImplementedError()
  182. def delete_sg(self, sg_id):
  183. """Delete security group associated to a namespace.
  184. :param sg_id: OpenStack security group ID
  185. """
  186. raise NotImplementedError()
  187. def create_sg_rules(self, pod):
  188. """Create security group rules for a pod.
  189. :param pod: dict containing Kubernetes Pod object
  190. """
  191. raise NotImplementedError()
  192. def delete_sg_rules(self, pod):
  193. """Delete security group rules for a pod
  194. :param pod: dict containing Kubernetes Pod object
  195. """
  196. raise NotImplementedError()
  197. def update_sg_rules(self, pod):
  198. """Update security group rules for a pod
  199. :param pod: dict containing Kubernetes Pod object
  200. """
  201. raise NotImplementedError()
  202. def delete_namespace_sg_rules(self, namespace):
  203. """Delete security group rule associated to a namespace.
  204. :param namespace: dict containing K8S Namespace object
  205. """
  206. raise NotImplementedError()
  207. def create_namespace_sg_rules(self, namespace):
  208. """Create security group rule associated to a namespace.
  209. :param namespace: dict containing K8S Namespace object
  210. """
  211. raise NotImplementedError()
  212. def update_namespace_sg_rules(self, namespace):
  213. """Update security group rule associated to a namespace.
  214. :param namespace: dict containing K8S Namespace object
  215. """
  216. raise NotImplementedError()
  217. @six.add_metaclass(abc.ABCMeta)
  218. class ServiceSecurityGroupsDriver(DriverBase):
  219. """Provides security groups for Kubernetes Services."""
  220. ALIAS = 'service_security_groups'
  221. @abc.abstractmethod
  222. def get_security_groups(self, service, project_id):
  223. """Get a list of security groups' IDs for Service.
  224. :param service: dict containing Kubernetes Service object
  225. :param project_id: OpenStack project ID
  226. :return: list containing security groups' IDs
  227. """
  228. raise NotImplementedError()
  229. @six.add_metaclass(abc.ABCMeta)
  230. class PodVIFDriver(DriverBase):
  231. """Manages Neutron ports to provide VIFs for Kubernetes Pods."""
  232. ALIAS = 'pod_vif'
  233. @abc.abstractmethod
  234. def request_vif(self, pod, project_id, subnets, security_groups):
  235. """Links Neutron port to pod and returns it as VIF object.
  236. Implementing drivers must ensure the Neutron port satisfying the
  237. requested parameters is present and is valid for specified `pod`. It
  238. is up to the implementing drivers to either create new ports on each
  239. request or reuse available ports when possible.
  240. Implementing drivers may return a VIF object with its `active` field
  241. set to 'False' to indicate that Neutron port requires additional
  242. actions to enable network connectivity after VIF is plugged (e.g.
  243. setting up OpenFlow and/or iptables rules by OpenVSwitch agent). In
  244. that case the Controller will call driver's `activate_vif` method
  245. and the CNI plugin will block until it receives activation
  246. confirmation from the Controller.
  247. :param pod: dict containing Kubernetes Pod object
  248. :param project_id: OpenStack project ID
  249. :param subnets: dict containing subnet mapping as returned by
  250. `PodSubnetsDriver.get_subnets`. If multiple entries
  251. are present in that mapping, it is guaranteed that
  252. all entries have the same value of `Network.id`.
  253. :param security_groups: list containing security groups' IDs as
  254. returned by
  255. `PodSecurityGroupsDriver.get_security_groups`
  256. :return: VIF object
  257. """
  258. raise NotImplementedError()
  259. def request_vifs(self, pod, project_id, subnets, security_groups,
  260. num_ports):
  261. """Creates Neutron ports for pods and returns them as VIF objects list.
  262. It follows the same pattern as request_vif but creating the specified
  263. amount of ports and vif objects at num_ports parameter.
  264. The port creation request is generic as it not going to be used by the
  265. pod -- at least not all of them. Additionally, in order to save Neutron
  266. calls, the ports creation is handled in a bulk request.
  267. :param pod: dict containing Kubernetes Pod object
  268. :param project_id: OpenStack project ID
  269. :param subnets: dict containing subnet mapping as returned by
  270. `PodSubnetsDriver.get_subnets`. If multiple entries
  271. are present in that mapping, it is guaranteed that
  272. all entries have the same value of `Network.id`.
  273. :param security_groups: list containing security groups' IDs as
  274. returned by
  275. `PodSecurityGroupsDriver.get_security_groups`
  276. :param num_ports: number of ports to be created
  277. :return: VIF objects list
  278. """
  279. raise NotImplementedError()
  280. @abc.abstractmethod
  281. def release_vif(self, pod, vif, project_id=None, security_groups=None):
  282. """Unlinks Neutron port corresponding to VIF object from pod.
  283. Implementing drivers must ensure the port is either deleted or made
  284. available for reuse by `PodVIFDriver.request_vif`.
  285. :param pod: dict containing Kubernetes Pod object
  286. :param vif: VIF object as returned by `PodVIFDriver.request_vif`
  287. :param project_id: OpenStack project ID
  288. :param security_groups: list containing security groups'
  289. IDs as returned by
  290. `PodSecurityGroupsDriver.get_security_groups`
  291. """
  292. raise NotImplementedError()
  293. def release_vifs(self, pods, vifs, project_id=None, security_groups=None):
  294. """Unlinks Neutron ports corresponding to VIF objects.
  295. It follows the same pattern as release_vif but releasing num_ports
  296. ports. Ideally it will also make use of bulk request to save Neutron
  297. calls in the release/recycle process.
  298. :param pods: list of dict containing Kubernetes Pod objects
  299. :param vifs: list of VIF objects as returned by
  300. `PodVIFDriver.request_vif`
  301. :param project_id: (optional) OpenStack project ID
  302. :param security_groups: (optional) list containing security groups'
  303. IDs as returned by
  304. `PodSecurityGroupsDriver.get_security_groups`
  305. """
  306. raise NotImplementedError()
  307. @abc.abstractmethod
  308. def activate_vif(self, pod, vif):
  309. """Updates VIF to become active.
  310. Implementing drivers should update the specified `vif` object's
  311. `active` field to 'True' but must ensure that the corresponding
  312. Neutron port is fully configured (i.e. the container using the `vif`
  313. can access the requested network resources).
  314. Implementing drivers may raise `ResourceNotReady` exception to
  315. indicate that port activation should be retried later which will
  316. cause `activate_vif` to be called again with the same arguments.
  317. This method may be called before, after or while the VIF is being
  318. plugged by the CNI plugin.
  319. :param pod: dict containing Kubernetes Pod object
  320. :param vif: VIF object as returned by `PodVIFDriver.request_vif`
  321. """
  322. raise NotImplementedError()
  323. @abc.abstractmethod
  324. def update_vif_sgs(self, pod, security_groups):
  325. """Update VIF security groups.
  326. Implementing drivers should update the port associated to the pod
  327. with the specified security groups.
  328. :param pod: dict containing Kubernetes Pod object
  329. :param security_groups: list containing security groups' IDs as
  330. returned by
  331. `PodSecurityGroupsDriver.get_security_groups`
  332. """
  333. raise NotImplementedError()
  334. @six.add_metaclass(abc.ABCMeta)
  335. class MultiVIFDriver(DriverBase):
  336. """Manages additional ports of Kubernetes Pods."""
  337. ALIAS = 'multi_vif'
  338. @abc.abstractmethod
  339. def request_additional_vifs(
  340. self, pod, project_id, security_groups):
  341. """Links Neutron ports to pod and returns them as a list of VIF objects.
  342. Implementing drivers must be able to parse the additional interface
  343. definition from pod. The format of the definition is up to the
  344. implementation of each driver. Then implementing drivers must invoke
  345. the VIF drivers to either create new Neutron ports on each request or
  346. reuse available ports when possible.
  347. :param pod: dict containing Kubernetes Pod object
  348. :param project_id: OpenStack project ID
  349. :param security_groups: list containing security groups' IDs as
  350. returned by
  351. `PodSecurityGroupsDriver.get_security_groups`
  352. :return: VIF object list
  353. """
  354. raise NotImplementedError()
  355. @classmethod
  356. def get_enabled_drivers(cls):
  357. if _MULTI_VIF_DRIVERS:
  358. pass
  359. else:
  360. drivers = config.CONF.kubernetes['multi_vif_drivers']
  361. for driver in drivers:
  362. _MULTI_VIF_DRIVERS.append(cls.get_instance(driver))
  363. return _MULTI_VIF_DRIVERS
  364. class LBaaSDriver(DriverBase):
  365. """Base class for Openstack loadbalancer services."""
  366. ALIAS = 'endpoints_lbaas'
  367. @abc.abstractmethod
  368. def get_service_loadbalancer_name(self, namespace, svc_name):
  369. """Generate name of a load balancer that represents K8S service.
  370. In case a load balancer represents K8S service/ep, the handler
  371. should call first this API to get the load balancer name and use the
  372. return value of this function as 'name' parameter for the
  373. 'ensure_loadbalancer' function
  374. :param namespace: K8S service namespace
  375. :param svc_name: K8S service name
  376. """
  377. raise NotImplementedError()
  378. @abc.abstractmethod
  379. def ensure_loadbalancer(self, name, project_id, subnet_id, ip,
  380. security_groups_ids, service_type, provider):
  381. """Get or create load balancer.
  382. :param name: LoadBlancer name
  383. :param project_id: OpenStack project ID
  384. :param subnet_id: Neutron subnet ID to host load balancer
  385. :param ip: IP of the load balancer
  386. :param security_groups_ids: security groups that should be allowed
  387. access to the load balancer
  388. :param service_type: K8s service type (ClusterIP or LoadBalancer)
  389. :param provider: load balancer backend service
  390. """
  391. raise NotImplementedError()
  392. @abc.abstractmethod
  393. def release_loadbalancer(self, loadbalancer):
  394. """Release load balancer.
  395. Should return without errors if load balancer does not exist (e.g.
  396. already deleted).
  397. :param loadbalancer: `LBaaSLoadBalancer` object
  398. """
  399. raise NotImplementedError()
  400. @abc.abstractmethod
  401. def ensure_listener(self, loadbalancer, protocol, port):
  402. """Get or create listener.
  403. :param loadbalancer: `LBaaSLoadBalancer` object
  404. :param protocol: listener's protocol (only TCP is supported for now)
  405. :param port: listener's port
  406. """
  407. raise NotImplementedError()
  408. @abc.abstractmethod
  409. def release_listener(self, loadbalancer, listener):
  410. """Release listener.
  411. Should return without errors if listener or load balancer does not
  412. exist (e.g. already deleted).
  413. :param loadbalancer: `LBaaSLoadBalancer` object
  414. :param listener: `LBaaSListener` object
  415. """
  416. raise NotImplementedError()
  417. @abc.abstractmethod
  418. def ensure_pool(self, loadbalancer, listener):
  419. """Get or create pool attached to Listener.
  420. :param loadbalancer: `LBaaSLoadBalancer` object
  421. :param listener: `LBaaSListener` object
  422. """
  423. raise NotImplementedError()
  424. @abc.abstractmethod
  425. def ensure_pool_attached_to_lb(self, loadbalancer, namespace,
  426. svc_name, protocol):
  427. """Get or create pool attached to LoadBalancer.
  428. :param loadbalancer: `LBaaSLoadBalancer` object
  429. :param namespace: K8S service's namespace
  430. :param svc_name: K8S service's name
  431. :param protocol: pool's protocol
  432. """
  433. raise NotImplementedError()
  434. @abc.abstractmethod
  435. def get_loadbalancer_pool_name(self, loadbalancer, namespace, svc_name):
  436. """Get name of a load balancer's pool attached to LB.
  437. The pool's name should be unique per K8S service
  438. :param loadbalancer: `LBaaSLoadBalancer` object
  439. :param namespace: K8S service's namespace
  440. :param svc_name: K8S service's name
  441. """
  442. raise NotImplementedError()
  443. @abc.abstractmethod
  444. def release_pool(self, loadbalancer, pool):
  445. """Release pool.
  446. Should return without errors if pool or load balancer does not exist
  447. (e.g. already deleted).
  448. :param loadbalancer: `LBaaSLoadBalancer` object
  449. :param pool: `LBaaSPool` object
  450. """
  451. raise NotImplementedError()
  452. @abc.abstractmethod
  453. def ensure_member(self, loadbalancer, pool,
  454. subnet_id, ip, port, target_ref_namespace,
  455. target_ref_name):
  456. """Get or create member.
  457. :param loadbalancer: `LBaaSLoadBalancer` object
  458. :param pool: `LBaaSPool` object
  459. :param subnet_id: Neutron subnet ID of the target
  460. :param ip: target's IP (e.g. Pod's IP)
  461. :param port: target port
  462. :param target_ref_namespace: Kubernetes EP target_ref namespace
  463. :param target_ref_name: Kubernetes EP target_ref name
  464. """
  465. raise NotImplementedError()
  466. @abc.abstractmethod
  467. def release_member(self, loadbalancer, member):
  468. """Release member.
  469. Should return without errors if memberor load balancer does not exist
  470. (e.g. already deleted).
  471. :param loadbalancer: `LBaaSLoadBalancer` object
  472. :param member: `LBaaSMember` object
  473. """
  474. raise NotImplementedError()
  475. @abc.abstractmethod
  476. def get_lb_by_uuid(self, lb_uuid):
  477. """Get loadbalancer by loadbalancer uuid.
  478. :param lb_uuid: Loadbalancer uuid
  479. """
  480. raise NotImplementedError()
  481. @abc.abstractmethod
  482. def get_pool_by_name(self, pool_name, project_id):
  483. """Get pool by pool's name.
  484. :param pool_name: the pool name
  485. :param project_id: project id
  486. """
  487. raise NotImplementedError()
  488. @abc.abstractmethod
  489. def ensure_l7_policy(self, namespace, route_name, loadbalancer,
  490. pool, listener_id):
  491. """Get or create L7 policy.
  492. :param namespace: ocp-route/k8s-ingress namespace
  493. :param route_name: ocp-route/k8s-ingress name
  494. :param loadbalancer: `LBaaSLoadBalancer` object
  495. :param pool: L7 policy's target pool
  496. :param listener_id: ID of listener to attach L7policy to
  497. """
  498. raise NotImplementedError()
  499. @abc.abstractmethod
  500. def release_l7_policy(self, loadbalancer, l7_policy):
  501. """Release l7policy.
  502. :param loadbalancer: `LBaaSLoadBalancer` object
  503. :param l7_policy: `LBaaSL7Policy` object
  504. """
  505. raise NotImplementedError()
  506. @abc.abstractmethod
  507. def ensure_l7_rule(self, loadbalancer, l7_policy, compare_type,
  508. type, value):
  509. """Get or create L7 rule.
  510. :param loadbalancer: `LBaaSLoadBalancer` object
  511. :param l7_policy: `LBaaSL7Policy` object
  512. :param compare_type: comparison type for the L7 rule.
  513. :param type: the L7 rule type
  514. :param value:the value to use for the comparison.
  515. """
  516. raise NotImplementedError()
  517. @abc.abstractmethod
  518. def release_l7_rule(self, loadbalancer, l7_rule):
  519. """Release L7 rule.
  520. :param loadbalancer: `LBaaSLoadBalancer` object
  521. :param l7_rule: `LBaaSL7Rule` object
  522. """
  523. raise NotImplementedError()
  524. @abc.abstractmethod
  525. def update_l7_rule(self, l7_rule, new_value):
  526. """Update L7 rule value.
  527. :param l7_rule: `LBaaSL7Rule` object
  528. :param new_value: rule's new value
  529. """
  530. raise NotImplementedError()
  531. @abc.abstractmethod
  532. def is_pool_used_by_other_l7policies(l7policy, pool):
  533. """Checks if pool used by other L7policy.
  534. :param l7policy: `LBaaSL7Policy` object
  535. :param pool: `LBaaSPool` object
  536. """
  537. raise NotImplementedError()
  538. @six.add_metaclass(abc.ABCMeta)
  539. class VIFPoolDriver(PodVIFDriver):
  540. """Manages Pool of Neutron ports to provide VIFs for Kubernetes Pods."""
  541. ALIAS = 'vif_pool'
  542. @abc.abstractmethod
  543. def set_vif_driver(self, driver):
  544. """Sets the driver the Pool should use to manage resources
  545. The driver will be used for acquiring, releasing and updating the
  546. vif resources.
  547. """
  548. raise NotImplementedError()
  549. @six.add_metaclass(abc.ABCMeta)
  550. class ServicePubIpDriver(DriverBase):
  551. """Manages loadbalancerIP/public ip for neutron lbaas."""
  552. ALIAS = 'service_public_ip'
  553. @abc.abstractmethod
  554. def acquire_service_pub_ip_info(self, spec_type, spec_lb_ip, project_id,
  555. port_id_to_be_associated=None):
  556. """Get k8s service loadbalancer IP info based on service spec
  557. :param spec_type: service.spec.type field
  558. :param spec_lb_ip: service spec LoadBlaceIP field
  559. :param project_id: openstack project id
  560. :param port_id_to_be_associated: port id to associate
  561. """
  562. raise NotImplementedError()
  563. @abc.abstractmethod
  564. def release_pub_ip(self, service_pub_ip_info):
  565. """Release (if needed) based on service_pub_ip_info content
  566. :param service_pub_ip_info: service loadbalancer IP info
  567. :returns True/False
  568. """
  569. raise NotImplementedError()
  570. @abc.abstractmethod
  571. def associate_pub_ip(self, service_pub_ip_info, vip_port_id):
  572. """Associate loadbalancer IP to lbaas VIP port ID
  573. :param service_pub_ip_info: service loadbalancer IP info
  574. :param vip_port_id: Lbaas VIP port id
  575. """
  576. raise NotImplementedError()
  577. @abc.abstractmethod
  578. def disassociate_pub_ip(self, service_pub_ip_info):
  579. """Disassociate loadbalancer IP and lbaas VIP port ID
  580. :param service_pub_ip_info: service loadbalancer IP info
  581. """
  582. @six.add_metaclass(abc.ABCMeta)
  583. class NetworkPolicyDriver(DriverBase):
  584. """Provide network-policy for pods"""
  585. ALIAS = 'network_policy'
  586. @abc.abstractmethod
  587. def ensure_network_policy(self, policy, project_id):
  588. """Policy created or updated
  589. :param policy: dict containing Kubernetes NP object
  590. :param project_id: openstack project_id
  591. :returns: list of Pod objects affected by the network policy
  592. creation or its podSelector modification
  593. """
  594. raise NotImplementedError()
  595. @abc.abstractmethod
  596. def release_network_policy(self, kuryrnetpolicy):
  597. """Delete a network policy
  598. :param kuryrnetpolicy: dict containing Kuryrnetpolicy CRD object
  599. """
  600. raise NotImplementedError()
  601. @abc.abstractmethod
  602. def affected_pods(self, policy, selector=None):
  603. """Return affected pods by the policy
  604. This method returns the list of pod objects affected by the policy, or
  605. by the selector if it is specified.
  606. :param policy: dict containing Kubernetes NP object
  607. :param selector: (optional) specifc pod selector
  608. :returns: list of Pods objects affected by the policy or the selector
  609. if it is passed
  610. """
  611. raise NotImplementedError()
  612. @abc.abstractmethod
  613. def knps_on_namespace(self, namespace):
  614. """Check if there si kuryr network policy CRDs on the namespace
  615. This method returns true if there are knps on the specified namespace
  616. or false otherwise
  617. :param namespace: namespace name where the knps CRDs should be
  618. :returns: true if knps CRDs on the namespace, false otherwise
  619. """
  620. raise NotImplementedError()
  621. @abc.abstractmethod
  622. def namespaced_pods(self, policy):
  623. """Return pods on the policy namespace
  624. This method returns the pods on the network policy namespace
  625. :param policy: dict containing Kubernetes NP object
  626. :returns: list of Pods objects on the policy namespace
  627. """
  628. raise NotImplementedError()
  629. @abc.abstractmethod
  630. def get_kuryrnetpolicy_crd(self, policy):
  631. """Return kuryrnetpolicy CRD object associated to the policy
  632. :param policy: dict containing Kubernetes NP object
  633. :returns: kuryrnetpolicy CRD object associated to the policy
  634. """
  635. raise NotImplementedError()
  636. @six.add_metaclass(abc.ABCMeta)
  637. class NetworkPolicyProjectDriver(DriverBase):
  638. """Get an OpenStack project id for K8s network policies"""
  639. ALIAS = 'network_policy_project'
  640. @abc.abstractmethod
  641. def get_project(self, policy):
  642. """Get an OpenStack project id for K8s pod ports.
  643. :param policy: dict containing Kubernetes NP object
  644. :returns: OpenStack project_id
  645. """
  646. raise NotImplementedError()