github.com/lmb/consul@v1.4.1/command/tls/ca/create/tls_ca_create.go (about)

     1  package create
     2  
     3  import (
     4  	"flag"
     5  	"fmt"
     6  	"os"
     7  
     8  	"github.com/hashicorp/consul/command/flags"
     9  	"github.com/hashicorp/consul/command/tls"
    10  	"github.com/mitchellh/cli"
    11  )
    12  
    13  func New(ui cli.Ui) *cmd {
    14  	c := &cmd{UI: ui}
    15  	c.init()
    16  	return c
    17  }
    18  
    19  type cmd struct {
    20  	UI                    cli.Ui
    21  	flags                 *flag.FlagSet
    22  	help                  string
    23  	days                  int
    24  	domain                string
    25  	constraint            bool
    26  	additionalConstraints flags.AppendSliceValue
    27  }
    28  
    29  func (c *cmd) init() {
    30  	c.flags = flag.NewFlagSet("", flag.ContinueOnError)
    31  	c.flags.IntVar(&c.days, "days", 1825, "Provide number of days the CA is valid for from now on. Defaults to 5 years.")
    32  	c.flags.BoolVar(&c.constraint, "name-constraint", false, "Add name constraints for the CA. Results in rejecting "+
    33  		"certificates for other DNS than specified. If turned on localhost and -domain will be added to the allowed "+
    34  		"DNS. If the UI is going to be served over HTTPS its DNS has to be added with -additional-constraint. It is not "+
    35  		"possible to add that after the fact! Defaults to false.")
    36  	c.flags.StringVar(&c.domain, "domain", "consul", "Domain of consul cluster. Only used in combination with -name-constraint. Defaults to consul.")
    37  	c.flags.Var(&c.additionalConstraints, "additional-name-constraint", "Add name constraints for the CA. Results in rejecting certificates "+
    38  		"for other DNS than specified. Can be used multiple times. Only used in combination with -name-constraint.")
    39  	c.help = flags.Usage(help, c.flags)
    40  }
    41  
    42  func (c *cmd) Run(args []string) int {
    43  	if err := c.flags.Parse(args); err != nil {
    44  		if err == flag.ErrHelp {
    45  			return 0
    46  		}
    47  		c.UI.Error(fmt.Sprintf("Failed to parse args: %v", err))
    48  		return 1
    49  	}
    50  
    51  	certFileName := fmt.Sprintf("%s-agent-ca.pem", c.domain)
    52  	pkFileName := fmt.Sprintf("%s-agent-ca-key.pem", c.domain)
    53  
    54  	if !(tls.FileDoesNotExist(certFileName)) {
    55  		c.UI.Error(certFileName + " already exists.")
    56  		return 1
    57  	}
    58  	if !(tls.FileDoesNotExist(pkFileName)) {
    59  		c.UI.Error(pkFileName + " already exists.")
    60  		return 1
    61  	}
    62  
    63  	sn, err := tls.GenerateSerialNumber()
    64  	if err != nil {
    65  		c.UI.Error(err.Error())
    66  		return 1
    67  	}
    68  	s, pk, err := tls.GeneratePrivateKey()
    69  	if err != nil {
    70  		c.UI.Error(err.Error())
    71  	}
    72  	constraints := []string{}
    73  	if c.constraint {
    74  		constraints = append(c.additionalConstraints, []string{c.domain, "localhost"}...)
    75  	}
    76  	ca, err := tls.GenerateCA(s, sn, c.days, constraints)
    77  	if err != nil {
    78  		c.UI.Error(err.Error())
    79  	}
    80  	caFile, err := os.Create(certFileName)
    81  	if err != nil {
    82  		c.UI.Error(err.Error())
    83  	}
    84  	caFile.WriteString(ca)
    85  	c.UI.Output("==> Saved " + certFileName)
    86  	pkFile, err := os.Create(pkFileName)
    87  	if err != nil {
    88  		c.UI.Error(err.Error())
    89  	}
    90  	pkFile.WriteString(pk)
    91  	c.UI.Output("==> Saved " + pkFileName)
    92  
    93  	return 0
    94  }
    95  
    96  func (c *cmd) Synopsis() string {
    97  	return synopsis
    98  }
    99  
   100  func (c *cmd) Help() string {
   101  	return c.help
   102  }
   103  
   104  const synopsis = "Create a new consul CA"
   105  const help = `
   106  Usage: consul tls ca create [options]
   107  
   108    Create a new consul CA:
   109  
   110    $ consul tls ca create
   111    ==> saved consul-agent-ca.pem
   112    ==> saved consul-agent-ca-key.pem
   113  `