[buildout]

parts =
  publish-connection-information
  pbs
  logrotate-entry-notifier
  pbs-sshkeys-authority
  sshkeys-openssh
  resilient-genstatrss-wrapper
  pbs-push-history-log
  cron-pbs-status-feed
  pull-push-stalled-promise
  notifier-feed-status-promise

## Monitor for pbs
  monitor-base
  monitor-check-resilient-feed-file

extends =
  ${monitor2-template:rendered}
  ${template-logrotate-base:rendered}

#----------------
#--
#-- Creation of all needed directories.

[rootdirectory]
recipe = slapos.cookbook:mkdirectory
etc = $${buildout:directory}/etc
srv = $${buildout:directory}/srv
bin = $${buildout:directory}/bin
tmp = $${buildout:directory}/tmp
var = $${buildout:directory}/var

[basedirectory]
recipe = slapos.cookbook:mkdirectory
log = $${rootdirectory:var}/log
services = $${rootdirectory:etc}/service
run = $${rootdirectory:var}/run
backup = $${rootdirectory:srv}/backup
promises = $${rootdirectory:etc}/promise
ssh-home = $${rootdirectory:etc}/ssh
notifier = $${rootdirectory:etc}/notifier

[directory]
recipe = slapos.cookbook:mkdirectory
cronstamps = $${rootdirectory:etc}/cronstamps
cron-entries = $${rootdirectory:etc}/cron.d
crontabs = $${rootdirectory:etc}/crontabs
cronoutput = $${basedirectory:log}/cron-ouput
pbs-backup = $${basedirectory:backup}/pbs
sshkeys = $${rootdirectory:srv}/sshkeys
pbs-wrappers = $${rootdirectory:bin}/pbs
dot-ssh = $${basedirectory:ssh-home}/.ssh
notifier-feeds = $${basedirectory:notifier}/feeds
notifier-callbacks = $${basedirectory:notifier}/callbacks
notifier-status-items = $${basedirectory:notifier}/status-items
monitor-resilient = $${monitor-directory:private}/resilient


#----------------
#--
#-- Set up the equeue and notifier.

[equeue]
recipe = slapos.cookbook:equeue
socket = $${basedirectory:run}/equeue.sock
lockfile = $${basedirectory:run}/equeue.lock
log = $${basedirectory:log}/equeue.log
database = $${rootdirectory:srv}/equeue.db
wrapper = $${basedirectory:services}/equeue
equeue-binary = ${buildout:bin-directory}/equeue

[notifier-port]
recipe = slapos.cookbook:free_port
minimum = 8088
maximum = 8097
ip = $${notifier:host}

# notifier.notify adds the [exporter, notifier] to the execution queue
# notifier.notify.callback sets up a callback
[notifier]
recipe = slapos.recipe.template:jinja2
template = ${template-wrapper:output}
rendered = $${:wrapper}
wrapper = $${basedirectory:services}/notifier
mode = 0700
command = ${buildout:bin-directory}/pubsubserver --callbacks $${directory:notifier-callbacks} --feeds $${directory:notifier-feeds} --equeue-socket $${equeue:socket} --logfile $${basedirectory:log}/notifier.log $${:host} $${:port}
host = {{ ipv6 }}
port = $${notifier-port:port}
context =
  key content notifier:command

[logrotate-entry-equeue]
<= logrotate
recipe = slapos.cookbook:logrotate.d
name = equeue
log = $${equeue:log}
frequency = daily
rotate-num = 30


#----------------
#--
#-- The pull-backup-server contains every backup (incremental)
#-- to prevent a corrupt dump from destroying everything.

[pbs]
<= notifier
recipe = slapos.cookbook:pbs
client = true
feeds = $${directory:notifier-feeds}
callbacks-directory = $${directory:notifier-callbacks}
equeue-socket = $${equeue:socket}
notifier-binary = ${buildout:bin-directory}/pubsubnotifier
rdiffbackup-binary = ${buildout:bin-directory}/rdiff-backup
sshclient-binary = $${openssh-client:wrapper-path}
known-hosts = $${directory:dot-ssh}/known_hosts
promises-directory = $${basedirectory:promises}
directory = $${directory:pbs-backup}
cron-entries = $${cron:cron-entries}
wrappers-directory = $${directory:pbs-wrappers}
run-directory = $${basedirectory:run}
pull-push-maximum-run = 5
# XXX: this should be named "notifier-host"
notifier-url = http://[$${notifier:host}]:$${notifier:port}
slave-instance-list = {{ dumps(slave_instance_list) }}
ignore-known-hosts-file = {{ slapparameter_dict.get('ignore-known-hosts-file', 'false') }}
# To get a verbose feed about PBS state
instance-root-name = $${monitor-instance-parameter:root-instance-title}
log-url = $${monitor-publish-parameters:monitor-base-url}/private/notifier/
status-item-directory = $${directory:notifier-status-items}

[pbs-resilient-status-feed]
recipe = slapos.cookbook:wrapper
command-line = ${buildout:directory}/bin/generatefeed --output $${:feed-path} --status-item-path $${pbs:status-item-directory} --title "Status feed for $${monitor-instance-parameter:root-instance-title}-PBS" --link $${pbs:log-url}
feed-path = $${directory:monitor-resilient}/pbs-status-rss
wrapper-path = $${rootdirectory:bin}/resilient-genstatusrss.py

[cron-pbs-status-feed]
<= cron
recipe = slapos.cookbook:cron.d
name = resilient-pbs-status-feed
frequency = */5 * * * *
command = $${pbs-resilient-status-feed:wrapper-path}

[logrotate-entry-notifier]
<= logrotate-entry-base
name = notifier
log = $${directory:notifier-feeds}/*
rotate-num = 5
frequency = weekly
nocompress = true

#----------------
#--
#-- sshkeys

[sshkeys-directory]
recipe = slapos.cookbook:mkdirectory
requests = $${directory:sshkeys}/openssl-requests
keys = $${directory:sshkeys}/openssl-keys

[pbs-sshkeys-authority]
recipe = slapos.cookbook:sshkeys_authority
request-directory = $${sshkeys-directory:requests}
keys-directory = $${sshkeys-directory:keys}
wrapper = $${basedirectory:services}/pbs_sshkeys_authority
keygen-binary = ${openssh:location}/bin/ssh-keygen

[sshkeys-openssh]
<= pbs-sshkeys-authority
recipe = slapos.cookbook:sshkeys_authority.request
name = pbs-client
type = rsa
executable = $${openssh-client:wrapper-path}
public-key = $${openssh-client:identity-file}.pub
private-key = $${openssh-client:identity-file}
wrapper = $${rootdirectory:bin}/do_backup


#----------------
#--
#-- OpenSSH.

[openssh-client]
recipe = slapos.cookbook:wrapper
home = $${basedirectory:ssh-home}
identity-file = $${:home}/id_rsa
command-line = ${openssh:location}/bin/ssh -T -o "UserKnownHostsFile $${pbs:known-hosts}" -i $${:identity-file}
wrapper-path = $${rootdirectory:bin}/ssh

#----------------
#--
#-- Resiliency promises.

[resilient-genstatrss-wrapper]
recipe = slapos.cookbook:wrapper
# XXX - hard-coded Urls
command-line = ${buildout:directory}/bin/rdiffbackup.genstatrss --output '$${monitor-directory:public}/resilient-feed' --rdiff_backup_data_folder '$${pbs:rdiff-backup-data-folder}' --feed_url '$${monitor-conf-parameters:base-url}/public/resilient-feed'
wrapper-path = $${directory:bin}/resilient-genstatrss.py

[pbs-push-history-log]
recipe = cns.recipe.symlink
symlink = $${pbs:rdiff-backup-data-folder}/restore.log = $${basedirectory:log}/pbs-push-history-log

[pull-push-stalled-promise-bin]
recipe = slapos.cookbook:wrapper
# # time-buffer is 24h (+1h of latitude)
command-line = ${buildout:bin-directory}/check-feed-as-promise --feed-path $${pbs-resilient-status-feed:feed-path} --title --ok-pattern 'OK' --time-buffer 90000
wrapper-path = $${rootdirectory:bin}/stalled-pull-push

[pull-push-stalled-promise]
<= monitor-promise-base
module = check_command_execute
name = stalled-pull-push.py
config-command = $${pull-push-stalled-promise-bin:wrapper-path}

[notifier-feed-status-promise-bin]
recipe = slapos.recipe.template:jinja2
template = ${notifier-feed-promise-template:target}
rendered = $${rootdirectory:bin}/notifier-feed-check-malformed-or-failure.py
mode = 700
context =
  key notifier_feed_directory directory:notifier-feeds
  raw base_url http://[$${notifier:host}]:$${notifier:port}/get/
  raw python_executable ${buildout:executable}

[notifier-feed-status-promise]
<= monitor-promise-base
module = check_command_execute
name = notifier-feed-check-malformed-or-failure.py
config-command = $${notifier-feed-status-promise-bin:rendered}

#----------------
#--
#-- Publish instance parameters.

[publish-connection-information]
recipe = slapos.cookbook:publish
ssh-key = $${sshkeys-openssh:public-key-value}
notification-url = http://[$${notifier:host}]:$${notifier:port}/notify
feeds-url = http://[$${notifier:host}]:$${notifier:port}/get/
monitor-base-url = $${monitor-publish-parameters:monitor-base-url}
monitor-url = $${monitor-publish-parameters:monitor-url}
monitor-user = $${monitor-publish-parameters:monitor-user}
monitor-password = $${monitor-publish-parameters:monitor-password}

#----------------
#--
#-- Monitor

[monitor-instance-parameter]
monitor-httpd-port = {{ slapparameter_dict.get('monitor-httpd-port', 8070) }}
monitor-title = {{ slapparameter_dict.get('monitor-title', 'PBS Instance') }}
cors-domains = {{ slapparameter_dict.get('monitor-cors-domains', '') }}
username = {{ slapparameter_dict.get('monitor-username', 'admin') }}
password = {{ slapparameter_dict.get('monitor-password', '$${monitor-htpasswd:passwd}') }}

[monitor-conf-parameters]
private-path-list += 
  $${logrotate-directory:logrotate-backup}
  $${basedirectory:log}

[monitor-check-resilient-feed-file]
recipe = slapos.recipe.template:jinja2
template = ${template-monitor-check-resilient-feed:location}/${template-monitor-check-resilient-feed:filename}
rendered = $${monitor-directory:bin}/check-create-resilient-feed-files
mode = 700
context =
  key input_feed_directory directory:notifier-feeds
  key monitor_feed_directory monitor-directory:public
  key base_url publish-connection-information:feeds-url
  raw python_executable ${buildout:executable}