-
Notifications
You must be signed in to change notification settings - Fork 266
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
feat(terraform): add plugin commands for terraform apply and plan #1641
Conversation
84e95d6
to
6d5d97f
Compare
@solomonope, would be great to get your eyes on this as well, |
@@ -34,6 +36,10 @@ export class PluginsCommand extends Command<Args> { | |||
name = "plugins" | |||
help = "Plugin-specific commands." | |||
|
|||
// FIXME: We need this while we're still resolving providers in the AnalyticsHandler |
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.
Do you know how we would fix 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.
By not doing that, basically. We'd add metadata as it becomes available, and not force/rush the init.
|
||
garden ${chalk.yellow("[global options]")} ${chalk.blueBright("<command>")} ${chalk.white("[args ...]")} | ||
|
||
${chalk.white.bold("PLUGIN COMMANDS")} |
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 could extract this and the stuff below to a helper function since we're doing basically the same in https://github.com/garden-io/garden/tree/master/garden-service/src/commands/options.ts
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 notice that the table config is duplicated as well, although not part of this PR per se.
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.
Sure
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.
Actually on second glance there isn't that much common with the code, seems like I'd be going out of my way there a bit. The table generation there could use the new helper function though, I guess.
garden-service/src/garden.ts
Outdated
} | ||
|
||
// As an optimization, we return immediately if all requested providers are already resolved | ||
const alreadyResolved = names.map((name) => this.resolvedProviders[name]).filter(Boolean) |
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.
A nitpick but the variable name sounds like a boolean, perhaps alreadyResolvedProviders
. Makes the providers = alreadyResolved
line below easier to read.
@@ -54,7 +54,7 @@ export class Logger extends LogNode { | |||
|
|||
static initialize(config: LoggerConfig): Logger { | |||
if (Logger.instance) { | |||
throw new InternalError("Logger already initialized", {}) | |||
return Logger.instance |
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.
Trying to think why we didn't just do this in the first place.
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.
Yeah, same. I couldn't think of a good reason.
} else if (plan.exitCode === 2) { | ||
// No error but stack is not up-to-date | ||
logEntry.setWarn({ msg: "Not up-to-date" }) | ||
if (autoApply) { | ||
// Trigger the prepareEnvironment handler | ||
return { ready: false, outputs: {} } | ||
} else { | ||
logEntry.warn(noAutoApplyMsg) | ||
logEntry.warn({ symbol: "warning", msg: noAutoApplyMsg(applyCommand) }) | ||
const outputs = await getTfOutputs(log, tfVersion, root) | ||
return { ready: true, outputs } |
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 you have autoApply
set to false, and have a Terraform module that's not been applied, e.g. because you've never "deployed" it before, Garden will print Already deployed
to the terminal but fail when other modules reference its runtime output.
Not sure how to workaround this tbh.
A similar thing would happen at the provider level but at least there you don't get the Already deployed
message which is a little misleading.
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 may need to special-case the module behavior (as opposed to the provider behavior). I can look into it.
@@ -850,11 +850,15 @@ export class TaskNodeBatch { | |||
*/ | |||
taskCached(result: TaskResult, depResults: TaskResult[]): boolean { | |||
const key = result.key | |||
this.results[key] = result | |||
if (this.remainingResultKeys.has(key)) { |
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 are we changing the task graph? And could @thsig lend a pair of eyes?
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.
Ah yes, I forgot to mention this in the commit. There was basically an error in the TaskGraph that caused old/unrelated task results to be lumped in the TaskResults object, that prompted an issue while I was testing all this. Could split that out into a separate commit.
@@ -104,6 +104,12 @@ export class ResolveProviderTask extends BaseTask { | |||
async process(dependencyResults: TaskResults) { | |||
const resolvedProviders: Provider[] = Object.values(dependencyResults).map((result) => result && result.output) | |||
|
|||
// Return immediately if the provider has been previously resolved | |||
const alreadyResolved = this.garden["resolvedProviders"][this.config.name] |
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.
Same as my comment above, looks like a boolean. Admittedly I'm not looking at this in VSCode with the type hints.
6d5d97f
to
37b71ed
Compare
37b71ed
to
105af55
Compare
0e4717f
to
9dfa229
Compare
There are a few console log statements in there, also needs to be squashed. |
This makes the terraform provider a little easier to work with day-to-day. We also explicitly discourage use of `autoApply` now, except for private environments. The status check is now also faster, because we don't refresh the stack state every time. This involved a few refactors, mainly to improve the plugin command framework. I also needed to modify the provider resolution flow so that individual providers can be resolved (otherwise it wouldn't be possible to run the apply/plan commands if another provider depended on the outputs).
9dfa229
to
6fa9d8e
Compare
What this PR does / why we need it:
This makes the terraform provider a little easier to work with
day-to-day. We also explicitly discourage use of
autoApply
now, exceptfor private environments. The status check is now also faster, because
we don't refresh the stack state every time.
This involved a few refactors, mainly to improve the plugin command
framework. I also needed to modify the provider resolution flow so that
individual providers can be resolved (otherwise it wouldn't be possible
to run the apply/plan commands if another provider depended on the
outputs).
Special notes for your reviewer:
Please try using this with a real project, see if it matches your expectations,
and the interface+docs feel clear and sensible.