Skip to content

Commit

Permalink
Merge pull request #472 from garden-io/provider-refactor
Browse files Browse the repository at this point in the history
refactor: add configureProvider plugin action
  • Loading branch information
edvald authored Jan 25, 2019
2 parents 4363fc5 + bdf6994 commit 7d5d74c
Show file tree
Hide file tree
Showing 23 changed files with 242 additions and 188 deletions.
4 changes: 2 additions & 2 deletions garden-service/src/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -381,7 +381,7 @@ export class ActionHelper implements TypeGuard {
}
}

private async callActionHandler<T extends keyof PluginActions>(
private async callActionHandler<T extends keyof Omit<PluginActions, "configureProvider">>(
{ params, actionType, pluginName, defaultHandler }:
{
params: ActionHelperParams<PluginActionParams[T]>,
Expand All @@ -402,7 +402,7 @@ export class ActionHelper implements TypeGuard {
return (<Function>handler)(handlerParams)
}

private async callModuleHandler<T extends keyof Omit<ModuleActions, "describeType" | "validate">>(
private async callModuleHandler<T extends keyof Omit<ModuleActions, "describeType" | "configure">>(
{ params, actionType, defaultHandler }:
{ params: ModuleActionHelperParams<ModuleActionParams[T]>, actionType: T, defaultHandler?: ModuleActions[T] },
): Promise<ModuleActionOutputs[T]> {
Expand Down
48 changes: 31 additions & 17 deletions garden-service/src/garden.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import {
sortBy,
difference,
find,
findIndex,
} from "lodash"
const AsyncLock = require("async-lock")

Expand All @@ -44,7 +45,7 @@ import {
pluginModuleSchema,
pluginSchema,
} from "./types/plugin/plugin"
import { Environment, SourceConfig, defaultProvider, Provider } from "./config/project"
import { Environment, SourceConfig, defaultProvider, ProviderConfig, Provider } from "./config/project"
import {
findByName,
getIgnorer,
Expand Down Expand Up @@ -418,7 +419,7 @@ export class Garden {
this.registeredPlugins[name] = factory
}

private async loadPlugin(pluginName: string, config: object) {
private async loadPlugin(pluginName: string, config: ProviderConfig) {
const factory = this.registeredPlugins[pluginName]

if (!factory) {
Expand All @@ -428,12 +429,11 @@ export class Garden {
})
}

let plugin
let plugin: GardenPlugin

try {
plugin = await factory({
projectName: this.projectName,
config,
log: this.log,
})
} catch (error) {
Expand All @@ -447,18 +447,6 @@ export class Garden {

this.loadedPlugins[pluginName] = plugin

// allow plugins to extend their own config (that gets passed to action handlers)
const providerConfig = findByName(this.environment.providers, pluginName)
if (providerConfig) {
extend(providerConfig, plugin.config, config)
} else {
const provider: Provider = {
name: pluginName,
config: extend({ name: pluginName }, plugin.config, config),
}
this.environment.providers.push(provider)
}

for (const modulePath of plugin.modules || []) {
let moduleConfig = await this.resolveModule(modulePath)
if (!moduleConfig) {
Expand Down Expand Up @@ -486,6 +474,32 @@ export class Garden {
handler && this.addModuleActionHandler(pluginName, actionType, moduleType, handler)
}
}

// allow plugins to be configured more than once
// (to support extending config for fixed plugins and environment defaults)
let providerIndex = findIndex(this.environment.providers, ["name", pluginName])
let providerConfig: ProviderConfig = providerIndex === -1
? config
: this.environment.providers[providerIndex].config

extend(providerConfig, config)

// call configureProvider action if provided
const configureHandler = actions.configureProvider
if (configureHandler) {
const configureOutput = await configureHandler({ config: providerConfig })
providerConfig = configureOutput.config
}

if (plugin.configSchema) {
providerConfig = validate(providerConfig, plugin.configSchema, { context: `${pluginName} configuration` })
}

if (providerIndex === -1) {
this.environment.providers.push({ name: pluginName, config: providerConfig })
} else {
this.environment.providers[providerIndex].config = providerConfig
}
}

private getPlugin(pluginName: string) {
Expand Down Expand Up @@ -839,7 +853,7 @@ export class Garden {
@param force - add the module again, even if it's already registered
*/
async addModule(config: ModuleConfig, force = false) {
const validateHandler = await this.getModuleActionHandler({ actionType: "validate", moduleType: config.type })
const validateHandler = await this.getModuleActionHandler({ actionType: "configure", moduleType: config.type })
const ctx = this.getPluginContext(validateHandler["pluginName"])

config = await validateHandler({ ctx, moduleConfig: config })
Expand Down
6 changes: 3 additions & 3 deletions garden-service/src/plugins/container/container.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,15 @@ import { GardenPlugin } from "../../types/plugin/plugin"
import {
BuildModuleParams,
GetBuildStatusParams,
ValidateModuleParams,
ConfigureModuleParams,
HotReloadServiceParams,
PublishModuleParams,
} from "../../types/plugin/params"
import { keyBy } from "lodash"
import { containerHelpers } from "./helpers"
import { ContainerModule, containerModuleSpecSchema } from "./config"

export async function validateContainerModule({ ctx, moduleConfig }: ValidateModuleParams<ContainerModule>) {
export async function configureContainerModule({ ctx, moduleConfig }: ConfigureModuleParams<ContainerModule>) {
moduleConfig.spec = validateWithPath({
config: moduleConfig.spec,
schema: containerModuleSpecSchema,
Expand Down Expand Up @@ -148,7 +148,7 @@ export async function validateContainerModule({ ctx, moduleConfig }: ValidateMod
export const gardenPlugin = (): GardenPlugin => ({
moduleActions: {
container: {
validate: validateContainerModule,
configure: configureContainerModule,

async getBuildStatus({ module, log }: GetBuildStatusParams<ContainerModule>) {
const identifier = await containerHelpers.imageExistsLocally(module)
Expand Down
15 changes: 8 additions & 7 deletions garden-service/src/plugins/exec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,16 @@ import { Module } from "../types/module"
import {
BuildResult,
BuildStatus,
ValidateModuleResult,
TestResult,
RunTaskResult,
ConfigureModuleResult,
} from "../types/plugin/outputs"
import {
BuildModuleParams,
GetBuildStatusParams,
ValidateModuleParams,
TestModuleParams, RunTaskParams,
TestModuleParams,
RunTaskParams,
ConfigureModuleParams,
} from "../types/plugin/params"
import { CommonServiceSpec } from "../config/service"
import { BaseTestSpec, baseTestSpecSchema } from "../config/test"
Expand Down Expand Up @@ -84,9 +85,9 @@ export const execModuleSpecSchema = Joi.object()

export interface ExecModule extends Module<ExecModuleSpec, CommonServiceSpec, ExecTestSpec> { }

export async function parseExecModule(
{ ctx, moduleConfig }: ValidateModuleParams<ExecModule>,
): Promise<ValidateModuleResult> {
export async function configureExecModule(
{ ctx, moduleConfig }: ConfigureModuleParams<ExecModule>,
): Promise<ConfigureModuleResult> {

moduleConfig.spec = validateWithPath({
config: moduleConfig.spec,
Expand Down Expand Up @@ -225,7 +226,7 @@ export async function runExecTask(params: RunTaskParams): Promise<RunTaskResult>
export const execPlugin: GardenPlugin = {
moduleActions: {
exec: {
validate: parseExecModule,
configure: configureExecModule,
getBuildStatus: getExecModuleBuildStatus,
build: buildExecModule,
runTask: runExecTask,
Expand Down
12 changes: 6 additions & 6 deletions garden-service/src/plugins/google/google-cloud-functions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@ import {
validateWithPath,
} from "../../config/common"
import { Module } from "../../types/module"
import { ValidateModuleResult } from "../../types/plugin/outputs"
import { ConfigureModuleResult } from "../../types/plugin/outputs"
import {
DeployServiceParams,
GetServiceOutputsParams,
GetServiceStatusParams,
ValidateModuleParams,
ConfigureModuleParams,
} from "../../types/plugin/params"
import { ServiceState, ServiceStatus, ingressHostnameSchema, Service } from "../../types/service"
import {
Expand Down Expand Up @@ -79,9 +79,9 @@ function getGcfProject<T extends GcfModule>(service: Service<T>, provider: Provi
return service.spec.project || provider.config["default-project"] || null
}

export async function parseGcfModule(
{ ctx, moduleConfig }: ValidateModuleParams<GcfModule>,
): Promise<ValidateModuleResult<GcfModule>> {
export async function configureGcfModule(
{ ctx, moduleConfig }: ConfigureModuleParams<GcfModule>,
): Promise<ConfigureModuleResult<GcfModule>> {

// TODO: check that each function exists at the specified path
moduleConfig.spec = validateWithPath({
Expand Down Expand Up @@ -116,7 +116,7 @@ export const gardenPlugin = (): GardenPlugin => ({
},
moduleActions: {
"google-cloud-function": {
validate: parseGcfModule,
configure: configureGcfModule,

async deployService(params: DeployServiceParams<GcfModule>) {
const { ctx, service } = params
Expand Down
10 changes: 5 additions & 5 deletions garden-service/src/plugins/kubernetes/container/handlers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,15 @@ import { getServiceLogs } from "./logs"
import { execInService, runContainerModule, runContainerService, runContainerTask } from "./run"
import { testContainerModule } from "./test"
import { ConfigurationError } from "../../../exceptions"
import { validateContainerModule } from "../../container/container"
import { configureContainerModule } from "../../container/container"
import { KubernetesProvider } from "../kubernetes"
import { ValidateModuleParams } from "../../../types/plugin/params"
import { ConfigureModuleParams } from "../../../types/plugin/params"
import { getContainerServiceStatus, getServiceOutputs } from "./status"
import { getTestResult } from "../test"
import { ContainerModule } from "../../container/config"

async function validate(params: ValidateModuleParams<ContainerModule>) {
const config = await validateContainerModule(params)
async function configure(params: ConfigureModuleParams<ContainerModule>) {
const config = await configureContainerModule(params)

// validate ingress specs
const provider: KubernetesProvider = params.ctx.provider
Expand Down Expand Up @@ -49,6 +49,7 @@ async function validate(params: ValidateModuleParams<ContainerModule>) {
}

export const containerHandlers = {
configure,
deployService: deployContainerService,
deleteService,
execInService,
Expand All @@ -62,5 +63,4 @@ export const containerHandlers = {
runService: runContainerService,
runTask: runContainerTask,
testModule: testContainerModule,
validate,
}
8 changes: 4 additions & 4 deletions garden-service/src/plugins/kubernetes/helm/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ import {
joiUserIdentifier,
} from "../../../config/common"
import { Module, FileCopySpec } from "../../../types/module"
import { ValidateModuleParams } from "../../../types/plugin/params"
import { ValidateModuleResult } from "../../../types/plugin/outputs"
import { ConfigureModuleParams } from "../../../types/plugin/params"
import { ConfigureModuleResult } from "../../../types/plugin/outputs"
import { containsSource } from "./common"
import { ConfigurationError } from "../../../exceptions"
import { deline } from "../../../util/string"
Expand Down Expand Up @@ -205,8 +205,8 @@ export const helmModuleSpecSchema = Joi.object().keys({
),
})

export async function validateHelmModule({ ctx, moduleConfig }: ValidateModuleParams<HelmModule>)
: Promise<ValidateModuleResult<HelmModule>> {
export async function validateHelmModule({ ctx, moduleConfig }: ConfigureModuleParams<HelmModule>)
: Promise<ConfigureModuleResult<HelmModule>> {
moduleConfig.spec = validateWithPath({
config: moduleConfig.spec,
schema: helmModuleSpecSchema,
Expand Down
4 changes: 2 additions & 2 deletions garden-service/src/plugins/kubernetes/helm/handlers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

import { ModuleAndRuntimeActions } from "../../../types/plugin/plugin"
import { getExecModuleBuildStatus } from "../../exec"
import { HelmModule, validateHelmModule } from "./config"
import { HelmModule, validateHelmModule as configureHelmModule } from "./config"
import { buildHelmModule } from "./build"
import { getServiceStatus, getServiceOutputs } from "./status"
import { deployService, deleteService } from "./deployment"
Expand All @@ -20,6 +20,7 @@ import { testHelmModule } from "./test"

export const helmHandlers: Partial<ModuleAndRuntimeActions<HelmModule>> = {
build: buildHelmModule,
configure: configureHelmModule,
// TODO: add execInService handler
deleteService,
deployService,
Expand All @@ -33,5 +34,4 @@ export const helmHandlers: Partial<ModuleAndRuntimeActions<HelmModule>> = {
runModule: runHelmModule,
runTask: runHelmTask,
testModule: testHelmModule,
validate: validateHelmModule,
}
8 changes: 3 additions & 5 deletions garden-service/src/plugins/kubernetes/kubernetes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import * as Joi from "joi"
import dedent = require("dedent")

import { joiArray, joiIdentifier, validate } from "../../config/common"
import { joiArray, joiIdentifier } from "../../config/common"
import { GardenPlugin } from "../../types/plugin/plugin"
import { Provider, providerConfigBaseSchema, ProviderConfig } from "../../config/project"
import { helmHandlers } from "./helm/handlers"
Expand Down Expand Up @@ -139,11 +139,9 @@ const configSchema = kubernetesConfigBase
_system: Joi.any().meta({ internal: true }),
})

export function gardenPlugin({ config }: { config: KubernetesConfig }): GardenPlugin {
config = validate(config, configSchema, { context: "kubernetes provider config" })

export function gardenPlugin(): GardenPlugin {
return {
config,
configSchema,
actions: {
getEnvironmentStatus: getRemoteEnvironmentStatus,
prepareEnvironment: prepareRemoteEnvironment,
Expand Down
Loading

0 comments on commit 7d5d74c

Please sign in to comment.