Пример #1
0
def system_actions(id):
	if not does_user_have_system_permission(id,"view.detail","systems.all.view"):
		abort(403)

	# Get the system
	system = cortex.lib.systems.get_system_by_id(id)

	# Ensure that the system actually exists, and return a 404 if it doesn't
	if system is None:
		abort(404)

	# Get the list of actions we can perform
	actions = []
	for action in app.wf_system_functions:
		if action['menu']:
			## Add to menu ONLY if:
			### they have workflows.all
			### they have the per-system permission set in the workflow action
			### they have the global permission set in the workflow action

			if does_user_have_permission("workflows.all"):
				actions.append(action)
			elif does_user_have_system_permission(id,action['system_permission']):
				app.logger.debug("User " + session['username'] + " does not have workflows.all")
				actions.append(action)
			elif action['permission'] is not None:
				app.logger.debug("User " + session['username'] + " does not have " + action['system_permission'])

				if does_user_have_permission("workflows." + action['permission']):
					actions.append(action)
				else:
					app.logger.debug("User " + session['username'] + " does not have " + action['permission'])

	return render_template('systems/actions.html', system=system, active='systems', actions=actions, title=system['name'])
Пример #2
0
def system_actions(id):
	if not does_user_have_system_permission(id,"view","systems.all.view"):
		abort(403)

	# Get the system
	system = cortex.lib.systems.get_system_by_id(id)

	# Ensure that the system actually exists, and return a 404 if it doesn't
	if system is None:
		abort(404)

	# Get the list of actions we can perform
	actions = []
	for action in app.wf_system_functions:
		if action['menu']:
			## Add to menu ONLY if:
			### they have workflows.all
			### they have the per-system permission set in the workflow action
			### they have the global permission set in the workflow action

			if does_user_have_permission("workflows.all"):
				actions.append(action)
			elif does_user_have_system_permission(id,action['system_permission']):
				app.logger.debug("User " + session['username'] + " does not have workflows.all")
				actions.append(action)								
			elif action['permission'] is not None:
				app.logger.debug("User " + session['username'] + " does not have " + action['system_permission'])

				if does_user_have_permission("workflows." + action['permission']):
					actions.append(action)
				else:
					app.logger.debug("User " + session['username'] + " does not have " + action['permission'])

	return render_template('systems/actions.html', system=system, active='systems', actions=actions, title=system['name'])
Пример #3
0
def puppet_facts(node):
    """Handle the Puppet node facts page"""

    # Get the system (we need to know the ID for permissions checking)
    system = cortex.lib.systems.get_system_by_puppet_certname(node)
    if system is None:
        abort(404)

        ## Check if the user is allowed to view the facts about this node
    if not does_user_have_system_permission(system["id"], "view.puppet", "systems.all.view.puppet"):
        abort(403)

    dbnode = None
    facts = None
    try:
        # Connect to PuppetDB, get the node information and then it's related facts
        db = cortex.lib.puppet.puppetdb_connect()
        dbnode = db.node(node)
        facts = dbnode.facts()
    except HTTPError, he:
        # If we get a 404 from the PuppetDB API
        if he.response.status_code == 404:
            # We will continue to render the page, just with no facts and display a nice error
            facts = None
        else:
            raise (he)
Пример #4
0
def puppet_facts(node):
	"""Handle the Puppet node facts page"""

	# Get the system (we need to know the ID for permissions checking)
	system = cortex.lib.systems.get_system_by_puppet_certname(node)
	if system is None:
		abort(404)

	## Check if the user is allowed to view the facts about this node
	if not does_user_have_system_permission(system['id'],"view.puppet","systems.all.view.puppet"):
		abort(403)

	dbnode = None
	facts = None
	try:
		# Connect to PuppetDB, get the node information and then it's related facts
		db     = cortex.lib.puppet.puppetdb_connect()
		dbnode = db.node(node)
		facts  = dbnode.facts()
	except HTTPError, he:
		# If we get a 404 from the PuppetDB API
		if he.response.status_code == 404:
			# We will continue to render the page, just with no facts and display a nice error
			facts = None
		else:
			raise(he)
Пример #5
0
def system(id):
	# Check user permissions. User must have either systems.all or specific 
	# access to the system
	if not does_user_have_system_permission(id,"view","systems.all.view"):
		abort(403)

	# Get the system
	system = cortex.lib.systems.get_system_by_id(id)

	# Ensure that the system actually exists, and return a 404 if it doesn't
	if system is None:
		abort(404)

	system_class = cortex.lib.classes.get(system['class'])
	system['review_status_text'] = cortex.lib.systems.REVIEW_STATUS_BY_ID[system['review_status']]
		
	if system['puppet_certname']:
		system['puppet_node_status'] = cortex.lib.puppet.puppetdb_get_node_status(system['puppet_certname'])
		
	if system['allocation_who_realname'] is not None:	
		system['allocation_who'] = system['allocation_who_realname'] + ' (' + system['allocation_who'] + ')'
	else:
		system['allocation_who'] = cortex.lib.user.get_user_realname(system['allocation_who']) + ' (' + system['allocation_who'] + ')'

	return render_template('systems/view.html', system=system, system_class=system_class, active='systems', title=system['name'])
Пример #6
0
def system(id):
	# Check user permissions. User must have either systems.all or specific 
	# access to the system
	if not does_user_have_system_permission(id,"view.detail","systems.all.view"):
		abort(403)

	# Get the system
	system = cortex.lib.systems.get_system_by_id(id)

	# Ensure that the system actually exists, and return a 404 if it doesn't
	if system is None:
		abort(404)

	system_class = cortex.lib.classes.get(system['class'])
	system['review_status_text'] = cortex.lib.systems.REVIEW_STATUS_BY_ID[system['review_status']]

	if system['puppet_certname']:
		system['puppet_node_status'] = cortex.lib.puppet.puppetdb_get_node_status(system['puppet_certname'])

	if system['allocation_who_realname'] is not None:
		system['allocation_who'] = system['allocation_who_realname'] + ' (' + system['allocation_who'] + ')'
	else:
		system['allocation_who'] = cortex.lib.user.get_user_realname(system['allocation_who']) + ' (' + system['allocation_who'] + ')'

	return render_template('systems/view.html', system=system, system_class=system_class, active='systems', title=system['name'])
Пример #7
0
def system(id):
	# Check user permissions. User must have either systems.all or specific 
	# access to the system
	if not does_user_have_system_permission(id,"view.detail","systems.all.view"):
		abort(403)

	# Get the system
	system = cortex.lib.systems.get_system_by_id(id)

	# Ensure that the system actually exists, and return a 404 if it doesn't
	if system is None:
		abort(404)

	system_class = cortex.lib.classes.get(system['class'])
	system['review_status_text'] = cortex.lib.systems.REVIEW_STATUS_BY_ID[system['review_status']]

	if system['puppet_certname']:
		system['puppet_node_status'] = cortex.lib.puppet.puppetdb_get_node_status(system['puppet_certname'])

	# Generate a 'pretty' display name. This is the format '<realname> (<username>)'
	system['allocation_who'] = cortex.lib.systems.generate_pretty_display_name(system['allocation_who'], system['allocation_who_realname'])
	system['primary_owner_who'] = cortex.lib.systems.generate_pretty_display_name(system['primary_owner_who'], system['primary_owner_who_realname'])
	system['secondary_owner_who'] = cortex.lib.systems.generate_pretty_display_name(system['secondary_owner_who'], system['secondary_owner_who_realname'])

	return render_template('systems/view.html', system=system, system_class=system_class, active='systems', title=system['name'])
Пример #8
0
def system_power(id):
	# Check user permissions. User must have either systems.all or specific
	# access to the system
	if not does_user_have_system_permission(id,"control.vmware.power", "control.all.vmware.power"):
		abort(403)

	# Get the system
	system = cortex.lib.systems.get_system_by_id(id)

	# Ensure that the system actually exists, and return a 404 if it doesn't
	if system is None:
		abort(404)

	try:
		if request.form.get('power_action', None) == "on":
				cortex.lib.systems.power_on(id)
		elif request.form.get('power_action', None) == "shutdown":
				cortex.lib.systems.shutdown(id)
		elif request.form.get('power_action', None) == "off":
				cortex.lib.systems.power_off(id)
		elif request.form.get('power_action', None) == "reset":
				cortex.lib.systems.reset(id)
		#is it an XHR?
		if request.headers.get('X-Requested-With', None) == "XMLHttpRequest":
			return system_status(id)
		else:
			return redirect(url_for('system_overview', id=id))
	except vim.fault.VimFault as e:
		abort(500)
Пример #9
0
			def decorated_function(*args, **kwargs):
				system_id = kwargs['target_id']

				## Grant permission ONLY if
				### they have workflows.all
				### they have the per-system permission set in the workflow action
				### they have the global permission set in the workflow action

				if permission is None:
					if not does_user_have_system_permission(system_id, system_permission) and not does_user_have_permission("workflows.all"):
						abort(403)

				else:
					if not does_user_have_system_permission(system_id, system_permission) and not does_user_have_permission("workflows." + permission) and not does_user_have_permission("workflows.all"):
						abort(403)

				return func(*args, **kwargs)
Пример #10
0
			def decorated_function(*args, **kwargs):
				id = kwargs['id']

				## Grant permission ONLY if
				### they have workflows.all
				### they have the per-system permission set in the workflow action
				### they have the global permission set in the workflow action

				if permission is None:
					if not does_user_have_system_permission(id,system_permission) and not does_user_have_permission("workflows.all"):
						abort(403)

				else:
					if not does_user_have_system_permission(id,system_permission) and not does_user_have_permission("workflows." + permission) and not does_user_have_permission("workflows.all"):
						abort(403)

				return fn(*args, **kwargs)
Пример #11
0
def puppet_enc_edit(node):
	"""Handles the manage Puppet node page"""

	# Get the system out of the database
	system       = cortex.lib.systems.get_system_by_puppet_certname(node)
	environments = cortex.lib.core.get_puppet_environments()
	env_dict     = cortex.lib.core.get_environments_as_dict()

	if system == None:
		abort(404)

	## Check if the user is allowed to edit the Puppet configuration
	if not does_user_have_system_permission(system['id'],"edit.puppet","systems.all.edit.puppet"):
		abort(403)

	# On any GET request, just display the information
	if request.method == 'GET':

		return render_template('puppet/enc.html', system=system, active='puppet', environments=environments, title=system['name'], nodename=node, pactive="edit", yaml=cortex.lib.puppet.generate_node_config(system['puppet_certname']))

	# On any POST request, validate the input and then save
	elif request.method == 'POST':
		# Extract data from form
		environment = request.form.get('environment', '')
		classes = request.form.get('classes', '')
		variables = request.form.get('variables', '')
		if 'include_default' in request.form:
			include_default = True
		else:
			include_default = False
		error = False

		# Validate environement:
		if environment not in [e['id'] for e in environments]:
			flash('Invalid environment', 'alert-danger')
			error = True

		# Validate classes YAML
		try:
			data = yaml.load(classes)
		except Exception, e:
			flash('Invalid YAML syntax for classes: ' + str(e), 'alert-danger')
			error = True

		try:
			if not data is None:
				assert isinstance(data, dict)
		except Exception, e:
			flash('Invalid YAML syntax for classes: result was not a list of classes, did you forget a trailing colon? ' + str(e), 'alert-danger')
			error = True
Пример #12
0
    def get(self, system_id):
        """
		Returns a single system from systems_info_view.
		"""
        if not does_user_have_system_permission(system_id, "view.detail",
                                                "systems.all.view"):
            raise InvalidPermissionException

        system = cortex.lib.systems.get_system_by_id(system_id)

        if not system:
            raise NoResultsFoundException

        return system
Пример #13
0
	def get(self, system_name):
		"""
		Returns a single system from systems_info_view, searching by name.
		"""

		system = cortex.lib.systems.get_system_by_name(system_name)

		if not system:
			raise NoResultsFoundException

		if not does_user_have_system_permission(system['id'], "view.detail", "systems.all.view"):
			raise InvalidPermissionException

		return system
Пример #14
0
def puppet_facts(node):
    """Handle the Puppet node facts page"""

    # Get the system (we need to know the ID for permissions checking)
    system = cortex.lib.systems.get_system_by_puppet_certname(node)
    if system is None:
        abort(404)

    ## Check if the user is allowed to view the facts about this node
    if not does_user_have_system_permission(system['id'], "view.puppet",
                                            "systems.all.view.puppet"):
        abort(403)

    dbnode = None
    facts = None
    try:
        # Connect to PuppetDB, get the node information and then it's related facts
        db = cortex.lib.puppet.puppetdb_connect()
        dbnode = db.node(node)
        facts = dbnode.facts()
    except HTTPError as he:
        # If we get a 404 from the PuppetDB API
        if he.response.status_code == 404:
            # We will continue to render the page, just with no facts and display a nice error
            facts = None
        else:
            raise (he)
    except Exception as e:
        return stderr(
            "Unable to connect to PuppetDB",
            "Unable to connect to the Puppet database. The error was: " +
            type(e).__name__ + " - " + str(e))

    # Turn the facts generator in to a dictionary
    facts_dict = {}

    if facts != None:
        for fact in facts:
            facts_dict[fact.name] = fact.value

    # Render
    return render_template('puppet/facts.html',
                           facts=facts_dict,
                           node=dbnode,
                           active='puppet',
                           title=node + " - Puppet Facts",
                           nodename=node,
                           pactive="facts",
                           system=system)
Пример #15
0
def puppet_catalog(node):
    """Show the Puppet catalog for a given node."""

    # Get the system
    system = cortex.lib.systems.get_system_by_puppet_certname(node)

    if system == None:
        abort(404)

    ## Check if the user is allowed to edit the Puppet configuration
    if not does_user_have_system_permission(system['id'],
                                            "view.puppet.catalog",
                                            "systems.all.view.puppet.catalog"):
        abort(403)

    dbnode = None
    catalog = None
    try:
        # Connect to PuppetDB, get the node information and then it's catalog.
        db = cortex.lib.puppet.puppetdb_connect()
        dbnode = db.node(node)
        catalog = db.catalog(node)
    except HTTPError as he:
        # If we get a 404 from the PuppetDB API
        if he.response.status_code == 404:
            catalog = None
        else:
            raise (he)
    except Exception as e:
        return stderr(
            "Unable to connect to PuppetDB",
            "Unable to connect to the Puppet database. The error was: " +
            type(e).__name__ + " - " + str(e))

    catalog_dict = {}

    if catalog != None:
        for res in catalog.get_resources():
            catalog_dict[str(res)] = res.parameters

    # Render
    return render_template('puppet/catalog.html',
                           catalog=catalog_dict,
                           node=dbnode,
                           active='puppet',
                           title=node + " - Puppet Catalog",
                           nodename=node,
                           pactive="catalog",
                           system=system)
Пример #16
0
def puppet_report(report_hash):
    """Displays an individual report for a Puppet node"""

    # Connect to Puppet DB and query for a report with the given hash
    try:
        db = cortex.lib.puppet.puppetdb_connect()
    except Exception as e:
        return stderr(
            "Unable to connect to PuppetDB",
            "Unable to connect to the Puppet database. The error was: " +
            type(e).__name__ + " - " + str(e))

    reports = db.reports(query='["=", "hash", "' + report_hash + '"]')

    # 'reports' is a generator. Get the next (first and indeed, only item) from the generator
    try:
        report = next(reports)
    except StopIteration as e:
        # If we get a StopIteration error, then we've not got any data
        # returned from the reports generator, so the report didn't
        # exist, hence we should 404
        return abort(404)

    # Get the system (we need the ID for perms check, amongst other things)
    system = cortex.lib.systems.get_system_by_puppet_certname(report.node)
    if system is None:
        return abort(404)

    ## Check if the user is allowed to view the report
    if not does_user_have_system_permission(system['id'], "view.puppet",
                                            "systems.all.view.puppet"):
        abort(403)

    # Build metrics into a more useful dictionary
    metrics = {}
    for metric in report.metrics:
        if metric['category'] not in metrics:
            metrics[metric['category']] = {}

        metrics[metric['category']][metric['name']] = metric['value']

    # Render
    return render_template('puppet/report.html',
                           report=report,
                           metrics=metrics,
                           system=system,
                           active='puppet',
                           title=report.node + " - Puppet Report")
Пример #17
0
def system_overview(id):
	# Check user permissions. User must have either systems.all or specific 
	# access to the system
	if not does_user_have_system_permission(id,"view.overview","systems.all.view"):
		abort(403)

	# Get the system
	system = cortex.lib.systems.get_system_by_id(id)

	# Ensure that the system actually exists, and return a 404 if it doesn't
	if system is None:
		abort(404)

	if system['allocation_who_realname'] is not None:
		system['allocation_who'] = system['allocation_who_realname'] + ' (' + system['allocation_who'] + ')'
	else:
		system['allocation_who'] = cortex.lib.user.get_user_realname(system['allocation_who']) + ' (' + system['allocation_who'] + ')'

	return render_template('systems/overview.html', system=system, active='systems', title=system['name'], power_ctl_perm=does_user_have_system_permission(id, "control.vmware.power", "control.all.vmware.power"))
Пример #18
0
def puppet_reports(node):
    """Handles the Puppet reports page for a node"""

    # Get the system (we need to know the ID for permissions checking)
    system = cortex.lib.systems.get_system_by_puppet_certname(node)
    if system is None:
        abort(404)

    ## Check if the user is allowed to view the reports of this node
    if not does_user_have_system_permission(system['id'], "view.puppet",
                                            "systems.all.view.puppet"):
        abort(403)

    try:
        # Connect to PuppetDB and get the reports
        db = cortex.lib.puppet.puppetdb_connect()
        reports = db.node(node).reports()

    except HTTPError as he:
        # If we get a 404 response from PuppetDB
        if he.response.status_code == 404:
            # Still display the page but with a nice error
            reports = None
        else:
            raise (he)
    except Exception as e:
        return stderr(
            "Unable to connect to PuppetDB",
            "Unable to connect to the Puppet database. The error was: " +
            type(e).__name__ + " - " + str(e))

    return render_template('puppet/reports.html',
                           reports=reports,
                           active='puppet',
                           title=node + " - Puppet Reports",
                           nodename=node,
                           pactive="reports",
                           system=system)
Пример #19
0
def puppet_reports(node):
	"""Handles the Puppet reports page for a node"""

	# Get the system (we need to know the ID for permissions checking)
	system = cortex.lib.systems.get_system_by_puppet_certname(node)
	if system is None:
		abort(404)

	## Check if the user is allowed to view the reports of this node
	if not does_user_have_system_permission(system['id'],"view.puppet","systems.all.view.puppet"):
		abort(403)

	try:
		# Connect to PuppetDB and get the reports
		db = cortex.lib.puppet.puppetdb_connect()
		reports = db.node(node).reports()
	except HTTPError, he:
		# If we get a 404 response from PuppetDB
		if he.response.status_code == 404:
			# Still display the page but with a nice error
			reports = None
		else:
			raise(he)
Пример #20
0
def puppet_reports(node):
    """Handles the Puppet reports page for a node"""

    # Get the system (we need to know the ID for permissions checking)
    system = cortex.lib.systems.get_system_by_puppet_certname(node)
    if system is None:
        abort(404)

        ## Check if the user is allowed to view the reports of this node
    if not does_user_have_system_permission(system["id"], "view.puppet", "systems.all.view.puppet"):
        abort(403)

    try:
        # Connect to PuppetDB and get the reports
        db = cortex.lib.puppet.puppetdb_connect()
        reports = db.node(node).reports()
    except HTTPError, he:
        # If we get a 404 response from PuppetDB
        if he.response.status_code == 404:
            # Still display the page but with a nice error
            reports = None
        else:
            raise (he)
Пример #21
0
def system_edit(id):
	if not does_user_have_system_permission(id,"view.detail","systems.all.view"):
		abort(403)

	# Get the system
	system = cortex.lib.systems.get_system_by_id(id)

	# Ensure that the system actually exists, and return a 404 if it doesn't
	if system is None:
		abort(404)

	if request.method == 'GET' or request.method == 'HEAD':
		system_class = cortex.lib.classes.get(system['class'])
		system['review_status_text'] = cortex.lib.systems.REVIEW_STATUS_BY_ID[system['review_status']]

		if system['puppet_certname']:
			system['puppet_node_status'] = cortex.lib.puppet.puppetdb_get_node_status(system['puppet_certname'])

		return render_template('systems/edit.html', system=system, system_class=system_class, active='systems', title=system['name'])

	elif request.method == 'POST':
		try:
			# Get a cursor to the database
			curd = g.db.cursor(mysql.cursors.DictCursor)

			# Extract CMDB ID from form
			if does_user_have_system_permission(id,"edit.cmdb","systems.all.edit.cmdb"):
				cmdb_id = request.form.get('cmdb_id',None)
				if cmdb_id is not None:
					cmdb_id = cmdb_id.strip()
					if len(cmdb_id) == 0:
						cmdb_id = None
					else:
						if not re.match('^[0-9a-f]+$', cmdb_id.lower()):
							raise ValueError()
			else:
				cmdb_id = system['cmdb_id']

			# Extract VMware UUID from form
			if does_user_have_system_permission(id,"edit.vmware","systems.all.edit.vmware"):
				vmware_uuid = request.form.get('vmware_uuid',None)
				if vmware_uuid is not None:
					vmware_uuid = vmware_uuid.strip()
					if len(vmware_uuid) == 0:
						vmware_uuid = None
					else:
						if not re.match('^[0-9a-f]{8}-([0-9a-f]{4}-){3}[0-9a-f]{12}$', vmware_uuid.lower()):
							raise ValueError()
			else:
				vmware_uuid = system['vmware_uuid']

			# Process the expiry date
			if does_user_have_system_permission(id,"edit.expiry","systems.all.edit.expiry"):
				if 'expiry_date' in request.form and request.form['expiry_date'] is not None and len(request.form['expiry_date'].strip()) > 0:
					expiry_date = request.form['expiry_date']
					try:
						expiry_date = datetime.datetime.strptime(expiry_date, '%Y-%m-%d')
					except Exception, e:
						abort(400)
				else:
					expiry_date = None
			else:
				expiry_date = system['expiry_date']

			# Extract Review Status from form
			if does_user_have_system_permission(id,"edit.review","systems.all.edit.review"):
				review_status = int(request.form.get('review_status', 0))
				if not review_status in cortex.lib.systems.REVIEW_STATUS_BY_ID:
					raise ValueError()

				# Extract Review Ticket from form
				review_task = request.form.get('review_task', None)
				if review_task is not None:
					review_task = review_task.strip()
					if len(review_task) == 0:
						review_task = None
					else:
						if not re.match('^[A-Z]+TASK[0-9]+$', review_task):
							raise ValueError()

				# If the review status is "Under review" and a task hasn't been specified,
				# then we should create one.
				if review_status == cortex.lib.systems.REVIEW_STATUS_BY_NAME['REVIEW'] and review_task is None:
					# Build some JSON
					task_data = {}
					task_data['time_constraint'] = 'asap'
					task_data['short_description'] = 'Review necessity of virtual machine ' + system['name']
					task_data['description'] = 'Please review the necessity of the virtual machine ' + system['name'] + ' to determine whether we need to keep it or whether it can be decommissioned. Information about the VM and links to ServiceNow can be found on Cortex at https://' + app.config['CORTEX_DOMAIN'] + url_for('system', id=id) + "\n\nOnce reviewed, please edit the system in Cortex using the link above and set it's 'Review Status' to either 'Required' or 'Not Required' and then close the associated project task."
					#task_data['opened_by'] = app.config['REVIEW_TASK_OPENER_SYS_ID']
					task_data['opened_by'] = 'example'
					task_data['assignment_group'] = app.config['REVIEW_TASK_TEAM']
					task_data['parent'] = app.config['REVIEW_TASK_PARENT_SYS_ID']

					# Make a post request to ServiceNow to create the task
					r = requests.post('https://' + app.config['SN_HOST'] + '/api/now/v1/table/pm_project_task', auth=(app.config['SN_USER'], app.config['SN_PASS']), headers={'Accept': 'application/json', 'Content-Type': 'application/json'}, json=task_data)

					# If we succeeded, get the task number
					if r is not None and r.status_code >= 200 and r.status_code <= 299:
						response_json = r.json()
						review_task = response_json['result']['number']
					else:
						error = "Failed to link ServiceNow task and CI."
						if r is not None:
							error = error + " HTTP Response code: " + str(r.status_code)
						app.logger.error(error)
						raise Exception()
			else:
				review_status = system['review_status']
				review_task = system['review_task']

			# Update the system
			curd.execute('UPDATE `systems` SET `allocation_comment` = %s, `cmdb_id` = %s, `vmware_uuid` = %s, `review_status` = %s, `review_task` = %s, `expiry_date` = %s WHERE `id` = %s', (request.form['allocation_comment'].strip(), cmdb_id, vmware_uuid, review_status, review_task, expiry_date, id))
			g.db.commit();
			cortex.lib.core.log(__name__, "systems.edit", "System '" + system['name'] + "' edited, id " + str(id), related_id=id)

			flash('System updated', "alert-success")
Пример #22
0
def system_backup(id):
	
	rubrik = cortex.lib.rubrik.Rubrik()

	if request.method == 'POST':

		if not does_user_have_system_permission(id,"edit.rubrik","systems.all.edit.rubrik"):
			abort(403)

		# Get the name of the vm
		system = cortex.lib.systems.get_system_by_id(id)
		if not system:
			abort(404)

		try:
			vm = rubrik.get_vm(system['name'])
		except:
			abort(500)

		mode = request.form.get('mode')
		if mode in ('INHERIT', 'UNPROTECTED'):
			rubrik.update_vm(vm['id'], {'configuredSlaDomainId': mode})
			flash('SLA Domain updated', 'alert-success')
		elif 'sla_domain' in request.form:
			rubrik.update_vm(vm['id'], {'configuredSlaDomainId': request.form.get('sla_domain')})
			flash('SLA Domain updated', 'alert-success')
		else:
			abort(400)

	# Check user permissions. User must have either systems.all.view.rubrik or edit.rubrik (there's no separate view at present)
	if not does_user_have_system_permission(id,"edit.rubrik","systems.all.view.rubrik"):
		abort(403)

	# Get the name of the vm
	system = cortex.lib.systems.get_system_by_id(id)
	if not system:
		abort(404)

	try:
		vm = rubrik.get_vm(system['name'])
	except:
		abort(500)

	# If the VM was not found, return early
	if vm is None:
		return render_template('systems/backup.html', system=system, vm=None, title=system['name'])

	# Get the list of all SLA Domains
	sla_domains = rubrik.get_sla_domains()

	# Get the SLA Domains and Snapshots for the VM
	vm['effectiveSlaDomain'] = next((sla_domain for sla_domain in sla_domains['data'] if sla_domain['id'] == vm['effectiveSlaDomainId']), 'unknown')
	vm['snapshots'] = rubrik.get_vm_snapshots(vm['id'])

	# Try to limit to the most recent 10, ignoring the error if there are less
	try:
		vm['snapshots']['data'] = vm['snapshots']['data'][:10]
	except (KeyError,):
		pass

	return render_template('systems/backup.html', system=system, sla_domains=sla_domains, vm=vm, title=system['name'])
Пример #23
0
def system_status(id):
	# Check user permissions. User must have either systems.all or specific
	# access to the system
	if not does_user_have_system_permission(id,"view.overview","systems.all.view"):
		abort(403)

	system = cortex.lib.systems.get_system_by_id(id)

	# Ensure that the system actually exists, and return a 404 if it doesn't
	if system is None:
		abort(404)
	# get the VM
	try:
		vm = cortex.lib.systems.get_vm_by_system_id(id)
	except ValueError as e:
		abort(404)

	data = {}
	data['hostname'] = ''
	data['dns_resolvers'] = []
	data['search_domain'] = ''
	routes = []
	ipaddr = []

	if vm is not None and vm.guest is not None:
		if vm.guest.ipStack is not None and len(vm.guest.ipStack) > 0:
			if vm.guest.ipStack[0].dnsConfig is not None:
				if vm.guest.ipStack[0].dnsConfig.hostName is not None:
					data['hostname'] = vm.guest.ipStack[0].dnsConfig.hostName
				if vm.guest.ipStack[0].dnsConfig.ipAddress is not None:
					data['dns_resolvers'] = vm.guest.ipStack[0].dnsConfig.ipAddress
				if vm.guest.ipStack[0].dnsConfig.domainName is not None:
					data['search_domain'] = vm.guest.ipStack[0].dnsConfig.domainName
			if vm.guest.ipStack[0].ipRouteConfig is not None and vm.guest.ipStack[0].ipRouteConfig.ipRoute is not None and len(vm.guest.ipStack[0].ipRouteConfig.ipRoute) > 0:
				for route in vm.guest.ipStack[0].ipRouteConfig.ipRoute:
					addroute = {}
					if route.gateway is not None and route.gateway.ipAddress is not None:
						addroute['gateway'] = route.gateway.ipAddress
					if route.network is not None:
						addroute['network'] = route.network
					if route.prefixLength is not None:
						addroute['prefix'] = route.prefixLength
					if addroute:
						routes = routes + [addroute]

		if vm.guest.net is not None and len(vm.guest.net) > 0:
			for net_adapter in vm.guest.net:
				if net_adapter.ipAddress is not None and len(net_adapter.ipAddress) > 0:
					for addr in net_adapter.ipAddress:
						ipaddr = ipaddr + [addr]

		data['net'] = {'ipaddr': ipaddr, 'routes': routes}
		if vm.guest.guestState is not None:
			data['guest_state'] = vm.guest.guestState
		if vm.runtime.powerState is not None:
			data['power_state'] = vm.runtime.powerState
		if vm.summary is not None and vm.summary.quickStats is not None:
			if vm.summary.quickStats.overallCpuUsage is not None and vm.summary.quickStats.staticCpuEntitlement is not None:
				data['cpu'] = {'overall_usage': vm.summary.quickStats.overallCpuUsage, 'entitlement': vm.summary.quickStats.staticCpuEntitlement}
			if vm.summary.quickStats.guestMemoryUsage is not None and vm.summary.quickStats.staticMemoryEntitlement is not None:
				data['mem'] = {'overall_usage': vm.summary.quickStats.guestMemoryUsage, 'entitlement': vm.summary.quickStats.staticMemoryEntitlement}
			if vm.summary.quickStats.uptimeSeconds is not None:
				data['uptime'] = vm.summary.quickStats.uptimeSeconds

	return jsonify(data)
Пример #24
0
def system_status(id):
	# Check user permissions. User must have either systems.all or specific
	# access to the system
	if not does_user_have_system_permission(id,"view.overview","systems.all.view"):
		abort(403)

	system = cortex.lib.systems.get_system_by_id(id)

	# Ensure that the system actually exists, and return a 404 if it doesn't
	if system is None:
		abort(404)

	data = {}
	data['hostname'] = ''
	data['dns_resolvers'] = []
	data['search_domain'] = ''
	routes = []
	ipaddr = []

	# get the VM
	try:
		vm = cortex.lib.systems.get_vm_by_system_id(id)
	except ValueError as e:
		abort(404)
	except Exception as e:
		# If we want to handle vCenter being unavailable gracefully.
		if not app.config.get('HANDLE_UNAVAILABLE_VCENTER_GRACEFULLY', False):
			raise e	
		else:
			vm = None
			# Add an error field to the data we return, 
			# so we can display a message on the template. 
			data['error'] = 'Unable to retrieve system information, please check vCenter availability.'

	if vm is not None and vm.guest is not None:
		if vm.guest.ipStack is not None and len(vm.guest.ipStack) > 0:
			if vm.guest.ipStack[0].dnsConfig is not None:
				if vm.guest.ipStack[0].dnsConfig.hostName is not None:
					data['hostname'] = vm.guest.ipStack[0].dnsConfig.hostName
				if vm.guest.ipStack[0].dnsConfig.ipAddress is not None:
					data['dns_resolvers'] = vm.guest.ipStack[0].dnsConfig.ipAddress
				if vm.guest.ipStack[0].dnsConfig.domainName is not None:
					data['search_domain'] = vm.guest.ipStack[0].dnsConfig.domainName
			if vm.guest.ipStack[0].ipRouteConfig is not None and vm.guest.ipStack[0].ipRouteConfig.ipRoute is not None and len(vm.guest.ipStack[0].ipRouteConfig.ipRoute) > 0:
				for route in vm.guest.ipStack[0].ipRouteConfig.ipRoute:
					addroute = {}
					if route.gateway is not None and route.gateway.ipAddress is not None:
						addroute['gateway'] = route.gateway.ipAddress
					if route.network is not None:
						addroute['network'] = route.network
					if route.prefixLength is not None:
						addroute['prefix'] = route.prefixLength
					if addroute:
						routes = routes + [addroute]

		if vm.guest.net is not None and len(vm.guest.net) > 0:
			for net_adapter in vm.guest.net:
				if net_adapter.ipAddress is not None and len(net_adapter.ipAddress) > 0:
					for addr in net_adapter.ipAddress:
						ipaddr = ipaddr + [addr]

		data['net'] = {'ipaddr': ipaddr, 'routes': routes}
		if vm.guest.guestState is not None:
			data['guest_state'] = vm.guest.guestState
		if vm.runtime.powerState is not None:
			data['power_state'] = vm.runtime.powerState
		if vm.summary is not None and vm.summary.quickStats is not None:
			if vm.summary.quickStats.overallCpuUsage is not None and vm.summary.quickStats.staticCpuEntitlement is not None:
				data['cpu'] = {'overall_usage': vm.summary.quickStats.overallCpuUsage, 'entitlement': vm.summary.quickStats.staticCpuEntitlement}
			if vm.summary.quickStats.guestMemoryUsage is not None and vm.summary.quickStats.staticMemoryEntitlement is not None:
				data['mem'] = {'overall_usage': vm.summary.quickStats.guestMemoryUsage, 'entitlement': vm.summary.quickStats.staticMemoryEntitlement}
			if vm.summary.quickStats.uptimeSeconds is not None:
				data['uptime'] = vm.summary.quickStats.uptimeSeconds

	return jsonify(data)
Пример #25
0
def system_edit(id):
	if not does_user_have_system_permission(id,"view","systems.all.view"):
		abort(403)

	# Get the system
	system = cortex.lib.systems.get_system_by_id(id)

	# Ensure that the system actually exists, and return a 404 if it doesn't
	if system is None:
		abort(404)

	if request.method == 'GET' or request.method == 'HEAD':
		system_class = cortex.lib.classes.get(system['class'])
		system['review_status_text'] = cortex.lib.systems.REVIEW_STATUS_BY_ID[system['review_status']]
		
		if system['puppet_certname']:
			system['puppet_node_status'] = cortex.lib.puppet.puppetdb_get_node_status(system['puppet_certname'])
		
		return render_template('systems/edit.html', system=system, system_class=system_class, active='systems', title=system['name'])

	elif request.method == 'POST':
		try:
			# Get a cursor to the database
			curd = g.db.cursor(mysql.cursors.DictCursor)

			# Extract CMDB ID from form
			if does_user_have_system_permission(id,"edit.cmdb","systems.all.edit.cmdb"):
				cmdb_id = request.form.get('cmdb_id',None)
				if cmdb_id is not None:			
					cmdb_id = cmdb_id.strip()
					if len(cmdb_id) == 0:
						cmdb_id = None
					else:
						if not re.match('^[0-9a-f]+$', cmdb_id.lower()):
							raise ValueError()
			else:
				cmdb_id = system['cmdb_id']

			# Extract VMware UUID from form
			if does_user_have_system_permission(id,"edit.vmware","systems.all.edit.vmware"):
				vmware_uuid = request.form.get('vmware_uuid',None)
				if vmware_uuid is not None:			
					vmware_uuid = vmware_uuid.strip()
					if len(vmware_uuid) == 0:
						vmware_uuid = None
					else:
						if not re.match('^[0-9a-f]{8}-([0-9a-f]{4}-){3}[0-9a-f]{12}$', vmware_uuid.lower()):
							raise ValueError()
			else:
				vmware_uuid = system['vmware_uuid']

			# Process the expiry date
			if does_user_have_system_permission(id,"edit.expiry","systems.all.edit.expiry"):
				if 'expiry_date' in request.form and request.form['expiry_date'] is not None and len(request.form['expiry_date'].strip()) > 0:
					expiry_date = request.form['expiry_date']
					try:
						expiry_date = datetime.datetime.strptime(expiry_date, '%Y-%m-%d')
					except Exception, e:
						abort(400)
				else:
					expiry_date = None
			else:
				expiry_date = system['expiry_date']

			# Extract Review Status from form
			if does_user_have_system_permission(id,"edit.review","systems.all.edit.review"):
				review_status = int(request.form.get('review_status', 0))
				if not review_status in cortex.lib.systems.REVIEW_STATUS_BY_ID:
					raise ValueError()

				# Extract Review Ticket from form
				review_task = request.form.get('review_task', None)
				if review_task is not None:
					review_task = review_task.strip()
					if len(review_task) == 0:
						review_task = None
					else:
						if not re.match('^[A-Z]+TASK[0-9]+$', review_task):
							raise ValueError()

				# If the review status is "Under review" and a task hasn't been specified,
				# then we should create one.
				if review_status == cortex.lib.systems.REVIEW_STATUS_BY_NAME['REVIEW'] and review_task is None:
					# Build some JSON
					task_data = {}
					task_data['time_constraint'] = 'asap'
					task_data['short_description'] = 'Review necessity of virtual machine ' + system['name']
					task_data['description'] = 'Please review the necessity of the virtual machine ' + system['name'] + ' to determine whether we need to keep it or whether it can be decommissioned. Information about the VM and links to ServiceNow can be found on Cortex at https://' + app.config['CORTEX_DOMAIN'] + url_for('system', id=id) + "\n\nOnce reviewed, please edit the system in Cortex using the link above and set it's 'Review Status' to either 'Required' or 'Not Required' and then close the associated project task."
					#task_data['opened_by'] = app.config['REVIEW_TASK_OPENER_SYS_ID']
					task_data['opened_by'] = 'example'
					task_data['assignment_group'] = app.config['REVIEW_TASK_TEAM']
					task_data['parent'] = app.config['REVIEW_TASK_PARENT_SYS_ID']

					# Make a post request to ServiceNow to create the task
					r = requests.post('https://' + app.config['SN_HOST'] + '/api/now/v1/table/pm_project_task', auth=(app.config['SN_USER'], app.config['SN_PASS']), headers={'Accept': 'application/json', 'Content-Type': 'application/json'}, json=task_data)

					# If we succeeded, get the task number
					if r is not None and r.status_code >= 200 and r.status_code <= 299:
						response_json = r.json()
						review_task = response_json['result']['number']
					else:
						error = "Failed to link ServiceNow task and CI."
						if r is not None:
							error = error + " HTTP Response code: " + str(r.status_code)
						app.logger.error(error)
						raise Exception()
			else:
				review_status = system['review_status']
				review_task = system['review_task']

			# Update the system
			curd.execute('UPDATE `systems` SET `allocation_comment` = %s, `cmdb_id` = %s, `vmware_uuid` = %s, `review_status` = %s, `review_task` = %s, `expiry_date` = %s WHERE `id` = %s', (request.form['allocation_comment'].strip(), cmdb_id, vmware_uuid, review_status, review_task, expiry_date, id))
			g.db.commit();

			flash('System updated', "alert-success") 
Пример #26
0
def adddisk_add():

	selected_system = None
	systems = None
	if request.method == "GET" and "system" in request.args and request.args["system"].strip():
		try:
			selected_system = get_system_by_id(int(request.args["system"].strip()))
		except ValueError:
			pass # System was not an int.
		else:
			# Ensure the system is actually a VM
			selected_system = selected_system if selected_system["vmware_uuid"] else None

		# Check permissions on this system
		if not does_user_have_system_permission(selected_system["id"], "adddisk") and not does_user_have_workflow_permission("systems.all.adddisk"):
			abort(403)

	# If a system was not selected, get all systems
	if not selected_system:
		# Get systems depending on permissions.
		if does_user_have_workflow_permission("systems.all.adddisk"):
			# User can add disks to all systems.
			systems = get_systems(order='id', order_asc=False, virtual_only=True)
		elif does_user_have_any_system_permission("adddisk"):
			# Select all VMs where the user has permission to add disks
			query_where = (
				"""WHERE (`cmdb_id` IS NOT NULL AND `cmdb_operational_status` = "In Service") AND `vmware_uuid` IS NOT NULL AND (`id` IN (SELECT `system_id` FROM `system_perms_view` WHERE (`type` = '0' AND `perm` = 'adddisk' AND `who` = %s) OR (`type` = '1' AND `perm` = 'adddisk' AND `who` IN (SELECT `group` FROM `ldap_group_cache` WHERE `username` = %s)))) ORDER BY `id` DESC""",
				(session["username"], session["username"]),
			)
			systems = get_systems(where_clause=query_where)
		else:
			abort(403)

	if request.method == "POST":
		# Get the values
		values = {k: request.form.get(k) if k in request.form else abort(400) for k in ["adddisk_task", "adddisk_size", "adddisk_system_id"]}
		values["adddisk_task"] = values["adddisk_task"] if values["adddisk_task"] else "unknown"

		try:
			values["adddisk_size"] = int(values["adddisk_size"])
		except ValueError:
			abort(400)

		if not MIN_DISK_SIZE <= values["adddisk_size"] <= MAX_DISK_SIZE:
			flash("Invalid disk size! Please choose a size between {} and {} GiB".format(MIN_DISK_SIZE, MAX_DISK_SIZE))
		else:

			# Check permissions before starting task
			if not does_user_have_system_permission(values["adddisk_system_id"], "adddisk") and not does_user_have_workflow_permission("systems.all.adddisk"):
				abort(403)

			# Task Options
			options = {}
			options["wfconfig"] = workflow.config
			options["values"] = values

			# Everything should be good - start a task.
			neocortex = cortex.lib.core.neocortex_connect()
			task_id = neocortex.create_task(__name__, session["username"], options, description="Add VMware disk")

			# Log the Task ID
			cortex.lib.core.log(__name__, "workflow.adddisk.add", "Add disk task {} started by {} with ServiceNow task {}".format(task_id, session["username"], values["adddisk_task"]))

			# Redirect to the status page for the task
			return redirect(url_for("task_status", task_id=task_id))

	return workflow.render_template("add.html", title="Add VMware Disk", selected_system=selected_system, systems=systems)
Пример #27
0
	# 'reports' is a generator. Get the next (first and indeed, only item) from the generator
	try:
		report = next(reports)
	except StopIteration, e:
		# If we get a StopIteration error, then we've not got any data
		# returned from the reports generator, so the report didn't
		# exist, hence we should 404
		return abort(404)

	# Get the system (we need the ID for perms check, amongst other things)
	system = cortex.lib.systems.get_system_by_puppet_certname(report.node)
	if system is None:
		return abort(404)

	## Check if the user is allowed to view the report
	if not does_user_have_system_permission(system['id'],"view.puppet","systems.all.view.puppet"):
		abort(403)

	# Build metrics into a more useful dictionary
	metrics = {}
	for metric in report.metrics:
		if metric['category'] not in metrics:
			metrics[metric['category']] = {}

		metrics[metric['category']][metric['name']] = metric['value']

	# Render
	return render_template('puppet/report.html', report=report, metrics=metrics, system=system, active='puppet', title=report.node + " - Puppet Report")

##############################################################################
Пример #28
0
def puppet_enc_edit(node):
    """Handles the manage Puppet node page"""

    # Get the system out of the database
    system = cortex.lib.systems.get_system_by_puppet_certname(node)
    environments = cortex.lib.core.get_puppet_environments()
    env_dict = cortex.lib.core.get_environments_as_dict()

    if system == None:
        abort(404)

        ## Check if the user is allowed to edit the Puppet configuration
    if not does_user_have_system_permission(system["id"], "edit.puppet", "systems.all.edit.puppet"):
        abort(403)

        # If we've got a new node, then don't show "None"
    if system["puppet_classes"] is None or system["puppet_classes"] == "":
        system["puppet_classes"] = "# Classes to include can be entered here\n"
    if system["puppet_variables"] is None or system["puppet_variables"] == "":
        system["puppet_variables"] = "# Global variables to include can be entered here\n"
    if system["puppet_certname"] is None:
        system["puppet_certname"] = ""

        # On any GET request, just display the information
    if request.method == "GET":

        return render_template(
            "puppet/enc.html",
            system=system,
            active="puppet",
            environments=environments,
            title=system["name"],
            nodename=node,
            pactive="edit",
            yaml=cortex.lib.puppet.generate_node_config(system["puppet_certname"]),
        )

        # On any POST request, validate the input and then save
    elif request.method == "POST":
        # Extract data from form
        environment = request.form.get("environment", "")
        classes = request.form.get("classes", "")
        variables = request.form.get("variables", "")
        if "include_default" in request.form:
            include_default = True
        else:
            include_default = False
        error = False

        # Validate environement:
        if environment not in [e["id"] for e in environments]:
            flash("Invalid environment", "alert-danger")
            error = True

            # Validate classes YAML
        try:
            yaml.load(classes)
        except Exception, e:
            flash("Invalid YAML syntax for classes: " + str(e), "alert-danger")
            error = True

            # Validate variables YAML
        try:
            yaml.load(variables)
        except Exception, e:
            flash("Invalid YAML syntax for variables: " + str(e), "alert-danger")
            error = True
Пример #29
0
def puppet_enc_edit(node):
    """Handles the manage Puppet node page"""

    # Get the system out of the database
    system = cortex.lib.systems.get_system_by_puppet_certname(node)
    environments = cortex.lib.core.get_puppet_environments()
    env_dict = cortex.lib.core.get_environments_as_dict()

    if system == None:
        abort(404)

    curd = g.db.cursor(mysql.cursors.DictCursor)
    curd.execute(
        "SELECT module_name, class_name, class_parameter, description, tag_name FROM puppet_modules_info;"
    )

    outcome = {}
    result = curd.fetchall()

    modules = {}

    for row in result:
        if row['module_name'] not in modules.keys():
            modules[row['module_name']] = {
                row['class_name']: {
                    row['class_parameter']: {
                        'description': row['description'],
                        'tag_name': row['tag_name']
                    }
                }
            }
        elif row['class_name'] not in modules[row['module_name']]:
            modules[row['module_name']][row['class_name']] = {
                row['class_parameter']: {
                    'description': row['description'],
                    'tag_name': row['tag_name']
                }
            }
        elif row['class_parameter'] not in modules[row['module_name']][
                row['class_name']]:
            modules[row['module_name']][row['class_name']][
                row['class_parameter']] = {
                    'description': row['description'],
                    'tag_name': row['tag_name']
                }

    # On any GET request, just display the information
    if request.method == 'GET':
        # If the user has view or edit permission send them the template - otherwise abort with 403.
        if does_user_have_system_permission(system['id'], "view.puppet.classify", "systems.all.view.puppet.classify") or \
         does_user_have_system_permission(system['id'], "edit.puppet"," systems.all.edit.puppet"):

            return render_template('puppet/enc.html',
                                   variable_names=modules,
                                   system=system,
                                   active='puppet',
                                   environments=environments,
                                   title=system['name'],
                                   nodename=node,
                                   pactive="edit",
                                   yaml=cortex.lib.puppet.generate_node_config(
                                       system['puppet_certname']))
        else:
            abort(403)

    # If the method is POST and the user has edit permission.
    # Validate the input and then save.
    elif request.method == 'POST' and does_user_have_system_permission(
            system['id'], "edit.puppet", "systems.all.edit.puppet"):
        # Extract data from form
        environment = request.form.get('environment', '')
        classes = request.form.get('classes', '')
        variables = request.form.get('variables', '')
        if 'include_default' in request.form:
            include_default = True
        else:
            include_default = False
        error = False

        # Validate environement:
        if environment not in [e['id'] for e in environments]:
            flash('Invalid environment', 'alert-danger')
            error = True

        # Validate classes YAML
        try:
            data = yaml.safe_load(classes)
        except Exception as e:
            flash('Invalid YAML syntax for classes: ' + str(e), 'alert-danger')
            error = True

        try:
            if not data is None:
                assert isinstance(data, dict)
        except Exception as e:
            flash(
                'Invalid YAML syntax for classes: result was not a list of classes, did you forget a trailing colon? '
                + str(e), 'alert-danger')
            error = True

        # Validate variables YAML
        try:
            data = yaml.safe_load(variables)
        except Exception as e:
            flash('Invalid YAML syntax for variables: ' + str(e),
                  'alert-danger')
            error = True

        try:
            if not data is None:
                assert isinstance(data, dict)
        except Exception as e:
            flash(
                'Invalid YAML syntax for variables: result was not a list of variables, did you forget a trailing colon? '
                + str(e), 'alert-danger')
            error = True

        # On error, overwrite what is in the system object with our form variables
        # and return the page back to the user for fixing
        if error:
            system['puppet_env'] = environment
            system['puppet_classes'] = classes
            system['puppet_variables'] = variables
            system['puppet_include_default'] = include_default
            return render_template('puppet/enc.html',
                                   system=system,
                                   active='puppet',
                                   environments=environments,
                                   title=system['name'])

        # Get a cursor to the database
        curd = g.db.cursor(mysql.cursors.DictCursor)

        # Update the system
        curd.execute(
            'UPDATE `puppet_nodes` SET `env` = %s, `classes` = %s, `variables` = %s, `include_default` = %s WHERE `certname` = %s',
            (env_dict[environment]['puppet'], classes, variables,
             include_default, system['puppet_certname']))
        g.db.commit()
        cortex.lib.core.log(
            __name__, "puppet.config.changed",
            "Puppet node configuration updated for '" +
            system['puppet_certname'] + "'")

        # Redirect back to the systems page
        flash('Puppet ENC for host ' + system['name'] + ' updated',
              'alert-success')

        return redirect(url_for('puppet_enc_edit', node=node))
    else:
        abort(403)
Пример #30
0
    # 'reports' is a generator. Get the next (first and indeed, only item) from the generator
    try:
        report = next(reports)
    except StopIteration, e:
        # If we get a StopIteration error, then we've not got any data
        # returned from the reports generator, so the report didn't
        # exist, hence we should 404
        return abort(404)

        # Get the system (we need the ID for perms check, amongst other things)
    system = cortex.lib.systems.get_system_by_puppet_certname(report.node)
    if system is None:
        return abort(404)

        ## Check if the user is allowed to view the report
    if not does_user_have_system_permission(system["id"], "view.puppet", "systems.all.view.puppet"):
        abort(403)

        # Build metrics into a more useful dictionary
    metrics = {}
    for metric in report.metrics:
        if metric["category"] not in metrics:
            metrics[metric["category"]] = {}

        metrics[metric["category"]][metric["name"]] = metric["value"]

        # Render
    return render_template(
        "puppet/report.html",
        report=report,
        metrics=metrics,
Пример #31
0
def puppet_enc_edit(node):
    """Handles the manage Puppet node page"""

    # Get the system out of the database
    system = cortex.lib.systems.get_system_by_puppet_certname(node)
    if system is None:
        abort(404)

    # Get the environments from the DB where:
    #  - the user has classify permission or,
    #  - the environment is the 'default' environment or,
    #  - the environment is an 'infrastructure' environment.

    if does_user_have_permission("puppet.environments.all.classify"):
        environments = cortex.lib.puppet.get_puppet_environments()
    else:
        environments = cortex.lib.puppet.get_puppet_environments(
            environment_permission="classify",
            include_default=True,
            include_infrastructure_envs=True,
        )

    # Get the environment names as a list
    environment_names = [e['environment_name'] for e in environments]

    # Get the database cursor
    curd = g.db.cursor(mysql.cursors.DictCursor)
    # TODO: Query with an order so 'production' take precedence
    curd.execute(
        "SELECT `puppet_modules`.`module_name` AS `module_name`, `puppet_classes`.`class_name` AS `class_name`, `puppet_documentation`.`name` AS `param`, `puppet_documentation`.`text` AS `param_desc` FROM `puppet_modules` LEFT JOIN `puppet_classes` ON `puppet_modules`.`id`=`puppet_classes`.`module_id` LEFT JOIN `puppet_documentation` ON `puppet_classes`.`id`=`puppet_documentation`.`class_id` WHERE `puppet_documentation`.`tag`=%s;",
        ("param", ))
    hints = {}
    for row in curd.fetchall():
        if row["module_name"] not in hints:
            hints[row["module_name"]] = {}
        if row["class_name"] not in hints[row["module_name"]]:
            hints[row["module_name"]][row["class_name"]] = {}
        if row["param"] not in hints[row["module_name"]][row["class_name"]]:
            hints[row["module_name"]][row["class_name"]][
                row["param"]] = row["param_desc"]

    # If the user has view or edit permission send them the template - otherwise abort with 403.
    if not does_user_have_system_permission(
            system['id'], "view.puppet.classify",
            "systems.all.view.puppet.classify"
    ) and not does_user_have_system_permission(system['id'], "edit.puppet",
                                               "systems.all.edit.puppet"):
        abort(403)

    # If the method is POST and the user has edit permission.
    # Validate the input and then save.
    if request.method == 'POST':
        if not does_user_have_system_permission(system['id'], "edit.puppet",
                                                "systems.all.edit.puppet"):
            abort(403)

        # Extract data from form
        environment = request.form.get('environment', '')
        classes = request.form.get('classes', '')
        variables = request.form.get('variables', '')
        include_default = bool('include_default' in request.form)
        error = False

        # Validate environement:
        if environment not in environment_names:
            flash(
                'Invalid Puppet environment, you can only classify systems with Environments you have \'classify\' permission over!',
                'alert-danger')
            error = True

        # Validate classes YAML
        try:
            data = yaml.safe_load(classes)
        except Exception as e:
            flash('Invalid YAML syntax for classes: ' + str(e), 'alert-danger')
            error = True

        try:
            if not data is None:
                assert isinstance(data, dict)
        except Exception as e:
            flash(
                'Invalid YAML syntax for classes: result was not a list of classes, did you forget a trailing colon? '
                + str(e), 'alert-danger')
            error = True

        # Validate variables YAML
        try:
            data = yaml.safe_load(variables)
        except Exception as e:
            flash('Invalid YAML syntax for variables: ' + str(e),
                  'alert-danger')
            error = True

        try:
            if not data is None:
                assert isinstance(data, dict)
        except Exception as e:
            flash(
                'Invalid YAML syntax for variables: result was not a list of variables, did you forget a trailing colon? '
                + str(e), 'alert-danger')
            error = True

        # On error, overwrite what is in the system object with our form variables
        # and return the page back to the user for fixing
        if error:
            system['puppet_env'] = environment
            system['puppet_classes'] = classes
            system['puppet_variables'] = variables
            system['puppet_include_default'] = include_default
            return render_template('puppet/enc.html',
                                   system=system,
                                   active='puppet',
                                   environments=environments,
                                   title=system['name'],
                                   hints=hints)

        # Get a cursor to the database
        curd = g.db.cursor(mysql.cursors.DictCursor)

        # Update the system
        curd.execute(
            'UPDATE `puppet_nodes` SET `env` = %s, `classes` = %s, `variables` = %s, `include_default` = %s WHERE `certname` = %s',
            (environment, classes, variables, include_default,
             system['puppet_certname']))
        g.db.commit()
        cortex.lib.core.log(
            __name__, "puppet.config.changed",
            "Puppet node configuration updated for '" +
            system['puppet_certname'] + "'")

        # Redirect back to the systems page
        flash('Puppet ENC for host ' + system['name'] + ' updated',
              'alert-success')

        return redirect(url_for('puppet_enc_edit', node=node))

    # On any GET request, just display the information
    return render_template('puppet/enc.html',
                           system=system,
                           active='puppet',
                           environments=environments,
                           title=system['name'],
                           nodename=node,
                           pactive="edit",
                           yaml=cortex.lib.puppet.generate_node_config(
                               system['puppet_certname']),
                           hints=hints,
                           environment_names=environment_names)
Пример #32
0
def snapshot_create():

    # Get systems depending on permissions.
    if does_user_have_workflow_permission('systems.all.snapshot'):
        # User can snapshot all systems.
        systems = get_systems(order='id', order_asc=False, virtual_only=True)
    elif does_user_have_any_system_permission('snapshot'):
        # Select all VMs where the user has permission to snapshot
        query_where = (
            """WHERE (`cmdb_id` IS NOT NULL AND `cmdb_operational_status` = "In Service") AND `vmware_uuid` IS NOT NULL AND (`id` IN (SELECT `system_id` FROM `p_system_perms_view` WHERE (`type` = '0' AND `perm` = 'snapshot' AND `who` = %s) OR (`type` = '1' AND `perm` = 'snapshot' AND `who` IN (SELECT `group` FROM `ldap_group_cache` WHERE `username` = %s)))) ORDER BY `id` DESC""",
            (session["username"], session["username"]),
        )
        systems = get_systems(where_clause=query_where)
    else:
        abort(403)

    # Create the values dict.
    values = {}

    if request.method == 'POST':

        values['snapshot_name'] = request.form.get(
            'snapshot_name', 'Snapshot - {}'.format(session['username']))[:80]
        values['snapshot_task'] = request.form.get('snapshot_task', '')
        values['snapshot_expiry'] = request.form.get('snapshot_expiry', None)
        values['snapshot_comments'] = request.form.get('snapshot_comments', '')
        values['snapshot_username'] = session['username']
        values['snapshot_memory'] = 'snapshot_memory' in request.form
        values['snapshot_cold'] = 'snapshot_cold' in request.form

        values['systems'] = list(set(request.form.getlist('systems[]')))
        values['snapshot_systems'] = []

        # Before starting the task check the permissions.
        error = False
        if not does_user_have_workflow_permission('systems.all.snapshot'):
            for system in values['systems']:
                try:
                    vm = next(i for i in systems if i['name'] == system)
                except StopIteration:
                    flash(
                        'You do not have permission to snapshot one or more select VMs. Please try again.',
                        'alert-danger')
                    error = True
                else:
                    values['snapshot_systems'].append(vm)
                    if not does_user_have_system_permission(
                            vm['id'], 'snapshot'):
                        flash(
                            'You do not have permission to snapshot {}, please remove this from the list of systems and try again.'
                            .format(vm['name']), 'alert-danger')
                        error = True

        if error:
            return workflow.render_template('create.html',
                                            title='Create VMware Snapshot',
                                            systems=systems,
                                            values=values)

        # Task Options
        options = {}
        options['wfconfig'] = workflow.config
        options['values'] = values

        # Everything should be good - start a task.
        neocortex = cortex.lib.core.neocortex_connect()
        task_id = neocortex.create_task(__name__,
                                        session['username'],
                                        options,
                                        description='Create a VMware Snapshot')

        # Redirect to the status page for the task
        return redirect(url_for('task_status', task_id=task_id))

    if 'systems' in request.args:
        values['snapshot_systems'] = []
        for system in request.args['systems'].strip(',').split(','):
            try:
                vm = next(i for i in systems if i['id'] == int(system))
            except StopIteration:
                pass  # System not in Systems List (Likely not a VM then).
            except ValueError:
                pass  # System was not an int.
            else:
                values['snapshot_systems'].append(vm)

    return workflow.render_template('create.html',
                                    title='Create VMware Snapshot',
                                    systems=systems,
                                    values=values)
Пример #33
0
def snapshot_create():
    # Don't go any further if workflows are currently locked
    raise_if_workflows_locked()

    # Get systems depending on permissions.
    if does_user_have_workflow_permission('systems.all.snapshot'):
        # User can snapshot all systems.
        systems = get_systems(order='id', order_asc=False, virtual_only=True)
    elif does_user_have_any_system_permission('snapshot'):
        # User can only snapshot certain systems.
        systems = get_systems(order='id',
                              order_asc=False,
                              virtual_only=True,
                              show_allocated_and_perms=True,
                              only_allocated_by=session['username'])
    else:
        abort(403)

    # Create the values dict.
    values = {}

    if request.method == 'GET':
        if 'systems' in request.args:
            values['snapshot_systems'] = []
            for system in request.args['systems'].strip(',').split(','):
                try:
                    vm = next(i for i in systems if i['id'] == int(system))
                except StopIteration:
                    pass  # System not in Systems List (Likely not a VM then).
                except ValueError:
                    pass  # System was not an int.
                else:
                    values['snapshot_systems'].append(vm)

        return workflow.render_template('create.html',
                                        systems=systems,
                                        values=values)

    elif request.method == 'POST':

        values['snapshot_name'] = request.form.get('snapshot_name', '')
        values['snapshot_task'] = request.form.get('snapshot_task', '')
        values['snapshot_expiry'] = request.form.get('snapshot_expiry', None)
        values['snapshot_comments'] = request.form.get('snapshot_comments', '')
        values['snapshot_username'] = session['username']
        values['snapshot_memory'] = 'snapshot_memory' in request.form
        values['snapshot_cold'] = 'snapshot_cold' in request.form

        values['systems'] = list(set(request.form.getlist('systems[]')))
        values['snapshot_systems'] = []

        # Before starting the task check the permissions.
        error = False
        if not does_user_have_workflow_permission('systems.all.snapshot'):
            for system in values['systems']:
                try:
                    vm = next(i for i in systems if i['name'] == system)
                except StopIteration:
                    flash(
                        'You do not have permission to snapshot one or more select VMs. Please try again.',
                        'alert-danger')
                    error = True
                else:
                    values['snapshot_systems'].append(vm)
                    if not does_user_have_system_permission(
                            vm['id'], 'snapshot'):
                        flash(
                            'You do not have permission to snapshot {}, please remove this from the list of systems and try again.'
                            .format(vm['name']), 'alert-danger')
                        error = True

        if error:
            return workflow.render_template('create.html',
                                            systems=systems,
                                            values=values)

        # Task Options
        options = {}
        options['wfconfig'] = workflow.config
        options['values'] = values

        # Everything should be good - start a task.
        neocortex = cortex.lib.core.neocortex_connect()
        task_id = neocortex.create_task(__name__,
                                        session['username'],
                                        options,
                                        description='Create a VMware Snapshot')

        # Redirect to the status page for the task
        return redirect(url_for('task_status', id=task_id))