Skip to content
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

Initial merge of Development to Master #1

Merged
merged 71 commits into from
Aug 24, 2020
Merged

Initial merge of Development to Master #1

merged 71 commits into from
Aug 24, 2020

Conversation

nabuskey
Copy link
Collaborator

Initial merge of Development to Master

Comment on lines +123 to +137
try {
// Cannot autowire EcsAccountMapper for some reason. It returns every field wth null values.
// Doing it this way is a problem.
if (this.ecsAccountMapper == null) {
this.ecsAccountMapper = (EcsAccountMapper) applicationContext.getBean("ecsAccountMapper");
}
EcsProviderUtils.synchronizeEcsCredentialsMapper(ecsAccountMapper, lazyLoadCredentialsRepository);
} catch (IllegalAccessException | NoSuchFieldException e) {
log.error("Error encountered while updating ECS credentials mapper: {}", e.getMessage());
e.printStackTrace();
return;
} catch (BeansException e) {
log.error("Error obtaining EcsAccountMapper bean from Spring context.");
return;
}
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I really do not like this. This is guaranteed to fail on @PostConstruct . But I am not sure how to go about resolving this. @nimakaviani

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmmmm I wonder if the problem you are seeing is somewhat similar to the issue discussed here: https://spinnakerteam.slack.com/archives/CK9FK4XDF/p1597093660354200

Have a look and let me know what you think.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately that doesn't work. The issue is that EcsAccountMapper depends on AccountCredentialsProvider which depends on CredentialsRepository. This plugin replaces CredentialsRepository and it needs to be able to update EcsAccountMapper when updates to accounts are made. So circular dependency. Note that this (BeansException) happens only at startup. It works fine once started.

We can take it out of this class and do it in another class but it may cause ECS account state inconsistency.
Is there anything similar to Go's channels in Java? Something light weight to communicate between objects.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Kotlin has the concept of coroutines and channels similar to golang (here) but nothing in Java that I know of. Let me check out the plugin code later today and play with it a bit to see if I can find any alternatives.

Copy link
Collaborator

@nimakaviani nimakaviani left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

some minor suggestions as I was looking at the code.

Comment on lines 55 to 63
CredentialsConfig.Account ec2Account = new CredentialsConfig.Account() {{
setName(account.getName());
setAccountId(account.getAccountId());
setAssumeRole(account.getAssumeRole());
setRegions(regions);
setPermissions(account.getPermissions());
setEnvironment(account.getEnvironment());
}};
return ec2Account;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
CredentialsConfig.Account ec2Account = new CredentialsConfig.Account() {{
setName(account.getName());
setAccountId(account.getAccountId());
setAssumeRole(account.getAssumeRole());
setRegions(regions);
setPermissions(account.getPermissions());
setEnvironment(account.getEnvironment());
}};
return ec2Account;
return new CredentialsConfig.Account() {{
setName(account.getName());
setAccountId(account.getAccountId());
setAssumeRole(account.getAssumeRole());
setRegions(regions);
setPermissions(account.getPermissions());
setEnvironment(account.getEnvironment());
}};```

Comment on lines +133 to +137
def accountToDelete = reservationReportAccounts.find { it.name == accountNameToDelete }

if (accountToDelete) {
reservationReportAccounts.remove(accountToDelete)
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
def accountToDelete = reservationReportAccounts.find { it.name == accountNameToDelete }
if (accountToDelete) {
reservationReportAccounts.remove(accountToDelete)
}
reservationReportAccounts.removeIf { it.name == accountNameToDelete }

synchronizer.sync();
cred = super.getOne(key);
if (cred != null) {
save(key, cred);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That doesn't seem necessary.

List<Class> classes = new ArrayList<>(Arrays.asList(AmazonPollingSynchronizer.class,
AmazonEC2InfraCachingAgentScheduler.class,
AmazonAWSCachingAgentScheduler.class, AmazonECSCachingAgentScheduler.class));
for (Class calssToAdd : classes) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

calssToAdd typo?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes it is. It's fixed in feature/refactor-account-response. Thanks!

* Remove Account constructor and add AccountsStatus unit test

* Remove unused code and imports

* Fix formatting

* remove @PostConstruct since it's guaranteed to fail
// agent removal
private final CredentialsLoader<? extends NetflixAmazonCredentials> credentialsLoader;
private final CredentialsConfig credentialsConfig;
private final LazyLoadCredentialsRepository lazyLoadCredentialsRepository;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LazyLoadCredentialsRepository is not required here. I'd just use AccountCredentialsRepository.

}
EcsProviderUtils.synchronizeEcsCredentialsMapper(ecsAccountMapper, lazyLoadCredentialsRepository);
} catch (IllegalAccessException | NoSuchFieldException e) {
log.error("Error encountered while updating ECS credentials mapper: {}", e.getMessage());
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

log.error(..., e), don't print stack trace.

return new ArrayList<>(ecsAccounts.values());
}

public Boolean getDesiredAccounts() {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can it return a boolean instead of Boolean? Otherwise we have to deal with value == null in the caller.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

changed to boolean. Thanks!

Copy link

@kevinawoo kevinawoo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm cool with it as long as everyone else is

* Implement IAM auth for API gateway
CredentialsConfig.Account ec2Account = new CredentialsConfig.Account() {{
setName("test1");
setAccountId("1");
setAssumeRole("role/role1");

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are we expecting the account registry to return SpinnakerAssumeRole with role/ prefixed to the role name? Seems like from the Response class in the code above, this is not a hard requirement.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if (exists != null) {
continue;
}
if ("SUSPENDED".equals(account.getStatus()) || account.getProviders() == null || account.getProviders().isEmpty()) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We may want to make the status check case insensitive... If for whatever reason AWS changes the casing returned from the Orgs API.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good idea. I will do that.


private Response getResources(String url) {
if (lastSyncTime != null) {
url = String.format("%s?after=%s", url, lastSyncTime.toString());
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the base URL contains parameters, for instance https://somewhere[.]com/api?param=1234, will this work? Is it supported?

* implement nextUrl support

* Add debug logs

* Add support for query strings in configuration

* Finalize JSON schema
@nabuskey
Copy link
Collaborator Author

Coverage for non-utility classes.

Package Class, % Method, % Line, %
com.amazon.aws.spinnaker.plugin.registration 100% (8/ 8) 78.8% (52/ 66) 74.9% (239/ 319)
com.amazon.aws.spinnaker.plugin.registration.auth.iam 100% (3/ 3) 100% (6/ 6) 100% (28/ 28)

* Add validity check for remote host response

* Add support for whitespaces in regions

* Handle cases where only deleted accounts are returned by remote host.
@nabuskey nabuskey merged commit c0996b7 into master Aug 24, 2020
jasoncoffman pushed a commit that referenced this pull request Aug 24, 2020
Initial merge of development branch to master.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

7 participants