func (dg *defaultGenerator) Generate(pathToServiceDir string) { // Open file that we will write all content to output, err := os.OpenFile(dg.outputFile, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600) if err != nil { log.Fatalf("Could not open output file: %s", err) } defer func() { err := output.Close() if err != nil { log.Fatal("Could not close file!", err) } }() files, err := ioutil.ReadDir(pathToServiceDir) if err != nil { log.Fatalf("Could not read dir: %s", pathToServiceDir) } for _, f := range files { err = dg.visit(pathToServiceDir, f) if err != nil { log.Fatalf("Error while parsing: %s/%s", pathToServiceDir, f.Name()) } } if err != nil { log.Fatalf("Error while iterating over directory: %s", err) } if err := codegen.Render(output, dg.tpl, dg.vm); err != nil { log.Fatalf("Could not render code: %s", err) } }
func (dg *defaultGenerator) Generate(pathToServices []string) { // Open file that we will write all content to output, err := os.OpenFile(dg.outputFile, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600) if err != nil { log.Fatalf("Could not open output file: %s", err) } defer func() { err := output.Close() if err != nil { log.Fatal("Could not close file!", err) } }() lookup := map[string]bool{} for _, servicePath := range pathToServices { if _, ok := lookup[servicePath]; ok { continue } lookup[servicePath] = true dg.vm.Services = append(dg.vm.Services, codegen.Service{ Import: codegen.Import{ Alias: "", Path: servicePath, }, }) } dg.vm.RoutesNum = len(lookup) if err := codegen.Render(output, dg.tpl, dg.vm); err != nil { log.Fatalf("Could not render code: %s", err) } }
// GenerateReplicationControllers renders k8s ReplicationControllers func GenerateReplicationControllers(outputFile string, rcvm RCViewModel) { basePath := filepath.Dir(outputFile) ok := utils.Exists(basePath) if !ok { if err := os.Mkdir(basePath, 0777); err != nil { log.Fatalf("Could not make dir, %s", err) } } // Open file that we will write all content to output, err := os.OpenFile(outputFile, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600) if err != nil { log.Fatalf("Could not open output file: %s", err) } defer func() { err := output.Close() if err != nil { log.Fatal("Could not close file!", err) } }() if err := codegen.Render(output, string(ReplicationControllerTemplate), rcvm); err != nil { log.Fatalf("Could not render replication controller: %s", err) } }
func makeDefaultGenerator(tpl, outputPath string) *defaultGenerator { outputPath = strings.TrimRight(outputPath, "/") outputPath = outputPath + string(filepath.Separator) + "gen" ok := utils.Exists(outputPath) if !ok { if err := os.Mkdir(outputPath, 0777); err != nil { log.Fatalf("Could not make dir, %s", err) } } outputFile := outputPath + string(filepath.Separator) + FILE_NAME_INIT return &defaultGenerator{ tpl: tpl, outputFile: outputFile, vm: &viewModel{ PackageName: "gen", Imports: codegen.Imports{ "github.com/nildev/lib/router": codegen.Import{ Alias: "", Path: "github.com/nildev/lib/router", }, }, Services: codegen.Services{}, }, } }
// Generate required integration code func Generate(pathToServiceDir, tplName, tplOrg, tplVer, basePattern string) { gopath := os.Getenv("GOPATH") if gopath == "" { log.Fatalf("GOPATH is not set") } rootDir := gopath + string(filepath.Separator) + "src" + string(filepath.Separator) + pathToServiceDir tplLoader := template.NewGoPathLoader() tplData, err := tplLoader.Load(tplOrg, tplName, tplVer) if err != nil { log.Fatalf("Could not load template [%s][%s][%s]", tplOrg, tplName, tplVer) } g := makeDefaultGenerator(string(tplData), rootDir, basePattern) g.Generate(rootDir) }
func main() { var ndState state.State var buildDir string var env string app := cli.NewApp() app.Name = "nildev" app.Usage = "Tool for code generation" app.EnableBashCompletion = true app.Version = "0.1.0" app.Flags = []cli.Flag{ cli.IntFlag{ Name: "verbosity", Value: 1, Usage: "logging level", }, cli.StringFlag{ Name: "buildDir", Value: "", Usage: "path to secrets file", Destination: &buildDir, }, cli.StringFlag{ Name: "env", Value: "dev", Usage: "environment for deployment", Destination: &env, }, } app.Before = func(c *cli.Context) error { ndState = state.Load() if buildDir == "" { buildDir = DefaultBuildDir } // setup logging here return nil } app.Commands = []cli.Command{ // { // Name: "services", // Usage: "manage service on nildev.io", // Action: func(c *cli.Context) {}, // Subcommands: []cli.Command{ //// { //// // go run nildev.go services search *account* //// Name: "search", //// Usage: "search for required service", //// Flags: []cli.Flag{}, //// Action: func(c *cli.Context) { //// // look up in nildev.services registry if we have it //// }, //// }, // // { // // // go run nildev.go services run github.com/nildev/account ... // // Name: "run", // // Usage: "setup and run services", // // Flags: []cli.Flag{ // // cli.StringFlag{ // // Name: "machine", // // Value: "", // // Usage: "docker-machine name to be used to run service", // // }, // // }, // // Action: func(c *cli.Context) { // // // machineName := c.String("machine") // // // // // // plt, err := services.MakeDockerComposePlatform(buildDir, env, machineName) // // // if err != nil { // // // log.Fatalf("Could not setup services, [%s]", err) // // // } // // // // // // names := []services.Name{} // // // for _, name := range c.Args() { // // // names = append(names, services.Name(name)) // // // } // // // // // // err = plt.(services.Platform).Setup(names...) // // // if err != nil { // // // log.Fatalf("Could not setup services, [%s]", err) // // // } // // // err = plt.(services.Platform).Run(names...) // // // if err != nil { // // // log.Fatalf("Could not run services, [%s]", err) // // // } // // }, // // }, // // { // // // go run nildev.go services remove github.com/nildev/account ... // // Name: "remove", // // Usage: "remove services", // // Flags: []cli.Flag{}, // // Action: func(c *cli.Context) { // // // remove whole service // // }, // }, // { // // go run nildev.go services register github.com/your_org/your_service // Name: "register", // Usage: "register your service to nildev.service registry", // Flags: []cli.Flag{}, // Action: func(c *cli.Context) { // // register manually your service // }, // }, // { // // go run nildev.go services deploy --secrets secrets.json --env env.json --services services.json // Name: "deploy", // Usage: "manage service on nildev.io. As argument spcific servie names can be passed to be launched from service.json", // Flags: []cli.Flag{ // cli.StringFlag{ // Name: "secrets", // Value: "secrets.json", // Usage: "path to secrets file", // }, // cli.StringFlag{ // Name: "env", // Value: "env.json", // Usage: "path to env file", // }, // cli.StringFlag{ // Name: "services", // Value: "services.json", // Usage: "path to services file", // }, // cli.StringFlag{ // Name: "platform", // Value: "kubernetes", // Usage: "platform to be used, avail options: kubernetes", // }, // }, // Action: func(c *cli.Context) { // pathToServicesFile := c.String("services") // pathToSecretsFile := c.String("secrets") // pathToEnvFile := c.String("env") // platform := c.String("platform") // // plt, err := services.MakePlatform(platform, buildDir, env, pathToServicesFile, pathToSecretsFile, pathToEnvFile) // if err != nil { // log.Fatalf("Could not setup services, [%s]", err) // } // // names := []services.Name{} // for _, name := range c.Args() { // names = append(names, services.Name(name)) // } // // err = plt.Setup(names...) // if err != nil { // log.Fatalf("Could not setup services, [%s]", err) // } // err = plt.Run(names...) // if err != nil { // log.Fatalf("Could not run services, [%s]", err) // } // }, // }, // }, // { // // go run nildev.go auth --provider=bitbucket.org // Name: "auth", // Usage: "authenticate yourself by using one of supported providers: bitbucket|github", // Flags: []cli.Flag{ // cli.StringFlag{ // Name: "provider", // Value: "bitbucket.org", // Usage: "provider: bitbucket.org", // }, // }, // Action: func(c *cli.Context) { // ndState.Token = string(auth.Auth(c.String("provider"))) // ndState.Provider = c.String("provider") // // state.Persist(ndState) // }, // }, { // go run nildev.go create --config config.json github.com/nildev/echo Name: "create", Usage: "create new project in $GOPATH/src/ based on selected template.\nFirst argument should be path to project, for example github.com/your_username/project", Flags: []cli.Flag{ cli.StringFlag{ Name: "template", Value: "[email protected]:nildev/prj-tpl-basic-api.git", Usage: "git repository to be used as template. If it is private repo make sure you have key added: ssh-add ~/.ssh/your_key", }, cli.StringFlag{ Name: "config", Value: "config.json", Usage: "path to json file with values that will replace variables in project template", }, }, Action: func(c *cli.Context) { pathToGoSrc := os.Getenv("GOPATH") if pathToGoSrc == "" { log.Fatalf("$GOPATH env is empty ? Do you have golang development environment setup ?") } pathToGoSrc += "/src" if len(c.Args()) == 0 { log.Fatalf("Please provide path to project, for example: github.com/your_username/repo_name|bitbucket.org/your_username/repo_name") } if c.String("config") == "" { log.Fatalf("Please provide path to config") } if c.String("template") == "" { log.Fatalf("Please provide path to project template git repository, for example [email protected]:nildev/prj-tpl-basic-api.git") } init := setup.NewInitializer() cfgLoader := setup.NewConfigLoader(c.String("config")) cfg := cfgLoader.Read(c.String("config")) destDir := pathToGoSrc + string(filepath.Separator) + c.Args()[0] init.Setup(cfg, destDir, c.String("template")) }, }, { // go run nildev.go build bitbucket.org/nildev/account // 1. build container and push it so it would have to be only deployed, also used for local testing // 2. push request to be deployed on nildev.io remote infrastructure Name: "build", Aliases: []string{"b"}, Usage: "build project", Flags: []cli.Flag{ cli.StringFlag{ Name: "registry", Value: "", Usage: "registry where to push image, for example quay.io. By default docker hub registry is used, which equals to empty string", }, }, Action: func(c *cli.Context) { pathToGoSrc := os.Getenv("GOPATH") if pathToGoSrc == "" { log.Fatalf("$GOPATH env is empty ? Do you have golang development environment setup ?") } pathToGoSrc += "/src" if len(c.Args()) == 0 { log.Fatalf("Please provide repository to build: your_username/repo_name") } regsitry := c.String("registry") if regsitry != "" { regsitry += "/" } tag := "latest" path := c.Args()[0] rez := strings.Split(c.Args()[0], ":") if len(rez) == 2 { tag = rez[1] path = rez[0] } providerParts := strings.SplitN(path, "/", 2) if len(providerParts) != 2 { log.Fatalf("Given path [%s] is invalid, should be : provider.com/your_username/repo_name", c.Args()[0]) } provider := providerParts[0] justRepoName := providerParts[1] repoName := regsitry + providerParts[1] fullRepoName := provider + string(filepath.Separator) + justRepoName log.Infof("src path [%s]", pathToGoSrc) log.Infof("Tag [%s]", tag) log.Infof("Provider [%s]", provider) log.Infof("Org/Project [%s]", justRepoName) log.Infof("Registry/Org/Project [%s]", repoName) log.Infof("Provider/Org/Project [%s]", fullRepoName) s := sh.NewSession() //s.ShowCMD = true params := []string{ "run", "--rm", "--net=host", "-v", "/var/run/docker.sock:/var/run/docker.sock", "-v", pathToGoSrc + ":/src", "nildev/api-builder:latest", fullRepoName, "github.com/nildev/api-host", repoName + ":" + tag, } log.Infof("Building ... ") log.Infof("First time it can take more time because images needs to be downloaded. \n\n") s = s.Command("docker", params) out, err := s.Output() if err != nil { log.Fatalf("----\n %s\n\n", err) } if len(out) > 0 { log.Infof("----\n %s\n\n", out) } }, }, // { // // go run nildev.go run --env dev github.com/nildev/echo // Name: "run", // Usage: "run service localy", // Flags: []cli.Flag{ // cli.StringFlag{ // Name: "variables, v", // Value: "", // Usage: "file with variables to be passed as env variables to your service container", // }, // cli.StringFlag{ // Name: "env", // Value: "", // Usage: "env indicates which docker-compose from project should be launched, for example docker-compose-${env}.yml", // }, // cli.StringFlag{ // Name: "registry", // Value: "", // Usage: "registry used to fetch image from, for example quay.io. By default docker hub registry is used, which equals to empty string", // }, // }, // Action: func(c *cli.Context) { // log.Infof("%s", c.String("v")) // log.Infof("%s", c.String("dcf")) // log.Infof("%s", c.String("registry")) // // // generate docker-compose.yml // // create network // // run // // if docker-compose found, run it // // docker run -d -p "8080:8080" -e "ND_BITBUCKET_CLIENT_ID=xxxx" -e "ND_BITBUCKET_SECRETE=xxx" -e "ND_DATABASE_NAME=nildev" -e "ND_MONGODB_URL=mongodb://192.168.99.100:27017/nildev" blackhole/account:latest // }, // }, { // go run nildev.go deploy --v file.json github.com/nildev/echo Name: "deploy", Usage: "deploy service on nildev.io", Flags: []cli.Flag{ cli.StringFlag{ Name: "variables, v", Value: "", Usage: "file with variables to be passed as env variables to your service container", }, cli.StringFlag{ Name: "registry", Value: "", Usage: "registry used to fetch image from, for example quay.io. By default docker hub registry is used, which equals to empty string", }, }, Action: func(c *cli.Context) { log.Infof("%s", c.String("v")) log.Infof("%s", c.String("registry")) // use kubernetes Go client to create Pod }, }, { // go run nildev.go io --sourceDir=$GOPATH/src/bitbucket.org/nildev/ping Name: "inout", Aliases: []string{"io"}, Usage: "generate *inout service* integration code required for nildev service container", Flags: []cli.Flag{ cli.StringFlag{ Name: "sourceDir", Value: "", Usage: "full path to service source directory", }, cli.StringFlag{ Name: "tpl", Value: "", Usage: "template name", }, cli.StringFlag{ Name: "org", Value: "", Usage: "organisation name", }, cli.StringFlag{ Name: "ver", Value: "", Usage: "template version", }, cli.StringFlag{ Name: "basePattern", Value: "/api/v1", Usage: "base pattern for api endpoints", }, }, Action: func(c *cli.Context) { tplName := c.String("tpl") tplOrg := c.String("org") tplVer := c.String("ver") basePattern := c.String("basePattern") if c.String("sourceDir") == "" { log.Fatalf("Please provide path to service source directory") } if tplName == "" { log.Fatalf("Please provide template name") } if tplOrg == "" { log.Fatalf("Please provide template provider organisation") } inout.Generate(c.String("sourceDir"), tplName, tplOrg, tplVer, basePattern) }, }, { // go run nildev.go r --services=bitbucket.org/nildev/ping --containerDir=$GOPATH/src/bitbucket.org/nildev/blackhole Name: "routes", Aliases: []string{"r"}, Usage: "generate routes for given services", Flags: []cli.Flag{ cli.StringFlag{ Name: "services", Value: "", Usage: "full path to service source directory", }, cli.StringFlag{ Name: "containerDir", Value: ".", Usage: "full path to service container source directory", }, cli.StringFlag{ Name: "tpl", Value: "", Usage: "template name", }, cli.StringFlag{ Name: "org", Value: "", Usage: "organisation name", }, cli.StringFlag{ Name: "ver", Value: "", Usage: "template version", }, }, Action: func(c *cli.Context) { tplName := c.String("tpl") tplOrg := c.String("org") tplVer := c.String("ver") if c.String("containerDir") == "" { log.Fatalf("Please provide path to service container source directory") } if c.String("services") == "" { log.Fatalf("Please provide comma seperated pathes to services source directory") } if tplName == "" { log.Fatalf("Please provide template name") } if tplOrg == "" { log.Fatalf("Please provide template provider organisation") } pathesToServices := strings.Split(c.String("services"), ",") routes.Generate(c.String("containerDir"), pathesToServices, tplName, tplOrg, tplVer) }, }, } err := app.Run(os.Args) if err != nil { log.Debugf("Could not run [codegen] cmd, %s", err) } }
// Run service in kubernetes platform func (k8s *KubernetesPlatform) Run(serviceNames ...Name) error { s := sh.NewSession() //s.ShowCMD = true paramsD := []string{ "delete", "-f", k8s.BuildDir + string(filepath.Separator), } s = s.Command("kubectl", paramsD) out, err := s.Output() if err != nil { log.Fatalf("----\n %s\n\n", err) } if len(out) > 0 { log.Infof("----\n %s\n\n", out) } paramsC := []string{ "create", "-f", k8s.BuildDir + string(filepath.Separator), } s = s.Command("kubectl", paramsC) out, err = s.Output() if err != nil { log.Fatalf("----\n %s\n\n", err) } if len(out) > 0 { log.Infof("----\n %s\n\n", out) } // define viewModel // read passed config // generate values and set on view model // render template // sh.Exec("kubectl create -f generated.json") // 1. Make secret resources // 2. Build name // 3. Build labels // 4. Build selectors // 5. Build template metadata // 5. Build template labels // 5. Build template specs volumes // 5. Build template container name // 5. Build template container image // 5. Build template container env // 5. Build template container volume mounts // 5. Build template container imagePullSecrets // find file read it and load // serviceCfg := Config{ // Name: "account", // Image: "nildev/account", // } // flags := pflag.NewFlagSet("", pflag.ContinueOnError) // flags.SetNormalizeFunc(util.WarnWordSepNormalizeFunc) // Warn for "_" flags // // options := cmd.CreateOptions{ // Filenames: []string{"/Users/SteelzZ/Projects/Bitbucket/cluster/apps/guestbook/redis-master-controller.json"}, // } // f := cmdutil.NewFactory(nil) // // cfg, _ := f.ClientConfig() // cfg.Host = "http://127.0.0.1:8080" // // schema, err := f.Validator(false, "~/.nildev") // // cmdNamespace, enforceNamespace, err := f.DefaultNamespace() // if err != nil { // return err // } // mapper, typer := f.Object() // r := resource.NewBuilder(mapper, typer, resource.ClientMapperFunc(f.ClientForMapping), f.Decoder(true)). // Schema(schema). // ContinueOnError(). // NamespaceParam(cmdNamespace).DefaultNamespace(). // FilenameParam(enforceNamespace, options.Filenames...). // Flatten(). // Do() // err = r.Err() // if err != nil { // return err // } // // count := 0 // err = r.Visit(func(info *resource.Info, err error) error { // if err != nil { // return err // } // // if err := createAndRefresh(info); err != nil { // return cmdutil.AddSourceToErr("creating", info.Source, err) // } // // return nil // }) // if err != nil { // return err // } // if count == 0 { // return fmt.Errorf("no objects passed to create") // } // generate k8s replication controller config // generate k8s service config return nil }