Added bash, kerberos and bind-tools to dockerfile. Updated for shell execution.

This commit is contained in:
Chris Stuurman 2024-04-01 01:12:14 +02:00
parent 91aa18dfe2
commit e064ae8dad
12 changed files with 236 additions and 73 deletions

1
.gitignore vendored
View File

@ -9,3 +9,4 @@ _test
icon
vendor
_out
bin/buildversion.exe

View File

@ -1,10 +1,17 @@
FROM golang:1.21-alpine3.18 AS build_deps
RUN apk add --no-cache git
# Let scripts know we're running in Docker (useful for containerised development)
ENV RUNNING_IN_DOCKER true
ENV DEBIAN_FRONTEND=noninteractive
ENV TZ="Africa/Johannesburg"
# Set up ZSH and our preferred terminal environment for containers
RUN apk add --no-cache git
WORKDIR /workspace
COPY go.mod .
COPY go.sum .
RUN go mod download
@ -19,6 +26,21 @@ FROM alpine:3.18
RUN apk add --no-cache ca-certificates
RUN apk add --no-cache bash bind-tools coreutils krb5
COPY ./config/bash.sh /root/.bashrc
#COPY ./config/krb5.conf /etc
RUN chown -R root:root /root/.bashrc && \
/bin/bash /root/.bashrc
RUN apk add --no-cache alpine-conf && \
setup-timezone -z Africa/Johannesburg
# chmod 0644 /etc/krb5.conf
#RUN mkdir -p /app
#COPY ./config/updatedns.sh /app
#RUN chmod 0744 /app/updatedns.sh
COPY --from=build /workspace/webhook /usr/local/bin/webhook
ENTRYPOINT ["webhook"]

View File

@ -23,6 +23,11 @@ bin/buildversion.exe: cmd/buildversion.go
go build -o bin/buildversion.exe cmd/buildversion.go
set TMP="C:\Users\Chris\AppData\Local\Temp"
#bin/cert-manager-webhook-sthome.exe: dependencies version.txt
# set TMP="C:\Temp\gotemp"
# go build -o bin/cert-manager-webhook-sthome.exe
# set TMP="C:\Users\Chris\AppData\Local\Temp"
version.txt: bin/buildversion.exe dependencies
bin/buildversion.exe
@ -42,16 +47,11 @@ _test/kubebuilder-$(KUBEBUILDER_VERSION)-$(OS)-$(ARCH)/etcd _test/kubebuilder-$(
clean:
rm -r _test $(OUT)
.PHONY: package
package: rendered-manifest.yaml
helm package deploy\sthome-webhook -d \\\truenas\Shared_data\Chris\clusterissuer\charts\
.PHONY: build
build: rendered-manifest.yaml dependencies version.txt
docker build -t "$(IMAGE_NAME):$(shell head -n 1 version.txt)" .
docker tag $(IMAGE_NAME) "docker.io/stuurmcp/$(IMAGE_NAME):$(shell head -n 1 version.txt)"
docker image push "stuurmcp/$(IMAGE_NAME):$(shell head -n 1 version.txt)"
helm package deploy\sthome-webhook -d \\\truenas\Shared_data\Chris\clusterissuer\charts\
build: rendered-manifest.yaml dependencies bin/buildversion.exe version.txt
docker build --pull --rm -f "Dockerfile" -t "stuurmcp/$(IMAGE_NAME):latest" -t "stuurmcp/$(IMAGE_NAME):$(shell head -n 1 version.txt)" "."
docker image push "docker.io/stuurmcp/$(IMAGE_NAME):$(shell head -n 1 version.txt)"
helm package deploy/sthome-webhook -d //truenas/Shared_data/Chris/clusterissuer/charts/
.PHONY: rendered-manifest.yaml
rendered-manifest.yaml: $(OUT)/rendered-manifest.yaml

View File

@ -10,23 +10,21 @@ import (
)
const (
version = "0.0.3-alpha"
version = "0.0.4-alpha"
chartfile = "./deploy/sthome-webhook/Chart.yaml"
valuesfile = "./deploy/sthome-webhook/values.yaml"
tagprefix = " tag: "
versiontxt = "./version.txt"
vertxtfile = "./version.txt"
apiVersion = "v1"
description = "Cert-Manager webhook for sthome"
name = "sthome-webhook"
)
var (
mfimagetag string
vfimagetag string
buildTime string
appVersion string
longversion string
versiontext string
buildTime string
appVersion string
longversion string
multilineversion string
)
func main() {
@ -46,13 +44,12 @@ func main() {
bNum, _ := strconv.Atoi(vLines[2])
bNum++
longversion = version + "." + fmt.Sprint(bNum)
mfimagetag = longversion
appVersion = "v" + longversion
// Generate a single string to write back to the file
versiontext = longversion + "\n" + buildTime + "\n" + fmt.Sprint(bNum)
multilineversion = longversion + "\n" + buildTime + "\n" + fmt.Sprint(bNum)
chartStr := "apiVersion: " + apiVersion + "\nappVersion: " + appVersion + "\ndescription: " + description + "\nname: " + name + "\nversion: " + longversion + "\n"
// Write the data back to the file.
_ = os.WriteFile(versiontxt, []byte(versiontext), 0777)
_ = os.WriteFile(vertxtfile, []byte(multilineversion), 0777)
_ = os.WriteFile(chartfile, []byte(chartStr), 0777)
replacetxtfilelines(valuesfile, tagprefix, tagprefix+longversion)
}

29
config/bash.sh Normal file
View File

@ -0,0 +1,29 @@
# ~/.bashrc: executed by bash(1) for non-login shells.
#
# Note: PS1 and umask are already set in /etc/profile. You should not
# need this unless you want different defaults for root.
# PS1='${debian_chroot:+($debian_chroot)}\h:\w\$ '
# umask 022
#
# You may uncomment the following lines if you want `ls' to be colorized:
# export LS_OPTIONS='--color=auto'
# eval "$(dircolors)"
# alias ls='ls $LS_OPTIONS'
# alias ll='ls $LS_OPTIONS -l'
# alias l='ls $LS_OPTIONS -lA'
#
alias h='fc -l'
alias j=jobs
alias m=$PAGER
alias ll='ls -laFo'
alias l='ls -l'
alias g='egrep -i'
alias dnsupd=/acme/updatedns.sh
#
# Some more alias to avoid making mistakes:
# alias rm='rm -i'
# alias cp='cp -i'
# alias mv='mv -i'
export PATH=/root/bin:$PATH:/acme
export FRONTEND=noninteractive
export TZ=Africa/Johannesburg

34
config/zsh.sh Normal file
View File

@ -0,0 +1,34 @@
HISTFILE=~/.zsh-histfile
SAVEHIST=1000
setopt APPEND_HISTORY
PROMPT="%n@%m[%40<...<%~%<<]%(!.#.$) "
bindkey "^[[A" up-line-or-search
bindkey "^[[F" end-of-line
bindkey "^[[H" beginning-of-line
bindkey "^[[3~" delete-char
# Enable the builtin emacs(1) command line editor in sh(1),
# e.g. C-a -> beginning-of-line.
set -o emacs
# Uncomment this and comment the above to enable the builtin vi(1) command
# line editor in sh(1), e.g. ESC to go into visual mode.
# set -o vi
# some useful aliases
alias h='fc -l'
alias j=jobs
alias m=$PAGER
alias ll='ls -laFo'
alias l='ls -l'
alias g='egrep -i'
alias dnsupd=/acme/updatedns.sh
# # be paranoid
# alias cp='cp -ip'
# alias mv='mv -i'
# alias rm='rm -i'
export PATH=/root/bin:$PATH

View File

@ -1,5 +1,5 @@
apiVersion: v1
appVersion: v0.0.3-alpha.42
appVersion: v0.0.4-alpha.86
description: Cert-Manager webhook for sthome
name: sthome-webhook
version: 0.0.3-alpha.42
version: 0.0.4-alpha.86

View File

@ -54,12 +54,26 @@ spec:
- name: certs
mountPath: /tls
readOnly: true
- name: scriptdir
mountPath: /acme
readOnly: false
- name: workdir
mountPath: /workdir
readOnly: false
resources:
{{ toYaml .Values.resources | indent 12 }}
volumes:
- name: certs
secret:
secretName: {{ include "sthome-webhook.servingCertificate" . }}
- name: scriptdir
hostPath:
path: {{ .Values.host.scriptdir }}
- name: workdir
hostPath:
path: {{ .Values.host.workdir}}
{{- with .Values.nodeSelector }}
nodeSelector:
{{ toYaml . | indent 8 }}

View File

@ -31,7 +31,7 @@ clusterIssuer:
image:
repository: stuurmcp/cert-manager-webhook-sthome
#repository: wstat.sthome.net:5000/cert-manager-webhook-sthome
tag: 0.0.3-alpha.42
tag: 0.0.4-alpha.86
#pullPolicy should be IfNotPresent. Set to Always for testing purposes
pullPolicy: IfNotPresent
@ -47,6 +47,10 @@ pki:
caDuration: 43800h # 5y
servingCertificateDuration: 8760h # 1y
host:
workdir: /mnt/stpool1/scripts/acme/cert-manager-webhook-sthome
scriptdir: /mnt/stpool1/scripts/acme
secret:
accessKey: ""
secretKey: ""

View File

@ -1,39 +1,45 @@
package sthome
import (
"log"
"os"
"os/exec"
"os/user"
//"bytes"
"k8s.io/klog/v2"
)
func Execute(dir string, script string, command []string) (bool, error) {
currentUser, err := user.Current()
if err != nil {
log.Fatalf("CZ: Unable to get current user: %s", err)
}
klog.InfoS("CZ: Executing ", "user", currentUser.Name, "script", command)
cmd := &exec.Cmd{
Dir: dir,
Path: script,
Args: command,
Stdout: os.Stdout,
Stderr: os.Stderr,
}
type saveOutput struct {
buffer []byte
}
err = cmd.Run()
func (so *saveOutput) Write(p []byte) (n int, err error) {
so.buffer = append(so.buffer, p...)
return os.Stdout.Write(p)
}
func Execute(shell string, command []string) (bool, error) {
var so saveOutput
//var buffer bytes.Buffer
/*
currentUser, err := user.Current()
if err != nil {
klog.Fatalf("CZ: Unable to get current user: %s", err)
}
klog.Infof("CZ: Executing as user %s : %s %v\n", currentUser.Name, shell, command)
*/
cmd := &exec.Cmd{
Path: shell,
Args: command,
}
cmd.Stdin = os.Stdin
cmd.Stdout = &so //&buffer
cmd.Stderr = os.Stderr
err := cmd.Run()
if err != nil {
klog.Errorf("CZ: Script run return error: %s\n", err)
klog.Errorf("Script return error: %s\n%s\n", err, string(so.buffer))
return false, err
}
/*
err = cmd.Wait()
if err != nil {
klog.Errorf("CZ: Script Wait return error: %s\n", err)
return false, err
}
*/
klog.Infof("Script returned success:\n%s\n", string(so.buffer))
return true, nil
}

View File

@ -2,6 +2,7 @@ package sthome
import (
"fmt"
"net"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"
@ -13,8 +14,13 @@ import (
const (
providerName = "sthome"
dnsUpdaterScriptDir = "/mnt/stpool1/scripts/acme/"
dnsUpdaterScriptCmd = "updatedns.sh"
shell = "/bin/bash"
dnsUpdaterScriptCmd = "/acme/updatedns.sh"
dnsserver_net = "10.0.0.15"
dnsserver_lan = "192.168.2.1"
hostserver_net = "truenas.sthome.net"
hostserver_lan = "truenas.sthome.lan"
)
// LocalDNSProviderSolver implements the provider-specific logic needed to
@ -73,21 +79,39 @@ func (loc *LocalDNSProviderSolver) Present(ch *v1alpha1.ChallengeRequest) error
}
*/
// TODO: do something more useful with the decoded configuration
fmt.Printf("CZ: Decoded configuration %v", cfg)
klog.InfoS("CZ: presenting record for ", ch.DNSName, ch.ResolvedFQDN, "domain", domainName)
klog.Infof("Decoded configuration %v\n", cfg)
klog.Infof("Presenting record for %s, ch: %s, domain: %s", ch.DNSName, ch.ResolvedFQDN, domainName)
// TODO: convert shell script to golang
localip := getOutboundIP(dnsserver_net)
// shell command
command := []string{
settxtcommand := []string{
shell,
dnsUpdaterScriptCmd,
"arg1=-set",
"arg2=.net",
fmt.Sprintf("arg3=%s", ch.DNSName),
"arg4=TXT",
fmt.Sprintf("arg5=%s", ch.Key),
"-set",
".net",
ch.DNSName,
"TXT",
ch.Key,
"-v",
"-l",
localip,
}
success, _ := Execute(dnsUpdaterScriptDir, dnsUpdaterScriptCmd, command)
klog.InfoS("CZ: Execute set returned", "success", success)
unsetcnamecommand := []string{
shell,
dnsUpdaterScriptCmd,
"-unset",
".net",
ch.DNSName,
"CNAME",
hostserver_net,
"-v",
"-l",
localip,
}
success, _ := Execute(shell, unsetcnamecommand)
klog.Infof("Execute unset CNAME returned success: %t", success)
success, _ = Execute(shell, settxtcommand)
klog.Infof("Execute set TXT returned success: %t", success)
return nil
}
@ -99,18 +123,36 @@ func (loc *LocalDNSProviderSolver) Present(ch *v1alpha1.ChallengeRequest) error
// concurrently.
func (loc *LocalDNSProviderSolver) CleanUp(ch *v1alpha1.ChallengeRequest) error {
// TODO: add code that deletes a record from the DNS provider's console
localip := getOutboundIP(dnsserver_net)
// shell command
command := []string{
unsetxtcommand := []string{
shell,
dnsUpdaterScriptCmd,
"arg1=-unset",
"arg2=.net",
fmt.Sprintf("arg3=%s", ch.DNSName),
"arg4=TXT",
fmt.Sprintf("arg5=%s", ch.Key),
"-unset",
".net",
ch.DNSName,
"TXT",
ch.Key,
"-v",
"-l",
localip,
}
success, _ := Execute(dnsUpdaterScriptDir, dnsUpdaterScriptCmd, command)
klog.InfoS("CZ: Execute unset returned", "success", success)
setcnamecommand := []string{
shell,
dnsUpdaterScriptCmd,
"-set",
".net",
ch.DNSName,
"CNAME",
hostserver_net,
"-v",
"-l",
localip,
}
success, _ := Execute(shell, unsetxtcommand)
klog.Infof("Execute unset TXT returned success: %t", success)
success, _ = Execute(shell, setcnamecommand)
klog.Infof("Execute set CNAME returned success: %t", success)
return nil
}
@ -141,3 +183,17 @@ func extractDomainName(zone string) string {
}
return util.UnFqdn(authZone)
}
// Get preferred outbound ip of this machine
func getOutboundIP(dest string) string {
conn, err := net.Dial("udp", dest+":80")
if err != nil {
klog.Errorf("net.Dial error: %s", err)
return "0.0.0.0"
}
defer conn.Close()
localAddr := conn.LocalAddr().(*net.UDPAddr)
return localAddr.IP.String()
}

View File

@ -1,3 +1,3 @@
0.0.3-alpha.42
20240330-0218
42
0.0.4-alpha.86
20240331-2359
86