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'])
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'])
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)
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)
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'])
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'])
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'])
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)
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)
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)
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
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
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
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)
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)
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")
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"))
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)
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)
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)
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")
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'])
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)
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)
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")
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)
# '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") ##############################################################################
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
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)
# '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,
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)
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)
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))