Skip to content

Commit

Permalink
Build product archives for easier enrollment
Browse files Browse the repository at this point in the history
* Option to include a santa release in the enrollment pkg
* Option to include an osquery release in the enrollment pkg
* SimpleMDM contrib app to manage enrollment pkg
* Other little fixes (flake8, django version, …)
  • Loading branch information
np5 committed Apr 10, 2017
1 parent bb82cdd commit 7d7ce37
Show file tree
Hide file tree
Showing 36 changed files with 1,244 additions and 351 deletions.
10 changes: 4 additions & 6 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
*/__pycache__*
.git/*
.gitignore
/conf/*
/docs/*
/fabfile.*
/tests/*
/venv/*
/wheels/*
./conf/*
./docs/*
./tests/*
./venv/*
5 changes: 4 additions & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM python:3.4
FROM python:3.6
ENV PYTHONUNBUFFERED 1

MAINTAINER Éric Falconnier <eric.falconnier@112hz.com>
Expand All @@ -19,6 +19,9 @@ RUN curl -fsSL https://github.com/mackyle/xar/archive/xar-1.6.1.tar.gz | tar xvz
# xmlsec1 for PySAML2
RUN apt-get install -y xmlsec1

# p7zip to extract dmg
RUN apt-get install -y p7zip-full

# zentral user and group
RUN groupadd -r zentral --gid=999 && useradd -r -s /bin/false -g zentral --uid=999 zentral

Expand Down
1 change: 1 addition & 0 deletions conf/start/zentral/base.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
]
},
"zentral.contrib.jamf": {},
"zentral.contrib.simplemdm": {},
"zentral.contrib.munki": {},
"zentral.contrib.nagios": {},
"zentral.contrib.osquery": {},
Expand Down
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
pip
setuptools
coverage
django
django<1.11
requests
ipython
psycopg2
Expand Down
2 changes: 1 addition & 1 deletion server/base/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ def get_context_data(self, **kwargs):
context = super(IndexView, self).get_context_data(**kwargs)
app_list = []
for app_name, app_config in apps.app_configs.items():
if hasattr(app_config, "events_module"):
if getattr(app_config, "events_module", None) is not None:
app_list.append(app_name)
app_list.sort()
context["apps"] = app_list
Expand Down
23 changes: 23 additions & 0 deletions server/templates/simplemdm/simplemdmapp_form.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{% extends 'base.html' %}
{% load bootstrap %}

{% block content %}
<ol class="breadcrumb">
<li><a href="/">Home</a></li>
<li><a href="{% url 'simplemdm:simplemdm_instances' %}">simplemdm instances</a></li>
<li><a href="{% url 'simplemdm:simplemdm_instance' simplemdm_instance.id %}">{{ simplemdm_instance }}</a></li>
<li class="active">{{ title }}</li>
</ol>

<h2>{{ title }}</h2>

<h3>{{ builder_name }}</h3>

<form method="POST">{% csrf_token %}
{{ form|bootstrap }}
<p>
<a href="{% url 'simplemdm:simplemdm_instance' simplemdm_instance.id %}" class="btn btn-default">Cancel</a>
<button class="btn btn-primary">Create and push app</button>
</p>
</form>
{% endblock %}
21 changes: 21 additions & 0 deletions server/templates/simplemdm/simplemdminstance_confirm_delete.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{% extends 'base.html' %}
{% load bootstrap %}

{% block content %}
<ol class="breadcrumb">
<li><a href="/">Home</a></li>
<li><a href="{% url 'simplemdm:simplemdm_instances' %}">simplemdm instances</a></li>
<li class="active">{{ title }}</li>
</ol>

<h2>{{ title }}</h2>

<form method="POST">{% csrf_token %}
<p>Do you really want to delete this SimpleMDM instance ?</p>
<p>
<a href="{% url 'simplemdm:simplemdm_instances' %}" class="btn btn-default">Cancel</a>
<button class="btn btn-danger">Delete</button>
</p>
</form>

{% endblock %}
49 changes: 49 additions & 0 deletions server/templates/simplemdm/simplemdminstance_detail.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
{% extends 'base.html' %}
{% load base_extras bootstrap %}

{% block content %}
<ol class="breadcrumb">
<li><a href="/">Home</a></li>
<li><a href="{% url 'simplemdm:simplemdm_instances' %}">simplemdm instances</a></li>
<li class="active">{{ title }}</li>
</ol>

<h2>{{ title }}</h2>


<h3>{{ app_number }} App{{ app_number|pluralize }}</h3>

<div class="dropdown">
<button class="btn btn-default dropdown-toggle" type="button" id="createSimpleMDMApp"
data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
Create
<span class="caret"></span>
</button>
<ul class="dropdown-menu" aria-labelledby="createSimpleMDMApp">
{% for link, anchor_text in create_app_links %}
<li><a href="{{ link }}">{{ anchor_text }}</a></li>
{% endfor %}
</ul>
</div>


<table class="table">
<thead>
<tr>
<th>Build</th>
<th>Created at</th>
</tr>
</thead>
<tbody>
{% for app in apps %}
<tr>
<td>
<p>{{ app.get_builder_class.name }}</p>
{{ app.build_kwargs|pythonprettyprint }}
</td>
<td>{{ app.created_at }}</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endblock %}
20 changes: 20 additions & 0 deletions server/templates/simplemdm/simplemdminstance_form.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{% extends 'base.html' %}
{% load bootstrap %}

{% block content %}
<ol class="breadcrumb">
<li><a href="/">Home</a></li>
<li><a href="{% url 'simplemdm:simplemdm_instances' %}">simplemdm instances</a></li>
<li class="active">{{ title }}</li>
</ol>

<h2>{{ title }}</h2>

<form method="POST">{% csrf_token %}
{{ form|bootstrap }}
<p>
<a href="{% url 'simplemdm:simplemdm_instances' %}" class="btn btn-default">Cancel</a>
<button class="btn btn-primary">Save</button>
</p>
</form>
{% endblock %}
50 changes: 50 additions & 0 deletions server/templates/simplemdm/simplemdminstance_list.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
{% extends 'base.html' %}
{% load bootstrap %}

{% block content %}
<ol class="breadcrumb">
<li><a href="/">Home</a></li>
<li class="active">{{ title }}</li>
</ol>

<h2>{{ title }}</h2>

<p>
<a href="{% url 'simplemdm:create_simplemdm_instance' %}" class="btn btn-default">Create</a>
</p>

<table class="table">
<thead>
<tr>
<th>Business unit</th>
<th>Account name</th>
<th>API key</th>
<th></th>
</tr>
</thead>
<tbody>
{% for simplemdm_instance in object_list %}
<tr>
<td>
<a href="{% url 'inventory:mbu_machines' simplemdm_instance.business_unit.meta_business_unit.id %}">
{{ simplemdm_instance.business_unit }}
</a>
</td>
<td>{{ simplemdm_instance.account_name }}</td>
<td><pre>{{ simplemdm_instance.api_key }}</pre></td>
<td>
<a href="{% url 'simplemdm:simplemdm_instance' simplemdm_instance.pk %}" class="btn btn-default">
<span class="glyphicon glyphicon-cog" aria-hidden="true"></span>
</a>
<a href="{% url 'simplemdm:update_simplemdm_instance' simplemdm_instance.pk %}" class="btn btn-default">
<span class="glyphicon glyphicon-edit" aria-hidden="true"></span>
</a>
<a href="{% url 'simplemdm:delete_simplemdm_instance' simplemdm_instance.pk %}" class="btn btn-danger">
<span class="glyphicon glyphicon-trash" aria-hidden="true"></span>
</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endblock %}
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ SAL_BUNDLE_ID = "com.salsoftware.sal"
SAL_KEY_PREFERENCE = "enrolment_key"
SAL_SERVER_PREFERENCE = "ServerURL"

USER_AGENT = "Zentral/mnkpf 0.1"
USER_AGENT = "Zentral/mnkpf 0.2"
ZENTRAL_API_ENDPOINT = "https://%TLS_HOSTNAME%/munki/"
ZENTRAL_API_SERVER_CERTIFICATE = "%TLS_SERVER_CERTS%"
ZENTRAL_API_SECRET_HEADER = "Zentral-API-Secret"
Expand Down Expand Up @@ -288,7 +288,7 @@ def make_api_request(url, data=None):
data = json.dumps(data)
req.add_header('Content-Type', 'application/json')
data = zlib.compress(data, 9)
req.add_header('Content-Encoding', 'gzip')
req.add_header('Content-Encoding', 'deflate')
if ZENTRAL_API_SERVER_CERTIFICATE:
ctx = ssl.create_default_context(cafile=ZENTRAL_API_SERVER_CERTIFICATE)
else:
Expand Down
32 changes: 12 additions & 20 deletions zentral/contrib/munki/osx_package/builder.py
Original file line number Diff line number Diff line change
@@ -1,33 +1,25 @@
import os
import shutil
from zentral.utils.osx_package import PackageBuilder
from zentral.utils.osx_package import EnrollmentForm, PackageBuilder

BASE_DIR = os.path.dirname(os.path.abspath(__file__))


class MunkiZentralEnrollPkgBuilder(PackageBuilder):
name = "Zentral Munki Enrollment"
form = EnrollmentForm
zentral_module = "zentral.contrib.munki"
package_name = "zentral_munki_enroll.pkg"
package_identifier = "io.zentral.munki_enroll"
base_package_identifier = "io.zentral.munki_enroll"
build_tmpl_dir = os.path.join(BASE_DIR, "build.tmpl")

def include_tls_server_certs(self, tls_server_certs):
tls_server_certs_rel_path = "usr/local/zentral/tls_server_certs.crt"
# copy crt in build dir
shutil.copy(tls_server_certs,
self.get_root_path(tls_server_certs_rel_path))
return "/{}".format(tls_server_certs_rel_path)

def extra_build_steps(self, tls_hostname, api_secret, tls_server_certs):
patterns = [("%TLS_HOSTNAME%", tls_hostname),
("%API_SECRET%", api_secret)]
if tls_server_certs:
if not os.path.exists(tls_server_certs):
raise ValueError("tls_server_certs file {} is not readable".format(tls_server_certs))
tls_server_certs_install_path = self.include_tls_server_certs(tls_server_certs)
else:
tls_server_certs_install_path = ""
def extra_build_steps(self):
# munki zentral postflight script
patterns = [("%TLS_HOSTNAME%", self.get_tls_hostname()),
("%API_SECRET%", self.make_api_secret())]
tls_server_certs_install_path = self.include_tls_server_certs()
patterns.append(("%TLS_SERVER_CERTS%", tls_server_certs_install_path))
postflight_script = self.get_root_path("usr/local/zentral/munki/zentral_postflight")
self.replace_in_file(postflight_script, patterns)
# postinstall script
postinstall_script = self.get_build_path("scripts", "postinstall")
self.replace_in_file(postinstall_script, (("%TLS_HOSTNAME%", tls_hostname),))
self.replace_in_file(postinstall_script, (("%TLS_HOSTNAME%", self.get_tls_hostname()),))
1 change: 1 addition & 0 deletions zentral/contrib/munki/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@


class EnrollmentView(LoginRequiredMixin, BaseEnrollmentView):
builder = MunkiZentralEnrollPkgBuilder
template_name = "munki/enrollment.html"


Expand Down
17 changes: 11 additions & 6 deletions zentral/contrib/osquery/deb_script/builder.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,25 @@
import os
from django.http import HttpResponse
from zentral.utils.osx_package import EnrollmentForm, APIConfigToolsMixin

BASE_DIR = os.path.dirname(os.path.abspath(__file__))


class OsqueryZentralEnrollScriptBuilder(object):
class OsqueryZentralEnrollScriptBuilder(APIConfigToolsMixin):
form = EnrollmentForm
zentral_module = "zentral.contrib.osquery"
script_name = "osquery_zentral_setup.sh"
with_package_signature = False

def build_and_make_response(self, business_unit, tls_hostname, enroll_secret_secret, tls_server_certs):
def __init__(self, business_unit, **kwargs):
self.business_unit = business_unit

def build_and_make_response(self):
template_path = os.path.join(BASE_DIR, "template.sh")
with open(template_path, "r") as f:
content = f.read()
content = content.replace("%TLS_HOSTNAME%", tls_hostname)
content = content.replace("%ENROLL_SECRET_SECRET%", enroll_secret_secret)
with open(tls_server_certs, "r") as f:
content = content.replace("%TLS_HOSTNAME%", self.get_tls_hostname())
content = content.replace("%ENROLL_SECRET_SECRET%", self.make_api_secret())
with open(self.get_tls_server_certs(), "r") as f:
tls_server_certs_data = f.read()
content = content.replace("%TLS_SERVER_CERTS%", tls_server_certs_data)
response = HttpResponse(content, "text/x-shellscript")
Expand Down
Loading

0 comments on commit 7d7ce37

Please sign in to comment.