def test_startup(self): common.default_logging() context = stub_zmq.Context() agent = felix.FelixAgent(config_path, context) set_expected_global_rules() stub_fiptables.check_state(expected_iptables) stub_ipsets.check_state(expected_ipsets) self.assertEqual(agent.hostname, "test_hostname")
def test_no_work(self): """ Test starting up, and sending no work at all. """ common.default_logging() context = stub_zmq.Context() agent = felix.FelixAgent(config_path, context) context.add_poll_result(0) agent.run() set_expected_global_rules() stub_fiptables.check_state(expected_iptables) stub_ipsets.check_state(expected_ipsets)
def test_empty_ipsets(self): """ Empty ipsets. """ description = "Description : blah" suffix = "whatever" rule_list = [] self.create_ipsets("inet") frules.update_ipsets(IPV4, description, suffix, rule_list, "ipset_addr", "ipset_port", "ipset_icmp", "tmp_ipset_addr", "tmp_ipset_port", "tmp_ipset_icmp") stub_ipsets.check_state(expected_ipsets)
def test_exception(self): """ Test exception when adding ipset value. """ description = "description" suffix = "suffix" rule_list = [{'cidr': "1.2.3.4/24"}] self.create_ipsets("inet") with mock.patch('calico.felix.test.stub_ipsets.add', side_effect=FailedSystemCall("oops", [], 1, "", "")): frules.update_ipsets(IPV4, description, suffix, rule_list, "ipset_addr", "ipset_port", "ipset_icmp", "tmp_ipset_addr", "tmp_ipset_port", "tmp_ipset_icmp") stub_ipsets.check_state(expected_ipsets)
def test_ipv6_ipsets(self): """ IPv6 ipsets """ description = "description" suffix = "suffix" rule_list = [] default_cidr = "2001::1:2:3:4/24" self.create_ipsets("inet6") # Ignored rules rule_list.append({'blah': "junk"}) # no CIDR rule_list.append({'cidr': "junk"}) # junk CIDR rule_list.append({'cidr': "1.2.3.4/32"}) # IPv4, not v6 rule_list.append({ 'cidr': default_cidr, 'port': 123 }) # port, no protocol rule_list.append({ 'cidr': default_cidr, 'protocol': "tcp", 'port': "blah" }) # bad port rule_list.append({ 'cidr': default_cidr, 'protocol': "tcp", 'port': ["blah", "bloop"] }) # bad port range rule_list.append({ 'cidr': default_cidr, 'protocol': "tcp", 'port': [0, 123] }) # bad port in range rule_list.append({ 'cidr': default_cidr, 'protocol': "tcp", 'port': [1, 2, 3] }) # not two in range rule_list.append({ 'cidr': default_cidr, 'protocol': "tcp", 'port': [1] }) # not two in range rule_list.append({ 'cidr': default_cidr, 'protocol': "icmp", 'port': "1" }) # port not allowed rule_list.append({ 'cidr': default_cidr, 'protocol': "ipv6-icmp", 'port': "1" }) # port not allowed rule_list.append({ 'cidr': default_cidr, 'protocol': "icmp", 'icmp_code': "1" }) # code without type rule_list.append({ 'cidr': default_cidr, 'protocol': "blah", 'port': "1" }) # port not allowed for protocol # Better rules rule_list.append({'cidr': "1:2:3::4/24"}) expected_ipsets.add("ipset_addr", "1:2:3::4/24") rule_list.append({'cidr': "1:2:3::/0", 'protocol': "tcp"}) expected_ipsets.add("ipset_port", "::/1,tcp:1-65535") expected_ipsets.add("ipset_port", "8000::/1,tcp:1-65535") rule_list.append({ 'cidr': "1::1/8", 'protocol': "udp", 'port': [2, 10] }) expected_ipsets.add("ipset_port", "1::1/8,udp:2-10") rule_list.append({'cidr': "1::2/8", 'protocol': "sctp", 'port': "2"}) expected_ipsets.add("ipset_port", "1::2/8,sctp:2") rule_list.append({ 'cidr': "1::3/8", 'protocol': "udplite", 'port': [2, 10] }) expected_ipsets.add("ipset_port", "1::3/8,udplite:2-10") rule_list.append({'cidr': "1::4/8", 'protocol': "ipv6-icmp"}) expected_ipsets.add("ipset_icmp", "1::4/8") rule_list.append({ 'cidr': "1::5/8", 'protocol': "ipv6-icmp", 'icmp_type': 123 }) expected_ipsets.add("ipset_port", "1::5/8,ipv6-icmp:123/0") rule_list.append({ 'cidr': "1::6/8", 'protocol': "ipv6-icmp", 'icmp_type': "type" }) expected_ipsets.add("ipset_port", "1::6/8,ipv6-icmp:type") rule_list.append({ 'cidr': "1::7/8", 'protocol': "ipv6-icmp", 'icmp_type': 123, 'icmp_code': "code" }) expected_ipsets.add("ipset_port", "1::7/8,ipv6-icmp:123/code") rule_list.append({ 'cidr': "1::8/8", 'protocol': "ipv6-icmp", 'icmp_type': "type", 'icmp_code': "code" }) # code ignored expected_ipsets.add("ipset_port", "1::8/8,ipv6-icmp:type") rule_list.append({'cidr': "1::9/8", 'protocol': "blah"}) expected_ipsets.add("ipset_port", "1::9/8,blah:0") frules.update_ipsets(IPV6, description, suffix, rule_list, "ipset_addr", "ipset_port", "ipset_icmp", "tmp_ipset_addr", "tmp_ipset_port", "tmp_ipset_icmp") stub_ipsets.check_state(expected_ipsets)
def test_main_flow(self): """ Test starting up and going through some of the basic flow. """ common.default_logging() context = stub_zmq.Context() agent = felix.FelixAgent(config_path, context) context.add_poll_result(0) agent.run() # Now we want to reply to the RESYNC request. resync_req = context.sent_data[TYPE_EP_REQ].pop() log.debug("Resync request : %s" % resync_req) self.assertFalse(context.sent_data_present()) resync_id = resync_req['resync_id'] resync_rsp = { 'type': "RESYNCSTATE", 'endpoint_count': 1, 'rc': "SUCCESS", 'message': "hello" } poll_result = context.add_poll_result(50) poll_result.add(TYPE_EP_REQ, resync_rsp) agent.run() # Felix expects one endpoint created message - give it what it wants endpoint_id = str(uuid.uuid4()) log.debug("Build first endpoint created : %s" % endpoint_id) mac = stub_utils.get_mac() suffix = endpoint_id[:11] tap = "tap" + suffix addr = '1.2.3.4' endpoint_created_req = { 'type': "ENDPOINTCREATED", 'endpoint_id': endpoint_id, 'resync_id': resync_id, 'issued': futils.time_ms(), 'mac': mac, 'state': Endpoint.STATE_ENABLED, 'addrs': [{ 'gateway': "1.2.3.1", 'addr': addr }] } poll_result = context.add_poll_result(100) poll_result.add(TYPE_EP_REP, endpoint_created_req) agent.run() log.debug("Create tap interface %s" % tap) tap_obj = stub_devices.TapInterface(tap) stub_devices.add_tap(tap_obj) poll_result = context.add_poll_result(150) agent.run() #*********************************************************************# #* As soon as that endpoint has been made to exist, we should see an *# #* ACL request coming through, and a response to the endpoint *# #* created. We send a reply to that now. *# #*********************************************************************# endpoint_created_rsp = context.sent_data[TYPE_EP_REP].pop() self.assertEqual(endpoint_created_rsp['rc'], "SUCCESS") acl_req = context.sent_data[TYPE_ACL_REQ].pop() self.assertFalse(context.sent_data_present()) self.assertEqual(acl_req['endpoint_id'], endpoint_id) acl_rsp = {'type': "GETACLSTATE", 'rc': "SUCCESS", 'message': ""} poll_result = context.add_poll_result(200) poll_result.add(TYPE_ACL_REQ, acl_rsp) # Check the rules are what we expect. set_expected_global_rules() add_endpoint_rules(suffix, tap, addr, None, mac) stub_fiptables.check_state(expected_iptables) add_endpoint_ipsets(suffix) stub_ipsets.check_state(expected_ipsets) # OK - now try giving it some ACLs, and see if they get applied correctly. acls = get_blank_acls() acls['v4']['outbound'].append({ 'cidr': "0.0.0.0/0", 'protocol': "icmp" }) acls['v4']['outbound'].append({ 'cidr': "1.2.3.0/24", 'protocol': "tcp" }) acls['v4']['outbound'].append({ 'cidr': "0.0.0.0/0", 'protocol': "tcp", 'port': "80" }) acls['v4']['inbound'].append({ 'cidr': "1.2.2.0/24", 'protocol': "icmp" }) acls['v4']['inbound'].append({ 'cidr': "0.0.0.0/0", 'protocol': "tcp", 'port': "8080" }) acls['v4']['inbound'].append({ 'cidr': "2.4.6.8/32", 'protocol': "udp", 'port': "8080" }) acls['v4']['inbound'].append({'cidr': "1.2.3.3/32"}) acls['v4']['inbound'].append({ 'cidr': "3.6.9.12/32", 'protocol': "tcp", 'port': ['10', '50'] }) acls['v4']['inbound'].append({ 'cidr': "5.4.3.2/32", 'protocol': "icmp", 'icmp_type': "3", 'icmp_code': "2" }) acls['v4']['inbound'].append({ 'cidr': "5.4.3.2/32", 'protocol': "icmp", 'icmp_type': "9" }) acls['v4']['inbound'].append({ 'cidr': "5.4.3.2/32", 'protocol': "icmp", 'icmp_type': "blah" }) # We include a couple of invalid rules that Felix will just ignore (and log). acls['v4']['inbound'].append({ 'cidr': "4.3.2.1/32", 'protocol': "tcp", 'port': ['blah', 'blah'] }) acls['v4']['inbound'].append({ 'cidr': "4.3.2.1/32", 'protocol': "tcp", 'port': ['1', '2', '3'] }) acls['v4']['inbound'].append({ 'cidr': "4.3.2.1/32", 'protocol': "tcp", 'port': 'flibble' }) acls['v4']['inbound'].append({'protocol': "tcp"}) acls['v4']['inbound'].append({'cidr': "4.3.2.1/32", 'port': "123"}) acls['v4']['inbound'].append({ 'cidr': "4.3.2.1/32", 'protocol': "icmp", 'icmp_code': "blah" }) acls['v4']['inbound'].append({ 'cidr': "4.3.2.1/32", 'protocol': "icmp", 'port': "1" }) acls['v4']['inbound'].append({ 'cidr': "4.3.2.1/32", 'protocol': "rsvp", 'port': "1" }) acl_req = {'type': "ACLUPDATE", 'acls': acls} poll_result.add(TYPE_ACL_SUB, acl_req, endpoint_id) agent.run() stub_fiptables.check_state(expected_iptables) expected_ipsets.add("felix-from-icmp-" + suffix, "0.0.0.0/1") expected_ipsets.add("felix-from-icmp-" + suffix, "128.0.0.0/1") expected_ipsets.add("felix-from-port-" + suffix, "1.2.3.0/24,tcp:0") expected_ipsets.add("felix-from-port-" + suffix, "0.0.0.0/1,tcp:80") expected_ipsets.add("felix-from-port-" + suffix, "128.0.0.0/1,tcp:80") expected_ipsets.add("felix-to-icmp-" + suffix, "1.2.2.0/24") expected_ipsets.add("felix-to-port-" + suffix, "0.0.0.0/1,tcp:8080") expected_ipsets.add("felix-to-port-" + suffix, "128.0.0.0/1,tcp:8080") expected_ipsets.add("felix-to-port-" + suffix, "2.4.6.8/32,udp:8080") expected_ipsets.add("felix-to-addr-" + suffix, "1.2.3.3/32") expected_ipsets.add("felix-to-port-" + suffix, "3.6.9.12/32,tcp:10-50") expected_ipsets.add("felix-to-port-" + suffix, "5.4.3.2/32,icmp:3/2") expected_ipsets.add("felix-to-port-" + suffix, "5.4.3.2/32,icmp:9/0") expected_ipsets.add("felix-to-port-" + suffix, "5.4.3.2/32,icmp:blah") stub_ipsets.check_state(expected_ipsets) # Add another endpoint, and check the state. endpoint_id2 = str(uuid.uuid4()) log.debug("Build second endpoint created : %s" % endpoint_id2) mac2 = stub_utils.get_mac() suffix2 = endpoint_id2[:11] tap2 = "tap" + suffix2 addr2 = '1.2.3.5' endpoint_created_req = { 'type': "ENDPOINTCREATED", 'endpoint_id': endpoint_id2, 'issued': futils.time_ms(), 'mac': mac2, 'state': Endpoint.STATE_ENABLED, 'addrs': [{ 'gateway': "1.2.3.1", 'addr': addr2 }] } poll_result = context.add_poll_result(250) poll_result.add(TYPE_EP_REP, endpoint_created_req) tap_obj2 = stub_devices.TapInterface(tap2) stub_devices.add_tap(tap_obj2) agent.run() # Check that we got what we expected - i.e. a success response, a GETACLSTATE, # and the rules in the right state. endpoint_created_rsp = context.sent_data[TYPE_EP_REP].pop() self.assertEqual(endpoint_created_rsp['rc'], "SUCCESS") acl_req = context.sent_data[TYPE_ACL_REQ].pop() self.assertEqual(acl_req['endpoint_id'], endpoint_id2) self.assertFalse(context.sent_data_present()) add_endpoint_rules(suffix2, tap2, addr2, None, mac2) stub_fiptables.check_state(expected_iptables) add_endpoint_ipsets(suffix2) stub_ipsets.check_state(expected_ipsets) # OK, finally wind down with an ENDPOINTDESTROYED message for that second endpoint. endpoint_destroyed_req = { 'type': "ENDPOINTDESTROYED", 'endpoint_id': endpoint_id2, 'issued': futils.time_ms() } poll_result = context.add_poll_result(300) poll_result.add(TYPE_EP_REP, endpoint_destroyed_req) stub_devices.del_tap(tap2) agent.run() # Rebuild and recheck the state. set_expected_global_rules() add_endpoint_rules(suffix, tap, addr, None, mac) stub_fiptables.check_state(expected_iptables)