]> WPIA git - infra.git/commitdiff
add: motion system from source
authorFelix Dörre <felix@dogcraft.de>
Sat, 22 Dec 2018 12:19:16 +0000 (13:19 +0100)
committerFelix Dörre <felix@dogcraft.de>
Sun, 6 Jan 2019 15:03:15 +0000 (16:03 +0100)
Change-Id: I3d69d1c6d8870df39699f079642100b7b1201654

15 files changed:
commands
environments/production/manifests/ip.pp
environments/production/manifests/motion.pp [new file with mode: 0644]
environments/production/manifests/nginx.pp
manager/admin-manage-certificates
modules/motion/.gitignore [new file with mode: 0644]
modules/motion/README [new file with mode: 0644]
modules/motion/files/.gitignore [new file with mode: 0644]
modules/motion/files/motion.ini [new file with mode: 0644]
modules/motion/files/motion.service [new file with mode: 0644]
modules/motion/files/user_map.template.epp [new file with mode: 0644]
modules/motion/manifests/container.pp [new file with mode: 0644]
modules/motion/manifests/virtual.pp [new file with mode: 0644]
modules/motion/templates/config.py.epp [new file with mode: 0644]
modules/motion/templates/nginx.epp [new file with mode: 0644]

index 531e973e0e1113565f74515476418e10aeb92be9..aa2f8087a93a4f1fb5775e9eabf4b7f59f1dbcea 100755 (executable)
--- a/commands
+++ b/commands
@@ -50,6 +50,7 @@ if [[ $com == "update certs" || $com == "force update certs" ]]; then
     update_cert "modules/gigi/files/gigi"
     update_cert "modules/gigi/files/client"
     update_cert "modules/gitweb/files/web"
+    update_cert "modules/motion/files/motion"
     echo "DONE"
     [[ -f $folder/web.crt ]] && rm $folder/web.crt
     [[ -f $folder/web.req ]] && rm $folder/web.req
index 944a6fca673f8016dbb6b7d8902a300541998ea8..dd510b18424dd6cc5c1173f5ae049b3710e865d1 100644 (file)
@@ -6,6 +6,7 @@ $ips = {
    hop => '10.0.3.18',
    quiz => '10.0.3.19',
    postgres => '10.0.3.14',
+   motion => '10.0.3.22',
    gitweb => '10.0.3.20'}
 
 $ipsv6 = {
@@ -17,6 +18,7 @@ $ipsv6 = {
    exim => 'fc00:1::11',
    hop => 'fc00:1::12',
    quiz => 'fc00:1::13',
+   motion => 'fc00:1::16',
    gitweb => 'fc00:1::14'}
 
 $passwords = {
diff --git a/environments/production/manifests/motion.pp b/environments/production/manifests/motion.pp
new file mode 100644 (file)
index 0000000..307b870
--- /dev/null
@@ -0,0 +1,8 @@
+motion::virtual{'motion':
+}
+
+node motion{
+  class{'motion::container':
+    container => 'motion'
+  }
+}
index 9b9c5613cf509479a3f63be3c4ff2300a6cd243d..db81cc5177f00fec1db11c766e6c856856956e5d 100644 (file)
@@ -1,4 +1,4 @@
-define front_vhost($source, $crt = undefined){
+define front_vhost($source, $crt = undefined, $args = {}){
   if $crt {
     file{"/etc/ssl/private/$name.crt":
       ensure => 'file',
@@ -16,7 +16,7 @@ define front_vhost($source, $crt = undefined){
   }
   file {"/etc/nginx/sites-available/$name.conf":
     ensure => 'file',
-    content => epp($source),
+    content => epp($source, $args),
     require => Package['nginx-light'],
   }->
   file {"/etc/nginx/sites-enabled/$name.conf":
index 2a6c4c0c7ddcf54c0c5c41b1680bf928cc3ad36c..634aa7f641fca686933cd6debfe731665f5c4bba 100755 (executable)
@@ -98,6 +98,9 @@ while true; do
             "modules/quiz/files/client")
                 options="profile=client-orga&CN=Quiz+Api+User&SANs=quiz@$domain"
                 ;;
+            "modules/motion/files/motion")
+                options="profile=server-orga&CN=&SANs=motion.$domain"
+                ;;
             *)
                 echo "Unknown certificate in $line, rejecting"
                 echo "FAIL" >&${COPROC[1]}
diff --git a/modules/motion/.gitignore b/modules/motion/.gitignore
new file mode 100644 (file)
index 0000000..5c9671b
--- /dev/null
@@ -0,0 +1,4 @@
+/files/motion-roots.pem
+/files/web.crt
+/files/web.key
+/templates/user_map.epp
diff --git a/modules/motion/README b/modules/motion/README
new file mode 100644 (file)
index 0000000..d4987f4
--- /dev/null
@@ -0,0 +1,3 @@
+Usage:
+- Put list of allowed root-pem files in "files/motion-roots.pem"
+- Add allowed certificates with usernames and privileges to "templates/user_map.epp" which can be initialized with a copy of "templates/user_map.template.epp"
diff --git a/modules/motion/files/.gitignore b/modules/motion/files/.gitignore
new file mode 100644 (file)
index 0000000..41b8c56
--- /dev/null
@@ -0,0 +1 @@
+user_map.epp
diff --git a/modules/motion/files/motion.ini b/modules/motion/files/motion.ini
new file mode 100644 (file)
index 0000000..20fead5
--- /dev/null
@@ -0,0 +1,6 @@
+[uwsgi]
+fastcgi-socket=/motion-socket/motion.fcgi
+chmod-socket=666
+virtualenv=/home/motion/motion
+master=True
+mount=/=motion:app
diff --git a/modules/motion/files/motion.service b/modules/motion/files/motion.service
new file mode 100644 (file)
index 0000000..e4ed3b4
--- /dev/null
@@ -0,0 +1,20 @@
+[Unit]
+Description=Motion uWSGI app
+After=syslog.target
+
+[Service]
+ExecStart=/home/motion/motion/bin/uwsgi --ini ../motion.ini
+User=motion
+Group=motion
+Restart=on-failure
+KillSignal=SIGQUIT
+Type=notify
+StandardError=journal
+NotifyAccess=all
+WorkingDirectory=/home/motion/motion
+PrivateTmp=yes
+PrivateDevices=yes
+ProtectSystem=strict
+ProtectHome=no
+ReadOnlyPaths=/home
+ReadWritePaths=/home/motion/motion/__pycache__/ /motion-socket
diff --git a/modules/motion/files/user_map.template.epp b/modules/motion/files/user_map.template.epp
new file mode 100644 (file)
index 0000000..064f5be
--- /dev/null
@@ -0,0 +1,6 @@
+map_hash_bucket_size 128;
+
+# user map
+map "$ssl_client_serial:$ssl_client_i_dn" $<%=$container%>_user_role {
+    default     "<invalid>/";
+}
diff --git a/modules/motion/manifests/container.pp b/modules/motion/manifests/container.pp
new file mode 100644 (file)
index 0000000..86ecc38
--- /dev/null
@@ -0,0 +1,82 @@
+class motion::container($container){
+  include container::contained;
+  include container::no_ssh;
+
+  package{ ['python3', 'python3-pip',  'virtualenv', 'libpq-dev']:
+    ensure => 'installed'
+  }
+  user{'motion':
+    ensure => present,
+    home => '/home/motion',
+    system => 'yes'
+  } ->
+  file{'/home/motion':
+    ensure => 'directory',
+    owner => 'motion',
+    group => 'motion'
+  }
+  file{'/motion-socket':
+    owner => 'motion',
+    group => 'motion'
+  }
+  package{'git':
+  } ->
+  exec{'clone motion':
+    command => '/usr/bin/git clone https://code.wpia.club/motion.git',
+    cwd => '/home/motion',
+    creates => '/home/motion/motion/.git',
+    user => 'motion'
+  } ->
+  file{'/home/motion/motion/__pycache__':
+    ensure => directory,
+    owner => motion,
+    group => motion
+  } ->
+  file{'/home/motion/motion/config.py':
+    content => epp("motion/config.py", {user => $container, password => 'motion'}),
+    owner => motion,
+    group => motion
+  } ->
+  exec {'motion-virtualenv':
+    command => '/usr/bin/virtualenv -p python3 motion',
+    cwd => '/home/motion',
+    creates => '/home/motion/motion/bin/activate',
+    user => 'motion',
+    require => [Package['virtualenv'], Package['python3-pip'], Exec['clone motion']],
+    before =>  Service['motion.service'],
+  } ->
+  exec{'pip dependencies':
+    command => '/bin/bash -c "source motion/bin/activate; /home/motion/motion/bin/pip install -r motion/requirements.txt"',
+    require => [Exec['motion-virtualenv'],Package['python3-pip']],
+    cwd => '/home/motion',
+    timeout => 0,
+    user => 'motion',
+    creates => '/home/motion/motion/bin/flask'
+  }
+
+  exec{'install uwsgi':
+    command => '/bin/bash -c "source motion/bin/activate; /home/motion/motion/bin/pip install uwsgi"',
+    require => Exec['motion-virtualenv'],
+    cwd => '/home/motion',
+    timeout => 0,
+    user => 'motion',
+    creates => '/home/motion/motion/bin/uwsgi'
+  }
+
+  file{'/home/motion/motion.ini':
+    source => 'puppet:///modules/motion/motion.ini'
+  } ->
+  systemd::unit_file {'motion.service':
+    ensure => 'file',
+    source => 'puppet:///modules/motion/motion.service',
+    notify => Service['motion.service'],
+    require => Exec['install uwsgi']
+  }
+  service{'motion.service':
+    ensure => 'running',
+    provider => 'systemd',
+    enable => true,
+    require => [Exec['pip dependencies'],Exec['systemctl-daemon-reload']],
+  }
+
+}
diff --git a/modules/motion/manifests/virtual.pp b/modules/motion/manifests/virtual.pp
new file mode 100644 (file)
index 0000000..ccc379d
--- /dev/null
@@ -0,0 +1,48 @@
+define motion::virtual ($domain = "motion.${systemDomain}", $container = $name) {
+  @file{"/run/${container}-socket":
+    ensure => 'directory',
+    tag => [root]
+  } ->
+  @lxc::container { $container:
+    contname => $container,
+    ip => $ips[$container],
+    dir => ['/motion-socket'],
+    bind => {
+      "/run/${container}-socket" => { 'target' => "motion-socket"},
+    },
+    tag => [root]
+  }
+  @lxc::container_bind{ "/run/${container}-socket":
+    container => 'front-nginx',
+    target => "${container}-socket",
+    tag => [root]
+  }
+
+  @file{"/etc/ssl/${container}-roots.pem":
+    ensure => 'file',
+    source => ['puppet:///modules/motion/motion-roots.pem', 'puppet:///modules/nre/config/ca/root.crt'],
+    tag => [nginx]
+  }
+  @front_vhost{$container:
+    source => 'motion/nginx.epp',
+    args => {container => $container, cert_stem => "/etc/ssl/private/${container}", domain => $domain, socket => "unix:/${container}-socket/motion.fcgi"},
+    crt => "motion/${container}",
+    tag => [nginx]
+  }
+
+
+  @postgresql::server::db { $container:
+    user     => $container,
+    password => postgresql_password($container, 'motion'),
+    tag => [primary]
+  }
+  @postgresql::server::pg_hba_rule { "allow ${container} to access its database":
+    description => "Open up PostgreSQL for access from motion-user to its database",
+    type        => 'host',
+    database    => $container,
+    user        => $container,
+    address     => "${ips[$container]}/32",
+    auth_method => 'md5',
+    tag => [primary]
+  }
+}
diff --git a/modules/motion/templates/config.py.epp b/modules/motion/templates/config.py.epp
new file mode 100644 (file)
index 0000000..27274f2
--- /dev/null
@@ -0,0 +1,4 @@
+DATABASE="pq://<%=$ips[postgres]%>/motion"
+USER="<%=$user%>"
+PASSWORD="<%=$password%>"
+GROUP_PREFIX={"motion.<%=$systemDomain%>":{"fellowship": "f", "board": "m"}}
diff --git a/modules/motion/templates/nginx.epp b/modules/motion/templates/nginx.epp
new file mode 100644 (file)
index 0000000..36dbfa6
--- /dev/null
@@ -0,0 +1,62 @@
+server {
+    listen       0.0.0.0:80;
+    server_name  <%=$domain%>;
+    gzip         on;
+
+    location / {
+        fastcgi_param  QUERY_STRING       $query_string;
+        fastcgi_param  REQUEST_METHOD     $request_method;
+        fastcgi_param  CONTENT_TYPE       $content_type;
+        fastcgi_param  CONTENT_LENGTH     $content_length;
+        fastcgi_param  REQUEST_URI        $request_uri;
+        fastcgi_param  PATH_INFO          $document_uri;
+        fastcgi_param  REMOTE_ADDR        $remote_addr;
+        fastcgi_param  REMOTE_PORT        $remote_port;
+        fastcgi_param  SERVER_NAME        $host;
+        fastcgi_param  SERVER_PORT        '80';
+        fastcgi_param  SERVER_PROTOCOL    'http';
+        fastcgi_param  USER_ROLES         'anonymous/void:*';
+        fastcgi_pass  <%=$socket%>;
+    }
+    location ~* /.well-known/someca-challenge/.* {
+        root /data/challenge;
+    }
+}
+<%=inline_epp(file('motion/user_map.epp', 'motion/user_map.template.epp'), {container => $container})%>
+log_format <%=$container%>-cert '$date_gmt $ssl_client_serial:$ssl_client_i_dn;$<%=$container%>_user_role';
+server {
+    listen       0.0.0.0:443 ssl;
+    server_name  <%=$domain%>;
+    gzip         on;
+    ssl_certificate <%=$cert_stem%>.crt;
+    ssl_certificate_key <%=$cert_stem%>.key;
+
+    ssl_client_certificate /etc/ssl/<%=$container%>-roots.pem;
+    ssl_verify_client on;
+    ssl_verify_depth 4;
+    access_log /tmp/<%=$container%>-certs.log <%=$container%>-cert;
+
+    location / {
+        fastcgi_param  QUERY_STRING       $query_string;
+        fastcgi_param  REQUEST_METHOD     $request_method;
+        fastcgi_param  CONTENT_TYPE       $content_type;
+        fastcgi_param  CONTENT_LENGTH     $content_length;
+        fastcgi_param  REQUEST_URI        $request_uri;
+        fastcgi_param  PATH_INFO          $document_uri;
+        fastcgi_param  REMOTE_ADDR        $remote_addr;
+        fastcgi_param  REMOTE_PORT        $remote_port;
+        fastcgi_param  SERVER_NAME        $host;
+        fastcgi_param  SERVER_PORT        '443';
+        fastcgi_param  SERVER_PROTOCOL    'https';
+        fastcgi_param  USER_ROLES         $<%=$container%>_user_role;
+        fastcgi_pass  <%=$socket%>;
+
+    <% if($protected != 'no') { %>
+        auth_basic "closed site";
+        auth_basic_user_file /etc/nginx/access.txt;
+        <% } %>
+    }
+    location ~* /.well-known/someca-challenge/.* {
+        root /data/challenge;
+    }
+}