136 lines
3.4 KiB
Go
136 lines
3.4 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"io"
|
|
v1 "k8s.io/api/core/v1"
|
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
|
"os"
|
|
"slices"
|
|
"strings"
|
|
)
|
|
|
|
type LinkerdPolicyGenerator struct {
|
|
config *Config
|
|
policyTemplates *PolicyTemplates
|
|
|
|
apps map[string]*Application
|
|
networks map[string]*Network
|
|
}
|
|
|
|
func NewLinkerdPolicyGenerator(config *Config, templates *PolicyTemplates) *LinkerdPolicyGenerator {
|
|
return &LinkerdPolicyGenerator{
|
|
config: config,
|
|
policyTemplates: templates,
|
|
apps: make(map[string]*Application),
|
|
networks: make(map[string]*Network),
|
|
}
|
|
}
|
|
|
|
func (g *LinkerdPolicyGenerator) Init(writer io.Writer) error {
|
|
return nil
|
|
}
|
|
|
|
func (g *LinkerdPolicyGenerator) GenerateNamespace(writer io.Writer, namespace *Namespace) error {
|
|
return nil
|
|
}
|
|
|
|
func (g *LinkerdPolicyGenerator) GenerateCommunicationRule(
|
|
writer io.Writer,
|
|
app *Application,
|
|
ingress *Ingress,
|
|
egress *Egress) error {
|
|
|
|
if app.Namespace.Unauthorized {
|
|
fmt.Fprintf(os.Stderr, "UNAUTHORIZED %s\n", app.Name)
|
|
return nil
|
|
}
|
|
|
|
// and the server resources
|
|
fmt.Fprintf(os.Stderr, "Server %s/%s\n",
|
|
app.Namespace.Name, app.Name)
|
|
err := g.policyTemplates.Execute("linkerd", "server", writer, app)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
for _, ingress := range ingress.Applications {
|
|
for _, port := range ingress.Ports {
|
|
if port.Protocol != "TCP" {
|
|
continue
|
|
}
|
|
g.apps[ingress.Application.Name] = ingress.Application
|
|
err = g.policyTemplates.Execute("linkerd", "authorizationpolicy-app",
|
|
writer,
|
|
map[string]any{
|
|
"app": app,
|
|
"port": port.Port,
|
|
"client": ingress.Application,
|
|
})
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
}
|
|
|
|
for _, ingress := range ingress.Networks {
|
|
for _, port := range ingress.Ports {
|
|
if port.Protocol != "TCP" {
|
|
continue
|
|
}
|
|
g.networks[ingress.Network.Name] = ingress.Network
|
|
err = g.policyTemplates.Execute("linkerd", "authorizationpolicy-net",
|
|
writer,
|
|
map[string]any{
|
|
"app": app,
|
|
"port": port.Port,
|
|
"client": ingress.Network,
|
|
})
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (g *LinkerdPolicyGenerator) serviceAccounts(peers []*ApplicationPeer) []v1.ServiceAccount {
|
|
serviceAccounts := []v1.ServiceAccount{}
|
|
for _, peer := range peers {
|
|
for _, sa := range peer.Application.ServiceAccounts {
|
|
serviceAccounts = append(serviceAccounts, v1.ServiceAccount{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: sa,
|
|
Namespace: peer.Application.Namespace.Name,
|
|
},
|
|
})
|
|
}
|
|
}
|
|
slices.SortFunc(serviceAccounts, func(s1 v1.ServiceAccount, s2 v1.ServiceAccount) int {
|
|
return strings.Compare(s1.Namespace+"/"+s1.Name, s2.Namespace+"/"+s2.Name)
|
|
})
|
|
return slices.CompactFunc(serviceAccounts, func(s1, s2 v1.ServiceAccount) bool {
|
|
return s1.Namespace == s2.Namespace && s1.Name == s2.Name
|
|
})
|
|
}
|
|
|
|
func (g *LinkerdPolicyGenerator) Finalize(writer io.Writer) error {
|
|
for _, app := range g.apps {
|
|
fmt.Fprintf(os.Stderr, "MeshTLSAuthentication %s/%s %v\n",
|
|
app.Namespace.Name, app.Name, app.ServiceAccounts)
|
|
err := g.policyTemplates.Execute("linkerd", "meshtlsauthentication",
|
|
writer, app)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
for _, network := range g.networks {
|
|
fmt.Fprintf(os.Stderr, "NetworkAuthentication default/%s\n", network.Name)
|
|
err := g.policyTemplates.Execute("linkerd", "networkauthentication", writer, network)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
return nil
|
|
}
|