github.com/marwan-at-work/consul@v1.4.5/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  	// TODO: perhaps add a -years arg to better capture user intent given that leap years are a thing
    32  	c.flags.IntVar(&c.days, "days", 1825, "Provide number of days the CA is valid for from now on. Defaults to 5 years.")
    33  	c.flags.BoolVar(&c.constraint, "name-constraint", false, "Add name constraints for the CA. Results in rejecting "+
    34  		"certificates for other DNS than specified. If turned on localhost and -domain will be added to the allowed "+
    35  		"DNS. If the UI is going to be served over HTTPS its DNS has to be added with -additional-constraint. It is not "+
    36  		"possible to add that after the fact! Defaults to false.")
    37  	c.flags.StringVar(&c.domain, "domain", "consul", "Domain of consul cluster. Only used in combination with -name-constraint. Defaults to consul.")
    38  	c.flags.Var(&c.additionalConstraints, "additional-name-constraint", "Add name constraints for the CA. Results in rejecting certificates "+
    39  		"for other DNS than specified. Can be used multiple times. Only used in combination with -name-constraint.")
    40  	c.help = flags.Usage(help, c.flags)
    41  }
    42  
    43  func (c *cmd) Run(args []string) int {
    44  	if err := c.flags.Parse(args); err != nil {
    45  		if err == flag.ErrHelp {
    46  			return 0
    47  		}
    48  		c.UI.Error(fmt.Sprintf("Failed to parse args: %v", err))
    49  		return 1
    50  	}
    51  
    52  	certFileName := fmt.Sprintf("%s-agent-ca.pem", c.domain)
    53  	pkFileName := fmt.Sprintf("%s-agent-ca-key.pem", c.domain)
    54  
    55  	if !(tls.FileDoesNotExist(certFileName)) {
    56  		c.UI.Error(certFileName + " already exists.")
    57  		return 1
    58  	}
    59  	if !(tls.FileDoesNotExist(pkFileName)) {
    60  		c.UI.Error(pkFileName + " already exists.")
    61  		return 1
    62  	}
    63  
    64  	sn, err := tls.GenerateSerialNumber()
    65  	if err != nil {
    66  		c.UI.Error(err.Error())
    67  		return 1
    68  	}
    69  	s, pk, err := tls.GeneratePrivateKey()
    70  	if err != nil {
    71  		c.UI.Error(err.Error())
    72  	}
    73  	constraints := []string{}
    74  	if c.constraint {
    75  		constraints = append(c.additionalConstraints, []string{c.domain, "localhost"}...)
    76  	}
    77  	ca, err := tls.GenerateCA(s, sn, c.days, constraints)
    78  	if err != nil {
    79  		c.UI.Error(err.Error())
    80  	}
    81  	caFile, err := os.Create(certFileName)
    82  	if err != nil {
    83  		c.UI.Error(err.Error())
    84  	}
    85  	caFile.WriteString(ca)
    86  	c.UI.Output("==> Saved " + certFileName)
    87  	pkFile, err := os.Create(pkFileName)
    88  	if err != nil {
    89  		c.UI.Error(err.Error())
    90  	}
    91  	pkFile.WriteString(pk)
    92  	c.UI.Output("==> Saved " + pkFileName)
    93  
    94  	return 0
    95  }
    96  
    97  func (c *cmd) Synopsis() string {
    98  	return synopsis
    99  }
   100  
   101  func (c *cmd) Help() string {
   102  	return c.help
   103  }
   104  
   105  const synopsis = "Create a new consul CA"
   106  const help = `
   107  Usage: consul tls ca create [options]
   108  
   109    Create a new consul CA:
   110  
   111    $ consul tls ca create
   112    ==> saved consul-agent-ca.pem
   113    ==> saved consul-agent-ca-key.pem
   114  `