...
This commit is contained in:
@@ -8,7 +8,7 @@ import incubaid.herolib.osal.startupmanager
|
||||
import time
|
||||
|
||||
__global (
|
||||
kubernetes_global map[string]&Kubernetes
|
||||
kubernetes_global map[string]&KubeClient
|
||||
kubernetes_default string
|
||||
)
|
||||
|
||||
@@ -22,15 +22,15 @@ pub mut:
|
||||
create bool // default will not create if not exist
|
||||
}
|
||||
|
||||
pub fn new(args ArgsGet) !&Kubernetes {
|
||||
mut obj := Kubernetes{
|
||||
pub fn new(args ArgsGet) !&KubeClient {
|
||||
mut obj := KubeClient{
|
||||
name: args.name
|
||||
}
|
||||
set(obj)!
|
||||
return get(name: args.name)!
|
||||
}
|
||||
|
||||
pub fn get(args ArgsGet) !&Kubernetes {
|
||||
pub fn get(args ArgsGet) !&KubeClient {
|
||||
mut context := base.context()!
|
||||
kubernetes_default = args.name
|
||||
if args.fromdb || args.name !in kubernetes_global {
|
||||
@@ -39,16 +39,16 @@ pub fn get(args ArgsGet) !&Kubernetes {
|
||||
data := r.hget('context:kubernetes', args.name)!
|
||||
if data.len == 0 {
|
||||
print_backtrace()
|
||||
return error('Kubernetes with name: kubernetes does not exist, prob bug.')
|
||||
return error('KubeClient with name: kubernetes does not exist, prob bug.')
|
||||
}
|
||||
mut obj := json.decode(Kubernetes, data)!
|
||||
mut obj := json.decode(KubeClient, data)!
|
||||
set_in_mem(obj)!
|
||||
} else {
|
||||
if args.create {
|
||||
new(args)!
|
||||
} else {
|
||||
print_backtrace()
|
||||
return error("Kubernetes with name 'kubernetes' does not exist")
|
||||
return error("KubeClient with name 'kubernetes' does not exist")
|
||||
}
|
||||
}
|
||||
return get(name: args.name)! // no longer from db nor create
|
||||
@@ -60,7 +60,7 @@ pub fn get(args ArgsGet) !&Kubernetes {
|
||||
}
|
||||
|
||||
// register the config for the future
|
||||
pub fn set(o Kubernetes) ! {
|
||||
pub fn set(o KubeClient) ! {
|
||||
mut o2 := set_in_mem(o)!
|
||||
kubernetes_default = o2.name
|
||||
mut context := base.context()!
|
||||
@@ -88,12 +88,12 @@ pub mut:
|
||||
}
|
||||
|
||||
// if fromdb set: load from filesystem, and not from mem, will also reset what is in mem
|
||||
pub fn list(args ArgsList) ![]&Kubernetes {
|
||||
mut res := []&Kubernetes{}
|
||||
pub fn list(args ArgsList) ![]&KubeClient {
|
||||
mut res := []&KubeClient{}
|
||||
mut context := base.context()!
|
||||
if args.fromdb {
|
||||
// reset what is in mem
|
||||
kubernetes_global = map[string]&Kubernetes{}
|
||||
kubernetes_global = map[string]&KubeClient{}
|
||||
kubernetes_default = ''
|
||||
}
|
||||
if args.fromdb {
|
||||
@@ -114,7 +114,7 @@ pub fn list(args ArgsList) ![]&Kubernetes {
|
||||
}
|
||||
|
||||
// only sets in mem, does not set as config
|
||||
fn set_in_mem(o Kubernetes) !Kubernetes {
|
||||
fn set_in_mem(o KubeClient) !KubeClient {
|
||||
mut o2 := obj_init(o)!
|
||||
kubernetes_global[o2.name] = &o2
|
||||
kubernetes_default = o2.name
|
||||
@@ -202,12 +202,12 @@ fn startupmanager_get(cat startupmanager.StartupManagerType) !startupmanager.Sta
|
||||
}
|
||||
|
||||
// load from disk and make sure is properly intialized
|
||||
pub fn (mut self Kubernetes) reload() ! {
|
||||
pub fn (mut self KubeClient) reload() ! {
|
||||
switch(self.name)
|
||||
self = obj_init(self)!
|
||||
}
|
||||
|
||||
pub fn (mut self Kubernetes) start() ! {
|
||||
pub fn (mut self KubeClient) start() ! {
|
||||
switch(self.name)
|
||||
if self.running()! {
|
||||
return
|
||||
@@ -244,13 +244,13 @@ pub fn (mut self Kubernetes) start() ! {
|
||||
return error('kubernetes did not install properly.')
|
||||
}
|
||||
|
||||
pub fn (mut self Kubernetes) install_start(args InstallArgs) ! {
|
||||
pub fn (mut self KubeClient) install_start(args InstallArgs) ! {
|
||||
switch(self.name)
|
||||
self.install(args)!
|
||||
self.start()!
|
||||
}
|
||||
|
||||
pub fn (mut self Kubernetes) stop() ! {
|
||||
pub fn (mut self KubeClient) stop() ! {
|
||||
switch(self.name)
|
||||
stop_pre()!
|
||||
for zprocess in startupcmd()! {
|
||||
@@ -260,13 +260,13 @@ pub fn (mut self Kubernetes) stop() ! {
|
||||
stop_post()!
|
||||
}
|
||||
|
||||
pub fn (mut self Kubernetes) restart() ! {
|
||||
pub fn (mut self KubeClient) restart() ! {
|
||||
switch(self.name)
|
||||
self.stop()!
|
||||
self.start()!
|
||||
}
|
||||
|
||||
pub fn (mut self Kubernetes) running() !bool {
|
||||
pub fn (mut self KubeClient) running() !bool {
|
||||
switch(self.name)
|
||||
|
||||
// walk over the generic processes, if not running return
|
||||
@@ -288,19 +288,19 @@ pub mut:
|
||||
reset bool
|
||||
}
|
||||
|
||||
pub fn (mut self Kubernetes) install(args InstallArgs) ! {
|
||||
pub fn (mut self KubeClient) install(args InstallArgs) ! {
|
||||
switch(self.name)
|
||||
if args.reset || (!installed()!) {
|
||||
install()!
|
||||
}
|
||||
}
|
||||
|
||||
pub fn (mut self Kubernetes) build() ! {
|
||||
pub fn (mut self KubeClient) build() ! {
|
||||
switch(self.name)
|
||||
build()!
|
||||
}
|
||||
|
||||
pub fn (mut self Kubernetes) destroy() ! {
|
||||
pub fn (mut self KubeClient) destroy() ! {
|
||||
switch(self.name)
|
||||
self.stop() or {}
|
||||
destroy()!
|
||||
|
||||
@@ -2,173 +2,16 @@ module kubernetes
|
||||
|
||||
import incubaid.herolib.data.paramsparser
|
||||
import incubaid.herolib.data.encoderhero
|
||||
import incubaid.herolib.data.ourjson
|
||||
import os
|
||||
|
||||
pub const version = '1.0.0'
|
||||
pub const version = '0.0.0'
|
||||
const singleton = false
|
||||
const default = true
|
||||
|
||||
// K8s API Version and Kind tracking
|
||||
@[params]
|
||||
pub struct K8sMetadata {
|
||||
pub mut:
|
||||
name string
|
||||
namespace string = 'default'
|
||||
labels map[string]string
|
||||
annotations map[string]string
|
||||
owner_reference string
|
||||
}
|
||||
|
||||
// Pod Specification
|
||||
@[params]
|
||||
pub struct ContainerSpec {
|
||||
pub mut:
|
||||
name string
|
||||
image string
|
||||
image_pull_policy string = 'IfNotPresent'
|
||||
ports []ContainerPort
|
||||
env []EnvVar
|
||||
resources ResourceRequirements
|
||||
volume_mounts []VolumeMount
|
||||
command []string
|
||||
args []string
|
||||
}
|
||||
|
||||
@[params]
|
||||
pub struct ContainerPort {
|
||||
pub mut:
|
||||
name string
|
||||
container_port int
|
||||
protocol string = 'TCP'
|
||||
host_port int
|
||||
}
|
||||
|
||||
@[params]
|
||||
pub struct EnvVar {
|
||||
pub mut:
|
||||
name string
|
||||
value string
|
||||
}
|
||||
|
||||
@[params]
|
||||
pub struct ResourceRequirements {
|
||||
pub mut:
|
||||
requests map[string]string // cpu, memory
|
||||
limits map[string]string
|
||||
}
|
||||
|
||||
@[params]
|
||||
pub struct VolumeMount {
|
||||
pub mut:
|
||||
name string
|
||||
mount_path string
|
||||
read_only bool
|
||||
}
|
||||
|
||||
@[params]
|
||||
pub struct PodSpec {
|
||||
pub mut:
|
||||
metadata K8sMetadata
|
||||
containers []ContainerSpec
|
||||
restart_policy string = 'Always'
|
||||
service_account string
|
||||
volumes []Volume
|
||||
}
|
||||
|
||||
@[params]
|
||||
pub struct Volume {
|
||||
pub mut:
|
||||
name string
|
||||
config_map string
|
||||
secret string
|
||||
empty_dir bool
|
||||
}
|
||||
|
||||
// Deployment Specification
|
||||
@[params]
|
||||
pub struct DeploymentSpec {
|
||||
pub mut:
|
||||
metadata K8sMetadata
|
||||
replicas int = 1
|
||||
selector map[string]string
|
||||
template PodSpec
|
||||
strategy DeploymentStrategy
|
||||
progress_deadline_seconds int = 600
|
||||
}
|
||||
|
||||
@[params]
|
||||
pub struct DeploymentStrategy {
|
||||
pub mut:
|
||||
strategy_type string = 'RollingUpdate'
|
||||
rolling_update RollingUpdateStrategy
|
||||
}
|
||||
|
||||
@[params]
|
||||
pub struct RollingUpdateStrategy {
|
||||
pub mut:
|
||||
max_surge string = '25%'
|
||||
max_unavailable string = '25%'
|
||||
}
|
||||
|
||||
// Service Specification
|
||||
@[params]
|
||||
pub struct ServiceSpec {
|
||||
pub mut:
|
||||
metadata K8sMetadata
|
||||
service_type string = 'ClusterIP' // ClusterIP, NodePort, LoadBalancer
|
||||
selector map[string]string
|
||||
ports []ServicePort
|
||||
cluster_ip string
|
||||
external_ips []string
|
||||
session_affinity string
|
||||
}
|
||||
|
||||
@[params]
|
||||
pub struct ServicePort {
|
||||
pub mut:
|
||||
name string
|
||||
protocol string = 'TCP'
|
||||
port int
|
||||
target_port int
|
||||
node_port int
|
||||
}
|
||||
|
||||
// ConfigMap
|
||||
@[params]
|
||||
pub struct ConfigMapSpec {
|
||||
pub mut:
|
||||
metadata K8sMetadata
|
||||
data map[string]string
|
||||
}
|
||||
|
||||
// Secret
|
||||
@[params]
|
||||
pub struct SecretSpec {
|
||||
pub mut:
|
||||
metadata K8sMetadata
|
||||
secret_type string = 'Opaque'
|
||||
data map[string]string // base64 encoded
|
||||
}
|
||||
|
||||
// Kube Client Configuration
|
||||
@[params]
|
||||
pub struct KubeConfig {
|
||||
pub mut:
|
||||
kubeconfig_path string
|
||||
context string = ''
|
||||
namespace string = 'default'
|
||||
api_server string
|
||||
ca_cert_path string
|
||||
client_cert_path string
|
||||
client_key_path string
|
||||
token string
|
||||
insecure_skip_tls_verify bool
|
||||
}
|
||||
|
||||
@[heap]
|
||||
pub struct KubeClient {
|
||||
pub mut:
|
||||
name string = 'default'
|
||||
name string = 'default'
|
||||
kubeconfig_path string
|
||||
config KubeConfig
|
||||
@@ -177,51 +20,28 @@ pub mut:
|
||||
kubectl_path string = 'kubectl'
|
||||
cache_enabled bool = true
|
||||
cache_ttl_seconds int = 300
|
||||
|
||||
}
|
||||
|
||||
// Validation result for YAML files
|
||||
pub struct K8sValidationResult {
|
||||
pub mut:
|
||||
valid bool
|
||||
kind string
|
||||
api_version string
|
||||
metadata K8sMetadata
|
||||
errors []string
|
||||
}
|
||||
|
||||
// Cluster info
|
||||
pub struct ClusterInfo {
|
||||
pub mut:
|
||||
version string
|
||||
nodes int
|
||||
namespaces int
|
||||
running_pods int
|
||||
api_server string
|
||||
}
|
||||
|
||||
// Initialization
|
||||
fn obj_init(mut cfg KubeClient) !KubeClient {
|
||||
// Resolve kubeconfig path
|
||||
if cfg.kubeconfig_path.is_empty() {
|
||||
home := os.home_dir()
|
||||
cfg.kubeconfig_path = '${home}/.kube/config'
|
||||
}
|
||||
|
||||
// Ensure kubeconfig exists
|
||||
if !os.path_exists(cfg.kubeconfig_path) {
|
||||
return error('kubeconfig not found at ${cfg.kubeconfig_path}')
|
||||
}
|
||||
|
||||
cfg.config.kubeconfig_path = cfg.kubeconfig_path
|
||||
|
||||
return cfg
|
||||
// your checking & initialization code if needed
|
||||
fn obj_init(mycfg_ KubeClient) !KubeClient {
|
||||
mut mycfg := mycfg_
|
||||
return mycfg
|
||||
}
|
||||
|
||||
// called before start if done
|
||||
fn configure() ! {
|
||||
// Configure any defaults or environment-specific settings
|
||||
// mut installer := get()!
|
||||
// mut mycode := $tmpl('templates/atemplate.yaml')
|
||||
// mut path := pathlib.get_file(path: cfg.configpath, create: true)!
|
||||
// path.write(mycode)!
|
||||
// console.print_debug(mycode)
|
||||
}
|
||||
|
||||
/////////////NORMALLY NO NEED TO TOUCH
|
||||
|
||||
pub fn heroscript_loads(heroscript string) !KubeClient {
|
||||
//TODO: will have to be implemented manual
|
||||
mut obj := encoderhero.decode[KubeClient](heroscript)!
|
||||
return obj_init(obj)!
|
||||
return obj
|
||||
}
|
||||
|
||||
216
lib/virt/kubernetes/kubernetes_resources_model.v
Normal file
216
lib/virt/kubernetes/kubernetes_resources_model.v
Normal file
@@ -0,0 +1,216 @@
|
||||
module kubernetes
|
||||
|
||||
import incubaid.herolib.data.paramsparser
|
||||
import incubaid.herolib.data.encoderhero
|
||||
import incubaid.herolib.data.ourjson
|
||||
import os
|
||||
|
||||
pub const version = '1.0.0'
|
||||
const singleton = false
|
||||
const default = true
|
||||
|
||||
// K8s API Version and Kind tracking
|
||||
@[params]
|
||||
pub struct K8sMetadata {
|
||||
pub mut:
|
||||
name string
|
||||
namespace string = 'default'
|
||||
labels map[string]string
|
||||
annotations map[string]string
|
||||
owner_reference string
|
||||
}
|
||||
|
||||
// Pod Specification
|
||||
@[params]
|
||||
pub struct ContainerSpec {
|
||||
pub mut:
|
||||
name string
|
||||
image string
|
||||
image_pull_policy string = 'IfNotPresent'
|
||||
ports []ContainerPort
|
||||
env []EnvVar
|
||||
resources ResourceRequirements
|
||||
volume_mounts []VolumeMount
|
||||
command []string
|
||||
args []string
|
||||
}
|
||||
|
||||
@[params]
|
||||
pub struct ContainerPort {
|
||||
pub mut:
|
||||
name string
|
||||
container_port int
|
||||
protocol string = 'TCP'
|
||||
host_port int
|
||||
}
|
||||
|
||||
@[params]
|
||||
pub struct EnvVar {
|
||||
pub mut:
|
||||
name string
|
||||
value string
|
||||
}
|
||||
|
||||
@[params]
|
||||
pub struct ResourceRequirements {
|
||||
pub mut:
|
||||
requests map[string]string // cpu, memory
|
||||
limits map[string]string
|
||||
}
|
||||
|
||||
@[params]
|
||||
pub struct VolumeMount {
|
||||
pub mut:
|
||||
name string
|
||||
mount_path string
|
||||
read_only bool
|
||||
}
|
||||
|
||||
@[params]
|
||||
pub struct PodSpec {
|
||||
pub mut:
|
||||
metadata K8sMetadata
|
||||
containers []ContainerSpec
|
||||
restart_policy string = 'Always'
|
||||
service_account string
|
||||
volumes []Volume
|
||||
}
|
||||
|
||||
@[params]
|
||||
pub struct Volume {
|
||||
pub mut:
|
||||
name string
|
||||
config_map string
|
||||
secret string
|
||||
empty_dir bool
|
||||
}
|
||||
|
||||
// Deployment Specification
|
||||
@[params]
|
||||
pub struct DeploymentSpec {
|
||||
pub mut:
|
||||
metadata K8sMetadata
|
||||
replicas int = 1
|
||||
selector map[string]string
|
||||
template PodSpec
|
||||
strategy DeploymentStrategy
|
||||
progress_deadline_seconds int = 600
|
||||
}
|
||||
|
||||
@[params]
|
||||
pub struct DeploymentStrategy {
|
||||
pub mut:
|
||||
strategy_type string = 'RollingUpdate'
|
||||
rolling_update RollingUpdateStrategy
|
||||
}
|
||||
|
||||
@[params]
|
||||
pub struct RollingUpdateStrategy {
|
||||
pub mut:
|
||||
max_surge string = '25%'
|
||||
max_unavailable string = '25%'
|
||||
}
|
||||
|
||||
// Service Specification
|
||||
@[params]
|
||||
pub struct ServiceSpec {
|
||||
pub mut:
|
||||
metadata K8sMetadata
|
||||
service_type string = 'ClusterIP' // ClusterIP, NodePort, LoadBalancer
|
||||
selector map[string]string
|
||||
ports []ServicePort
|
||||
cluster_ip string
|
||||
external_ips []string
|
||||
session_affinity string
|
||||
}
|
||||
|
||||
@[params]
|
||||
pub struct ServicePort {
|
||||
pub mut:
|
||||
name string
|
||||
protocol string = 'TCP'
|
||||
port int
|
||||
target_port int
|
||||
node_port int
|
||||
}
|
||||
|
||||
// ConfigMap
|
||||
@[params]
|
||||
pub struct ConfigMapSpec {
|
||||
pub mut:
|
||||
metadata K8sMetadata
|
||||
data map[string]string
|
||||
}
|
||||
|
||||
// Secret
|
||||
@[params]
|
||||
pub struct SecretSpec {
|
||||
pub mut:
|
||||
metadata K8sMetadata
|
||||
secret_type string = 'Opaque'
|
||||
data map[string]string // base64 encoded
|
||||
}
|
||||
|
||||
// Kube Client Configuration
|
||||
@[params]
|
||||
pub struct KubeConfig {
|
||||
pub mut:
|
||||
kubeconfig_path string
|
||||
context string = ''
|
||||
namespace string = 'default'
|
||||
api_server string
|
||||
ca_cert_path string
|
||||
client_cert_path string
|
||||
client_key_path string
|
||||
token string
|
||||
insecure_skip_tls_verify bool
|
||||
}
|
||||
|
||||
|
||||
// Validation result for YAML files
|
||||
pub struct K8sValidationResult {
|
||||
pub mut:
|
||||
valid bool
|
||||
kind string
|
||||
api_version string
|
||||
metadata K8sMetadata
|
||||
errors []string
|
||||
}
|
||||
|
||||
// Cluster info
|
||||
pub struct ClusterInfo {
|
||||
pub mut:
|
||||
version string
|
||||
nodes int
|
||||
namespaces int
|
||||
running_pods int
|
||||
api_server string
|
||||
}
|
||||
|
||||
// Initialization
|
||||
fn obj_init(mut cfg KubeClient) !KubeClient {
|
||||
// Resolve kubeconfig path
|
||||
if cfg.kubeconfig_path.is_empty() {
|
||||
home := os.home_dir()
|
||||
cfg.kubeconfig_path = '${home}/.kube/config'
|
||||
}
|
||||
|
||||
// Ensure kubeconfig exists
|
||||
if !os.path_exists(cfg.kubeconfig_path) {
|
||||
return error('kubeconfig not found at ${cfg.kubeconfig_path}')
|
||||
}
|
||||
|
||||
cfg.config.kubeconfig_path = cfg.kubeconfig_path
|
||||
|
||||
return cfg
|
||||
}
|
||||
|
||||
fn configure() ! {
|
||||
// Configure any defaults or environment-specific settings
|
||||
}
|
||||
|
||||
pub fn heroscript_loads(heroscript string) !KubeClient {
|
||||
// TODO: this will have to be redone, because its much more complicated now, need to define a nice play processors
|
||||
mut obj := encoderhero.decode[KubeClient](heroscript)!
|
||||
return obj_init(obj)!
|
||||
}
|
||||
@@ -6,7 +6,7 @@ import os
|
||||
fn test_model_creation() ! {
|
||||
mut deployment := DeploymentSpec{
|
||||
metadata: K8sMetadata{
|
||||
name: 'test-app'
|
||||
name: 'test-app'
|
||||
namespace: 'default'
|
||||
}
|
||||
replicas: 3
|
||||
@@ -14,21 +14,21 @@ fn test_model_creation() ! {
|
||||
'app': 'test-app'
|
||||
}
|
||||
template: PodSpec{
|
||||
metadata: K8sMetadata{
|
||||
name: 'test-app-pod'
|
||||
metadata: K8sMetadata{
|
||||
name: 'test-app-pod'
|
||||
namespace: 'default'
|
||||
}
|
||||
containers: [
|
||||
ContainerSpec{
|
||||
name: 'app'
|
||||
name: 'app'
|
||||
image: 'nginx:latest'
|
||||
ports: [
|
||||
ContainerPort{
|
||||
name: 'http'
|
||||
name: 'http'
|
||||
container_port: 80
|
||||
}
|
||||
},
|
||||
]
|
||||
}
|
||||
},
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -41,7 +41,8 @@ fn test_model_creation() ! {
|
||||
|
||||
fn test_yaml_validation() ! {
|
||||
// Create test YAML file
|
||||
test_yaml := '''
|
||||
test_yaml := ''
|
||||
'
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
@@ -60,7 +61,8 @@ spec:
|
||||
containers:
|
||||
- name: app
|
||||
image: nginx:latest
|
||||
'''
|
||||
'
|
||||
''
|
||||
|
||||
test_file := '/tmp/test-deployment.yaml'
|
||||
os.write_file(test_file, test_yaml)!
|
||||
|
||||
@@ -50,21 +50,21 @@ pub fn yaml_validate(yaml_path string) !K8sValidationResult {
|
||||
}
|
||||
|
||||
// Validate kind values
|
||||
valid_kinds := ['Pod', 'Deployment', 'Service', 'ConfigMap', 'Secret', 'StatefulSet',
|
||||
'DaemonSet', 'Job', 'CronJob', 'Ingress', 'PersistentVolume', 'PersistentVolumeClaim']
|
||||
valid_kinds := ['Pod', 'Deployment', 'Service', 'ConfigMap', 'Secret', 'StatefulSet', 'DaemonSet',
|
||||
'Job', 'CronJob', 'Ingress', 'PersistentVolume', 'PersistentVolumeClaim']
|
||||
if kind !in valid_kinds {
|
||||
errors << 'Invalid kind: ${kind}. Valid kinds: ${valid_kinds.join(", ")}'
|
||||
errors << 'Invalid kind: ${kind}. Valid kinds: ${valid_kinds.join(', ')}'
|
||||
}
|
||||
|
||||
return K8sValidationResult{
|
||||
valid: errors.len == 0
|
||||
kind: kind
|
||||
valid: errors.len == 0
|
||||
kind: kind
|
||||
api_version: api_version
|
||||
metadata: K8sMetadata{
|
||||
name: metadata_name
|
||||
metadata: K8sMetadata{
|
||||
name: metadata_name
|
||||
namespace: metadata_namespace
|
||||
}
|
||||
errors: errors
|
||||
errors: errors
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user