{"action":"created","comment":{"url":"https://api.github.com/repos/arista-eosplus/pyeapi/pulls/comments/42171001","id":42171001,"diff_hunk":"@@ -0,0 +1,302 @@\n+#\n+# Copyright (c) 2014, Arista Networks, Inc.\n+# All rights reserved.\n+#\n+# Redistribution and use in source and binary forms, with or without\n+# modification, are permitted provided that the following conditions are\n+# met:\n+#\n+#   Redistributions of source code must retain the above copyright notice,\n+#   this list of conditions and the following disclaimer.\n+#\n+#   Redistributions in binary form must reproduce the above copyright\n+#   notice, this list of conditions and the following disclaimer in the\n+#   documentation and/or other materials provided with the distribution.\n+#\n+#   Neither the name of Arista Networks nor the names of its\n+#   contributors may be used to endorse or promote products derived from\n+#   this software without specific prior written permission.\n+#\n+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n+# \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ARISTA NETWORKS\n+# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR\n+# BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\n+# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE\n+# OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN\n+# IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n+#\n+\"\"\"Module for working with EOS static routes\n+\n+The staticroute resource provides configuration management of static\n+route resources on an EOS node. It provides the following class\n+implementations:\n+\n+    * StaticRoute - Configure static routes in EOS\n+\n+StaticRoute Attributes:\n+    ip_dest (string): The ip address of the destination in the\n+        form of A.B.C.D/E\n+    next_hop (string): The next hop interface or ip address\n+    next_hop_ip (string): The next hop address on destination interface\n+    distance (int): Administrative distance for this route\n+    tag (int): Route tag\n+    route_name (string): Route name\n+\n+Notes:\n+    The 'default' prefix function of the 'ip route' command,\n+    'default ip route ...', currently equivalent to the 'no ip route ...'\n+    command.\n+\"\"\"\n+\n+import re\n+\n+from pyeapi.api import EntityCollection\n+\n+# Define the regex to match ip route lines (by lines in regex):\n+#   'ip route' header\n+#   ip_dest\n+#   next_hop\n+#   next_hop_ip\n+#   distance\n+#   tag\n+#   name\n+ROUTES_RE = re.compile(r'(?<=^ip route)'\n+                       r' (\\d+\\.\\d+\\.\\d+\\.\\d+\\/\\d+)'\n+                       r' (\\d+\\.\\d+\\.\\d+\\.\\d+|\\S+)'\n+                       r'(?: (\\d+\\.\\d+\\.\\d+\\.\\d+))?'\n+                       r' (\\d+)'\n+                       r'(?: tag (\\d+))?'\n+                       r'(?: name (\\S+))?', re.M)\n+\n+# Define a format for the unique route id\n+# The four parts in order are ip_dest, next_hop, next_hop_ip, and distance\n+ROUTE_ID = \"%s--%s--%s--%s\"\n+\n+\n+class StaticRoute(EntityCollection):\n+    \"\"\"The StaticRoute class provides a configuration instance\n+    for working with static routes\n+\n+    \"\"\"\n+\n+    def __str__(self):\n+        return 'StaticRoute'\n+\n+    def get(self, ip_dest, next_hop, distance, next_hop_ip=None):\n+        \"\"\"Retrieves the ip route information for the route specified\n+            by the ip_dest, next_hop, and distance parameters\n+\n+        Args:\n+            ip_dest (string): The ip address of the destination in the\n+                form of A.B.C.D/E\n+            next_hop (string): The next hop interface or ip address\n+            distance (int): Administrative distance for this route\n+\n+        Returns:\n+            dict: An ip route dict object\n+\n+            If the unique route specified by the ip_dest, next_hop, and\n+            distance does not exist, then None is returned.\n+        \"\"\"\n+\n+        # If distance is None, then set to 1 to match what EOS will\n+        # do when distance is not specified.\n+        if distance is None:\n+            distance = 1\n+\n+        # Make the unique route_id for the requested route\n+        route_id = ROUTE_ID % (ip_dest, next_hop, next_hop_ip, distance)\n+\n+        # Return the route configuration if found, or return None\n+        return self.getall().get(route_id)\n+\n+    def getall(self):\n+        \"\"\"Return all ip routes configured on the switch as a resource dict\n+\n+        Returns:\n+            dict: A dict of unique ip route names with a nested route\n+                dict object. The unique name is built with the ip destination,\n+                next hop, and distance values for the route.\n+        \"\"\"\n+\n+        # Find all the ip routes in the config\n+        matches = ROUTES_RE.findall(self.config)\n+\n+        # Parse the routes and add them to the routes dict\n+        routes = dict()\n+        for match in matches:\n+            # Set the route dict to the returned values, replacing\n+            # empty strings with None\n+            route = dict()\n+            route['ip_dest'] = match[0]\n+            route['next_hop'] = match[1]\n+            route['next_hop_ip'] = None if match[2] is '' else match[2]\n+            route['distance'] = match[3]\n+            route['tag'] = None if match[4] is '' else match[4]\n+            route['route_name'] = None if match[5] is '' else match[5]\n+\n+            # Build a unique route_id from the ip_dest, next_hop, and distance\n+            route_id = ROUTE_ID % \\\n+                (route['ip_dest'], route['next_hop'],\n+                 route['next_hop_ip'], route['distance'])\n+\n+            # Update the routes dict\n+            routes.update({route_id: route})\n+\n+        return routes\n+\n+    def create(self, ip_dest, next_hop, next_hop_ip=None,\n+               distance=None, tag=None, route_name=None):\n+        \"\"\"Create a static route\n+\n+        Args:\n+            ip_dest (string): The ip address of the destination in the\n+                form of A.B.C.D/E\n+            next_hop (string): The next hop interface or ip address\n+            next_hop_ip (string): The next hop address on destination\n+                interface\n+            distance (int): Administrative distance for this route\n+            tag (int): Route tag","path":"pyeapi/api/staticroute.py","position":163,"original_position":163,"commit_id":"5c3d4ae4389d50c05a9fd51b2d7f31087de04f02","original_commit_id":"5c3d4ae4389d50c05a9fd51b2d7f31087de04f02","user":{"login":"phil-arista","id":7631359,"avatar_url":"https://avatars.githubusercontent.com/u/7631359?v=3","gravatar_id":"","url":"https://api.github.com/users/phil-arista","html_url":"https://github.com/phil-arista","followers_url":"https://api.github.com/users/phil-arista/followers","following_url":"https://api.github.com/users/phil-arista/following{/other_user}","gists_url":"https://api.github.com/users/phil-arista/gists{/gist_id}","starred_url":"https://api.github.com/users/phil-arista/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/phil-arista/subscriptions","organizations_url":"https://api.github.com/users/phil-arista/orgs","repos_url":"https://api.github.com/users/phil-arista/repos","events_url":"https://api.github.com/users/phil-arista/events{/privacy}","received_events_url":"https://api.github.com/users/phil-arista/received_events","type":"User","site_admin":false},"body":"The object returns tag and distance as strings and not integers","created_at":"2015-10-15T19:47:13Z","updated_at":"2015-10-15T19:47:13Z","html_url":"https://github.com/arista-eosplus/pyeapi/pull/45#discussion_r42171001","pull_request_url":"https://api.github.com/repos/arista-eosplus/pyeapi/pulls/45","_links":{"self":{"href":"https://api.github.com/repos/arista-eosplus/pyeapi/pulls/comments/42171001"},"html":{"href":"https://github.com/arista-eosplus/pyeapi/pull/45#discussion_r42171001"},"pull_request":{"href":"https://api.github.com/repos/arista-eosplus/pyeapi/pulls/45"}}},"pull_request":{"url":"https://api.github.com/repos/arista-eosplus/pyeapi/pulls/45","id":47803387,"html_url":"https://github.com/arista-eosplus/pyeapi/pull/45","diff_url":"https://github.com/arista-eosplus/pyeapi/pull/45.diff","patch_url":"https://github.com/arista-eosplus/pyeapi/pull/45.patch","issue_url":"https://api.github.com/repos/arista-eosplus/pyeapi/issues/45","number":45,"state":"open","locked":false,"title":"Staticroute","user":{"login":"grybak","id":13952603,"avatar_url":"https://avatars.githubusercontent.com/u/13952603?v=3","gravatar_id":"","url":"https://api.github.com/users/grybak","html_url":"https://github.com/grybak","followers_url":"https://api.github.com/users/grybak/followers","following_url":"https://api.github.com/users/grybak/following{/other_user}","gists_url":"https://api.github.com/users/grybak/gists{/gist_id}","starred_url":"https://api.github.com/users/grybak/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/grybak/subscriptions","organizations_url":"https://api.github.com/users/grybak/orgs","repos_url":"https://api.github.com/users/grybak/repos","events_url":"https://api.github.com/users/grybak/events{/privacy}","received_events_url":"https://api.github.com/users/grybak/received_events","type":"User","site_admin":false},"body":"Add staticroute library with system/unit tests","created_at":"2015-10-15T15:38:06Z","updated_at":"2015-10-15T19:47:13Z","closed_at":null,"merged_at":null,"merge_commit_sha":"586a3c6baf9ae8ae0589461e8d925956c0c9821a","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/arista-eosplus/pyeapi/pulls/45/commits","review_comments_url":"https://api.github.com/repos/arista-eosplus/pyeapi/pulls/45/comments","review_comment_url":"https://api.github.com/repos/arista-eosplus/pyeapi/pulls/comments{/number}","comments_url":"https://api.github.com/repos/arista-eosplus/pyeapi/issues/45/comments","statuses_url":"https://api.github.com/repos/arista-eosplus/pyeapi/statuses/5c3d4ae4389d50c05a9fd51b2d7f31087de04f02","head":{"label":"arista-eosplus:staticroute","ref":"staticroute","sha":"5c3d4ae4389d50c05a9fd51b2d7f31087de04f02","user":{"login":"arista-eosplus","id":6643264,"avatar_url":"https://avatars.githubusercontent.com/u/6643264?v=3","gravatar_id":"","url":"https://api.github.com/users/arista-eosplus","html_url":"https://github.com/arista-eosplus","followers_url":"https://api.github.com/users/arista-eosplus/followers","following_url":"https://api.github.com/users/arista-eosplus/following{/other_user}","gists_url":"https://api.github.com/users/arista-eosplus/gists{/gist_id}","starred_url":"https://api.github.com/users/arista-eosplus/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/arista-eosplus/subscriptions","organizations_url":"https://api.github.com/users/arista-eosplus/orgs","repos_url":"https://api.github.com/users/arista-eosplus/repos","events_url":"https://api.github.com/users/arista-eosplus/events{/privacy}","received_events_url":"https://api.github.com/users/arista-eosplus/received_events","type":"Organization","site_admin":false},"repo":{"id":26839425,"name":"pyeapi","full_name":"arista-eosplus/pyeapi","owner":{"login":"arista-eosplus","id":6643264,"avatar_url":"https://avatars.githubusercontent.com/u/6643264?v=3","gravatar_id":"","url":"https://api.github.com/users/arista-eosplus","html_url":"https://github.com/arista-eosplus","followers_url":"https://api.github.com/users/arista-eosplus/followers","following_url":"https://api.github.com/users/arista-eosplus/following{/other_user}","gists_url":"https://api.github.com/users/arista-eosplus/gists{/gist_id}","starred_url":"https://api.github.com/users/arista-eosplus/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/arista-eosplus/subscriptions","organizations_url":"https://api.github.com/users/arista-eosplus/orgs","repos_url":"https://api.github.com/users/arista-eosplus/repos","events_url":"https://api.github.com/users/arista-eosplus/events{/privacy}","received_events_url":"https://api.github.com/users/arista-eosplus/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/arista-eosplus/pyeapi","description":"Python client for Arista eAPI","fork":false,"url":"https://api.github.com/repos/arista-eosplus/pyeapi","forks_url":"https://api.github.com/repos/arista-eosplus/pyeapi/forks","keys_url":"https://api.github.com/repos/arista-eosplus/pyeapi/keys{/key_id}","collaborators_url":"https://api.github.com/repos/arista-eosplus/pyeapi/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/arista-eosplus/pyeapi/teams","hooks_url":"https://api.github.com/repos/arista-eosplus/pyeapi/hooks","issue_events_url":"https://api.github.com/repos/arista-eosplus/pyeapi/issues/events{/number}","events_url":"https://api.github.com/repos/arista-eosplus/pyeapi/events","assignees_url":"https://api.github.com/repos/arista-eosplus/pyeapi/assignees{/user}","branches_url":"https://api.github.com/repos/arista-eosplus/pyeapi/branches{/branch}","tags_url":"https://api.github.com/repos/arista-eosplus/pyeapi/tags","blobs_url":"https://api.github.com/repos/arista-eosplus/pyeapi/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/arista-eosplus/pyeapi/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/arista-eosplus/pyeapi/git/refs{/sha}","trees_url":"https://api.github.com/repos/arista-eosplus/pyeapi/git/trees{/sha}","statuses_url":"https://api.github.com/repos/arista-eosplus/pyeapi/statuses/{sha}","languages_url":"https://api.github.com/repos/arista-eosplus/pyeapi/languages","stargazers_url":"https://api.github.com/repos/arista-eosplus/pyeapi/stargazers","contributors_url":"https://api.github.com/repos/arista-eosplus/pyeapi/contributors","subscribers_url":"https://api.github.com/repos/arista-eosplus/pyeapi/subscribers","subscription_url":"https://api.github.com/repos/arista-eosplus/pyeapi/subscription","commits_url":"https://api.github.com/repos/arista-eosplus/pyeapi/commits{/sha}","git_commits_url":"https://api.github.com/repos/arista-eosplus/pyeapi/git/commits{/sha}","comments_url":"https://api.github.com/repos/arista-eosplus/pyeapi/comments{/number}","issue_comment_url":"https://api.github.com/repos/arista-eosplus/pyeapi/issues/comments{/number}","contents_url":"https://api.github.com/repos/arista-eosplus/pyeapi/contents/{+path}","compare_url":"https://api.github.com/repos/arista-eosplus/pyeapi/compare/{base}...{head}","merges_url":"https://api.github.com/repos/arista-eosplus/pyeapi/merges","archive_url":"https://api.github.com/repos/arista-eosplus/pyeapi/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/arista-eosplus/pyeapi/downloads","issues_url":"https://api.github.com/repos/arista-eosplus/pyeapi/issues{/number}","pulls_url":"https://api.github.com/repos/arista-eosplus/pyeapi/pulls{/number}","milestones_url":"https://api.github.com/repos/arista-eosplus/pyeapi/milestones{/number}","notifications_url":"https://api.github.com/repos/arista-eosplus/pyeapi/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/arista-eosplus/pyeapi/labels{/name}","releases_url":"https://api.github.com/repos/arista-eosplus/pyeapi/releases{/id}","created_at":"2014-11-19T01:52:42Z","updated_at":"2015-10-13T21:17:32Z","pushed_at":"2015-10-15T19:30:05Z","git_url":"git://github.com/arista-eosplus/pyeapi.git","ssh_url":"git@github.com:arista-eosplus/pyeapi.git","clone_url":"https://github.com/arista-eosplus/pyeapi.git","svn_url":"https://github.com/arista-eosplus/pyeapi","homepage":null,"size":1259,"stargazers_count":17,"watchers_count":17,"language":"Python","has_issues":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":13,"mirror_url":null,"open_issues_count":14,"forks":13,"open_issues":14,"watchers":17,"default_branch":"develop"}},"base":{"label":"arista-eosplus:develop","ref":"develop","sha":"836d2d3ed3f423e972c998244815c22f77e467e3","user":{"login":"arista-eosplus","id":6643264,"avatar_url":"https://avatars.githubusercontent.com/u/6643264?v=3","gravatar_id":"","url":"https://api.github.com/users/arista-eosplus","html_url":"https://github.com/arista-eosplus","followers_url":"https://api.github.com/users/arista-eosplus/followers","following_url":"https://api.github.com/users/arista-eosplus/following{/other_user}","gists_url":"https://api.github.com/users/arista-eosplus/gists{/gist_id}","starred_url":"https://api.github.com/users/arista-eosplus/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/arista-eosplus/subscriptions","organizations_url":"https://api.github.com/users/arista-eosplus/orgs","repos_url":"https://api.github.com/users/arista-eosplus/repos","events_url":"https://api.github.com/users/arista-eosplus/events{/privacy}","received_events_url":"https://api.github.com/users/arista-eosplus/received_events","type":"Organization","site_admin":false},"repo":{"id":26839425,"name":"pyeapi","full_name":"arista-eosplus/pyeapi","owner":{"login":"arista-eosplus","id":6643264,"avatar_url":"https://avatars.githubusercontent.com/u/6643264?v=3","gravatar_id":"","url":"https://api.github.com/users/arista-eosplus","html_url":"https://github.com/arista-eosplus","followers_url":"https://api.github.com/users/arista-eosplus/followers","following_url":"https://api.github.com/users/arista-eosplus/following{/other_user}","gists_url":"https://api.github.com/users/arista-eosplus/gists{/gist_id}","starred_url":"https://api.github.com/users/arista-eosplus/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/arista-eosplus/subscriptions","organizations_url":"https://api.github.com/users/arista-eosplus/orgs","repos_url":"https://api.github.com/users/arista-eosplus/repos","events_url":"https://api.github.com/users/arista-eosplus/events{/privacy}","received_events_url":"https://api.github.com/users/arista-eosplus/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/arista-eosplus/pyeapi","description":"Python client for Arista eAPI","fork":false,"url":"https://api.github.com/repos/arista-eosplus/pyeapi","forks_url":"https://api.github.com/repos/arista-eosplus/pyeapi/forks","keys_url":"https://api.github.com/repos/arista-eosplus/pyeapi/keys{/key_id}","collaborators_url":"https://api.github.com/repos/arista-eosplus/pyeapi/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/arista-eosplus/pyeapi/teams","hooks_url":"https://api.github.com/repos/arista-eosplus/pyeapi/hooks","issue_events_url":"https://api.github.com/repos/arista-eosplus/pyeapi/issues/events{/number}","events_url":"https://api.github.com/repos/arista-eosplus/pyeapi/events","assignees_url":"https://api.github.com/repos/arista-eosplus/pyeapi/assignees{/user}","branches_url":"https://api.github.com/repos/arista-eosplus/pyeapi/branches{/branch}","tags_url":"https://api.github.com/repos/arista-eosplus/pyeapi/tags","blobs_url":"https://api.github.com/repos/arista-eosplus/pyeapi/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/arista-eosplus/pyeapi/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/arista-eosplus/pyeapi/git/refs{/sha}","trees_url":"https://api.github.com/repos/arista-eosplus/pyeapi/git/trees{/sha}","statuses_url":"https://api.github.com/repos/arista-eosplus/pyeapi/statuses/{sha}","languages_url":"https://api.github.com/repos/arista-eosplus/pyeapi/languages","stargazers_url":"https://api.github.com/repos/arista-eosplus/pyeapi/stargazers","contributors_url":"https://api.github.com/repos/arista-eosplus/pyeapi/contributors","subscribers_url":"https://api.github.com/repos/arista-eosplus/pyeapi/subscribers","subscription_url":"https://api.github.com/repos/arista-eosplus/pyeapi/subscription","commits_url":"https://api.github.com/repos/arista-eosplus/pyeapi/commits{/sha}","git_commits_url":"https://api.github.com/repos/arista-eosplus/pyeapi/git/commits{/sha}","comments_url":"https://api.github.com/repos/arista-eosplus/pyeapi/comments{/number}","issue_comment_url":"https://api.github.com/repos/arista-eosplus/pyeapi/issues/comments{/number}","contents_url":"https://api.github.com/repos/arista-eosplus/pyeapi/contents/{+path}","compare_url":"https://api.github.com/repos/arista-eosplus/pyeapi/compare/{base}...{head}","merges_url":"https://api.github.com/repos/arista-eosplus/pyeapi/merges","archive_url":"https://api.github.com/repos/arista-eosplus/pyeapi/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/arista-eosplus/pyeapi/downloads","issues_url":"https://api.github.com/repos/arista-eosplus/pyeapi/issues{/number}","pulls_url":"https://api.github.com/repos/arista-eosplus/pyeapi/pulls{/number}","milestones_url":"https://api.github.com/repos/arista-eosplus/pyeapi/milestones{/number}","notifications_url":"https://api.github.com/repos/arista-eosplus/pyeapi/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/arista-eosplus/pyeapi/labels{/name}","releases_url":"https://api.github.com/repos/arista-eosplus/pyeapi/releases{/id}","created_at":"2014-11-19T01:52:42Z","updated_at":"2015-10-13T21:17:32Z","pushed_at":"2015-10-15T19:30:05Z","git_url":"git://github.com/arista-eosplus/pyeapi.git","ssh_url":"git@github.com:arista-eosplus/pyeapi.git","clone_url":"https://github.com/arista-eosplus/pyeapi.git","svn_url":"https://github.com/arista-eosplus/pyeapi","homepage":null,"size":1259,"stargazers_count":17,"watchers_count":17,"language":"Python","has_issues":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":13,"mirror_url":null,"open_issues_count":14,"forks":13,"open_issues":14,"watchers":17,"default_branch":"develop"}},"_links":{"self":{"href":"https://api.github.com/repos/arista-eosplus/pyeapi/pulls/45"},"html":{"href":"https://github.com/arista-eosplus/pyeapi/pull/45"},"issue":{"href":"https://api.github.com/repos/arista-eosplus/pyeapi/issues/45"},"comments":{"href":"https://api.github.com/repos/arista-eosplus/pyeapi/issues/45/comments"},"review_comments":{"href":"https://api.github.com/repos/arista-eosplus/pyeapi/pulls/45/comments"},"review_comment":{"href":"https://api.github.com/repos/arista-eosplus/pyeapi/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/arista-eosplus/pyeapi/pulls/45/commits"},"statuses":{"href":"https://api.github.com/repos/arista-eosplus/pyeapi/statuses/5c3d4ae4389d50c05a9fd51b2d7f31087de04f02"}}}}