{"action":"created","comment":{"url":"https://api.github.com/repos/dice-cyfronet/ip-wrangler/pulls/comments/24322400","id":24322400,"diff_hunk":"@@ -0,0 +1,131 @@\n+module IpWrangler\n+  class NAT\n+    $lsof_bin_path = '/usr/bin/sudo /usr/bin/lsof'\n+\n+    def initialize(config, db_name, chain_name, logger)\n+      @config = config\n+      @db = DB.new(db_name, logger)\n+      @iptables = Iptables.new(chain_name, logger)\n+      @logger = logger\n+\n+      @db.select_nat_port.each do |nat_port|\n+        @iptables.append_nat_port(nat_port[:public_ip], nat_port[:public_port],\n+          nat_port[:private_ip], nat_port[:private_port],\n+          nat_port[:protocol])\n+      end\n+      @db.select_nat_ip.each do |nat_ip|\n+        @iptables.append_nat_ip(nat_ip[:public_ip], nat_ip[:private_ip])\n+      end\n+    end\n+\n+    def not_used_port?(public_ip, public_port, protocol)\n+      command = \"#{$lsof_bin_path} -i #{protocol}@#{public_ip}:#{public_port}\"\n+      output = IpWrangler::Exec.execute_command(command)\n+      output.empty?\n+    end\n+\n+    def not_used_ip?(public_ip)\n+      command = \"#{$lsof_bin_path} -i @#{public_ip}\"\n+      output = IpWrangler::Exec.execute_command(command)\n+      output.empty?\n+    end\n+\n+    def find_port(private_ip, private_port, protocol)\n+      port = @db.get_first_empty_nat_port(protocol)\n+      if port\n+        public_port = port[:public_port]\n+        if not_used_port?(@config[:port_ip], public_port, protocol) &&\n+            @iptables.not_exists_nat_port?(@config[:port_ip], public_port,\n+            protocol, private_ip, private_port)\n+          return @config[:port_ip], public_port\n+        end\n+      end\n+      nil\n+    end\n+\n+    def find_ip(private_ip)\n+      ip = @db.get_first_empty_nat_ip\n+      if ip\n+        public_ip = ip[:public_ip]\n+        if not_used_ip?(public_ip) &&\n+            @iptables.not_exists_nat_ip?(public_ip, private_ip)\n+          return public_ip\n+        end\n+      end\n+      nil\n+    end\n+\n+    def get_nat_ports(private_ip = nil)\n+      @db.select_nat_port(private_ip)\n+    end\n+\n+    def get_nat_ips(private_ip = nil)\n+      @db.select_nat_ip(private_ip)\n+    end\n+\n+    def lock_port(private_ip, private_port, protocol)\n+      port = @db.select_nat_port(private_ip, private_port, protocol)\n+      if port.empty?\n+        public_ip, public_port = find_port(private_ip, private_port, protocol)\n+        if public_ip && public_port\n+          @db.insert_nat_port(public_ip, public_port,\n+            private_ip, private_port, protocol)\n+          @iptables.append_nat_port(public_ip, public_port,\n+            private_ip, private_port, protocol)\n+          {public_ip: public_ip, public_port: public_port,\n+           private_ip: private_ip, private_port: private_port,\n+           protocol: protocol}\n+        end\n+      else\n+        port = port.to_a[0]\n+        {public_ip: port[:public_ip], public_port: port[:public_port],\n+          private_ip: private_ip, private_port: private_port,\n+          protocol: port[:protocol]}\n+      end\n+    end\n+\n+    def lock_ip(private_ip)\n+      ip = @db.select_nat_ip(private_ip)\n+      if ip.empty?\n+        public_ip = find_ip(private_ip)\n+        if public_ip\n+          @db.insert_nat_ip(public_ip, private_ip)\n+          @iptables.append_nat_ip(public_ip, private_ip)\n+          {public_ip: public_ip,\n+           private_ip: private_ip}\n+        end\n+      else\n+        ip = ip.to_a[0]\n+        {public_ip: ip[:public_ip],\n+         private_ip: private_ip}\n+      end\n+    end\n+\n+    def release_port(private_ip, private_port = nil, protocol = nil)\n+      released_port = []\n+      @db.select_nat_port(private_ip, private_port, protocol).each do |nat_port|\n+        @iptables.delete_nat_port(nat_port[:public_ip], nat_port[:public_port],\n+          nat_port[:private_ip], nat_port[:private_port],","path":"lib/ip_wrangler/nat.rb","position":108,"original_position":108,"commit_id":"825158d73fd9c9fd0df073e21f56d00925018426","original_commit_id":"825158d73fd9c9fd0df073e21f56d00925018426","user":{"login":"houndci","id":6697940,"avatar_url":"https://avatars.githubusercontent.com/u/6697940?v=3","gravatar_id":"","url":"https://api.github.com/users/houndci","html_url":"https://github.com/houndci","followers_url":"https://api.github.com/users/houndci/followers","following_url":"https://api.github.com/users/houndci/following{/other_user}","gists_url":"https://api.github.com/users/houndci/gists{/gist_id}","starred_url":"https://api.github.com/users/houndci/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/houndci/subscriptions","organizations_url":"https://api.github.com/users/houndci/orgs","repos_url":"https://api.github.com/users/houndci/repos","events_url":"https://api.github.com/users/houndci/events{/privacy}","received_events_url":"https://api.github.com/users/houndci/received_events","type":"User","site_admin":false},"body":"Align the parameters of a method call if they span more than one line.","created_at":"2015-02-09T11:33:15Z","updated_at":"2015-02-09T11:33:15Z","html_url":"https://github.com/dice-cyfronet/ip-wrangler/pull/4#discussion_r24322400","pull_request_url":"https://api.github.com/repos/dice-cyfronet/ip-wrangler/pulls/4","_links":{"self":{"href":"https://api.github.com/repos/dice-cyfronet/ip-wrangler/pulls/comments/24322400"},"html":{"href":"https://github.com/dice-cyfronet/ip-wrangler/pull/4#discussion_r24322400"},"pull_request":{"href":"https://api.github.com/repos/dice-cyfronet/ip-wrangler/pulls/4"}}},"pull_request":{"url":"https://api.github.com/repos/dice-cyfronet/ip-wrangler/pulls/4","id":27834569,"html_url":"https://github.com/dice-cyfronet/ip-wrangler/pull/4","diff_url":"https://github.com/dice-cyfronet/ip-wrangler/pull/4.diff","patch_url":"https://github.com/dice-cyfronet/ip-wrangler/pull/4.patch","issue_url":"https://api.github.com/repos/dice-cyfronet/ip-wrangler/issues/4","number":4,"state":"open","locked":false,"title":"Migrate to gem","user":{"login":"paoolo","id":3436085,"avatar_url":"https://avatars.githubusercontent.com/u/3436085?v=3","gravatar_id":"","url":"https://api.github.com/users/paoolo","html_url":"https://github.com/paoolo","followers_url":"https://api.github.com/users/paoolo/followers","following_url":"https://api.github.com/users/paoolo/following{/other_user}","gists_url":"https://api.github.com/users/paoolo/gists{/gist_id}","starred_url":"https://api.github.com/users/paoolo/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/paoolo/subscriptions","organizations_url":"https://api.github.com/users/paoolo/orgs","repos_url":"https://api.github.com/users/paoolo/repos","events_url":"https://api.github.com/users/paoolo/events{/privacy}","received_events_url":"https://api.github.com/users/paoolo/received_events","type":"User","site_admin":false},"body":"","created_at":"2015-01-22T11:13:53Z","updated_at":"2015-02-09T11:33:15Z","closed_at":null,"merged_at":null,"merge_commit_sha":"dff4367d139d68de6177e5e96751ae8bd1162a1d","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/dice-cyfronet/ip-wrangler/pulls/4/commits","review_comments_url":"https://api.github.com/repos/dice-cyfronet/ip-wrangler/pulls/4/comments","review_comment_url":"https://api.github.com/repos/dice-cyfronet/ip-wrangler/pulls/comments/{number}","comments_url":"https://api.github.com/repos/dice-cyfronet/ip-wrangler/issues/4/comments","statuses_url":"https://api.github.com/repos/dice-cyfronet/ip-wrangler/statuses/825158d73fd9c9fd0df073e21f56d00925018426","head":{"label":"dice-cyfronet:task_create_gem","ref":"task_create_gem","sha":"825158d73fd9c9fd0df073e21f56d00925018426","user":{"login":"dice-cyfronet","id":1628782,"avatar_url":"https://avatars.githubusercontent.com/u/1628782?v=3","gravatar_id":"","url":"https://api.github.com/users/dice-cyfronet","html_url":"https://github.com/dice-cyfronet","followers_url":"https://api.github.com/users/dice-cyfronet/followers","following_url":"https://api.github.com/users/dice-cyfronet/following{/other_user}","gists_url":"https://api.github.com/users/dice-cyfronet/gists{/gist_id}","starred_url":"https://api.github.com/users/dice-cyfronet/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dice-cyfronet/subscriptions","organizations_url":"https://api.github.com/users/dice-cyfronet/orgs","repos_url":"https://api.github.com/users/dice-cyfronet/repos","events_url":"https://api.github.com/users/dice-cyfronet/events{/privacy}","received_events_url":"https://api.github.com/users/dice-cyfronet/received_events","type":"Organization","site_admin":false},"repo":{"id":27371146,"name":"ip-wrangler","full_name":"dice-cyfronet/ip-wrangler","owner":{"login":"dice-cyfronet","id":1628782,"avatar_url":"https://avatars.githubusercontent.com/u/1628782?v=3","gravatar_id":"","url":"https://api.github.com/users/dice-cyfronet","html_url":"https://github.com/dice-cyfronet","followers_url":"https://api.github.com/users/dice-cyfronet/followers","following_url":"https://api.github.com/users/dice-cyfronet/following{/other_user}","gists_url":"https://api.github.com/users/dice-cyfronet/gists{/gist_id}","starred_url":"https://api.github.com/users/dice-cyfronet/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dice-cyfronet/subscriptions","organizations_url":"https://api.github.com/users/dice-cyfronet/orgs","repos_url":"https://api.github.com/users/dice-cyfronet/repos","events_url":"https://api.github.com/users/dice-cyfronet/events{/privacy}","received_events_url":"https://api.github.com/users/dice-cyfronet/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/dice-cyfronet/ip-wrangler","description":"IP NAT and port mapping management Web service","fork":false,"url":"https://api.github.com/repos/dice-cyfronet/ip-wrangler","forks_url":"https://api.github.com/repos/dice-cyfronet/ip-wrangler/forks","keys_url":"https://api.github.com/repos/dice-cyfronet/ip-wrangler/keys{/key_id}","collaborators_url":"https://api.github.com/repos/dice-cyfronet/ip-wrangler/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/dice-cyfronet/ip-wrangler/teams","hooks_url":"https://api.github.com/repos/dice-cyfronet/ip-wrangler/hooks","issue_events_url":"https://api.github.com/repos/dice-cyfronet/ip-wrangler/issues/events{/number}","events_url":"https://api.github.com/repos/dice-cyfronet/ip-wrangler/events","assignees_url":"https://api.github.com/repos/dice-cyfronet/ip-wrangler/assignees{/user}","branches_url":"https://api.github.com/repos/dice-cyfronet/ip-wrangler/branches{/branch}","tags_url":"https://api.github.com/repos/dice-cyfronet/ip-wrangler/tags","blobs_url":"https://api.github.com/repos/dice-cyfronet/ip-wrangler/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/dice-cyfronet/ip-wrangler/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/dice-cyfronet/ip-wrangler/git/refs{/sha}","trees_url":"https://api.github.com/repos/dice-cyfronet/ip-wrangler/git/trees{/sha}","statuses_url":"https://api.github.com/repos/dice-cyfronet/ip-wrangler/statuses/{sha}","languages_url":"https://api.github.com/repos/dice-cyfronet/ip-wrangler/languages","stargazers_url":"https://api.github.com/repos/dice-cyfronet/ip-wrangler/stargazers","contributors_url":"https://api.github.com/repos/dice-cyfronet/ip-wrangler/contributors","subscribers_url":"https://api.github.com/repos/dice-cyfronet/ip-wrangler/subscribers","subscription_url":"https://api.github.com/repos/dice-cyfronet/ip-wrangler/subscription","commits_url":"https://api.github.com/repos/dice-cyfronet/ip-wrangler/commits{/sha}","git_commits_url":"https://api.github.com/repos/dice-cyfronet/ip-wrangler/git/commits{/sha}","comments_url":"https://api.github.com/repos/dice-cyfronet/ip-wrangler/comments{/number}","issue_comment_url":"https://api.github.com/repos/dice-cyfronet/ip-wrangler/issues/comments/{number}","contents_url":"https://api.github.com/repos/dice-cyfronet/ip-wrangler/contents/{+path}","compare_url":"https://api.github.com/repos/dice-cyfronet/ip-wrangler/compare/{base}...{head}","merges_url":"https://api.github.com/repos/dice-cyfronet/ip-wrangler/merges","archive_url":"https://api.github.com/repos/dice-cyfronet/ip-wrangler/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/dice-cyfronet/ip-wrangler/downloads","issues_url":"https://api.github.com/repos/dice-cyfronet/ip-wrangler/issues{/number}","pulls_url":"https://api.github.com/repos/dice-cyfronet/ip-wrangler/pulls{/number}","milestones_url":"https://api.github.com/repos/dice-cyfronet/ip-wrangler/milestones{/number}","notifications_url":"https://api.github.com/repos/dice-cyfronet/ip-wrangler/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/dice-cyfronet/ip-wrangler/labels{/name}","releases_url":"https://api.github.com/repos/dice-cyfronet/ip-wrangler/releases{/id}","created_at":"2014-12-01T09:04:34Z","updated_at":"2015-02-06T23:14:57Z","pushed_at":"2015-02-09T11:33:07Z","git_url":"git://github.com/dice-cyfronet/ip-wrangler.git","ssh_url":"git@github.com:dice-cyfronet/ip-wrangler.git","clone_url":"https://github.com/dice-cyfronet/ip-wrangler.git","svn_url":"https://github.com/dice-cyfronet/ip-wrangler","homepage":"","size":808,"stargazers_count":0,"watchers_count":0,"language":"Ruby","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":4,"forks":0,"open_issues":4,"watchers":0,"default_branch":"master"}},"base":{"label":"dice-cyfronet:master","ref":"master","sha":"d8554504995dfe4899313e6b2e5f05fa2b97d523","user":{"login":"dice-cyfronet","id":1628782,"avatar_url":"https://avatars.githubusercontent.com/u/1628782?v=3","gravatar_id":"","url":"https://api.github.com/users/dice-cyfronet","html_url":"https://github.com/dice-cyfronet","followers_url":"https://api.github.com/users/dice-cyfronet/followers","following_url":"https://api.github.com/users/dice-cyfronet/following{/other_user}","gists_url":"https://api.github.com/users/dice-cyfronet/gists{/gist_id}","starred_url":"https://api.github.com/users/dice-cyfronet/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dice-cyfronet/subscriptions","organizations_url":"https://api.github.com/users/dice-cyfronet/orgs","repos_url":"https://api.github.com/users/dice-cyfronet/repos","events_url":"https://api.github.com/users/dice-cyfronet/events{/privacy}","received_events_url":"https://api.github.com/users/dice-cyfronet/received_events","type":"Organization","site_admin":false},"repo":{"id":27371146,"name":"ip-wrangler","full_name":"dice-cyfronet/ip-wrangler","owner":{"login":"dice-cyfronet","id":1628782,"avatar_url":"https://avatars.githubusercontent.com/u/1628782?v=3","gravatar_id":"","url":"https://api.github.com/users/dice-cyfronet","html_url":"https://github.com/dice-cyfronet","followers_url":"https://api.github.com/users/dice-cyfronet/followers","following_url":"https://api.github.com/users/dice-cyfronet/following{/other_user}","gists_url":"https://api.github.com/users/dice-cyfronet/gists{/gist_id}","starred_url":"https://api.github.com/users/dice-cyfronet/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dice-cyfronet/subscriptions","organizations_url":"https://api.github.com/users/dice-cyfronet/orgs","repos_url":"https://api.github.com/users/dice-cyfronet/repos","events_url":"https://api.github.com/users/dice-cyfronet/events{/privacy}","received_events_url":"https://api.github.com/users/dice-cyfronet/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/dice-cyfronet/ip-wrangler","description":"IP NAT and port mapping management Web service","fork":false,"url":"https://api.github.com/repos/dice-cyfronet/ip-wrangler","forks_url":"https://api.github.com/repos/dice-cyfronet/ip-wrangler/forks","keys_url":"https://api.github.com/repos/dice-cyfronet/ip-wrangler/keys{/key_id}","collaborators_url":"https://api.github.com/repos/dice-cyfronet/ip-wrangler/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/dice-cyfronet/ip-wrangler/teams","hooks_url":"https://api.github.com/repos/dice-cyfronet/ip-wrangler/hooks","issue_events_url":"https://api.github.com/repos/dice-cyfronet/ip-wrangler/issues/events{/number}","events_url":"https://api.github.com/repos/dice-cyfronet/ip-wrangler/events","assignees_url":"https://api.github.com/repos/dice-cyfronet/ip-wrangler/assignees{/user}","branches_url":"https://api.github.com/repos/dice-cyfronet/ip-wrangler/branches{/branch}","tags_url":"https://api.github.com/repos/dice-cyfronet/ip-wrangler/tags","blobs_url":"https://api.github.com/repos/dice-cyfronet/ip-wrangler/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/dice-cyfronet/ip-wrangler/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/dice-cyfronet/ip-wrangler/git/refs{/sha}","trees_url":"https://api.github.com/repos/dice-cyfronet/ip-wrangler/git/trees{/sha}","statuses_url":"https://api.github.com/repos/dice-cyfronet/ip-wrangler/statuses/{sha}","languages_url":"https://api.github.com/repos/dice-cyfronet/ip-wrangler/languages","stargazers_url":"https://api.github.com/repos/dice-cyfronet/ip-wrangler/stargazers","contributors_url":"https://api.github.com/repos/dice-cyfronet/ip-wrangler/contributors","subscribers_url":"https://api.github.com/repos/dice-cyfronet/ip-wrangler/subscribers","subscription_url":"https://api.github.com/repos/dice-cyfronet/ip-wrangler/subscription","commits_url":"https://api.github.com/repos/dice-cyfronet/ip-wrangler/commits{/sha}","git_commits_url":"https://api.github.com/repos/dice-cyfronet/ip-wrangler/git/commits{/sha}","comments_url":"https://api.github.com/repos/dice-cyfronet/ip-wrangler/comments{/number}","issue_comment_url":"https://api.github.com/repos/dice-cyfronet/ip-wrangler/issues/comments/{number}","contents_url":"https://api.github.com/repos/dice-cyfronet/ip-wrangler/contents/{+path}","compare_url":"https://api.github.com/repos/dice-cyfronet/ip-wrangler/compare/{base}...{head}","merges_url":"https://api.github.com/repos/dice-cyfronet/ip-wrangler/merges","archive_url":"https://api.github.com/repos/dice-cyfronet/ip-wrangler/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/dice-cyfronet/ip-wrangler/downloads","issues_url":"https://api.github.com/repos/dice-cyfronet/ip-wrangler/issues{/number}","pulls_url":"https://api.github.com/repos/dice-cyfronet/ip-wrangler/pulls{/number}","milestones_url":"https://api.github.com/repos/dice-cyfronet/ip-wrangler/milestones{/number}","notifications_url":"https://api.github.com/repos/dice-cyfronet/ip-wrangler/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/dice-cyfronet/ip-wrangler/labels{/name}","releases_url":"https://api.github.com/repos/dice-cyfronet/ip-wrangler/releases{/id}","created_at":"2014-12-01T09:04:34Z","updated_at":"2015-02-06T23:14:57Z","pushed_at":"2015-02-09T11:33:07Z","git_url":"git://github.com/dice-cyfronet/ip-wrangler.git","ssh_url":"git@github.com:dice-cyfronet/ip-wrangler.git","clone_url":"https://github.com/dice-cyfronet/ip-wrangler.git","svn_url":"https://github.com/dice-cyfronet/ip-wrangler","homepage":"","size":808,"stargazers_count":0,"watchers_count":0,"language":"Ruby","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":4,"forks":0,"open_issues":4,"watchers":0,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/dice-cyfronet/ip-wrangler/pulls/4"},"html":{"href":"https://github.com/dice-cyfronet/ip-wrangler/pull/4"},"issue":{"href":"https://api.github.com/repos/dice-cyfronet/ip-wrangler/issues/4"},"comments":{"href":"https://api.github.com/repos/dice-cyfronet/ip-wrangler/issues/4/comments"},"review_comments":{"href":"https://api.github.com/repos/dice-cyfronet/ip-wrangler/pulls/4/comments"},"review_comment":{"href":"https://api.github.com/repos/dice-cyfronet/ip-wrangler/pulls/comments/{number}"},"commits":{"href":"https://api.github.com/repos/dice-cyfronet/ip-wrangler/pulls/4/commits"},"statuses":{"href":"https://api.github.com/repos/dice-cyfronet/ip-wrangler/statuses/825158d73fd9c9fd0df073e21f56d00925018426"}}}}