first commit
This commit is contained in:
@@ -0,0 +1,45 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/goccy/go-yaml"
|
||||
"net"
|
||||
)
|
||||
|
||||
func validateCIDR(cidr string) error {
|
||||
_, _, err := net.ParseCIDR(cidr)
|
||||
return err
|
||||
}
|
||||
|
||||
type CIDR string
|
||||
|
||||
// UnmarshalYAML implements the yaml.Unmarshaler interface
|
||||
func (c *CIDR) UnmarshalYAML(value []byte) error {
|
||||
// Get the string value from the node
|
||||
var s string
|
||||
if err := yaml.Unmarshal(value, &s); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := validateCIDR(s); err != nil {
|
||||
return err
|
||||
}
|
||||
*c = CIDR(s)
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalYAML implements the yaml.Marshaler interface
|
||||
func (c CIDR) MarshalYAML() ([]byte, error) {
|
||||
// Do any custom processing here before marshalling
|
||||
return []byte(string(c)), nil
|
||||
}
|
||||
|
||||
// CIDRS represents each network entry in the YAML
|
||||
type CIDRS struct {
|
||||
Name string `yaml:"name"`
|
||||
CIDR CIDR `yaml:"cidr"`
|
||||
Except []CIDR `yaml:"except,omitempty"`
|
||||
}
|
||||
|
||||
// Config represents the top-level YAML structure
|
||||
type Config struct {
|
||||
Networks []CIDRS `yaml:"networks"`
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"github.com/goccy/go-yaml"
|
||||
"github.com/spf13/cobra"
|
||||
"os"
|
||||
)
|
||||
|
||||
type Options struct {
|
||||
}
|
||||
|
||||
func execute(files []string, options *Options) error {
|
||||
if len(files) != 1 {
|
||||
return fmt.Errorf("File expected")
|
||||
}
|
||||
yamlFile, err := os.ReadFile(files[0])
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error reading YAML file: %v", err)
|
||||
}
|
||||
|
||||
// Parse the YAML content
|
||||
dec := yaml.NewDecoder(bytes.NewReader(yamlFile),
|
||||
yaml.UseJSONUnmarshaler(),
|
||||
yaml.DisallowUnknownField(),
|
||||
)
|
||||
var config Config
|
||||
err = dec.Decode(&config)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error parsing YAML: %v", err)
|
||||
}
|
||||
|
||||
fmt.Printf("PARSED %+v\n", config)
|
||||
return nil
|
||||
}
|
||||
|
||||
func main() {
|
||||
options := Options{}
|
||||
cmd := &cobra.Command{
|
||||
Use: "policygen",
|
||||
Short: "Generate network policies",
|
||||
Long: "Generated policies based on a more compact representation of topology",
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
return execute(args, &options)
|
||||
},
|
||||
}
|
||||
|
||||
cmd.Execute()
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"html/template"
|
||||
"io/fs"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
import "embed"
|
||||
import sprig "github.com/Masterminds/sprig/v3" // This provides most Helm functions
|
||||
import "github.com/goccy/go-yaml"
|
||||
|
||||
// This provides most Helm functions
|
||||
|
||||
//go:embed templates/*
|
||||
var templateFS embed.FS
|
||||
|
||||
func NewTemplate() *template.Template {
|
||||
tmpl := template.New("")
|
||||
|
||||
// Combine sprig functions with custom functions
|
||||
funcMap := template.FuncMap{}
|
||||
|
||||
// Add all sprig functions
|
||||
for name, fn := range sprig.FuncMap() {
|
||||
funcMap[name] = fn
|
||||
}
|
||||
|
||||
// Add any custom functions you want
|
||||
customFuncs := template.FuncMap{
|
||||
"toYaml": func(v interface{}) string {
|
||||
data, err := yaml.Marshal(v)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
return string(data)
|
||||
},
|
||||
}
|
||||
|
||||
// Merge custom functions
|
||||
for name, fn := range customFuncs {
|
||||
funcMap[name] = fn
|
||||
}
|
||||
|
||||
// Add the function map to the template
|
||||
tmpl = tmpl.Funcs(funcMap)
|
||||
|
||||
return tmpl
|
||||
}
|
||||
|
||||
func showContents(files fs.FS) {
|
||||
entries, err := fs.ReadDir(files, ".")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
for _, entry := range entries {
|
||||
fmt.Printf("entry %s %s\n", entry.Name(), entry.Type())
|
||||
if entry.Type().IsDir() {
|
||||
subdir, err := fs.Sub(files, entry.Name())
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
showContents(subdir)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func loadTemplates() (*template.Template, error) {
|
||||
showContents(templateFS)
|
||||
|
||||
// Parse all templates at once from the embedded FS
|
||||
tmpl := NewTemplate()
|
||||
|
||||
err := loadTemplatesGlob(tmpl)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return tmpl, err
|
||||
}
|
||||
|
||||
func loadTemplatesGlob(tmpl *template.Template) error {
|
||||
return fs.WalkDir(templateFS, ".", func(path string, d os.DirEntry, err error) error {
|
||||
if strings.HasSuffix(path, ".yaml") {
|
||||
data, err := fs.ReadFile(templateFS, path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Fprintf(os.Stderr, "Loading template %s\n", path)
|
||||
tmpl.New(path).Parse(string(data))
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
kind: CiliumNetworkPolicy
|
||||
apiVersion: cilium.io/v2
|
||||
metadata:
|
||||
name: {{.name}}
|
||||
namespace: {{.namespace}}
|
||||
spec:
|
||||
endpointSelector:
|
||||
{{ .selector }}
|
||||
egress:
|
||||
- toEntities:
|
||||
- kube-apiserver
|
||||
- toPorts:
|
||||
- ports:
|
||||
- port: "6443"
|
||||
protocol: TCP
|
||||
@@ -0,0 +1,13 @@
|
||||
kind: CiliumNetworkPolicy
|
||||
apiVersion: cilium.io/v2
|
||||
metadata:
|
||||
name: {{.name}}
|
||||
namespace: {{.namespace}}
|
||||
spec:
|
||||
endpointSelector:
|
||||
{{ .selector }}
|
||||
ingress:
|
||||
- fromEntities:
|
||||
- kube-apiserver
|
||||
# See https://github.com/cilium/cilium/issues/35401
|
||||
- remote-node
|
||||
@@ -0,0 +1,14 @@
|
||||
kind: NetworkPolicy
|
||||
apiVersion: networking.k8s.io/v1
|
||||
metadata:
|
||||
name: "{{.name}}"
|
||||
namespace: "{{.namespace}}"
|
||||
spec:
|
||||
policyTypes:
|
||||
- Egress
|
||||
podSelector:
|
||||
{{.selector}}
|
||||
egress:
|
||||
{{- range $from := .from }}
|
||||
- {{ $from | nindent 4 }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,14 @@
|
||||
kind: NetworkPolicy
|
||||
apiVersion: networking.k8s.io/v1
|
||||
metadata:
|
||||
name: "{{.name}}"
|
||||
namespace: "{{.namespace}}"
|
||||
spec:
|
||||
policyTypes:
|
||||
- Ingress
|
||||
podSelector:
|
||||
{{.selector}}
|
||||
ingress:
|
||||
{{- range $from := .from }}
|
||||
- {{ $from | nindent 4 }}
|
||||
{{- end }}
|
||||
Reference in New Issue
Block a user