Ejemplo n.º 1
0
Archivo: validate.go Proyecto: ACPK/atc
func validatePlan(c atc.Config, identifier string, plan atc.PlanConfig) []string {
	foundTypes := foundTypes{
		identifier: identifier,
		found:      make(map[string]bool),
	}

	if plan.Get != "" {
		foundTypes.Find("get")
	}

	if plan.Put != "" {
		foundTypes.Find("put")
	}

	if plan.Task != "" {
		foundTypes.Find("task")
	}

	if plan.Do != nil {
		foundTypes.Find("do")
	}

	if plan.Aggregate != nil {
		foundTypes.Find("aggregate")
	}

	if plan.Try != nil {
		foundTypes.Find("try")
	}

	if valid, message := foundTypes.IsValid(); !valid {
		return []string{message}
	}

	errorMessages := []string{}

	switch {
	case plan.Do != nil:
		for i, plan := range *plan.Do {
			subIdentifier := fmt.Sprintf("%s[%d]", identifier, i)
			errorMessages = append(errorMessages, validatePlan(c, subIdentifier, plan)...)
		}

	case plan.Aggregate != nil:
		for i, plan := range *plan.Aggregate {
			subIdentifier := fmt.Sprintf("%s.aggregate[%d]", identifier, i)
			errorMessages = append(errorMessages, validatePlan(c, subIdentifier, plan)...)
		}

	case plan.Get != "":
		subIdentifier := fmt.Sprintf("%s.get.%s", identifier, plan.Get)

		errorMessages = append(errorMessages, validateInapplicableFields(
			[]string{"privileged", "config", "file"},
			plan, subIdentifier)...,
		)

		if plan.Resource != "" {
			_, found := c.Resources.Lookup(plan.Resource)
			if !found {
				errorMessages = append(
					errorMessages,
					fmt.Sprintf(
						"%s refers to a resource that does not exist ('%s')",
						subIdentifier,
						plan.Resource,
					),
				)
			}
		} else {
			_, found := c.Resources.Lookup(plan.Get)
			if !found {
				errorMessages = append(
					errorMessages,
					fmt.Sprintf(
						"%s refers to a resource that does not exist",
						subIdentifier,
					),
				)
			}
		}

		for _, job := range plan.Passed {
			jobConfig, found := c.Jobs.Lookup(job)
			if !found {
				errorMessages = append(
					errorMessages,
					fmt.Sprintf(
						"%s.passed references an unknown job ('%s')",
						subIdentifier,
						job,
					),
				)
			} else {
				foundResource := false

				for _, jobInput := range JobInputs(jobConfig) {
					if jobInput.Resource == plan.ResourceName() {
						foundResource = true
						break
					}
				}

				for _, jobOutput := range JobOutputs(jobConfig) {
					if jobOutput.Resource == plan.ResourceName() {
						foundResource = true
						break
					}
				}

				if !foundResource {
					errorMessages = append(
						errorMessages,
						fmt.Sprintf(
							"%s.passed references a job ('%s') which doesn't interact with the resource ('%s')",
							subIdentifier,
							job,
							plan.Get,
						),
					)
				}
			}
		}

	case plan.Put != "":
		subIdentifier := fmt.Sprintf("%s.put.%s", identifier, plan.Put)

		errorMessages = append(errorMessages, validateInapplicableFields(
			[]string{"passed", "trigger", "privileged", "config", "file"},
			plan, subIdentifier)...,
		)

		if plan.Resource != "" {
			_, found := c.Resources.Lookup(plan.Resource)
			if !found {
				errorMessages = append(
					errorMessages,
					fmt.Sprintf(
						"%s refers to a resource that does not exist ('%s')",
						subIdentifier,
						plan.Resource,
					),
				)
			}
		} else {
			_, found := c.Resources.Lookup(plan.Put)
			if !found {
				errorMessages = append(
					errorMessages,
					fmt.Sprintf(
						"%s refers to a resource that does not exist",
						subIdentifier,
					),
				)
			}
		}

	case plan.Task != "":
		subIdentifier := fmt.Sprintf("%s.task.%s", identifier, plan.Task)

		if plan.TaskConfig == nil && plan.TaskConfigPath == "" {
			errorMessages = append(errorMessages, subIdentifier+" does not specify any task configuration")
		}

		errorMessages = append(errorMessages, validateInapplicableFields(
			[]string{"resource", "passed", "trigger"},
			plan, subIdentifier)...,
		)

		if plan.Params != nil {
			errorMessages = append(errorMessages, subIdentifier+" specifies params, which should be config.params")
		}

	case plan.Try != nil:
		subIdentifier := fmt.Sprintf("%s.try", identifier)
		errorMessages = append(errorMessages, validatePlan(c, subIdentifier, *plan.Try)...)
	}

	if plan.Ensure != nil {
		subIdentifier := fmt.Sprintf("%s.ensure", identifier)
		errorMessages = append(errorMessages, validatePlan(c, subIdentifier, *plan.Ensure)...)
	}

	if plan.Success != nil {
		subIdentifier := fmt.Sprintf("%s.success", identifier)
		errorMessages = append(errorMessages, validatePlan(c, subIdentifier, *plan.Success)...)
	}

	if plan.Failure != nil {
		subIdentifier := fmt.Sprintf("%s.failure", identifier)
		errorMessages = append(errorMessages, validatePlan(c, subIdentifier, *plan.Failure)...)
	}

	if plan.Timeout != "" {
		_, err := time.ParseDuration(plan.Timeout)
		if err != nil {
			subIdentifier := fmt.Sprintf("%s.timeout", identifier)
			errorMessages = append(errorMessages, subIdentifier+fmt.Sprintf(" refers to a duration that could not be parsed ('%s')", plan.Timeout))
		}
	}

	return errorMessages
}