示例#1
0
def test_resolver_endpoint_ids_by_selectors():
    resolver = EndpointResolver(test_endpoints)
    app1_ids = resolver.resolve_endpoint_ids(['id=app1'], [], [], 'default')

    assert 30391 in app1_ids
    assert 33243 in app1_ids
    assert len(app1_ids) == 2
示例#2
0
def test_resolver_endpoint_ids_by_names():
    resolver = EndpointResolver(test_endpoints)
    ids = resolver.resolve_endpoint_ids(
        [], ['default:app1-799c454b56-xcw8t', 'default:app3'], [], 'default')

    assert 30391 in ids
    assert 51796 in ids
    assert len(ids) == 2
示例#3
0
def test_resolver_retrieve_ep_ids():
    resolver = EndpointResolver(test_endpoints)

    ids = resolver.resolve_endpoint_ids([], [],
                                        ["10.0.0.1", "f00d::a0f:0:0:1687"],
                                        "default")

    assert 5766 in ids
    assert 30391 in ids
示例#4
0
    def run(self, monitor_args: MonitorArgs, nodes: List[str],
            cmd_override: str):

        api = core_v1_api.CoreV1Api()

        try:
            pods = api.list_namespaced_pod(self.namespace,
                                           label_selector='k8s-app=cilium')
        except ApiException as e:
            print('could not list Cilium pods: %s\n' % e)
            sys.exit(1)

        if nodes:
            names = [
                (pod.metadata.name, pod.spec.node_name) for pod in pods.items
                if pod.metadata.name in nodes or pod.spec.node_name in nodes
            ]
        else:
            names = [(pod.metadata.name, pod.spec.node_name)
                     for pod in pods.items]

        if not names:
            raise ValueError('No Cilium nodes in cluster match provided names'
                             ', or Cilium is not deployed')

        endpoints = self.retrieve_endpoint_data()
        pod_resolver = EndpointResolver(endpoints)

        if cmd_override:
            cmd = cmd_override.split(" ")
        else:
            cmd = self.get_monitor_command(monitor_args, names, pod_resolver)

        mode = ""

        if monitor_args.raw:
            mode = "raw"

        if monitor_args.verbose or cmd_override:
            mode = "verbose"

        self.monitors = [
            Monitor(name[0], name[1], self.namespace, self.data_queue,
                    self.close_queue, api, cmd, mode, pod_resolver)
            for name in names
        ]

        for m in self.monitors:
            m.process.start()
示例#5
0
    def get_monitor_command(self, args: MonitorArgs, names: List[str],
                            resolver: EndpointResolver) -> List[str]:
        related_ids = resolver.resolve_endpoint_ids(args.related_selectors,
                                                    args.related_pods,
                                                    args.related_ips,
                                                    self.endpoint_namespace)
        if (args.related_selectors or args.related_pods) and not related_ids:
            raise NoEndpointException("No related endpoints found")

        related_ids.update(args.related_endpoints)

        to_ids = resolver.resolve_endpoint_ids(args.to_selectors, args.to_pods,
                                               args.to_ips,
                                               self.endpoint_namespace)
        if (args.to_selectors or args.to_pods) and not to_ids:
            raise NoEndpointException("No to endpoints found")

        to_ids.update(args.to_endpoints)

        from_ids = resolver.resolve_endpoint_ids(args.from_selectors,
                                                 args.from_pods, args.from_ips,
                                                 self.endpoint_namespace)
        if (args.from_selectors or args.from_pods) and not from_ids:
            raise NoEndpointException("No from endpoints found")

        from_ids.update(args.from_endpoints)

        exec_command = ['cilium', 'monitor']

        if args.verbose:
            exec_command.append('-v')

        if args.hex:
            if '-v' not in exec_command:
                exec_command.append('-v')
            exec_command.append('--hex')

        if not args.hex and not args.verbose and not args.raw:
            exec_command.append('--json')

        if related_ids:
            for e in related_ids:
                exec_command.append('--related-to')
                exec_command.append(str(e))

        if to_ids:
            for e in to_ids:
                exec_command.append('--to')
                exec_command.append(str(e))

        if from_ids:
            for e in from_ids:
                exec_command.append('--from')
                exec_command.append(str(e))

        if args.types:
            for t in args.types:
                exec_command.append('--type')
                exec_command.append(t)

        print(exec_command)
        return exec_command
示例#6
0
def test_json_processor():
    resolver = EndpointResolver(test_endpoints)
    p = MonitorOutputProcessorJSON(resolver)

    p.add_out('{"type":"logRecord","observationPoint":"Ingress","flowType":')
    p.add_out('"Request","l7Proto":"http","srcEpID":0,"srcEpLabels":["k8s:i')
    p.add_out('o.kubernetes.pod.namespace=default","k8s:id=app2"],"srcIdent')
    p.add_out('ity":3338,"dstEpID":13949,"dstEpLabels":["k8s:id=app1","k8s:')
    p.add_out('io.kubernetes.pod.namespace=default"],"DstIdentity":45459,"v')
    p.add_out('erdict":"Denied","http":{"Code":403,"Method":"GET","URL":{"S')
    p.add_out('cheme":"http","Opaque":"","User":null,"Host":"app1-service",')
    p.add_out('"Path":"/private","RawPath":"","ForceQuery":false,"RawQuery"')
    p.add_out(':"","Fragment":""},"Protocol":"HTTP/1.1","Headers":{"Accept"')
    p.add_out(':["*/*"],"User-Agent":["curl/7.54.0"],"X-Request-Id":["05199')
    p.add_out('9d8-6987-4d79-9fad-729c87cb49ae"]}}}')

    p.add_out('{"type":"logRecord","observationPoi')
    p.add_out('nt":"Ingress","flowType":"Request",')
    p.add_out('"l7Proto":"kafka","srcEpID":0,"srcE')
    p.add_out('pLabels":["k8s:app=empire-backup","')
    p.add_out('k8s:io.kubernetes.pod.namespace=def')
    p.add_out('ault"],"srcIdentity":8370,"dstEpID"')
    p.add_out(':29381,"dstEpLabels":["k8s:io.kuber')
    p.add_out('netes.pod.namespace=default","k8s:a')
    p.add_out('pp=kafka"],"DstIdentity":12427,"ver')
    p.add_out('dict":"Forwarded","kafka":{"ErrorCo')
    p.add_out('de":0,"APIVersion":5,"APIKey":"fetc')
    p.add_out('h","CorrelationID":10,"Topic":{"Top')
    p.add_out('ic":"deathstar-plans"}}}')

    p.add_out("""
{
    "cpu": "CPU 01:",
    "type": "trace",
    "mark": "0xd3f88100",
    "ifindex": "lxca3b25",
    "state": "reply",
    "observationPoint": "to-endpoint",
    "traceSummary": "-> endpoint 5766",
    "source": 5766,
    "bytes": 66,
    "srcLabel": 49055,
    "dstLabel": 20496,
    "dstID": 5766,
    "summary": {
        "l2":{"src":"22:46:9b:ed:13:e9", "dst":"06:ea:01:96:66:ef"},
        "l3":{"src":"10.0.0.1", "dst":"10.0.0.2"},
        "l4":{"src":"80", "dst":"37934"}
    }
}
""")

    p.add_out("""
{
    "cpu": "CPU 00:",
    "type": "drop",
    "mark": "0xa9263786",
    "ifindex": "lxc05f8b",
    "reason": "Policy denied (L3)",
    "source": 5766,
    "bytes": 66,
    "srcLabel": 49055,
    "dstLabel": 20496,
    "dstID": 5766,
    "summary": {
        "l2":{"src":"22:46:9b:ed:13:e9", "dst":"06:ea:01:96:66:ef"},
        "l3":{"src":"10.0.0.1", "dst":"10.0.0.2"},
        "l4":{"src":"80", "dst":"37934"}
    }
}
""")

    p.add_out('{"type":"debug","message":"debug message","cpu":"CPU 01"}')

    p.add_out("""
{
    "cpu": "CPU 01:",
    "type": "capture",
    "mark": "0x8b0fe309",
    "message": "Delivery to ifindex 51",
    "source": 29898,
    "bytes": 66,
    "summary": "capture summary",
    "prefix": "-> cilium_health"
}
    """)

    p.add_out("""
{
    "type": "agent",
    "subtype": "Policy updated",
    "message": {
        "labels": [
            "unspec:io.cilium.k8s.policy.name=rule1",
            "unspec:io.cilium.k8s.policy.namespace=default"
        ],
        "revision": 10,
        "rule_count": 1
    }
}
    """)

    events = [x for x in p]

    assert len(events) == 7
    assert events[0] == (
        "(k8s:id=app2) => (k8s:id=app1) http GET /private Denied")

    assert events[1] == ("(k8s:app=empire-backup) => (k8s:app=kafka)"
                         " kafka fetch deathstar-plans Forwarded")

    assert events[2] == (
        "trace (default:app2 10.0.0.1:80) => (default:app1-799c454b56-xcw8t 10.0.0.2:37934)"  # noqa: E501
    )

    assert events[3] == (
        "drop: Policy denied (L3) (default:app2 10.0.0.1:80) => (default:app1-799c454b56-xcw8t 10.0.0.2:37934)"  # noqa: E501
    )

    assert events[4] == ("debug: debug message on CPU 01")

    assert events[5] == ("-> cilium_health: capture summary")

    assert events[6] == (
        "Policy updated: {'labels': ['unspec:io.cilium.k8s.policy.name=rule1', 'unspec:io.cilium.k8s.policy.namespace=default'], 'revision': 10, 'rule_count': 1}"  # noqa: E501
    )