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

Commit

Permalink
refactor to use grpc api types
Browse files Browse the repository at this point in the history
  • Loading branch information
waynz0r committed Jan 17, 2024
1 parent f152e0d commit 4a975f1
Show file tree
Hide file tree
Showing 9 changed files with 799 additions and 34 deletions.
24 changes: 10 additions & 14 deletions internal/cli/cmd/agent/agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,12 @@ import (
"github.com/spf13/cobra"

"github.com/cisco-open/nasp/internal/cli"
"github.com/cisco-open/nasp/internal/policy"
"github.com/cisco-open/nasp/internal/service"
"github.com/cisco-open/nasp/pkg/agent/commands"
"github.com/cisco-open/nasp/pkg/agent/messenger"
"github.com/cisco-open/nasp/pkg/config"
"github.com/cisco-open/nasp/pkg/config/metadata/collectors"
"github.com/cisco-open/nasp/pkg/rules"
"github.com/cisco-open/nasp/pkg/sd"
"github.com/cisco-open/nasp/pkg/tls"
)

Expand Down Expand Up @@ -143,9 +143,9 @@ 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 {
l := service.NewFileLoader(c.cli.Viper().GetStringSlice("agent.sdPath"), service.FileLoadWithLogger(logger))
if err := l.Run(cmd.Context(), func(entries service.Services) {
if j, err := json.MarshalIndent(entries, "", " "); err != nil {
c.cli.Logger().Error(err, "could not marshal module config")
} else {
eventBus.Publish(messenger.MessageOutgoingTopic, messenger.NewCommand(messenger.Command{
Expand All @@ -162,24 +162,20 @@ func (c *agentCommand) run(cmd *cobra.Command) error {
// rules loader
eventBus.Subscribe(messenger.MessengerStartedTopic, func(topic string, _ bool) {
go func() {
r := rules.NewRuleFilesLoader(
r := policy.NewFileLoader(
c.cli.Viper().GetStringSlice("agent.rulesPath"),
logger,
rules.RuleFilesLoaderWithTemplater(rules.NewRuleTemplater(rules.RuleTemplateValues{
policy.FileLoaderWithTemplateFunc(policy.NewPolicyTemplater(policy.PolicyTemplateValues{
TrustDomain: c.cli.Configuration().Agent.TrustDomain,
}, c.cli.Logger()).Execute,
))
if err := r.Run(cmd.Context(), func(r rules.Rules) {
if err := r.Run(cmd.Context(), func(r policy.Policies) {
logger.Info("rule count", "count", len(r))

if err := r.Organize(); err != nil {
logger.Error(err, "problem with the rules")

return
}
r.Organize()

type Policies struct {
Policies rules.Rules `json:"policies"`
Policies policy.Policies `json:"policies"`
}

y, _ := json.MarshalIndent(Policies{
Expand Down
48 changes: 28 additions & 20 deletions internal/cli/cmd/agent/rule.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
package agent

import (
"bytes"
"os"
"strconv"
"strings"
Expand All @@ -30,13 +29,15 @@ import (
"github.com/dchest/validator"
"github.com/spf13/cobra"
"github.com/spiffe/go-spiffe/v2/spiffeid"
"gopkg.in/yaml.v3"
"google.golang.org/protobuf/encoding/protojson"
"google.golang.org/protobuf/types/known/durationpb"
"google.golang.org/protobuf/types/known/structpb"
"sigs.k8s.io/yaml"

"github.com/cisco-open/nasp/api/v1/core"
"github.com/cisco-open/nasp/internal/cli"
"github.com/cisco-open/nasp/pkg/config/metadata/collectors"
"github.com/cisco-open/nasp/pkg/rules"
"github.com/cisco-open/nasp/pkg/tls"
"github.com/cisco-open/nasp/pkg/util"
"github.com/gezacorp/metadatax"
)

Expand Down Expand Up @@ -122,45 +123,52 @@ func (c *generateRuleCommand) run(cmd *cobra.Command, args []string) error {
for _, e := range errors.GetErrors(err) {
c.cli.Logger().V(1).Info("error during metadata collection", "error", e)
}
err = nil
}

rule := rules.Rule{
Selectors: []rules.Selectors{{}},
Properties: rules.Properties{
rule := &core.Policy{
Selectors: []*structpb.Struct{
{
Fields: make(map[string]*structpb.Value),
},
},
Certificate: &core.Policy_Certificate{
WorkloadID: args[1],
DNS: c.opts.dnsNames,
TTL: c.opts.ttl.String(),
DnsNames: c.opts.dnsNames,
Ttl: durationpb.New(c.opts.ttl),
},
Policy: rules.Policy{
Connection: &core.Policy_Connection{
Mtls: core.Policy_Connection_STRICT,
AllowedSPIFFEIDs: c.opts.allowedSPIFFEIDs,
},
}

if c.opts.disableMTLS {
rule.Policy.MTLS = util.BoolPointer(false)
rule.Connection.Mtls = core.Policy_Connection_DISABLE
}

for _, label := range md.GetLabelsSlice() {
if !c.matchLabel(label.Name) {
continue
}

rule.Selectors[0][label.Name] = label.Value
rule.Selectors[0].Fields[label.Name] = structpb.NewStringValue(label.Value)
}

if len(rule.Selectors[0]) == 0 {
if len(rule.Selectors[0].Fields) == 0 {
return errors.New("could not find selectors")
}

buf := new(bytes.Buffer)
e := yaml.NewEncoder(buf)
e.SetIndent(2)
if err := e.Encode([]rules.Rule{rule}); err != nil {
return err
jsonBytes, err := protojson.Marshal(rule)
if err != nil {
return errors.WrapIf(err, "could not marshal json")
}

yamlBytes, err := yaml.JSONToYAML([]byte("[" + string(jsonBytes) + "]"))
if err != nil {
return errors.WrapIf(err, "could not marshal yaml")
}

os.Stdout.Write(buf.Bytes())
os.Stdout.Write(yamlBytes)

return err
}
Expand Down
153 changes: 153 additions & 0 deletions internal/policy/convert.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
/*
* 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 policy

import (
"encoding/json"
"fmt"

"github.com/google/uuid"
"google.golang.org/protobuf/types/known/structpb"
)

func ConvertPolicy(policy *RawPolicy) *Policy {
iPolicy := &Policy{
ID: getPolicyID(policy),
Certificate: policy.GetCertificate(),
Connection: policy.GetConnection(),
Egress: ConvertPolicies(policy.Egress),
}

for _, sel := range policy.GetSelectors() {
iPolicy.Selectors = append(iPolicy.Selectors, convertSelectorsToRawSelectors(sel)...)
}

return iPolicy
}

func ConvertPolicies(policies []*RawPolicy) Policies {
iPolicies := Policies{}
for _, policy := range policies {
iPolicies = append(iPolicies, ConvertPolicy(policy))
}

return iPolicies
}

func convertSelectorsToRawSelectors(selectors *structpb.Struct) Selectors {
return convertStringArraysSelectorsToMap(makeArrayPermutations(flattenAndStringifySelectors(selectors)))
}

func getPolicyID(policy *RawPolicy) string {
y, err := json.Marshal(policy.Connection)
if err != nil {
return ""
}

return uuid.NewSHA1(uuid.Nil, y).String()
}

func getValueForKind(value *structpb.Value) []string {
values := []string{}

switch val := value.Kind.(type) {
case *structpb.Value_NumberValue:
values = append(values, fmt.Sprintf("%0.0f", val.NumberValue))
case *structpb.Value_StringValue:
values = append(values, val.StringValue)
case *structpb.Value_ListValue:
for _, v := range val.ListValue.GetValues() {
values = append(values, getValueForKind(v)...)
}
}

return values
}

func flattenAndStringifySelectors(selectors *structpb.Struct) [][]string {
results := [][]string{}

for k, v := range selectors.Fields {
m := make([]string, 0)

values := getValueForKind(v)
for _, val := range values {
m = append(m, fmt.Sprintf("%s:%s", k, val))
}

if len(m) > 0 {
results = append(results, m)
}
}

return results
}

func makeArrayPermutations(arrays [][]string) [][]string {
n := len(arrays)
rest := make([][]string, 0)
indicies := make([]int, n)

for i := 0; i < n; i++ {
indicies[i] = 0
}

for {
r := make([]string, 0)
for i := 0; i < n; i++ {
r = append(r, arrays[i][indicies[i]])

}
rest = append(rest, r)

next := n - 1
for next >= 0 && (indicies[next]+1 >= len(arrays[next])) {
next--
}

if next < 0 {
break
}

indicies[next]++

for i := next + 1; i < n; i++ {
indicies[i] = 0
}
}

return rest
}

func convertStringArraysSelectorsToMap(arrays [][]string) []map[string]bool {
result := []map[string]bool{}

for _, array := range arrays {
m := map[string]bool{}

for _, value := range array {
m[value] = true
}

result = append(result, m)
}

return result
}
Loading

0 comments on commit 4a975f1

Please sign in to comment.