github.com/koron/hk@v0.0.0-20150303213137-b8aeaa3ab34c/ssl.go (about)

     1  package main
     2  
     3  import (
     4  	"fmt"
     5  	"io/ioutil"
     6  	"os"
     7  	"strings"
     8  	"time"
     9  
    10  	"github.com/heroku/hk/Godeps/_workspace/src/github.com/bgentry/heroku-go"
    11  )
    12  
    13  var cmdSSL = &Command{
    14  	Run:      runSSL,
    15  	Usage:    "ssl",
    16  	NeedsApp: true,
    17  	Category: "ssl",
    18  	Short:    "show ssl endpoint info",
    19  	Long:     `Show SSL endpoint and certificate information.`,
    20  }
    21  
    22  func runSSL(cmd *Command, args []string) {
    23  	if len(args) != 0 {
    24  		cmd.PrintUsage()
    25  		os.Exit(2)
    26  	}
    27  	endpoints, err := client.SSLEndpointList(mustApp(), nil)
    28  	must(err)
    29  
    30  	if len(endpoints) == 0 {
    31  		return
    32  	}
    33  
    34  	chain, err := decodeCertChain(endpoints[0].CertificateChain)
    35  	must(err)
    36  
    37  	fmt.Println("Hostname:       ", endpoints[0].Cname)
    38  	fmt.Println("Common Name(s): ", strings.Join(chain.CommonNames(), ", "))
    39  	fmt.Println("Expires:        ", chain.Expires().UTC().Format(time.RFC3339))
    40  }
    41  
    42  var cmdSSLCertAdd = &Command{
    43  	Run:      runSSLCertAdd,
    44  	Usage:    "ssl-cert-add [-s] <certfile> <keyfile>",
    45  	NeedsApp: true,
    46  	Category: "ssl",
    47  	Short:    "add a new ssl cert",
    48  	Long: `
    49  Add a new SSL certificate to an app. An SSL endpoint will be
    50  created if the app doesn't yet have one. Otherwise, its cert will
    51  be updated.
    52  
    53  Options:
    54  
    55      -s  skip SSL cert optimization and pre-processing
    56  
    57  Examples:
    58  
    59      $ hk ssl-cert-add cert.pem key.pem
    60      hobby-dev        $0/mo
    61  `,
    62  }
    63  
    64  var (
    65  	skipCertPreprocess bool
    66  )
    67  
    68  func init() {
    69  	cmdSSLCertAdd.Flag.BoolVarP(&skipCertPreprocess, "skip-preprocess", "s", false, "skip SSL cert preprocessing")
    70  }
    71  
    72  func runSSLCertAdd(cmd *Command, args []string) {
    73  	if len(args) != 2 {
    74  		cmd.PrintUsage()
    75  		os.Exit(2)
    76  	}
    77  	appname := mustApp()
    78  
    79  	certb, err := ioutil.ReadFile(args[0])
    80  	if err != nil {
    81  		printFatal("reading certfile: %s", err.Error())
    82  	}
    83  	keyb, err := ioutil.ReadFile(args[1])
    84  	if err != nil {
    85  		printFatal("reading keyfile: %s", err.Error())
    86  	}
    87  
    88  	endpoints, err := client.SSLEndpointList(appname, nil)
    89  	must(err)
    90  
    91  	cert := string(certb)
    92  	key := string(keyb)
    93  
    94  	preprocess := !skipCertPreprocess
    95  
    96  	if len(endpoints) == 0 {
    97  		opts := heroku.SSLEndpointCreateOpts{Preprocess: &preprocess}
    98  		ep, err := client.SSLEndpointCreate(appname, cert, key, &opts)
    99  		must(err)
   100  		fmt.Printf("Added cert for %s at %s.\n", appname, ep.Cname)
   101  		return
   102  	}
   103  
   104  	opts := heroku.SSLEndpointUpdateOpts{
   105  		CertificateChain: &cert,
   106  		Preprocess:       &preprocess,
   107  		PrivateKey:       &key,
   108  	}
   109  	_, err = client.SSLEndpointUpdate(appname, endpoints[0].Id, &opts)
   110  	must(err)
   111  	fmt.Printf("Updated cert for %s at %s.\n", appname, endpoints[0].Cname)
   112  }
   113  
   114  var cmdSSLDestroy = &Command{
   115  	Run:      runSSLDestroy,
   116  	Usage:    "ssl-destroy",
   117  	NeedsApp: true,
   118  	Category: "ssl",
   119  	Short:    "destroy ssl endpoint",
   120  	Long: `
   121  Removes the SSL endpoints from an app along with all SSL
   122  certificates. If your app's DNS is still configured to point at
   123  the SSL endpoint, this may take your app offline. The command
   124  will prompt for confirmation, or accept confirmation via stdin.
   125  
   126  Examples:
   127  
   128      $ hk ssl-destroy
   129      warning: This will destroy the SSL endpoint on myapp. Please type "myapp" to continue:
   130      > myapp
   131      Destroyed SSL endpoint on myapp.
   132  
   133      $ echo myapp | hk ssl-destroy
   134      Destroyed SSL endpoint on myapp.
   135  `,
   136  }
   137  
   138  func runSSLDestroy(cmd *Command, args []string) {
   139  	if len(args) != 0 {
   140  		cmd.PrintUsage()
   141  		os.Exit(2)
   142  	}
   143  	appname := mustApp()
   144  
   145  	endpoints, err := client.SSLEndpointList(appname, nil)
   146  	must(err)
   147  
   148  	if len(endpoints) == 0 {
   149  		printFatal("App %s has no SSL endpoint to destroy.", appname)
   150  	}
   151  
   152  	warning := "This will destroy the SSL endpoint on %s. Please type %q to continue:"
   153  	mustConfirm(fmt.Sprintf(warning, appname, appname), appname)
   154  
   155  	err = client.SSLEndpointDelete(appname, endpoints[0].Id)
   156  	must(err)
   157  	fmt.Printf("Destroyed SSL endpoint on %s.\n", appname)
   158  }
   159  
   160  var cmdSSLCertRollback = &Command{
   161  	Run:      runSSLCertRollback,
   162  	Usage:    "ssl-cert-rollback",
   163  	NeedsApp: true,
   164  	Category: "ssl",
   165  	Short:    "add a new ssl cert",
   166  	Long: `
   167  Rolls back an SSL endpoint's certificate to the previous version.
   168  
   169  Examples:
   170  
   171      $ hk ssl-cert-rollback
   172      Rolled back cert for myapp.
   173  `,
   174  }
   175  
   176  func runSSLCertRollback(cmd *Command, args []string) {
   177  	if len(args) != 0 {
   178  		cmd.PrintUsage()
   179  		os.Exit(2)
   180  	}
   181  	appname := mustApp()
   182  
   183  	endpoints, err := client.SSLEndpointList(appname, nil)
   184  	must(err)
   185  
   186  	if len(endpoints) == 0 {
   187  		printFatal("App %s has no SSL endpoint to rollback.", appname)
   188  	}
   189  
   190  	t := true
   191  	opts := heroku.SSLEndpointUpdateOpts{Rollback: &t}
   192  	_, err = client.SSLEndpointUpdate(appname, endpoints[0].Id, &opts)
   193  	must(err)
   194  	fmt.Printf("Rolled back cert for %s.\n", appname)
   195  }