github.com/tickoalcantara12/micro/v3@v3.0.0-20221007104245-9d75b9bcbab9/profile/profile.go (about) 1 // Package profile is for specific profiles 2 // @todo this package is the definition of cruft and 3 // should be rewritten in a more elegant way 4 package profile 5 6 import ( 7 "fmt" 8 "os" 9 "path/filepath" 10 11 "github.com/tickoalcantara12/micro/v3/service/auth/jwt" 12 "github.com/tickoalcantara12/micro/v3/service/auth/noop" 13 "github.com/tickoalcantara12/micro/v3/service/broker" 14 memBroker "github.com/tickoalcantara12/micro/v3/service/broker/memory" 15 "github.com/tickoalcantara12/micro/v3/service/build/golang" 16 "github.com/tickoalcantara12/micro/v3/service/client" 17 grpcClient "github.com/tickoalcantara12/micro/v3/service/client/grpc" 18 "github.com/tickoalcantara12/micro/v3/service/config" 19 storeConfig "github.com/tickoalcantara12/micro/v3/service/config/store" 20 evStore "github.com/tickoalcantara12/micro/v3/service/events/store" 21 memStream "github.com/tickoalcantara12/micro/v3/service/events/stream/memory" 22 "github.com/tickoalcantara12/micro/v3/service/logger" 23 "github.com/tickoalcantara12/micro/v3/service/model" 24 "github.com/tickoalcantara12/micro/v3/service/registry" 25 "github.com/tickoalcantara12/micro/v3/service/registry/memory" 26 "github.com/tickoalcantara12/micro/v3/service/router" 27 k8sRouter "github.com/tickoalcantara12/micro/v3/service/router/kubernetes" 28 regRouter "github.com/tickoalcantara12/micro/v3/service/router/registry" 29 "github.com/tickoalcantara12/micro/v3/service/runtime/kubernetes" 30 "github.com/tickoalcantara12/micro/v3/service/runtime/local" 31 "github.com/tickoalcantara12/micro/v3/service/server" 32 grpcServer "github.com/tickoalcantara12/micro/v3/service/server/grpc" 33 "github.com/tickoalcantara12/micro/v3/service/store/file" 34 mem "github.com/tickoalcantara12/micro/v3/service/store/memory" 35 "github.com/tickoalcantara12/micro/v3/util/opentelemetry" 36 "github.com/tickoalcantara12/micro/v3/util/opentelemetry/jaeger" 37 "github.com/urfave/cli/v2" 38 39 microAuth "github.com/tickoalcantara12/micro/v3/service/auth" 40 microBuilder "github.com/tickoalcantara12/micro/v3/service/build" 41 microEvents "github.com/tickoalcantara12/micro/v3/service/events" 42 microRuntime "github.com/tickoalcantara12/micro/v3/service/runtime" 43 microStore "github.com/tickoalcantara12/micro/v3/service/store" 44 inAuth "github.com/tickoalcantara12/micro/v3/util/auth" 45 "github.com/tickoalcantara12/micro/v3/util/user" 46 ) 47 48 // profiles which when called will configure micro to run in that environment 49 var profiles = map[string]*Profile{ 50 // built in profiles 51 "client": Client, 52 "service": Service, 53 "server": Server, 54 "test": Test, 55 "local": Local, 56 "kubernetes": Kubernetes, 57 } 58 59 // Profile configures an environment 60 type Profile struct { 61 // name of the profile 62 Name string 63 // function used for setup 64 Setup func(*cli.Context) error 65 // TODO: presetup dependencies 66 // e.g start resources 67 } 68 69 // Register a profile 70 func Register(name string, p *Profile) error { 71 if _, ok := profiles[name]; ok { 72 return fmt.Errorf("profile %s already exists", name) 73 } 74 profiles[name] = p 75 return nil 76 } 77 78 // Load a profile 79 func Load(name string) (*Profile, error) { 80 v, ok := profiles[name] 81 if !ok { 82 return nil, fmt.Errorf("profile %s does not exist", name) 83 } 84 return v, nil 85 } 86 87 // Client profile is for any entrypoint that behaves as a client 88 var Client = &Profile{ 89 Name: "client", 90 Setup: func(ctx *cli.Context) error { return nil }, 91 } 92 93 // Local profile to run as a single process 94 var Local = &Profile{ 95 Name: "local", 96 Setup: func(ctx *cli.Context) error { 97 // set client/server 98 client.DefaultClient = grpcClient.NewClient() 99 server.DefaultServer = grpcServer.NewServer() 100 101 microAuth.DefaultAuth = jwt.NewAuth() 102 microStore.DefaultStore = file.NewStore(file.WithDir(filepath.Join(user.Dir, "server", "store"))) 103 SetupConfigSecretKey(ctx) 104 config.DefaultConfig, _ = storeConfig.NewConfig(microStore.DefaultStore, "") 105 106 SetupJWT(ctx) 107 SetupRegistry(memory.NewRegistry()) 108 SetupBroker(memBroker.NewBroker()) 109 110 // set the store in the model 111 model.DefaultModel = model.NewModel( 112 model.WithStore(microStore.DefaultStore), 113 ) 114 115 microRuntime.DefaultRuntime = local.NewRuntime() 116 117 var err error 118 microEvents.DefaultStream, err = memStream.NewStream() 119 if err != nil { 120 logger.Fatalf("Error configuring stream: %v", err) 121 } 122 microEvents.DefaultStore = evStore.NewStore( 123 evStore.WithStore(microStore.DefaultStore), 124 ) 125 126 microStore.DefaultBlobStore, err = file.NewBlobStore() 127 if err != nil { 128 logger.Fatalf("Error configuring file blob store: %v", err) 129 } 130 131 return nil 132 }, 133 } 134 135 // Kubernetes profile to run on kubernetes with zero deps. Designed for use with the micro helm chart 136 var Kubernetes = &Profile{ 137 Name: "kubernetes", 138 Setup: func(ctx *cli.Context) (err error) { 139 microAuth.DefaultAuth = jwt.NewAuth() 140 SetupJWT(ctx) 141 142 microRuntime.DefaultRuntime = kubernetes.NewRuntime() 143 microBuilder.DefaultBuilder, err = golang.NewBuilder() 144 if err != nil { 145 logger.Fatalf("Error configuring golang builder: %v", err) 146 } 147 148 microEvents.DefaultStream, err = memStream.NewStream() 149 if err != nil { 150 logger.Fatalf("Error configuring stream: %v", err) 151 } 152 153 microStore.DefaultStore = file.NewStore(file.WithDir("/store")) 154 microStore.DefaultBlobStore, err = file.NewBlobStore(file.WithDir("/store/blob")) 155 if err != nil { 156 logger.Fatalf("Error configuring file blob store: %v", err) 157 } 158 159 // set the store in the model 160 model.DefaultModel = model.NewModel( 161 model.WithStore(microStore.DefaultStore), 162 ) 163 164 // the registry service uses the memory registry, the other core services will use the default 165 // rpc client and call the registry service 166 if ctx.Args().Get(1) == "registry" { 167 SetupRegistry(memory.NewRegistry()) 168 } 169 170 // the broker service uses the memory broker, the other core services will use the default 171 // rpc client and call the broker service 172 if ctx.Args().Get(1) == "broker" { 173 SetupBroker(memBroker.NewBroker()) 174 } 175 176 config.DefaultConfig, err = storeConfig.NewConfig(microStore.DefaultStore, "") 177 if err != nil { 178 logger.Fatalf("Error configuring config: %v", err) 179 } 180 SetupConfigSecretKey(ctx) 181 182 // Use k8s routing which is DNS based 183 router.DefaultRouter = k8sRouter.NewRouter() 184 client.DefaultClient.Init(client.Router(router.DefaultRouter)) 185 186 // Configure tracing with Jaeger: 187 tracingServiceName := ctx.Args().Get(1) 188 if len(tracingServiceName) == 0 { 189 tracingServiceName = "Micro" 190 } 191 openTracer, _, err := jaeger.New( 192 opentelemetry.WithServiceName(tracingServiceName), 193 opentelemetry.WithTraceReporterAddress("localhost:6831"), 194 ) 195 if err != nil { 196 logger.Fatalf("Error configuring opentracing: %v", err) 197 } 198 opentelemetry.DefaultOpenTracer = openTracer 199 200 return nil 201 }, 202 } 203 204 var Server = &Profile{ 205 Name: "server", 206 Setup: func(ctx *cli.Context) error { 207 microAuth.DefaultAuth = jwt.NewAuth() 208 microStore.DefaultStore = file.NewStore(file.WithDir(filepath.Join(user.Dir, "server", "store"))) 209 SetupConfigSecretKey(ctx) 210 config.DefaultConfig, _ = storeConfig.NewConfig(microStore.DefaultStore, "") 211 SetupJWT(ctx) 212 213 // the registry service uses the memory registry, the other core services will use the default 214 // rpc client and call the registry service 215 if ctx.Args().Get(1) == "registry" { 216 SetupRegistry(memory.NewRegistry()) 217 } else { 218 // set the registry address 219 registry.DefaultRegistry.Init( 220 registry.Addrs("localhost:8000"), 221 ) 222 223 SetupRegistry(registry.DefaultRegistry) 224 } 225 226 // the broker service uses the memory broker, the other core services will use the default 227 // rpc client and call the broker service 228 if ctx.Args().Get(1) == "broker" { 229 SetupBroker(memBroker.NewBroker()) 230 } else { 231 broker.DefaultBroker.Init( 232 broker.Addrs("localhost:8003"), 233 ) 234 SetupBroker(broker.DefaultBroker) 235 } 236 237 // set the store in the model 238 model.DefaultModel = model.NewModel( 239 model.WithStore(microStore.DefaultStore), 240 ) 241 242 // use the local runtime, note: the local runtime is designed to run source code directly so 243 // the runtime builder should NOT be set when using this implementation 244 microRuntime.DefaultRuntime = local.NewRuntime() 245 246 var err error 247 microEvents.DefaultStream, err = memStream.NewStream() 248 if err != nil { 249 logger.Fatalf("Error configuring stream: %v", err) 250 } 251 microEvents.DefaultStore = evStore.NewStore( 252 evStore.WithStore(microStore.DefaultStore), 253 ) 254 255 microStore.DefaultBlobStore, err = file.NewBlobStore() 256 if err != nil { 257 logger.Fatalf("Error configuring file blob store: %v", err) 258 } 259 260 // Configure tracing with Jaeger (forced tracing): 261 tracingServiceName := ctx.Args().Get(1) 262 if len(tracingServiceName) == 0 { 263 tracingServiceName = "Micro" 264 } 265 openTracer, _, err := jaeger.New( 266 opentelemetry.WithServiceName(tracingServiceName), 267 opentelemetry.WithSamplingRate(1), 268 ) 269 if err != nil { 270 logger.Fatalf("Error configuring opentracing: %v", err) 271 } 272 opentelemetry.DefaultOpenTracer = openTracer 273 274 return nil 275 }, 276 } 277 278 // Service is the default for any services run 279 var Service = &Profile{ 280 Name: "service", 281 Setup: func(ctx *cli.Context) error { return nil }, 282 } 283 284 // Test profile is used for the go test suite 285 var Test = &Profile{ 286 Name: "test", 287 Setup: func(ctx *cli.Context) error { 288 microAuth.DefaultAuth = noop.NewAuth() 289 microStore.DefaultStore = mem.NewStore() 290 microStore.DefaultBlobStore, _ = file.NewBlobStore() 291 config.DefaultConfig, _ = storeConfig.NewConfig(microStore.DefaultStore, "") 292 SetupRegistry(memory.NewRegistry()) 293 // set the store in the model 294 model.DefaultModel = model.NewModel( 295 model.WithStore(microStore.DefaultStore), 296 ) 297 return nil 298 }, 299 } 300 301 // SetupRegistry configures the registry 302 func SetupRegistry(reg registry.Registry) { 303 registry.DefaultRegistry = reg 304 router.DefaultRouter = regRouter.NewRouter(router.Registry(reg)) 305 client.DefaultClient.Init(client.Registry(reg), client.Router(router.DefaultRouter)) 306 server.DefaultServer.Init(server.Registry(reg)) 307 } 308 309 // SetupBroker configures the broker 310 func SetupBroker(b broker.Broker) { 311 broker.DefaultBroker = b 312 client.DefaultClient.Init(client.Broker(b)) 313 server.DefaultServer.Init(server.Broker(b)) 314 } 315 316 // SetupJWT configures the default internal system rules 317 func SetupJWT(ctx *cli.Context) { 318 for _, rule := range inAuth.SystemRules { 319 if err := microAuth.DefaultAuth.Grant(rule); err != nil { 320 logger.Fatal("Error creating default rule: %v", err) 321 } 322 } 323 } 324 325 func SetupConfigSecretKey(ctx *cli.Context) { 326 key := ctx.String("config_secret_key") 327 if len(key) == 0 { 328 k, err := user.GetConfigSecretKey() 329 if err != nil { 330 logger.Fatal("Error getting config secret: %v", err) 331 } 332 os.Setenv("MICRO_CONFIG_SECRET_KEY", k) 333 } 334 }