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 28KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831
  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. @six.add_metaclass(abc.ABCMeta)
  203. class ServiceSecurityGroupsDriver(DriverBase):
  204. """Provides security groups for Kubernetes Services."""
  205. ALIAS = 'service_security_groups'
  206. @abc.abstractmethod
  207. def get_security_groups(self, service, project_id):
  208. """Get a list of security groups' IDs for Service.
  209. :param service: dict containing Kubernetes Service object
  210. :param project_id: OpenStack project ID
  211. :return: list containing security groups' IDs
  212. """
  213. raise NotImplementedError()
  214. @six.add_metaclass(abc.ABCMeta)
  215. class PodVIFDriver(DriverBase):
  216. """Manages Neutron ports to provide VIFs for Kubernetes Pods."""
  217. ALIAS = 'pod_vif'
  218. @abc.abstractmethod
  219. def request_vif(self, pod, project_id, subnets, security_groups):
  220. """Links Neutron port to pod and returns it as VIF object.
  221. Implementing drivers must ensure the Neutron port satisfying the
  222. requested parameters is present and is valid for specified `pod`. It
  223. is up to the implementing drivers to either create new ports on each
  224. request or reuse available ports when possible.
  225. Implementing drivers may return a VIF object with its `active` field
  226. set to 'False' to indicate that Neutron port requires additional
  227. actions to enable network connectivity after VIF is plugged (e.g.
  228. setting up OpenFlow and/or iptables rules by OpenVSwitch agent). In
  229. that case the Controller will call driver's `activate_vif` method
  230. and the CNI plugin will block until it receives activation
  231. confirmation from the Controller.
  232. :param pod: dict containing Kubernetes Pod object
  233. :param project_id: OpenStack project ID
  234. :param subnets: dict containing subnet mapping as returned by
  235. `PodSubnetsDriver.get_subnets`. If multiple entries
  236. are present in that mapping, it is guaranteed that
  237. all entries have the same value of `Network.id`.
  238. :param security_groups: list containing security groups' IDs as
  239. returned by
  240. `PodSecurityGroupsDriver.get_security_groups`
  241. :return: VIF object
  242. """
  243. raise NotImplementedError()
  244. def request_vifs(self, pod, project_id, subnets, security_groups,
  245. num_ports):
  246. """Creates Neutron ports for pods and returns them as VIF objects list.
  247. It follows the same pattern as request_vif but creating the specified
  248. amount of ports and vif objects at num_ports parameter.
  249. The port creation request is generic as it not going to be used by the
  250. pod -- at least not all of them. Additionally, in order to save Neutron
  251. calls, the ports creation is handled in a bulk request.
  252. :param pod: dict containing Kubernetes Pod object
  253. :param project_id: OpenStack project ID
  254. :param subnets: dict containing subnet mapping as returned by
  255. `PodSubnetsDriver.get_subnets`. If multiple entries
  256. are present in that mapping, it is guaranteed that
  257. all entries have the same value of `Network.id`.
  258. :param security_groups: list containing security groups' IDs as
  259. returned by
  260. `PodSecurityGroupsDriver.get_security_groups`
  261. :param num_ports: number of ports to be created
  262. :return: VIF objects list
  263. """
  264. raise NotImplementedError()
  265. @abc.abstractmethod
  266. def release_vif(self, pod, vif, project_id=None, security_groups=None):
  267. """Unlinks Neutron port corresponding to VIF object from pod.
  268. Implementing drivers must ensure the port is either deleted or made
  269. available for reuse by `PodVIFDriver.request_vif`.
  270. :param pod: dict containing Kubernetes Pod object
  271. :param vif: VIF object as returned by `PodVIFDriver.request_vif`
  272. :param project_id: OpenStack project ID
  273. :param security_groups: list containing security groups'
  274. IDs as returned by
  275. `PodSecurityGroupsDriver.get_security_groups`
  276. """
  277. raise NotImplementedError()
  278. def release_vifs(self, pods, vifs, project_id=None, security_groups=None):
  279. """Unlinks Neutron ports corresponding to VIF objects.
  280. It follows the same pattern as release_vif but releasing num_ports
  281. ports. Ideally it will also make use of bulk request to save Neutron
  282. calls in the release/recycle process.
  283. :param pods: list of dict containing Kubernetes Pod objects
  284. :param vifs: list of VIF objects as returned by
  285. `PodVIFDriver.request_vif`
  286. :param project_id: (optional) OpenStack project ID
  287. :param security_groups: (optional) list containing security groups'
  288. IDs as returned by
  289. `PodSecurityGroupsDriver.get_security_groups`
  290. """
  291. raise NotImplementedError()
  292. @abc.abstractmethod
  293. def activate_vif(self, pod, vif):
  294. """Updates VIF to become active.
  295. Implementing drivers should update the specified `vif` object's
  296. `active` field to 'True' but must ensure that the corresponding
  297. Neutron port is fully configured (i.e. the container using the `vif`
  298. can access the requested network resources).
  299. Implementing drivers may raise `ResourceNotReady` exception to
  300. indicate that port activation should be retried later which will
  301. cause `activate_vif` to be called again with the same arguments.
  302. This method may be called before, after or while the VIF is being
  303. plugged by the CNI plugin.
  304. :param pod: dict containing Kubernetes Pod object
  305. :param vif: VIF object as returned by `PodVIFDriver.request_vif`
  306. """
  307. raise NotImplementedError()
  308. @abc.abstractmethod
  309. def update_vif_sgs(self, pod, security_groups):
  310. """Update VIF security groups.
  311. Implementing drivers should update the port associated to the pod
  312. with the specified security groups.
  313. :param pod: dict containing Kubernetes Pod object
  314. :param security_groups: list containing security groups' IDs as
  315. returned by
  316. `PodSecurityGroupsDriver.get_security_groups`
  317. """
  318. raise NotImplementedError()
  319. @six.add_metaclass(abc.ABCMeta)
  320. class MultiVIFDriver(DriverBase):
  321. """Manages additional ports of Kubernetes Pods."""
  322. ALIAS = 'multi_vif'
  323. @abc.abstractmethod
  324. def request_additional_vifs(
  325. self, pod, project_id, security_groups):
  326. """Links Neutron ports to pod and returns them as a list of VIF objects.
  327. Implementing drivers must be able to parse the additional interface
  328. definition from pod. The format of the definition is up to the
  329. implementation of each driver. Then implementing drivers must invoke
  330. the VIF drivers to either create new Neutron ports on each request or
  331. reuse available ports when possible.
  332. :param pod: dict containing Kubernetes Pod object
  333. :param project_id: OpenStack project ID
  334. :param security_groups: list containing security groups' IDs as
  335. returned by
  336. `PodSecurityGroupsDriver.get_security_groups`
  337. :return: VIF object list
  338. """
  339. raise NotImplementedError()
  340. @classmethod
  341. def get_enabled_drivers(cls):
  342. if _MULTI_VIF_DRIVERS:
  343. pass
  344. else:
  345. drivers = config.CONF.kubernetes['multi_vif_drivers']
  346. for driver in drivers:
  347. _MULTI_VIF_DRIVERS.append(cls.get_instance(driver))
  348. return _MULTI_VIF_DRIVERS
  349. class LBaaSDriver(DriverBase):
  350. """Base class for Openstack loadbalancer services."""
  351. ALIAS = 'endpoints_lbaas'
  352. @abc.abstractmethod
  353. def get_service_loadbalancer_name(self, namespace, svc_name):
  354. """Generate name of a load balancer that represents K8S service.
  355. In case a load balancer represents K8S service/ep, the handler
  356. should call first this API to get the load balancer name and use the
  357. return value of this function as 'name' parameter for the
  358. 'ensure_loadbalancer' function
  359. :param namespace: K8S service namespace
  360. :param svc_name: K8S service name
  361. """
  362. raise NotImplementedError()
  363. @abc.abstractmethod
  364. def ensure_loadbalancer(self, name, project_id, subnet_id, ip,
  365. security_groups_ids, service_type, provider):
  366. """Get or create load balancer.
  367. :param name: LoadBlancer name
  368. :param project_id: OpenStack project ID
  369. :param subnet_id: Neutron subnet ID to host load balancer
  370. :param ip: IP of the load balancer
  371. :param security_groups_ids: security groups that should be allowed
  372. access to the load balancer
  373. :param service_type: K8s service type (ClusterIP or LoadBalancer)
  374. :param provider: load balancer backend service
  375. """
  376. raise NotImplementedError()
  377. @abc.abstractmethod
  378. def release_loadbalancer(self, loadbalancer):
  379. """Release load balancer.
  380. Should return without errors if load balancer does not exist (e.g.
  381. already deleted).
  382. :param loadbalancer: `LBaaSLoadBalancer` object
  383. """
  384. raise NotImplementedError()
  385. @abc.abstractmethod
  386. def ensure_listener(self, loadbalancer, protocol, port):
  387. """Get or create listener.
  388. :param loadbalancer: `LBaaSLoadBalancer` object
  389. :param protocol: listener's protocol (only TCP is supported for now)
  390. :param port: listener's port
  391. """
  392. raise NotImplementedError()
  393. @abc.abstractmethod
  394. def release_listener(self, loadbalancer, listener):
  395. """Release listener.
  396. Should return without errors if listener or load balancer does not
  397. exist (e.g. already deleted).
  398. :param loadbalancer: `LBaaSLoadBalancer` object
  399. :param listener: `LBaaSListener` object
  400. """
  401. raise NotImplementedError()
  402. @abc.abstractmethod
  403. def ensure_pool(self, loadbalancer, listener):
  404. """Get or create pool attached to Listener.
  405. :param loadbalancer: `LBaaSLoadBalancer` object
  406. :param listener: `LBaaSListener` object
  407. """
  408. raise NotImplementedError()
  409. @abc.abstractmethod
  410. def ensure_pool_attached_to_lb(self, loadbalancer, namespace,
  411. svc_name, protocol):
  412. """Get or create pool attached to LoadBalancer.
  413. :param loadbalancer: `LBaaSLoadBalancer` object
  414. :param namespace: K8S service's namespace
  415. :param svc_name: K8S service's name
  416. :param protocol: pool's protocol
  417. """
  418. raise NotImplementedError()
  419. @abc.abstractmethod
  420. def get_loadbalancer_pool_name(self, loadbalancer, namespace, svc_name):
  421. """Get name of a load balancer's pool attached to LB.
  422. The pool's name should be unique per K8S service
  423. :param loadbalancer: `LBaaSLoadBalancer` object
  424. :param namespace: K8S service's namespace
  425. :param svc_name: K8S service's name
  426. """
  427. raise NotImplementedError()
  428. @abc.abstractmethod
  429. def release_pool(self, loadbalancer, pool):
  430. """Release pool.
  431. Should return without errors if pool or load balancer does not exist
  432. (e.g. already deleted).
  433. :param loadbalancer: `LBaaSLoadBalancer` object
  434. :param pool: `LBaaSPool` object
  435. """
  436. raise NotImplementedError()
  437. @abc.abstractmethod
  438. def ensure_member(self, loadbalancer, pool,
  439. subnet_id, ip, port, target_ref_namespace,
  440. target_ref_name):
  441. """Get or create member.
  442. :param loadbalancer: `LBaaSLoadBalancer` object
  443. :param pool: `LBaaSPool` object
  444. :param subnet_id: Neutron subnet ID of the target
  445. :param ip: target's IP (e.g. Pod's IP)
  446. :param port: target port
  447. :param target_ref_namespace: Kubernetes EP target_ref namespace
  448. :param target_ref_name: Kubernetes EP target_ref name
  449. """
  450. raise NotImplementedError()
  451. @abc.abstractmethod
  452. def release_member(self, loadbalancer, member):
  453. """Release member.
  454. Should return without errors if memberor load balancer does not exist
  455. (e.g. already deleted).
  456. :param loadbalancer: `LBaaSLoadBalancer` object
  457. :param member: `LBaaSMember` object
  458. """
  459. raise NotImplementedError()
  460. @abc.abstractmethod
  461. def get_lb_by_uuid(self, lb_uuid):
  462. """Get loadbalancer by loadbalancer uuid.
  463. :param lb_uuid: Loadbalancer uuid
  464. """
  465. raise NotImplementedError()
  466. @abc.abstractmethod
  467. def get_pool_by_name(self, pool_name, project_id):
  468. """Get pool by pool's name.
  469. :param pool_name: the pool name
  470. :param project_id: project id
  471. """
  472. raise NotImplementedError()
  473. @abc.abstractmethod
  474. def ensure_l7_policy(self, namespace, route_name, loadbalancer,
  475. pool, listener_id):
  476. """Get or create L7 policy.
  477. :param namespace: ocp-route/k8s-ingress namespace
  478. :param route_name: ocp-route/k8s-ingress name
  479. :param loadbalancer: `LBaaSLoadBalancer` object
  480. :param pool: L7 policy's target pool
  481. :param listener_id: ID of listener to attach L7policy to
  482. """
  483. raise NotImplementedError()
  484. @abc.abstractmethod
  485. def release_l7_policy(self, loadbalancer, l7_policy):
  486. """Release l7policy.
  487. :param loadbalancer: `LBaaSLoadBalancer` object
  488. :param l7_policy: `LBaaSL7Policy` object
  489. """
  490. raise NotImplementedError()
  491. @abc.abstractmethod
  492. def ensure_l7_rule(self, loadbalancer, l7_policy, compare_type,
  493. type, value):
  494. """Get or create L7 rule.
  495. :param loadbalancer: `LBaaSLoadBalancer` object
  496. :param l7_policy: `LBaaSL7Policy` object
  497. :param compare_type: comparison type for the L7 rule.
  498. :param type: the L7 rule type
  499. :param value:the value to use for the comparison.
  500. """
  501. raise NotImplementedError()
  502. @abc.abstractmethod
  503. def release_l7_rule(self, loadbalancer, l7_rule):
  504. """Release L7 rule.
  505. :param loadbalancer: `LBaaSLoadBalancer` object
  506. :param l7_rule: `LBaaSL7Rule` object
  507. """
  508. raise NotImplementedError()
  509. @abc.abstractmethod
  510. def update_l7_rule(self, l7_rule, new_value):
  511. """Update L7 rule value.
  512. :param l7_rule: `LBaaSL7Rule` object
  513. :param new_value: rule's new value
  514. """
  515. raise NotImplementedError()
  516. @abc.abstractmethod
  517. def is_pool_used_by_other_l7policies(l7policy, pool):
  518. """Checks if pool used by other L7policy.
  519. :param l7policy: `LBaaSL7Policy` object
  520. :param pool: `LBaaSPool` object
  521. """
  522. raise NotImplementedError()
  523. @six.add_metaclass(abc.ABCMeta)
  524. class VIFPoolDriver(PodVIFDriver):
  525. """Manages Pool of Neutron ports to provide VIFs for Kubernetes Pods."""
  526. ALIAS = 'vif_pool'
  527. @abc.abstractmethod
  528. def set_vif_driver(self, driver):
  529. """Sets the driver the Pool should use to manage resources
  530. The driver will be used for acquiring, releasing and updating the
  531. vif resources.
  532. """
  533. raise NotImplementedError()
  534. @six.add_metaclass(abc.ABCMeta)
  535. class ServicePubIpDriver(DriverBase):
  536. """Manages loadbalancerIP/public ip for neutron lbaas."""
  537. ALIAS = 'service_public_ip'
  538. @abc.abstractmethod
  539. def acquire_service_pub_ip_info(self, spec_type, spec_lb_ip, project_id,
  540. port_id_to_be_associated=None):
  541. """Get k8s service loadbalancer IP info based on service spec
  542. :param spec_type: service.spec.type field
  543. :param spec_lb_ip: service spec LoadBlaceIP field
  544. :param project_id: openstack project id
  545. :param port_id_to_be_associated: port id to associate
  546. """
  547. raise NotImplementedError()
  548. @abc.abstractmethod
  549. def release_pub_ip(self, service_pub_ip_info):
  550. """Release (if needed) based on service_pub_ip_info content
  551. :param service_pub_ip_info: service loadbalancer IP info
  552. :returns True/False
  553. """
  554. raise NotImplementedError()
  555. @abc.abstractmethod
  556. def associate_pub_ip(self, service_pub_ip_info, vip_port_id):
  557. """Associate loadbalancer IP to lbaas VIP port ID
  558. :param service_pub_ip_info: service loadbalancer IP info
  559. :param vip_port_id: Lbaas VIP port id
  560. """
  561. raise NotImplementedError()
  562. @abc.abstractmethod
  563. def disassociate_pub_ip(self, service_pub_ip_info):
  564. """Disassociate loadbalancer IP and lbaas VIP port ID
  565. :param service_pub_ip_info: service loadbalancer IP info
  566. """
  567. @six.add_metaclass(abc.ABCMeta)
  568. class NetworkPolicyDriver(DriverBase):
  569. """Provide network-policy for pods"""
  570. ALIAS = 'network_policy'
  571. @abc.abstractmethod
  572. def ensure_network_policy(self, policy, project_id):
  573. """Policy created or updated
  574. :param policy: dict containing Kubernetes NP object
  575. :param project_id: openstack project_id
  576. :returns: list of Pod objects affected by the network policy
  577. creation or its podSelector modification
  578. """
  579. raise NotImplementedError()
  580. @abc.abstractmethod
  581. def release_network_policy(self, kuryrnetpolicy):
  582. """Delete a network policy
  583. :param kuryrnetpolicy: dict containing Kuryrnetpolicy CRD object
  584. """
  585. raise NotImplementedError()
  586. @abc.abstractmethod
  587. def affected_pods(self, policy, selector=None):
  588. """Return affected pods by the policy
  589. This method returns the list of pod objects affected by the policy, or
  590. by the selector if it is specified.
  591. :param policy: dict containing Kubernetes NP object
  592. :param selector: (optional) specifc pod selector
  593. :returns: list of Pods objects affected by the policy or the selector
  594. if it is passed
  595. """
  596. raise NotImplementedError()
  597. @abc.abstractmethod
  598. def knps_on_namespace(self, namespace):
  599. """Check if there si kuryr network policy CRDs on the namespace
  600. This method returns true if there are knps on the specified namespace
  601. or false otherwise
  602. :param namespace: namespace name where the knps CRDs should be
  603. :returns: true if knps CRDs on the namespace, false otherwise
  604. """
  605. raise NotImplementedError()
  606. @abc.abstractmethod
  607. def namespaced_pods(self, policy):
  608. """Return pods on the policy namespace
  609. This method returns the pods on the network policy namespace
  610. :param policy: dict containing Kubernetes NP object
  611. :returns: list of Pods objects on the policy namespace
  612. """
  613. raise NotImplementedError()
  614. @abc.abstractmethod
  615. def get_kuryrnetpolicy_crd(self, policy):
  616. """Return kuryrnetpolicy CRD object associated to the policy
  617. :param policy: dict containing Kubernetes NP object
  618. :returns: kuryrnetpolicy CRD object associated to the policy
  619. """
  620. raise NotImplementedError()
  621. @six.add_metaclass(abc.ABCMeta)
  622. class NetworkPolicyProjectDriver(DriverBase):
  623. """Get an OpenStack project id for K8s network policies"""
  624. ALIAS = 'network_policy_project'
  625. @abc.abstractmethod
  626. def get_project(self, policy):
  627. """Get an OpenStack project id for K8s pod ports.
  628. :param policy: dict containing Kubernetes NP object
  629. :returns: OpenStack project_id
  630. """
  631. raise NotImplementedError()