// puppet_enc_edit [python]
@app.route('/puppet/enc/<node>', methods=['GET', 'POST'])
@cortex.lib.user.login_required
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)

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