def test_filters_clb_types(self): """ Only one CLB step is returned per CLB """ steps = pbag([ AddNodesToCLB(lb_id='5', address_configs=s( ('1.1.1.1', CLBDescription(lb_id='5', port=80)))), RemoveNodesFromCLB(lb_id='5', node_ids=s('1')), # Unoptimizable step CreateServer(server_config=pmap({})), ]) # returned steps could be pbag of any of the 2 lists below depending # on how `one_clb_step` iterates over the steps. Since it is pbag the # order of elements is not guaranteed list1 = [ AddNodesToCLB(lb_id='5', address_configs=s( ('1.1.1.1', CLBDescription(lb_id='5', port=80)))), CreateServer(server_config=pmap({})) ] list2 = [ RemoveNodesFromCLB(lb_id='5', node_ids=s('1')), CreateServer(server_config=pmap({})) ] self.assertEqual( matches(MatchesAny(Equals(pbag(list1)), Equals(pbag(list2)))), optimize_steps(steps))
def test_optimize_clb_adds_maintain_unique_ports(self): """ Multiple ports can be specified for the same address and LB ID when adding to a CLB. """ steps = pbag([ AddNodesToCLB(lb_id='5', address_configs=s( ('1.1.1.1', CLBDescription(lb_id='5', port=80)))), AddNodesToCLB(lb_id='5', address_configs=s( ('1.1.1.1', CLBDescription(lb_id='5', port=8080)))) ]) self.assertEqual( optimize_steps(steps), pbag([ AddNodesToCLB( lb_id='5', address_configs=s( ('1.1.1.1', CLBDescription(lb_id='5', port=80)), ('1.1.1.1', CLBDescription(lb_id='5', port=8080)))) ]))
def test_add_nodes_to_clbs(self): """Logs :obj:`AddNodesToCLB`.""" adds = pbag([ AddNodesToCLB(lb_id='lbid1', address_configs=pset([('10.0.0.1', _clbd('lbid1', 1234))])), AddNodesToCLB(lb_id='lbid1', address_configs=pset([('10.0.0.2', _clbd('lbid1', 1235))])), AddNodesToCLB(lb_id='lbid2', address_configs=pset([('10.0.0.1', _clbd('lbid2', 4321))])) ]) self.assert_logs(adds, [ Log('convergence-add-clb-nodes', fields={ 'lb_id': 'lbid1', 'addresses': ['10.0.0.1:1234', '10.0.0.2:1235'], 'cloud_feed': True }), Log('convergence-add-clb-nodes', fields={ 'lb_id': 'lbid2', 'addresses': ['10.0.0.1:4321'], 'cloud_feed': True }) ])
def add_server_to_lb(server, description, load_balancer): """ Add a server to a load balancing entity as described by `description`. :ivar server: The server to be added :type server: :class:`NovaServer` :ivar description: The description of the load balancer and how to add the server to it. :type description: :class:`ILBDescription` provider """ if isinstance(description, CLBDescription): if server.servicenet_address: if load_balancer is None: return fail_convergence( CLBHealthInfoNotFound(description.lb_id)) if load_balancer.health_monitor: description = assoc_obj(description, condition=CLBNodeCondition.DRAINING) return AddNodesToCLB( lb_id=description.lb_id, address_configs=pset( [(server.servicenet_address, description)])) elif isinstance(description, RCv3Description): return BulkAddToRCv3(lb_node_pairs=pset( [(description.lb_id, server.id)]))
def _add_one_node_to_clb(self): """ Return an effect from adding nodes to CLB. Uses 1 default node. """ lb_id = "12345" lb_nodes = pset([('1.2.3.4', CLBDescription(lb_id=lb_id, port=80))]) step = AddNodesToCLB(lb_id=lb_id, address_configs=lb_nodes) return step.as_effect()
def test_mixed(self): """ When there are multiple steps of same CLB then first step of each CLB is returned """ steps = [ CreateServer(server_config=pmap({"name": "server"})), DeleteServer(server_id="abc"), AddNodesToCLB(lb_id='5', address_configs=s( ('1.1.1.1', CLBDescription(lb_id='5', port=80)))), RemoveNodesFromCLB(lb_id='5', node_ids=s('1')), RemoveNodesFromCLB(lb_id='6', node_ids=s('3')), AddNodesToCLB(lb_id='6', address_configs=s( ('2.1.1.1', CLBDescription(lb_id='6', port=80)))), ChangeCLBNode(lb_id='7', node_id='9', condition=CLBNodeCondition.ENABLED, weight=10, type=CLBNodeType.PRIMARY), RemoveNodesFromCLB(lb_id='7', node_ids=s('4')), AddNodesToCLB(lb_id='7', address_configs=s( ('3.1.1.1', CLBDescription(lb_id='9', port=80)))), ChangeCLBNode(lb_id='5', node_id='11', condition=CLBNodeCondition.ENABLED, weight=10, type=CLBNodeType.PRIMARY) ] self.assertEqual( list(one_clb_step(steps)), ( steps[:3] + # Non-CLB steps and 1 step for CLB 5 [steps[4]] + # One step for CLB 6 [steps[6]]) # One step for CLB 7 )
def test_optimize_clb_adds(self): """ Multiple :class:`AddNodesToCLB` steps for the same LB are merged into one. """ steps = pbag([ AddNodesToCLB(lb_id='5', address_configs=s( ('1.1.1.1', CLBDescription(lb_id='5', port=80)))), AddNodesToCLB(lb_id='5', address_configs=s( ('1.2.3.4', CLBDescription(lb_id='5', port=80)))) ]) self.assertEqual( optimize_steps(steps), pbag([ AddNodesToCLB( lb_id='5', address_configs=s( ('1.1.1.1', CLBDescription(lb_id='5', port=80)), ('1.2.3.4', CLBDescription(lb_id='5', port=80)))) ]))
def test_optimize_leaves_other_steps(self): """ Unoptimizable steps pass the optimizer unchanged. """ steps = pbag([ AddNodesToCLB(lb_id='5', address_configs=s( ('1.1.1.1', CLBDescription(lb_id='5', port=80)))), RemoveNodesFromCLB(lb_id='6', node_ids=s('1')), CreateServer(server_config=pmap({})), BulkRemoveFromRCv3(lb_node_pairs=pset([("lb-1", "node-a")])), BulkAddToRCv3(lb_node_pairs=pset([("lb-2", "node-b")])) # Note that the add & remove pair should not be the same; # the optimizer might reasonably optimize opposite # operations away in the future. ]) self.assertEqual(optimize_steps(steps), steps)
def test_mixed_optimization(self): """ Mixes of optimizable and unoptimizable steps still get optimized correctly. """ steps = pbag([ # CLB adds AddNodesToCLB(lb_id='5', address_configs=s( ('1.1.1.1', CLBDescription(lb_id='5', port=80)))), AddNodesToCLB(lb_id='5', address_configs=s( ('1.1.1.2', CLBDescription(lb_id='5', port=80)))), AddNodesToCLB(lb_id='6', address_configs=s( ('1.1.1.1', CLBDescription(lb_id='6', port=80)))), AddNodesToCLB(lb_id='6', address_configs=s( ('1.1.1.2', CLBDescription(lb_id='6', port=80)))), RemoveNodesFromCLB(lb_id='5', node_ids=s('1')), RemoveNodesFromCLB(lb_id='5', node_ids=s('2')), RemoveNodesFromCLB(lb_id='6', node_ids=s('3')), RemoveNodesFromCLB(lb_id='6', node_ids=s('4')), # Unoptimizable steps CreateServer(server_config=pmap({})), ]) self.assertEqual( optimize_steps(steps), pbag([ # Optimized CLB adds AddNodesToCLB( lb_id='5', address_configs=s( ('1.1.1.1', CLBDescription(lb_id='5', port=80)), ('1.1.1.2', CLBDescription(lb_id='5', port=80)))), AddNodesToCLB( lb_id='6', address_configs=s( ('1.1.1.1', CLBDescription(lb_id='6', port=80)), ('1.1.1.2', CLBDescription(lb_id='6', port=80)))), RemoveNodesFromCLB(lb_id='5', node_ids=s('1', '2')), RemoveNodesFromCLB(lb_id='6', node_ids=s('3', '4')), # Unoptimizable steps CreateServer(server_config=pmap({})) ]))
def test_add_nodes_to_clb(self): """ :obj:`AddNodesToCLB` produces a request for adding any number of nodes to a cloud load balancer. """ lb_id = "12345" lb_nodes = pset([ ('1.2.3.4', CLBDescription(lb_id=lb_id, port=80)), ('1.2.3.4', CLBDescription(lb_id=lb_id, port=8080)), ('2.3.4.5', CLBDescription(lb_id=lb_id, port=80)) ]) step = AddNodesToCLB(lb_id=lb_id, address_configs=lb_nodes) eff = step.as_effect() self.assertEqual( eff.intent, service_request( ServiceType.CLOUD_LOAD_BALANCERS, 'POST', "loadbalancers/12345/nodes", json_response=True, success_pred=ANY, data={"nodes": ANY}).intent) node_data = sorted(eff.intent.data['nodes'], key=lambda n: (n['address'], n['port'])) self.assertEqual(node_data, [ {'address': '1.2.3.4', 'port': 80, 'condition': 'ENABLED', 'type': 'PRIMARY', 'weight': 1}, {'address': '1.2.3.4', 'port': 8080, 'condition': 'ENABLED', 'type': 'PRIMARY', 'weight': 1}, {'address': '2.3.4.5', 'port': 80, 'condition': 'ENABLED', 'type': 'PRIMARY', 'weight': 1} ])
def add_server_to_lb(server, description): """ Add a server to a load balancing entity as described by `description`. :ivar server: The server to be added :type server: :class:`NovaServer` :ivar description: The description of the load balancer and how to add the server to it. :type description: :class:`ILBDescription` provider """ if isinstance(description, CLBDescription): if server.servicenet_address: return AddNodesToCLB( lb_id=description.lb_id, address_configs=pset( [(server.servicenet_address, description)])) elif isinstance(description, RCv3Description): return BulkAddToRCv3(lb_node_pairs=pset( [(description.lb_id, server.id)]))
def test_clb_adds_multiple_load_balancers(self): """ Aggregation is done on a per-load-balancer basis when adding to a CLB. """ steps = pbag([ AddNodesToCLB(lb_id='5', address_configs=s( ('1.1.1.1', CLBDescription(lb_id='5', port=80)))), AddNodesToCLB(lb_id='5', address_configs=s( ('1.1.1.2', CLBDescription(lb_id='5', port=80)))), AddNodesToCLB(lb_id='6', address_configs=s( ('1.1.1.1', CLBDescription(lb_id='6', port=80)))), AddNodesToCLB(lb_id='6', address_configs=s( ('1.1.1.2', CLBDescription(lb_id='6', port=80)))), ]) self.assertEqual( optimize_steps(steps), pbag([ AddNodesToCLB( lb_id='5', address_configs=s( ('1.1.1.1', CLBDescription(lb_id='5', port=80)), ('1.1.1.2', CLBDescription(lb_id='5', port=80)))), AddNodesToCLB( lb_id='6', address_configs=s( ('1.1.1.1', CLBDescription(lb_id='6', port=80)), ('1.1.1.2', CLBDescription(lb_id='6', port=80)))), ]))