eliminating duplicate communications. this caused problems with linkerd
and helm
This commit is contained in:
parent
cd4023f5ce
commit
2bea96cc57
@ -3,6 +3,7 @@ package main
|
||||
import (
|
||||
"io"
|
||||
"os"
|
||||
"slices"
|
||||
)
|
||||
|
||||
type Generator interface {
|
||||
@ -15,13 +16,15 @@ type Generator interface {
|
||||
type ApplicationPeer struct {
|
||||
Application *Application
|
||||
Ports []Port
|
||||
Rule string
|
||||
// used as convenience for template rendering.
|
||||
Rule string
|
||||
}
|
||||
|
||||
type NetworkPeer struct {
|
||||
Network *Network
|
||||
Ports []Port
|
||||
Rule string
|
||||
// Used as convenience for template rendering.
|
||||
Rule string
|
||||
}
|
||||
|
||||
type Peer struct {
|
||||
@ -32,13 +35,23 @@ type Peer struct {
|
||||
|
||||
func (p *Peer) append(app *ApplicationPeer, network *NetworkPeer, predefined string) {
|
||||
if app != nil {
|
||||
p.Applications = append(p.Applications, app)
|
||||
if !slices.ContainsFunc(p.Applications, func(a *ApplicationPeer) bool {
|
||||
return a.Application.Name == app.Application.Name && slices.Equal(a.Ports, app.Ports)
|
||||
}) {
|
||||
p.Applications = append(p.Applications, app)
|
||||
}
|
||||
}
|
||||
if network != nil {
|
||||
p.Networks = append(p.Networks, network)
|
||||
if !slices.ContainsFunc(p.Networks, func(n *NetworkPeer) bool {
|
||||
return n.Network.Name == network.Network.Name && slices.Equal(n.Network.Ports, network.Network.Ports)
|
||||
}) {
|
||||
p.Networks = append(p.Networks, network)
|
||||
}
|
||||
}
|
||||
if predefined != "" {
|
||||
p.Predefined = append(p.Predefined, predefined)
|
||||
if !slices.Contains(p.Predefined, predefined) {
|
||||
p.Predefined = append(p.Predefined, predefined)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -7,7 +7,6 @@ import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"os"
|
||||
"slices"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
@ -15,6 +14,7 @@ type LinkerdPolicyGenerator struct {
|
||||
config *Config
|
||||
policyTemplates *PolicyTemplates
|
||||
|
||||
apps map[string]*Application
|
||||
networks map[string]*Network
|
||||
}
|
||||
|
||||
@ -22,6 +22,7 @@ func NewLinkerdPolicyGenerator(config *Config, templates *PolicyTemplates) *Link
|
||||
return &LinkerdPolicyGenerator{
|
||||
config: config,
|
||||
policyTemplates: templates,
|
||||
apps: make(map[string]*Application),
|
||||
networks: make(map[string]*Network),
|
||||
}
|
||||
}
|
||||
@ -53,83 +54,37 @@ func (g *LinkerdPolicyGenerator) GenerateCommunicationRule(
|
||||
return err
|
||||
}
|
||||
|
||||
if len(ingress.Applications)+
|
||||
len(ingress.Networks) > 0 {
|
||||
ports := make(map[int]bool)
|
||||
//
|
||||
clientApplications := make(map[int][]*ApplicationPeer)
|
||||
for _, ingress := range ingress.Applications {
|
||||
for _, port := range ingress.Ports {
|
||||
if port.Protocol == "TCP" {
|
||||
portno, err := strconv.Atoi(port.Port)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error convert port '%s' of ingress '%s' of app '%s': %w",
|
||||
port.Port, ingress.Application.Name, app.Name, err)
|
||||
}
|
||||
ports[portno] = true
|
||||
clientApplications[portno] = append(clientApplications[portno], ingress)
|
||||
}
|
||||
for _, ingress := range ingress.Applications {
|
||||
for _, port := range ingress.Ports {
|
||||
if port.Protocol != "TCP" {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
clientNetworks := make(map[int][]*NetworkPeer)
|
||||
for _, ingress := range ingress.Networks {
|
||||
for _, port := range ingress.Ports {
|
||||
if port.Protocol == "TCP" {
|
||||
portno, err := strconv.Atoi(port.Port)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error convert port '%s' of ingress '%s' of app '%s': %w",
|
||||
port.Port, ingress.Network.Name, app.Name, err)
|
||||
}
|
||||
ports[portno] = true
|
||||
clientNetworks[portno] = append(clientNetworks[portno], ingress)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for port, _ := range ports {
|
||||
fmt.Fprintf(os.Stderr, "Generating authorization policy: %v %v -> %v : %v\n",
|
||||
Map(clientApplications[port], func(peer *ApplicationPeer) string {
|
||||
return peer.Application.Name
|
||||
}),
|
||||
Map(clientNetworks[port], func(peer *NetworkPeer) string {
|
||||
return peer.Network.Name
|
||||
}),
|
||||
app.Name,
|
||||
port)
|
||||
// Optimization: keep track of the references clientApps and
|
||||
// client Networks and only generate authentications for those instead of for
|
||||
// all apps and networks.
|
||||
for _, clientNetwork := range clientNetworks[port] {
|
||||
g.networks[clientNetwork.Network.Name] = clientNetwork.Network
|
||||
}
|
||||
|
||||
// linkerd rules
|
||||
// 1. an authpolicy may contain only one meshtlsauthentication rule
|
||||
// 2. an authpolicy may contain only one service account .
|
||||
// 3. an authpolicy may contain only one networkauthentication
|
||||
//
|
||||
// Should generate here a methtlsautheorization for every port
|
||||
// and pass in a list of service accounts instead of a list of apps.
|
||||
serviceAccounts := g.serviceAccounts(clientApplications[port])
|
||||
if len(serviceAccounts) > 0 {
|
||||
err = g.policyTemplates.Execute("linkerd", "meshtlsauthentication",
|
||||
writer,
|
||||
map[string]any{
|
||||
"app": app,
|
||||
"port": port,
|
||||
"serviceAccounts": serviceAccounts,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
err = g.policyTemplates.Execute("linkerd", "authorizationpolicy",
|
||||
g.apps[ingress.Application.Name] = ingress.Application
|
||||
err = g.policyTemplates.Execute("linkerd", "authorizationpolicy-app",
|
||||
writer,
|
||||
map[string]any{
|
||||
"app": app,
|
||||
"port": port,
|
||||
"clientNetworks": clientNetworks[port],
|
||||
"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
|
||||
@ -160,6 +115,15 @@ func (g *LinkerdPolicyGenerator) serviceAccounts(peers []*ApplicationPeer) []v1.
|
||||
}
|
||||
|
||||
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)
|
||||
|
@ -0,0 +1,16 @@
|
||||
---
|
||||
apiVersion: policy.linkerd.io/v1alpha1
|
||||
kind: AuthorizationPolicy
|
||||
metadata:
|
||||
name: app-{{ .client.Name }}-to-{{ .app.Name }}-p{{ .port }}
|
||||
namespace: {{ .app.Namespace.Name}}
|
||||
spec:
|
||||
targetRef:
|
||||
group: policy.linkerd.io
|
||||
kind: Server
|
||||
name: {{ .app.Name }}-p{{ .port }}
|
||||
requiredAuthenticationRefs:
|
||||
- name: {{ .client.Name }}
|
||||
namespace: {{ .client.Namespace.Name }}
|
||||
kind: MeshTLSAuthentication
|
||||
group: policy.linkerd.io
|
@ -2,7 +2,7 @@
|
||||
apiVersion: policy.linkerd.io/v1alpha1
|
||||
kind: AuthorizationPolicy
|
||||
metadata:
|
||||
name: {{ .app.Name }}-p{{ .port }}
|
||||
name: net-{{ .client.Name }}-to-{{ .app.Name }}-p{{ .port }}
|
||||
namespace: {{ .app.Namespace.Name}}
|
||||
spec:
|
||||
targetRef:
|
||||
@ -10,13 +10,7 @@ spec:
|
||||
kind: Server
|
||||
name: {{ .app.Name }}-p{{ .port }}
|
||||
requiredAuthenticationRefs:
|
||||
- name: {{ .app.Name }}-p{{ .port }}
|
||||
namespace: {{ .app.Namespace.Name }}
|
||||
kind: MeshTLSAuthentication
|
||||
group: policy.linkerd.io
|
||||
{{- range $net := .clientNetworks }}
|
||||
- name: {{ $net.Network.Name }}
|
||||
- name: {{ .client.Name }}
|
||||
namespace: default
|
||||
kind: NetworkAuthentication
|
||||
group: policy.linkerd.io
|
||||
{{- end }}
|
@ -2,13 +2,16 @@
|
||||
apiVersion: policy.linkerd.io/v1alpha1
|
||||
kind: MeshTLSAuthentication
|
||||
metadata:
|
||||
name: {{ .app.Name }}-p{{.port}}
|
||||
namespace: {{ .app.Namespace.Name }}
|
||||
name: {{ .Name }}
|
||||
namespace: {{ .Namespace.Name }}
|
||||
spec:
|
||||
{{- if .ServiceAccounts }}
|
||||
identityRefs:
|
||||
{{- range $sa := .serviceAccounts }}
|
||||
{{- range $sa := .ServiceAccounts }}
|
||||
- kind: ServiceAccount
|
||||
name: {{ $sa.Name }}
|
||||
namespace: {{ $sa.Namespace }}
|
||||
name: {{ $sa }}
|
||||
{{- end }}
|
||||
{{- else }}
|
||||
fail (printf "no service accounts defined for app %s" .Name )
|
||||
{{- end}}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user