Skip to content

Commit

Permalink
Added vmhost parameter in the facts template to check running device …
Browse files Browse the repository at this point in the history
…is vmhost supported or not.
  • Loading branch information
dineshbaburam91 committed Oct 9, 2024
1 parent 02c7d02 commit 235a2b9
Show file tree
Hide file tree
Showing 6 changed files with 136 additions and 1 deletion.
2 changes: 1 addition & 1 deletion lib/jnpr/junos/facts/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@
The following dictionary keys represent the available facts and their meaning:
"""

import sys

import jnpr.junos.facts.current_re
Expand All @@ -48,6 +47,7 @@
import jnpr.junos.facts.personality
import jnpr.junos.facts.swver
import jnpr.junos.facts.is_linux
import jnpr.junos.facts.vmhost


def _build_fact_callbacks_and_doc_strings():
Expand Down
40 changes: 40 additions & 0 deletions lib/jnpr/junos/facts/vmhost.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
from jnpr.junos.exception import RpcError
import re
from lxml import etree


def provides_facts():
"""
Returns a dictionary keyed on the facts provided by this module. The value
of each key is the doc string describing the fact.
"""
return {
"vmhost": "A boolean indicating if the device is vmhost.",
}


def get_facts(device):
"""
Gathers facts from the sysctl command.
"""
SYSCTL_VMHOST_MODE = "sysctl -n hw.re.vmhost_mode"
vmhost = None

if device.facts["_is_linux"]:
vmhost = None
else:
try:
rsp = device.rpc.request_shell_execute(command=SYSCTL_VMHOST_MODE)
if rsp.tag == "rpc-error":
raise RpcError()
result = re.sub("<[^<]+>", "", etree.tostring(rsp).decode())
if result.strip() == "1":
vmhost = True
else:
vmhost = False
except RpcError:
pass

return {
"vmhost": vmhost,
}
11 changes: 11 additions & 0 deletions tests/unit/facts/rpc-reply/vmhost_error_request-shell-execute.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<rpc-reply xmlns:junos="http://xml.juniper.net/junos/16.1R1/junos">
<rpc-error>
<error-type>protocol</error-type>
<error-tag>operation-failed</error-tag>
<error-severity>error</error-severity>
<error-message>permission denied</error-message>
<error-info>
<bad-element>system</bad-element>
</error-info>
</rpc-error>
</rpc-reply>
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<rpc-reply xmlns:junos="http://xml.juniper.net/junos/16.1R1/junos">
<output>
0
</output>
</rpc-reply>
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<rpc-reply xmlns:junos="http://xml.juniper.net/junos/16.1R1/junos">
<output>
1
</output>
</rpc-reply>
74 changes: 74 additions & 0 deletions tests/unit/facts/test_vmhost.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
__author__ = "Stacy Smith"
__credits__ = "Jeremy Schulman, Nitin Kumar"

import unittest
from nose.plugins.attrib import attr
from mock import patch, MagicMock
import os

from jnpr.junos import Device

from ncclient.manager import Manager, make_device_handler
from ncclient.transport import SSHSession


@attr("unit")
class TestVmHost(unittest.TestCase):
@patch("ncclient.manager.connect")
def setUp(self, mock_connect):
mock_connect.side_effect = self._mock_manager_setup
self.dev = Device(
host="1.1.1.1", user="rick", password="password123", gather_facts=False
)
self.dev.open()

@patch("jnpr.junos.Device.execute")
def test_vmhost_true(self, mock_execute):
mock_execute.side_effect = self._mock_manager_vmhost_true
self.assertEqual(self.dev.facts["vmhost"], True)

@patch("jnpr.junos.Device.execute")
def test_vmhost_false(self, mock_execute):
mock_execute.side_effect = self._mock_manager_vmhost_false
self.assertEqual(self.dev.facts["vmhost"], False)

@patch("jnpr.junos.Device.execute")
def test_vmhost_none(self, mock_execute):
mock_execute.side_effect = self._mock_manager_vmhost_false
self.dev.facts._cache["_is_linux"] = True
self.assertEqual(self.dev.facts["vmhost"], None)

@patch("jnpr.junos.Device.execute")
def test_vmhost_error(self, mock_execute):
mock_execute.side_effect = self._mock_manager_vmhost_error
self.assertEqual(self.dev.facts["vmhost"], None)

def _read_file(self, fname):
from ncclient.xml_ import NCElement

fpath = os.path.join(os.path.dirname(__file__), "rpc-reply", fname)
foo = open(fpath).read()

rpc_reply = NCElement(
foo, self.dev._conn._device_handler.transform_reply()
)._NCElement__doc[0]
return rpc_reply

def _mock_manager_setup(self, *args, **kwargs):
if kwargs:
device_params = kwargs["device_params"]
device_handler = make_device_handler(device_params)
session = SSHSession(device_handler)
return Manager(session, device_handler)

def _mock_manager_vmhost_true(self, *args, **kwargs):
if args:
return self._read_file("vmhost_true_" + args[0].tag + ".xml")

def _mock_manager_vmhost_false(self, *args, **kwargs):
if args:
return self._read_file("vmhost_false_" + args[0].tag + ".xml")

def _mock_manager_vmhost_error(self, *args, **kwargs):
if args:
return self._read_file("vmhost_error_" + args[0].tag + ".xml")

0 comments on commit 235a2b9

Please sign in to comment.