-
Notifications
You must be signed in to change notification settings - Fork 36
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
Subdomain User Operations #76
Conversation
Skipping CI for Draft Pull Request. |
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.
Would it be possible to create an e2e test for this scenario? It seems fairly complex so I'd feel more comfortable if we were validating that the users are handled correctly
pkg/cloud/user_credentials.go
Outdated
// GetOrCreateUserWithKeys will search a domain and account for the first user that has api keys. | ||
// Creates a CAPC user if no such user is found. | ||
func (c *client) GetOrCreateUserWithKeys(user *User) error { | ||
return nil | ||
} |
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.
can we remove these no-op and unused functions?
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.
Well, this is a draft PR, so yes I'll remove them. : )
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.
BTW, I do eventually want methods like this in the codebase to be able to create domains/accounts/users on the fly in testing.
But since we will probably never do that in production, I'll probably put them in the test suite itself.
controllers/utils/base_reconciler.go
Outdated
r.CSCluster.Spec.Account, r.CSCluster.Spec.Domain) | ||
} | ||
cfg := cloud.Config{APIKey: user.APIKey, SecretKey: user.SecretKey} | ||
if client, err := r.CSClient.NewClientFromSpec(cfg); err != nil { |
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.
if client, err := r.CSClient.NewClientFromSpec(cfg); err != nil { | |
if r.CSUser, err := r.CSClient.NewClientFromSpec(cfg); err != nil { |
Can we remove the else statement with this?
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.
Not without a more verbose variable declaration to bring both vars into scope. : )
if err != nil && strings.Contains(strings.ToLower(err.Error()), "i/o timeout") { | ||
return newC, errors.Wrap(err, "timeout while checking CloudStack API Client connectivity") | ||
} | ||
return newC, errors.Wrap(err, "checking CloudStack API Client connectivity:") |
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.
Looks like this function always returns an error. When should it return nil for error?
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.
It doesn't. errors.Wrap
will return nil if the passed err is nil.
|
||
// GetUserWithKeys will search a domain and account for the first user that has api keys. | ||
// Returns true if a user is found and false otherwise. | ||
func (c *client) GetUserWithKeys(user *User) (bool, error) { |
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.
How does this function work differently from calling ResolveUserKeys directly?
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.
Well, ResolveUserKeys works if a user is already specified--for example you've already got a user's name or ID.
In all of our current cases we don't know of any sub-domain users until we run. As the method comment mentions, this will look at all users in a domain and resolve the passed user pointer to the first user that has sufficient API keys.
pkg/cloud/user_credentials.go
Outdated
|
||
// CreateUserWithKeys will create a CloudStack user in the specified domain and account and generate API keyes for | ||
// said user. | ||
func (c *client) CreateUserWithKeys(user *User) error { |
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.
Please remove the functions not used and not implemented.
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.
Well, this is a draft PR, so yes I'll remove them. : )
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.
BTW, I do eventually want methods like this in the codebase to be able to create domains/accounts/users on the fly in testing.
But since we will probably never do that in production, I'll probably put them in the test suite itself.
@@ -109,7 +109,7 @@ func (c *client) ResolveTemplate( | |||
zoneID string, | |||
) (templateID string, retErr error) { | |||
if len(csMachine.Spec.Template.ID) > 0 { | |||
csTemplate, count, err := c.cs.Template.GetTemplateByID(csMachine.Spec.Template.ID, "all") | |||
csTemplate, count, err := c.cs.Template.GetTemplateByID(csMachine.Spec.Template.ID, "executable") |
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.
"all" is only availalble to admin users.
// Attempt deletion regardless of machine state. | ||
p := c.cs.VirtualMachine.NewDestroyVirtualMachineParams(*csMachine.Spec.InstanceID) | ||
p := c.csAsync.VirtualMachine.NewDestroyVirtualMachineParams(*csMachine.Spec.InstanceID) |
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.
This shouldn't make any difference, but I was checking that.
We use the Async client here anyway, so felt better to match.
return fmt.Sprintf(`"%s" and "%s", %s`, account, domainID, desc) | ||
} | ||
} | ||
DescribeTable("DomainID and Account test table.", |
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.
We no longer need to set domain and account, so all these extra tests are for code that doesn't exist.
@@ -229,7 +229,6 @@ var _ = Describe("Network", func() { | |||
dummies.SetDummyIsoNetToNameOnly() | |||
dummies.SetClusterSpecToNet(&dummies.ISONet1) | |||
dummies.CSCluster.Spec.ControlPlaneEndpoint.Host = "" | |||
Ω(client.ResolveZones(dummies.CSCluster)).Should(Succeed()) |
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.
No such thing anymore!
Yes, it is possible. I will need to add an account and domain to our EC2 instance that has full perms, and then we'd just add that account and domain to our normal runs. That said, I probably can't get to this today. |
The code looks good to me. I think it'd be worth calling out the specific behavior that is implemented when using subdomains w.r.t. users expectations in the README |
}) | ||
|
||
Context("UserCred Semi-Integ Tests", func() { | ||
client, connectionErr := cloud.NewClient("../../cloud-config") |
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.
should we be hardcoding this path in the tests? I'd prefer to look at the secrets environment variable being set instead
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.
Completely, we should not.
This and other issues are why I want to turn my attention towards our CI/CD this week.
The semi-integ unit tests only work locally at the moment. They do pass for me, but there are other configuration hurdles besides this one that is preventing the semi-integs from working. For example, the name of the sub domain user should be configurable.
The E2E tests have some of this configuration, but not enough to run all tests. So, yeah. Working to get to this this week. : )
} | ||
|
||
// Settup dummies. | ||
// TODO: move these to the test dummies package. |
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.
could you create an issue to track this?
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 think the overhead of an issue for this one todo is necessary, but I can if you really want. I'll be in this file this week too.
|
||
// Settup dummies. | ||
// TODO: move these to the test dummies package. | ||
domain = cloud.Domain{Path: "ROOT/blah/blah/subsub"} |
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'd also like to see a test case where domain is not provided and we assume it to be root
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 will see about adding unit test for that soon, but this is handled via our E2Es.
@rejoshed would you mind creating an issue to track this? |
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: maxdrib, rejoshed, wongni The full list of commands accepted by this bot can be found here. The pull request process is described here
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
/lgtm |
Issue #, if available: CTECH-214
Description of changes:
When account and domain are specified CAPC will find (or create) a user in that domain and perform operations as that user. 🎆
Testing performed:
Created a cluster w/Affinity groups in a subdomain using an account and user in that domain.
Deleted the machinedeployment and watched the deletion process. Recreated machinedeployment. Deleted the whole cluster.
By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.