mirror of
https://github.com/lukaszraczylo/kportal.git
synced 2026-07-13 07:47:52 +00:00
WIP - before the testing.
This commit is contained in:
@@ -0,0 +1,152 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
// Config represents the root configuration structure from .kportal.yaml
|
||||
type Config struct {
|
||||
Contexts []Context `yaml:"contexts"`
|
||||
}
|
||||
|
||||
// Context represents a Kubernetes context with its namespaces
|
||||
type Context struct {
|
||||
Name string `yaml:"name"`
|
||||
Namespaces []Namespace `yaml:"namespaces"`
|
||||
}
|
||||
|
||||
// Namespace represents a Kubernetes namespace with its forwards
|
||||
type Namespace struct {
|
||||
Name string `yaml:"name"`
|
||||
Forwards []Forward `yaml:"forwards"`
|
||||
}
|
||||
|
||||
// Forward represents a single port-forward configuration
|
||||
type Forward struct {
|
||||
Resource string `yaml:"resource"` // e.g., "pod/my-app", "service/postgres", "pod"
|
||||
Selector string `yaml:"selector"` // Label selector for pod resolution (e.g., "app=nginx,env=prod")
|
||||
Protocol string `yaml:"protocol"` // tcp or udp
|
||||
Port int `yaml:"port"` // Remote port
|
||||
LocalPort int `yaml:"localPort"` // Local port
|
||||
|
||||
// Runtime fields (not in YAML)
|
||||
contextName string
|
||||
namespaceName string
|
||||
}
|
||||
|
||||
// ID returns a unique identifier for this forward configuration.
|
||||
// Format: context/namespace/resource:localPort
|
||||
func (f *Forward) ID() string {
|
||||
return fmt.Sprintf("%s/%s/%s:%d", f.contextName, f.namespaceName, f.Resource, f.LocalPort)
|
||||
}
|
||||
|
||||
// String returns a human-readable representation of the forward.
|
||||
// Format: context/namespace/resource:port→localPort
|
||||
func (f *Forward) String() string {
|
||||
if f.Selector != "" {
|
||||
return fmt.Sprintf("%s/%s/%s[%s]:%d→%d",
|
||||
f.contextName, f.namespaceName, f.Resource, f.Selector, f.Port, f.LocalPort)
|
||||
}
|
||||
return fmt.Sprintf("%s/%s/%s:%d→%d",
|
||||
f.contextName, f.namespaceName, f.Resource, f.Port, f.LocalPort)
|
||||
}
|
||||
|
||||
// SetContext sets the context and namespace names for this forward.
|
||||
// This is used during config parsing to populate runtime fields.
|
||||
func (f *Forward) SetContext(ctx, ns string) {
|
||||
f.contextName = ctx
|
||||
f.namespaceName = ns
|
||||
}
|
||||
|
||||
// GetContext returns the context name for this forward.
|
||||
func (f *Forward) GetContext() string {
|
||||
return f.contextName
|
||||
}
|
||||
|
||||
// GetNamespace returns the namespace name for this forward.
|
||||
func (f *Forward) GetNamespace() string {
|
||||
return f.namespaceName
|
||||
}
|
||||
|
||||
// LoadConfig loads and parses the configuration file from the given path.
|
||||
func LoadConfig(path string) (*Config, error) {
|
||||
data, err := os.ReadFile(path)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to read config file: %w", err)
|
||||
}
|
||||
|
||||
return ParseConfig(data)
|
||||
}
|
||||
|
||||
// ParseConfig parses YAML configuration data into a Config struct.
|
||||
func ParseConfig(data []byte) (*Config, error) {
|
||||
var cfg Config
|
||||
if err := yaml.Unmarshal(data, &cfg); err != nil {
|
||||
return nil, fmt.Errorf("failed to parse YAML: %w", err)
|
||||
}
|
||||
|
||||
// Populate runtime fields (context and namespace names)
|
||||
for i := range cfg.Contexts {
|
||||
ctx := &cfg.Contexts[i]
|
||||
for j := range ctx.Namespaces {
|
||||
ns := &ctx.Namespaces[j]
|
||||
for k := range ns.Forwards {
|
||||
fwd := &ns.Forwards[k]
|
||||
fwd.SetContext(ctx.Name, ns.Name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return &cfg, nil
|
||||
}
|
||||
|
||||
// GetAllForwards returns a flat list of all forwards across all contexts and namespaces.
|
||||
func (c *Config) GetAllForwards() []Forward {
|
||||
var forwards []Forward
|
||||
|
||||
for _, ctx := range c.Contexts {
|
||||
for _, ns := range ctx.Namespaces {
|
||||
forwards = append(forwards, ns.Forwards...)
|
||||
}
|
||||
}
|
||||
|
||||
return forwards
|
||||
}
|
||||
|
||||
// GetForwardsByContext returns all forwards for a specific context.
|
||||
func (c *Config) GetForwardsByContext(contextName string) []Forward {
|
||||
var forwards []Forward
|
||||
|
||||
for _, ctx := range c.Contexts {
|
||||
if ctx.Name == contextName {
|
||||
for _, ns := range ctx.Namespaces {
|
||||
forwards = append(forwards, ns.Forwards...)
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return forwards
|
||||
}
|
||||
|
||||
// GetForwardsByNamespace returns all forwards for a specific context and namespace.
|
||||
func (c *Config) GetForwardsByNamespace(contextName, namespaceName string) []Forward {
|
||||
var forwards []Forward
|
||||
|
||||
for _, ctx := range c.Contexts {
|
||||
if ctx.Name == contextName {
|
||||
for _, ns := range ctx.Namespaces {
|
||||
if ns.Name == namespaceName {
|
||||
forwards = append(forwards, ns.Forwards...)
|
||||
break
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return forwards
|
||||
}
|
||||
Reference in New Issue
Block a user