feat(ansible): add playbook for installing A13Labs systools with tasks for downloading, unpacking, and setting permissions
This commit is contained in:
@@ -1,3 +1,3 @@
|
|||||||
Match User git
|
Match User git
|
||||||
AuthorizedKeysCommandUser git
|
AuthorizedKeysCommandUser git
|
||||||
AuthorizedKeysCommand /usr/local/bin/gitea-auth -u %u -t %t -k %k
|
AuthorizedKeysCommand /usr/local/bin/k8s_gitea_auth -u %u -t %t -k %k
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
NAMESPACE=gitea
|
|
||||||
PREFIX=gitea-app
|
|
||||||
# Get the list of running pod names in the given namespace and filter by prefix
|
|
||||||
POD_NAME=$(/usr/local/bin/kubectl get pods -n "$NAMESPACE" -o json | jq -r --arg PREFIX "$PREFIX" '.items[] | select(.metadata.name | startswith($PREFIX)) | select(.status.phase == "Running") | .metadata.name' | head -n 1)
|
|
||||||
# Check if a running pod matching the prefix is found
|
|
||||||
if [ -z "$POD_NAME" ]; then
|
|
||||||
exit 1
|
|
||||||
else
|
|
||||||
/usr/local/bin/kubectl exec -n "$NAMESPACE" "$POD_NAME" -i -- su -s /bin/bash git -- /usr/local/bin/gitea keys -c /data/gitea/conf/app.ini -e git "$@"
|
|
||||||
fi
|
|
||||||
@@ -1,11 +1,4 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
NAMESPACE=gitea
|
NAMESPACE=gitea
|
||||||
PREFIX=gitea-app
|
PREFIX=gitea-app
|
||||||
# Get the list of running pod names in the given namespace and filter by prefix
|
/usr/local/bin/k8s_gitea_shell "$NAMESPACE" "$PREFIX" "$@"
|
||||||
POD_NAME=$(/usr/local/bin/kubectl get pods -n "$NAMESPACE" -o json | jq -r --arg PREFIX "$PREFIX" '.items[] | select(.metadata.name | startswith($PREFIX)) | select(.status.phase == "Running") | .metadata.name' | head -n 1)
|
|
||||||
# Remove the -c flag from the command
|
|
||||||
COMMAND=$(echo "$@" | sed "s/-c //g")
|
|
||||||
# Check if a running pod matching the prefix is found
|
|
||||||
if [ ! -z "$POD_NAME" ]; then
|
|
||||||
/usr/local/bin/kubectl exec -n "$NAMESPACE" "$POD_NAME" -i -- env SSH_ORIGINAL_COMMAND="$SSH_ORIGINAL_COMMAND" su -s /bin/bash git -- $COMMAND
|
|
||||||
fi
|
|
||||||
|
|||||||
@@ -0,0 +1,40 @@
|
|||||||
|
---
|
||||||
|
- name: Install A13Labs systools
|
||||||
|
hosts: ubuntu
|
||||||
|
gather_facts: true
|
||||||
|
|
||||||
|
# Specific tasks for this playbook
|
||||||
|
tasks:
|
||||||
|
- name: Set required facts
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
systools_verion: " {{ systools_version | default('0.0.1') }}"
|
||||||
|
tags: always
|
||||||
|
|
||||||
|
- name: Download systools zip file
|
||||||
|
ansible.builtin.get_url:
|
||||||
|
url: https://github.com/a13labs/systools/releases/download/v{{ systools_version }}/systools-v{{ systools_version }}-linux-amd64.zip
|
||||||
|
dest: /tmp/systools-v{{ systools_version }}-linux-amd64.zip
|
||||||
|
mode: '0644'
|
||||||
|
|
||||||
|
- name: Unpack systools zip file
|
||||||
|
ansible.builtin.unarchive:
|
||||||
|
src: /tmp/systools-v{{ systools_version }}-linux-amd64.zip
|
||||||
|
dest: /usr/local/bin
|
||||||
|
remote_src: true
|
||||||
|
mode: '0755'
|
||||||
|
extra_opts:
|
||||||
|
- -j
|
||||||
|
|
||||||
|
- name: Remove systools zip file
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: /tmp/systools-v{{ systools_version }}-linux-amd64.zip
|
||||||
|
state: absent
|
||||||
|
|
||||||
|
- name: Set root-only executable permissions for specific tools
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: /usr/local/bin/{{ item }}
|
||||||
|
mode: '0750'
|
||||||
|
loop:
|
||||||
|
- open_volume
|
||||||
|
- read_system_id
|
||||||
|
- k8s_encryption_provider
|
||||||
@@ -92,9 +92,6 @@ resource "kubernetes_deployment" "gitea" {
|
|||||||
requests = {
|
requests = {
|
||||||
memory = "100Mi"
|
memory = "100Mi"
|
||||||
}
|
}
|
||||||
limits = {
|
|
||||||
memory = "300Mi"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
liveness_probe {
|
liveness_probe {
|
||||||
|
|||||||
@@ -191,9 +191,6 @@ resource "kubernetes_deployment" "website" {
|
|||||||
requests = {
|
requests = {
|
||||||
memory = "100Mi"
|
memory = "100Mi"
|
||||||
}
|
}
|
||||||
limits = {
|
|
||||||
memory = "500Mi"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
readiness_probe {
|
readiness_probe {
|
||||||
|
|||||||
@@ -1,11 +0,0 @@
|
|||||||
BINARY=open_volume
|
|
||||||
|
|
||||||
.PHONY: all build clean
|
|
||||||
|
|
||||||
all: build
|
|
||||||
|
|
||||||
build:
|
|
||||||
go build -o $(BINARY) main.go
|
|
||||||
|
|
||||||
clean:
|
|
||||||
rm -f $(BINARY)
|
|
||||||
@@ -1,126 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"crypto/md5"
|
|
||||||
"encoding/hex"
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"io/ioutil"
|
|
||||||
"log"
|
|
||||||
"net"
|
|
||||||
"net/http"
|
|
||||||
"os"
|
|
||||||
"os/exec"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
func usage() {
|
|
||||||
fmt.Printf("Usage: %s <keyserver> <image> <device>\n", os.Args[0])
|
|
||||||
fmt.Printf("Example: %s https://keyserver.example.com /path/to/image.img <device>\n", os.Args[0])
|
|
||||||
fmt.Printf("Example: %s https://keyserver.example.com /path/to/image.img /dev/mapper/crypt1\n", os.Args[0])
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
func fileExists(path string) bool {
|
|
||||||
_, err := os.Stat(path)
|
|
||||||
return err == nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func deviceExists(device string) bool {
|
|
||||||
_, err := os.Stat("/dev/mapper/" + device)
|
|
||||||
return err == nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func keyserverReachable(url string) bool {
|
|
||||||
resp, err := http.Head(url)
|
|
||||||
if err != nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
resp.Body.Close()
|
|
||||||
return resp.StatusCode < 400
|
|
||||||
}
|
|
||||||
|
|
||||||
func getUUID() string {
|
|
||||||
// Get CPU model name
|
|
||||||
cpuinfo, _ := ioutil.ReadFile("/proc/cpuinfo")
|
|
||||||
var model string
|
|
||||||
for _, line := range strings.Split(string(cpuinfo), "\n") {
|
|
||||||
if strings.HasPrefix(line, "model name") {
|
|
||||||
model = line
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Get eth0 MAC address
|
|
||||||
iface, err := net.InterfaceByName("eth0")
|
|
||||||
mac := ""
|
|
||||||
if err == nil {
|
|
||||||
mac = iface.HardwareAddr.String()
|
|
||||||
}
|
|
||||||
// Get system UUID
|
|
||||||
out, _ := exec.Command("sudo", "dmidecode", "-s", "system-uuid").Output()
|
|
||||||
sysuuid := strings.TrimSpace(string(out))
|
|
||||||
uuid := model + mac + sysuuid
|
|
||||||
return uuid
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
log.SetFlags(0)
|
|
||||||
if len(os.Args) != 4 {
|
|
||||||
usage()
|
|
||||||
}
|
|
||||||
keyserver := os.Args[1]
|
|
||||||
image := os.Args[2]
|
|
||||||
device := os.Args[3]
|
|
||||||
|
|
||||||
if !fileExists(image) {
|
|
||||||
log.Printf("open_volume: (%s) Image file not found", device)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
if !keyserverReachable(keyserver) {
|
|
||||||
log.Printf("open_volume: (%s) Key server not reachable, exiting.", device)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
if deviceExists(device) {
|
|
||||||
fmt.Printf("open_volume: (%s) Device already open, exiting.\n", device)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
uuid := getUUID()
|
|
||||||
h := md5.Sum([]byte(uuid))
|
|
||||||
keyid := hex.EncodeToString(h[:])
|
|
||||||
|
|
||||||
log.Printf("open_volume: (%s) Downloading key from key server,", device)
|
|
||||||
keyurl := fmt.Sprintf("%s/%s", keyserver, keyid)
|
|
||||||
resp, err := http.Get(keyurl)
|
|
||||||
if err != nil || resp.StatusCode != 200 {
|
|
||||||
log.Printf("open_volume: (%s) Failed to download key from key server", device)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
defer resp.Body.Close()
|
|
||||||
|
|
||||||
tmpfile, err := ioutil.TempFile("", "keyfile")
|
|
||||||
if err != nil {
|
|
||||||
log.Printf("open_volume: (%s) Failed to create temp file", device)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
defer os.Remove(tmpfile.Name())
|
|
||||||
_, err = io.Copy(tmpfile, resp.Body)
|
|
||||||
tmpfile.Close()
|
|
||||||
if err != nil {
|
|
||||||
log.Printf("open_volume: (%s) Failed to save key file", device)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Printf("open_volume:'%s' Key downloaded successfully, opening volume", device)
|
|
||||||
cmd := exec.Command("/usr/sbin/cryptsetup", "luksOpen", image, device, "-d", tmpfile.Name())
|
|
||||||
out, err := cmd.CombinedOutput()
|
|
||||||
if err != nil {
|
|
||||||
log.Printf("open_volume: (%s) Failed to open volume: %s", device, string(out))
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Printf("open_volume: (%s) Volume opened successfully, removing key file", device)
|
|
||||||
os.Exit(0)
|
|
||||||
}
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
BINARY=read_system_id
|
|
||||||
|
|
||||||
.PHONY: all build clean
|
|
||||||
|
|
||||||
all: build
|
|
||||||
|
|
||||||
build:
|
|
||||||
go build -o $(BINARY) main.go
|
|
||||||
|
|
||||||
clean:
|
|
||||||
rm -f $(BINARY)
|
|
||||||
@@ -1,79 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bufio"
|
|
||||||
"crypto/md5"
|
|
||||||
"encoding/hex"
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"os"
|
|
||||||
"os/exec"
|
|
||||||
"regexp"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
func getModelName() string {
|
|
||||||
file, err := os.Open("/proc/cpuinfo")
|
|
||||||
if err != nil {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
defer file.Close()
|
|
||||||
scanner := bufio.NewScanner(file)
|
|
||||||
re := regexp.MustCompile(`^model name\s*:\s*(.*)$`)
|
|
||||||
for scanner.Scan() {
|
|
||||||
line := scanner.Text()
|
|
||||||
if matches := re.FindStringSubmatch(line); matches != nil {
|
|
||||||
return matches[1]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
func getEth0Mac() string {
|
|
||||||
out, err := exec.Command("ip", "link").Output()
|
|
||||||
if err != nil {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
re := regexp.MustCompile(`^(\d+):\s+([a-zA-Z0-9]+):.*<.*>\s+link/ether\s+([0-9a-f:]{17})`)
|
|
||||||
matches := re.FindAllStringSubmatch(string(out), -1)
|
|
||||||
fmt.Println("Matches:", matches)
|
|
||||||
if len(matches) == 0 {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
first_device := matches[0][2]
|
|
||||||
fmt.Println("First device:", first_device)
|
|
||||||
// Get the MAC address of the first device
|
|
||||||
out, err = exec.Command("ip", "link", "show", first_device).Output()
|
|
||||||
if err != nil {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
re = regexp.MustCompile(`ether\s+([0-9a-f:]{17})`)
|
|
||||||
match := re.FindStringSubmatch(string(out))
|
|
||||||
if match != nil {
|
|
||||||
return match[1]
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
func getSystemUUID() string {
|
|
||||||
out, err := exec.Command("sudo", "dmidecode", "-s", "system-uuid").Output()
|
|
||||||
if err != nil {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
return strings.TrimSpace(string(out))
|
|
||||||
}
|
|
||||||
|
|
||||||
func md5sum(s string) string {
|
|
||||||
h := md5.New()
|
|
||||||
io.WriteString(h, s)
|
|
||||||
return hex.EncodeToString(h.Sum(nil))
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
uuid := getModelName()
|
|
||||||
uuid += getEth0Mac()
|
|
||||||
uuid += getSystemUUID()
|
|
||||||
fmt.Println(uuid)
|
|
||||||
hash := md5sum(uuid)
|
|
||||||
fmt.Println(hash)
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
uuid=$(cat /proc/cpuinfo | grep 'model name' | head -1)
|
|
||||||
uuid+=$(ip link show wlo1 | grep ether | awk '{print $2}')
|
|
||||||
uuid+=$(sudo dmidecode -s system-uuid)
|
|
||||||
echo "UUID: $uuid"
|
|
||||||
echo -n "$uuid" | md5sum | awk '{print $1}'
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
BINARY=start_encryption_provider
|
|
||||||
|
|
||||||
.PHONY: all build clean
|
|
||||||
|
|
||||||
all: build
|
|
||||||
|
|
||||||
build:
|
|
||||||
go build -o $(BINARY) main.go
|
|
||||||
|
|
||||||
clean:
|
|
||||||
rm -f $(BINARY)
|
|
||||||
@@ -1,130 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"crypto/md5"
|
|
||||||
"encoding/hex"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"log"
|
|
||||||
"net"
|
|
||||||
"net/http"
|
|
||||||
"os"
|
|
||||||
"os/exec"
|
|
||||||
"path/filepath"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Credentials struct {
|
|
||||||
AccessKey string `json:"access_key"`
|
|
||||||
SecretKey string `json:"secret_key"`
|
|
||||||
KeyArn string `json:"key_arn"`
|
|
||||||
Region string `json:"region"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
if len(os.Args) < 2 {
|
|
||||||
fmt.Printf("Usage: %s <keyserver> [socket]\n", os.Args[0])
|
|
||||||
fmt.Printf("Example: %s https://keyserver.example.com\n", os.Args[0])
|
|
||||||
fmt.Printf("Example: %s https://keyserver.example.com /var/run/kmsplugin/socket.sock\n", os.Args[0])
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
keyserver := os.Args[1]
|
|
||||||
socket := "/var/run/kmsplugin/socket.sock"
|
|
||||||
if len(os.Args) > 2 {
|
|
||||||
socket = os.Args[2]
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if keyserver is reachable
|
|
||||||
resp, err := http.Head(keyserver)
|
|
||||||
if err != nil || resp.StatusCode >= 400 {
|
|
||||||
log.Println("Key server not reachable, exiting.")
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generate UUID
|
|
||||||
uuid := getCPUModel() + getEth0MAC() + getSystemUUID()
|
|
||||||
keyID := md5sum(uuid)
|
|
||||||
|
|
||||||
log.Println("Downloading key from key server")
|
|
||||||
keyURL := fmt.Sprintf("%s/%s-encryption-service-credentials.json", keyserver, keyID)
|
|
||||||
resp, err = http.Get(keyURL)
|
|
||||||
if err != nil || resp.StatusCode != 200 {
|
|
||||||
log.Println("Failed to download key from key server")
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
defer resp.Body.Close()
|
|
||||||
body, err := io.ReadAll(resp.Body) // Changed from ioutil.ReadAll
|
|
||||||
if err != nil {
|
|
||||||
log.Println("Failed to read key file")
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
var creds Credentials
|
|
||||||
if err := json.Unmarshal(body, &creds); err != nil {
|
|
||||||
log.Println("Failed to extract credentials from key file")
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
os.Setenv("AWS_ACCESS_KEY_ID", creds.AccessKey)
|
|
||||||
os.Setenv("AWS_SECRET_ACCESS_KEY", creds.SecretKey)
|
|
||||||
|
|
||||||
// Prepare socket dir
|
|
||||||
socketDir := filepath.Dir(socket)
|
|
||||||
os.MkdirAll(socketDir, 0700)
|
|
||||||
os.Chmod(socketDir, 0700)
|
|
||||||
|
|
||||||
if _, err := os.Stat("/usr/local/bin/aws-encryption-provider"); os.IsNotExist(err) {
|
|
||||||
log.Println("Encryption provider not found, exiting.")
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
cmd := exec.Command("/usr/local/bin/aws-encryption-provider",
|
|
||||||
"--key="+creds.KeyArn,
|
|
||||||
"--region="+creds.Region,
|
|
||||||
"--listen="+socket,
|
|
||||||
)
|
|
||||||
cmd.Stdout = os.Stdout
|
|
||||||
cmd.Stderr = os.Stderr
|
|
||||||
if err := cmd.Run(); err != nil {
|
|
||||||
log.Println("Failed to start encryption provider")
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
os.Exit(0)
|
|
||||||
}
|
|
||||||
|
|
||||||
func getCPUModel() string {
|
|
||||||
data, err := os.ReadFile("/proc/cpuinfo") // Changed from ioutil.ReadFile
|
|
||||||
if err != nil {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
for _, line := range strings.Split(string(data), "\n") {
|
|
||||||
if strings.HasPrefix(line, "model name") {
|
|
||||||
return line
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
func getEth0MAC() string {
|
|
||||||
iface, err := net.InterfaceByName("eth0")
|
|
||||||
if err != nil {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
return iface.HardwareAddr.String()
|
|
||||||
}
|
|
||||||
|
|
||||||
func getSystemUUID() string {
|
|
||||||
out, err := exec.Command("sudo", "dmidecode", "-s", "system-uuid").Output()
|
|
||||||
if err != nil {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
return strings.TrimSpace(string(out))
|
|
||||||
}
|
|
||||||
|
|
||||||
func md5sum(s string) string {
|
|
||||||
h := md5.New()
|
|
||||||
io.WriteString(h, s)
|
|
||||||
return hex.EncodeToString(h.Sum(nil))
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user