From f55fb4055f6523996000353cf82dae9b741af353 Mon Sep 17 00:00:00 2001 From: Quentin McGaw Date: Tue, 29 Dec 2020 01:16:53 +0000 Subject: [PATCH] Code maintenance: OS user abstraction interface --- cmd/gluetun/main.go | 8 ++-- internal/alpine/alpine.go | 15 +++---- internal/alpine/users.go | 4 +- internal/os/user/alias.go | 7 ++++ internal/os/user/mock_user/user.go | 64 ++++++++++++++++++++++++++++++ internal/os/user/user.go | 24 +++++++++++ 6 files changed, 108 insertions(+), 14 deletions(-) create mode 100644 internal/os/user/alias.go create mode 100644 internal/os/user/mock_user/user.go create mode 100644 internal/os/user/user.go diff --git a/cmd/gluetun/main.go b/cmd/gluetun/main.go index 414da442..df559712 100644 --- a/cmd/gluetun/main.go +++ b/cmd/gluetun/main.go @@ -23,6 +23,7 @@ import ( "github.com/qdm12/gluetun/internal/models" "github.com/qdm12/gluetun/internal/openvpn" "github.com/qdm12/gluetun/internal/os" + "github.com/qdm12/gluetun/internal/os/user" "github.com/qdm12/gluetun/internal/params" "github.com/qdm12/gluetun/internal/publicip" "github.com/qdm12/gluetun/internal/routing" @@ -53,11 +54,12 @@ func main() { ctx := context.Background() args := nativeos.Args os := os.New() - nativeos.Exit(_main(ctx, args, os)) + osUser := user.New() + nativeos.Exit(_main(ctx, args, os, osUser)) } //nolint:gocognit,gocyclo -func _main(background context.Context, args []string, os os.OS) int { +func _main(background context.Context, args []string, os os.OS, osUser user.OSUser) int { if len(args) > 1 { // cli operation var err error switch args[1] { @@ -86,7 +88,7 @@ func _main(background context.Context, args []string, os os.OS) int { httpClient := &http.Client{Timeout: clientTimeout} client := network.NewClient(clientTimeout) // Create configurators - alpineConf := alpine.NewConfigurator(os.OpenFile) + alpineConf := alpine.NewConfigurator(os.OpenFile, osUser) unix := unix.New() ovpnConf := openvpn.NewConfigurator(logger, os, unix) dnsConf := dns.NewConfigurator(logger, client, os.OpenFile) diff --git a/internal/alpine/alpine.go b/internal/alpine/alpine.go index d3b2a7ae..1c420086 100644 --- a/internal/alpine/alpine.go +++ b/internal/alpine/alpine.go @@ -1,9 +1,8 @@ package alpine import ( - "os/user" - "github.com/qdm12/gluetun/internal/os" + "github.com/qdm12/gluetun/internal/os/user" ) type Configurator interface { @@ -11,15 +10,13 @@ type Configurator interface { } type configurator struct { - openFile os.OpenFileFunc - lookupUID func(uid string) (*user.User, error) - lookupUser func(username string) (*user.User, error) + openFile os.OpenFileFunc + osUser user.OSUser } -func NewConfigurator(openFile os.OpenFileFunc) Configurator { +func NewConfigurator(openFile os.OpenFileFunc, osUser user.OSUser) Configurator { return &configurator{ - openFile: openFile, - lookupUID: user.LookupId, - lookupUser: user.Lookup, + openFile: openFile, + osUser: osUser, } } diff --git a/internal/alpine/users.go b/internal/alpine/users.go index d997bc7f..915e2c2c 100644 --- a/internal/alpine/users.go +++ b/internal/alpine/users.go @@ -9,7 +9,7 @@ import ( // CreateUser creates a user in Alpine with the given UID. func (c *configurator) CreateUser(username string, uid int) (createdUsername string, err error) { UIDStr := fmt.Sprintf("%d", uid) - u, err := c.lookupUID(UIDStr) + u, err := c.osUser.LookupID(UIDStr) _, unknownUID := err.(user.UnknownUserIdError) if err != nil && !unknownUID { return "", fmt.Errorf("cannot create user: %w", err) @@ -19,7 +19,7 @@ func (c *configurator) CreateUser(username string, uid int) (createdUsername str } return u.Username, nil } - u, err = c.lookupUser(username) + u, err = c.osUser.Lookup(username) _, unknownUsername := err.(user.UnknownUserError) if err != nil && !unknownUsername { return "", fmt.Errorf("cannot create user: %w", err) diff --git a/internal/os/user/alias.go b/internal/os/user/alias.go new file mode 100644 index 00000000..043aa13c --- /dev/null +++ b/internal/os/user/alias.go @@ -0,0 +1,7 @@ +package user + +import osuser "os/user" + +// Aliases used for convenience so "os/user" does not have to be imported + +type User osuser.User diff --git a/internal/os/user/mock_user/user.go b/internal/os/user/mock_user/user.go new file mode 100644 index 00000000..f26a446a --- /dev/null +++ b/internal/os/user/mock_user/user.go @@ -0,0 +1,64 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: github.com/qdm12/gluetun/internal/os/user (interfaces: OSUser) + +// Package mock_user is a generated GoMock package. +package mock_user + +import ( + gomock "github.com/golang/mock/gomock" + user "os/user" + reflect "reflect" +) + +// MockOSUser is a mock of OSUser interface +type MockOSUser struct { + ctrl *gomock.Controller + recorder *MockOSUserMockRecorder +} + +// MockOSUserMockRecorder is the mock recorder for MockOSUser +type MockOSUserMockRecorder struct { + mock *MockOSUser +} + +// NewMockOSUser creates a new mock instance +func NewMockOSUser(ctrl *gomock.Controller) *MockOSUser { + mock := &MockOSUser{ctrl: ctrl} + mock.recorder = &MockOSUserMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use +func (m *MockOSUser) EXPECT() *MockOSUserMockRecorder { + return m.recorder +} + +// Lookup mocks base method +func (m *MockOSUser) Lookup(arg0 string) (*user.User, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Lookup", arg0) + ret0, _ := ret[0].(*user.User) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Lookup indicates an expected call of Lookup +func (mr *MockOSUserMockRecorder) Lookup(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Lookup", reflect.TypeOf((*MockOSUser)(nil).Lookup), arg0) +} + +// LookupID mocks base method +func (m *MockOSUser) LookupID(arg0 string) (*user.User, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "LookupID", arg0) + ret0, _ := ret[0].(*user.User) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// LookupID indicates an expected call of LookupID +func (mr *MockOSUserMockRecorder) LookupID(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LookupID", reflect.TypeOf((*MockOSUser)(nil).LookupID), arg0) +} diff --git a/internal/os/user/user.go b/internal/os/user/user.go new file mode 100644 index 00000000..d2b2308c --- /dev/null +++ b/internal/os/user/user.go @@ -0,0 +1,24 @@ +package user + +import osuser "os/user" + +//go:generate mockgen -destination=mock_$GOPACKAGE/$GOFILE . OSUser + +type OSUser interface { + LookupID(uid string) (*osuser.User, error) + Lookup(username string) (*osuser.User, error) +} + +func New() OSUser { + return &osUser{} +} + +type osUser struct{} + +func (u *osUser) LookupID(uid string) (*osuser.User, error) { + return osuser.LookupId(uid) +} + +func (u *osUser) Lookup(username string) (*osuser.User, error) { + return osuser.Lookup(username) +}