cp over all the bundles from kunsis bw repo
This commit is contained in:
parent
65b117b819
commit
1f73b04351
89 changed files with 3991 additions and 0 deletions
27
bundles/users/README.md
Normal file
27
bundles/users/README.md
Normal file
|
@ -0,0 +1,27 @@
|
|||
# bundles/users
|
||||
|
||||
This bundle evaluates node metadata to determine which users should
|
||||
exist on the system.
|
||||
It will also create a home directory, add ssh keys and deploy shell
|
||||
configs, if user-specific configuration exists.
|
||||
|
||||
## metadata
|
||||
'users': {
|
||||
'username': {
|
||||
'home': '/home/username', # this is the default
|
||||
'shell': '/bin/bash', # this is the default
|
||||
'groups': {
|
||||
# list of groups the user should be in
|
||||
},
|
||||
'ssh_pubkey': [
|
||||
# list of ssh pubkeys that are allowed to log in
|
||||
],
|
||||
},
|
||||
}
|
||||
|
||||
## custom shell config
|
||||
Deploy your custom config to these paths:
|
||||
|
||||
* data/users/files/tmux/username.conf
|
||||
* data/users/files/fish/username.conf
|
||||
* data/users/files/bash/username.bashrc
|
72
bundles/users/files/bashrc
Normal file
72
bundles/users/files/bashrc
Normal file
|
@ -0,0 +1,72 @@
|
|||
[ -z "$PS1" ] && return
|
||||
|
||||
__node_name="${node.name}"
|
||||
|
||||
<%text>
|
||||
if [[ "$(id -u)" -eq 0 ]]
|
||||
then
|
||||
export PS1='\[\e[1;34m\][\[\e[1;91m\]'"$__node_name"'\[\e[1;34m\]][\[\e[1;91m\]\u\[\e[1;34m\]@\[\e[1;91m\]$PWD\[\e[1;34m\]] > \[\e[0m\]'
|
||||
else
|
||||
export PS1='\[\e[1;34m\][\[\e[1;32m\]'"$__node_name"'\[\e[1;34m\]][\[\e[1;32m\]\u\[\e[1;34m\]@\[\e[1;32m\]\w\[\e[1;34m\]] > \[\e[0m\]'
|
||||
fi
|
||||
case $TERM in
|
||||
xterm*|rxvt*)
|
||||
export PROMPT_COMMAND='echo -ne "\a\e]0;'"$__node_name"':${PWD}\a"'
|
||||
;;
|
||||
screen*)
|
||||
export PROMPT_COMMAND='echo -ne "\a\ek'"$__node_name"':${PWD}\e\\"'
|
||||
;;
|
||||
*)
|
||||
unset PROMPT_COMMAND
|
||||
;;
|
||||
esac
|
||||
|
||||
if [[ -f "/etc/node.description" ]]
|
||||
then
|
||||
echo
|
||||
cat "/etc/node.description"
|
||||
echo
|
||||
fi
|
||||
|
||||
uptime
|
||||
last | grep 'still logged in'
|
||||
|
||||
export HISTCONTROL=ignoredups
|
||||
export HISTSIZE=50000
|
||||
export HISTTIMEFORMAT="%d/%m/%y %T "
|
||||
export SAVEHIST=50000
|
||||
shopt -s checkjobs
|
||||
shopt -s checkwinsize
|
||||
shopt -s globstar
|
||||
shopt -s histreedit
|
||||
|
||||
export LESS="-iRS -# 2"
|
||||
|
||||
export EDITOR=vim
|
||||
export VISUAL=vim
|
||||
|
||||
alias ipb='ip -brief'
|
||||
alias l='ls -lAh'
|
||||
alias s='sudo -i'
|
||||
alias v='vim -p'
|
||||
</%text>
|
||||
% for k, v in sorted(node.metadata.get('bash_aliases', {}).items()):
|
||||
alias ${k}='${v}'
|
||||
% endfor
|
||||
|
||||
rsback()
|
||||
{
|
||||
for i
|
||||
do
|
||||
[ -e "$i" ] || { echo "ERROR: $i does not exist" >&2; continue; }
|
||||
printf 'rsync -zaP -e ssh %q ' '--rsync-path=sudo rsync'
|
||||
printf '%q:%q .' "${node.hostname}" "$(printf '%q' "$(readlink -e -- "$i")")"
|
||||
printf '\n'
|
||||
done
|
||||
}
|
||||
% for k, v in sorted(node.metadata.get('bash_functions', {}).items()):
|
||||
|
||||
${k}() {
|
||||
${v}
|
||||
}
|
||||
% endfor
|
23
bundles/users/files/fish.conf
Normal file
23
bundles/users/files/fish.conf
Normal file
|
@ -0,0 +1,23 @@
|
|||
function fish_greeting
|
||||
uptime
|
||||
last | grep 'still logged in'
|
||||
end
|
||||
|
||||
function fish_prompt
|
||||
set -l last_status $status
|
||||
|
||||
echo -n "$USER@${node.name}:"
|
||||
|
||||
set_color $fish_color_cwd
|
||||
echo -n (pwd)
|
||||
set_color normal
|
||||
|
||||
if not test $last_status -eq 0
|
||||
set_color $fish_color_error
|
||||
echo -n " [$status]"
|
||||
set_color normal
|
||||
end
|
||||
|
||||
echo -n '➤ '
|
||||
set_color normal
|
||||
end
|
32
bundles/users/files/fish_variables
Normal file
32
bundles/users/files/fish_variables
Normal file
|
@ -0,0 +1,32 @@
|
|||
# This file contains fish universal variable definitions.
|
||||
# VERSION: 3.0
|
||||
SETUVAR fish_color_autosuggestion:555\x1ebrblack
|
||||
SETUVAR fish_color_cancel:\x2dr
|
||||
SETUVAR fish_color_command:005fd7
|
||||
SETUVAR fish_color_comment:990000
|
||||
SETUVAR fish_color_cwd:green
|
||||
SETUVAR fish_color_cwd_root:red
|
||||
SETUVAR fish_color_end:009900
|
||||
SETUVAR fish_color_error:ff0000
|
||||
SETUVAR fish_color_escape:00a6b2
|
||||
SETUVAR fish_color_history_current:\x2d\x2dbold
|
||||
SETUVAR fish_color_host:normal
|
||||
SETUVAR fish_color_host_remote:yellow
|
||||
SETUVAR fish_color_match:\x2d\x2dbackground\x3dbrblue
|
||||
SETUVAR fish_color_normal:normal
|
||||
SETUVAR fish_color_operator:00a6b2
|
||||
SETUVAR fish_color_param:00afff
|
||||
SETUVAR fish_color_quote:999900
|
||||
SETUVAR fish_color_redirection:00afff
|
||||
SETUVAR fish_color_search_match:bryellow\x1e\x2d\x2dbackground\x3dbrblack
|
||||
SETUVAR fish_color_selection:white\x1e\x2d\x2dbold\x1e\x2d\x2dbackground\x3dbrblack
|
||||
SETUVAR fish_color_status:red
|
||||
SETUVAR fish_color_user:brgreen
|
||||
SETUVAR fish_color_valid_path:\x2d\x2dunderline
|
||||
SETUVAR fish_features:stderr\x2dnocaret\x1eqmark\x2dnoglob
|
||||
SETUVAR fish_greeting:Welcome\x20to\x20fish\x2c\x20the\x20friendly\x20interactive\x20shell
|
||||
SETUVAR fish_key_bindings:fish_default_key_bindings
|
||||
SETUVAR fish_pager_color_completion:\x1d
|
||||
SETUVAR fish_pager_color_description:B3A06D\x1eyellow
|
||||
SETUVAR fish_pager_color_prefix:white\x1e\x2d\x2dbold\x1e\x2d\x2dunderline
|
||||
SETUVAR fish_pager_color_progress:brwhite\x1e\x2d\x2dbackground\x3dcyan
|
51
bundles/users/files/tmux.conf
Normal file
51
bundles/users/files/tmux.conf
Normal file
|
@ -0,0 +1,51 @@
|
|||
bind C-a send-prefix # Pass on ctrl-a for other apps
|
||||
|
||||
set-option -g set-titles on
|
||||
set-option -g set-titles-string '#W [#(logname)@${node.name}]'
|
||||
|
||||
# Status bar
|
||||
set -g status on
|
||||
set -g status-interval 1
|
||||
set -g status-left '[#(logname)@${node.name}] '
|
||||
set -g status-left-length 100
|
||||
set -g status-right ' [#(lsb_release -ds)] [#(date --rfc-3339=seconds)]'
|
||||
set -g status-right-length 200
|
||||
|
||||
# Numbering starts at 1
|
||||
set -g base-index 1
|
||||
setw -g pane-base-index 1
|
||||
set-option -g renumber-windows on
|
||||
|
||||
# Activity monitoring
|
||||
setw -g monitor-activity on
|
||||
set -g visual-activity on
|
||||
|
||||
# Terminal
|
||||
set-option -g default-shell $SHELL
|
||||
set -g default-terminal "tmux-256color"
|
||||
|
||||
# Keybindings
|
||||
bind-key -n M-Left select-pane -L
|
||||
bind-key -n M-Right select-pane -R
|
||||
bind-key -n M-Up select-pane -U
|
||||
bind-key -n M-Down select-pane -D
|
||||
|
||||
# Vim-Keybindings, adapted for neo layout, shifted one key to the right
|
||||
bind-key -n M-n select-pane -L
|
||||
bind-key -n M-d select-pane -R
|
||||
bind-key -n M-t select-pane -U
|
||||
bind-key -n M-r select-pane -D
|
||||
|
||||
#### COLOUR (Solarized dark)
|
||||
set-option -g status-bg black #base02
|
||||
set-option -g status-fg yellow #yellow
|
||||
set-option -g status-style default
|
||||
set-window-option -g window-status-style fg=brightblue,bg=default
|
||||
set-window-option -g window-status-activity-style fg=green,bg=default,none
|
||||
set-window-option -g window-status-current-style fg=brightred,bg=default,none
|
||||
set-option -g pane-border-style fg=black
|
||||
set-option -g pane-active-border-style fg=brightgreen
|
||||
set-option -g message-style bg=black,fg=brightred
|
||||
set-option -g display-panes-active-colour blue #blue
|
||||
set-option -g display-panes-colour brightred #orange
|
||||
set-window-option -g clock-mode-colour green #green
|
28
bundles/users/files/vimrc
Normal file
28
bundles/users/files/vimrc
Normal file
|
@ -0,0 +1,28 @@
|
|||
set number
|
||||
set lbr
|
||||
set fdc=0
|
||||
set vb
|
||||
set expandtab
|
||||
set shiftwidth=4
|
||||
set tabstop=4
|
||||
set softtabstop=4
|
||||
set linespace=0
|
||||
set autoindent
|
||||
set smartindent
|
||||
set mouse=a
|
||||
set cursorline
|
||||
syntax on
|
||||
set showcmd
|
||||
set encoding=utf-8
|
||||
set autowrite
|
||||
set noautochdir
|
||||
set list
|
||||
set listchars=trail:␣,tab:→\ ,extends:>,precedes:<
|
||||
set hlsearch
|
||||
map <silent> <c-k> :nohlsearch<CR>
|
||||
|
||||
set colorcolumn=72,120
|
||||
hi colorcolumn ctermbg=NONE ctermfg=red cterm=bold guibg=NONE guifg=red gui=bold
|
||||
|
||||
au BufRead /tmp/neomutt-* set tw=72
|
||||
au BufRead /tmp/mutt-* set tw=72
|
89
bundles/users/items.py
Normal file
89
bundles/users/items.py
Normal file
|
@ -0,0 +1,89 @@
|
|||
from os.path import join, exists
|
||||
|
||||
files = {
|
||||
'/etc/bash.bashrc': {
|
||||
'source': 'bashrc',
|
||||
'content_type': 'mako',
|
||||
},
|
||||
'/etc/tmux.conf': {
|
||||
'source': 'tmux.conf',
|
||||
'content_type': 'mako',
|
||||
},
|
||||
'/etc/vim/vimrc.local': {
|
||||
'source': 'vimrc',
|
||||
},
|
||||
}
|
||||
|
||||
for group, attrs in node.metadata.get('groups', {}).items():
|
||||
groups[group] = attrs
|
||||
|
||||
for username, attrs in node.metadata['users'].items():
|
||||
home = attrs.get('home', '/home/{}'.format(username))
|
||||
|
||||
if attrs.get('delete', False):
|
||||
users[username] = {'delete': True}
|
||||
files[home] = {'delete': True}
|
||||
|
||||
else:
|
||||
user = users.setdefault(username, {})
|
||||
|
||||
user['home'] = home
|
||||
user['shell'] = attrs.get('shell', '/bin/bash')
|
||||
|
||||
if 'password' in attrs:
|
||||
user['password'] = attrs['password']
|
||||
else:
|
||||
user['password_hash'] = 'x' if node.use_shadow_passwords else '*'
|
||||
|
||||
if 'groups' in attrs:
|
||||
user['groups'] = attrs['groups']
|
||||
|
||||
directories[home] = {
|
||||
'owner': username,
|
||||
'mode': attrs.get('home-mode', '0700'),
|
||||
}
|
||||
|
||||
if 'ssh_pubkey' in attrs:
|
||||
files[home + '/.ssh/authorized_keys'] = {
|
||||
'content': '\n'.join(sorted(set(attrs['ssh_pubkey']))) + '\n',
|
||||
'owner': username,
|
||||
'mode': '0600',
|
||||
}
|
||||
|
||||
elif not attrs.get('do_not_remove_authorized_keys_from_home', False):
|
||||
files[home + '/.ssh/authorized_keys'] = {'delete': True}
|
||||
|
||||
if exists(join(repo.path, 'data', 'users', 'files', 'tmux', '{}.conf'.format(username))):
|
||||
files[home + '/.tmux.conf'] = {
|
||||
'content_type': 'mako',
|
||||
'source': 'tmux/{}.conf'.format(username),
|
||||
}
|
||||
else:
|
||||
files[home + '/.tmux.conf'] = {
|
||||
'delete': True,
|
||||
}
|
||||
|
||||
if exists(join(repo.path, 'data', 'users', 'files', 'bash', '{}.bashrc'.format(username))):
|
||||
files[home + '/.bashrc'] = {
|
||||
'content_type': 'mako',
|
||||
'source': 'bash/{}.bashrc'.format(username),
|
||||
}
|
||||
else:
|
||||
files[home + '/.bashrc'] = {
|
||||
'delete': True,
|
||||
}
|
||||
|
||||
if attrs.get('enable_linger', False):
|
||||
linger_test = ''
|
||||
linger_command = 'enable'
|
||||
else:
|
||||
linger_test = '!'
|
||||
linger_command = 'disable'
|
||||
|
||||
actions[f'ensure_linger_state_for_user_{username}'] = {
|
||||
'command': f'loginctl {linger_command}-linger {username}',
|
||||
'unless': f'{linger_test} test -f /var/lib/systemd/linger/{username}',
|
||||
'needs': {
|
||||
f'user:{username}',
|
||||
},
|
||||
}
|
41
bundles/users/metadata.py
Normal file
41
bundles/users/metadata.py
Normal file
|
@ -0,0 +1,41 @@
|
|||
from json import loads
|
||||
from os.path import join
|
||||
|
||||
defaults = {
|
||||
'users': {
|
||||
'root': {
|
||||
'home': '/root',
|
||||
'shell': '/bin/bash',
|
||||
'password': repo.vault.human_password_for('root on {}'.format(node.name)),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@metadata_reactor.provides(
|
||||
'users',
|
||||
)
|
||||
def add_users_from_json(metadata):
|
||||
with open(join(repo.path, 'users.json'), 'r') as f:
|
||||
json = loads(f.read())
|
||||
|
||||
users = {}
|
||||
metadata_users = metadata.get('users', {})
|
||||
# First, add all admin users
|
||||
for uname, config in json.items():
|
||||
if config.get('is_admin', False) or uname in metadata_users:
|
||||
users[uname] = {
|
||||
'ssh_pubkey': set(config['ssh_pubkey']),
|
||||
'is_admin': config.get('is_admin', False),
|
||||
}
|
||||
|
||||
# Then, run again to get all 'to be deleted' users
|
||||
for uname, config in json.items():
|
||||
if uname not in metadata_users:
|
||||
users.setdefault(uname, {
|
||||
'delete': True,
|
||||
})
|
||||
|
||||
return {
|
||||
'users': users,
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue