{"action":"created","comment":{"url":"https://api.github.com/repos/noironetworks/python-opflex-agent/pulls/comments/43210048","id":43210048,"diff_hunk":"@@ -277,15 +277,68 @@ def port_bound(self, port, net_uuid,\n                     port, net_uuid, network_type, physical_network,\n                     segmentation_id, fixed_ips, device_owner, ovs_restarted)\n         elif network_type in self.supported_pt_network_types:\n+            # PT cleanup is needed before writing the new endpoint files\n+            self.mapping_cleanup(port.vif_id, cleanup_vrf=False)\n             if ((self.opflex_networks is None) or\n                     (physical_network in self.opflex_networks)):\n                 # Port has to be untagged due to a opflex agent requirement\n                 self.int_br.clear_db_attribute(\"Port\", port.port_name, \"tag\")\n-                self.mapping_to_file(port, net_uuid, mapping, fixed_ips,\n+                # Multiple files will be created based on how many MAC\n+                # addresses are owned by the specific port.\n+                mapping_copy = copy.deepcopy(mapping)\n+                mac_aap_map = {}\n+                mapping_copy['allowed_address_pairs'] = []\n+                mapping_copy['floating_ip'] = []\n+                fip_by_fixed = {}\n+                original_mac = mapping.get('mac_address') or port.vif_mac\n+                # Prepare FIPs by fixed_ip\n+                for fip in mapping.get('floating_ip', []):\n+                    fip_by_fixed.setdefault(\n+                        fip['fixed_ip_address'], []).append(fip)\n+                # For the main MAC, set floating IP collection to all those\n+                # FIPs pointing to the Port fixed ips.\n+                for fixed in fixed_ips:\n+                    mapping_copy['floating_ip'].extend(\n+                        fip_by_fixed.get(fixed['ip_address'], []))\n+\n+                # For the main MAC EP, set al the AAP with no mac address or\n+                # MAC address equal to the original MAC.\n+                for aap in mapping.get('allowed_address_pairs', []):\n+                    if not aap.get('mac_address') or aap.get(\n+                            'mac_address') == original_mac:\n+                        # Should go with the MAIN mac address EP file\n+                        mapping_copy['allowed_address_pairs'].append(aap)","path":"opflexagent/gbp_ovs_agent.py","position":35,"original_position":35,"commit_id":"527560bdcd0fd7169b5a734dc9d54d2cb6e2afaf","original_commit_id":"527560bdcd0fd7169b5a734dc9d54d2cb6e2afaf","user":{"login":"amittbose","id":8573271,"avatar_url":"https://avatars.githubusercontent.com/u/8573271?v=3","gravatar_id":"","url":"https://api.github.com/users/amittbose","html_url":"https://github.com/amittbose","followers_url":"https://api.github.com/users/amittbose/followers","following_url":"https://api.github.com/users/amittbose/following{/other_user}","gists_url":"https://api.github.com/users/amittbose/gists{/gist_id}","starred_url":"https://api.github.com/users/amittbose/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/amittbose/subscriptions","organizations_url":"https://api.github.com/users/amittbose/orgs","repos_url":"https://api.github.com/users/amittbose/repos","events_url":"https://api.github.com/users/amittbose/events{/privacy}","received_events_url":"https://api.github.com/users/amittbose/received_events","type":"User","site_admin":false},"body":"Are you creating an EP file for an inactive AAP with a different MAC? If yes, then it'll probably be fine. This is kind of confusing though because the additional EP file is really for an AAP (=virtual-ip), and having another virtual-IP section in it is just odd.\r\nNote that if you are creating this file for inactive AAPs, then the promotion of AAP to fixed-IP needs to happen only for active AAPs.  ","created_at":"2015-10-28T01:22:59Z","updated_at":"2015-10-28T01:22:59Z","html_url":"https://github.com/noironetworks/python-opflex-agent/pull/10#discussion_r43210048","pull_request_url":"https://api.github.com/repos/noironetworks/python-opflex-agent/pulls/10","_links":{"self":{"href":"https://api.github.com/repos/noironetworks/python-opflex-agent/pulls/comments/43210048"},"html":{"href":"https://github.com/noironetworks/python-opflex-agent/pull/10#discussion_r43210048"},"pull_request":{"href":"https://api.github.com/repos/noironetworks/python-opflex-agent/pulls/10"}}},"pull_request":{"url":"https://api.github.com/repos/noironetworks/python-opflex-agent/pulls/10","id":48414834,"html_url":"https://github.com/noironetworks/python-opflex-agent/pull/10","diff_url":"https://github.com/noironetworks/python-opflex-agent/pull/10.diff","patch_url":"https://github.com/noironetworks/python-opflex-agent/pull/10.patch","issue_url":"https://api.github.com/repos/noironetworks/python-opflex-agent/issues/10","number":10,"state":"open","locked":false,"title":"create multiple EP files per MAC address","user":{"login":"ivar-lazzaro","id":6353941,"avatar_url":"https://avatars.githubusercontent.com/u/6353941?v=3","gravatar_id":"","url":"https://api.github.com/users/ivar-lazzaro","html_url":"https://github.com/ivar-lazzaro","followers_url":"https://api.github.com/users/ivar-lazzaro/followers","following_url":"https://api.github.com/users/ivar-lazzaro/following{/other_user}","gists_url":"https://api.github.com/users/ivar-lazzaro/gists{/gist_id}","starred_url":"https://api.github.com/users/ivar-lazzaro/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ivar-lazzaro/subscriptions","organizations_url":"https://api.github.com/users/ivar-lazzaro/orgs","repos_url":"https://api.github.com/users/ivar-lazzaro/repos","events_url":"https://api.github.com/users/ivar-lazzaro/events{/privacy}","received_events_url":"https://api.github.com/users/ivar-lazzaro/received_events","type":"User","site_admin":false},"body":"allow_address_pairs extension in Neutron allows multiple MAC\r\naddresses to exist for the same port. Create one EP file for each\r\nMAC as per the opflex afgent specifications.","created_at":"2015-10-22T03:45:50Z","updated_at":"2015-10-28T01:22:59Z","closed_at":null,"merged_at":null,"merge_commit_sha":"e3c9d19ed88c30eb87dbe2ce7b220b30b64d5956","assignee":{"login":"amittbose","id":8573271,"avatar_url":"https://avatars.githubusercontent.com/u/8573271?v=3","gravatar_id":"","url":"https://api.github.com/users/amittbose","html_url":"https://github.com/amittbose","followers_url":"https://api.github.com/users/amittbose/followers","following_url":"https://api.github.com/users/amittbose/following{/other_user}","gists_url":"https://api.github.com/users/amittbose/gists{/gist_id}","starred_url":"https://api.github.com/users/amittbose/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/amittbose/subscriptions","organizations_url":"https://api.github.com/users/amittbose/orgs","repos_url":"https://api.github.com/users/amittbose/repos","events_url":"https://api.github.com/users/amittbose/events{/privacy}","received_events_url":"https://api.github.com/users/amittbose/received_events","type":"User","site_admin":false},"milestone":null,"commits_url":"https://api.github.com/repos/noironetworks/python-opflex-agent/pulls/10/commits","review_comments_url":"https://api.github.com/repos/noironetworks/python-opflex-agent/pulls/10/comments","review_comment_url":"https://api.github.com/repos/noironetworks/python-opflex-agent/pulls/comments{/number}","comments_url":"https://api.github.com/repos/noironetworks/python-opflex-agent/issues/10/comments","statuses_url":"https://api.github.com/repos/noironetworks/python-opflex-agent/statuses/527560bdcd0fd7169b5a734dc9d54d2cb6e2afaf","head":{"label":"noironetworks:feature_branch_ha_address","ref":"feature_branch_ha_address","sha":"527560bdcd0fd7169b5a734dc9d54d2cb6e2afaf","user":{"login":"noironetworks","id":6634092,"avatar_url":"https://avatars.githubusercontent.com/u/6634092?v=3","gravatar_id":"","url":"https://api.github.com/users/noironetworks","html_url":"https://github.com/noironetworks","followers_url":"https://api.github.com/users/noironetworks/followers","following_url":"https://api.github.com/users/noironetworks/following{/other_user}","gists_url":"https://api.github.com/users/noironetworks/gists{/gist_id}","starred_url":"https://api.github.com/users/noironetworks/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/noironetworks/subscriptions","organizations_url":"https://api.github.com/users/noironetworks/orgs","repos_url":"https://api.github.com/users/noironetworks/repos","events_url":"https://api.github.com/users/noironetworks/events{/privacy}","received_events_url":"https://api.github.com/users/noironetworks/received_events","type":"Organization","site_admin":false},"repo":{"id":29504542,"name":"python-opflex-agent","full_name":"noironetworks/python-opflex-agent","owner":{"login":"noironetworks","id":6634092,"avatar_url":"https://avatars.githubusercontent.com/u/6634092?v=3","gravatar_id":"","url":"https://api.github.com/users/noironetworks","html_url":"https://github.com/noironetworks","followers_url":"https://api.github.com/users/noironetworks/followers","following_url":"https://api.github.com/users/noironetworks/following{/other_user}","gists_url":"https://api.github.com/users/noironetworks/gists{/gist_id}","starred_url":"https://api.github.com/users/noironetworks/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/noironetworks/subscriptions","organizations_url":"https://api.github.com/users/noironetworks/orgs","repos_url":"https://api.github.com/users/noironetworks/repos","events_url":"https://api.github.com/users/noironetworks/events{/privacy}","received_events_url":"https://api.github.com/users/noironetworks/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/noironetworks/python-opflex-agent","description":"","fork":false,"url":"https://api.github.com/repos/noironetworks/python-opflex-agent","forks_url":"https://api.github.com/repos/noironetworks/python-opflex-agent/forks","keys_url":"https://api.github.com/repos/noironetworks/python-opflex-agent/keys{/key_id}","collaborators_url":"https://api.github.com/repos/noironetworks/python-opflex-agent/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/noironetworks/python-opflex-agent/teams","hooks_url":"https://api.github.com/repos/noironetworks/python-opflex-agent/hooks","issue_events_url":"https://api.github.com/repos/noironetworks/python-opflex-agent/issues/events{/number}","events_url":"https://api.github.com/repos/noironetworks/python-opflex-agent/events","assignees_url":"https://api.github.com/repos/noironetworks/python-opflex-agent/assignees{/user}","branches_url":"https://api.github.com/repos/noironetworks/python-opflex-agent/branches{/branch}","tags_url":"https://api.github.com/repos/noironetworks/python-opflex-agent/tags","blobs_url":"https://api.github.com/repos/noironetworks/python-opflex-agent/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/noironetworks/python-opflex-agent/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/noironetworks/python-opflex-agent/git/refs{/sha}","trees_url":"https://api.github.com/repos/noironetworks/python-opflex-agent/git/trees{/sha}","statuses_url":"https://api.github.com/repos/noironetworks/python-opflex-agent/statuses/{sha}","languages_url":"https://api.github.com/repos/noironetworks/python-opflex-agent/languages","stargazers_url":"https://api.github.com/repos/noironetworks/python-opflex-agent/stargazers","contributors_url":"https://api.github.com/repos/noironetworks/python-opflex-agent/contributors","subscribers_url":"https://api.github.com/repos/noironetworks/python-opflex-agent/subscribers","subscription_url":"https://api.github.com/repos/noironetworks/python-opflex-agent/subscription","commits_url":"https://api.github.com/repos/noironetworks/python-opflex-agent/commits{/sha}","git_commits_url":"https://api.github.com/repos/noironetworks/python-opflex-agent/git/commits{/sha}","comments_url":"https://api.github.com/repos/noironetworks/python-opflex-agent/comments{/number}","issue_comment_url":"https://api.github.com/repos/noironetworks/python-opflex-agent/issues/comments{/number}","contents_url":"https://api.github.com/repos/noironetworks/python-opflex-agent/contents/{+path}","compare_url":"https://api.github.com/repos/noironetworks/python-opflex-agent/compare/{base}...{head}","merges_url":"https://api.github.com/repos/noironetworks/python-opflex-agent/merges","archive_url":"https://api.github.com/repos/noironetworks/python-opflex-agent/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/noironetworks/python-opflex-agent/downloads","issues_url":"https://api.github.com/repos/noironetworks/python-opflex-agent/issues{/number}","pulls_url":"https://api.github.com/repos/noironetworks/python-opflex-agent/pulls{/number}","milestones_url":"https://api.github.com/repos/noironetworks/python-opflex-agent/milestones{/number}","notifications_url":"https://api.github.com/repos/noironetworks/python-opflex-agent/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/noironetworks/python-opflex-agent/labels{/name}","releases_url":"https://api.github.com/repos/noironetworks/python-opflex-agent/releases{/id}","created_at":"2015-01-20T00:55:10Z","updated_at":"2015-09-04T21:38:13Z","pushed_at":"2015-10-27T17:11:51Z","git_url":"git://github.com/noironetworks/python-opflex-agent.git","ssh_url":"git@github.com:noironetworks/python-opflex-agent.git","clone_url":"https://github.com/noironetworks/python-opflex-agent.git","svn_url":"https://github.com/noironetworks/python-opflex-agent","homepage":null,"size":500,"stargazers_count":2,"watchers_count":2,"language":"Python","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":2,"mirror_url":null,"open_issues_count":1,"forks":2,"open_issues":1,"watchers":2,"default_branch":"master"}},"base":{"label":"noironetworks:master","ref":"master","sha":"74b7a06cc0b4be2c8b6224e5afae44d4e3285476","user":{"login":"noironetworks","id":6634092,"avatar_url":"https://avatars.githubusercontent.com/u/6634092?v=3","gravatar_id":"","url":"https://api.github.com/users/noironetworks","html_url":"https://github.com/noironetworks","followers_url":"https://api.github.com/users/noironetworks/followers","following_url":"https://api.github.com/users/noironetworks/following{/other_user}","gists_url":"https://api.github.com/users/noironetworks/gists{/gist_id}","starred_url":"https://api.github.com/users/noironetworks/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/noironetworks/subscriptions","organizations_url":"https://api.github.com/users/noironetworks/orgs","repos_url":"https://api.github.com/users/noironetworks/repos","events_url":"https://api.github.com/users/noironetworks/events{/privacy}","received_events_url":"https://api.github.com/users/noironetworks/received_events","type":"Organization","site_admin":false},"repo":{"id":29504542,"name":"python-opflex-agent","full_name":"noironetworks/python-opflex-agent","owner":{"login":"noironetworks","id":6634092,"avatar_url":"https://avatars.githubusercontent.com/u/6634092?v=3","gravatar_id":"","url":"https://api.github.com/users/noironetworks","html_url":"https://github.com/noironetworks","followers_url":"https://api.github.com/users/noironetworks/followers","following_url":"https://api.github.com/users/noironetworks/following{/other_user}","gists_url":"https://api.github.com/users/noironetworks/gists{/gist_id}","starred_url":"https://api.github.com/users/noironetworks/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/noironetworks/subscriptions","organizations_url":"https://api.github.com/users/noironetworks/orgs","repos_url":"https://api.github.com/users/noironetworks/repos","events_url":"https://api.github.com/users/noironetworks/events{/privacy}","received_events_url":"https://api.github.com/users/noironetworks/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/noironetworks/python-opflex-agent","description":"","fork":false,"url":"https://api.github.com/repos/noironetworks/python-opflex-agent","forks_url":"https://api.github.com/repos/noironetworks/python-opflex-agent/forks","keys_url":"https://api.github.com/repos/noironetworks/python-opflex-agent/keys{/key_id}","collaborators_url":"https://api.github.com/repos/noironetworks/python-opflex-agent/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/noironetworks/python-opflex-agent/teams","hooks_url":"https://api.github.com/repos/noironetworks/python-opflex-agent/hooks","issue_events_url":"https://api.github.com/repos/noironetworks/python-opflex-agent/issues/events{/number}","events_url":"https://api.github.com/repos/noironetworks/python-opflex-agent/events","assignees_url":"https://api.github.com/repos/noironetworks/python-opflex-agent/assignees{/user}","branches_url":"https://api.github.com/repos/noironetworks/python-opflex-agent/branches{/branch}","tags_url":"https://api.github.com/repos/noironetworks/python-opflex-agent/tags","blobs_url":"https://api.github.com/repos/noironetworks/python-opflex-agent/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/noironetworks/python-opflex-agent/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/noironetworks/python-opflex-agent/git/refs{/sha}","trees_url":"https://api.github.com/repos/noironetworks/python-opflex-agent/git/trees{/sha}","statuses_url":"https://api.github.com/repos/noironetworks/python-opflex-agent/statuses/{sha}","languages_url":"https://api.github.com/repos/noironetworks/python-opflex-agent/languages","stargazers_url":"https://api.github.com/repos/noironetworks/python-opflex-agent/stargazers","contributors_url":"https://api.github.com/repos/noironetworks/python-opflex-agent/contributors","subscribers_url":"https://api.github.com/repos/noironetworks/python-opflex-agent/subscribers","subscription_url":"https://api.github.com/repos/noironetworks/python-opflex-agent/subscription","commits_url":"https://api.github.com/repos/noironetworks/python-opflex-agent/commits{/sha}","git_commits_url":"https://api.github.com/repos/noironetworks/python-opflex-agent/git/commits{/sha}","comments_url":"https://api.github.com/repos/noironetworks/python-opflex-agent/comments{/number}","issue_comment_url":"https://api.github.com/repos/noironetworks/python-opflex-agent/issues/comments{/number}","contents_url":"https://api.github.com/repos/noironetworks/python-opflex-agent/contents/{+path}","compare_url":"https://api.github.com/repos/noironetworks/python-opflex-agent/compare/{base}...{head}","merges_url":"https://api.github.com/repos/noironetworks/python-opflex-agent/merges","archive_url":"https://api.github.com/repos/noironetworks/python-opflex-agent/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/noironetworks/python-opflex-agent/downloads","issues_url":"https://api.github.com/repos/noironetworks/python-opflex-agent/issues{/number}","pulls_url":"https://api.github.com/repos/noironetworks/python-opflex-agent/pulls{/number}","milestones_url":"https://api.github.com/repos/noironetworks/python-opflex-agent/milestones{/number}","notifications_url":"https://api.github.com/repos/noironetworks/python-opflex-agent/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/noironetworks/python-opflex-agent/labels{/name}","releases_url":"https://api.github.com/repos/noironetworks/python-opflex-agent/releases{/id}","created_at":"2015-01-20T00:55:10Z","updated_at":"2015-09-04T21:38:13Z","pushed_at":"2015-10-27T17:11:51Z","git_url":"git://github.com/noironetworks/python-opflex-agent.git","ssh_url":"git@github.com:noironetworks/python-opflex-agent.git","clone_url":"https://github.com/noironetworks/python-opflex-agent.git","svn_url":"https://github.com/noironetworks/python-opflex-agent","homepage":null,"size":500,"stargazers_count":2,"watchers_count":2,"language":"Python","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":2,"mirror_url":null,"open_issues_count":1,"forks":2,"open_issues":1,"watchers":2,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/noironetworks/python-opflex-agent/pulls/10"},"html":{"href":"https://github.com/noironetworks/python-opflex-agent/pull/10"},"issue":{"href":"https://api.github.com/repos/noironetworks/python-opflex-agent/issues/10"},"comments":{"href":"https://api.github.com/repos/noironetworks/python-opflex-agent/issues/10/comments"},"review_comments":{"href":"https://api.github.com/repos/noironetworks/python-opflex-agent/pulls/10/comments"},"review_comment":{"href":"https://api.github.com/repos/noironetworks/python-opflex-agent/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/noironetworks/python-opflex-agent/pulls/10/commits"},"statuses":{"href":"https://api.github.com/repos/noironetworks/python-opflex-agent/statuses/527560bdcd0fd7169b5a734dc9d54d2cb6e2afaf"}}}}