Skip to content
This repository has been archived by the owner on Jul 16, 2023. It is now read-only.

Sync with upstream #7

Open
wants to merge 75 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
75 commits
Select commit Hold shift + click to select a range
621809c
Create dhcp python package
sebastianrakel Jan 23, 2016
2cd5741
add docs for setting up isc-dhcp + ldap
bastelfreak Jan 23, 2016
862e122
Added base dhcp config
sebastianrakel Jan 26, 2016
0f1392f
Some LDAP Testing, but @bastelfreak forced me to push!
sebastianrakel Jan 26, 2016
24d45ad
Add dhcp to webserver
sebastianrakel Jan 26, 2016
f559454
Merge branch 'feat-isc-dhcp' of github.com:virtapi/marmoset into feat…
sebastianrakel Jan 26, 2016
a87d715
Added pip requirements
sebastianrakel Jan 26, 2016
2fcd69c
update pip requirements
sebastianrakel Jan 26, 2016
1a58d13
Added some validation functions for ip stuff (developed by @bastelfreak)
sebastianrakel Jan 27, 2016
4a0b4fd
Update Parameters for dhcp creation/update
sebastianrakel Jan 27, 2016
c366f73
Use networkmask and addentional statemetns from dhcp_config, not test…
sebastianrakel Jan 27, 2016
75c6195
Added ip validation and ip, networkmask, gateway export from cidr not…
sebastianrakel Jan 27, 2016
6d0f425
Remove dhcp hostname parameter
sebastianrakel Jan 27, 2016
fa0a094
Make __init__.py PEP8 conform
sebastianrakel Jan 27, 2016
84af84a
cleanup imports
sebastianrakel Jan 27, 2016
730854f
Make marmoset/webserver/dhcp.py imports PEP8 conform
sebastianrakel Jan 27, 2016
415e513
use camelcase for installimage
bastelfreak Jan 27, 2016
fbbc0a3
add DHCP options and missing PXE option
bastelfreak Jan 27, 2016
3102c3f
update setup notes to work with virtualenvs
bastelfreak Jan 27, 2016
206cf65
use env and not python3 directly
bastelfreak Jan 27, 2016
21fa7c0
add infos about DHCP endpoints
bastelfreak Jan 27, 2016
dfe784d
remove gunicorn notice, add uwsgi info
bastelfreak Jan 28, 2016
1479deb
remove redundant block, add more info about uwsgi
bastelfreak Jan 28, 2016
956367d
don't suggest /opt, use it
bastelfreak Jan 28, 2016
3ff748c
fix typo
bastelfreak Jan 28, 2016
7cdc025
fix sentence construction
bastelfreak Jan 28, 2016
5766b15
Added Methods to get LDAP DHCP Information
sebastianrakel Feb 5, 2016
a193eae
Added Methods to dhcp_config.py
sebastianrakel Feb 5, 2016
4dc70c9
Fix: Check in is_cidr that the given parameter contains a '/'
sebastianrakel Feb 5, 2016
677907e
Added correct implementation and checks of dhcp endpoint
sebastianrakel Feb 5, 2016
5b28305
Remove the additional Statement for dhcp endpoint from webserver __in…
sebastianrakel Feb 5, 2016
34ab1f7
Added a variable for the config
sebastianrakel Feb 5, 2016
53a7ddb
Change aweful variable name 'set_not_required_if_none' to 'allow_none…
sebastianrakel Feb 5, 2016
9b9ec41
Add Parameter check for creation of new configurations
sebastianrakel Feb 5, 2016
806077c
Merge pull request #36 from aibor/master
bastelfreak Feb 5, 2016
41f8842
add basic setup.py to distribute the project
bastelfreak Feb 5, 2016
911afd3
add tox support for basic lint checks
bastelfreak Feb 5, 2016
fa51762
add travis support
bastelfreak Feb 5, 2016
f9eb97b
Added some validation of parameters
sebastianrakel Feb 7, 2016
007c664
Fix conversion of ip objects
sebastianrakel Feb 7, 2016
8cd88d3
Added [Common] with FQDN option section to config.
sebastianrakel Feb 7, 2016
b3c514a
Use the new FQDN Config var for dhcp_hostname in dhcp_config
sebastianrakel Feb 7, 2016
4bb3d6f
Fix validation of ipv4
sebastianrakel Feb 7, 2016
94aa647
Fix PEP8 issues for DHCP Endpoint stuff
sebastianrakel Feb 7, 2016
f66963d
add missing webserver switch
bastelfreak Feb 7, 2016
f8d9fb7
Added check for empty response of ldap
sebastianrakel Feb 7, 2016
9c3351e
Fix: Check DN is not none before searching in ldap
sebastianrakel Feb 7, 2016
086502d
Merge branch 'feat-isc-dhcp' of github.com:virtapi/marmoset into feat…
sebastianrakel Feb 7, 2016
3775e5e
Fix validation of mac addresses
sebastianrakel Feb 7, 2016
eda91b6
fix linting and add support for sphinxs
bastelfreak Feb 9, 2016
db3b143
enable always linting + unit tests
bastelfreak Feb 9, 2016
35d4921
disable join messages
bastelfreak Feb 9, 2016
df01a68
enable more python versions via virtualenv
bastelfreak Feb 9, 2016
9e16f48
Merge pull request #37 from virtapi/feature-travis2
sebastianrakel Feb 9, 2016
afc87e1
add info about our own nspawn image
bastelfreak Feb 11, 2016
b236da1
update URL to containeupdate URL to containerr
bastelfreak Feb 11, 2016
f89aad7
add --verify=no param to machinectl
bastelfreak Feb 11, 2016
7361b01
Added multi parameter to get multiple mac/ip DNs
sebastianrakel Feb 13, 2016
72f7a61
Seperate remove in mac and ip function, also returns the count of fou…
sebastianrakel Feb 13, 2016
89e6126
Seperate remove in remove_by_ipv4 and remove_by_mac, also added remov…
sebastianrakel Feb 13, 2016
6bcc23a
Fix: macs will now be removed by mac and not by founded ip
sebastianrakel Feb 13, 2016
dc26635
Fix: Return messages now response in json format
sebastianrakel Feb 13, 2016
9b0dec8
add [install] section to marmoset.service
bastelfreak Feb 15, 2016
916fe1b
Merge pull request #46 from virtapi/update-systemd-service
sebastianrakel Feb 15, 2016
304396c
Merge pull request #31 from virtapi/feat-isc-dhcp
bastelfreak Feb 15, 2016
856e102
update port, add infos about DHCP endpoint
bastelfreak Feb 15, 2016
a2beb99
add notice about system packages
bastelfreak Feb 15, 2016
4092ea8
update search_base_dn
bastelfreak Feb 15, 2016
8b77b8c
update ldap_client_base_dn to match the dhcpGroup
bastelfreak Feb 15, 2016
609deac
remove HEG urls
bastelfreak Feb 15, 2016
bdcce0d
fix markup typo
bastelfreak Feb 15, 2016
5b45136
fix ordering in ldap_client_base_dn
bastelfreak Feb 15, 2016
efc36a6
Merge pull request #32 from virtapi/update-docs
bastelfreak Feb 15, 2016
1b99ef8
set correct ServerName in example conf
bastelfreak Feb 15, 2016
b619f80
Merge pull request #47 from virtapi/improve-docs
sebastianrakel Feb 15, 2016
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
---
sudo: required
dist: trusty
language: python
python:
- "3.3"
- "3.4"
- "3.5"
before_install:
- sudo apt-get update -q
- sudo apt-get -y install libvirt-bin libvirt-dev
install:
- pip install tox
script:
- tox -e lint
- tox -e testxunit
notifications:
irc:
on_success: change
on_failure: always
skip_join: true
channels:
- "irc.freenode.org#virtapi"
email: false
184 changes: 176 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ Monkeying around with virtual machines and pxe configs.
- [HTTP PXE](#http-pxe)
- [HTTP VM](#http-vm)
- [HTTP installimage](#http-installimage)
- [HTTP DHCP](#http-dhcp)
+ [Issues](#issues)
+ [Copyright](#copyright)
+ [Name origin](#name-origin)
Expand All @@ -24,10 +25,26 @@ Monkeying around with virtual machines and pxe configs.

## Setup

Create `marmoset.conf` before using marmoset! See `Configuration` for details.
Clone the repo into /opt, then copy the service file into the systemd directory and reload systemd to recognize the file:
```bash
cd /opt
git clone https://github.com/virtapi/marmoset.git
cd marmoset
cp ext/marmoset.service /etc/systemd/system/
systemctl daemon-reload
```
Copy the `marmoset.conf.example` to `marmoset.conf` and adjust the settings to your needs.
Checkout the Comments in the file our our [Configuration](#configuration) section.

Now we need to setup a virtualenv and install the required python packages (remove libvirt from the requirements.txt and `pkg-config libvirt gcc` from the list of packages to install if you don't want to manage VMs with marmoset):
```bash
pacman -Syu python-virtualenv pkg-config libvirt gcc
virtualenv prod
source prod/bin/activate
pip install --upgrade pip
pip install -r requirements.txt
```

---

## Requirements
Expand All @@ -49,6 +66,7 @@ Please checkout our [requirements.txt](requirements.txt) for a complete and auth
* wheel

In addition to these python packages, you also need Python 3. This project originally started with Python 3.3, we are currently developing and testing on 3.5 but we plan to support Python 3.3 and 3.4 as well.
We also need pkg-config and libvirt, which you need to install via your system-wide package manager (these aren't python packages).

---

Expand Down Expand Up @@ -128,9 +146,11 @@ Start it like this:

$ ./marmoset.py server

Or with gunicorn:
Or use our systemd service:

$ systemctl start marmoset

$ gunicorn marmoset.app:app
A third solution is to use nginx + uwsgi to power the app. This is the recommended way if you expect a high amount of requests.

### HTTP PXE

Expand Down Expand Up @@ -381,7 +401,7 @@ Remove a VM:
This endpoint is meant to work together with our [installimage](https://github.com/virtapi/installimage). We identify each dataset by its MAC address and store the key:value config pairs for the installimage.

#### List Entries
curl -u admin:secret http://localhost:8080/v1/installimage
curl -u admin:secret http://localhost:5000/v1/installimage

```json
[
Expand Down Expand Up @@ -414,7 +434,7 @@ This endpoint is meant to work together with our [installimage](https://github.c
```

#### List a single Entry
curl -u admin:secret http://localhost:8080/v1/installimage/b8:ac:6f:97:7e:77
curl -u admin:secret http://localhost:5000/v1/installimage/b8:ac:6f:97:7e:77

```json
{
Expand All @@ -434,7 +454,7 @@ This endpoint is meant to work together with our [installimage](https://github.c
```

#### List a single Entry in the installimage format
curl -u admin:secret http://localhost:8080/v1/installimage/b8:ac:6f:97:7e:77/config
curl -u admin:secret http://localhost:5000/v1/installimage/b8:ac:6f:97:7e:77/config

```
PART / ext4 all
Expand All @@ -449,7 +469,7 @@ HOSTNAME CentOS-71-64-minimal
```

#### Create a record
curl -u admin:secret --data "drive1=/dev/sda&bootloader=grub&hostname=CentOS-71-64-minimal&PART=/ ext4 all&image=/root/.installimage/../images/CentOS-71-64-minimal.tar.gz" http://localhost:8080/v1/installimage/b8:ac:6f:97:7e:77
curl -u admin:secret --data "drive1=/dev/sda&bootloader=grub&hostname=CentOS-71-64-minimal&PART=/ ext4 all&image=/root/.installimage/../images/CentOS-71-64-minimal.tar.gz" http://localhost:5000/v1/installimage/b8:ac:6f:97:7e:77

Returns the created record:
```json
Expand All @@ -470,7 +490,7 @@ Returns the created record:
```

#### Delete a Record
curl -u admin:secret -X DELETE http://localhost:8080/v1/installimage/b8:ac:6f:97:7e:77
curl -u admin:secret -X DELETE http://localhost:5000/v1/installimage/b8:ac:6f:97:7e:77

Errormessage if you want to delete or list a nonexistent entry:
```json
Expand All @@ -479,8 +499,156 @@ Errormessage if you want to delete or list a nonexistent entry:
}
```

### HTTP DHCP
This endpoint allows us the throw static IP/MAC combinations into a ldap database. Currently tested is only the [openldap](http://www.openldap.org/) backend. This database is connected to an isc-dhcpd. We can identify an object by its IP or MAC address.

#### List Entries
curl -u admin:secret http://localhost:5000/v1/dhcp
```json
[
{
"additional_statements": {},
"dhcp_hostname": "odin.fritz.box",
"gateway": "192.168.10.1",
"ip_address": "192.168.10.5",
"mac": "00:00:00:00:00:00",
"networkmask": "255.255.255.0"
},
{
"additional_statements": {},
"dhcp_hostname": "odin.fritz.box",
"gateway": "10.3.7.1",
"ip_address": "10.3.7.41",
"mac": "00:00:00:00:00:00",
"networkmask": "255.255.255.0"
}
]
```

#### List One Entry based on MAC
curl -u admin:secret http://localhost:5000/v1/dhcp/mac/00:00:00:00:00:00
```json
{
"additional_statements": {},
"dhcp_hostname": "odin.fritz.box",
"gateway": "10.3.7.1",
"ip_address": "10.3.7.41",
"mac": "00:00:00:00:00:00",
"networkmask": "255.255.255.0"
}
```

or:
curl -u admin:secret http://localhost:5000/v1/dhcp/mac/23.45.67.8
```
"please provide a valid mac address"
```

#### List one Entry based on IP
curl -u admin:secret http://localhost:5000/v1/dhcp/ipv4/10.3.7.41
```json
{
"additional_statements": {},
"dhcp_hostname": "odin.fritz.box",
"gateway": "10.3.7.1",
"ip_address": "10.3.7.41",
"mac": "00:00:00:00:00:00",
"networkmask": "255.255.255.0"
}
```

or:
curl -u admin:secret http://localhost:5000/v1/dhcp/ipv4/23.45.67.888
```
"please provide a valid ipv4 address"
```

#### Create a new Entry:
this will return the new created entry:
curl -u admin:secret --data 'ip_address=10.3.7.41&mac=b8:ac:6f:97:7e:77&gateway=10.3.7.1&networkmask=255.255.255.0' http://localhost:5000/v1/dhcp
```json
{
"additional_statements": {},
"dhcp_hostname": "example.com",
"gateway": "10.3.7.1",
"ip_address": "10.3.7.41",
"mac": "b8:ac:6f:97:7e:77",
"networkmask": "255.255.255.0"
}
```

an update works the same way, just submit the command again and change new updated params, again the API will respond with the updated entry.

#### Delete an Entry:
curl -u admin:secret -X DELETE http://localhost:5000/v1/dhcp/ipv4/10.3.7.41

Deleting a nonexistent entry:
curl -u admin:secret -X DELETE http://localhost:5000/v1/dhcp/ipv4/10.3.7.41

will return:
```json
{
"message": "The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again. You have requested this URI [/v1/dhcp/ipv4/10.3.7.41] but did you mean /v1/dhcp/ipv4/<ipv4> ?"
}
```

---

## Setup LDAP + isc-dhcpd
We will do all this in a clean Arch nspawn container (login for a new container is always root without password):
```bash
mkdir marmoset_container
sudo pacman -Syu arch-install-scripts
sudo pacstrap -c -d marmoset_container
sudo systemd-nspawn -b -D marmoset_container/
pacman -Syu git openldap
```

Installing the isc-dhcpd is currently a bit tricky because the default package is not linked against ldap. You can get the sources and replace the PKGBUILD with [mine](https://p.bastelfreak.de/U6f5/) or use the package that I [built](https://p.bastelfreak.de/C6An/). The needed data can be found [here](https://p.bastelfreak.de/t5XS/). Please adjust the params `suffix` and `rootdn` for your needs (in /etc/openldap/slapd.conf), we use `dc=example,dc=com` and `cn=root,dc=example,dc=com` in our example.

```bash
curl -JO https://p.bastelfreak.de/C6An/
pacman -U dhcp*.pkg.tar.xz
cd /etc/openldap/schema
curl -JO https://raw.githubusercontent.com/dcantrell/ldap-for-dhcp/master/dhcp.schema
cd ..
echo 'include /etc/openldap/schema/dhcp.schema' >> slapd.conf
echo 'index dhcpHWAddress eq' >> slapd.conf
echo 'index dhcpClassData eq' >> slapd.conf
cp DB_CONFIG.example /var/lib/openldap/openldap-data/DB_CONFIG
curl https://p.bastelfreak.de/j63 > initial_data.ldif
systemctl start slapd
ldapadd -x -W -D 'cn=root,dc=example,dc=com' -f initial_data.ldif -c
```

Last step, you need to add the following settings to your `/etc/dhcpd.conf` before you start the daemon:
```
ldap-server "localhost";
ldap-port 389;
ldap-username "cn=root, dc=example, dc=com";
ldap-password "secret";
ldap-base-dn "dc=example, dc=com";
ldap-method dynamic;
ldap-debug-file "/var/log/dhcp-ldap-startup.log";
```

```bash
systemctl start dhcpd4.service
```

We also provide a prepacked nspawn container. It has a working openldap + DHCP server,
the openldap is configured to start at boot. Systemd is so awesome that it supports downloading the tar,
so no fiddeling with curl/wget. machinectl will throw the image into a btrfs subvol and requires you to run /var/lib/machines on btrfs:
```bash
pacman -Syu btrfs-progs
modprobe loop
machinectl --verify=no pull-tar https://bastelfreak.de/marmoset_container.tar marmoset_container
machinectl start marmoset_container
machinectl login marmoset_container
```

If you don't run btrfs you can still download the tar to /var/lib/machines, extract it by hand and then continue with the machinectl commands (or start it oldschool like with systemd-nspawn).

## Issues

Find this code at [the git repo](https://www.github.com/virtapi/marmoset/). Find the original code at [the git repo](https://www.aibor.de/cgit/marmoset/).
Expand Down
3 changes: 3 additions & 0 deletions ext/marmoset.service
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,6 @@ ExecStart=/opt/marmoset/marmoset.py server
User=marmoset
Group=marmoset
PrivateTmp=true

[Install]
WantedBy=multi-user.target
20 changes: 18 additions & 2 deletions marmoset.conf.example
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@
[Modules]
PXE: True
VM: True
INSTALLIMAGE: True
Webserver: True
Installimage: True
DHCP: True

[Webserver]
# Settings for HTTP Basic Auth
Expand All @@ -18,7 +20,7 @@ Port: 5000
# Domain that is used by clients to address the server. It is used to
# build absolute urls. If unset, it defaults to 'localhost'.
# take a look here about the syntax: http://stackoverflow.com/a/23312820
ServerName:
ServerName: localhost:5000
Debug: False

[Libvirt]
Expand All @@ -34,9 +36,13 @@ Network:
# storage name is given.
Storage:

# this will be used for storing PXE options
[PXEConfig]
ConfigDirectory: /srv/tftp/pxelinux.cfg/

# this will be used for storing installimage options
[Config]
ConfigDirectory: /srv/tftp/config/
# The PXELabel section has no defaults, as its entries depend on
# the PXE configuration. The syntax is `label: callbackmethod`.
# If the entry doesn't need any callback, just let callbackmethod
Expand All @@ -47,3 +53,13 @@ ConfigDirectory: /srv/tftp/pxelinux.cfg/
#freebsd: createpwhashfile
#openbsd:

[DHCPConfig]
# list of all statements that we allow
# see https://github.com/virtapi/marmoset/issues/7#issuecomment-175262281
# and see https://github.com/virtapi/marmoset/issues/7#issuecomment-175275522
additional_statements = option domain-name-servers,option domain-name,max-lease-time,default-lease-time,option ntp-servers
ldap_server = localhost
ldap_port = 389
ldap_bind_dn = cn=root,dc=example,dc=com
ldap_passwort = secret
ldap_client_base_dn = cn=static,cn=DHCP Service Config,dc=example,dc=com
2 changes: 1 addition & 1 deletion marmoset.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!/usr/bin/python3
#!/usr/bin/env python3

import marmoset

Expand Down
7 changes: 5 additions & 2 deletions marmoset/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
from . import config, cli
from marmoset import config
from marmoset import cli
from marmoset import validation

def run(config_file = None):

def run(config_file=None):
cfg = config.load(config_file)
cli.parse(cfg)

4 changes: 3 additions & 1 deletion marmoset/app.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
from . import config, webserver

app = webserver.app(config.load())
config = config.load()

app = webserver.app(config)

8 changes: 7 additions & 1 deletion marmoset/config.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
from os import path
import configparser, warnings
import configparser
import warnings
import socket

PATH = path.join(path.dirname(__file__), '../marmoset.conf')

def default():
config = configparser.ConfigParser()

config['Common'] = dict(
FQDN=socket.getfqdn()
)

config['Modules'] = dict(
Webserver = 'True',
PXE = 'True',
Expand Down
2 changes: 2 additions & 0 deletions marmoset/dhcp/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
from .dhcp_config import DhcpConfig
from .isc_dhcp_ldap_config import ISCDhcpLdapConfig
Loading