6 Commits

Author SHA1 Message Date
4ebb402015 fixed stupid bug
All checks were successful
Build and Push Docker Image / Build image (push) Successful in 1m45s
2025-04-09 17:15:02 +03:00
a54c905cc7 updated deployment to latest version
Some checks failed
Build and Push Docker Image / Build image (push) Has been cancelled
2025-04-07 13:48:24 +03:00
8f005effa3 fixed bug where server ports is nil
Some checks failed
Build and Push Docker Image / Build image (push) Has been cancelled
2025-04-07 13:45:53 +03:00
7776d546e9 fixed bug where server ports is nil
All checks were successful
Build and Push Docker Image / Build image (push) Successful in 1m45s
2025-04-07 13:36:07 +03:00
7ef824830e added command and args to status
Some checks failed
Build and Push Docker Image / Build image (push) Has been cancelled
2025-04-05 22:35:43 +03:00
39f1c0d92c added config path to file
Some checks failed
Build and Push Docker Image / Build image (push) Has been cancelled
2025-04-05 17:15:00 +03:00
10 changed files with 144 additions and 53 deletions

View File

@@ -44,6 +44,8 @@ type ServerStatus struct {
Domain string `json:"domain,omitempty"`
Running bool `json:"running,omitempty"`
HostPorts []PortMapping `json:"host_ports,omitempty"`
Args []string `json:"args,omitempty"`
Command []string `json:"command,omitempty"`
}
type ServerSpec struct {

View File

@@ -333,6 +333,16 @@ func (in *ServerStatus) DeepCopyInto(out *ServerStatus) {
*out = make([]PortMapping, len(*in))
copy(*out, *in)
}
if in.Args != nil {
in, out := &in.Args, &out.Args
*out = make([]string, len(*in))
copy(*out, *in)
}
if in.Command != nil {
in, out := &in.Command, &out.Command
*out = make([]string, len(*in))
copy(*out, *in)
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServerStatus.

View File

@@ -146,8 +146,13 @@ func main() {
setupLog.Error(err, "unable to start manager")
os.Exit(1)
}
configPath := os.Getenv("CONFIG_PATH")
if configPath == "" {
configPath = "config.yaml"
}
config := &controller.ServerManagerReconcilerConfig{}
configData, err := os.ReadFile("config.yaml")
configData, err := os.ReadFile(configPath)
if err != nil {
setupLog.Error(err, "unable to read config file")
}

View File

@@ -94,6 +94,14 @@ spec:
INSERT ADDITIONAL STATUS FIELD - define observed state of cluster
Important: Run "make" to regenerate code after modifying this file
properties:
args:
items:
type: string
type: array
command:
items:
type: string
type: array
domain:
type: string
host_ports:

View File

@@ -0,0 +1,31 @@
# https://kubernetes.io/docs/concepts/configuration/configmap/
apiVersion: v1
kind: ConfigMap
metadata:
name: server-manager-config
namespace: server-manager
data:
config.yaml: |
domain_label: "ddns.acooldomain.co/hostname"
default_domain: "acooldomain.co"
browser:
domain: games.acooldomain.co
sub_path: /browsers
auth_header: x-authentik-username
cert_resolver: letsencrypt
entrypoints:
- websecure
additional_routes:
- kind: Rule
match: "Host(`games.acooldomain.co`) && PathPrefix(`/outpost.goauthentik.io/`)"
priority: 15
services:
- kind: Service
name: ak-outpost-traefik
namespace: authentik
port: 9000
middleware:
name: authentik
namespace: authentik

View File

@@ -1,2 +1,3 @@
resources:
- manager.yaml
- config.yaml
- manager.yaml

View File

@@ -5,13 +5,13 @@ metadata:
control-plane: controller-manager
app.kubernetes.io/name: kubernetes-operator
app.kubernetes.io/managed-by: kustomize
name: system
name: server-manager
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: controller-manager
namespace: system
namespace: server-manager
labels:
control-plane: controller-manager
app.kubernetes.io/name: kubernetes-operator
@@ -48,6 +48,11 @@ spec:
# operator: In
# values:
# - linux
volumes:
- name: config
configMap:
name: server-manager-config
securityContext:
runAsNonRoot: true
# TODO(user): For common cases that do not require escalating privileges
@@ -55,41 +60,44 @@ spec:
# More info: https://kubernetes.io/docs/concepts/security/pod-security-standards/#restricted
# Please uncomment the following code if your project does NOT have to work on old Kubernetes
# versions < 1.19 or on vendors versions which do NOT support this field by default (i.e. Openshift < 4.11 ).
# seccompProfile:
# type: RuntimeDefault
seccompProfile:
type: RuntimeDefault
containers:
- command:
- /manager
args:
- --leader-elect
- --health-probe-bind-address=:8081
image: controller:latest
name: manager
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- "ALL"
livenessProbe:
httpGet:
path: /healthz
port: 8081
initialDelaySeconds: 15
periodSeconds: 20
readinessProbe:
httpGet:
path: /readyz
port: 8081
initialDelaySeconds: 5
periodSeconds: 10
# TODO(user): Configure the resources accordingly based on the project requirements.
# More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
resources:
limits:
cpu: 500m
memory: 128Mi
requests:
cpu: 10m
memory: 64Mi
serviceAccountName: controller-manager
- command:
- /manager
image: git.acooldomain.co/server-manager/kubernetes-operator:v0.0.5
env:
- name: CONFIG_PATH
value: /etc/server-manager/config.yaml
volumeMounts:
- name: config
mountPath: /etc/server-manager
name: manager
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- "ALL"
livenessProbe:
httpGet:
path: /healthz
port: 8081
initialDelaySeconds: 15
periodSeconds: 20
readinessProbe:
httpGet:
path: /readyz
port: 8081
initialDelaySeconds: 5
periodSeconds: 10
# TODO(user): Configure the resources accordingly based on the project requirements.
# More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
resources:
limits:
cpu: 500m
memory: 128Mi
requests:
cpu: 10m
memory: 64Mi
serviceAccountName: server-manager
terminationGracePeriodSeconds: 10

View File

@@ -4,12 +4,12 @@ metadata:
labels:
app.kubernetes.io/name: kubernetes-operator
app.kubernetes.io/managed-by: kustomize
name: manager-rolebinding
name: server-manager-rolebinding
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: manager-role
name: server-manager-role
subjects:
- kind: ServiceAccount
name: controller-manager
namespace: system
- kind: ServiceAccount
name: server-manager
namespace: server-manager

View File

@@ -4,5 +4,5 @@ metadata:
labels:
app.kubernetes.io/name: kubernetes-operator
app.kubernetes.io/managed-by: kustomize
name: controller-manager
namespace: system
name: server-manager
namespace: server-manager

View File

@@ -157,6 +157,11 @@ func (r *ServerManagerReconciler) Reconcile(ctx context.Context, req ctrl.Reques
logging.Error(err, "Failed to get image")
return reconcile.Result{}, err
}
if len(s.Spec.Server.Ports) == 0 {
s.Spec.Server.Ports = image.Spec.Ports
err := r.Update(ctx, s)
return reconcile.Result{}, err
}
serverPod := r.ServerPod(s, pvc, image)
found := &corev1.Pod{}
@@ -185,11 +190,27 @@ func (r *ServerManagerReconciler) Reconcile(ctx context.Context, req ctrl.Reques
s.Status.Server.Running = true
statusChanged = true
}
if s.Status.Server.Command == nil {
s.Status.Server.Command = serverPod.Spec.Containers[0].Command
statusChanged = true
}
if s.Status.Server.Args == nil {
s.Status.Server.Args = serverPod.Spec.Containers[0].Args
statusChanged = true
}
default:
if s.Status.Server.Running {
s.Status.Server.Running = false
statusChanged = true
}
if len(s.Status.Server.Args) != 0 {
s.Status.Server.Args = nil
statusChanged = true
}
if len(s.Status.Server.Command) != 0 {
s.Status.Server.Command = nil
statusChanged = true
}
}
}
@@ -198,6 +219,14 @@ func (r *ServerManagerReconciler) Reconcile(ctx context.Context, req ctrl.Reques
s.Status.Server.Running = false
statusChanged = true
}
if len(s.Status.Server.Args) != 0 {
s.Status.Server.Args = nil
statusChanged = true
}
if len(s.Status.Server.Command) != 0 {
s.Status.Server.Command = nil
statusChanged = true
}
}
logging.Info("verified pod")
@@ -301,7 +330,7 @@ func (r *ServerManagerReconciler) Reconcile(ctx context.Context, req ctrl.Reques
}
}
}
if errors.IsNotFound(err) && !s.Spec.Server.On {
if errors.IsNotFound(err) && !s.Spec.Browser.On {
if s.Status.Browser.Running {
s.Status.Browser.Running = false
statusChanged = true
@@ -368,7 +397,7 @@ func (r *ServerManagerReconciler) GenerateBrowserUrl(s *servermanagerv1alpha1.Se
}
func (r *ServerManagerReconciler) GenerateBrowserSubPath(s *servermanagerv1alpha1.ServerManager) string {
if r.Config.Browser.SubPath == "" {
if r.Config.Browser.SubPath != "" {
return fmt.Sprintf("%s/%s/%s", r.Config.Browser.SubPath, s.Namespace, s.Name)
} else {
return fmt.Sprintf("/%s/%s", s.Namespace, s.Name)
@@ -611,13 +640,10 @@ func (r *ServerManagerReconciler) ServerPvc(s *servermanagerv1alpha1.ServerManag
func (r *ServerManagerReconciler) ServerPod(s *servermanagerv1alpha1.ServerManager, pvc *corev1.PersistentVolumeClaim, image *servermanagerv1alpha1.Image) *corev1.Pod {
serverPorts := image.Spec.Ports
if len(s.Spec.Server.Ports) > 0 {
serverPorts = s.Spec.Server.Ports
}
ports := make([]corev1.ContainerPort, len(serverPorts))
for i, port := range s.Spec.Server.Ports {
for i, port := range serverPorts {
ports[i] = corev1.ContainerPort{
ContainerPort: port.Port,
Protocol: port.Protocol,