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 }