Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
db69e437d5
|
|||
|
663c4da0a0
|
|||
|
010e2d0d64
|
|||
|
065eac06b1
|
|||
|
1759af98b8
|
+2
-22
@@ -8,27 +8,7 @@ data_bag_path "data_bags"
|
||||
encrypted_data_bag_secret "#{current_dir}/encrypted_data_bag_secret"
|
||||
local_mode true # Chef local mode, replacing Solo
|
||||
|
||||
# Knife-Zero config, see https://knife-zero.github.io/40_configuration/
|
||||
# Prevent attributes from being saved to the node files
|
||||
knife[:automatic_attribute_whitelist] = %w[
|
||||
fqdn
|
||||
os
|
||||
os_version
|
||||
hostname
|
||||
ipaddress
|
||||
roles
|
||||
recipes
|
||||
ipaddress
|
||||
platform
|
||||
platform_version
|
||||
cloud
|
||||
cloud_v2
|
||||
chef_packages
|
||||
]
|
||||
|
||||
# Added to /etc/chef/client.rb on node bootstrap
|
||||
# https://docs.chef.io/attribute_persistence/
|
||||
# Source of truth: site-cookbooks/kosmos-base/files/default/chef_normal_attributes.yml
|
||||
normal_attrs = YAML.load_file(File.expand_path("../site-cookbooks/kosmos-base/files/default/chef_normal_attributes.yml", __dir__))
|
||||
knife[:normal_attribute_allowlist] = normal_attrs
|
||||
knife[:allowed_normal_attributes] = normal_attrs
|
||||
# Source of truth: site-cookbooks/kosmos-base/files/default/chef_attributes.rb
|
||||
client_d_dir(File.expand_path("../site-cookbooks/kosmos-base/files/default/chef_attributes.rb"))
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT="$(git rev-parse --show-toplevel)/scripts/util/sanitize_node.sh"
|
||||
|
||||
FILES=$(git diff --cached --name-only --diff-filter=ACM -- 'nodes/*.json' || true)
|
||||
|
||||
[[ -z "$FILES" ]] && exit 0
|
||||
|
||||
DIRTY=0
|
||||
|
||||
while IFS= read -r file; do
|
||||
staged_tmp=$(mktemp)
|
||||
sanitized_tmp=$(mktemp)
|
||||
|
||||
# 1. get staged version
|
||||
git show ":$file" > "$staged_tmp"
|
||||
|
||||
# 2. sanitize IN PLACE (on temp copy)
|
||||
cp "$staged_tmp" "$sanitized_tmp"
|
||||
"$SCRIPT" "$sanitized_tmp"
|
||||
|
||||
# 3. if sanitizer changed file, update working tree
|
||||
if ! diff -q "$staged_tmp" "$sanitized_tmp" >/dev/null; then
|
||||
cp "$sanitized_tmp" "$file"
|
||||
echo "Sanitized: $file"
|
||||
DIRTY=1
|
||||
fi
|
||||
|
||||
rm -f "$staged_tmp" "$sanitized_tmp"
|
||||
|
||||
done <<< "$FILES"
|
||||
|
||||
if [[ "$DIRTY" -ne 0 ]]; then
|
||||
echo ""
|
||||
echo "Commit paused, sanitized files must be re-staged."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
exit 0
|
||||
@@ -28,10 +28,6 @@ Clone this repository, `cd` into it, and run:
|
||||
|
||||
bundle install
|
||||
|
||||
### Enable Git hooks
|
||||
|
||||
git config core.hooksPath .githooks
|
||||
|
||||
## Common tasks
|
||||
|
||||
### Bootstrap a new host server
|
||||
|
||||
@@ -36,7 +36,6 @@
|
||||
"kosmos-base::systemd_emails",
|
||||
"apt::unattended-upgrades",
|
||||
"kosmos-base::firewall",
|
||||
"kosmos-base::tmux",
|
||||
"kosmos-postfix::default",
|
||||
"postfix::default",
|
||||
"postfix::_common",
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
"kosmos-base",
|
||||
"kosmos-base::default",
|
||||
"kosmos_prometheus::node_exporter",
|
||||
"kosmos_zerotier::ohai_plugin",
|
||||
"kosmos_kvm::guest",
|
||||
"kosmos_prometheus::server",
|
||||
"kosmos_prometheus::alertmanager",
|
||||
@@ -38,6 +39,7 @@
|
||||
"postfix::_attributes",
|
||||
"postfix::sasl_auth",
|
||||
"hostname::default",
|
||||
"zerotier::ohai_plugin",
|
||||
"firewall::default"
|
||||
],
|
||||
"platform": "ubuntu",
|
||||
@@ -53,6 +55,22 @@
|
||||
"version": "18.2.13",
|
||||
"ohai_root": "/opt/chef/embedded/lib/ruby/gems/3.1.0/gems/ohai-18.2.13/lib/ohai"
|
||||
}
|
||||
},
|
||||
"zerotier": {
|
||||
"version": "1.16.2",
|
||||
"node_id": "77fcedcdce",
|
||||
"networks": {
|
||||
"8541e5153eb4327c": {
|
||||
"network_name": "virgo",
|
||||
"mac": "7e:45:48:d3:d8:2b",
|
||||
"status": "OK",
|
||||
"type": "PRIVATE",
|
||||
"interface": "ztsb7vcj2c",
|
||||
"addresses": [
|
||||
"10.1.1.146/24"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"run_list": [
|
||||
|
||||
@@ -3,4 +3,5 @@ name "base"
|
||||
run_list %w(
|
||||
kosmos-base::default
|
||||
kosmos_prometheus::node_exporter
|
||||
kosmos_zerotier::ohai_plugin
|
||||
)
|
||||
|
||||
@@ -1,69 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
# Strip the top-level "override" and "default" attributes from Chef node JSON files.
|
||||
#
|
||||
# Usage:
|
||||
# ./scripts/util/strip_node_attrs.sh <node> [<node> ...]
|
||||
# ./scripts/util/strip_node_attrs.sh --all
|
||||
#
|
||||
# A <node> may be a bare node name (e.g. "prometheus-1"), a path relative to the
|
||||
# repository root (e.g. "nodes/prometheus-1.json"), or an absolute path.
|
||||
#
|
||||
# Exit codes:
|
||||
# 0 - all target files processed successfully
|
||||
# 1 - one or more targets could not be processed (missing args, missing jq,
|
||||
# file not found, invalid JSON, or write failure)
|
||||
|
||||
set -uo pipefail
|
||||
|
||||
command -v jq >/dev/null 2>&1 || exit 1
|
||||
|
||||
root="$(git rev-parse --show-toplevel 2>/dev/null)" || root="$(pwd)"
|
||||
|
||||
targets=()
|
||||
if [ "$#" -eq 0 ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
for arg in "$@"; do
|
||||
if [ "$arg" = "--all" ]; then
|
||||
shopt -s nullglob
|
||||
for f in "$root"/nodes/*.json; do
|
||||
targets+=("$f")
|
||||
done
|
||||
shopt -u nullglob
|
||||
continue
|
||||
fi
|
||||
|
||||
if [[ "$arg" == */* ]]; then
|
||||
if [[ "$arg" = /* ]]; then
|
||||
targets+=("$arg")
|
||||
else
|
||||
targets+=("$root/$arg")
|
||||
fi
|
||||
else
|
||||
targets+=("$root/nodes/$arg.json")
|
||||
fi
|
||||
done
|
||||
|
||||
if [ "${#targets[@]}" -eq 0 ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
rc=0
|
||||
for file in "${targets[@]}"; do
|
||||
[ -f "$file" ] || { rc=1; continue; }
|
||||
|
||||
jq -e . "$file" >/dev/null 2>&1 || { rc=1; continue; }
|
||||
|
||||
tmp="$(mktemp "${file}.XXXXXX")" || { rc=1; continue; }
|
||||
if jq --indent 2 'del(.override, .default)' "$file" > "$tmp" 2>/dev/null; then
|
||||
truncate -s -1 "$tmp" 2>/dev/null || true
|
||||
mv "$tmp" "$file" || { rm -f "$tmp"; rc=1; continue; }
|
||||
else
|
||||
rm -f "$tmp"
|
||||
rc=1
|
||||
continue
|
||||
fi
|
||||
done
|
||||
|
||||
exit "$rc"
|
||||
@@ -1,15 +1,2 @@
|
||||
node.default["kosmos-base"]["journald"]["system_max_use"] = "256M"
|
||||
node.default["kosmos-base"]["journald"]["max_retention_sec"] = "7d"
|
||||
|
||||
node.default["kosmos-base"]["tmux"]["plugins_dir"] = "/usr/local/share/tmux/plugins"
|
||||
node.default["kosmos-base"]["tmux"]["default_conf"] = "/usr/local/share/tmux/tmux.conf.default"
|
||||
node.default["kosmos-base"]["tmux"]["tpm_redux"]["repo"] = "https://github.com/RyanMacG/tpm-redux.git"
|
||||
node.default["kosmos-base"]["tmux"]["tpm_redux"]["revision"] = "c5347f71a291eadf26dbecacc43154ecd8ad061b"
|
||||
# Keys are tpm shorthand names (used in `set -g @plugin`). Values contain the
|
||||
# git repo and the exact commit SHA the plugin is pinned to.
|
||||
node.default["kosmos-base"]["tmux"]["plugins"] = {
|
||||
"tmux-plugins/tmux-resurrect" => {
|
||||
"repo" => "https://github.com/tmux-plugins/tmux-resurrect.git",
|
||||
"revision" => "e87d7d592cac97fa38c12395ebec042c154a1844",
|
||||
},
|
||||
}
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
allowed_automatic_attributes ["fqdn", "os", "os_version", "hostname",
|
||||
"ipaddress", "roles", "recipes", "ipaddress",
|
||||
"platform", "platform_version", "cloud",
|
||||
"cloud_v2", "chef_packages", "zerotier"]
|
||||
allowed_default_attributes []
|
||||
allowed_override_attributes []
|
||||
allowed_normal_attributes ["knife_zero", "kosmos_kvm", "kosmos-ejabberd",
|
||||
"openresty", "vm_host"]
|
||||
@@ -1,6 +0,0 @@
|
||||
---
|
||||
- knife_zero
|
||||
- kosmos_kvm
|
||||
- kosmos-ejabberd
|
||||
- openresty
|
||||
- vm_host
|
||||
@@ -1,44 +0,0 @@
|
||||
# basti's tmux overrides — appended after the system default config is sourced.
|
||||
|
||||
set -g prefix C-a
|
||||
set -sg escape-time 1
|
||||
set -g base-index 1
|
||||
set -g history-limit 20000
|
||||
set -g mouse off
|
||||
set -g status-justify centre
|
||||
set -g status-style dim
|
||||
set -ag status-style fg=white
|
||||
set -ag status-style bg=colour236
|
||||
set -g window-status-current-style bright
|
||||
set -ag window-status-current-style fg=white
|
||||
set -ag window-status-current-style bg=colour238
|
||||
set -g pane-border-style fg=colour238
|
||||
set -g pane-active-border-style fg=colour244
|
||||
|
||||
setw -g pane-base-index 1
|
||||
setw -g mode-keys vi
|
||||
|
||||
bind C-a send-prefix
|
||||
bind r source-file ~/.tmux.conf \; display "Reloaded!"
|
||||
bind | split-window -h
|
||||
bind - split-window -v
|
||||
bind h select-pane -L
|
||||
bind j select-pane -D
|
||||
bind k select-pane -U
|
||||
bind l select-pane -R
|
||||
bind -r H resize-pane -L 5
|
||||
bind -r J resize-pane -D 5
|
||||
bind -r K resize-pane -U 5
|
||||
bind -r L resize-pane -R 5
|
||||
|
||||
unbind p
|
||||
bind p paste-buffer
|
||||
bind-key -T copy-mode-vi v send-keys -X begin-selection
|
||||
bind-key -T copy-mode-vi y send-keys -X copy-selection-and-cancel
|
||||
|
||||
unbind Up
|
||||
bind Up new-window -d -n tmp \; swap-pane -s tmp.1 \; select-window -t tmp
|
||||
unbind Down
|
||||
bind Down last-window \; swap-pane -s tmp.1 \; kill-window -t tmp
|
||||
|
||||
bind P pipe-pane -o "cat >>~/#W.log" \; display "Toggled logging to ~/#W.log"
|
||||
@@ -2,57 +2,31 @@
|
||||
# Cookbook Name:: kosmos-base
|
||||
# Recipe:: default
|
||||
#
|
||||
# The MIT License (MIT)
|
||||
#
|
||||
# Copyright:: 2019, Kosmos Developers
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
# THE SOFTWARE.
|
||||
|
||||
ruby_block "cleanup client.rb" do
|
||||
block do
|
||||
fe = Chef::Util::FileEdit.new("/etc/chef/client.rb")
|
||||
# Delete old attributes, replaced by allow_*_attributes
|
||||
fe.search_file_delete_line(/^.*_attribute_whitelist.*/)
|
||||
fe.write_file
|
||||
end
|
||||
end
|
||||
|
||||
cookbook_file "/etc/chef/client.d/attributes.rb" do
|
||||
source "chef_attributes.rb"
|
||||
mode "0644"
|
||||
notifies :create, "ruby_block[reload_client_config]", :immediately
|
||||
end
|
||||
|
||||
ruby_block "reload_client_config" do
|
||||
block do
|
||||
Chef::Config.from_file("/etc/chef/client.rb")
|
||||
end
|
||||
action :nothing
|
||||
end
|
||||
|
||||
include_recipe "apt"
|
||||
|
||||
cookbook_file "/etc/chef/chef_normal_attributes.yml" do
|
||||
source "chef_normal_attributes.yml"
|
||||
owner "root"
|
||||
group "root"
|
||||
mode "0644"
|
||||
end
|
||||
|
||||
ruby_block "update allowed_normal_attributes in client.rb" do
|
||||
block do
|
||||
whitelist = YAML.load_file("/etc/chef/chef_normal_attributes.yml")
|
||||
fe = Chef::Util::FileEdit.new("/etc/chef/client.rb")
|
||||
fe.search_file_replace_line(
|
||||
/^allowed_normal_attributes.*/,
|
||||
"allowed_normal_attributes #{whitelist.inspect}"
|
||||
)
|
||||
fe.write_file
|
||||
|
||||
Chef::Config[:allowed_normal_attributes] = whitelist
|
||||
Chef::Config[:normal_attribute_allowlist] = whitelist
|
||||
end
|
||||
not_if do
|
||||
whitelist = YAML.load_file("/etc/chef/chef_normal_attributes.yml")
|
||||
client_rb = ::File.read("/etc/chef/client.rb")
|
||||
whitelist.all? { |attr| client_rb.include?(attr) }
|
||||
end
|
||||
end
|
||||
|
||||
directory "/etc/apt/keyrings" do
|
||||
mode "0755"
|
||||
action :create
|
||||
@@ -107,8 +81,6 @@ unless node.chef_environment == "development"
|
||||
|
||||
include_recipe "kosmos-base::firewall"
|
||||
|
||||
include_recipe "kosmos-base::tmux"
|
||||
|
||||
include_recipe "kosmos-postfix"
|
||||
|
||||
node.override["set_fqdn"] = "*"
|
||||
|
||||
@@ -1,102 +0,0 @@
|
||||
#
|
||||
# Cookbook Name:: kosmos-base
|
||||
# Recipe:: tmux
|
||||
#
|
||||
|
||||
package "tmux"
|
||||
|
||||
plugins_dir = node["kosmos-base"]["tmux"]["plugins_dir"]
|
||||
default_conf = node["kosmos-base"]["tmux"]["default_conf"]
|
||||
tpm_redux = node["kosmos-base"]["tmux"]["tpm_redux"]
|
||||
plugins = node["kosmos-base"]["tmux"]["plugins"]
|
||||
|
||||
directory plugins_dir do
|
||||
owner "root"
|
||||
group "root"
|
||||
mode "0755"
|
||||
recursive true
|
||||
action :create
|
||||
end
|
||||
|
||||
# Install tpm-redux (the plugin manager) at a pinned commit.
|
||||
git "#{plugins_dir}/tpm-redux" do
|
||||
repository tpm_redux["repo"]
|
||||
revision tpm_redux["revision"]
|
||||
user "root"
|
||||
group "root"
|
||||
action :sync
|
||||
end
|
||||
|
||||
# Install each managed plugin at a pinned commit. Plugins are cloned by Chef
|
||||
# into a shared, root-owned directory so that users never need to install them
|
||||
# themselves.
|
||||
plugins.each do |shorthand, meta|
|
||||
git "#{plugins_dir}/#{shorthand.split('/').last}" do
|
||||
repository meta["repo"]
|
||||
revision meta["revision"]
|
||||
user "root"
|
||||
group "root"
|
||||
action :sync
|
||||
end
|
||||
end
|
||||
|
||||
# System default tmux config: minimal — only the plugin manager environment,
|
||||
# the @plugin declarations for the chef-managed plugins, and the tpm-redux
|
||||
# initialisation line (which must be the last line of the file).
|
||||
template default_conf do
|
||||
source "tmux.conf.default.erb"
|
||||
owner "root"
|
||||
group "root"
|
||||
mode "0644"
|
||||
variables(
|
||||
plugins_dir: plugins_dir,
|
||||
plugins: plugins
|
||||
)
|
||||
action :create
|
||||
end
|
||||
|
||||
# Write a per-user ~/.tmux.conf. Users who submit their own overrides as a
|
||||
# cookbook file at files/default/tmux_users/<username>.conf get a fully
|
||||
# managed config: it sources the system default (so chef-managed plugins
|
||||
# always load) and then appends the user's overrides. Users who have not
|
||||
# submitted a file get a blank importer written only if ~/.tmux.conf does
|
||||
# not already exist, so any hand-written/local config is left untouched.
|
||||
cookbook = run_context.cookbook_collection["kosmos-base"]
|
||||
|
||||
search(:users, "groups:sysadmin AND NOT action:remove") do |u|
|
||||
username = u["username"] || u["id"]
|
||||
home_dir = u["home"] || "/home/#{username}"
|
||||
group_name = u["gid"] || username
|
||||
|
||||
next unless Dir.exist?(home_dir)
|
||||
|
||||
user_conf_source = "tmux_users/#{username}.conf"
|
||||
|
||||
if cookbook.has_cookbook_file_for_node?(node, user_conf_source)
|
||||
disk_path = cookbook.preferred_filename_on_disk_location(node, :files, user_conf_source)
|
||||
# Chef reads ERB templates with IO.binread, so the template output buffer
|
||||
# is ASCII-8BIT. File.read returns UTF-8 on the node; concatenating a UTF-8
|
||||
# string into an ASCII-8BIT buffer raises an encoding error on non-ASCII
|
||||
# content. Retag as ASCII-8BIT to match the buffer — the raw bytes are
|
||||
# still valid UTF-8, so the written file is correct.
|
||||
user_content = File.read(disk_path).force_encoding("ASCII-8BIT")
|
||||
|
||||
template "#{home_dir}/.tmux.conf" do
|
||||
source "tmux.conf.user.erb"
|
||||
owner username
|
||||
group group_name
|
||||
mode "0644"
|
||||
variables(default_conf: default_conf, user_content: user_content)
|
||||
action :create
|
||||
end
|
||||
else
|
||||
template "#{home_dir}/.tmux.conf" do
|
||||
source "tmux.conf.user.erb"
|
||||
owner username
|
||||
group group_name
|
||||
mode "0644"
|
||||
variables(default_conf: default_conf, user_content: nil)
|
||||
action :create_if_missing
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,14 +0,0 @@
|
||||
# Managed by Chef (kosmos-base::tmux). Do not edit on this host.
|
||||
#
|
||||
# This is the system default tmux config. It is sourced by each user's
|
||||
# ~/.tmux.conf via `source-file`. Plugins are managed by Chef and live in
|
||||
# a shared, root-owned directory; users do not install plugins themselves.
|
||||
|
||||
set-environment -g TMUX_PLUGIN_MANAGER_PATH '<%= @plugins_dir %>'
|
||||
|
||||
<% @plugins.each do |shorthand, _meta| -%>
|
||||
set -g @plugin '<%= shorthand %>'
|
||||
<% end -%>
|
||||
|
||||
# Initialize TPM Redux (must remain the last line of the file)
|
||||
run '<%= @plugins_dir %>/tpm-redux/tpm'
|
||||
@@ -1,15 +0,0 @@
|
||||
# ~/.tmux.conf — created/managed by Chef (kosmos-base::tmux).
|
||||
#
|
||||
# This file imports the system default config below, then appends any overrides
|
||||
# the user has submitted to files/default/tmux_users/<username>.conf in the
|
||||
# kosmos-base cookbook. If you manage your own tmux config locally and have not
|
||||
# submitted a file, Chef will not overwrite it.
|
||||
|
||||
source-file <%= @default_conf %>
|
||||
|
||||
<% if @user_content && !@user_content.empty? -%>
|
||||
# === user overrides (from files/default/tmux_users/<username>.conf) ===
|
||||
<%= @user_content %>
|
||||
<% else -%>
|
||||
# === Add your custom settings below this line ===
|
||||
<% end -%>
|
||||
@@ -4,7 +4,8 @@ maintainer_email 'mail@kosmos.org'
|
||||
license 'MIT'
|
||||
description 'Installs/Configures zerotier'
|
||||
long_description 'Installs/Configures zerotier'
|
||||
version '0.1.0'
|
||||
version '0.2.0'
|
||||
chef_version '>= 14.0'
|
||||
|
||||
depends 'kosmos-base'
|
||||
depends 'zerotier'
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
#
|
||||
# Cookbook:: kosmos_zerotier
|
||||
# Recipe:: ohai_plugin
|
||||
#
|
||||
|
||||
include_recipe "zerotier::ohai_plugin"
|
||||
|
||||
ohai "reload_zerotier" do
|
||||
action :reload
|
||||
plugin "zerotier"
|
||||
notifies :run, "ruby_block[save_chef_zero_node]", :delayed
|
||||
end
|
||||
|
||||
# Force save the node back to disk in Chef Zero
|
||||
ruby_block "save_chef_zero_node" do
|
||||
block do
|
||||
node.save
|
||||
Chef::Log.info("Node #{node.name} saved to disk with ZeroTier data")
|
||||
end
|
||||
action :nothing
|
||||
end
|
||||
Reference in New Issue
Block a user