update iptables
This commit is contained in:
parent
f6f4258609
commit
f25fa59449
@ -47,7 +47,6 @@ resources:
|
||||
defer ts.Close()
|
||||
|
||||
yaml, cliErr := exec.Command("./jx", "import", "--resource", ts.URL).Output()
|
||||
slog.Info("TestCliHTTPSource", "err", cliErr)
|
||||
assert.Nil(t, cliErr)
|
||||
assert.NotEqual(t, "", string(yaml))
|
||||
assert.Greater(t, len(yaml), 0)
|
||||
|
@ -29,7 +29,7 @@ var (
|
||||
)
|
||||
|
||||
var GlobalOformat *string
|
||||
var GlobalOutput *string
|
||||
var GlobalOutput string
|
||||
var GlobalQuiet *bool
|
||||
|
||||
var ImportMerge *bool
|
||||
@ -89,7 +89,6 @@ func LoadSourceURI(uri string) []*resource.Document {
|
||||
if extractErr != nil {
|
||||
log.Fatal(extractErr)
|
||||
}
|
||||
slog.Info("extract documents", "documents", extractDocuments)
|
||||
return extractDocuments
|
||||
}
|
||||
return []*resource.Document{ resource.NewDocument() }
|
||||
@ -103,7 +102,6 @@ func ImportSubCommand(cmd *flag.FlagSet, output io.Writer) (err error) {
|
||||
return e
|
||||
}
|
||||
|
||||
var encoder resource.Encoder
|
||||
merged := resource.NewDocument()
|
||||
documents := make([]*resource.Document, 0, 100)
|
||||
for _,source := range cmd.Args() {
|
||||
@ -113,20 +111,20 @@ func ImportSubCommand(cmd *flag.FlagSet, output io.Writer) (err error) {
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
switch *GlobalOformat {
|
||||
case FormatYaml:
|
||||
encoder = resource.NewYAMLEncoder(output)
|
||||
case FormatJson:
|
||||
encoder = resource.NewJSONEncoder(output)
|
||||
}
|
||||
*/
|
||||
|
||||
if *GlobalOutput != "" {
|
||||
_, err := target.TargetTypes.New(*GlobalOutput)
|
||||
slog.Info("main.ImportResource", "args", os.Args, "output", GlobalOutput)
|
||||
outputTarget, err := target.TargetTypes.New(GlobalOutput)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
//outputTarget.EmitResources(
|
||||
}
|
||||
|
||||
if len(documents) == 0 {
|
||||
documents = append(documents, resource.NewDocument())
|
||||
@ -151,18 +149,18 @@ func ImportSubCommand(cmd *flag.FlagSet, output io.Writer) (err error) {
|
||||
} else {
|
||||
if *ImportMerge {
|
||||
merged.ResourceDecls = append(merged.ResourceDecls, d.ResourceDecls...)
|
||||
slog.Info("merging", "doc", merged.ResourceDecls, "src", d.ResourceDecls)
|
||||
} else {
|
||||
if documentGenerateErr := encoder.Encode(d); documentGenerateErr != nil {
|
||||
return documentGenerateErr
|
||||
slog.Info("main.ImportResource", "outputTarget", outputTarget, "type", outputTarget.Type())
|
||||
if outputErr := outputTarget.EmitResources([]*resource.Document{d}, nil); outputErr != nil {
|
||||
return outputErr
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if *ImportMerge {
|
||||
if documentGenerateErr := encoder.Encode(merged); documentGenerateErr != nil {
|
||||
return documentGenerateErr
|
||||
if outputErr := outputTarget.EmitResources([]*resource.Document{merged}, nil); outputErr != nil {
|
||||
return outputErr
|
||||
}
|
||||
}
|
||||
return err
|
||||
@ -276,8 +274,8 @@ func main() {
|
||||
for _,subCmd := range jxSubCommands {
|
||||
cmdFlagSet := flag.NewFlagSet(subCmd.Name, flag.ExitOnError)
|
||||
GlobalOformat = cmdFlagSet.String("oformat", "yaml", "Output serialization format")
|
||||
GlobalOutput = cmdFlagSet.String("output", "-", "Output target (default stdout)")
|
||||
GlobalOutput = cmdFlagSet.String("o", "-", "Output target (default stdout)")
|
||||
cmdFlagSet.StringVar(&GlobalOutput, "output", "-", "Output target (default stdout)")
|
||||
cmdFlagSet.StringVar(&GlobalOutput, "o", "-", "Output target (default stdout)")
|
||||
GlobalQuiet = cmdFlagSet.Bool("quiet", false, "Generate terse output.")
|
||||
|
||||
switch subCmd.Name {
|
||||
@ -295,22 +293,19 @@ func main() {
|
||||
}
|
||||
case "import":
|
||||
cmdFlagSet.Usage = func() {
|
||||
fmt.Println("jx import source [source2]")
|
||||
fmt.Println("jx import source...")
|
||||
cmdFlagSet.PrintDefaults()
|
||||
VersionUsage()
|
||||
}
|
||||
}
|
||||
slog.Info("command", "command", subCmd)
|
||||
if os.Args[1] == subCmd.Name {
|
||||
if e := subCmd.Run(cmdFlagSet, os.Stdout); e != nil {
|
||||
log.Fatal(e)
|
||||
}
|
||||
return
|
||||
} else {
|
||||
}
|
||||
}
|
||||
flag.PrintDefaults()
|
||||
VersionUsage()
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ func (d *Document) Filter(filter ResourceSelector) []*Declaration {
|
||||
resources := make([]*Declaration, 0, len(d.ResourceDecls))
|
||||
for i := range d.ResourceDecls {
|
||||
filterResource := &d.ResourceDecls[i]
|
||||
if filter(filterResource) {
|
||||
if filter == nil || filter(filterResource) {
|
||||
resources = append(resources, &d.ResourceDecls[i])
|
||||
}
|
||||
}
|
||||
|
@ -45,6 +45,7 @@ func init() {
|
||||
|
||||
// Manage the state of file system objects
|
||||
type File struct {
|
||||
normalizePath bool `json:"-" yaml:"-"`
|
||||
Path string `json:"path" yaml:"path"`
|
||||
Owner string `json:"owner" yaml:"owner"`
|
||||
Group string `json:"group" yaml:"group"`
|
||||
@ -69,13 +70,20 @@ type ResourceFileInfo struct {
|
||||
func NewFile() *File {
|
||||
currentUser, _ := user.Current()
|
||||
group, _ := user.LookupGroupId(currentUser.Gid)
|
||||
f := &File{Owner: currentUser.Username, Group: group.Name, Mode: "0644", FileType: RegularFile}
|
||||
f := &File{ normalizePath: false, Owner: currentUser.Username, Group: group.Name, Mode: "0644", FileType: RegularFile}
|
||||
slog.Info("NewFile()", "file", f)
|
||||
return f
|
||||
}
|
||||
|
||||
func NewNormalizedFile() *File {
|
||||
f := NewFile()
|
||||
f.normalizePath = true
|
||||
return f
|
||||
}
|
||||
|
||||
func (f *File) Clone() Resource {
|
||||
return &File {
|
||||
normalizePath: f.normalizePath,
|
||||
Path: f.Path,
|
||||
Owner: f.Owner,
|
||||
Group: f.Group,
|
||||
@ -100,10 +108,9 @@ func (f *File) SetURI(uri string) error {
|
||||
resourceUri, e := url.Parse(uri)
|
||||
if e == nil {
|
||||
if resourceUri.Scheme == "file" {
|
||||
if absFilePath, err := filepath.Abs(filepath.Join(resourceUri.Hostname(), resourceUri.RequestURI())); err != nil {
|
||||
f.Path = filepath.Join(resourceUri.Hostname(), resourceUri.RequestURI())
|
||||
if err := f.NormalizePath(); err != nil {
|
||||
return err
|
||||
} else {
|
||||
f.Path = absFilePath
|
||||
}
|
||||
} else {
|
||||
e = fmt.Errorf("%w: %s is not a file", ErrInvalidResourceURI, uri)
|
||||
@ -187,34 +194,40 @@ func (f *File) Apply() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *File) LoadDecl(yamlResourceDeclaration string) error {
|
||||
func (f *File) LoadDecl(yamlResourceDeclaration string) (err error) {
|
||||
d := NewYAMLStringDecoder(yamlResourceDeclaration)
|
||||
return d.Decode(f)
|
||||
err = d.Decode(f)
|
||||
if err == nil {
|
||||
f.UpdateContentAttributes()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (f *File) ResolveId(ctx context.Context) string {
|
||||
filePath, fileAbsErr := filepath.Abs(f.Path)
|
||||
if fileAbsErr != nil {
|
||||
panic(fileAbsErr)
|
||||
if e := f.NormalizePath(); e != nil {
|
||||
panic(e)
|
||||
}
|
||||
f.Path = filePath
|
||||
return filePath
|
||||
return f.Path
|
||||
}
|
||||
|
||||
func (f *File) NormalizePath() error {
|
||||
if f.normalizePath {
|
||||
filePath, fileAbsErr := filepath.Abs(f.Path)
|
||||
if fileAbsErr == nil {
|
||||
f.Path = filePath
|
||||
}
|
||||
return fileAbsErr
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *File) FileInfo() fs.FileInfo {
|
||||
return &ResourceFileInfo{ resource: f }
|
||||
}
|
||||
|
||||
func (f *ResourceFileInfo) Name() string {
|
||||
return filepath.Base(f.resource.Path)
|
||||
// return filepath.Base(f.resource.Path)
|
||||
return f.resource.Path
|
||||
}
|
||||
|
||||
func (f *ResourceFileInfo) Size() int64 {
|
||||
@ -246,6 +259,11 @@ func (f *ResourceFileInfo) Sys() any {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *File) UpdateContentAttributes() {
|
||||
f.Size = int64(len(f.Content))
|
||||
f.Sha256 = fmt.Sprintf("%x", sha256.Sum256([]byte(f.Content)))
|
||||
}
|
||||
|
||||
func (f *File) UpdateAttributesFromFileInfo(info os.FileInfo) error {
|
||||
if info != nil {
|
||||
f.Mtime = info.ModTime()
|
||||
|
307
internal/resource/iptables.go
Normal file
307
internal/resource/iptables.go
Normal file
@ -0,0 +1,307 @@
|
||||
// Copyright 2024 Matthew Rich <matthewrich.conf@gmail.com>. All rights reserved.
|
||||
|
||||
package resource
|
||||
|
||||
import (
|
||||
"context"
|
||||
_ "encoding/hex"
|
||||
"encoding/json"
|
||||
_ "errors"
|
||||
"fmt"
|
||||
"gopkg.in/yaml.v3"
|
||||
"io"
|
||||
"net/url"
|
||||
_ "os/exec"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
"log/slog"
|
||||
)
|
||||
|
||||
func init() {
|
||||
ResourceTypes.Register("iptable", func(u *url.URL) Resource {
|
||||
i := NewIptable()
|
||||
i.Table = IptableName(u.Hostname())
|
||||
fields := strings.Split(u.Path, "/")
|
||||
slog.Info("iptables factory", "iptable", i, "uri", u, "field", fields)
|
||||
i.Chain = IptableChain(fields[1])
|
||||
id, _ := strconv.ParseUint(fields[2], 10, 32)
|
||||
i.Id = uint(id)
|
||||
return i
|
||||
})
|
||||
}
|
||||
|
||||
type IptableIPVersion string
|
||||
|
||||
const (
|
||||
IptableIPv4 IptableIPVersion = "ipv4"
|
||||
IPtableIPv6 IptableIPVersion = "ipv6"
|
||||
)
|
||||
|
||||
type IptableName string
|
||||
|
||||
const (
|
||||
IptableNameFilter = "filter"
|
||||
IptableNameNat = "nat"
|
||||
IptableNameMangel = "mangle"
|
||||
IptableNameRaw = "raw"
|
||||
IptableNameSecurity = "security"
|
||||
)
|
||||
|
||||
var IptableNumber = regexp.MustCompile(`^[0-9]+$`)
|
||||
|
||||
type IptableChain string
|
||||
|
||||
const (
|
||||
IptableChainInput = "INPUT"
|
||||
IptableChainOutput = "OUTPUT"
|
||||
IptableChainForward = "FORWARD"
|
||||
IptableChainPreRouting = "PREROUTING"
|
||||
IptableChainPostRouting = "POSTROUTING"
|
||||
)
|
||||
|
||||
type IptableProto string
|
||||
|
||||
const (
|
||||
IptableProtoTCP = "tcp"
|
||||
IptableProtoUDP = "udp"
|
||||
IptableProtoUDPLite = "udplite"
|
||||
IptableProtoICMP = "icmp"
|
||||
IptableProtoICMPv6 = "icmpv6"
|
||||
IptableProtoESP = "ESP"
|
||||
IptableProtoAH = "AH"
|
||||
IptableProtoSCTP = "sctp"
|
||||
IptableProtoMH = "mh"
|
||||
IptableProtoAll = "all"
|
||||
)
|
||||
|
||||
type IptableCIDR string
|
||||
|
||||
type ExtensionFlag struct {
|
||||
Name string `json:"name" yaml:"name"`
|
||||
Value string `json:"value" yaml:"value"`
|
||||
}
|
||||
|
||||
type IptablePort uint16
|
||||
|
||||
// Manage the state of iptables rules
|
||||
// iptable://filter/INPUT/0
|
||||
type Iptable struct {
|
||||
Id uint `json:"id" yaml:"id"`
|
||||
Table IptableName `json:"table" yaml:"table"`
|
||||
Chain IptableChain `json:"chain" yaml:"chain"`
|
||||
Destination IptableCIDR `json:"destination,omitempty" yaml:"destination,omitempty"`
|
||||
Source IptableCIDR `json:"source,omitempty" yaml:"source,omitempty"`
|
||||
Dport IptablePort `json:"dport,omitempty" yaml:"dport,omitempty"`
|
||||
Sport IptablePort `json:"sport,omitempty" yaml:"sport,omitempty"`
|
||||
In string `json:"in,omitempty" yaml:"in,omitempty"`
|
||||
Out string `json:"out,omitempty" yaml:"out,omitempty"`
|
||||
Match []string `json:"match,omitempty" yaml:"match,omitempty"`
|
||||
Flags []ExtensionFlag `json:"extension_flags,omitempty" yaml:"extension_flags,omitempty"`
|
||||
Proto IptableProto `json:"proto,omitempty" yaml:"proto,omitempty"`
|
||||
Jump string `json:"jump" yaml:"jump"`
|
||||
State string `json:"state" yaml:"state"`
|
||||
|
||||
CreateCommand *Command `yaml:"-" json:"-"`
|
||||
ReadCommand *Command `yaml:"-" json:"-"`
|
||||
UpdateCommand *Command `yaml:"-" json:"-"`
|
||||
DeleteCommand *Command `yaml:"-" json:"-"`
|
||||
}
|
||||
|
||||
func NewIptable() *Iptable {
|
||||
i := &Iptable{}
|
||||
i.CreateCommand, i.ReadCommand, i.UpdateCommand, i.DeleteCommand = i.NewCRUD()
|
||||
return i
|
||||
}
|
||||
|
||||
func (i *Iptable) Clone() Resource {
|
||||
return &Iptable {
|
||||
Id: i.Id,
|
||||
Table: i.Table,
|
||||
Chain: i.Chain,
|
||||
Destination: i.Destination,
|
||||
Source: i.Source,
|
||||
In: i.In,
|
||||
Out: i.Out,
|
||||
Match: i.Match,
|
||||
Proto: i.Proto,
|
||||
State: i.State,
|
||||
}
|
||||
}
|
||||
|
||||
func (i *Iptable) URI() string {
|
||||
return fmt.Sprintf("iptable://%s/%s/%d", i.Table, i.Chain, i.Id)
|
||||
}
|
||||
|
||||
func (i *Iptable) SetURI(uri string) error {
|
||||
resourceUri, e := url.Parse(uri)
|
||||
if e == nil {
|
||||
if resourceUri.Scheme == "iptable" {
|
||||
i.Table = IptableName(resourceUri.Hostname())
|
||||
fields := strings.Split(resourceUri.Path, "/")
|
||||
i.Chain = IptableChain(fields[1])
|
||||
id, _ := strconv.ParseUint(fields[2], 10, 32)
|
||||
i.Id = uint(id)
|
||||
} else {
|
||||
e = fmt.Errorf("%w: %s is not an iptable rule", ErrInvalidResourceURI, uri)
|
||||
}
|
||||
}
|
||||
return e
|
||||
}
|
||||
|
||||
func (i *Iptable) Validate() error {
|
||||
s := NewSchema(i.Type())
|
||||
jsonDoc, jsonErr := i.JSON()
|
||||
if jsonErr == nil {
|
||||
return s.Validate(string(jsonDoc))
|
||||
}
|
||||
return jsonErr
|
||||
}
|
||||
|
||||
func (i *Iptable) JSON() ([]byte, error) {
|
||||
return json.Marshal(i)
|
||||
}
|
||||
|
||||
func (i *Iptable) UnmarshalJSON(data []byte) error {
|
||||
if unmarshalErr := json.Unmarshal(data, i); unmarshalErr != nil {
|
||||
return unmarshalErr
|
||||
}
|
||||
i.CreateCommand, i.ReadCommand, i.UpdateCommand, i.DeleteCommand = i.NewCRUD()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (i *Iptable) UnmarshalYAML(value *yaml.Node) error {
|
||||
type decodeIptable Iptable
|
||||
if unmarshalErr := value.Decode((*decodeIptable)(i)); unmarshalErr != nil {
|
||||
return unmarshalErr
|
||||
}
|
||||
i.CreateCommand, i.ReadCommand, i.UpdateCommand, i.DeleteCommand = i.NewCRUD()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (i *Iptable) NewCRUD() (create *Command, read *Command, update *Command, del *Command) {
|
||||
return NewIptableCreateCommand(), NewIptableReadCommand(), NewIptableUpdateCommand(), NewIptableDeleteCommand()
|
||||
}
|
||||
|
||||
func (i *Iptable) Apply() error {
|
||||
|
||||
switch i.State {
|
||||
case "absent":
|
||||
case "present":
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (i *Iptable) Load(r io.Reader) error {
|
||||
return NewYAMLDecoder(r).Decode(i)
|
||||
}
|
||||
|
||||
func (i *Iptable) LoadDecl(yamlResourceDeclaration string) error {
|
||||
return NewYAMLStringDecoder(yamlResourceDeclaration).Decode(i)
|
||||
}
|
||||
|
||||
|
||||
func (i *Iptable) ResolveId(ctx context.Context) string {
|
||||
// uri := fmt.Sprintf("%s?gateway=%s&interface=%s&rtid=%s&metric=%d&type=%s&scope=%s",
|
||||
// n.To, n.Gateway, n.Interface, n.Rtid, n.Metric, n.RouteType, n.Scope)
|
||||
// n.Id = hex.EncodeToString([]byte(uri))
|
||||
return fmt.Sprintf("%d", i.Id)
|
||||
}
|
||||
|
||||
func (i *Iptable) Read(ctx context.Context) ([]byte, error) {
|
||||
out, err := i.ReadCommand.Execute(i)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
exErr := i.ReadCommand.Extractor(out, i)
|
||||
if exErr != nil {
|
||||
return nil, exErr
|
||||
}
|
||||
return yaml.Marshal(i)
|
||||
}
|
||||
|
||||
func (i *Iptable) Type() string { return "iptable" }
|
||||
|
||||
func NewIptableCreateCommand() *Command {
|
||||
c := NewCommand()
|
||||
c.Path = "iptables"
|
||||
c.Args = []CommandArg{
|
||||
CommandArg("-t"),
|
||||
CommandArg("{{ .Table }}"),
|
||||
CommandArg("-R"),
|
||||
CommandArg("{{ .Chain }}"),
|
||||
CommandArg("{{ .Id }}"),
|
||||
CommandArg("{{ if .In }}-i {{ .In }}{{ else if .Out }}-o {{ .Out }}{{ end }}"),
|
||||
CommandArg("{{ range .Match }}-m {{ . }} {{ end }}"),
|
||||
CommandArg("{{ if .Source }}-s {{ .Source }}{{ end }}"),
|
||||
CommandArg("{{ if .Destination }}-d {{ .Destination }}{{ end }}"),
|
||||
CommandArg("{{ if .Jump }}-j {{ .Jump }}{{ end }}"),
|
||||
}
|
||||
return c
|
||||
}
|
||||
|
||||
func NewIptableReadCommand() *Command {
|
||||
c := NewCommand()
|
||||
c.Path = "iptables"
|
||||
c.Args = []CommandArg{
|
||||
CommandArg("-t"),
|
||||
CommandArg("{{ .Table }}"),
|
||||
CommandArg("-S"),
|
||||
CommandArg("{{ .Chain }}"),
|
||||
CommandArg("{{ .Id }}"),
|
||||
}
|
||||
c.Extractor = func(out []byte, target any) error {
|
||||
i := target.(*Iptable)
|
||||
ruleFields := strings.Split(strings.TrimSpace(string(out)), " ")
|
||||
switch ruleFields[0] {
|
||||
case "-A":
|
||||
//chain := ruleFields[1]
|
||||
flags := ruleFields[2:]
|
||||
for optind,opt := range flags {
|
||||
if optind > len(flags) - 2 {
|
||||
break
|
||||
}
|
||||
optValue := flags[optind + 1]
|
||||
switch opt {
|
||||
case "-i":
|
||||
i.In = optValue
|
||||
case "-o":
|
||||
i.Out = optValue
|
||||
case "-m":
|
||||
i.Match = append(i.Match, optValue)
|
||||
case "-s":
|
||||
i.Source = IptableCIDR(optValue)
|
||||
case "-d":
|
||||
i.Destination = IptableCIDR(optValue)
|
||||
case "-p":
|
||||
i.Proto = IptableProto(optValue)
|
||||
case "-j":
|
||||
i.Jump = optValue
|
||||
case "--dport":
|
||||
port,_ := strconv.ParseUint(optValue, 10, 16)
|
||||
i.Dport = IptablePort(port)
|
||||
case "--sport":
|
||||
port,_ := strconv.ParseUint(optValue, 10, 16)
|
||||
i.Sport = IptablePort(port)
|
||||
default:
|
||||
if opt[0] == '-' {
|
||||
i.Flags = append(i.Flags, ExtensionFlag{ Name: strings.Trim(opt, "-"), Value: strings.TrimSpace(optValue)})
|
||||
}
|
||||
}
|
||||
}
|
||||
i.State = "present"
|
||||
default:
|
||||
i.State = "absent"
|
||||
}
|
||||
return nil
|
||||
}
|
||||
return c
|
||||
}
|
||||
|
||||
func NewIptableUpdateCommand() *Command {
|
||||
return nil
|
||||
}
|
||||
|
||||
func NewIptableDeleteCommand() *Command {
|
||||
return nil
|
||||
}
|
76
internal/resource/iptables_test.go
Normal file
76
internal/resource/iptables_test.go
Normal file
@ -0,0 +1,76 @@
|
||||
// Copyright 2024 Matthew Rich <matthewrich.conf@gmail.com>. All rights reserved.
|
||||
|
||||
package resource
|
||||
|
||||
import (
|
||||
"context"
|
||||
_ "encoding/json"
|
||||
_ "fmt"
|
||||
"github.com/stretchr/testify/assert"
|
||||
_ "gopkg.in/yaml.v3"
|
||||
_ "io"
|
||||
_ "log"
|
||||
_ "net/http"
|
||||
_ "net/http/httptest"
|
||||
_ "net/url"
|
||||
_ "os"
|
||||
_ "path/filepath"
|
||||
_ "strings"
|
||||
_ "syscall"
|
||||
"testing"
|
||||
_ "time"
|
||||
)
|
||||
|
||||
func TestNewIptableResource(t *testing.T) {
|
||||
i := NewIptable()
|
||||
assert.NotNil(t, i)
|
||||
}
|
||||
|
||||
func TestIptableApplyResourceTransformation(t *testing.T) {
|
||||
i := NewIptable()
|
||||
assert.NotNil(t, i)
|
||||
|
||||
//e := f.Apply()
|
||||
//assert.Equal(t, nil, e)
|
||||
}
|
||||
|
||||
func TestReadIptable(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
testRule := NewIptable()
|
||||
assert.NotNil(t, testRule)
|
||||
|
||||
declarationAttributes := `
|
||||
id: 0
|
||||
table: "filter"
|
||||
chain: "INPUT"
|
||||
source: "192.168.0.0/24"
|
||||
destination: "192.168.0.1"
|
||||
jump: "ACCEPT"
|
||||
state: present
|
||||
`
|
||||
m := &MockCommand{
|
||||
Executor: func(value any) ([]byte, error) {
|
||||
return nil, nil
|
||||
},
|
||||
Extractor: func(output []byte, target any) error {
|
||||
testRule.Table = "filter"
|
||||
testRule.Chain = "INPUT"
|
||||
testRule.Id = 0
|
||||
testRule.In = "eth0"
|
||||
testRule.Source = "192.168.0.0/24"
|
||||
testRule.State = "present"
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
e := testRule.LoadDecl(declarationAttributes)
|
||||
assert.Nil(t, e)
|
||||
testRule.ReadCommand = (*Command)(m)
|
||||
// testRuleErr := testRule.Apply()
|
||||
// assert.Nil(t, testRuleErr)
|
||||
r, e := testRule.Read(ctx)
|
||||
|
||||
assert.Nil(t, e)
|
||||
assert.NotNil(t, r)
|
||||
assert.Equal(t, "eth0", testRule.In)
|
||||
}
|
@ -38,6 +38,7 @@ func TestResolveId(t *testing.T) {
|
||||
testFile := NewResource("file://../../README.md")
|
||||
assert.NotNil(t, testFile)
|
||||
|
||||
testFile.(*File).normalizePath = true
|
||||
absolutePath, e := filepath.Abs("../../README.md")
|
||||
assert.Nil(t, e)
|
||||
|
||||
|
@ -15,7 +15,8 @@
|
||||
{ "$ref": "http-declaration.jsonschema" },
|
||||
{ "$ref": "user-declaration.jsonschema" },
|
||||
{ "$ref": "exec-declaration.jsonschema" },
|
||||
{ "$ref": "network_route-declaration.jsonschema" }
|
||||
{ "$ref": "network_route-declaration.jsonschema" },
|
||||
{ "$ref": "iptable-declaration.jsonschema" }
|
||||
]
|
||||
}
|
||||
}
|
||||
|
17
internal/resource/schemas/iptable-declaration.jsonschema
Normal file
17
internal/resource/schemas/iptable-declaration.jsonschema
Normal file
@ -0,0 +1,17 @@
|
||||
{
|
||||
"$id": "iptable-declaration.jsonschema",
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"title": "iptable-declaration",
|
||||
"type": "object",
|
||||
"required": [ "type", "attributes" ],
|
||||
"properties": {
|
||||
"type": {
|
||||
"type": "string",
|
||||
"description": "Resource type name.",
|
||||
"enum": [ "iptable" ]
|
||||
},
|
||||
"attributes": {
|
||||
"$ref": "iptable.jsonschema"
|
||||
}
|
||||
}
|
||||
}
|
68
internal/resource/schemas/iptable.jsonschema
Normal file
68
internal/resource/schemas/iptable.jsonschema
Normal file
@ -0,0 +1,68 @@
|
||||
{
|
||||
"$id": "iptable.jsonschema",
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"title": "iptable",
|
||||
"type": "object",
|
||||
"required": [ "chain" ],
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "integer",
|
||||
"minimum": 1
|
||||
},
|
||||
"table": {
|
||||
"type": "string",
|
||||
"description": "Rule table name"
|
||||
},
|
||||
"chain": {
|
||||
"type": "string",
|
||||
"description": "Rule chain name"
|
||||
},
|
||||
"destination": {
|
||||
"type": "string",
|
||||
"description": "Destination CIDR",
|
||||
"pattern": "^([0-9]{1,3}\\.){3}[0-9]{1,3}/([0-9]|[1-2][0-9]|3[0-2])$"
|
||||
},
|
||||
"source": {
|
||||
"type": "string",
|
||||
"description": "Source CIDR",
|
||||
"pattern": "^([0-9]{1,3}\\.){3}[0-9]{1,3}/([0-9]|[1-2][0-9]|3[0-2])$"
|
||||
},
|
||||
"in": {
|
||||
"type": "string",
|
||||
"description": "Input ethernet device"
|
||||
},
|
||||
"out": {
|
||||
"type": "string",
|
||||
"description": "Output ethernet device"
|
||||
},
|
||||
"match": {
|
||||
"type": "array",
|
||||
"description": "Rule match extensions",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"extension_flags": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"value": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"proto": {
|
||||
"type": "string",
|
||||
"description": "Rule protocol",
|
||||
"pattern": "^(tcp|udp|udplite|icmp|icmpv6|ESP|AH|sctp|mh|all|[0-9]+)$"
|
||||
},
|
||||
"jump": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user