Skip to content

Commit 91fd5da

Browse files
committed
Provide platform to DI
NewFilenameLocator added thursday work
1 parent a747a8a commit 91fd5da

File tree

16 files changed

+219
-185
lines changed

16 files changed

+219
-185
lines changed

plugins/platformdetect/platform_detector.go

Lines changed: 21 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -6,36 +6,15 @@ import (
66
"slices"
77

88
"github.com/untangle/golang-shared/plugins"
9+
"github.com/untangle/golang-shared/plugins/types"
910
"github.com/untangle/golang-shared/services/settings"
1011
)
1112

12-
// HostType is a externally-opaque type for declaring a host
13-
// type.
14-
type HostType struct {
15-
indicatorFilename string
16-
name string
17-
}
18-
19-
var (
20-
EOS = HostType{
21-
indicatorFilename: "/etc/Eos-release",
22-
name: "Eos",
23-
}
24-
OpenWrt = HostType{
25-
indicatorFilename: "/etc/openwrt_version",
26-
name: "OpenWrt",
27-
}
28-
Unclassified = HostType{
29-
indicatorFilename: "",
30-
name: "Unclassified",
31-
}
32-
)
33-
3413
// PlatformFilter is a plugin predicate (declared in
3514
// golang-shared/plugins) which filters out plugins that have
3615
// PluginSpec metadata and don't apply to the current platform.
3716
type PlatformFilter struct {
38-
currentPlatform HostType
17+
currentPlatform types.Platform
3918
}
4019

4120
// PlatformSpec is a specification of the platforms that apply to a
@@ -50,31 +29,28 @@ type PlatformFilter struct {
5029
// empty (just don't supply a PlatformSpec in this case) but if they
5130
// are, the plugin will be run.
5231
type PlatformSpec struct {
53-
OnlyOn []HostType
54-
Excludes []HostType
32+
OnlyOn []types.Platform
33+
Excludes []types.Platform
5534
}
5635

57-
// NewPlatformFilter creates a new platform filter, during
58-
// construction we determine the platform from the filesystem.
59-
func NewPlatformFilter(fs fs.StatFS) *PlatformFilter {
60-
platforms := []HostType{
61-
EOS,
62-
OpenWrt,
63-
Unclassified,
64-
}
65-
filter := &PlatformFilter{
66-
currentPlatform: Unclassified,
67-
}
68-
for _, plat := range platforms {
69-
if settings.FileExistsInFS(plat.indicatorFilename, fs) {
70-
filter.currentPlatform = plat
71-
return filter
36+
// Determines the platform by looking at the provided FS
37+
// for specific files.
38+
func GetCurrentPlatform(fs fs.StatFS) types.Platform {
39+
for _, plat := range types.Platforms {
40+
if settings.FileExistsInFS(plat.IndicatorFilename, fs) {
41+
return plat
7242
}
7343
}
74-
return filter
44+
return types.Unclassified
45+
}
46+
47+
// NewPlatformFilter creates a new platform filter, during
48+
// construction we determine the platform from the filesystem.
49+
func NewPlatformFilter(platform types.Platform) *PlatformFilter {
50+
return &PlatformFilter{currentPlatform: platform}
7551
}
7652

77-
// IsRelevant implements the golang-shared plugins.PluginPredicate
53+
// IsRelevant implements the golang-shared types.PluginPredicate
7854
// interface and only returns true when the current platform is supported.
7955
func (pf *PlatformFilter) IsRelevant(pc plugins.PluginConstructor, metadata ...any) bool {
8056
for _, i := range metadata {
@@ -89,9 +65,10 @@ func (pf *PlatformFilter) IsRelevant(pc plugins.PluginConstructor, metadata ...a
8965
spec.Excludes))
9066

9167
}
92-
if len(spec.OnlyOn) > 0 && !slices.Contains(spec.OnlyOn, pf.currentPlatform) {
68+
platformMatch := func(p types.Platform) bool { return p.Equals(pf.currentPlatform) }
69+
if len(spec.OnlyOn) > 0 && !slices.ContainsFunc(spec.OnlyOn, platformMatch) {
9370
return false
94-
} else if len(spec.Excludes) > 0 && slices.Contains(spec.Excludes, pf.currentPlatform) {
71+
} else if len(spec.Excludes) > 0 && slices.ContainsFunc(spec.Excludes, platformMatch) {
9572
return false
9673
}
9774
}

plugins/platformdetect/platform_detector_test.go

Lines changed: 21 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"testing/fstest"
77

88
"github.com/untangle/golang-shared/plugins"
9+
"github.com/untangle/golang-shared/plugins/types"
910
)
1011

1112
func TestPlatformFilter(t *testing.T) {
@@ -14,64 +15,64 @@ func TestPlatformFilter(t *testing.T) {
1415
files []string
1516
metadata []any
1617
expected bool
17-
currentPlatform HostType
18+
currentPlatform types.Platform
1819
}{
1920
{
2021
name: "EOS platform, no metadata",
21-
files: []string{EOS.indicatorFilename},
22+
files: []string{types.EOS.IndicatorFilename},
2223
metadata: nil,
2324
expected: true,
24-
currentPlatform: EOS,
25+
currentPlatform: types.EOS,
2526
},
2627
{
2728
name: "OpenWrt platform, no metadata",
28-
files: []string{OpenWrt.indicatorFilename},
29+
files: []string{types.OpenWrt.IndicatorFilename},
2930
metadata: nil,
3031
expected: true,
31-
currentPlatform: OpenWrt,
32+
currentPlatform: types.OpenWrt,
3233
},
3334
{
3435
name: "Unclassified platform, no metadata",
3536
files: []string{},
3637
metadata: nil,
3738
expected: true,
38-
currentPlatform: Unclassified,
39+
currentPlatform: types.Unclassified,
3940
},
4041
{
4142
name: "EOS platform, only on EOS",
42-
files: []string{EOS.indicatorFilename},
43+
files: []string{types.EOS.IndicatorFilename},
4344
metadata: []any{PlatformSpec{
44-
OnlyOn: []HostType{EOS},
45+
OnlyOn: []types.Platform{types.EOS},
4546
}},
4647
expected: true,
47-
currentPlatform: EOS,
48+
currentPlatform: types.EOS,
4849
},
4950
{
5051
name: "EOS platform, only on OpenWrt",
51-
files: []string{EOS.indicatorFilename},
52+
files: []string{types.EOS.IndicatorFilename},
5253
metadata: []any{PlatformSpec{
53-
OnlyOn: []HostType{OpenWrt},
54+
OnlyOn: []types.Platform{types.OpenWrt},
5455
}},
5556
expected: false,
56-
currentPlatform: EOS,
57+
currentPlatform: types.EOS,
5758
},
5859
{
5960
name: "OpenWrt platform, excludes OpenWrt",
60-
files: []string{OpenWrt.indicatorFilename},
61+
files: []string{types.OpenWrt.IndicatorFilename},
6162
metadata: []any{PlatformSpec{
62-
Excludes: []HostType{OpenWrt},
63+
Excludes: []types.Platform{types.OpenWrt},
6364
}},
6465
expected: false,
65-
currentPlatform: OpenWrt,
66+
currentPlatform: types.OpenWrt,
6667
},
6768
{
6869
name: "No platform match",
6970
files: []string{"/etc/something_else"},
7071
metadata: []any{PlatformSpec{
71-
OnlyOn: []HostType{OpenWrt},
72+
OnlyOn: []types.Platform{types.OpenWrt},
7273
}},
7374
expected: false,
74-
currentPlatform: Unclassified,
75+
currentPlatform: types.Unclassified,
7576
},
7677
}
7778

@@ -87,11 +88,11 @@ func TestPlatformFilter(t *testing.T) {
8788
fs[f[1:]] = &fstest.MapFile{}
8889
}
8990

90-
filter := NewPlatformFilter(fs)
91+
filter := NewPlatformFilter(GetCurrentPlatform(fs))
9192

92-
if filter.currentPlatform != tt.currentPlatform {
93+
if filter.currentPlatform.Name != tt.currentPlatform.Name {
9394
t.Errorf("Incorrect platform detected. Expected %s, got %s",
94-
tt.currentPlatform.name, filter.currentPlatform.name)
95+
tt.currentPlatform.Name, filter.currentPlatform.Name)
9596
}
9697

9798
var pc plugins.PluginConstructor

plugins/types/platform.go

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
package types
2+
3+
// HostType is a externally-opaque type for declaring a host
4+
// type.
5+
type Platform struct {
6+
IndicatorFilename string
7+
Name string
8+
9+
// Path settings files should be looked up in
10+
SettingsDirPath string
11+
12+
// Files that have a unique mapping on the platform.
13+
// The mapping goes from the openWRT equivalent file
14+
// to it's platform specific file location.
15+
AdditionalFileMappings map[string]string
16+
}
17+
18+
// Equals checks if two platforms are equal. Simply
19+
// compares their names
20+
func (p *Platform) Equals(other Platform) bool {
21+
return p.Name == other.Name
22+
}
23+
24+
var (
25+
EOS = Platform{
26+
IndicatorFilename: "/etc/Eos-release",
27+
Name: "Eos",
28+
SettingsDirPath: "/mnt/flash/mfw-settings",
29+
AdditionalFileMappings: map[string]string{
30+
"/etc/config/categories.json": "/usr/share/bctid/categories.json",
31+
},
32+
}
33+
OpenWrt = Platform{
34+
IndicatorFilename: "/etc/openwrt_version",
35+
Name: "OpenWrt",
36+
SettingsDirPath: "/etc/config",
37+
}
38+
Vittoria = Platform{
39+
IndicatorFilename: "/notknown/",
40+
Name: "Unclassified",
41+
SettingsDirPath: "/velocloud/",
42+
}
43+
Unclassified = Platform{
44+
IndicatorFilename: "",
45+
Name: "Unclassified",
46+
SettingsDirPath: "",
47+
}
48+
49+
Platforms = []Platform{
50+
EOS,
51+
OpenWrt,
52+
Vittoria,
53+
Unclassified,
54+
}
55+
)
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
[{"name":"untangle-node-sitefilter","allowedState":0},{"name":"untangle-node-classd","allowedState":1},{"name":"untangle-node-dynamic-lists","allowedState":0},{"name":"untangle-node-dns-filter","allowedState":0},{"name":"untangle-node-dos-filter","allowedState":0},{"name":"untangle-node-threat-prevention","allowedState":1},{"name":"untangle-node-geoip","allowedState":0},{"name":"untangle-node-captiveportal","allowedState":0},{"name":"untangle-node-discovery","allowedState":0}]
1+
[{"name":"untangle-node-geoip","allowedState":0},{"name":"untangle-node-classd","allowedState":1},{"name":"untangle-node-dos-filter","allowedState":0},{"name":"untangle-node-threat-prevention","allowedState":1},{"name":"untangle-node-dynamic-lists","allowedState":0},{"name":"untangle-node-sitefilter","allowedState":0},{"name":"untangle-node-captiveportal","allowedState":0},{"name":"untangle-node-discovery","allowedState":0},{"name":"untangle-node-dns-filter","allowedState":0}]

services/settings/filesystem.go

Lines changed: 29 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -4,29 +4,24 @@ import (
44
"fmt"
55
"io/fs"
66
"os"
7+
"path/filepath"
78
"strings"
9+
10+
"github.com/untangle/golang-shared/plugins/types"
811
)
912

1013
// FilenameLocator finds files on the local filesystem, allowing the
1114
// system to be EOS or OpenWrt mode and concealing the
1215
// differences.
1316
type FilenameLocator struct {
1417
fileExists func(filename string) bool
18+
platform types.Platform
1519
}
1620

17-
const (
18-
// Present of file indicates we are in native mode
19-
nativeEOSIndicatorFile = "/etc/efw-version"
20-
21-
// Standard prefix for native EOS
22-
nativeEOSPrefix = "/mnt/flash/mfw-settings/"
23-
24-
// Standard prefix for OpenWRT
25-
openWRTPrefix = "/etc/config/"
26-
)
27-
28-
var openWRTFileToNativeEOS = map[string]string{
29-
"/etc/config/categories.json": "/usr/share/bctid/categories.json",
21+
func NewFilenameLocator(platform types.Platform) *FilenameLocator {
22+
return &FilenameLocator{
23+
fileExists: FileExists,
24+
}
3025
}
3126

3227
// NoFileAtPath is an error for if a file doesn't exist. In this case
@@ -83,39 +78,36 @@ func FileExistsInFS(fname string, fs fs.StatFS) bool {
8378
// it assumes that called uses default to OpenWRT platform. Only paths in mappings or paths which
8479
// starts with /etc/config are translated.
8580
func (f *FilenameLocator) getPlatformFileName(filename string) (string, error) { // Check if we are in native mode, most likely since there is only native and OpenWRT mode
86-
if f.fileExists(nativeEOSIndicatorFile) { // In EOS mode, try mapping
87-
if nativePath, exists := openWRTFileToNativeEOS[filename]; exists {
88-
if !f.fileExists(nativePath) {
89-
return nativePath, &NoFileAtPath{name: nativePath}
90-
} else {
91-
return nativePath, nil
92-
}
93-
// Still on EOS, if file contains /etc/config then translate, otherwise return
94-
} else if strings.Contains(filename, openWRTPrefix) {
95-
nativePath := nativeEOSPrefix + filename[strings.LastIndex(filename, "/")+1:]
96-
97-
if !f.fileExists(nativePath) {
98-
return nativePath, &NoFileAtPath{name: nativePath}
99-
} else {
100-
return nativePath, nil
101-
}
102-
}
81+
// File lookups are mapped from the OpenWRT filenames. No additional translation needed.
82+
fmt.Printf("\n wat \n")
83+
if f.platform.Equals(types.OpenWrt) {
84+
return filename, nil
10385
}
104-
// On OpenWRT or no translation needed
105-
if !f.fileExists(filename) {
106-
return filename, &NoFileAtPath{name: filename}
86+
87+
if nativePath, ok := f.platform.AdditionalFileMappings[filename]; ok {
88+
fmt.Printf("\nadditional mappings\n")
89+
if !f.fileExists(nativePath) {
90+
return nativePath, &NoFileAtPath{name: nativePath}
91+
} else {
92+
return nativePath, nil
93+
}
94+
} else if strings.Contains(filename, types.OpenWrt.SettingsDirPath) {
95+
nativePath := filepath.Join(f.platform.SettingsDirPath, filename[strings.LastIndex(filename, "/")+1:])
96+
97+
if !f.fileExists(nativePath) {
98+
return nativePath, &NoFileAtPath{name: nativePath}
99+
} else {
100+
return nativePath, nil
101+
}
107102
}
103+
108104
return filename, nil
109105
}
110106

111107
// LocateFile locates the input filename on the filesystem,
112108
// automatically translating it to EOS filenames when needed.
113109
func (f *FilenameLocator) LocateFile(filename string) (string, error) {
114-
if f.fileExists(filename) {
115-
return filename, nil
116-
}
117110
return f.getPlatformFileName(filename)
118-
119111
}
120112

121113
var defaultLocator = &FilenameLocator{

0 commit comments

Comments
 (0)