github.com/projectcontour/contour@v1.28.2/cmd/contour/contour.go (about)

     1  // Copyright Project Contour Authors
     2  // Licensed under the Apache License, Version 2.0 (the "License");
     3  // you may not use this file except in compliance with the License.
     4  // You may obtain a copy of the License at
     5  //
     6  //     http://www.apache.org/licenses/LICENSE-2.0
     7  //
     8  // Unless required by applicable law or agreed to in writing, software
     9  // distributed under the License is distributed on an "AS IS" BASIS,
    10  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    11  // See the License for the specific language governing permissions and
    12  // limitations under the License.
    13  
    14  package main
    15  
    16  import (
    17  	"os"
    18  
    19  	"go.uber.org/automaxprocs/maxprocs"
    20  
    21  	"github.com/alecthomas/kingpin/v2"
    22  	resource_v3 "github.com/envoyproxy/go-control-plane/pkg/resource/v3"
    23  	"github.com/projectcontour/contour/internal/build"
    24  	"github.com/projectcontour/contour/internal/envoy"
    25  	envoy_v3 "github.com/projectcontour/contour/internal/envoy/v3"
    26  	"github.com/projectcontour/contour/internal/k8s"
    27  	"github.com/sirupsen/logrus"
    28  )
    29  
    30  func main() {
    31  	log := logrus.StandardLogger()
    32  	k8s.InitLogging(k8s.LogWriterOption(log.WithField("context", "kubernetes")))
    33  
    34  	// set GOMAXPROCS
    35  	_, err := maxprocs.Set(maxprocs.Logger(log.Printf))
    36  	if err != nil {
    37  		log.WithError(err).Error("failed to set GOMAXPROCS")
    38  	}
    39  
    40  	// NOTE: when add a new subcommand, we'll have to remember to add it to 'TestOptionFlagsAreSorted'
    41  	// to ensure the option flags in lexicographic order.
    42  
    43  	app := kingpin.New("contour", "Contour Kubernetes ingress controller.")
    44  	app.HelpFlag.Short('h')
    45  
    46  	// Log-format applies to log format of all sub-commands.
    47  	logFormat := app.Flag("log-format", "Log output format for Contour. Either text or json.").Default("text").Enum("text", "json")
    48  
    49  	bootstrap, bootstrapCtx := registerBootstrap(app)
    50  
    51  	certgenApp, certgenConfig := registerCertGen(app)
    52  
    53  	cli, client := registerCli(app, log)
    54  
    55  	var resources []string
    56  	cds := cli.Command("cds", "Watch services.")
    57  	cds.Arg("resources", "CDS resource filter").StringsVar(&resources)
    58  
    59  	eds := cli.Command("eds", "Watch endpoints.")
    60  	eds.Arg("resources", "EDS resource filter").StringsVar(&resources)
    61  
    62  	lds := cli.Command("lds", "Watch listeners.")
    63  	lds.Arg("resources", "LDS resource filter").StringsVar(&resources)
    64  
    65  	rds := cli.Command("rds", "Watch routes.")
    66  	rds.Arg("resources", "RDS resource filter").StringsVar(&resources)
    67  
    68  	sds := cli.Command("sds", "Watch secrets.")
    69  	sds.Arg("resources", "SDS resource filter").StringsVar(&resources)
    70  
    71  	envoyCmd := app.Command("envoy", "Sub-command for envoy actions.")
    72  
    73  	// Add a "shutdown" command which initiates an Envoy shutdown sequence.
    74  	sdmShutdown, sdmShutdownCtx := registerShutdown(envoyCmd, log)
    75  
    76  	sdm, shutdownManagerCtx := registerShutdownManager(envoyCmd, log)
    77  
    78  	gatewayProvisioner, gatewayProvisionerConfig := registerGatewayProvisioner(app)
    79  
    80  	serve, serveCtx := registerServe(app)
    81  	version := app.Command("version", "Build information for Contour.")
    82  
    83  	args := os.Args[1:]
    84  	cmd := kingpin.MustParse(app.Parse(args))
    85  
    86  	switch *logFormat {
    87  	case "text":
    88  		log.SetFormatter(&logrus.TextFormatter{})
    89  	case "json":
    90  		log.SetFormatter(&logrus.JSONFormatter{})
    91  	}
    92  
    93  	switch cmd {
    94  	case gatewayProvisioner.FullCommand():
    95  		runGatewayProvisioner(gatewayProvisionerConfig)
    96  	case sdm.FullCommand():
    97  		doShutdownManager(shutdownManagerCtx)
    98  	case sdmShutdown.FullCommand():
    99  		sdmShutdownCtx.shutdownHandler()
   100  	case bootstrap.FullCommand():
   101  		if err := bootstrapCtx.XDSResourceVersion.Validate(); err != nil {
   102  			log.WithError(err).Fatal("failed to parse bootstrap args")
   103  		}
   104  		if err := envoy.ValidAdminAddress(bootstrapCtx.AdminAddress); err != nil {
   105  			log.WithField("flag", "--admin-address").WithError(err).Fatal("failed to parse bootstrap args")
   106  		}
   107  		if err := envoy_v3.WriteBootstrap(bootstrapCtx); err != nil {
   108  			log.WithError(err).Fatal("failed to write bootstrap configuration")
   109  		}
   110  	case certgenApp.FullCommand():
   111  		doCertgen(certgenConfig, log)
   112  	case cds.FullCommand():
   113  		if client.Delta {
   114  			stream := client.DeltaClusterStream()
   115  			watchDeltaStream(log, stream, resource_v3.ClusterType, resources, client.Nack, client.NodeID)
   116  		} else {
   117  			stream := client.ClusterStream()
   118  			watchstream(log, stream, resource_v3.ClusterType, resources, client.Nack, client.NodeID)
   119  		}
   120  	case eds.FullCommand():
   121  		if client.Delta {
   122  			stream := client.DeltaEndpointStream()
   123  			watchDeltaStream(log, stream, resource_v3.EndpointType, resources, client.Nack, client.NodeID)
   124  		} else {
   125  			stream := client.EndpointStream()
   126  			watchstream(log, stream, resource_v3.EndpointType, resources, client.Nack, client.NodeID)
   127  		}
   128  	case lds.FullCommand():
   129  		if client.Delta {
   130  			stream := client.DeltaListenerStream()
   131  			watchDeltaStream(log, stream, resource_v3.ListenerType, resources, client.Nack, client.NodeID)
   132  		} else {
   133  			stream := client.ListenerStream()
   134  			watchstream(log, stream, resource_v3.ListenerType, resources, client.Nack, client.NodeID)
   135  		}
   136  	case rds.FullCommand():
   137  		if client.Delta {
   138  			stream := client.DeltaRouteStream()
   139  			watchDeltaStream(log, stream, resource_v3.RouteType, resources, client.Nack, client.NodeID)
   140  		} else {
   141  			stream := client.RouteStream()
   142  			watchstream(log, stream, resource_v3.RouteType, resources, client.Nack, client.NodeID)
   143  		}
   144  	case sds.FullCommand():
   145  		if client.Delta {
   146  			stream := client.DeltaRouteStream()
   147  			watchDeltaStream(log, stream, resource_v3.SecretType, resources, client.Nack, client.NodeID)
   148  		} else {
   149  			stream := client.RouteStream()
   150  			watchstream(log, stream, resource_v3.SecretType, resources, client.Nack, client.NodeID)
   151  		}
   152  	case serve.FullCommand():
   153  		// Parse args a second time so cli flags are applied
   154  		// on top of any values sourced from -c's config file.
   155  		kingpin.MustParse(app.Parse(args))
   156  
   157  		if serveCtx.Config.Debug {
   158  			log.SetLevel(logrus.DebugLevel)
   159  		}
   160  
   161  		// Reinitialize with the target debug level.
   162  		k8s.InitLogging(
   163  			k8s.LogWriterOption(log.WithField("context", "kubernetes")),
   164  			k8s.LogLevelOption(int(serveCtx.KubernetesDebug)),
   165  		)
   166  
   167  		log.Infof("args: %v", args)
   168  
   169  		// Validate the result of applying the command-line
   170  		// flags on top of the config file.
   171  		if err := serveCtx.Config.Validate(); err != nil {
   172  			log.WithError(err).Fatal("invalid configuration")
   173  		}
   174  
   175  		// Build out serve deps.
   176  		serve, err := NewServer(log, serveCtx)
   177  		if err != nil {
   178  			log.WithError(err).Fatal("unable to initialize Server dependencies required to start Contour")
   179  		}
   180  
   181  		if err := serve.doServe(); err != nil {
   182  			log.WithError(err).Fatal("Contour server failed")
   183  		}
   184  	case version.FullCommand():
   185  		println(build.PrintBuildInfo())
   186  	default:
   187  		app.Usage(args)
   188  		os.Exit(2)
   189  	}
   190  }