(obj runtime.Object, updatedAnnotations map[string]string, toRevision int64, dryRunStrategy cmdutil.DryRunStrategy)
| 97 | } |
| 98 | |
| 99 | func (r *DeploymentRollbacker) Rollback(obj runtime.Object, updatedAnnotations map[string]string, toRevision int64, dryRunStrategy cmdutil.DryRunStrategy) (string, error) { |
| 100 | if toRevision < 0 { |
| 101 | return "", revisionNotFoundErr(toRevision) |
| 102 | } |
| 103 | accessor, err := meta.Accessor(obj) |
| 104 | if err != nil { |
| 105 | return "", fmt.Errorf("failed to create accessor for kind %v: %s", obj.GetObjectKind(), err.Error()) |
| 106 | } |
| 107 | name := accessor.GetName() |
| 108 | namespace := accessor.GetNamespace() |
| 109 | |
| 110 | // TODO: Fix this after kubectl has been removed from core. It is not possible to convert the runtime.Object |
| 111 | // to the external appsv1 Deployment without round-tripping through an internal version of Deployment. We're |
| 112 | // currently getting rid of all internal versions of resources. So we specifically request the appsv1 version |
| 113 | // here. This follows the same pattern as for DaemonSet and StatefulSet. |
| 114 | deployment, err := r.c.AppsV1().Deployments(namespace).Get(context.TODO(), name, metav1.GetOptions{}) |
| 115 | if err != nil { |
| 116 | return "", fmt.Errorf("failed to retrieve Deployment %s: %v", name, err) |
| 117 | } |
| 118 | |
| 119 | rsForRevision, err := deploymentRevision(deployment, r.c, toRevision) |
| 120 | if err != nil { |
| 121 | return "", err |
| 122 | } |
| 123 | if dryRunStrategy == cmdutil.DryRunClient { |
| 124 | return printTemplate(&rsForRevision.Spec.Template) |
| 125 | } |
| 126 | if deployment.Spec.Paused { |
| 127 | return "", fmt.Errorf("you cannot rollback a paused deployment; resume it first with 'kubectl rollout resume' and try again") |
| 128 | } |
| 129 | |
| 130 | // Skip if the revision already matches current Deployment |
| 131 | if equalIgnoreHash(&rsForRevision.Spec.Template, &deployment.Spec.Template) { |
| 132 | return fmt.Sprintf("%s (current template already matches revision %d)", rollbackSkipped, toRevision), nil |
| 133 | } |
| 134 | |
| 135 | // remove hash label before patching back into the deployment |
| 136 | delete(rsForRevision.Spec.Template.Labels, appsv1.DefaultDeploymentUniqueLabelKey) |
| 137 | |
| 138 | // compute deployment annotations |
| 139 | annotations := map[string]string{} |
| 140 | for k := range annotationsToSkip { |
| 141 | if v, ok := deployment.Annotations[k]; ok { |
| 142 | annotations[k] = v |
| 143 | } |
| 144 | } |
| 145 | for k, v := range rsForRevision.Annotations { |
| 146 | if !annotationsToSkip[k] { |
| 147 | annotations[k] = v |
| 148 | } |
| 149 | } |
| 150 | |
| 151 | // make patch to restore |
| 152 | patchType, patch, err := getDeploymentPatch(&rsForRevision.Spec.Template, annotations) |
| 153 | if err != nil { |
| 154 | return "", fmt.Errorf("failed restoring revision %d: %v", toRevision, err) |
| 155 | } |
| 156 |
nothing calls this directly
no test coverage detected