// processTriggers will go over all deployment triggers that require processing and update
// the deployment config accordingly. This contains the work that the image change controller
// had been doing up to the point we got the /instantiate endpoint.
163852
func processTriggers(config *appsapi.DeploymentConfig, is images.ImageStreamsGetter, force bool, exclude []appsapi.DeploymentTriggerType) error {
	errs := []error{}

	// Process any image change triggers.
	for _, trigger := range config.Spec.Triggers {
		if trigger.Type != appsapi.DeploymentTriggerOnImageChange {
			continue
		}

		params := trigger.ImageChangeParams

		// Forced deployments should always try to resolve the images in the template.
		// On the other hand, paused deployments or non-automatic triggers shouldn't.
		if !force && (config.Spec.Paused || !params.Automatic) {
			continue
		}

		if containsTriggerType(exclude, trigger.Type) {
			continue
		}

		// Tag references are already validated
		name, tag, _ := imageapi.SplitImageStreamTag(params.From.Name)
		stream, err := is.ImageStreams(params.From.Namespace).Get(name, metav1.GetOptions{})
		if err != nil {
			if !errors.IsNotFound(err) {
				errs = append(errs, err)
			}
			continue
		}

		// Find the latest tag event for the trigger reference.
		latestReference, ok := imageapi.ResolveLatestTaggedImage(stream, tag)
		if !ok {
			continue
		}

		// Ensure a change occurred
		if len(latestReference) == 0 || latestReference == params.LastTriggeredImage {
			continue
		}

		// Update containers
		names := sets.NewString(params.ContainerNames...)
		for i := range config.Spec.Template.Spec.Containers {
			container := &config.Spec.Template.Spec.Containers[i]
			if !names.Has(container.Name) {
				continue
			}
			if container.Image != latestReference || params.LastTriggeredImage != latestReference {
				// Update the image
				container.Image = latestReference
				// Log the last triggered image ID
				params.LastTriggeredImage = latestReference
			}
		}
		for i := range config.Spec.Template.Spec.InitContainers {
			container := &config.Spec.Template.Spec.InitContainers[i]
			if !names.Has(container.Name) {
				continue
			}
			if container.Image != latestReference || params.LastTriggeredImage != latestReference {
				// Update the image
				container.Image = latestReference
				// Log the last triggered image ID
				params.LastTriggeredImage = latestReference
			}
		}
	}

	if err := utilerrors.NewAggregate(errs); err != nil {
		return errors.NewInternalError(err)
	}

	return nil
}
1042353
func (t *LaunchTemplate) CheckChanges(a, e, changes *LaunchTemplate) error {
	if e.ImageID == nil {
		return fi.RequiredField("ImageID")
	}
	if e.InstanceType == nil {
		return fi.RequiredField("InstanceType")
	}

	if a != nil {
		if e.Name == nil {
			return fi.RequiredField("Name")
		}
	}
	return nil
}
283883
func (g *BuildGenerator) updateImageTriggers(ctx context.Context, bc *buildv1.BuildConfig, from, triggeredBy *corev1.ObjectReference) error {
	var requestTrigger *buildv1.ImageChangeTrigger
	if from != nil {
		requestTrigger = findImageChangeTrigger(bc, from)
	}
	if requestTrigger != nil && triggeredBy != nil && requestTrigger.LastTriggeredImageID == triggeredBy.Name {
		klog.V(2).Infof("Aborting imageid triggered build for BuildConfig %s/%s with imageid %s because the BuildConfig already matches this imageid", bc.Namespace, bc.Name, triggeredBy.Name)
		return fmt.Errorf("build config %s/%s has already instantiated a build for imageid %s", bc.Namespace, bc.Name, triggeredBy.Name)
	}
	// Update last triggered image id for all image change triggers
	for _, trigger := range bc.Spec.Triggers {
		if trigger.Type != buildv1.ImageChangeBuildTriggerType {
			continue
		}
		// Use the requested image id for the trigger that caused the build, otherwise resolve to the latest
		if triggeredBy != nil && trigger.ImageChange == requestTrigger {
			trigger.ImageChange.LastTriggeredImageID = triggeredBy.Name
			continue
		}

		triggerImageRef := trigger.ImageChange.From
		if triggerImageRef == nil {
			triggerImageRef = buildutil.GetInputReference(bc.Spec.Strategy)
		}
		if triggerImageRef == nil {
			klog.Warningf("Could not get ImageStream reference for default ImageChangeTrigger on BuildConfig %s/%s", bc.Namespace, bc.Name)
			continue
		}
		image, err := g.resolveImageStreamReference(ctx, *triggerImageRef, bc.Namespace)
		if err != nil {
			// If the trigger is for the strategy from ref, return an error
			if trigger.ImageChange.From == nil {
				return err
			}
			// Otherwise, warn that an error occurred, but continue
			klog.Warningf("Could not resolve trigger reference for build config %s/%s: %#v", bc.Namespace, bc.Name, triggerImageRef)
		}
		trigger.ImageChange.LastTriggeredImageID = image
	}
	return nil
}
329923
func (s *GetTriggerOutput) SetTrigger(v *Trigger) *GetTriggerOutput {
	s.Trigger = v
	return s
}
89686
func (s *CreateDatasetInput) SetTriggers(v []*DatasetTrigger) *CreateDatasetInput {
	s.Triggers = v
	return s
}
935341
func (s *RepositoryTriggerExecutionFailure) SetTrigger(v string) *RepositoryTriggerExecutionFailure {
	s.Trigger = &v
	return s
}
688544
func (s *EnvironmentResourceDescription) SetTriggers(v []*Trigger) *EnvironmentResourceDescription {
	s.Triggers = v
	return s
}
536487
func (d *BuildConfigDescriber) DescribeTriggers(bc *buildv1.BuildConfig, out *tabwriter.Writer) {
	describeBuildTriggers(bc.Spec.Triggers, bc.Name, bc.Namespace, out, d)
}
994383
func (s *UpdateTriggerOutput) SetTrigger(v *Trigger) *UpdateTriggerOutput {
	s.Trigger = v
	return s
}
264360
func (s *GetRepositoryTriggersOutput) SetTriggers(v []*RepositoryTrigger) *GetRepositoryTriggersOutput {
	s.Triggers = v
	return s
}
337918
func (r *ImageRef) BuildTriggers() []buildv1.BuildTriggerPolicy {
	if r.Stream == nil && !r.AsImageStream {
		return nil
	}
	return []buildv1.BuildTriggerPolicy{
		{
			Type:        buildv1.ImageChangeBuildTriggerType,
			ImageChange: &buildv1.ImageChangeTrigger{},
		},
	}
}
1008604
func (ic *IngressIPController) processChange(change *serviceChange) error {
	service := ic.getCachedService(change.key)

	ic.clearOldAllocation(service, change.oldService)

	if service == nil {
		// Service was deleted - no further processing required
		return nil
	}

	typeLoadBalancer := service.Spec.Type == v1.ServiceTypeLoadBalancer
	hasAllocation := len(service.Status.LoadBalancer.Ingress) > 0
	switch {
	case typeLoadBalancer && hasAllocation:
		return ic.recordAllocation(service, change.key)
	case typeLoadBalancer && !hasAllocation:
		return ic.allocate(service, change.key)
	case !typeLoadBalancer && hasAllocation:
		return ic.deallocate(service, change.key)
	default:
		return nil
	}
}
142542
func (p *pluginControl) ProcessMetrics(metrics []core.Metric, config map[string]ctypes.ConfigValue, taskID, pluginName string, pluginVersion int) ([]core.Metric, []error) {
	// If control is not started we don't want tasks to be able to
	// go through a workflow.
	if !p.Started {
		return nil, []error{ErrControllerNotStarted}
	}
	// merge global plugin config into the config for this request
	// without over-writing the task specific config
	cfg := p.Config.Plugins.getPluginConfigDataNode(core.ProcessorPluginType, pluginName, pluginVersion).Table()
	merged := make(map[string]ctypes.ConfigValue)
	for k, v := range cfg {
		merged[k] = v
	}
	for k, v := range config {
		merged[k] = v
	}

	return p.pluginRunner.AvailablePlugins().processMetrics(metrics, pluginName, pluginVersion, merged, taskID)
}
552845
func (r *RequestBuilder) FromNoopTrigger(t *scheduler.NoopTrigger) {
	r.Properties = structFromMap(map[string]string{
		"noop_trigger_data": t.Data, // for testing
	})
}
615524
func RecordImageChangeCauses(config *appsv1.DeploymentConfig, imageNames []string) {
	config.Status.Details = &appsv1.DeploymentDetails{
		Message: "image change",
	}
	for _, imageName := range imageNames {
		config.Status.Details.Causes = append(config.Status.Details.Causes, appsv1.DeploymentCause{
			Type:         appsv1.DeploymentTriggerOnImageChange,
			ImageTrigger: &appsv1.DeploymentCauseImageTrigger{From: v1.ObjectReference{Kind: "DockerImage", Name: imageName}},
		})
	}
}
418567
func AddTriggerEdges(g osgraph.MutableUniqueGraph, node *buildgraph.BuildConfigNode) {
	for _, trigger := range node.BuildConfig.Spec.Triggers {
		if trigger.Type != buildv1.ImageChangeBuildTriggerType {
			continue
		}
		from := trigger.ImageChange.From
		if trigger.ImageChange.From == nil {
			from = buildutil.GetInputReference(node.BuildConfig.Spec.Strategy)
		}
		triggerNode := imageRefNode(g, from, node.BuildConfig)
		g.AddEdge(triggerNode, node, BuildTriggerImageEdgeKind)
	}
}
1290483
func (ctl *taskController) EmitTrigger(ctx context.Context, trigger *internal.Trigger) {
	ctl.DebugLog("Emitting a trigger %s", trigger.Id)
	trigger.JobId = ctl.JobID()
	trigger.InvocationId = ctl.InvocationID()

	// See docs for internal.Trigger proto. Tuple (created, order_in_batch) used
	// for casual ordering of triggers emitted by an invocation. Callers of
	// EmitTrigger are free to override this by supplying their own timestamp. In
	// such case they also should provide order_in_batch. Otherwise we build the
	// tuple for them based on the order of EmitTrigger calls.
	if trigger.Created == nil {
		trigger.Created = google.NewTimestamp(clock.Now(ctx))
		trigger.OrderInBatch = ctl.triggerIndex
	}

	ctl.triggers = append(ctl.triggers, trigger)
	ctl.triggerIndex++ // note: this is NOT reset in Save, unlike ctl.triggers.
}