Esempio n. 1
0
	def run(self, params, args):

		hosts = self.getHostnames(args)
		(name, interface, mac) = self.fillParams([
			('name',      None, True),
			('interface', None),
			('mac',       None)
			])

		if len(name.split('.')) > 1:
			raise ParamType(self, 'name', 'non-FQDN (base hostname)')
		if not interface and not mac:
			raise ParamRequired(self, ('interface', 'mac'))
		if len(hosts) != 1:
			raise ArgUnique(self, 'host')

		host = hosts[0]		

		if name.upper() == "NULL":
			name = host

		if interface:
			self.db.execute("""
				update networks, nodes set 
				networks.name='%s' where nodes.name='%s'
				and networks.node=nodes.id and
				networks.device like '%s'
				""" % (name, host, interface))
		else:
			self.db.execute("""
				update networks, nodes set 
				networks.name='%s' where nodes.name='%s'
				and networks.node=nodes.id and
				networks.mac like '%s'
				""" % (name, host, mac))
Esempio n. 2
0
    def run(self, params, args):

        (vlan, interface, mac) = self.fillParams([('vlan', None, True),
                                                  ('interface', None),
                                                  ('mac', None)])

        if not interface and not mac:
            raise ParamRequired(self, ('interface', 'mac'))
        try:
            vlanid = int(vlan)
        except:
            raise ParamType(self, 'vlan', 'integer')

        for host in self.getHostnames(args):
            if interface:
                self.db.execute("""
					update networks net, nodes n
					set net.vlanid = IF(%d = 0, NULL, %d)
					where net.device like '%s' and
					n.name = '%s' and net.node = n.id
					""" % (vlanid, vlanid, interface, host))
            else:
                self.db.execute("""
					update networks net, nodes n
					set net.vlanid = IF(%d = 0, NULL, %d)
					where net.mac like'%s' and
					n.name = '%s' and net.node = n.id
					""" % (vlanid, vlanid, mac, host))
Esempio n. 3
0
    def run(self, params, args):
        (host, interface, port) = self.fillParams([('host', None),
                                                   ('interface', None),
                                                   ('port', None)])

        switches = self.getSwitchNames(args)
        if len(switches) == 0:
            raise ArgRequired(self, 'switch')
        if len(switches) > 1:
            raise ArgUnique(self, 'switch')
        switch = switches[0]

        hosts = self.getHostnames([host])
        host = hosts[0]

        if not host:
            raise ParamRequired(self, ('host'))
        if not interface:
            raise ParamRequired(self, ('interface'))
        if not port:
            raise ParamRequired(self, ('port'))

        try:
            port = int(port)
        except:
            raise ParamType(self, 'port', 'integer')

        #
        # check if the host/port is defined for this switch
        #
        found = False
        for o in self.call('list.switch.host', [switch]):
            if o['host'] == host and o['port'] == port:
                found = True
        if not found:
            raise ArgError(self, 'host/port',
                           '"%s/%s" not found' % (host, port))

        #
        # see if the interface exists for this host
        #
        row = self.db.select("""net.id from networks net, nodes n
			where n.name='%s' and net.device='%s'
			and net.node = n.id""" % (host, interface))

        if not row:
            raise CommandError(
                self, 'interface "%s" does not exist for host "%s"' %
                (interface, host))

        interfaceid, = row[0]

        self.db.execute("""update switchports set interface=%s
			where port=%s and switch=(select id from nodes where name='%s')
			""" % (interfaceid, port, switch))
Esempio n. 4
0
    def run(self, params, args):
        hosts = self.getHosts(args)

        (vlan, interface, mac, network) = self.fillParams([('vlan', None,
                                                            True),
                                                           ('interface', None),
                                                           ('mac', None),
                                                           ('network', None)])

        # Gotta have one of these
        if not any([interface, mac, network]):
            raise ParamRequired(self, ('interface', 'mac', 'network'))

        # Make sure interface, mac, and/or network exist on our hosts
        self.validate(hosts, interface, mac, network)

        # vlan has to be an integer
        try:
            vlan = int(vlan)
        except:
            raise ParamType(self, 'vlan', 'integer')

        # If vlan is 0 then it should be NULL in the db
        if vlan == 0:
            vlan = None

        for host in hosts:
            if network:
                sql = """
					update networks,nodes,subnets set networks.vlanid=%s
					where nodes.name=%s and subnets.name=%s
					and networks.node=nodes.id and networks.subnet=subnets.id
				"""
                values = [vlan, host, network]
            else:
                sql = """
					update networks,nodes set networks.vlanid=%s
					where nodes.name=%s and networks.node=nodes.id
				"""
                values = [vlan, host]

            if interface:
                sql += " and networks.device=%s"
                values.append(interface)

            if mac:
                sql += " and networks.mac=%s"
                values.append(mac)

            self.db.execute(sql, values)
Esempio n. 5
0
    def run(self, params, args):
        if len(args) == 0:
            raise ArgRequired(self, 'network')

        if len(args) != 1:
            raise ArgUnique(self, 'network')

        name = args[0]

        if ' ' in name:
            raise CommandError(self, 'network name must not contain a space')

        (address, mask, gateway, mtu, zone, dns,
         pxe) = self.fillParams([('address', None, True), ('mask', None, True),
                                 ('gateway', None), ('mtu', '1500'),
                                 ('zone', name), ('dns', 'n'), ('pxe', 'n')])

        dns = self.str2bool(dns)
        pxe = self.str2bool(pxe)

        # A None gateway is a blank string
        if gateway is None:
            gateway = ''

        # The mtu parameter needs to be an int
        if mtu:
            try:
                mtu = int(mtu)
            except:
                raise ParamType(self, 'mtu', 'integer')

        # Make sure the network doesn't already exist
        if self.db.count('(ID) from subnets where name=%s', (name, )) != 0:
            raise CommandError(self, 'network "%s" exists' % name)

        # Check that we are a valid network
        try:
            if ipaddress.IPv4Network(u"%s/%s" % (address, mask)):
                pass
        except:
            msg = '%s/%s is not a valid network address and subnet mask combination'
            raise CommandError(self, msg % (address, mask))

        # Insert our data
        self.db.execute(
            """
			insert into subnets (name, address, mask, gateway, mtu, zone, dns, pxe)
			values (%s, %s, %s, %s, %s, %s, %s, %s)
		""", (name, address, mask, gateway, mtu, zone, dns, pxe))
Esempio n. 6
0
	def run(self, params, args):
		host = self.getSingleHost(args)

		(name, interface, mac, network) = self.fillParams([
			('name', None, True),
			('interface', None),
			('mac', None),
			('network', None)
		])

		# Name can't be a FQDN (IE: have dots)
		if '.' in name:
			raise ParamType(self, 'name', 'non-FQDN (base hostname)')

		# Gotta have one of these
		if not any([interface, mac, network]):
			raise ParamRequired(self, ('interface', 'mac', 'network'))

		# Make sure interface, mac, and/or network exist on our hosts
		self.validate([host], interface, mac, network)

		# If name is set to 'NULL' it gets the host name
		if name.upper() == 'NULL':
			name = host

		# Make the change in the DB
		if network:
			sql = """
				update networks,nodes,subnets set networks.name=%s
				where nodes.name=%s and subnets.name=%s
				and networks.node=nodes.id and networks.subnet=subnets.id
			"""
			values = [name, host, network]
		else:
			sql = """
				update networks,nodes set networks.name=%s
				where nodes.name=%s and networks.node=nodes.id
			"""
			values = [name, host]

		if interface:
			sql += " and networks.device=%s"
			values.append(interface)

		if mac:
			sql += " and networks.mac=%s"
			values.append(mac)

		self.db.execute(sql, values)
Esempio n. 7
0
	def run(self, params, args):
		switches = self.getSwitchNames(args)
		if not switches:
			raise ArgRequired(self, 'switch')
		elif len(switches) > 1:
			raise ArgUnique(self, 'switch')
		switch = switches[0]

		(host, interface, port) = self.fillParams([
			('host', None),
			('interface', None),
			('port', None)
		])

		hosts = self.getHostnames([host])
		if not hosts:
			raise ParamRequired(self, ('host'))
		elif len(hosts) > 1:
			raise ParamUnique(self, 'host')
		host = hosts[0]

		try:
			port = int(port)
		except:
			raise ParamType(self, 'port', 'integer')

		# Check if the host/port is defined for this switch
		for row in self.call('list.switch.host', [switch]):
			if row['host'] == host and row['port'] == port:
				break
		else:
			raise ArgError(self, 'host/port', f'"{host}/{port}" not found')

		# See if the interface exists for this host
		row = self.db.select("""
			networks.id FROM networks, nodes
			WHERE nodes.name=%s AND networks.device=%s AND networks.node=nodes.id
		""", (host, interface))

		if not row:
			raise CommandError(
				self, f'interface "{interface}" does not exist for host "{host}"'
			)

		self.db.execute("""
			UPDATE switchports SET interface=%s
			WHERE port=%s AND switch=(SELECT id FROM nodes WHERE name=%s)
		""", (row[0][0], port, switch))
Esempio n. 8
0
    def run(self, params, args):
        switches = self.getSwitchNames(args)
        if not switches:
            raise ArgRequired(self, 'switch')
        elif len(switches) > 1:
            raise ArgUnique(self, 'switch')
        switch = switches[0]

        (host, interface, port) = self.fillParams([('host', None),
                                                   ('interface', None),
                                                   ('port', None)])

        hosts = self.getHostnames([host])
        if not hosts:
            raise ParamRequired(self, ('host'))
        elif len(hosts) > 1:
            raise ParamUnique(self, 'host')
        host = hosts[0]

        try:
            port = int(port)
        except:
            raise ParamType(self, 'port', 'integer')

        # Check if the host/interface is defined for this switch
        for row in self.call('list.switch.host', [switch]):
            if row['host'] == host and row['interface'] == interface:
                break
        else:
            raise ArgError(self, 'host/interface',
                           f'"{host}/{interface}" not found')

        # Update the switch port
        self.db.execute(
            """
			UPDATE switchports SET port=%s
			WHERE interface=(
				SELECT networks.id FROM networks, nodes
				WHERE nodes.name=%s AND networks.device=%s
				AND networks.node=nodes.id
			)
			AND switch=(SELECT id FROM nodes WHERE name=%s)
		""", (port, host, interface, switch))
Esempio n. 9
0
	def run(self, params, args):
		scope = None
		oses = []
		appliances = []
		hosts = []

		if len(args) == 0:
			scope = 'global'
		elif len(args) == 1:
			try:
				oses = self.getOSNames(args)
			except:
				oses = []

			try:
				appliances = self.getApplianceNames(args)
			except:
				appliances = []

			try:
				hosts = self.getHostnames(args)
			except:
				hosts = []
		else:
			raise CommandError(self, 'must supply zero or one argument')

		if not scope:
			if args[0] in oses:
				scope = 'os'
			elif args[0] in appliances:
				scope = 'appliance'
			elif args[0] in hosts:
				scope = 'host'

		if not scope:
			raise CommandError(self, 'argument "%s" must be a valid os, appliance name or host name' % args[0])

		if scope == 'global':
			name = 'global'
		else:
			name = args[0]

		adapter, enclosure, slot, hotspare, raidlevel, arrayid, options, force = self.fillParams([
			('adapter', None),
			('enclosure', None),
			('slot', None),
			('hotspare', None),
			('raidlevel', None),
			('arrayid', None, True),
			('options', ''),
			('force', 'n')
			])

		if not hotspare and not slot:
			raise ParamRequired(self, [ 'slot', 'hotspare' ])
		if arrayid != 'global' and not raidlevel:
			raise ParamRequired(self, 'raidlevel')

		if adapter:
			try:
				adapter = int(adapter)
			except:
				raise ParamType(self, 'adapter', 'integer')
			if adapter < 0:
				raise ParamValue(self, 'adapter', '>= 0')
		else:
			adapter = -1

		if enclosure:
			try:
				enclosure = int(enclosure)
			except:
				raise ParamType(self, 'enclosure', 'integer')
			if enclosure < 0:
				raise ParamValue(self, 'enclosure', '>= 0')
		else:
			enclosure = -1

		slots = []
		if slot:
			for s in slot.split(','):
				if s == '*':
					#
					# represent '*' in the database as '-1'
					#
					s = -1
				else:
					try:
						s = int(s)
					except:
						raise ParamType(self, 'slot', 'integer')
					if s < 0:
						raise ParamValue(self, 'slot', '>= 0')
					if s in slots:
						raise ParamError(self, 'slot', ' "%s" is listed twice' % s)
				slots.append(s)

		hotspares = []
		if hotspare:
			for h in hotspare.split(','):
				try:
					h = int(h)
				except:	
					raise ParamType(self, 'hotspare', 'integer')
				if h < 0:
					raise ParamValue(self, 'hostspare', '>= 0')
				if h in hotspares:
					raise ParamError(self, 'hostspare', ' "%s" is listed twice' % h)
				hotspares.append(h)

		if arrayid in [ 'global', '*' ]:
			pass
		else:
			try:
				arrayid = int(arrayid)
			except:
				raise ParamType(self, 'arrayid', 'integer')
			if arrayid < 1:
				raise ParamValue(self, 'arrayid', '>= 0')

		if arrayid == 'global' and len(hotspares) == 0:
			raise ParamError(self, 'arrayid', 'is "global" with no hotspares. Please supply at least one hotspare')

		#
		# look up the id in the appropriate 'scope' table
		#
		tableid = None
		if scope == 'global':
			tableid = -1
		elif scope == 'appliance':
			self.db.execute("""select id from appliances where
				name = '%s' """ % name)
			tableid, = self.db.fetchone()
		elif scope == 'host':
			self.db.execute("""select id from nodes where
				name = '%s' """ % name)
			tableid, = self.db.fetchone()

		#
		# make sure the specification doesn't already exist
		#
		force = self.str2bool(force)
		for slot in slots:
			if not force:
				self.checkIt(name, scope, tableid, adapter, enclosure,
					slot)
		for hotspare in hotspares:
			if not force:
				self.checkIt(name, scope, tableid, adapter, enclosure,
					hotspare)

		if arrayid == 'global':
			arrayid = -1
		elif arrayid == '*':
			arrayid = -2

		#
		# now add the specifications to the database
		#
		for slot in slots:
			self.db.execute("""insert into storage_controller
				(scope, tableid, adapter, enclosure, slot,
				raidlevel, arrayid, options) values ('%s', %s, %s, %s,
				%s, %s, %s, '%s') """ % (scope, tableid, adapter,
				enclosure, slot, raidlevel, arrayid, options))

		for hotspare in hotspares:
			raidlevel = -1
			if arrayid == 'global':
				arrayid = -1

			self.db.execute("""insert into storage_controller
				(scope, tableid, adapter, enclosure, slot,
				raidlevel, arrayid, options) values ('%s', %s, %s, %s,
				%s, %s, %s, '%s') """ % (scope, tableid, adapter,
				enclosure, hotspare, raidlevel, arrayid, options))
Esempio n. 10
0
	def run(self, params, args):
		host = self.getSingleHost(args)

		(interface, mac, network, ip, module, 
		 name, vlan, default, options, channel, unsafe) = self.fillParams([
			('interface', None),
			('mac',       None),
			('network',   None),
			('ip',	      None),
			('module',    None),
			('name',      None),
			('vlan',      None),
			('default',   None),
			('options',   None),
			('channel',   None),
			('unsafe',    False)
		])

		# Make sure empty strings are converted to None
		(interface, mac, network, ip, module, 
		name, vlan, default, options, channel) = map(blank_str_to_None, (
			interface, mac, network, ip, module, 
		 	name, vlan, default, options, channel
		))
		
		# Gotta have an interface or mac
		if not interface and not mac:
			raise ParamRequired(self, ('interface', 'mac'))
		
		# Name can't be a FQDN (IE: have dots)
		if name and '.' in name:
			raise ParamType(self, 'name', 'non-FQDN (base hostname)')

		# Check if the network exists
		subnet_id = None
		if network:
			rows = self.db.select('ID from subnets where name = %s', (network,))
			if len(rows) == 0:
				raise CommandError(self, f'network "{network}" does not exist')
			else:
				subnet_id = rows[0][0]

		# The vlan parameter needs to be an int
		if vlan:
			try:
				vlan = int(vlan)
			except:
				raise ParamType(self, 'vlan', 'integer')
		
		# Stacki can use the usafe parameter to disable the check if the
		# interface already exists.  The spreadsheet loading uses this
		# since before add.host.interface is called all the interfaces
		# are removed.
		
		unsafe = self.str2bool(unsafe)
		if not unsafe:
			for row in self.call('list.host.interface', [ host ]):
				if interface == row['interface']:
					raise CommandError(self, f'interface {interface} exists on {host}')
				if mac and mac == row['mac']:
					raise CommandError(self, f'mac {mac} exists on {host}')

		# Some parameters accept the string 'NULL' to mean put a NULL in the db
		if ip and ip.upper() == 'NULL':
			ip = None
		
		if module and module.upper() == 'NULL':
			module = None
		
		if channel and channel.upper() == 'NULL':
			channel = None
		
		# If name is set to 'NULL' it gets the host name, but confusingly
		# if name is None it gets a NULL in the db. Not sure the history
		# of this unique behavior.
		if name and name.upper() == 'NULL':
			name = host
		
		# If vlan is 0 then it should be NULL in the db
		if vlan == 0:
			vlan = None
		
		# Default is a boolean
		default = self.str2bool(default)

		# If ip is set to "auto" we let the 'set' command handle it
		ip_is_auto = False
		if ip and ip.upper() == "AUTO":
			ip_is_auto = True
			ip = None

			# The auto ip feature requires a network parameter
			if subnet_id is None:
				raise ParamRequired(self, 'network')

		# Unset other default interface if the added one is the default interface
		if default:
			self.db.execute("""
				update networks set main=0
				where node=(select id from nodes where name=%s)
				""", (host,)
				)


		# Insert all our data
		self.db.execute("""
			insert into networks(
				node, mac, ip, name, device, subnet, 
				module, vlanid, options, channel, main
			)
			values (
				(select id from nodes where name=%s),
				%s, %s, %s, %s, %s, %s, %s, %s, %s, %s
			)
		""",(
			host, mac, ip, name, interface, subnet_id,
			module,	vlan, options, channel, default
		))

		# Handle auto ip if needed
		if ip_is_auto:
			self.command('set.host.interface.ip', (
				host,
				f'mac={mac}' if mac else f'interface={interface}',
				'ip=auto'
			))
Esempio n. 11
0
    def run(self, params, args):
        scope = None
        oses = []
        appliances = []
        hosts = []

        if len(args) == 0:
            scope = 'global'
        elif len(args) == 1:
            try:
                oses = self.getOSNames(args)
            except:
                oses = []

            try:
                appliances = self.getApplianceNames(args)
            except:
                appliances = []

            try:
                hosts = self.getHostnames(args)
            except:
                hosts = []
        else:
            raise ArgRequired(self, 'scope')

        if not scope:
            if args[0] in oses:
                scope = 'os'
            elif args[0] in appliances:
                scope = 'appliance'
            elif args[0] in hosts:
                scope = 'host'

        if not scope:
            raise ArgValue(self, 'scope',
                           'valid os, appliance name or host name')

        if scope == 'global':
            name = 'global'
        else:
            name = args[0]

        device, size, fstype, mountpt, options, partid = \
         self.fillParams([
          ('device', None, True),
          ('size', None),
          ('type', None),
          ('mountpoint', None),
          ('options', None),
          ('partid', None),
          ])

        if not device:
            raise ParamRequired(self, 'device')

        # Validate size
        if size:
            try:
                s = int(size)
            except:
                #
                # If mountpoint is 'swap' then allow
                # 'hibernate', 'recommended' as sizes.
                #
                if mountpt == 'swap' and \
                 size not in ['recommended', 'hibernation']:
                    raise ParamType(self, 'size', 'integer')
            if s < 0:
                raise ParamValue(self, 'size', '>= 0')

        # Validate partid
        if partid:
            try:
                p = int(partid)
            except:
                partid = None

            if p < 1:
                raise ParamValue(self, 'partid', '>= 0')

            partid = p

        #
        # look up the id in the appropriate 'scope' table
        #
        tableid = None
        if scope == 'global':
            tableid = -1
        elif scope == 'appliance':
            self.db.execute("""select id from appliances where
				name = '%s' """ % name)
            tableid, = self.db.fetchone()
        elif scope == 'host':
            self.db.execute("""select id from nodes where
				name = '%s' """ % name)
            tableid, = self.db.fetchone()

        #
        # make sure the specification for mountpt doesn't already exist
        #
        if mountpt:
            self.checkIt(device, scope, tableid, mountpt)

        if not options:
            options = ""

        #
        # now add the specifications to the database
        #
        sqlvars = "Scope, TableID, device, Mountpoint, Size, FsType, Options"
        sqldata = "'%s', %s, '%s', '%s', %s, '%s', '%s'" % \
         (scope, tableid, device, mountpt, size, fstype, options)

        if partid:
            sqlvars += ", PartID"
            sqldata += ", %s" % partid

        self.db.execute("""insert into storage_partition
			(%s) values (%s) """ % (sqlvars, sqldata))
Esempio n. 12
0
    def run(self, params, args):
        scope = None
        oses = []
        appliances = []
        hosts = []

        if len(args) == 0:
            scope = 'global'
        elif len(args) == 1:
            try:
                oses = self.getOSNames(args)
            except:
                oses = []

            try:
                appliances = self.getApplianceNames(args)
            except:
                appliances = []

            try:
                hosts = self.getHostnames(args)
            except:
                hosts = []
        else:
            raise ArgRequired(self, 'scope')

        if not scope:
            if args[0] in oses:
                scope = 'os'
            elif args[0] in appliances:
                scope = 'appliance'
            elif args[0] in hosts:
                scope = 'host'

        if not scope:
            raise ArgValue(self, 'scope',
                           'a valid os, appliance name or host name')

        if scope == 'global':
            name = None
        else:
            name = args[0]

        adapter, enclosure, slot = self.fillParams([('adapter', None),
                                                    ('enclosure', None),
                                                    ('slot', None, True)])

        if adapter and adapter != '*':
            try:
                adapter = int(adapter)
            except:
                raise ParamType(self, 'adapter', 'integer')
            if adapter < 0:
                raise ParamValue(self, 'adapter', '>= 0')
        else:
            adapter = -1

        if enclosure and enclosure != '*':
            try:
                enclosure = int(enclosure)
            except:
                raise ParamType(self, 'enclosure', 'integer')
            if enclosure < 0:
                raise ParamValue(self, 'enclosure', '>= 0')
        else:
            enclosure = -1

        slots = []
        if slot and slot != '*':
            for s in slot.split(','):
                try:
                    s = int(s)
                except:
                    raise ParamType(self, 'slot', 'integer')
                if s < 0:
                    raise ParamValue(self, 'slot', '>= 0')
                if s in slots:
                    raise ParamError(self, 'slot', '"%s" is listed twice' % s)
                slots.append(s)

        #
        # look up the id in the appropriate 'scope' table
        #
        tableid = None
        if scope == 'global':
            tableid = -1
        elif scope == 'appliance':
            self.db.execute("""select id from appliances where
				name = '%s' """ % name)
            tableid, = self.db.fetchone()
        elif scope == 'host':
            self.db.execute("""select id from nodes where
				name = '%s' """ % name)
            tableid, = self.db.fetchone()

        deletesql = """delete from storage_controller where
			scope = '%s' and tableid = %s """ % (scope, tableid)

        if adapter != -1:
            deletesql += ' and adapter = %s' % adapter

        if enclosure != -1:
            deletesql += ' and enclosure = %s' % enclosure

        if slot != '*':
            for slot in slots:
                dsql = '%s and slot = %s' % (deletesql, slot)
                self.db.execute(dsql)
        else:
            self.db.execute(deletesql)
Esempio n. 13
0
    def run(self, params, args):

        hosts = self.getHostnames(args)
        (interface, mac, network, ip, module, name, vlan, default, options,
         unsafe) = self.fillParams([('interface', None), ('mac', None),
                                    ('network', None), ('ip', None),
                                    ('module', None), ('name', None),
                                    ('vlan', None), ('default', None),
                                    ('options', None), ('unsafe', False)])

        if not interface and not mac:
            raise ParamRequired(self, ('interface', 'mac'))
        if name and len(name.split('.')) > 1:
            raise ParamType(self, 'name', 'non-FQDN (base hostname)')
        if len(hosts) != 1:
            raise ArgUnique(self, 'host')

        host = hosts[0]

        # Stacki can use the usafe parameter to disable the check if the
        # interface already exists.  The spreadsheet loading uses this
        # since before add.host.interface is called all the interfaces
        # are removed.

        unsafe = self.str2bool(unsafe)
        if not unsafe:
            for dict in self.call('list.host.interface', [host]):
                if interface == dict['interface']:
                    raise CommandError(self, 'interface exists')
                if mac and mac == dict['mac']:
                    raise CommandError(self, 'mac exists')

        fields = [
            'network', 'ip', 'module', 'name', 'vlan', 'default', 'options'
        ]

        # Insert the mac or interface into the database and then use
        # that to key off of for all the subsequent fields.
        # Give the MAC preferrence (need to pick one) but still do the
        # right thing when MAC and Interface are both specified.
        #
        # The MAC handle includes some optimization to include more
        # information on the initial insert, in order to reduce the
        # updates for each extra field.

        if mac:
            handle = 'mac=%s' % mac
            fields.append('interface')

            keys = ['node', 'mac']
            vals = [
                '(select id from nodes where name="%s")' % host,
                '"%s"' % mac
            ]

            if interface:
                fields.remove('interface')
                keys.append('device')
                vals.append('"%s"' % interface)
            if network:
                fields.remove('network')
                keys.append('subnet')
                vals.append('(select id from subnets s where s.name="%s")' %
                            network)
            if ip:
                fields.remove('ip')
                keys.append('ip')
                vals.append('NULLIF("%s","NULL")' % ip.upper())
            if name:
                if name.upper() == "NULL":
                    name = host
                fields.remove('name')
                keys.append('name')
                vals.append('"%s"' % name)
            if default:
                fields.remove('default')
                keys.append('main')
                vals.append('%d' % self.str2bool(default))
            if options:
                fields.remove('options')
                keys.append('options')
                vals.append('"%s"' % options)

            self.db.execute("""
				insert into networks(%s) values (%s)
				""" % (','.join(keys), ','.join(vals)))

        else:
            handle = 'interface=%s' % interface
            fields.append('mac')

            self.db.execute("""
				insert into networks(node, device)
				values ((select id from nodes where name='%s'), '%s')
				""" % (host, interface))

        for key in fields:
            if key in params:
                self.command('set.host.interface.%s' % key,
                             (host, handle, "%s=%s" % (key, params[key])))
Esempio n. 14
0
	def run(self, params, args):
		# Get the scope and make sure the args are valid
		scope, = self.fillParams([('scope', 'global')])
		scope_mappings = self.getScopeMappings(args, scope)

		# Now validate the params
		adapter, enclosure, slot, hotspare, raidlevel, arrayid, options = self.fillParams([
			('adapter', None),
			('enclosure', None),
			('slot', None),
			('hotspare', None),
			('raidlevel', None),
			('arrayid', None, True),
			('options', '')
		])

		# Gotta have either a hotspare list or a slot list
		if not hotspare and not slot:
			raise ParamRequired(self, ['slot', 'hotspare'])

		# Non-global arrays need a raid level
		if arrayid != 'global' and not raidlevel:
			raise ParamRequired(self, 'raidlevel')

		# Make sure the adapter is an integer greater than 0, if it exists
		if adapter:
			try:
				adapter = int(adapter)
			except:
				raise ParamType(self, 'adapter', 'integer')

			if adapter < 0:
				raise ParamValue(self, 'adapter', '>= 0')
		else:
			adapter = -1

		# Make sure the enclosure is an integer greater than 0, if it exists
		if enclosure:
			try:
				enclosure = int(enclosure)
			except:
				raise ParamType(self, 'enclosure', 'integer')

			if enclosure < 0:
				raise ParamValue(self, 'enclosure', '>= 0')
		else:
			enclosure = -1

		# Parse the slots
		slots = []
		if slot:
			for s in slot.split(','):
				# Make sure the slot is valid
				if s == '*':
					# Represent '*' in the database as '-1'
					s = -1
				else:
					try:
						s = int(s)
					except:
						raise ParamType(self, 'slot', 'integer')

					if s < 0:
						raise ParamValue(self, 'slot', '>= 0')

					if s in slots:
						raise ParamError(
							self, 'slot', f'"{s}" is listed twice'
						)

				# Needs to be unique in the scope
				for scope_mapping in scope_mappings:
					# Check that the route is unique for the scope
					if self.db.count("""
						(storage_controller.id)
						FROM storage_controller,scope_map
						WHERE storage_controller.scope_map_id = scope_map.id
						AND storage_controller.adapter = %s
						AND storage_controller.enclosure = %s
						AND storage_controller.slot = %s
						AND scope_map.scope = %s
						AND scope_map.appliance_id <=> %s
						AND scope_map.os_id <=> %s
						AND scope_map.environment_id <=> %s
						AND scope_map.node_id <=> %s
					""", (adapter, enclosure, s, *scope_mapping)) != 0:
		 				raise CommandError(
							self,
							f'disk specification for "{adapter}/'
							f'{enclosure}/{s}" already exists'
						)

				# Looks good
				slots.append(s)

		# Parse the hotspares
		hotspares = []
		if hotspare:
			for h in hotspare.split(','):
				# Make sure the hotspare is valid
				try:
					h = int(h)
				except:
					raise ParamType(self, 'hotspare', 'integer')

				if h < 0:
					raise ParamValue(self, 'hotspare', '>= 0')

				if h in hotspares:
					raise ParamError(
						self, 'hotspare', f'"{h}" is listed twice'
					)

				if h in slots:
					raise ParamError(
						self, 'hotspare', f'"{h}" is listed in slots'
					)

				# Needs to be unique in the scope
				for scope_mapping in scope_mappings:
					# Check that the route is unique for the scope
					if self.db.count("""
						(storage_controller.id)
						FROM storage_controller,scope_map
						WHERE storage_controller.scope_map_id = scope_map.id
						AND storage_controller.adapter = %s
						AND storage_controller.enclosure = %s
						AND storage_controller.slot = %s
						AND scope_map.scope = %s
						AND scope_map.appliance_id <=> %s
						AND scope_map.os_id <=> %s
						AND scope_map.environment_id <=> %s
						AND scope_map.node_id <=> %s
					""", (adapter, enclosure, h, *scope_mapping)) != 0:
		 				raise CommandError(
							self,
							f'disk specification for "{adapter}/'
							f'{enclosure}/{h}" already exists'
						)

				# Looks good
				hotspares.append(h)

		# Check the arrayid
		if arrayid not in {'global', '*'}:
			try:
				arrayid = int(arrayid)
			except:
				raise ParamType(self, 'arrayid', 'integer')

			if arrayid < 1:
				raise ParamValue(self, 'arrayid', '>= 1')

		if arrayid == 'global' and len(hotspares) == 0:
			raise ParamError(self, 'arrayid', 'is "global" with no hotspares')

		# Special encodings for arrayid
		if arrayid == 'global':
			arrayid = -1
		elif arrayid == '*':
			arrayid = -2

		# Everything is valid, add the data for each scope_mapping
		for scope_mapping in scope_mappings:
			# Add the slots
			for slot in slots:
				# First add the scope mapping
				self.db.execute("""
					INSERT INTO scope_map(
						scope, appliance_id, os_id, environment_id, node_id
					)
					VALUES (%s, %s, %s, %s, %s)
				""", scope_mapping)

				# Then add the slot controller entry
				self.db.execute("""
					INSERT INTO storage_controller(
						scope_map_id, adapter, enclosure, slot,
						raidlevel, arrayid, options
					)
					VALUES (LAST_INSERT_ID(), %s, %s, %s, %s, %s, %s)
				""", (adapter, enclosure, slot, raidlevel, arrayid, options))

			# And add the hotspares
			for hotspare in hotspares:
				# First add the scope mapping
				self.db.execute("""
					INSERT INTO scope_map(
						scope, appliance_id, os_id, environment_id, node_id
					)
					VALUES (%s, %s, %s, %s, %s)
				""", scope_mapping)

				# Then add the hotspare controller entry
				self.db.execute("""
					INSERT INTO storage_controller(
						scope_map_id, adapter, enclosure, slot,
						raidlevel, arrayid, options
					)
					VALUES (LAST_INSERT_ID(), %s, %s, %s, '-1', %s, %s)
				""", (adapter, enclosure, hotspare, arrayid, options))
Esempio n. 15
0
    def run(self, params, args):
        scope = None
        oses = []
        appliances = []
        hosts = []

        if len(args) == 0:
            scope = 'global'
        elif len(args) == 1:
            try:
                oses = self.getOSNames(args)
            except:
                oses = []

            try:
                appliances = self.getApplianceNames(args)
            except:
                appliances = []

            try:
                hosts = self.getHostnames(args)
            except:
                hosts = []
        else:
            raise ArgRequired(self, 'scope')

        if not scope:
            if args[0] in oses:
                scope = 'os'
            elif args[0] in appliances:
                scope = 'appliance'
            elif args[0] in hosts:
                scope = 'host'

        if not scope:
            raise ArgValue(self, 'scope',
                           'valid os, appliance name or host name')

        if scope == 'global':
            name = 'global'
        else:
            name = args[0]

        device, size, fstype, mountpt, options, partid = self.fillParams([
            ('device', None, True),
            ('size', None, True),
            ('type', None),
            ('mountpoint', None),
            ('options', None),
            ('partid', None),
        ])

        if not device:
            raise ParamRequired(self, 'device')

        if not size:
            raise ParamRequired(self, 'size')

        # Validate size
        try:
            s = int(size)
            if s < 0:
                raise ParamValue(self, 'size', '>= 0')
        except:
            # If mountpoint is 'swap' then allow
            # 'hibernate', 'recommended' as sizes
            if mountpt == 'swap' and size not in [
                    'recommended', 'hibernation'
            ]:
                raise ParamType(self, 'size', 'integer')
            else:
                raise ParamType(self, 'size', 'integer')

        # Validate partid
        if partid:
            try:
                p = int(partid)
            except ValueError:
                raise ParamValue(self, 'partid', 'an integer')

            if p < 1:
                raise ParamValue(self, 'partid', '>= 0')

            partid = p
        else:
            partid = 0

        # Look up the id in the appropriate 'scope' table
        if scope == 'appliance':
            tableid = self.db.select('id from appliances where name=%s',
                                     [name])[0][0]
        elif scope == 'os':
            tableid = self.db.select('id from oses where name=%s',
                                     [name])[0][0]
        elif scope == 'host':
            tableid = self.db.select('id from nodes where name=%s',
                                     [name])[0][0]
        else:
            tableid = -1

        # Make sure the specification for mountpt doesn't already exist
        if mountpt:
            self.checkIt(device, scope, tableid, mountpt)
        else:
            # Preserve the existing behavior (sad panda)
            mountpt = 'None'

        # Preserve the existing behavior (sad panda)
        if not fstype:
            fstype = 'None'

        if not options:
            options = ""

        # Now add the specifications to the database
        self.db.execute(
            """
			INSERT INTO storage_partition(
				Scope, TableID, device, Mountpoint,
				Size, FsType, Options, PartID
			)
			VALUES(%s, %s, %s, %s, %s, %s, %s, %s)
		""", (scope, tableid, device, mountpt, size, fstype, options, partid))
Esempio n. 16
0
    def run(self, params, args):
        # Get the scope and make sure the args are valid
        scope, = self.fillParams([('scope', 'global')])
        scope_mappings = self.getScopeMappings(args, scope)

        # Now validate the params
        device, size, fstype, mountpoint, options, partid = self.fillParams([
            ('device', None, True),
            ('size', None, True),
            ('type', None),
            ('mountpoint', None),
            ('options', None),
            ('partid', None),
        ])

        if not device:
            raise ParamRequired(self, 'device')

        if not size:
            raise ParamRequired(self, 'size')

        # Validate size
        if mountpoint == 'swap' and size in ['recommended', 'hibernation']:
            if size == 'recommended':
                size = -1
            else:
                size = -2
        else:
            try:
                size = int(size)
            except:
                raise ParamType(self, 'size', 'integer')

            if size < 0:
                raise ParamValue(self, 'size', '>= 0')

        # Validate partid
        if partid:
            try:
                partid = int(partid)
            except ValueError:
                raise ParamType(self, 'partid', 'integer')

            if partid < 1:
                raise ParamValue(self, 'partid', '>= 0')
        else:
            partid = 0

        # Make sure the specification for mountpoint doesn't already exist
        if mountpoint:
            # Needs to be unique in the scope
            for scope_mapping in scope_mappings:
                # Check that the route is unique for the scope
                if self.db.count(
                        """
					(storage_partition.id)
					FROM storage_partition,scope_map
					WHERE storage_partition.scope_map_id = scope_map.id
					AND storage_partition.device = %s
					AND storage_partition.mountpoint = %s
					AND scope_map.scope = %s
					AND scope_map.appliance_id <=> %s
					AND scope_map.os_id <=> %s
					AND scope_map.environment_id <=> %s
					AND scope_map.node_id <=> %s
				""", (device, mountpoint, *scope_mapping)) != 0:
                    raise CommandError(
                        self, f'partition specification for device "{device}" '
                        f'and mount point "{mountpoint}" already exists')
        else:
            mountpoint = None

        if not fstype:
            fstype = None

        if not options:
            options = ""

        # Everything is valid, add the data for each scope_mapping
        for scope_mapping in scope_mappings:
            # First add the scope mapping
            self.db.execute(
                """
				INSERT INTO scope_map(
					scope, appliance_id, os_id, environment_id, node_id
				)
				VALUES (%s, %s, %s, %s, %s)
			""", scope_mapping)

            # Then add the storage partition entry
            self.db.execute(
                """
				INSERT INTO storage_partition(
					scope_map_id, device, mountpoint,
					size, fstype, options, partid
				)
				VALUES (LAST_INSERT_ID(), %s, %s, %s, %s, %s, %s)
			""", (device, mountpoint, size, fstype, options, partid))
Esempio n. 17
0
    def run(self, params, args):

        # Parse Params
        (cmd, managed, x11, t, d, collate, n, method) = self.fillParams([
            ('command', None, True),  # Command
            ('managed', 'y'),  # Run on Managed Hosts only
            ('x11', 'n'),  # Run without X11
            ('timeout', '0'),  # Set timeout for commands
            ('delay', '0'),  # Set delay between each thread
            ('collate', 'y'),  # Collate output
            ('threads', self.getAttr('run.host.threads')),
            ('method', self.getAttr('run.host.impl'))
        ])
        #  Check that a command was even input:
        if cmd == '':
            raise ParamValue(self, 'cmd', 'string with contents')
        # Get list of hosts to run the command on
        self.hosts = self.getHostnames(args, self.str2bool(managed))
        self.run_hosts = self.getRunHosts(self.hosts)

        # Get timeout for commands
        try:
            self.timeout = int(t)
        except:
            raise ParamType(self, 'timeout', 'integer')
        if self.timeout < 0:
            raise ParamValue(self, 'timeout', '> 0')

        # Get Number of threads to run concurrently
        if n is None:
            self.numthreads = 0
        else:
            try:
                self.numthreads = int(n)
            except:
                raise ParamType(self, 'threads', 'integer')
            if self.numthreads < 0:
                raise ParamValue(self, 'threads', '> 0')

        # Get time to pause between subsequent threads
        try:
            self.delay = float(d)
        except:
            raise ParamType(self, 'delay', 'float')

        # Check if we want to unset the Display
        if not self.str2bool(x11):
            try:
                del os.environ['DISPLAY']
            except KeyError:
                pass

        # Get the command
        self.cmd = cmd

        # Get the implementation to run. By default, run SSH
        if method is None:
            method = 'ssh'

        # Check if we should collate the output
        self.collate = self.str2bool(collate)

        if self.collate:
            self.beginOutput()

        self.runImplementation(method, [self.hosts, cmd])

        if self.collate:
            self.endOutput(header=['host', 'output'], trimOwner=False)
Esempio n. 18
0
    def run(self, params, args):
        # Get the scope and make sure the args are valid
        scope, = self.fillParams([('scope', 'global')])
        scope_mappings = self.getScopeMappings(args, scope)

        # Now validate the params
        adapter, enclosure, slot = self.fillParams([('adapter', None),
                                                    ('enclosure', None),
                                                    ('slot', None, True)])

        # Make sure the adapter is an integer greater than 0, if it exists
        if adapter and adapter != '*':
            try:
                adapter = int(adapter)
            except:
                raise ParamType(self, 'adapter', 'integer')

            if adapter < 0:
                raise ParamValue(self, 'adapter', '>= 0')
        else:
            adapter = None

        # Make sure the enclosure is an integer greater than 0, if it exists
        if enclosure and enclosure != '*':
            try:
                enclosure = int(enclosure)
            except:
                raise ParamType(self, 'enclosure', 'integer')

            if enclosure < 0:
                raise ParamValue(self, 'enclosure', '>= 0')
        else:
            enclosure = None

        # Parse the slots
        slots = []
        if slot:
            for s in slot.split(','):
                # Make sure the slot is valid
                if s == '*':
                    # We're removing them all
                    s = None
                else:
                    try:
                        s = int(s)
                    except:
                        raise ParamType(self, 'slot', 'integer')

                    if s < 0:
                        raise ParamValue(self, 'slot', '>= 0')

                    if s in slots:
                        raise ParamError(self, 'slot',
                                         f'"{s}" is listed twice')

                # Looks good
                slots.append(s)

        scope_ids = []
        for scope_mapping in scope_mappings:
            for slot in slots:
                # Check that the controller configuration exists for the scope
                query = """
					scope_map.id FROM storage_controller,scope_map
					WHERE storage_controller.scope_map_id = scope_map.id
					AND scope_map.scope = %s
					AND scope_map.appliance_id <=> %s
					AND scope_map.os_id <=> %s
					AND scope_map.environment_id <=> %s
					AND scope_map.node_id <=> %s
				"""
                values = list(scope_mapping)

                # 0 might be valid so need to check for None
                if adapter is not None:
                    query += " AND storage_controller.adapter = %s"
                    values.append(adapter)

                if enclosure is not None:
                    query += " AND storage_controller.enclosure = %s"
                    values.append(enclosure)

                if slot is not None:
                    query += " AND storage_controller.slot = %s"
                    values.append(slot)

                rows = self.db.select(query, values)
                if not rows:
                    if adapter is None:
                        adapter = '*'
                    if enclosure is None:
                        enclosure = '*'
                    if slot is None:
                        slot = '*'

                    raise CommandError(
                        self, f'disk specification for "{adapter}/'
                        f'{enclosure}/{slot}" doesn\'t exist')

                scope_ids.extend(flatten(rows))

        # Controller disk specifications existed for all the scope mappings,
        # so delete them.
        # Note: We just delete the scope mapping, the ON DELETE CASCADE takes
        # care of removing the storage_controller table entries for us.
        self.db.execute('delete from scope_map where id in %s', (scope_ids, ))