Skip to content
This repository has been archived by the owner on Sep 19, 2024. It is now read-only.

Commit

Permalink
basic service discovery support
Browse files Browse the repository at this point in the history
  • Loading branch information
waynz0r committed Nov 14, 2023
1 parent 835b80b commit 2de0723
Show file tree
Hide file tree
Showing 5 changed files with 214 additions and 3 deletions.
23 changes: 21 additions & 2 deletions internal/cli/cmd/agent/agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import (
"github.com/cisco-open/nasp/pkg/agent/server"
"github.com/cisco-open/nasp/pkg/config"
"github.com/cisco-open/nasp/pkg/rules"
"github.com/cisco-open/nasp/pkg/sd"
"github.com/cisco-open/nasp/pkg/tls"
)

Expand All @@ -59,6 +60,7 @@ func NewCommand(c cli.CLI) *cobra.Command {
cmd.PersistentFlags().String("agent-local-address", "/tmp/nasp/agent.sock", "Local address")
cmd.Flags().String("kernel-module-device", "/dev/nasp", "Device for the Nasp kernel module")
cmd.Flags().StringSlice("rules-path", nil, "Rules path")
cmd.Flags().StringSlice("sd-path", nil, "Service discovery definition path")
cmd.Flags().String("trust-domain", config.DefaultTrustDomain, "Trust domain")
cmd.Flags().Duration("default-cert-ttl", config.DefaultCertTTLDuration, "Default certificate TTL")
cmd.Flags().String("ca-pem-path", "", "Path for CA pem")
Expand Down Expand Up @@ -116,8 +118,6 @@ func (c *agentCommand) run(cmd *cobra.Command) error {
logger.Info("sending config to kernel")
if cj, err := json.Marshal(config.KernelModuleConfig{TrustDomain: c.cli.Configuration().Agent.TrustDomain}); err != nil {
c.cli.Logger().Error(err, "could not marshal module config")

return
} else {
eventBus.Publish(messenger.MessageOutgoingTopic, messenger.NewCommand(messenger.Command{
Command: "load_config",
Expand All @@ -126,6 +126,25 @@ func (c *agentCommand) run(cmd *cobra.Command) error {
}
})

// service discovery loader
eventBus.Subscribe(messenger.MessengerStartedTopic, func(topic string, _ bool) {
go func() {
l := sd.NewFilesLoader(c.cli.Viper().GetStringSlice("agent.sdPath"), logger)
if err := l.Run(cmd.Context(), func(entries sd.Entries) {
if j, err := json.Marshal(entries); err != nil {
c.cli.Logger().Error(err, "could not marshal module config")
} else {
eventBus.Publish(messenger.MessageOutgoingTopic, messenger.NewCommand(messenger.Command{
Command: "load_sd_info",
Code: j,
}))
}
}); err != nil {
errChan <- err
}
}()
})

// rules loader
eventBus.Subscribe(messenger.MessengerStartedTopic, func(topic string, _ bool) {
go func() {
Expand Down
33 changes: 33 additions & 0 deletions pkg/sd/entry.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
* The MIT License (MIT)
* Copyright (c) 2023 Cisco and/or its affiliates. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or substantial
* portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
* TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

package sd

type Entries map[string]Entry

type RawEntries []*RawEntry

type RawEntry struct {
Tags []string `yaml:"tags,omitempty" json:"tags,omitempty"`
Addresses []string `yaml:"addresses,omitempty" json:"addresses,omitempty"`
}

type Entry struct {
Tags []string `yaml:"tags,omitempty" json:"tags,omitempty"`
}
144 changes: 144 additions & 0 deletions pkg/sd/loader.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
/*
* The MIT License (MIT)
* Copyright (c) 2023 Cisco and/or its affiliates. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or substantial
* portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
* TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

package sd

import (
"context"
"fmt"
"net"
"net/netip"
"strconv"
"strings"
"sync"

"github.com/go-logr/logr"
"gopkg.in/yaml.v2"

"github.com/cisco-open/nasp/pkg/util"
)

type FilesLoader interface {
Run(context.Context, EntryHandlerFunc) error
}

type filesLoader struct {
fileContentLoader util.FileContentLoader
logger logr.Logger

mu sync.Mutex
}

type EntryHandlerFunc func(Entries)

func NewFilesLoader(paths []string, logger logr.Logger) FilesLoader {
l := logger.WithName("sdFileLoader")

return &filesLoader{
fileContentLoader: util.NewFileContentLoader(paths, l),
logger: l,

mu: sync.Mutex{},
}
}

func (r *filesLoader) Run(ctx context.Context, h EntryHandlerFunc) error {
return r.fileContentLoader.Run(ctx, func(contents map[string][]byte) {
loadedEntries := make(Entries, 0)

for file, content := range contents {
var rawEntries RawEntries
if err := yaml.Unmarshal(content, &rawEntries); err != nil {
r.logger.Error(err, "error during sd file parsing", "path", file)
continue
}

for _, entry := range rawEntries {
// skip invalid entries
if len(entry.Tags) == 0 || len(entry.Addresses) == 0 {
continue
}
for _, address := range entry.Addresses {
addrs := resolveAddress(address)
for _, addr := range addrs {
loadedEntries[addressToString(addr)] = Entry{
Tags: entry.Tags,
}
}
}
}
}

h(loadedEntries)
})
}

func addressToString(addr netip.AddrPort) string {
if addr.Port() == 0 {
return addr.Addr().StringExpanded()
}

return fmt.Sprintf("%s:%d", addr.Addr().StringExpanded(), addr.Port())
}

func resolveAddress(address string) []netip.AddrPort {
hasPort := strings.ContainsRune(address, ':')
addrporrs := make([]netip.AddrPort, 0)

var host, port string
var err error

if hasPort {
host, port, err = net.SplitHostPort(address)
if err != nil {
return nil
}
} else {
host = address
}

var intport int
if port != "" {
intport, err = strconv.Atoi(port)
if err != nil {
return nil
}
}

addrs := make([]netip.Addr, 0)
if addr, err := netip.ParseAddr(host); err != nil {
netips, err := net.LookupIP(host)
if err != nil {
return nil
}
for _, ip := range netips {
if addr, ok := netip.AddrFromSlice(ip); ok {
addrs = append(addrs, addr)
}
}
} else {
addrs = append(addrs, addr)
}

for _, addr := range addrs {
addrporrs = append(addrporrs, netip.AddrPortFrom(addr, uint16(intport)))
}

return addrporrs
}
7 changes: 6 additions & 1 deletion rules.d/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
# local python or go file-server
- linux:uid: [501, 1001]
linux:binary:name: [python3.10, python3.11, file-server]
destination:port: 8000
destination:port: [8000, 8080]
properties:
mtls: true
workloadID: accounting/department-a/important-backend
Expand All @@ -41,3 +41,8 @@
properties:
mtls: true
workloadID: curl
egress:
- selectors:
- label: traefik
properties:
workloadID: specific-workload-id
10 changes: 10 additions & 0 deletions sd.d/ci.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
- tags:
- app:label:traefik
- linux:uid:500
- linux:binary:name:traefik
addresses:
- 127.0.0.1:8000
- addresses:
- 127.0.0.1:8080
tags:
- app-label:python

0 comments on commit 2de0723

Please sign in to comment.