-
Notifications
You must be signed in to change notification settings - Fork 31
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feature/userdel diffs #584
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -131,19 +131,10 @@ func NewUser(system SystemUtils) *User { | |
|
||
// Check if a user user exists | ||
func (u *User) Check(context.Context, resource.Renderer) (resource.TaskStatus, error) { | ||
var ( | ||
userByID *user.User | ||
uidErr error | ||
) | ||
|
||
// lookup the user by name and lookup the user by uid | ||
// the lookups return ErrUnsupported if the system is not supported | ||
// lookup the user by name | ||
// ErrUnsupported is returned if the system is not supported | ||
// Lookup returns user.UnknownUserError if the user is not found | ||
// LookupID returns user.UnknownUserIdError if the uid is not found | ||
userByName, nameErr := u.system.Lookup(u.Username) | ||
if u.UID != "" { | ||
userByID, uidErr = u.system.LookupID(u.UID) | ||
} | ||
|
||
status := resource.NewStatus() | ||
|
||
|
@@ -152,10 +143,10 @@ func (u *User) Check(context.Context, resource.Renderer) (resource.TaskStatus, e | |
return status, ErrUnsupported | ||
} | ||
|
||
_, nameNotFound := nameErr.(user.UnknownUserError) | ||
|
||
switch u.State { | ||
case StatePresent: | ||
_, nameNotFound := nameErr.(user.UnknownUserError) | ||
|
||
switch { | ||
case nameNotFound: | ||
_, err := u.DiffAdd(status) | ||
|
@@ -175,37 +166,12 @@ func (u *User) Check(context.Context, resource.Renderer) (resource.TaskStatus, e | |
} | ||
} | ||
case StateAbsent: | ||
switch { | ||
case u.UID == "": | ||
_, nameNotFound := nameErr.(user.UnknownUserError) | ||
|
||
switch { | ||
case nameNotFound: | ||
status.AddMessage(fmt.Sprintf("user %s does not exist", u.Username)) | ||
case userByName != nil: | ||
status.RaiseLevel(resource.StatusWillChange) | ||
status.AddDifference("user", fmt.Sprintf("user %s", u.Username), fmt.Sprintf("<%s>", string(StateAbsent)), "") | ||
} | ||
case u.UID != "": | ||
_, nameNotFound := nameErr.(user.UnknownUserError) | ||
_, uidNotFound := uidErr.(user.UnknownUserIdError) | ||
|
||
switch { | ||
case nameNotFound && uidNotFound: | ||
status.AddMessage(fmt.Sprintf("user %s and uid %s do not exist", u.Username, u.UID)) | ||
case nameNotFound: | ||
status.RaiseLevel(resource.StatusCantChange) | ||
return status, fmt.Errorf("cannot delete user %s with uid %s: user does not exist", u.Username, u.UID) | ||
case uidNotFound: | ||
status.RaiseLevel(resource.StatusCantChange) | ||
return status, fmt.Errorf("cannot delete user %s with uid %s: uid does not exist", u.Username, u.UID) | ||
case userByName != nil && userByID != nil && userByName.Name != userByID.Name || userByName.Uid != userByID.Uid: | ||
status.RaiseLevel(resource.StatusCantChange) | ||
return status, fmt.Errorf("cannot delete user %s with uid %s: user and uid belong to different users", u.Username, u.UID) | ||
case userByName != nil && userByID != nil && *userByName == *userByID: | ||
status.RaiseLevel(resource.StatusWillChange) | ||
status.AddDifference("user", fmt.Sprintf("user %s with uid %s", u.Username, u.UID), fmt.Sprintf("<%s>", string(StateAbsent)), "") | ||
} | ||
err := u.DiffDel(status, userByName, nameNotFound) | ||
if err != nil { | ||
return status, errors.Wrapf(err, "cannot delete user %s", u.Username) | ||
} | ||
if resource.AnyChanges(status.Differences) { | ||
status.AddMessage("delete user") | ||
} | ||
default: | ||
status.RaiseLevel(resource.StatusFatal) | ||
|
@@ -217,19 +183,10 @@ func (u *User) Check(context.Context, resource.Renderer) (resource.TaskStatus, e | |
|
||
// Apply changes for user | ||
func (u *User) Apply(context.Context) (resource.TaskStatus, error) { | ||
var ( | ||
userByID *user.User | ||
uidErr error | ||
) | ||
|
||
// lookup the user by name and lookup the user by uid | ||
// the lookups return ErrUnsupported if the system is not supported | ||
// lookup the user by name | ||
// ErrUnsupported is returned if the system is not supported | ||
// Lookup returns user.UnknownUserError if the user is not found | ||
// LookupID returns user.UnknownUserIdError if the uid is not found | ||
userByName, nameErr := u.system.Lookup(u.Username) | ||
if u.UID != "" { | ||
userByID, uidErr = u.system.LookupID(u.UID) | ||
} | ||
|
||
status := resource.NewStatus() | ||
|
||
|
@@ -238,10 +195,10 @@ func (u *User) Apply(context.Context) (resource.TaskStatus, error) { | |
return status, ErrUnsupported | ||
} | ||
|
||
_, nameNotFound := nameErr.(user.UnknownUserError) | ||
|
||
switch u.State { | ||
case StatePresent: | ||
_, nameNotFound := nameErr.(user.UnknownUserError) | ||
|
||
switch { | ||
case nameNotFound: | ||
options, err := u.DiffAdd(status) | ||
|
@@ -273,40 +230,18 @@ func (u *User) Apply(context.Context) (resource.TaskStatus, error) { | |
} | ||
} | ||
case StateAbsent: | ||
switch { | ||
case u.UID == "": | ||
_, nameNotFound := nameErr.(user.UnknownUserError) | ||
|
||
switch { | ||
case !nameNotFound && userByName != nil: | ||
err := u.system.DelUser(u.Username) | ||
if err != nil { | ||
status.RaiseLevel(resource.StatusFatal) | ||
status.AddMessage(fmt.Sprintf("error deleting user %s", u.Username)) | ||
return status, errors.Wrap(err, "user delete") | ||
} | ||
status.AddMessage(fmt.Sprintf("deleted user %s", u.Username)) | ||
default: | ||
status.RaiseLevel(resource.StatusCantChange) | ||
return status, fmt.Errorf("will not attempt to delete user %s", u.Username) | ||
} | ||
case u.UID != "": | ||
_, nameNotFound := nameErr.(user.UnknownUserError) | ||
_, uidNotFound := uidErr.(user.UnknownUserIdError) | ||
|
||
switch { | ||
case !nameNotFound && !uidNotFound && userByName != nil && userByID != nil && *userByName == *userByID: | ||
err := u.system.DelUser(u.Username) | ||
if err != nil { | ||
status.RaiseLevel(resource.StatusFatal) | ||
status.AddMessage(fmt.Sprintf("error deleting user %s with uid %s", u.Username, u.UID)) | ||
return status, errors.Wrap(err, "user delete") | ||
} | ||
status.AddMessage(fmt.Sprintf("deleted user %s with uid %s", u.Username, u.UID)) | ||
default: | ||
status.RaiseLevel(resource.StatusCantChange) | ||
return status, fmt.Errorf("will not attempt to delete user %s with uid %s", u.Username, u.UID) | ||
err := u.DiffDel(status, userByName, nameNotFound) | ||
if err != nil { | ||
return status, errors.Wrapf(err, "will not attempt to delete user %s", u.Username) | ||
} | ||
if resource.AnyChanges(status.Differences) { | ||
err = u.system.DelUser(u.Username) | ||
if err != nil { | ||
status.RaiseLevel(resource.StatusFatal) | ||
status.AddMessage(fmt.Sprintf("error deleting user %s", u.Username)) | ||
return status, errors.Wrap(err, "user delete") | ||
} | ||
status.AddMessage(fmt.Sprintf("deleted user %s", u.Username)) | ||
} | ||
default: | ||
status.RaiseLevel(resource.StatusFatal) | ||
|
@@ -401,6 +336,39 @@ func (u *User) DiffAdd(status *resource.Status) (*AddUserOptions, error) { | |
return options, nil | ||
} | ||
|
||
// DiffDel checks for differences between the current and desired state for the | ||
// user to be deleted indicated by the User fields. | ||
func (u *User) DiffDel(status *resource.Status, userByName *user.User, nameNotFound bool) error { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nitpick: should this be public? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It makes sense to be private, but is public for testing purposes. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. IMO it would be better to make the tests part of the package than it would be to expose extra members. But it's definitely not a blocker. :) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. After some discussion, we've concluded to leave as is for There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🤘 ticket? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Opened #585 |
||
if nameNotFound || userByName == nil { | ||
return nil | ||
} | ||
|
||
switch { | ||
case u.UID == "": | ||
status.AddDifference("user", u.Username, fmt.Sprintf("<%s>", string(StateAbsent)), "") | ||
case u.UID != "": | ||
userByID, err := user.LookupId(u.UID) | ||
_, uidNotFound := err.(user.UnknownUserIdError) | ||
|
||
switch { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nitpick: this There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I thought you liked switch better. ;) I will change it back to |
||
case uidNotFound: | ||
status.RaiseLevel(resource.StatusCantChange) | ||
return fmt.Errorf("uid %s does not exist", u.UID) | ||
case userByID != nil && *userByID != *userByName: | ||
status.RaiseLevel(resource.StatusCantChange) | ||
return fmt.Errorf("uid %s belongs to different user", u.UID) | ||
case userByID != nil && *userByID == *userByName: | ||
status.AddDifference("user", u.Username, fmt.Sprintf("<%s>", string(StateAbsent)), "") | ||
} | ||
} | ||
|
||
if resource.AnyChanges(status.Differences) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. possible enhancement: why isn't this a method on |
||
status.RaiseLevel(resource.StatusWillChange) | ||
} | ||
|
||
return nil | ||
} | ||
|
||
// DiffMod checks for differences between the user associated with u.Username | ||
// and the desired modifications of that user indicated by the other User | ||
// fields. The options to be used for the modify command are set. | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why couldn't apply use the status that you've created already, again? I feel like we had this discussion, but a) I don't remember and b) has the answer changed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't believe we can since we no longer keep
status
as a field of the task struct.