Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
# Get the certificate
curd = g.db.cursor(mysql.cursors.DictCursor)
curd.execute('SELECT `subjectDN` FROM `certificate` WHERE `digest` = %s', (digest,))
certificate = curd.fetchone()
# If the certificate was not found then notify the user
if certificate is None:
raise Exception('Certificate does not exist')
# Update the certificate notify parameter
curd = g.db.cursor(mysql.cursors.DictCursor)
curd.execute('UPDATE `certificate` SET `notify` = NOT(`notify`) WHERE `digest` = %s', (digest,))
g.db.commit()
# Log
cortex.lib.core.log(__name__, "certificate.notify", "Certificate " + str(digest) + " (" + str(certificate['subjectDN']) + ") notification changed")
except Exception as e:
flash('Failed to change certificate notification: ' + str(e), category='alert-danger')
return redirect(url_for('certificate_edit', digest=digest))
elif request.form['action'] == 'save_notes':
# Get the certificate
curd = g.db.cursor(mysql.cursors.DictCursor)
curd.execute('SELECT `subjectDN` FROM `certificate` WHERE `digest` = %s', (digest,))
certificate = curd.fetchone()
# If the certificate was not found then return appropriate response
if certificate is None:
abort(404)
# Update the certificate notify parameter
curd = g.db.cursor(mysql.cursors.DictCursor)
# 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))
else:
abort(403)
def api_puppet_enc(certname):
"""Returns the YAML associated with the given node."""
# The request should contain a parameter in the headers which contains
# the autthentication pre-shared key. Validate this:
if 'X-Auth-Token' not in request.headers:
app.logger.warn('auth_token missing from Puppet ENC API request (certname: ' + certname + ')')
return abort(401)
if request.headers['X-Auth-Token'] != app.config['ENC_API_AUTH_TOKEN']:
app.logger.warn('Incorrect auth_token on request to Puppet ENC API (certname: ' + certname + ')')
return abort(401)
# Check that we've got a valid hostname
if not cortex.lib.core.is_valid_hostname(certname):
app.logger.warn('Invalid certname presented to Puppet ENC API (certname: ' + certname + ')')
abort(400)
# Generate the Puppet configuration
node_yaml = cortex.lib.puppet.generate_node_config(certname)
# If we don't get any configuration, return 404
if node_yaml is None:
return abort(404)
# Make a response and return it
r = make_response(node_yaml)
r.headers['Content-Type'] = "application/x-yaml"
return r
def api_register_system():
"""API endpoint for when systems register with Cortex to obtain their
Puppet certificates, their Puppet environment, a satellite registration
key, etc. Clients can authenticate either via username/password, which
is checked against LDAP, or via the VMware virtual machine UUID, which
is checked against the VMware systems cache."""
# Create a corpus (task helper) object
corpus = Corpus(g.db, app.config)
# Clients can send hostname, username and password (interactive installation)
if 'hostname' in request.form and 'username' in request.form and 'password' in request.form:
# Get the hostname and remove the domain portions, if any
# we want the 'short' hostname / the node name
hostname = cortex.lib.core.fqdn_strip_domain(request.form['hostname'])
# Match the hostname to a system record in the database
system = cortex.lib.systems.get_system_by_name(hostname)
if not system:
app.logger.warn('Could not locate host in systems table for register API (hostname: ' + hostname + ')')
abort(404)
# LDAP username/password authentication
if not cortex.lib.user.authenticate(request.form['username'], request.form['password']):
app.logger.warn('Incorrect username/password when registering ' + hostname + ', username: ' + request.form['username'] + ')')
abort(403)
# LDAP authorisation
if not cortex.lib.user.does_user_have_permission('api.register', request.form['username']):
app.logger.warn('User does not have permission when attempting to register ' + hostname + ', username: ' + request.form['username'] + ')')
"""Returns a CSV file, much like the /systems/download/csv but with API
auth rather than normal auth."""
# The request should contain a parameter in the headers which contains
# the authentication pre-shared key. Validate this:
if 'X-Auth-Token' not in request.headers:
app.logger.warn('auth_token missing from Systems API request')
return abort(401)
if request.headers['X-Auth-Token'] != app.config['CORTEX_API_AUTH_TOKEN']:
app.logger.warn('Incorrect auth_token on request to Systems API')
return abort(401)
# Get the list of systems
cur = cortex.lib.systems.get_systems(return_cursor=True)
cortex.lib.core.log(__name__, "api.systems.csv", "CSV of systems downloaded")
# Return the response as a downloadable CSV
return Response(cortex.lib.systems.csv_stream(cur), mimetype="text/csv", headers={'Content-Disposition': 'attachment; filename="systems.csv"'})
# Handle POST request
if request.method == "POST" and all(k in request.form for k in ["action", "environment_id"]):
environment_id = request.form["environment_id"]
if request.form["action"] == "delete_environment":
if not does_user_have_puppet_permission(environment_id, "delete", "puppet.environments.all.delete"):
abort(403)
elif "puppet" not in app.workflows:
return stderr("Unable to delete Puppet environment", "Error deleting Puppet environment, the workflow 'puppet' is required in order to delete Puppet environments, but was not found in app.workflows.")
else:
# Task Options
options = {
"actions": [{"id":"environment.delete", "desc": "Deleting Puppet Environment"}],
"values": {"environment_id": environment_id},
}
# Everything should be good - start a task.
neocortex = cortex.lib.core.neocortex_connect()
task_id = neocortex.create_task("puppet", session["username"], options, description="Delete Puppet Environment")
# Redirect to the status page for the task
return redirect(url_for("task_status", id=task_id))
else:
abort(400)
# Handle GET request
else:
# Get the database cursor
curd = g.db.cursor(mysql.cursors.DictCursor)
environments = []
permissions = []
if environment_id and does_user_have_puppet_permission(environment_id, "view", "puppet.environments.all.view"):
curd.execute("SELECT * FROM `puppet_environments` WHERE `id`=%s LIMIT 1", (environment_id,))
environments = curd.fetchall()
curd = g.db.cursor()
curd.execute("SELECT `id` FROM `puppet_environments` WHERE `environment_name`=%s", (values["environment_name"],))
if curd.fetchone():
error = True
flash("The environment name '{}' already exists".format(values["environment_name"]), "alert-danger")
if not error:
# Task Options
options = {
"wfconfig": workflow.config,
"actions": [{"id":"environment.create", "desc": "Creating Puppet Environment"}],
"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 Puppet Environment")
# Redirect to the status page for the task
return redirect(url_for("task_status", id=task_id))
return workflow.render_template("create.html", environment_types=environment_types, values=values, can_create_all=can_create_all)
def clear_session():
"""Ends the logged in user's login session. The session remains but it
is marked as being not logged in."""
if 'username' in session:
cortex.lib.core.log(__name__, 'cortex.logout', session['username'] + ' logged out using ' + request.user_agent.string)
# Remove the following items from the session
session.pop('logged_in', None)
session.pop('username', None)
session.pop('id', None)
session.pop('cas_ticket', None)
session.pop('_csrf_token', None)
"sandbox": "Create Sandbox Virtual Machine",
}.get(build_type, "Create Virtual Machine")
# Get the list of clusters
all_clusters = cortex.lib.core.vmware_list_clusters(get_build_config(build_type, "VCENTER_TAG"))
# Limit to the configured clusters
clusters = []
for cluster in all_clusters:
if cluster["name"] in get_build_config(build_type, "CLUSTERS"):
clusters.append(cluster)
# Get a list of folders for the standard build
folders = []
if build_type == "standard":
for folder in cortex.lib.core.vmware_list_folders(get_build_config(build_type, "VCENTER_TAG")):
if folder["name"] not in get_build_config(build_type, "HIDE_FOLDERS", []):
folders.append(folder)
folders.sort(key=lambda x: x["fully_qualified_path"])
# Get the list of environments
environments = cortex.lib.core.get_cmdb_environments()
if request.method == "GET":
# Get a list of Users
autocomplete_users = get_user_list_from_cache()
# Get the VM Specs from the DB
try:
vm_spec_json = cortex.lib.admin.get_kv_setting("vm.specs", load_as_json=True)
except ValueError:
def abort_on_missing_task():
if 'task' not in request.args:
abort(404)
# Check that the task exists
task = cortex.lib.core.task_get(request.args['task'])
if task is None:
abort(404)
if task['module'] != 'certmgr':
abort(400)
return task