Example #1
0
 def routingprefixlength(self):
     """Return an integer."""
     netmask = IPAddress.asList(self.netmask)
     # for an easy way to determine the highest bit set see https://wiki.python.org/moin/BitManipulation
     return 8 * len(netmask) - int(
         math.floor(
             math.log(
                 IPAddress.asInteger(IPAddress.bitNot(netmask)) + 1, 2)))
Example #2
0
 def _changeIPAddress(cls, portsFileContent, oldIpAddress, newIpAddress):
     """Change all occurences of a specific IP address."""
     # method made to be portsFileContentModifyingMethod parameter for method modify()
     oldIpAddress = IPAddress.asString(oldIpAddress)
     newIpAddress = IPAddress.asString(newIpAddress)
     # feel the misery of not yet having better XPath from Python 2.7 and ElementTree 1.3
     sshElements = portsFileContent.findall("ssh")
     for sshElement in sshElements:
         if oldIpAddress == sshElement.findtext("ipaddress"):
             # found oldIpAddress
             ipaddressElement = sshElement.find("ipaddress")
             ipaddressElement.text = newIpAddress
Example #3
0
 def _changeIPAddress(cls, portsFileContent, oldIpAddress, newIpAddress):
     """Change all occurences of a specific IP address."""
     # method made to be portsFileContentModifyingMethod parameter for method modify()
     oldIpAddress = IPAddress.asString(oldIpAddress)
     newIpAddress = IPAddress.asString(newIpAddress)
     # feel the misery of not yet having better XPath from Python 2.7 and ElementTree 1.3
     sshElements = portsFileContent.findall("ssh")
     for sshElement in sshElements:
         if oldIpAddress == sshElement.findtext("ipaddress"):
             # found oldIpAddress
             ipaddressElement = sshElement.find("ipaddress")
             ipaddressElement.text = newIpAddress
Example #4
0
 def removeKnownHostKey(cls, ipaddress):
     """Remove line from ~/.ssh/known_hosts file."""
     knownHostsFile = SshCommand._knownHostFilePath
     ipaddress = IPAddress.asString(ipaddress)
     if not os.path.exists(knownHostsFile):
         # maybe file hasn't been created yet, nothing to do
         return
     with open (knownHostsFile, "r") as inputFile:
         knownHostLines = inputFile.readlines()
     ipaddressRegex = re.compile(r"^[ \t]*" + re.escape(ipaddress) + r"\s")
     anyMatch = False
     newKnownHostLines = []
     for knownHostLine in knownHostLines:
         if ipaddressRegex.search(knownHostLine):
             # a match, don't copy it over
             anyMatch = True
         else:
             # all others copy over
             newKnownHostLines.append(knownHostLine)
     if anyMatch:
         with open (knownHostsFile, "w") as outputFile:
             outputFile.writelines(newKnownHostLines)
     if not anyMatch: # possibly not found as plain text because hashed
         sshKeygen = CommandCapture(["ssh-keygen",
                                     "-f", knownHostsFile,
                                     "-R", ipaddress],
                                    copyToStdio=False,
                                    exceptionIfNotZero=False, exceptionIfAnyStderr=False)
Example #5
0
 def sleepUntilHasAcceptedKnownHostKey(cls,
                                       sshParameters,
                                       checkIntervalSeconds=3.0,
                                       ticker=False,
                                       extraSleepSeconds=5.0):
     """If available return, else loop sleeping for checkIntervalSeconds.
     
     sshParameters
         an SshParameters instance to use in the attempts."""
     printed = False
     ticked = False
     # check the essential condition, initially and then repeatedly
     while not SshCommand.hasAcceptedKnownHostKey(
             sshParameters=sshParameters):
         if not printed:
             # first time only printing
             print "waiting for ssh to be available to get host key from " + IPAddress.asString(
                 sshParameters.ipaddress)
             sys.stdout.flush()
             printed = True
         if ticker:
             if not ticked:
                 # first time only printing
                 sys.stdout.write("[")
             sys.stdout.write(".")
             sys.stdout.flush()
             ticked = True
         time.sleep(checkIntervalSeconds)
     if ticked:
         # final printing
         sys.stdout.write("]\n")
         sys.stdout.flush()
     if extraSleepSeconds:
         time.sleep(extraSleepSeconds)
Example #6
0
 def sleepUntilIsAvailable(cls,
                           sshParameters,
                           checkIntervalSeconds=5.0,
                           ticker=False,
                           probingCommand="hostname"):
     """If available return, else loop sleeping for checkIntervalSeconds."""
     printed = False
     ticked = False
     # check the essential condition, initially and then repeatedly
     while not SshCommand.isAvailable(sshParameters,
                                      probingCommand=probingCommand):
         if not printed:
             # first time only printing
             print "waiting for ssh to be available to connect to " + IPAddress.asString(
                 sshParameters.ipaddress)
             sys.stdout.flush()
             printed = True
         if ticker:
             if not ticked:
                 # first time only printing
                 sys.stdout.write("[")
             sys.stdout.write(".")
             sys.stdout.flush()
             ticked = True
         time.sleep(checkIntervalSeconds)
     if ticked:
         # final printing
         sys.stdout.write("]\n")
         sys.stdout.flush()
Example #7
0
 def removeKnownHostKey(cls, ipaddress):
     """Remove line from ~/.ssh/known_hosts file."""
     knownHostsFile = SshCommand._knownHostFilePath
     ipaddress = IPAddress.asString(ipaddress)
     if not os.path.exists(knownHostsFile):
         # maybe file hasn't been created yet, nothing to do
         return
     with open(knownHostsFile, "r") as inputFile:
         knownHostLines = inputFile.readlines()
     ipaddressRegex = re.compile(r"^[ \t]*" + re.escape(ipaddress) + r"\s")
     anyMatch = False
     newKnownHostLines = []
     for knownHostLine in knownHostLines:
         if ipaddressRegex.search(knownHostLine):
             # a match, don't copy it over
             anyMatch = True
         else:
             # all others copy over
             newKnownHostLines.append(knownHostLine)
     if anyMatch:
         with open(knownHostsFile, "w") as outputFile:
             outputFile.writelines(newKnownHostLines)
     if not anyMatch:  # possibly not found as plain text because hashed
         sshKeygen = CommandCapture(
             ["ssh-keygen", "-f", knownHostsFile, "-R", ipaddress],
             copyToStdio=False,
             exceptionIfNotZero=False,
             exceptionIfAnyStderr=False)
Example #8
0
 def sleepUntilIsAvailable(cls, sshParameters,
                           checkIntervalSeconds=5.0, ticker=False,
                           probingCommand="hostname"):
     """If available return, else loop sleeping for checkIntervalSeconds."""
     printed = False
     ticked = False
     # check the essential condition, initially and then repeatedly
     while not SshCommand.isAvailable(sshParameters,
                                      probingCommand=probingCommand):
         if not printed:
             # first time only printing
             print "waiting for ssh to be available to connect to " + IPAddress.asString(sshParameters.ipaddress)
             sys.stdout.flush()
             printed = True
         if ticker:
             if not ticked:
                 # first time only printing
                 sys.stdout.write("[")
             sys.stdout.write(".")
             sys.stdout.flush()
             ticked = True
         time.sleep(checkIntervalSeconds)
     if ticked:
         # final printing
         sys.stdout.write("]\n")
         sys.stdout.flush()
Example #9
0
 def sleepUntilHasAcceptedKnownHostKey(cls, sshParameters,
                                       checkIntervalSeconds=3.0, ticker=False,
                                       extraSleepSeconds=5.0):
     """If available return, else loop sleeping for checkIntervalSeconds.
     
     sshParameters
         an SshParameters instance to use in the attempts."""
     printed = False
     ticked = False
     # check the essential condition, initially and then repeatedly
     while not SshCommand.hasAcceptedKnownHostKey(sshParameters=sshParameters):
         if not printed:
             # first time only printing
             print "waiting for ssh to be available to get host key from " + IPAddress.asString(sshParameters.ipaddress)
             sys.stdout.flush()
             printed = True
         if ticker:
             if not ticked:
                 # first time only printing
                 sys.stdout.write("[")
             sys.stdout.write(".")
             sys.stdout.flush()
             ticked = True
         time.sleep(checkIntervalSeconds)
     if ticked:
         # final printing
         sys.stdout.write("]\n")
         sys.stdout.flush()
     if extraSleepSeconds:
         time.sleep(extraSleepSeconds)
Example #10
0
 def sleepUntilIsGuiAvailable(cls, sshParameters,
                              checkIntervalSeconds=3.0, ticker=False,
                              extraSleepSeconds=5.0):
     """If GUI available return, else loop sleeping for checkIntervalSeconds.
     
     Should be user to be meaningful.
     
     As implemented first calls SshCommand.sleepUntilIsAvailable(sshParameters).
     
     sshParameters
         an SshParameters instance."""
     cls.sleepUntilIsAvailable(sshParameters,
                               checkIntervalSeconds=checkIntervalSeconds, ticker=ticker)
     printed = False
     ticked = False
     # check the essential condition, initially and then repeatedly
     while not cls.isGuiAvailable(sshParameters):
         if not printed:
             # first time only printing
             print "waiting for GUI to be available to connect to " + IPAddress.asString(sshParameters.ipaddress)
             sys.stdout.flush()
             printed = True
         if ticker:
             if not ticked:
                 # first time only printing
                 sys.stdout.write("[")
             sys.stdout.write(".")
             sys.stdout.flush()
             ticked = True
         time.sleep(checkIntervalSeconds)
     if ticked:
         # final printing
         sys.stdout.write("]\n")
     if extraSleepSeconds:
         time.sleep(extraSleepSeconds)
Example #11
0
 def commandToChangeStaticIPAddress(cls,
                                    oldIpAddress,
                                    newIpAddress,
                                    interface=None):
     """Build command to change static IP address.
     
     Must be root to succeed.
     
     As implemented works in Enterprise Linux versions 6.x.
     
     Example use:
     
         vm = VMwareMachine("~/vmware/examples/example68/example68.vmx")
         VMwareHypervisor.local.start(vm.vmxFilePath)
         vm.sleepUntilSshIsAvailable(ticker=True)
         vm.sshCommand([ElClone.commandToChangeStaticIPAddress("10.123.45.67", "10.123.45.68")])
         vm.portsFile.changeIPAddress("10.123.45.67", "10.123.45.68")
         vm.sleepUntilSshIsAvailable(ticker=True)
         vm.acceptKnownHostKey()
         vm.sshCommand([ElClone.commandToChangeHostname("example67", "example68")])
     
     interface
         a string, e.g. "eth0".
     
     Return command to change static IP address."""
     oldIpAddress = IPAddress.asString(oldIpAddress)
     newIpAddress = IPAddress.asString(newIpAddress)
     if re.search(r"\s", oldIpAddress):
         raise Exception(
             "not accepting whitespace in IP address ({0})".format(
                 oldIpAddress))
     if re.search(r"\s", newIpAddress):
         raise Exception(
             "not accepting whitespace in IP address ({0})".format(
                 newIpAddress))
     # quite sensitive to quoting and not quoting
     command = r"sed -i -e 's/=\"\?" + re.escape(
         oldIpAddress) + r"\"\?/=\"" + re.escape(newIpAddress) + r"\"/'"
     if interface:
         command += r" '/etc/sysconfig/network-scripts/ifcfg-" + re.escape(
             interface) + r"'"
     else:
         # quite sensitive to quoting and not quoting
         command = r"for f in /etc/sysconfig/network-scripts/ifcfg-* ; do " + command + r" $f ; done"
     # oddly has been observed to require two times service network restart
     command += r" ; ( nohup sh -c 'service network restart ; service network restart' &> /dev/null & )"
     return command
Example #12
0
 def _removeSsh(cls, portsFileContent, ipaddress, user):
     """Remove .ports file entry for ssh access for a user."""
     # method made to be portsFileContentModifyingMethod parameter for method modify()
     ipaddress = IPAddress.asString(ipaddress)
     # feel the misery of not yet having better XPath from Python 2.7 and ElementTree 1.3
     ports = portsFileContent.getroot()
     sshElements = portsFileContent.findall("ssh")
     for sshElement in sshElements:
         if user == sshElement.findtext("user") and ipaddress == sshElement.findtext("ipaddress"):
             # found user at ipaddress
             ports.remove(sshElement)
Example #13
0
 def _removeSsh(cls, portsFileContent, ipaddress, user):
     """Remove .ports file entry for ssh access for a user."""
     # method made to be portsFileContentModifyingMethod parameter for method modify()
     ipaddress = IPAddress.asString(ipaddress)
     # feel the misery of not yet having better XPath from Python 2.7 and ElementTree 1.3
     ports = portsFileContent.getroot()
     sshElements = portsFileContent.findall("ssh")
     for sshElement in sshElements:
         if user == sshElement.findtext("user") and ipaddress == sshElement.findtext("ipaddress"):
             # found user at ipaddress
             ports.remove(sshElement)
Example #14
0
 def normalizeStaticIp(self,
                       ipaddress,
                       netmask="255.255.255.0",
                       gateway=None,
                       nameservers=None):
     """Normalize static IP options for network configuration.
     
     As implemented only supports IPv4.
     
     ipaddress
         IP address.
     
     netmask
         netmask.
         Defaults to 255.255.255.0.
     
     gateway
         gateway.
         If None then default to ip.1.
     
     nameservers
         one nameserver or a list of nameservers.
         If None then default to gateway.
         If empty list then remove option.
     
     return
         a NetworkConfigurationStaticParameters instance."""
     # also see http://docs.redhat.com/docs/en-US/Red_Hat_Enterprise_Linux/6/html/Installation_Guide/s1-kickstart2-options.html
     # sanity check
     ipaddress = IPAddress.asString(ipaddress)
     if not re.match(r"^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$",
                     ipaddress):
         raise Exception(
             "won't accept apparently impossible IP address {0}".format(
                 ipaddress))
     netmask = IPAddress.asString(netmask)
     if gateway is None:
         # default to ip.1
         gateway = IPAddress.bitOr(IPAddress.bitAnd(ipaddress, netmask),
                                   "0.0.0.1")
     gateway = IPAddress.asString(gateway)
     if nameservers is None:
         # default to gateway
         nameservers = [gateway]
     elif not isinstance(nameservers, list):
         # process one as a list of one
         nameservers = [nameservers]
     else:
         # given a list already
         nameservers = nameservers
     nameserversStrings = [
         IPAddress.asString(oneNameserver) for oneNameserver in nameservers
     ]
     normalized = NetworkConfigurationStaticParameters(
         ipaddress=ipaddress,
         netmask=netmask,
         gateway=gateway,
         nameservers=nameserversStrings)
     return normalized
Example #15
0
 def commandToChangeStaticIPAddress(cls, oldIpAddress, newIpAddress, interface=None):
     """Build command to change static IP address.
     
     Must be root to succeed.
     
     As implemented works in Enterprise Linux versions 6.x.
     
     Example use:
     
         vm = VMwareMachine("~/vmware/examples/example68/example68.vmx")
         VMwareHypervisor.local.start(vm.vmxFilePath)
         vm.sleepUntilSshIsAvailable(ticker=True)
         vm.sshCommand([ElClone.commandToChangeStaticIPAddress("10.123.45.67", "10.123.45.68")])
         vm.portsFile.changeIPAddress("10.123.45.67", "10.123.45.68")
         vm.sleepUntilSshIsAvailable(ticker=True)
         vm.acceptKnownHostKey()
         vm.sshCommand([ElClone.commandToChangeHostname("example67", "example68")])
     
     interface
         a string, e.g. "eth0".
     
     Return command to change static IP address."""
     oldIpAddress = IPAddress.asString(oldIpAddress)
     newIpAddress = IPAddress.asString(newIpAddress)
     if re.search(r"\s", oldIpAddress):
         raise Exception("not accepting whitespace in IP address ({0})".format(oldIpAddress))
     if re.search(r"\s", newIpAddress):
         raise Exception("not accepting whitespace in IP address ({0})".format(newIpAddress))
     # quite sensitive to quoting and not quoting
     command = r"sed -i -e 's/=\"\?" + re.escape(oldIpAddress) + r"\"\?/=\"" + re.escape(newIpAddress) + r"\"/'"
     if interface:
         command += r" '/etc/sysconfig/network-scripts/ifcfg-" + re.escape(interface) + r"'"
     else:
         # quite sensitive to quoting and not quoting
         command = r"for f in /etc/sysconfig/network-scripts/ifcfg-* ; do " + command + r" $f ; done"
     # oddly has been observed to require two times service network restart
     command += r" ; ( nohup sh -c 'service network restart ; service network restart' &> /dev/null & )"
     return command
Example #16
0
 def commandToAppendAddressNameLineToEtcHosts(cls, ipaddress, name):
     """Build command to append an ipaddress hostname line to /etc/hosts.
     
     Only if no line yet.
     As implemented any fgrep match of name in /etc/hosts prevents addition.
     
     Must be root to succeed.
     
     Return command to append an ipaddress hostname line to /etc/hosts."""
     name = re.escape(name)  # precaution
     ipaddress = IPAddress.asString(ipaddress)
     command = "fgrep -q -e '" + name + "' /etc/hosts || " \
               + "echo '" + ipaddress + " " + name + "' >> /etc/hosts"
     return command
Example #17
0
 def commandToAppendAddressNameLineToEtcHosts(cls, ipaddress, name):
     """Build command to append an ipaddress hostname line to /etc/hosts.
     
     Only if no line yet.
     As implemented any fgrep match of name in /etc/hosts prevents addition.
     
     Must be root to succeed.
     
     Return command to append an ipaddress hostname line to /etc/hosts."""
     name = re.escape(name) # precaution
     ipaddress = IPAddress.asString(ipaddress)
     command = "fgrep -q -e '" + name + "' /etc/hosts || " \
               + "echo '" + ipaddress + " " + name + "' >> /etc/hosts"
     return command
Example #18
0
 def __init__(self, ipaddress, user, pwd):
     """Create new SshParameters instance.
     
     Example use::
     
         exampleSshParameters = SshParameters("10.123.45.67", "joe", "redwood")
     
     ipaddress
         IP address or domain name.
     
     user
         a string.
     
     pwd
         a string or None."""
     self.ipaddress = IPAddress.asString(ipaddress)
     self.user = user
     self.pwd = pwd
Example #19
0
 def __init__(self, ipaddress, user, pwd):
     """Create new SshParameters instance.
     
     Example use::
     
         exampleSshParameters = SshParameters("10.123.45.67", "joe", "redwood")
     
     ipaddress
         IP address or domain name.
     
     user
         a string.
     
     pwd
         a string or None."""
     self.ipaddress = IPAddress.asString(ipaddress)
     self.user = user
     self.pwd = pwd
 def normalizeStaticIp(self, ipaddress, netmask="255.255.255.0", gateway=None, nameservers=None):
     """Normalize static IP options for network configuration.
     
     As implemented only supports IPv4.
     
     ipaddress
         IP address.
     
     netmask
         netmask.
         Defaults to 255.255.255.0.
     
     gateway
         gateway.
         If None then default to ip.1.
     
     nameservers
         one nameserver or a list of nameservers.
         If None then default to gateway.
         If empty list then remove option.
     
     return
         a NetworkConfigurationStaticParameters instance."""
     # also see http://docs.redhat.com/docs/en-US/Red_Hat_Enterprise_Linux/6/html/Installation_Guide/s1-kickstart2-options.html
     # sanity check
     ipaddress = IPAddress.asString(ipaddress)
     if not re.match(r"^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$", ipaddress):
         raise Exception("won't accept apparently impossible IP address {0}".format(ipaddress))
     netmask = IPAddress.asString(netmask)
     if gateway is None:
         # default to ip.1
         gateway = IPAddress.bitOr(IPAddress.bitAnd(ipaddress, netmask), "0.0.0.1")
     gateway = IPAddress.asString(gateway)
     if nameservers is None:
         # default to gateway
         nameservers = [gateway]
     elif not isinstance(nameservers, list):
         # process one as a list of one
         nameservers = [nameservers]
     else:
         # given a list already
         nameservers = nameservers
     nameserversStrings = [IPAddress.asString(oneNameserver) for oneNameserver in nameservers]
     normalized = NetworkConfigurationStaticParameters(ipaddress=ipaddress,
                                                       netmask=netmask,
                                                       gateway=gateway,
                                                       nameservers=nameserversStrings)
     return normalized
Example #21
0
 def _setSsh(cls, portsFileContent, ipaddress, user, pwd):
     """Set .ports file entry for ssh access for a user."""
     # method made to be portsFileContentModifyingMethod parameter for method modify()
     ipaddress = IPAddress.asString(ipaddress)
     # feel the misery of not yet having better XPath from Python 2.7 and ElementTree 1.3
     sshElements = portsFileContent.findall("ssh")
     for sshElement in sshElements:
         if user == sshElement.findtext("user") and ipaddress == sshElement.findtext("ipaddress"):
             # found user at ipaddress
             pwdElement = sshElement.find("pwd")
             if pwdElement is None: # odd case
                 pwdElement = SubElement(sshElement, "pwd")
             pwdElement.text = pwd
             return # done
     # no entry yet for user at ipaddress
     sshElement = SubElement(portsFileContent.getroot(), "ssh")
     ipaddressElement = SubElement(sshElement, "ipaddress")
     ipaddressElement.text = ipaddress
     userElement = SubElement(sshElement, "user")
     userElement.text = user
     pwdElement = SubElement(sshElement, "pwd")
     pwdElement.text = pwd
Example #22
0
 def _setSsh(cls, portsFileContent, ipaddress, user, pwd):
     """Set .ports file entry for ssh access for a user."""
     # method made to be portsFileContentModifyingMethod parameter for method modify()
     ipaddress = IPAddress.asString(ipaddress)
     # feel the misery of not yet having better XPath from Python 2.7 and ElementTree 1.3
     sshElements = portsFileContent.findall("ssh")
     for sshElement in sshElements:
         if user == sshElement.findtext("user") and ipaddress == sshElement.findtext("ipaddress"):
             # found user at ipaddress
             pwdElement = sshElement.find("pwd")
             if pwdElement is None: # odd case
                 pwdElement = SubElement(sshElement, "pwd")
             pwdElement.text = pwd
             return # done
     # no entry yet for user at ipaddress
     sshElement = SubElement(portsFileContent.getroot(), "ssh")
     ipaddressElement = SubElement(sshElement, "ipaddress")
     ipaddressElement.text = ipaddress
     userElement = SubElement(sshElement, "user")
     userElement.text = user
     pwdElement = SubElement(sshElement, "pwd")
     pwdElement.text = pwd
Example #23
0
    def addNetworkConfigurationStatic(self, mac,
                                      ipaddress, netmask="255.255.255.0", gateway=None, nameservers=None,
                                      limitRoutingToLocalByNetmask=False):
        """Add an additional network device with static IP.
        
        As implemented only supports IPv4.
        
        mac
            the MAC, e.g. "01:23:45:67:89:ab" or "01-23-45-67-89-AB".
        
        ipaddress
            IP address.
        
        netmask
            netmask.
            Defaults to 255.255.255.0.
        
        gateway
            gateway.
            If None then default to ip.1.
        
        nameservers
            one nameserver or a list of nameservers.
            If None then default to gateway.
            If empty list then do not add any.
        
        return
            self, for daisychaining."""
        # sanity check
        normalizedStaticIp = NetworkConfigurationStaticParameters.normalizeStaticIp(ipaddress, netmask, gateway, nameservers)
        # see http://technet.microsoft.com/en-us/library/ff716288.aspx
        mac = mac.replace(":","-").upper()
        ipaddressSlashRoutingPrefixLength = normalizedStaticIp.ipaddress + "/" + str(normalizedStaticIp.routingprefixlength)
        gatewaySlashRoutingPrefixLength = normalizedStaticIp.gateway + "/" + str(normalizedStaticIp.routingprefixlength)
        if not limitRoutingToLocalByNetmask:
            routePrefix = "0.0.0.0/0"
        else:
            routePrefix = IPAddress.asString(normalizedStaticIp.localprefix) + "/" + str(normalizedStaticIp.routingprefixlength)
        nameservers = normalizedStaticIp.nameservers
        additionalContent = r"""
<component name="Microsoft-Windows-TCPIP" processorArchitecture="x86" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <Interfaces>
    <Interface wcm:action="add">
      <Identifier>""" + mac + r"""</Identifier>
      <Ipv4Settings>
        <DhcpEnabled>false</DhcpEnabled>
        <RouterDiscoveryEnabled>false</RouterDiscoveryEnabled>
      </Ipv4Settings>
      <UnicastIpAddresses>
        <IpAddress wcm:action="add" wcm:keyValue="1">""" + ipaddressSlashRoutingPrefixLength + r"""</IpAddress>
      </UnicastIpAddresses>
      <Routes>
        <Route wcm:action="add">
          <Identifier>1</Identifier>
          <NextHopAddress>""" + gatewaySlashRoutingPrefixLength + r"""</NextHopAddress>
          <Prefix>""" + routePrefix + r"""</Prefix>
        </Route>
      </Routes>
    </Interface>
  </Interfaces>
</component>"""
        if nameservers:
            additionalContent += r"""
<component name="Microsoft-Windows-DNS-Client" processorArchitecture="x86" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <Interfaces>
    <Interface wcm:action="add">
      <Identifier>""" + mac + r"""</Identifier>
      <DNSServerSearchOrder>
""" + "\n".join(map(lambda nameserver, i:
                    r"""<IpAddress wcm:action="add" wcm:keyValue=""" r'"' + str(i+1) + r'"' r""">""" + nameserver + r"""</IpAddress>""",
                    nameservers, range(0,len(nameservers)))) + r"""
      </DNSServerSearchOrder>
      <EnableAdapterDomainNameRegistration>false</EnableAdapterDomainNameRegistration>
      <DisableDynamicUpdate>true</DisableDynamicUpdate>
    </Interface>
  </Interfaces>
<DNSDomain>example.com</DNSDomain>
</component>"""
        self._appendToChildren("settings", "pass", "specialize", additionalContent, prepend=True)
        return self
Example #24
0
    def addNetworkConfigurationStatic(self,
                                      mac,
                                      ipaddress,
                                      netmask="255.255.255.0",
                                      gateway=None,
                                      nameservers=None,
                                      limitRoutingToLocalByNetmask=False):
        """Add an additional network device with static IP.
        
        As implemented only supports IPv4.
        
        mac
            the MAC, e.g. "01:23:45:67:89:ab" or "01-23-45-67-89-AB".
        
        ipaddress
            IP address.
        
        netmask
            netmask.
            Defaults to 255.255.255.0.
        
        gateway
            gateway.
            If None then default to ip.1.
        
        nameservers
            one nameserver or a list of nameservers.
            If None then default to gateway.
            If empty list then do not add any.
        
        return
            self, for daisychaining."""
        # sanity check
        normalizedStaticIp = NetworkConfigurationStaticParameters.normalizeStaticIp(
            ipaddress, netmask, gateway, nameservers)
        # see http://technet.microsoft.com/en-us/library/ff716288.aspx
        mac = mac.replace(":", "-").upper()
        ipaddressSlashRoutingPrefixLength = normalizedStaticIp.ipaddress + "/" + str(
            normalizedStaticIp.routingprefixlength)
        gatewaySlashRoutingPrefixLength = normalizedStaticIp.gateway + "/" + str(
            normalizedStaticIp.routingprefixlength)
        if not limitRoutingToLocalByNetmask:
            routePrefix = "0.0.0.0/0"
        else:
            routePrefix = IPAddress.asString(
                normalizedStaticIp.localprefix) + "/" + str(
                    normalizedStaticIp.routingprefixlength)
        nameservers = normalizedStaticIp.nameservers
        additionalContent = r"""
<component name="Microsoft-Windows-TCPIP" processorArchitecture="x86" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <Interfaces>
    <Interface wcm:action="add">
      <Identifier>""" + mac + r"""</Identifier>
      <Ipv4Settings>
        <DhcpEnabled>false</DhcpEnabled>
        <RouterDiscoveryEnabled>false</RouterDiscoveryEnabled>
      </Ipv4Settings>
      <UnicastIpAddresses>
        <IpAddress wcm:action="add" wcm:keyValue="1">""" + ipaddressSlashRoutingPrefixLength + r"""</IpAddress>
      </UnicastIpAddresses>
      <Routes>
        <Route wcm:action="add">
          <Identifier>1</Identifier>
          <NextHopAddress>""" + gatewaySlashRoutingPrefixLength + r"""</NextHopAddress>
          <Prefix>""" + routePrefix + r"""</Prefix>
        </Route>
      </Routes>
    </Interface>
  </Interfaces>
</component>"""
        if nameservers:
            additionalContent += r"""
<component name="Microsoft-Windows-DNS-Client" processorArchitecture="x86" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <Interfaces>
    <Interface wcm:action="add">
      <Identifier>""" + mac + r"""</Identifier>
      <DNSServerSearchOrder>
""" + "\n".join(
                map(
                    lambda nameserver, i:
                    r"""<IpAddress wcm:action="add" wcm:keyValue="""
                    r'"' + str(i + 1) + r'"'
                    r""">""" + nameserver + r"""</IpAddress>""", nameservers,
                    range(0, len(nameservers)))) + r"""
      </DNSServerSearchOrder>
      <EnableAdapterDomainNameRegistration>false</EnableAdapterDomainNameRegistration>
      <DisableDynamicUpdate>true</DisableDynamicUpdate>
    </Interface>
  </Interfaces>
<DNSDomain>example.com</DNSDomain>
</component>"""
        self._appendToChildren("settings",
                               "pass",
                               "specialize",
                               additionalContent,
                               prepend=True)
        return self
Example #25
0
                                                      VmdkFile, VMwareHypervisor,
                                                      SshCommand, ScpCommand],
                                                     verbose=True)
# this is a good way to preflight check
VMwareHypervisor.localRequired()

# BEGIN essential example code
ipaddress = "192.168.0.166"
# a possible modification pointed out
# makes sense e.g. if used together with whateverVm.vmxFile.setEthernetAdapter(adapter, "hostonly")
#ipaddress = IPAddress.numberWithinSubnet(VMwareHypervisor.localHostOnlyIPAddress, 166)
rootpw = "redwood"
# Ubuntu kickstart supports only one regular user
regularUser = ("jack","rainbow")
# one possible way of making new VM names and directories
name = IPAddress.nameWithNumber("example", ipaddress, separator=None)
exampleVm = VMwareMachine(ScriptUser.loggedIn.userHomeRelative("vmware/examples/%s/%s.vmx" % (name, name)))
# make the virtual machine
exists = exampleVm.vmxFile.exists()
if exists == False:
    exampleVm.mkdir()
    downloadedDistroIsoImage = UbIsoImage(Download.fromUrl
                                          ("http://releases.ubuntu.com/precise/ubuntu-12.04.3-alternate-i386.iso"))
    # some possible choices pointed out
    # server w command line only
    kickstartFileContent = UbKickstartFileContent(UbKickstartTemplates.usableUbKickstartTemplate001)
    kickstartFileContent.replaceRootpw(rootpw)
    kickstartFileContent.ubReplaceHostname(exampleVm.basenameStem)
    kickstartFileContent.ubCreateNetworkConfigurationSection()
    kickstartFileContent.ubAddNetworkConfigurationStatic(device="eth0", ipaddress=ipaddress, nameservers=Nameserver.list)
    # put in DHCP at eth0, to be used with NAT, works well if before hostonly
Example #26
0
 def localprefix(self):
     return IPAddress.bitAnd(self.ipaddress, self.netmask)
 def routingprefixlength(self):
     """Return an integer."""
     netmask = IPAddress.asList(self.netmask)
     # for an easy way to determine the highest bit set see https://wiki.python.org/moin/BitManipulation
     return 8 * len(netmask) - int(math.floor(math.log(IPAddress.asInteger(IPAddress.bitNot(netmask)) + 1, 2)))
Example #28
0
 def __init__(self,
              fromPath, toPath,
              fromSshParameters=None, toSshParameters=None,
              recurseDirectories=False,
              preserveTimes=True):
     """Create new ScpCommand instance.
     
     Will wait until completed.
     
     Either fromPath or toPath is expected to be local, i.e. without user and without IP address.
     Correspondingly either fromSshParameters or toSshParameters must NOT be assigned an SshParameters
     instance and remain default None.
     
     fromPath
         one path or a list of paths.
         
         Absolute paths strongly recommended.
     
     toPath
         one path.
         
         Absolute path strongly recommended.
         
         Must be directory if more than one fromPath.
     
     fromSshParameters
         an SshParameters instance.
     
     toSshParameters
         an SshParameters instance.
     
     recurseDirectories
         a hint for when fromSshParameters."""
     if not _gotPty:
         # cannot use scp if no pty
         raise Exception("must have module pty available to use scp command"
                         ", which is known to be available in Python 2.6 on Linux, but not on Windows")
     #
     if fromSshParameters and toSshParameters:
         raise Exception("cannot copy if both fromSshParameters and toSshParameters, only one or other")
     if not fromSshParameters and not toSshParameters:
         raise Exception("cannot copy if neither fromSshParameters nor toSshParameters, requires one or other")
     #
     if not isinstance(fromPath, (list, tuple)): # should be one string for one path to copy from
         fromPaths = [fromPath]
     else: # should be a list of strings for multiple paths to copy from
         fromPaths = fromPath
     if len(fromPaths) == 0:
         raise Exception("cannot copy zero files, requires at least one")
     if fromSshParameters: # get files from remote
         if len(fromPaths) > 1 or recurseDirectories:
             if not os.path.isdir(toPath):
                 raise Exception("cannot copy multiple files into a file, must copy into a directory, not into %s" % toPath)
         self._fromSpecification = \
             [fromSshParameters.user + "@" + IPAddress.asString(fromSshParameters.ipaddress) + ":" + " ".join(fromPaths)]
         self._toSpecification = toPath
         self._pwd = fromSshParameters.pwd
     else: # put files to remote
         anyFromDirectory = False
         for path in fromPaths:
             if os.path.isdir(path):
                 anyFromDirectory = True
                 break
         if anyFromDirectory:
             recurseDirectories = True # mandatory in this case
         self._fromSpecification = fromPaths
         self._toSpecification = \
             toSshParameters.user + "@" + IPAddress.asString(toSshParameters.ipaddress) + ":" + toPath
         self._pwd = toSshParameters.pwd
     self._args = ["scp"]
     if preserveTimes:
         self._args.append("-p")
     if recurseDirectories:
         self._args.append("-r")
     self._args.extend(self._fromSpecification) # a list because possibly more than one
     self._args.append(self._toSpecification)
     #
     self._output = ""
     self._returncode = None
     #
     # fork and connect child to a pseudo-terminal
     self._pid, self._fd = pty.fork()
     if self._pid == 0:
         # in child process
         os.execvp("scp", self._args)
     else:
         # in parent process
         if self._pwd:
             # if given a password then apply
             promptedForPassword = False
             outputTillPrompt = ""
             # look for password prompt
             while not promptedForPassword:
                 try:
                     newOutput = os.read(self._fd, 1024)
                     if not len(newOutput):
                         # end has been reached
                         # was raise Exception("unexpected end of output from scp")
                         raise Exception("failing to connect for scp\n" + 
                                         outputTillPrompt)
                     # ssh has been observed returning "\r\n" for newline, but we want "\n"
                     newOutput = SshCommand._crLfRegex.sub("\n", newOutput)
                     outputTillPrompt += newOutput
                     if SshCommand._acceptPromptRegex.search(outputTillPrompt):
                         # e.g. "Are you sure you want to continue connecting (yes/no)? "
                         raise Exception("cannot proceed unless having accepted host key\n" +
                                         outputTillPrompt +
                                         '\nE.g. invoke SshCommand.acceptKnownHostKey(SshParameters("{0}",user,pwd)).'.format(self._ipaddress))
                     if SshCommand._pwdPromptRegex.search(outputTillPrompt):
                         # e.g. "10.123.45.67's password: "******"@    WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!     @" and closing
                     raise Exception("failing to connect for scp\n" + 
                                     outputTillPrompt)
             os.write(self._fd, self._pwd + "\n")
         # look for output
         endOfOutput = False
         outputSincePrompt = ""
         try:
             while not endOfOutput:
                 try:
                     newOutput = os.read(self._fd, 1024)
                     if len(newOutput):
                         outputSincePrompt += newOutput
                     else:
                         # end has been reached
                         endOfOutput = True
                 except EnvironmentError as e:
                     # some ideas maybe at http://bugs.python.org/issue5380
                     if e.errno == 5: # errno.EIO:
                         # seen when pty closes OSError: [Errno 5] Input/output error
                         endOfOutput = True
                     else:
                         # we accept what we got so far, for now
                         endOfOutput = True
         finally:
             # remove any leading space (maybe there after "password:"******"\n")
             self._output = re.sub(r"^\s*?\n(.*)$", r"\1", outputSincePrompt)
             #
             # get returncode
             try:
                 ignorePidAgain, waitEncodedStatusIndication = os.waitpid(self._pid, 0)
                 if os.WIFEXITED(waitEncodedStatusIndication):
                     # normal exit(status) call
                     self._returncode = os.WEXITSTATUS(waitEncodedStatusIndication)
                     # raise an exception if there is a reason
                     exceptionMessage = ""
                     if self._returncode:
                         exceptionMessage += "returncode: " + str(self._returncode)
                     if exceptionMessage:
                         commandDescription = "scp from:\n\t" + str(self._fromSpecification)
                         commandDescription += "\nto:\n\t" + self._toSpecification
                         commandDescription += "\nargs:\n\t" + str(self._args)
                         exceptionMessage = commandDescription + "\n" + exceptionMessage
                         exceptionMessage += "\noutput:\n" + self._output
                         raise ScpCommandException(exceptionMessage)
                 else:
                     # e.g. os.WIFSIGNALED or os.WIFSTOPPED
                     self._returncode = -1
                     raise ScpCommandException("scp did not exit normally")
             except OSError:
                 # supposedly can occur
                 self._returncode = -1
                 raise ScpCommandException("scp did not exit normally")
 def localprefix(self):
     return IPAddress.bitAnd(self.ipaddress, self.netmask)
Example #30
0
 def __init__(self,
              fromPath,
              toPath,
              fromSshParameters=None,
              toSshParameters=None,
              recurseDirectories=False,
              preserveTimes=True):
     """Create new ScpCommand instance.
     
     Will wait until completed.
     
     Either fromPath or toPath is expected to be local, i.e. without user and without IP address.
     Correspondingly either fromSshParameters or toSshParameters must NOT be assigned an SshParameters
     instance and remain default None.
     
     fromPath
         one path or a list of paths.
         
         Absolute paths strongly recommended.
     
     toPath
         one path.
         
         Absolute path strongly recommended.
         
         Must be directory if more than one fromPath.
     
     fromSshParameters
         an SshParameters instance.
     
     toSshParameters
         an SshParameters instance.
     
     recurseDirectories
         a hint for when fromSshParameters."""
     if not _gotPty:
         # cannot use scp if no pty
         raise Exception(
             "must have module pty available to use scp command"
             ", which is known to be available in Python 2.6 on Linux, but not on Windows"
         )
     #
     if fromSshParameters and toSshParameters:
         raise Exception(
             "cannot copy if both fromSshParameters and toSshParameters, only one or other"
         )
     if not fromSshParameters and not toSshParameters:
         raise Exception(
             "cannot copy if neither fromSshParameters nor toSshParameters, requires one or other"
         )
     #
     if not isinstance(
             fromPath,
         (list, tuple)):  # should be one string for one path to copy from
         fromPaths = [fromPath]
     else:  # should be a list of strings for multiple paths to copy from
         fromPaths = fromPath
     if len(fromPaths) == 0:
         raise Exception("cannot copy zero files, requires at least one")
     if fromSshParameters:  # get files from remote
         if len(fromPaths) > 1 or recurseDirectories:
             if not os.path.isdir(toPath):
                 raise Exception(
                     "cannot copy multiple files into a file, must copy into a directory, not into %s"
                     % toPath)
         self._fromSpecification = \
             [fromSshParameters.user + "@" + IPAddress.asString(fromSshParameters.ipaddress) + ":" + " ".join(fromPaths)]
         self._toSpecification = toPath
         self._pwd = fromSshParameters.pwd
     else:  # put files to remote
         anyFromDirectory = False
         for path in fromPaths:
             if os.path.isdir(path):
                 anyFromDirectory = True
                 break
         if anyFromDirectory:
             recurseDirectories = True  # mandatory in this case
         self._fromSpecification = fromPaths
         self._toSpecification = \
             toSshParameters.user + "@" + IPAddress.asString(toSshParameters.ipaddress) + ":" + toPath
         self._pwd = toSshParameters.pwd
     self._args = ["scp"]
     if preserveTimes:
         self._args.append("-p")
     if recurseDirectories:
         self._args.append("-r")
     self._args.extend(
         self._fromSpecification)  # a list because possibly more than one
     self._args.append(self._toSpecification)
     #
     self._output = ""
     self._returncode = None
     #
     # fork and connect child to a pseudo-terminal
     self._pid, self._fd = pty.fork()
     if self._pid == 0:
         # in child process
         os.execvp("scp", self._args)
     else:
         # in parent process
         if self._pwd:
             # if given a password then apply
             promptedForPassword = False
             outputTillPrompt = ""
             # look for password prompt
             while not promptedForPassword:
                 try:
                     newOutput = os.read(self._fd, 1024)
                     if not len(newOutput):
                         # end has been reached
                         # was raise Exception("unexpected end of output from scp")
                         raise Exception("failing to connect for scp\n" +
                                         outputTillPrompt)
                     # ssh has been observed returning "\r\n" for newline, but we want "\n"
                     newOutput = SshCommand._crLfRegex.sub("\n", newOutput)
                     outputTillPrompt += newOutput
                     if SshCommand._acceptPromptRegex.search(
                             outputTillPrompt):
                         # e.g. "Are you sure you want to continue connecting (yes/no)? "
                         raise Exception(
                             "cannot proceed unless having accepted host key\n"
                             + outputTillPrompt +
                             '\nE.g. invoke SshCommand.acceptKnownHostKey(SshParameters("{0}",user,pwd)).'
                             .format(self._ipaddress))
                     if SshCommand._pwdPromptRegex.search(outputTillPrompt):
                         # e.g. "10.123.45.67's password: "******"@    WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!     @" and closing
                     raise Exception("failing to connect for scp\n" +
                                     outputTillPrompt)
             os.write(self._fd, self._pwd + "\n")
         # look for output
         endOfOutput = False
         outputSincePrompt = ""
         try:
             while not endOfOutput:
                 try:
                     newOutput = os.read(self._fd, 1024)
                     if len(newOutput):
                         outputSincePrompt += newOutput
                     else:
                         # end has been reached
                         endOfOutput = True
                 except EnvironmentError as e:
                     # some ideas maybe at http://bugs.python.org/issue5380
                     if e.errno == 5:  # errno.EIO:
                         # seen when pty closes OSError: [Errno 5] Input/output error
                         endOfOutput = True
                     else:
                         # we accept what we got so far, for now
                         endOfOutput = True
         finally:
             # remove any leading space (maybe there after "password:"******"\n")
             self._output = re.sub(r"^\s*?\n(.*)$", r"\1",
                                   outputSincePrompt)
             #
             # get returncode
             try:
                 ignorePidAgain, waitEncodedStatusIndication = os.waitpid(
                     self._pid, 0)
                 if os.WIFEXITED(waitEncodedStatusIndication):
                     # normal exit(status) call
                     self._returncode = os.WEXITSTATUS(
                         waitEncodedStatusIndication)
                     # raise an exception if there is a reason
                     exceptionMessage = ""
                     if self._returncode:
                         exceptionMessage += "returncode: " + str(
                             self._returncode)
                     if exceptionMessage:
                         commandDescription = "scp from:\n\t" + str(
                             self._fromSpecification)
                         commandDescription += "\nto:\n\t" + self._toSpecification
                         commandDescription += "\nargs:\n\t" + str(
                             self._args)
                         exceptionMessage = commandDescription + "\n" + exceptionMessage
                         exceptionMessage += "\noutput:\n" + self._output
                         raise ScpCommandException(exceptionMessage)
                 else:
                     # e.g. os.WIFSIGNALED or os.WIFSTOPPED
                     self._returncode = -1
                     raise ScpCommandException("scp did not exit normally")
             except OSError:
                 # supposedly can occur
                 self._returncode = -1
                 raise ScpCommandException("scp did not exit normally")
Example #31
0
#!/usr/bin/python

# demoing some control of virtual machines

from nrvr.util.ipaddress import IPAddress
from nrvr.util.user import ScriptUser
from nrvr.vm.vmware import VMwareMachine, VMwareHypervisor

ipaddress = "192.168.4.171"
name = IPAddress.nameWithNumber("example", ipaddress)
exampleVm = VMwareMachine(ScriptUser.loggedIn.userHomeRelative("vmware/examples/%s/%s.vmx" % (name, name)))
VMwareHypervisor.local.start(exampleVm.vmxFilePath, gui=True)
print exampleVm.sshCommand(["ls nonexistent ; echo `hostname`"]).output

import os
import os.path
import shutil
import tempfile
from nrvr.util.times import Timestamp

_exampleDir = os.path.join(tempfile.gettempdir(), Timestamp.microsecondTimestamp())
os.mkdir(_exampleDir, 0755)
try:
    _sendDir = os.path.join(_exampleDir, "send")
    os.mkdir(_sendDir, 0755)
    _exampleFile1 = os.path.join(_sendDir, "example1.txt")
    with open(_exampleFile1, "w") as outputFile:
        outputFile.write("this is an example\n" * 1000000)
    _scpExample1 = exampleVm.scpPutCommand(fromHostPath=_exampleFile1, toGuestPath="~/example1.txt")
    print "returncode=" + str(_scpExample1.returncode)
    print "output=" + _scpExample1.output