resources: Move FileRes.uid()/.gid() to util.go

This commit is contained in:
Guillaume Herail
2017-11-21 14:44:12 +01:00
committed by James Shubin
parent 52fd1ae73e
commit bfc2549289
5 changed files with 118 additions and 107 deletions

View File

@@ -26,7 +26,6 @@ import (
"io/ioutil" "io/ioutil"
"log" "log"
"os" "os"
"os/user"
"path" "path"
"path/filepath" "path/filepath"
"strconv" "strconv"
@@ -97,11 +96,11 @@ func (obj *FileRes) Validate() error {
} }
} }
if _, err := obj.uid(); obj.Owner != "" && err != nil { if _, err := GetUID(obj.Owner); obj.Owner != "" && err != nil {
return err return err
} }
if _, err := obj.gid(); obj.Group != "" && err != nil { if _, err := GetGID(obj.Group); obj.Group != "" && err != nil {
return err return err
} }
@@ -124,22 +123,6 @@ func (obj *FileRes) mode() (os.FileMode, error) {
return os.FileMode(m), nil return os.FileMode(m), nil
} }
// uid returns the user id for the owner specified in the yaml file graph.
// Caller should first check obj.Owner is not empty
func (obj *FileRes) uid() (int, error) {
u2, err2 := user.LookupId(obj.Owner)
if err2 == nil {
return strconv.Atoi(u2.Uid)
}
u, err := user.Lookup(obj.Owner)
if err == nil {
return strconv.Atoi(u.Uid)
}
return -1, errwrap.Wrapf(err, "owner lookup error (%s)", obj.Owner)
}
// Init runs some startup code for this resource. // Init runs some startup code for this resource.
func (obj *FileRes) Init() error { func (obj *FileRes) Init() error {
obj.sha256sum = "" obj.sha256sum = ""
@@ -767,7 +750,7 @@ func (obj *FileRes) chownCheckApply(apply bool) (checkOK bool, _ error) {
} }
if obj.Owner != "" { if obj.Owner != "" {
expectedUID, err = obj.uid() expectedUID, err = GetUID(obj.Owner)
if err != nil { if err != nil {
return false, err return false, err
} }
@@ -777,7 +760,7 @@ func (obj *FileRes) chownCheckApply(apply bool) (checkOK bool, _ error) {
} }
if obj.Group != "" { if obj.Group != "" {
expectedGID, err = obj.gid() expectedGID, err = GetGID(obj.Group)
if err != nil { if err != nil {
return false, err return false, err
} }

View File

@@ -1,43 +0,0 @@
// Mgmt
// Copyright (C) 2013-2017+ James Shubin and the project contributors
// Written by James Shubin <james@shubin.ca> and the project contributors
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
// +build go1.7
package resources
import (
"os/user"
"strconv"
errwrap "github.com/pkg/errors"
)
// gid returns the group id for the group specified in the yaml file graph.
// Caller should first check obj.Group is not empty
func (obj *FileRes) gid() (int, error) {
g2, err2 := user.LookupGroupId(obj.Group)
if err2 == nil {
return strconv.Atoi(g2.Gid)
}
g, err := user.LookupGroup(obj.Group)
if err == nil {
return strconv.Atoi(g.Gid)
}
return -1, errwrap.Wrapf(err, "Group lookup error (%s)", obj.Group)
}

View File

@@ -1,43 +0,0 @@
// Mgmt
// Copyright (C) 2013-2017+ James Shubin and the project contributors
// Written by James Shubin <james@shubin.ca> and the project contributors
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
// +build !go1.7
package resources
import (
"strconv"
group "github.com/hnakamur/group"
errwrap "github.com/pkg/errors"
)
// gid returns the group id for the group specified in the yaml file graph.
// Caller should first check obj.Group is not empty
func (obj *FileRes) gid() (int, error) {
g2, err2 := group.LookupId(obj.Group)
if err2 == nil {
return strconv.Atoi(g2.Gid)
}
g, err := group.Lookup(obj.Group)
if err == nil {
return strconv.Atoi(g.Gid)
}
return -1, errwrap.Wrapf(err, "Group lookup error (%s)", obj.Group)
}

View File

@@ -22,8 +22,10 @@ import (
"encoding/base64" "encoding/base64"
"encoding/gob" "encoding/gob"
"fmt" "fmt"
"os/user"
"reflect" "reflect"
"sort" "sort"
"strconv"
"strings" "strings"
errwrap "github.com/pkg/errors" errwrap "github.com/pkg/errors"
@@ -133,3 +135,37 @@ func LowerStructFieldNameToFieldName(res Res) (map[string]string, error) {
} }
return result, nil return result, nil
} }
// GetUID returns the UID of an user. It supports an UID or an username. Caller
// should first check user is not empty. It will return an error if it can't
// lookup the UID or username.
func GetUID(username string) (int, error) {
userObj, err := user.LookupId(username)
if err == nil {
return strconv.Atoi(userObj.Uid)
}
userObj, err = user.Lookup(username)
if err == nil {
return strconv.Atoi(userObj.Gid)
}
return -1, errwrap.Wrapf(err, "user lookup error (%s)", username)
}
// GetGID returns the GID of a group. It supports a GID or a group name. Caller
// should first check group is not empty. It will return an error if it can't
// lookup the GID or group name.
func GetGID(group string) (int, error) {
groupObj, err := user.LookupGroupId(group)
if err == nil {
return strconv.Atoi(groupObj.Gid)
}
groupObj, err = user.LookupGroup(group)
if err == nil {
return strconv.Atoi(groupObj.Gid)
}
return -1, errwrap.Wrapf(err, "group lookup error (%s)", group)
}

View File

@@ -21,7 +21,9 @@ import (
"bytes" "bytes"
"encoding/base64" "encoding/base64"
"encoding/gob" "encoding/gob"
"os/user"
"reflect" "reflect"
"strconv"
"testing" "testing"
) )
@@ -236,3 +238,79 @@ func TestLowerStructFieldNameToFieldName1(t *testing.T) {
return return
} }
} }
func TestUnknownGroup(t *testing.T) {
gid, err := GetGID("unknowngroup")
if err == nil {
t.Errorf("expected failure, but passed with: %d", gid)
}
}
func TestUnknownUser(t *testing.T) {
uid, err := GetUID("unknownuser")
if err == nil {
t.Errorf("expected failure, but passed with: %d", uid)
}
}
func TestCurrentUserGroupByName(t *testing.T) {
// get current user
userObj, err := user.Current()
if err != nil {
t.Errorf("error trying to lookup current user: %s", err.Error())
}
currentUID := userObj.Uid
currentGID := userObj.Gid
var uid int
var gid int
// now try to get the uid/gid via our API (via username and group name)
if uid, err = GetUID(userObj.Username); err != nil {
t.Errorf("error trying to lookup current user UID: %s", err.Error())
}
if strconv.Itoa(uid) != currentUID {
t.Errorf("uid didn't match current user's: %s vs %s", strconv.Itoa(uid), currentUID)
}
if gid, err = GetGID(userObj.Username); err != nil {
t.Errorf("error trying to lookup current user UID: %s", err.Error())
}
if strconv.Itoa(gid) != currentGID {
t.Errorf("gid didn't match current user's: %s vs %s", strconv.Itoa(gid), currentGID)
}
}
func TestCurrentUserGroupById(t *testing.T) {
// get current user
userObj, err := user.Current()
if err != nil {
t.Errorf("error trying to lookup current user: %s", err.Error())
}
currentUID := userObj.Uid
currentGID := userObj.Gid
var uid int
var gid int
// now try to get the uid/gid via our API (via uid and gid)
if uid, err = GetUID(currentUID); err != nil {
t.Errorf("error trying to lookup current user UID: %s", err.Error())
}
if strconv.Itoa(uid) != currentUID {
t.Errorf("uid didn't match current user's: %s vs %s", strconv.Itoa(uid), currentUID)
}
if gid, err = GetGID(currentGID); err != nil {
t.Errorf("error trying to lookup current user UID: %s", err.Error())
}
if strconv.Itoa(gid) != currentGID {
t.Errorf("gid didn't match current user's: %s vs %s", strconv.Itoa(gid), currentGID)
}
}