001/* -*- mode: Java; c-basic-offset: 2; indent-tabs-mode: nil; coding: utf-8-unix -*-
002 *
003 * Copyright © 2017 MicroBean.
004 *
005 * Licensed under the Apache License, Version 2.0 (the "License");
006 * you may not use this file except in compliance with the License.
007 * You may obtain a copy of the License at
008 *
009 *     http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
014 * implied.  See the License for the specific language governing
015 * permissions and limitations under the License.
016 */
017package org.microbean.helm.maven;
018
019import java.util.Objects;
020
021import java.util.concurrent.Callable;
022import java.util.concurrent.Future;
023
024import hapi.release.ReleaseOuterClass.Release;
025
026import hapi.services.tiller.Tiller.RollbackReleaseRequest;
027import hapi.services.tiller.Tiller.RollbackReleaseResponse;
028
029import org.apache.maven.plugin.logging.Log;
030
031import org.apache.maven.plugins.annotations.Mojo;
032import org.apache.maven.plugins.annotations.Parameter;
033
034import org.microbean.helm.ReleaseManager;
035
036/**
037 * <a
038 * href="https://docs.helm.sh/using_helm/#helm-upgrade-and-helm-rollback-upgrading-a-release-and-recovering-on-failure">Rolls
039 * a release back</a> to a prior version.
040 *
041 * @author <a href="https://about.me/lairdnelson"
042 * target="_parent">Laird Nelson</a>
043 */
044@Mojo(name = "rollback")
045public class RollbackReleaseMojo extends AbstractForceableMutatingReleaseMojo {
046
047
048  /*
049   * Instance fields.
050   */
051
052
053  /**
054   * The version to roll back to.
055   */
056  @Parameter(required = true)
057  private Integer version;
058
059
060  /*
061   * Constructors.
062   */
063  
064
065  /**
066   * Creates a new {@link RollbackReleaseMojo}.
067   */
068  public RollbackReleaseMojo() {
069    super();
070  }
071
072
073  /*
074   * Instance methods.
075   */
076
077
078  /**
079   * {@inheritDoc}
080   *
081   * <p>This implementation <a
082   * href="https://docs.helm.sh/using_helm/#helm-upgrade-and-helm-rollback-upgrading-a-release-and-recovering-on-failure">rolls
083   * a named release back</a> to a {@linkplain #getVersion() prior
084   * version}.</p>
085   */
086  @Override
087  protected void execute(final Callable<ReleaseManager> releaseManagerCallable) throws Exception {
088    Objects.requireNonNull(releaseManagerCallable);
089    final Log log = this.getLog();
090    assert log != null;
091
092    final Integer version = this.getVersion();
093    if (version == null) {
094      throw new IllegalStateException("version was not specified");
095    }
096    
097    final RollbackReleaseRequest.Builder requestBuilder = RollbackReleaseRequest.newBuilder();
098    assert requestBuilder != null;
099
100    requestBuilder.setDisableHooks(this.getDisableHooks());
101    requestBuilder.setDryRun(this.getDryRun());
102    requestBuilder.setForce(this.getForce());
103    requestBuilder.setRecreate(this.getRecreate());
104
105    final String releaseName = this.getReleaseName();
106    if (releaseName != null) {
107      requestBuilder.setName(releaseName);
108    }
109    
110    requestBuilder.setTimeout(this.getTimeout());
111    requestBuilder.setVersion(version.intValue());
112    requestBuilder.setWait(this.getWait());
113
114    final ReleaseManager releaseManager = releaseManagerCallable.call();
115    if (releaseManager == null) {
116      throw new IllegalStateException("releaseManagerCallable.call() == null");
117    }
118
119    if (log.isInfoEnabled()) {
120      log.info("Rolling back release " + requestBuilder.getName());
121    }
122    final Future<RollbackReleaseResponse> rollbackReleaseResponseFuture = releaseManager.rollback(requestBuilder.build());
123    assert rollbackReleaseResponseFuture != null;
124    final RollbackReleaseResponse rollbackReleaseResponse = rollbackReleaseResponseFuture.get();
125    assert rollbackReleaseResponse != null;
126    if (log.isInfoEnabled()) {
127      final Release release = rollbackReleaseResponse.getRelease();
128      assert release != null;
129      log.info("Rolled back release " + release.getName());
130    }
131    
132  }
133
134  /**
135   * Returns the version of the release to roll back to.
136   *
137   * <p>This method may return {@code null}.</p>
138   *
139   * <p>Overrides of this method are permitted to return {@code null}.</p>
140   *
141   * @return the version of the release to roll back to, or {@code
142   * null}
143   *
144   * @see #setVersion(Integer)
145   */
146  public Integer getVersion() {
147    return this.version;
148  }
149
150  /**
151   * Sets the version of the release to roll back to.
152   *
153   * @param version the version to roll back to; must not be {@code
154   * null}
155   *
156   * @exception NullPointerException if {@code version} is {@code
157   * null}
158   *
159   * @see #getVersion()
160   */
161  public void setVersion(final Integer version) {
162    Objects.requireNonNull(version);
163    this.version = version;
164  }
165
166}