{"action":"created","comment":{"url":"https://api.github.com/repos/projectcalico/k8s-policy/pulls/comments/62744418","id":62744418,"diff_hunk":"@@ -14,35 +14,140 @@ def __init__(self, msg=None, policy=None):\n \n \n class PolicyParser(object):\n+    \"\"\"\n+    Parser for Kubernetes NetworkPolicy API objects.\n+\n+    They are defined by the NetworkPolicySpec in the /apis/networking API\n+    group.\n+    \"\"\"\n     def __init__(self, policy):\n-        self.namespace = policy[\"metadata\"][\"namespace\"]\n+        \"\"\"\n+        Create a Parser for a Kubernetes NetworkPolicy API object.\n+\n+        Returns the parser.\n+        Throws PolicyError if the Policy is invalid.\n+        \"\"\"\n         self.policy = policy\n+        try:\n+            self.namespace = self.policy[\"metadata\"][\"namespace\"]\n+        except KeyError:\n+            raise PolicyError(\n+                \"Policy object missing required fields metadata/namespace\",\n+                self.policy\n+            )\n+\n+    def calculate_pod_selector(self):\n+        \"\"\"\n+        Generate the Calico pod selector for this Policy.\n+\n+        Returns the pod selector in the Calico datamodel format.\n+        Throws PolicyError if the Policy is invalid or unsupported.\n+        \"\"\"\n+        _log.debug(\"Calculating pod selector\")\n+        try:\n+            k8s_selector = self.policy[\"spec\"][\"podSelector\"]\n+        except KeyError:\n+            raise PolicyError(\n+                \"Policy object missing required fields spec/podSelector\",\n+                self.policy\n+            )\n+\n+        # PodSelectors only select pods from the Policy's namespace.\n+        calico_selectors = [\"%s == '%s'\" %\n+            (K8S_NAMESPACE_LABEL, self.namespace)]\n+\n+        # An empty PodSelector matches all pods in the namespace.\n+        if k8s_selector:\n+            calico_selectors += self._calculate_selectors(k8s_selector)\n+      \n+        _log.debug(\"Selector with %d filters\" % len(calico_selectors))\n+        return \" && \".join(calico_selectors)\n \n     def calculate_inbound_rules(self):\n         \"\"\"\n-        Takes a NetworkPolicy object from the API and returns a list of\n-        Calico Rule objects which should be applied on ingress.\n+        Generate Calico Rule objects for this Policy's ingress rules.\n+\n+        Returns a list of Calico datamodel Rules.\n+        Throws PolicyError if the Policy is invalid or unsupported.\n         \"\"\"\n         _log.debug(\"Calculating inbound rules\")\n         rules = []\n \n-        # Iterate through and create the appropriate Calico Rule objects.\n-        allow_incomings = self.policy[\"spec\"].get(\"ingress\") or []\n-        _log.debug(\"Found %s ingress rules\", len(allow_incomings))\n-        for allow_incoming_clause in allow_incomings:\n-            # Convert each allow_incoming_clause into one or more\n-            # Calico Rule objects.\n-            if allow_incoming_clause:\n-                # Rule exists - parse it.\n-                r = self._allow_incoming_to_rules(allow_incoming_clause)\n-            else:\n-                # An empty rule means allow all traffic.\n-                r = [Rule(action=\"allow\")]\n-            rules.extend(r)\n+        ingress_rules = self.policy[\"spec\"].get(\"ingress\")\n+        if ingress_rules:","path":"policy_parser.py","position":80,"original_position":80,"commit_id":"d70588e67c94d7297c78b3dfc38702ccd46ba1f8","original_commit_id":"d70588e67c94d7297c78b3dfc38702ccd46ba1f8","user":{"login":"caseydavenport","id":1944093,"avatar_url":"https://avatars.githubusercontent.com/u/1944093?v=3","gravatar_id":"","url":"https://api.github.com/users/caseydavenport","html_url":"https://github.com/caseydavenport","followers_url":"https://api.github.com/users/caseydavenport/followers","following_url":"https://api.github.com/users/caseydavenport/following{/other_user}","gists_url":"https://api.github.com/users/caseydavenport/gists{/gist_id}","starred_url":"https://api.github.com/users/caseydavenport/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/caseydavenport/subscriptions","organizations_url":"https://api.github.com/users/caseydavenport/orgs","repos_url":"https://api.github.com/users/caseydavenport/repos","events_url":"https://api.github.com/users/caseydavenport/events{/privacy}","received_events_url":"https://api.github.com/users/caseydavenport/received_events","type":"User","site_admin":false},"body":"I think this should be `if not ingress_rules:`","created_at":"2016-05-10T20:20:25Z","updated_at":"2016-05-10T20:20:25Z","html_url":"https://github.com/projectcalico/k8s-policy/pull/26#discussion_r62744418","pull_request_url":"https://api.github.com/repos/projectcalico/k8s-policy/pulls/26","_links":{"self":{"href":"https://api.github.com/repos/projectcalico/k8s-policy/pulls/comments/62744418"},"html":{"href":"https://github.com/projectcalico/k8s-policy/pull/26#discussion_r62744418"},"pull_request":{"href":"https://api.github.com/repos/projectcalico/k8s-policy/pulls/26"}}},"pull_request":{"url":"https://api.github.com/repos/projectcalico/k8s-policy/pulls/26","id":69556264,"html_url":"https://github.com/projectcalico/k8s-policy/pull/26","diff_url":"https://github.com/projectcalico/k8s-policy/pull/26.diff","patch_url":"https://github.com/projectcalico/k8s-policy/pull/26.patch","issue_url":"https://api.github.com/repos/projectcalico/k8s-policy/issues/26","number":26,"state":"open","locked":false,"title":"Selectors","user":{"login":"matthewdupre","id":9053570,"avatar_url":"https://avatars.githubusercontent.com/u/9053570?v=3","gravatar_id":"","url":"https://api.github.com/users/matthewdupre","html_url":"https://github.com/matthewdupre","followers_url":"https://api.github.com/users/matthewdupre/followers","following_url":"https://api.github.com/users/matthewdupre/following{/other_user}","gists_url":"https://api.github.com/users/matthewdupre/gists{/gist_id}","starred_url":"https://api.github.com/users/matthewdupre/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/matthewdupre/subscriptions","organizations_url":"https://api.github.com/users/matthewdupre/orgs","repos_url":"https://api.github.com/users/matthewdupre/repos","events_url":"https://api.github.com/users/matthewdupre/events{/privacy}","received_events_url":"https://api.github.com/users/matthewdupre/received_events","type":"User","site_admin":false},"body":"","created_at":"2016-05-10T18:40:03Z","updated_at":"2016-05-10T20:20:25Z","closed_at":null,"merged_at":null,"merge_commit_sha":"085814392fdf0a64a1d2c934e52e5808cafdfe41","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/projectcalico/k8s-policy/pulls/26/commits","review_comments_url":"https://api.github.com/repos/projectcalico/k8s-policy/pulls/26/comments","review_comment_url":"https://api.github.com/repos/projectcalico/k8s-policy/pulls/comments{/number}","comments_url":"https://api.github.com/repos/projectcalico/k8s-policy/issues/26/comments","statuses_url":"https://api.github.com/repos/projectcalico/k8s-policy/statuses/d70588e67c94d7297c78b3dfc38702ccd46ba1f8","head":{"label":"matthewdupre:selectors","ref":"selectors","sha":"d70588e67c94d7297c78b3dfc38702ccd46ba1f8","user":{"login":"matthewdupre","id":9053570,"avatar_url":"https://avatars.githubusercontent.com/u/9053570?v=3","gravatar_id":"","url":"https://api.github.com/users/matthewdupre","html_url":"https://github.com/matthewdupre","followers_url":"https://api.github.com/users/matthewdupre/followers","following_url":"https://api.github.com/users/matthewdupre/following{/other_user}","gists_url":"https://api.github.com/users/matthewdupre/gists{/gist_id}","starred_url":"https://api.github.com/users/matthewdupre/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/matthewdupre/subscriptions","organizations_url":"https://api.github.com/users/matthewdupre/orgs","repos_url":"https://api.github.com/users/matthewdupre/repos","events_url":"https://api.github.com/users/matthewdupre/events{/privacy}","received_events_url":"https://api.github.com/users/matthewdupre/received_events","type":"User","site_admin":false},"repo":{"id":58076084,"name":"k8s-policy","full_name":"matthewdupre/k8s-policy","owner":{"login":"matthewdupre","id":9053570,"avatar_url":"https://avatars.githubusercontent.com/u/9053570?v=3","gravatar_id":"","url":"https://api.github.com/users/matthewdupre","html_url":"https://github.com/matthewdupre","followers_url":"https://api.github.com/users/matthewdupre/followers","following_url":"https://api.github.com/users/matthewdupre/following{/other_user}","gists_url":"https://api.github.com/users/matthewdupre/gists{/gist_id}","starred_url":"https://api.github.com/users/matthewdupre/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/matthewdupre/subscriptions","organizations_url":"https://api.github.com/users/matthewdupre/orgs","repos_url":"https://api.github.com/users/matthewdupre/repos","events_url":"https://api.github.com/users/matthewdupre/events{/privacy}","received_events_url":"https://api.github.com/users/matthewdupre/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/matthewdupre/k8s-policy","description":"Calico policy agent for Kubernetes","fork":true,"url":"https://api.github.com/repos/matthewdupre/k8s-policy","forks_url":"https://api.github.com/repos/matthewdupre/k8s-policy/forks","keys_url":"https://api.github.com/repos/matthewdupre/k8s-policy/keys{/key_id}","collaborators_url":"https://api.github.com/repos/matthewdupre/k8s-policy/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/matthewdupre/k8s-policy/teams","hooks_url":"https://api.github.com/repos/matthewdupre/k8s-policy/hooks","issue_events_url":"https://api.github.com/repos/matthewdupre/k8s-policy/issues/events{/number}","events_url":"https://api.github.com/repos/matthewdupre/k8s-policy/events","assignees_url":"https://api.github.com/repos/matthewdupre/k8s-policy/assignees{/user}","branches_url":"https://api.github.com/repos/matthewdupre/k8s-policy/branches{/branch}","tags_url":"https://api.github.com/repos/matthewdupre/k8s-policy/tags","blobs_url":"https://api.github.com/repos/matthewdupre/k8s-policy/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/matthewdupre/k8s-policy/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/matthewdupre/k8s-policy/git/refs{/sha}","trees_url":"https://api.github.com/repos/matthewdupre/k8s-policy/git/trees{/sha}","statuses_url":"https://api.github.com/repos/matthewdupre/k8s-policy/statuses/{sha}","languages_url":"https://api.github.com/repos/matthewdupre/k8s-policy/languages","stargazers_url":"https://api.github.com/repos/matthewdupre/k8s-policy/stargazers","contributors_url":"https://api.github.com/repos/matthewdupre/k8s-policy/contributors","subscribers_url":"https://api.github.com/repos/matthewdupre/k8s-policy/subscribers","subscription_url":"https://api.github.com/repos/matthewdupre/k8s-policy/subscription","commits_url":"https://api.github.com/repos/matthewdupre/k8s-policy/commits{/sha}","git_commits_url":"https://api.github.com/repos/matthewdupre/k8s-policy/git/commits{/sha}","comments_url":"https://api.github.com/repos/matthewdupre/k8s-policy/comments{/number}","issue_comment_url":"https://api.github.com/repos/matthewdupre/k8s-policy/issues/comments{/number}","contents_url":"https://api.github.com/repos/matthewdupre/k8s-policy/contents/{+path}","compare_url":"https://api.github.com/repos/matthewdupre/k8s-policy/compare/{base}...{head}","merges_url":"https://api.github.com/repos/matthewdupre/k8s-policy/merges","archive_url":"https://api.github.com/repos/matthewdupre/k8s-policy/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/matthewdupre/k8s-policy/downloads","issues_url":"https://api.github.com/repos/matthewdupre/k8s-policy/issues{/number}","pulls_url":"https://api.github.com/repos/matthewdupre/k8s-policy/pulls{/number}","milestones_url":"https://api.github.com/repos/matthewdupre/k8s-policy/milestones{/number}","notifications_url":"https://api.github.com/repos/matthewdupre/k8s-policy/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/matthewdupre/k8s-policy/labels{/name}","releases_url":"https://api.github.com/repos/matthewdupre/k8s-policy/releases{/id}","deployments_url":"https://api.github.com/repos/matthewdupre/k8s-policy/deployments","created_at":"2016-05-04T18:49:27Z","updated_at":"2016-05-04T18:49:29Z","pushed_at":"2016-05-10T18:59:45Z","git_url":"git://github.com/matthewdupre/k8s-policy.git","ssh_url":"git@github.com:matthewdupre/k8s-policy.git","clone_url":"https://github.com/matthewdupre/k8s-policy.git","svn_url":"https://github.com/matthewdupre/k8s-policy","homepage":null,"size":75,"stargazers_count":0,"watchers_count":0,"language":"Python","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"projectcalico:master","ref":"master","sha":"4aa4c1688721d61dc6a4d92709ace4b392c8678f","user":{"login":"projectcalico","id":12304728,"avatar_url":"https://avatars.githubusercontent.com/u/12304728?v=3","gravatar_id":"","url":"https://api.github.com/users/projectcalico","html_url":"https://github.com/projectcalico","followers_url":"https://api.github.com/users/projectcalico/followers","following_url":"https://api.github.com/users/projectcalico/following{/other_user}","gists_url":"https://api.github.com/users/projectcalico/gists{/gist_id}","starred_url":"https://api.github.com/users/projectcalico/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/projectcalico/subscriptions","organizations_url":"https://api.github.com/users/projectcalico/orgs","repos_url":"https://api.github.com/users/projectcalico/repos","events_url":"https://api.github.com/users/projectcalico/events{/privacy}","received_events_url":"https://api.github.com/users/projectcalico/received_events","type":"Organization","site_admin":false},"repo":{"id":52315446,"name":"k8s-policy","full_name":"projectcalico/k8s-policy","owner":{"login":"projectcalico","id":12304728,"avatar_url":"https://avatars.githubusercontent.com/u/12304728?v=3","gravatar_id":"","url":"https://api.github.com/users/projectcalico","html_url":"https://github.com/projectcalico","followers_url":"https://api.github.com/users/projectcalico/followers","following_url":"https://api.github.com/users/projectcalico/following{/other_user}","gists_url":"https://api.github.com/users/projectcalico/gists{/gist_id}","starred_url":"https://api.github.com/users/projectcalico/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/projectcalico/subscriptions","organizations_url":"https://api.github.com/users/projectcalico/orgs","repos_url":"https://api.github.com/users/projectcalico/repos","events_url":"https://api.github.com/users/projectcalico/events{/privacy}","received_events_url":"https://api.github.com/users/projectcalico/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/projectcalico/k8s-policy","description":"Calico policy agent for Kubernetes","fork":false,"url":"https://api.github.com/repos/projectcalico/k8s-policy","forks_url":"https://api.github.com/repos/projectcalico/k8s-policy/forks","keys_url":"https://api.github.com/repos/projectcalico/k8s-policy/keys{/key_id}","collaborators_url":"https://api.github.com/repos/projectcalico/k8s-policy/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/projectcalico/k8s-policy/teams","hooks_url":"https://api.github.com/repos/projectcalico/k8s-policy/hooks","issue_events_url":"https://api.github.com/repos/projectcalico/k8s-policy/issues/events{/number}","events_url":"https://api.github.com/repos/projectcalico/k8s-policy/events","assignees_url":"https://api.github.com/repos/projectcalico/k8s-policy/assignees{/user}","branches_url":"https://api.github.com/repos/projectcalico/k8s-policy/branches{/branch}","tags_url":"https://api.github.com/repos/projectcalico/k8s-policy/tags","blobs_url":"https://api.github.com/repos/projectcalico/k8s-policy/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/projectcalico/k8s-policy/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/projectcalico/k8s-policy/git/refs{/sha}","trees_url":"https://api.github.com/repos/projectcalico/k8s-policy/git/trees{/sha}","statuses_url":"https://api.github.com/repos/projectcalico/k8s-policy/statuses/{sha}","languages_url":"https://api.github.com/repos/projectcalico/k8s-policy/languages","stargazers_url":"https://api.github.com/repos/projectcalico/k8s-policy/stargazers","contributors_url":"https://api.github.com/repos/projectcalico/k8s-policy/contributors","subscribers_url":"https://api.github.com/repos/projectcalico/k8s-policy/subscribers","subscription_url":"https://api.github.com/repos/projectcalico/k8s-policy/subscription","commits_url":"https://api.github.com/repos/projectcalico/k8s-policy/commits{/sha}","git_commits_url":"https://api.github.com/repos/projectcalico/k8s-policy/git/commits{/sha}","comments_url":"https://api.github.com/repos/projectcalico/k8s-policy/comments{/number}","issue_comment_url":"https://api.github.com/repos/projectcalico/k8s-policy/issues/comments{/number}","contents_url":"https://api.github.com/repos/projectcalico/k8s-policy/contents/{+path}","compare_url":"https://api.github.com/repos/projectcalico/k8s-policy/compare/{base}...{head}","merges_url":"https://api.github.com/repos/projectcalico/k8s-policy/merges","archive_url":"https://api.github.com/repos/projectcalico/k8s-policy/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/projectcalico/k8s-policy/downloads","issues_url":"https://api.github.com/repos/projectcalico/k8s-policy/issues{/number}","pulls_url":"https://api.github.com/repos/projectcalico/k8s-policy/pulls{/number}","milestones_url":"https://api.github.com/repos/projectcalico/k8s-policy/milestones{/number}","notifications_url":"https://api.github.com/repos/projectcalico/k8s-policy/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/projectcalico/k8s-policy/labels{/name}","releases_url":"https://api.github.com/repos/projectcalico/k8s-policy/releases{/id}","deployments_url":"https://api.github.com/repos/projectcalico/k8s-policy/deployments","created_at":"2016-02-22T23:59:25Z","updated_at":"2016-05-04T07:57:01Z","pushed_at":"2016-05-10T18:59:46Z","git_url":"git://github.com/projectcalico/k8s-policy.git","ssh_url":"git@github.com:projectcalico/k8s-policy.git","clone_url":"https://github.com/projectcalico/k8s-policy.git","svn_url":"https://github.com/projectcalico/k8s-policy","homepage":null,"size":71,"stargazers_count":5,"watchers_count":5,"language":"Python","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":3,"mirror_url":null,"open_issues_count":5,"forks":3,"open_issues":5,"watchers":5,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/projectcalico/k8s-policy/pulls/26"},"html":{"href":"https://github.com/projectcalico/k8s-policy/pull/26"},"issue":{"href":"https://api.github.com/repos/projectcalico/k8s-policy/issues/26"},"comments":{"href":"https://api.github.com/repos/projectcalico/k8s-policy/issues/26/comments"},"review_comments":{"href":"https://api.github.com/repos/projectcalico/k8s-policy/pulls/26/comments"},"review_comment":{"href":"https://api.github.com/repos/projectcalico/k8s-policy/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/projectcalico/k8s-policy/pulls/26/commits"},"statuses":{"href":"https://api.github.com/repos/projectcalico/k8s-policy/statuses/d70588e67c94d7297c78b3dfc38702ccd46ba1f8"}}}}