func UpdateMatchingContainerImage()

in gke-deploy/core/resource/resource.go [227:287]


func UpdateMatchingContainerImage(ctx context.Context, objs Objects, imageName, replace string) error {
	matched := false
	for _, obj := range objs {
		var nestedFields []string

		switch kind := ObjectKind(obj); kind {
		case "CronJob":
			nestedFields = []string{"spec", "jobTemplate", "spec", "template", "spec", "containers"}
		case "Pod":
			nestedFields = []string{"spec", "containers"}
		case "DaemonSet", "Deployment", "Job", "ReplicaSet", "ReplicationController", "StatefulSet":
			nestedFields = []string{"spec", "template", "spec", "containers"}
		default:
			continue
		}

		cons, ok, err := unstructured.NestedFieldNoCopy(obj.Object, nestedFields...)
		if err != nil {
			return fmt.Errorf("failed to get nested containers field: %v", err)
		}
		if !ok {
			continue
		}
		consList, ok := cons.([]interface{})
		if !ok {
			return fmt.Errorf("failed to convert containers to list")
		}

		for _, con := range consList {
			conMap, ok := con.(map[string]interface{})
			if !ok {
				return fmt.Errorf("failed to convert container to map")
			}
			im, ok, err := unstructured.NestedString(conMap, "image")
			if err != nil {
				return fmt.Errorf("failed to get image field: %v", err)
			}
			if !ok {
				continue
			}

			ref, err := name.ParseReference(im)
			if err != nil {
				return fmt.Errorf("failed to parse reference from image %q: %v", im, err)
			}
			if image.Name(ref) == imageName {
				fmt.Printf("Updating container of resource: %v\n", obj)
				if err := unstructured.SetNestedField(conMap, replace, "image"); err != nil {
					return fmt.Errorf("failed to set image field: %v", err)
				}
				matched = true
			}
		}
	}

	if !matched {
		fmt.Fprintf(os.Stderr, "\nWARNING: Did not find any resources with a container that has image name %q\n\n", imageName)
	}

	return nil
}