예제 #1
0
파일: main.go 프로젝트: whawty/auth
func cmdRun(c *cli.Context) error {
	s, err := openAndCheck(c)
	if err != nil {
		return cli.NewExitError(err.Error(), 3)
	}

	webAddr := c.String("web-addr")
	saslPaths := c.StringSlice("sock")

	var wg sync.WaitGroup
	if webAddr != "" {
		wg.Add(1)
		go func() {
			defer wg.Done()
			if err := runWebAddr(webAddr, s.GetInterface(), c.GlobalString("web-static-dir")); err != nil {
				fmt.Printf("warning running web interface failed: %s\n", err)
			}
		}()
	}
	for _, path := range saslPaths {
		p := path
		wg.Add(1)
		go func() {
			defer wg.Done()
			if err := runSaslAuthSocket(p, s.GetInterface()); err != nil {
				fmt.Printf("warning running auth agent(%s) failed: %s\n", p, err)
			}
		}()
	}
	wg.Wait()

	return cli.NewExitError(fmt.Sprintf("shutting down since all auth sockets have closed."), 0)
}
예제 #2
0
func upAction(c *cli.Context) error {
	// TODO: get port from args
	port := "3000"
	consPort, err := getConsolePort(port)
	if err != nil {
		return cli.NewExitError(err.Error(), 1)
	}

	// TODO:
	apiServerURL := "https://api.leancloud.cn"

	appInfo, err := apps.CurrentAppInfo(".")
	if err != nil {
		return cli.NewExitError(err.Error(), 1)
	}

	rtm, err := apps.DetectRuntime(".")
	if err != nil {
		return cli.NewExitError(err.Error(), 1)
	}

	rtm.Envs["LC_APP_ID"] = appInfo.AppID
	rtm.Envs["LC_APP_KEY"] = appInfo.AppKey
	rtm.Envs["LC_APP_MASTER_KEY"] = appInfo.MasterKey
	rtm.Envs["LC_APP_PORT"] = port
	rtm.Envs["LC_API_SERVER"] = apiServerURL
	rtm.Envs["LEANCLOUD_APP_ID"] = appInfo.AppID
	rtm.Envs["LEANCLOUD_APP_KEY"] = appInfo.AppKey
	rtm.Envs["LEANCLOUD_APP_MASTER_KEY"] = appInfo.MasterKey
	rtm.Envs["LEANCLOUD_APP_PORT"] = port
	rtm.Envs["LEANCLOUD_API_SERVER"] = apiServerURL

	go func() {
		err := rtm.Run()
		if err != nil {
			panic(err)
		}
	}()

	cons := &console.Server{
		AppID:       appInfo.AppID,
		AppKey:      appInfo.AppKey,
		MasterKey:   appInfo.MasterKey,
		AppPort:     port,
		ConsolePort: consPort,
	}

	cons.Run()
	return nil
}
예제 #3
0
파일: main.go 프로젝트: whawty/auth
func cmdCheck(c *cli.Context) error {
	s, err := NewStore(c.GlobalString("store"), c.GlobalString("do-upgrades"),
		c.GlobalString("policy-type"), c.GlobalString("policy-condition"), c.GlobalString("hooks-dir"))
	if err != nil {
		return cli.NewExitError(fmt.Sprintf("Error opening whawty store: %s", err), 3)
	}
	ok, err := s.GetInterface().Check()
	if err != nil {
		return cli.NewExitError(fmt.Sprintf("Error checking whawty store: %s", err), 3)
	}
	if !ok {
		return cli.NewExitError(fmt.Sprintf("whawty store is invalid!"), 1)
	}
	return cli.NewExitError(fmt.Sprintf("whawty store is ok!"), 0)
}
예제 #4
0
파일: jobs.go 프로젝트: ngageoint/scale
func jobs_push(c *cli.Context) error {
	// push the image
	docker_image, err := get_docker_image_name(c)
	if err != nil {
		return cli.NewExitError(err.Error(), 1)
	}
	log.Info("Pushing", docker_image)
	cmd := exec.Command("docker", "push", docker_image)
	output, err := cmd.CombinedOutput()
	if err != nil {
		return cli.NewExitError(err.Error(), 1)
	}
	log.Info(string(output))
	return nil
}
예제 #5
0
파일: main.go 프로젝트: whawty/auth
func cmdList(c *cli.Context) error {
	s, err := openAndCheck(c)
	if err != nil {
		return cli.NewExitError(err.Error(), 3)
	}

	if c.Bool("full") {
		err = cmdListFull(s.GetInterface())
	} else {
		err = cmdListSupported(s.GetInterface())
	}
	if err != nil {
		return cli.NewExitError(err.Error(), 3)
	}
	return cli.NewExitError("", 0)
}
예제 #6
0
func loginAction(c *cli.Context) error {
	email, password := inputAccountInfo()
	info, err := api.Login(email, password)
	if err != nil {
		switch e := err.(type) {
		case api.Error:
			return cli.NewExitError(e.Content, 1)
		default:
			return cli.NewExitError(e.Error(), 1)
		}
	}
	fmt.Println("登录成功:")
	fmt.Printf("用户名: %s\r\n", info.Get("username").MustString())
	fmt.Printf("邮箱: %s\r\n", info.Get("email").MustString())
	return nil
}
예제 #7
0
파일: main.go 프로젝트: whawty/auth
func cmdRunSa(c *cli.Context) error {
	s, err := openAndCheck(c)
	if err != nil {
		return cli.NewExitError(err.Error(), 3)
	}

	listeners, err := activation.Listeners(true)
	if err != nil {
		return cli.NewExitError(fmt.Sprintf("fetching socket listeners from systemd failed: %s", err), 2)
	}

	fmt.Printf("got %d sockets from systemd\n", len(listeners))
	if len(listeners) == 0 {
		return cli.NewExitError("shutting down since there are no sockets to lissten on.", 2)
	}

	var wg sync.WaitGroup
	for idx, listener := range listeners {
		switch listener.(type) {
		case *net.UnixListener:
			fmt.Printf("listener[%d]: is a UNIX socket (-> saslauthd)\n", idx)
			wg.Add(1)
			ln := listener.(*net.UnixListener)
			go func() {
				defer wg.Done()
				if err := runSaslAuthSocketListener(ln, s.GetInterface()); err != nil {
					fmt.Printf("warning running auth agent failed: %s\n", err)
				}
			}()
		case *net.TCPListener:
			fmt.Printf("listener[%d]: is a TCP socket (-> HTTP)\n", idx)
			wg.Add(1)
			ln := listener.(*net.TCPListener)
			go func() {
				defer wg.Done()
				if err := runWebListener(ln, s.GetInterface(), c.GlobalString("web-static-dir")); err != nil {
					fmt.Printf("error running web-api: %s", err)
				}
			}()
		default:
			fmt.Printf("listener[%d]: has type %T (ingnoring)\n", idx, listener)
		}
	}
	wg.Wait()

	return cli.NewExitError(fmt.Sprintf("shutting down since all auth sockets have closed."), 0)
}
예제 #8
0
파일: main.go 프로젝트: whawty/auth
func cmdRemove(c *cli.Context) error {
	s, err := openAndCheck(c)
	if err != nil {
		return cli.NewExitError(err.Error(), 3)
	}

	username := c.Args().First()
	if username == "" {
		cli.ShowCommandHelp(c, "remove")
		return cli.NewExitError("", 0)
	}

	if err := s.GetInterface().Remove(username); err != nil {
		return cli.NewExitError(fmt.Sprintf("Error removing user '%s': %s", username, err), 3)
	}
	return cli.NewExitError(fmt.Sprintf("user '%s' successfully removed!", username), 0)
}
예제 #9
0
파일: jobs.go 프로젝트: ngageoint/scale
func jobs_commit(c *cli.Context) error {
	// push json into Dockerfile
	var job_type scalecli.JobType
	err := Parse_json_or_yaml("job_type", &job_type)
	if err != nil {
		return cli.NewExitError(err.Error(), 1)
	}
	registry := c.GlobalString("registry")
	if registry != "" {
		if !strings.HasPrefix(job_type.DockerImage, registry) {
			job_type.DockerImage = registry + "/" + job_type.DockerImage
		}
	}
	tag := c.GlobalString("tag")
	if tag != "" {
		if !strings.HasSuffix(job_type.DockerImage, tag) {
			job_type.DockerImage = job_type.DockerImage + ":" + tag
		}
	}
	json_data, err := json.Marshal(job_type)
	if err != nil {
		return cli.NewExitError(err.Error(), 1)
	}
	err = set_label_value("Dockerfile", "com.ngageoint.scale.job-type", string(json_data))
	if err != nil {
		return cli.NewExitError(err.Error(), 1)
	}

	// build the docker image
	docker_image, err := get_docker_image_name(c)
	if err != nil {
		return cli.NewExitError(err.Error(), 1)
	}
	log.Info("Building", docker_image)
	cmd := exec.Command("docker", "build", "-t", docker_image, ".")
	output, err := cmd.CombinedOutput()
	if err != nil {
		return cli.NewExitError(string(output), 1)
	}
	log.Info(string(output))

	if c.Bool("push") {
		jobs_push(c)
	}
	return nil
}
예제 #10
0
파일: strike.go 프로젝트: ngageoint/scale
func strike_create(c *cli.Context) error {
	url := c.GlobalString("url")
	if url == "" {
		return cli.NewExitError("A URL must be provided with the SCALE_URL environment variable or the --url argument", 1)
	}
	data_file := c.String("data")
	var strike_data scalecli.StrikeData
	err := Parse_json_or_yaml(data_file, &strike_data)
	if err != nil {
		return cli.NewExitError(err.Error(), 1)
	}
	strike_process_id, err := scalecli.CreateStrikeProcess(url, strike_data)
	if err != nil {
		return cli.NewExitError(err.Error(), 1)
	}
	color.Blue(fmt.Sprintf("Strike process %d created.", strike_process_id))
	return nil
}
예제 #11
0
func workspaces_list(c *cli.Context) error {
	max := c.Int("max")
	url := c.GlobalString("url")
	if url == "" {
		return cli.NewExitError("A URL must be provided with the SCALE_URL environment variable or the --url argument", 1)
	}
	workspaces, err := scalecli.GetWorkspaceList(url, max)
	if err != nil {
		return cli.NewExitError(err.Error(), 1)
	}
	for _, workspace := range workspaces {
		if workspace.Is_active {
			color.Green(workspace.String())
		} else {
			color.White(workspace.String())
		}
	}
	return nil
}
예제 #12
0
파일: main.go 프로젝트: whawty/auth
func cmdSetAdmin(c *cli.Context) error {
	s, err := openAndCheck(c)
	if err != nil {
		return cli.NewExitError(err.Error(), 3)
	}

	username := c.Args().First()
	if username == "" {
		cli.ShowCommandHelp(c, "set-admin")
		return cli.NewExitError("", 0)
	}

	isAdmin, err := strconv.ParseBool(c.Args().Get(1))
	if err != nil {
		cli.ShowCommandHelp(c, "set-admin")
		return cli.NewExitError("", 0)
	}

	if err := s.GetInterface().SetAdmin(username, isAdmin); err != nil {
		return cli.NewExitError(fmt.Sprintf("Error changing admin status of user '%s': %s", username, err), 3)
	}

	if isAdmin {
		return cli.NewExitError(fmt.Sprintf("user '%s' is now an admin!", username), 0)
	} else {
		return cli.NewExitError(fmt.Sprintf("user '%s' is now a normal user!", username), 0)
	}
}
예제 #13
0
파일: main.go 프로젝트: whawty/auth
func cmdUpdate(c *cli.Context) error {
	s, err := openAndCheck(c)
	if err != nil {
		return cli.NewExitError(err.Error(), 3)
	}

	username := c.Args().First()
	if username == "" {
		cli.ShowCommandHelp(c, "update")
		return cli.NewExitError("", 0)
	}

	password := c.Args().Get(1)
	if password == "" {
		pwd, err := askPass()
		if err != nil {
			if err != gopass.ErrInterrupted {
				return cli.NewExitError(err.Error(), 2)
			}
			return cli.NewExitError("", 2)
		}
		password = pwd
	}

	if err := s.GetInterface().Update(username, password); err != nil {
		return cli.NewExitError(fmt.Sprintf("Error updating user '%s': %s", username, err), 3)
	}
	return cli.NewExitError(fmt.Sprintf("user '%s' successfully updated!", username), 0)
}
예제 #14
0
파일: main.go 프로젝트: whawty/auth
func cmdInit(c *cli.Context) error {
	username := c.Args().First()
	if username == "" {
		cli.ShowCommandHelp(c, "init")
		return cli.NewExitError("", 0)
	}

	password := c.Args().Get(1)
	if password == "" {
		pwd, err := askPass()
		if err != nil {
			if err != gopass.ErrInterrupted {
				return cli.NewExitError(err.Error(), 2)
			}
			return cli.NewExitError("", 2)
		}
		password = pwd
	}

	s, err := NewStore(c.GlobalString("store"), c.GlobalString("do-upgrades"),
		c.GlobalString("policy-type"), c.GlobalString("policy-condition"), c.GlobalString("hooks-dir"))
	if err != nil {
		return cli.NewExitError(fmt.Sprintf("Error initializing whawty store: %s", err), 3)
	}
	if err := s.GetInterface().Init(username, password); err != nil {
		return cli.NewExitError(fmt.Sprintf("Error initializing whawty store: %s", err), 3)
	}
	return cli.NewExitError(fmt.Sprintf("whawty store successfully initialized!"), 0)
}
예제 #15
0
파일: jobs.go 프로젝트: ngageoint/scale
func jobs_validate(c *cli.Context) error {
	var job_type scalecli.JobType
	err := Parse_json_or_yaml("job_type", &job_type)
	if err != nil {
		return cli.NewExitError(err.Error(), 1)
	}

	url := c.GlobalString("url")
	if url == "" {
		return cli.NewExitError("A URL must be provided with the SCALE_URL environment variable or the --url argument", 1)
	}
	warnings, err := scalecli.ValidateJobType(url, job_type)
	if err != nil {
		return cli.NewExitError(err.Error(), 1)
	}
	if warnings == "" {
		color.White("Job type specification is valid.")
	} else {
		color.Yellow(warnings)
	}
	return nil
}
예제 #16
0
func workspaces_create(c *cli.Context) error {
	url := c.GlobalString("url")
	if url == "" {
		return cli.NewExitError("A URL must be provided with the SCALE_URL environment variable or the --url argument", 1)
	}
	data_file := c.String("data")
	var ws_data scalecli.NewWorkspace
	err := Parse_json_or_yaml(data_file, &ws_data)
	if err != nil {
		return cli.NewExitError(err.Error(), 1)
	}
	if ws_data.Version == "" {
		ws_data.Version = "1.0"
	}
	warnings, err := scalecli.CreateWorkspace(url, ws_data)
	if err != nil {
		return cli.NewExitError(err.Error(), 1)
	}
	if warnings != "" {
		return cli.NewExitError(warnings, 1)
	}
	return nil
}
예제 #17
0
func diffCommandAction(c *cli.Context) error {
	config := diff.Config{
		Certification:  c.Args().First(),
		OpencontrolDir: opencontrolDir,
	}
	inventory, errs := diff.ComputeGapAnalysis(config)
	if errs != nil && len(errs) > 0 {
		return cli.NewExitError(cli.NewMultiError(errs...).Error(), 1)
	}
	fmt.Fprintf(c.App.Writer, "\nNumber of missing controls: %d\n", len(inventory.MissingControlList))
	for _, standardAndControl := range sortmap.ByKey(inventory.MissingControlList) {
		fmt.Fprintf(c.App.Writer, "%s\n", standardAndControl.Key)
	}
	return nil
}
예제 #18
0
파일: main.go 프로젝트: whawty/auth
func cmdAuthenticate(c *cli.Context) error {
	s, err := openAndCheck(c)
	if err != nil {
		return cli.NewExitError(err.Error(), 3)
	}

	username := c.Args().First()
	if username == "" {
		cli.ShowCommandHelp(c, "authenticate")
		return cli.NewExitError("", 0)
	}

	password := c.Args().Get(1)
	if password == "" {
		fmt.Printf("password for '%s': ", username)
		pwd, err := gopass.GetPasswd()
		if err != nil {
			if err != gopass.ErrInterrupted {
				return cli.NewExitError(err.Error(), 2)
			}
			return cli.NewExitError("", 2)
		}
		password = string(pwd)
	}

	ok, isAdmin, _, err := s.GetInterface().Authenticate(username, password)
	if err != nil {
		return cli.NewExitError(fmt.Sprintf("Error authenticating user '%s': %s", username, err), 3)
	}
	if !ok {
		return cli.NewExitError(fmt.Sprintf("Error wrong password for user '%s'", username), 1)
	}

	// wait for potential upgrades - this might still be to fast for remote upgrades
	// TODO: find a better way to handle this situation
	time.Sleep(100 * time.Millisecond)

	if isAdmin {
		return cli.NewExitError(fmt.Sprintf("user '%s' is an admin.", username), 0)
	} else {
		return cli.NewExitError(fmt.Sprintf("user '%s' is a normal user.", username), 0)
	}
}
예제 #19
0
// NewCLIApp creates a new instances of the CLI
func NewCLIApp() *cli.App {
	app := cli.NewApp()
	app.Name = "Compliance Masonry"
	app.Usage = "Open Control CLI Tool"
	app.Version = "1.1.1"
	app.Flags = []cli.Flag{
		cli.BoolFlag{
			Name:  "verbose",
			Usage: "Indicates whether to run the command with verbosity.",
		},
	}
	app.Before = func(c *cli.Context) error {
		// Resets the log to output to nothing
		log.SetOutput(ioutil.Discard)
		if c.Bool("verbose") {
			log.SetOutput(os.Stderr)
			log.Println("Running with verbosity")
		}
		return nil
	}
	app.Commands = []cli.Command{
		{
			Name:    "get",
			Aliases: []string{"g"},
			Usage:   "Install compliance dependencies",
			Flags: []cli.Flag{
				cli.StringFlag{
					Name:  "dest",
					Value: constants.DefaultDestination,
					Usage: "Location to download the repos.",
				},
				cli.StringFlag{
					Name:  "config",
					Value: constants.DefaultConfigYaml,
					Usage: "Location of system yaml",
				},
			},
			Action: func(c *cli.Context) error {
				f := fs.OSUtil{}
				config := c.String("config")
				configBytes, err := f.OpenAndReadFile(config)
				if err != nil {
					app.Writer.Write([]byte(err.Error()))
					os.Exit(1)
				}
				wd, err := os.Getwd()
				if err != nil {
					app.Writer.Write([]byte(err.Error()))
					os.Exit(1)
				}
				destination := filepath.Join(wd, c.String("dest"))
				err = Get(destination,
					configBytes,
					&common.ConfigWorker{Downloader: common.NewVCSDownloader(), Parser: parser.Parser{}, ResourceMap: mapset.Init(), FSUtil: f})
				if err != nil {
					return cli.NewExitError(err.Error(), 1)
				}
				app.Writer.Write([]byte("Compliance Dependencies Installed"))
				return nil
			},
		},
		{
			Name:    "docs",
			Aliases: []string{"d"},
			Usage:   "Create Documentation",
			Subcommands: []cli.Command{
				{
					Name:    "gitbook",
					Aliases: []string{"g"},
					Usage:   "Create Gitbook Documentation",
					Flags: []cli.Flag{
						cli.StringFlag{
							Name:        "opencontrols, o",
							Value:       "opencontrols",
							Usage:       "Set opencontrols directory",
							Destination: &opencontrolDir,
						},
						cli.StringFlag{
							Name:        "exports, e",
							Value:       "exports",
							Usage:       "Sets the export directory",
							Destination: &exportPath,
						},
						cli.StringFlag{
							Name:        "markdowns, m",
							Value:       "markdowns",
							Usage:       "Sets the markdowns directory",
							Destination: &markdownPath,
						},
					},
					Action: func(c *cli.Context) error {
						config := gitbook.Config{
							Certification:  c.Args().First(),
							OpencontrolDir: opencontrolDir,
							ExportPath:     exportPath,
							MarkdownPath:   markdownPath,
						}
						warning, errMessages := docs.MakeGitbook(config)
						if warning != "" {
							app.Writer.Write([]byte(warning))
						}
						if errMessages != nil && len(errMessages) > 0 {
							err := cli.NewMultiError(errMessages...)
							return cli.NewExitError(err.Error(), 1)
						} else {
							app.Writer.Write([]byte("New Gitbook Documentation Created"))
							return nil
						}
					},
				},
				{
					Name:    "docx",
					Aliases: []string{"d"},
					Usage:   "Create Docx Documentation using a Template",
					Flags: []cli.Flag{
						cli.StringFlag{
							Name:        "opencontrols, o",
							Value:       "opencontrols",
							Usage:       "Set opencontrols directory",
							Destination: &opencontrolDir,
						},
						cli.StringFlag{
							Name:        "template, t",
							Value:       "",
							Usage:       "Set template to build",
							Destination: &templatePath,
						},
						cli.StringFlag{
							Name:        "export, e",
							Value:       "export.docx",
							Usage:       "Sets the export directory",
							Destination: &exportPath,
						},
					},
					Action: func(c *cli.Context) error {
						config := docx.Config{
							OpencontrolDir: opencontrolDir,
							TemplatePath:   templatePath,
							ExportPath:     exportPath,
						}
						if err := docs.BuildTemplate(config); err != nil && len(err.Error()) > 0 {
							return cli.NewExitError(err.Error(), 1)
						} else {
							app.Writer.Write([]byte("New Docx Created"))
							return nil
						}
					},
				},
			},
		},
		diffCommand,
	}
	return app
}
예제 #20
0
파일: jobs.go 프로젝트: ngageoint/scale
func jobs_template(c *cli.Context) error {
	// locate the template...if none is specified, fall back to a hard coded default
	template_name := c.String("template")
	if template_name != "" {
		template_path := c.GlobalString("template-path")
		tmp, err := find_template_in_path(template_name, template_path)
		if err != nil {
			return cli.NewExitError(err.Error(), 1)
		}
		template_name = tmp
	}

	// setup the target dir
	target_dir := "."
	if c.NArg() > 0 {
		target_dir = c.Args()[0]
	}
	d, err := os.Stat(target_dir)
	if err == nil {
		if !d.Mode().IsDir() {
			return cli.NewExitError("Target exists and is not a directory.", 1)
		} else if c.Bool("f") {
			log.Warning("Target directory", strconv.Quote(target_dir), "exists. Overriting contents.")
		} else {
			return cli.NewExitError(fmt.Sprint("Target directory", strconv.Quote(target_dir), "exists. Use -f to overrite."), -1)
		}
	} else {
		if e, ok := err.(*os.PathError); ok && e.Err == syscall.ENOENT {
			os.MkdirAll(target_dir, 0755)
		} else {
			return cli.NewExitError(err.Error(), 1)
		}
	}

	context := map[string]string{}
	for _, val := range c.StringSlice("arg") {
		tmp := strings.Split(val, "=")
		if len(tmp) != 2 {
			log.Warning("Invalid arg", val)
		} else {
			context[tmp[0]] = tmp[1]
		}
	}

	// use the hardcoded defaults
	if template_name == "" {
		for fname, val := range defaults {
			log.Info("Processing", fname)
			target_path := filepath.Join(target_dir, fname)
			// process template
			tmpl, err := template.New(fname).Parse(val)
			if err != nil {
				return cli.NewExitError(err.Error(), 1)
			}
			outfile, err := os.Create(target_path)
			if err != nil {
				return cli.NewExitError(err.Error(), 1)
			}
			err = tmpl.Execute(outfile, context)
			outfile.Close()
			if err != nil {
				return cli.NewExitError(err.Error(), 1)
			}
		}
	}
	// go through all files in the template directory and apply the template to the output dir
	filepath.Walk(template_name, func(path string, info os.FileInfo, err error) error {
		if err != nil {
			return err
		}
		relpath, err := filepath.Rel(template_name, path)
		if err != nil {
			return err
		}
		if relpath == "." || relpath == ".." {
			return nil
		}
		log.Info("Processing", relpath)
		target_path := filepath.Join(target_dir, relpath)
		if info.IsDir() {
			os.Mkdir(target_path, 0755)
		} else {
			// process template
			tmpl, err := template.New(info.Name()).ParseFiles(path)
			if err != nil {
				return err
			}
			outfile, err := os.Create(target_path)
			if err != nil {
				return err
			}
			err = tmpl.Execute(outfile, context)
			outfile.Close()
			if err != nil {
				return err
			}
		}
		return nil
	})
	return nil
}
예제 #21
0
파일: jobs.go 프로젝트: ngageoint/scale
func jobs_deploy(c *cli.Context) error {
	// pull the image
	err := error(nil) // some weird scoping issues if we don't declare here
	docker_image := c.String("image")
	if docker_image == "" {
		docker_image, err = get_docker_image_name(c)
		if err != nil {
			return cli.NewExitError(err.Error(), 1)
		}
	} else {
		if c.GlobalString("registry") != "" {
			docker_image = c.GlobalString("registry") + "/" + docker_image
		}
		if c.GlobalString("tag") != "" {
			docker_image = docker_image + ":" + c.GlobalString("tag")
		}
	}
	log.Info("Using docker image:", docker_image)
	if c.Bool("pull") {
		log.Info("Pulling", docker_image)
		cmd := exec.Command("docker", "pull", docker_image)
		_, err = cmd.CombinedOutput()
		if err != nil {
			log.Warning("Unable to pull the image. Checking if it is locally available.", err)
		}
	}

	// extract the JSON
	cmd := exec.Command("docker", "inspect", "-f", "{{(index .Config.Labels \"com.ngageoint.scale.job-type\")}}", docker_image)
	output, err := cmd.CombinedOutput()
	if err != nil {
		log.Debug(string(output))
		return cli.NewExitError(err.Error(), 1)
	}
	json_value := strings.Replace(string(output), "$ {", "${", -1)
	if strings.TrimSpace(json_value) == "" {
		return cli.NewExitError(fmt.Sprint("Scale job type information not found in ", docker_image), 1)
	}
	var job_type scalecli.JobType
	err = json.Unmarshal([]byte(json_value), &job_type)
	if err != nil {
		return cli.NewExitError(err.Error(), 1)
	}

	url := c.GlobalString("url")
	if url == "" {
		return cli.NewExitError("A URL must be provided with the SCALE_URL environment variable or the --url argument", 1)
	}

	if c.Bool("n") {
		// validate only
		warnings, err := scalecli.ValidateJobType(url, job_type)
		if err != nil {
			return cli.NewExitError(err.Error(), 1)
		}
		if warnings == "" {
			color.White("Job type specification is valid.")
		} else {
			color.Yellow(warnings)
		}
		return nil
	}

	// check for existing job type
	job_types, err := scalecli.GetJobTypes(url, job_type.Name)
	if err != nil {
		return cli.NewExitError(err.Error(), 1)
	}
	if len(job_types) == 0 {
		// create a new job type
		log.Info("Creating new job type entry")
		err = scalecli.CreateJobType(url, job_type)
		if err != nil {
			return cli.NewExitError(err.Error(), 1)
		}
	} else {
		for _, jt := range job_types {
			if jt.Version == job_type.Version {
				// found an exising entry, either update or create a new one
				log.Info("Updating job type metadata", jt.Id)
				err = scalecli.UpdateJobType(url, jt.Id, job_type)
				if err != nil {
					return cli.NewExitError(err.Error(), 1)
				}
				return nil
			}
		}
		// no entry found, create a new one
		log.Info("Creating new job type entry for", job_type.Name, "version", job_type.Version)
		err = scalecli.CreateJobType(url, job_type)
		if err != nil {
			return cli.NewExitError(err.Error(), 1)
		}
	}
	return nil
}
예제 #22
0
파일: recipes.go 프로젝트: ngageoint/scale
func recipes_run(c *cli.Context) error {
	url := c.GlobalString("url")
	if url == "" {
		return cli.NewExitError("A URL must be provided with the SCALE_URL environment variable or the --url argument", 1)
	}
	if c.NArg() != 1 && c.NArg() != 2 {
		return cli.NewExitError("Must specify a single recipe type name or id.", 1)
	}
	var recipe_type scalecli.RecipeType
	found := false
	id, err := strconv.Atoi(c.Args()[0])
	if err == nil {
		var resp_code int
		recipe_type, resp_code, err = scalecli.GetRecipeTypeDetails(url, id)
		if err != nil && resp_code != 404 {
			return cli.NewExitError(err.Error(), 1)
		} else if err == nil {
			found = true
		}
	}
	if !found {
		name := c.Args()[0]
		recipe_types, err := scalecli.GetRecipeTypes(url)
		if err != nil {
			return cli.NewExitError(err.Error(), 1)
		}
		var version string
		if c.NArg() == 2 {
			version = c.Args()[1]
		}
		switch len(recipe_types) {
		case 0:
			return cli.NewExitError("Recipe type not found.", 1)
		case 1:
			recipe_type = recipe_types[0]
			found = true
			break
		default:
			for _, rt := range recipe_types {
				if rt.Name == name && rt.Version == version {
					recipe_type = rt
					found = true
					break
				}
			}
			if !found {
				for _, rt := range recipe_types {
					fmt.Printf("%4d %8s [%25s] - %s\n", rt.Id, rt.Version, rt.Name, rt.Title)
				}
				return cli.NewExitError("Multiple recipe types found", 1)
			}
		}
	}
	data_file := c.String("data")
	var recipe_data scalecli.RecipeData
	err = Parse_json_or_yaml(data_file, &recipe_data)
	if err != nil {
		return cli.NewExitError(err.Error(), 1)
	}
	update_location, err := scalecli.RunRecipe(url, recipe_type.Id, recipe_data)
	if err != nil {
		return cli.NewExitError(err.Error(), 1)
	}
	color.Blue(fmt.Sprintf("Recipe submited, updates available at %s", update_location))
	return nil
}
예제 #23
0
파일: dashboards.go 프로젝트: y-kuno/mkr
func (g graphDef) getBaseGraph(graphType string, height int, width int) (baseGraph baseGraph, err error) {
	if g.isHostGraph() {
		if g.GraphName == "" {
			return nil, cli.NewExitError("graph_name is required for host graph.", 1)
		}

		return hostGraph{
			g.HostID,
			graphType,
			g.GraphName,
			g.Period,
			height,
			width,
		}, nil
	}

	if g.isServiceGraph() {
		if g.GraphName == "" {
			return nil, cli.NewExitError("graph_name is required for service graph.", 1)
		}

		return serviceGraph{
			g.ServiceName,
			graphType,
			g.GraphName,
			g.Period,
			height,
			width,
		}, nil
	}

	if g.isRoleGraph() {
		if g.GraphName == "" {
			return nil, cli.NewExitError("graph_name is required for role graph.", 1)
		}

		return roleGraph{
			g.ServiceName,
			g.RoleName,
			graphType,
			g.GraphName,
			g.Period,
			g.Stacked,
			g.Simplified,
			height,
			width,
		}, nil
	}

	if g.isExpressionGraph() {
		return expressionGraph{
			g.Query,
			graphType,
			g.Period,
			height,
			width,
		}, nil
	}

	return nil, cli.NewExitError("either host_id, service_name or query should be specified.", 1)
}
예제 #24
0
파일: dashboards.go 프로젝트: y-kuno/mkr
func doGenerateDashboards(c *cli.Context) error {
	conffile := c.GlobalString("conf")

	isStdout := c.Bool("print")

	argFilePath := c.Args()
	if len(argFilePath) < 1 {
		cli.ShowCommandHelp(c, "generate")
		return cli.NewExitError("specify a yaml file.", 1)
	}

	buf, err := ioutil.ReadFile(argFilePath[0])
	logger.DieIf(err)

	yml := graphsConfig{}
	err = yaml.Unmarshal(buf, &yml)
	logger.DieIf(err)

	client := newMackerel(conffile)

	org, err := client.GetOrg()
	logger.DieIf(err)

	if yml.ConfigVersion == "" {
		return cli.NewExitError("config_version is required in yaml.", 1)
	}
	if yml.ConfigVersion != "0.9" {
		return cli.NewExitError(fmt.Sprintf("config_version %s is not suport.", yml.ConfigVersion), 1)
	}
	if yml.Title == "" {
		return cli.NewExitError("title is required in yaml.", 1)
	}
	if yml.URLPath == "" {
		return cli.NewExitError("url_path is required in yaml.", 1)
	}
	if yml.Format == "" {
		yml.Format = "iframe"
	}
	if yml.Format != "iframe" && yml.Format != "image" {
		return cli.NewExitError("graph_type should be 'iframe' or 'image'.", 1)
	}
	if yml.Height == 0 {
		yml.Height = 200
	}
	if yml.Width == 0 {
		yml.Width = 400
	}

	if yml.HostGraphFormat != nil && yml.GraphFormat != nil {
		return cli.NewExitError("you cannot specify both 'graphs' and host_graphs'.", 1)
	}

	var markdown string
	for _, h := range yml.HostGraphFormat {
		mdf := generateHostGraphsMarkdownFactory(h, yml.Format, yml.Height, yml.Width)
		markdown += mdf.generate(org.Name)
	}
	for _, g := range yml.GraphFormat {
		mdf, err := generateGraphsMarkdownFactory(g, yml.Format, yml.Height, yml.Width)
		if err != nil {
			return err
		}
		markdown += mdf.generate(org.Name)
	}

	if isStdout {
		fmt.Println(markdown)
	} else {
		updateDashboard := &mackerel.Dashboard{
			Title:        yml.Title,
			BodyMarkDown: markdown,
			URLPath:      yml.URLPath,
		}

		dashboards, fetchError := client.FindDashboards()
		logger.DieIf(fetchError)

		dashboardID := ""
		for _, ds := range dashboards {
			if ds.URLPath == yml.URLPath {
				dashboardID = ds.ID
			}
		}

		if dashboardID == "" {
			_, createError := client.CreateDashboard(updateDashboard)
			logger.DieIf(createError)
		} else {
			_, updateError := client.UpdateDashboard(dashboardID, updateDashboard)
			logger.DieIf(updateError)
		}
	}

	return nil
}
예제 #25
0
func main() {
	app := cli.NewApp()
	app.Name = "triton"
	app.Usage = "Utilities for the Triton Data Pipeline"
	app.Version = "0.0.1"
	app.Commands = []cli.Command{
		{
			Name:    "store",
			Aliases: []string{"s"},
			Usage:   "store triton data to s3",
			Flags: []cli.Flag{
				cli.StringFlag{
					Name:  "stream",
					Usage: "Named triton stream",
				},
				cli.StringFlag{
					Name:   "bucket",
					Usage:  "Destination S3 bucket",
					EnvVar: "TRITON_BUCKET",
				},
				cli.BoolFlag{
					Name:  "skip-to-latest",
					Usage: "Skip to latest in stream (ignoring previous checkpoints)",
				},
				cli.StringFlag{
					Name:   "checkpoint-db",
					Usage:  "Database connect string for storing checkpoints. Defaults to local sqlite.",
					Value:  "sqlite://triton.db",
					EnvVar: "TRITON_DB",
				},
				cli.StringFlag{
					Name:   "client-name",
					Usage:  "optional name of triton client",
					Value:  "store",
					EnvVar: "TRITON_CLIENT",
				},
			},
			Action: func(c *cli.Context) error {
				if c.String("bucket") == "" {
					cli.ShowSubcommandHelp(c)
					return cli.NewExitError("bucket name required", 1)
				}

				if c.String("stream") == "" {
					cli.ShowSubcommandHelp(c)
					return cli.NewExitError("stream name required", 1)
				}

				if strings.Contains(c.String("client-name"), "-") {
					cli.ShowSubcommandHelp(c)
					return cli.NewExitError("client name cannot contain a -", 1)
				}

				store(c.String("client-name"), c.String("stream"), c.String("bucket"), c.String("checkpoint-db"), c.Bool("skip-to-latest"))
				return nil
			},
		},
		{
			Name:  "stats",
			Usage: "output stats for triton processes",
			Flags: []cli.Flag{
				cli.StringFlag{
					Name:   "checkpoint-db",
					Usage:  "Database connect string for storing checkpoints. Defaults to local sqlite.",
					Value:  "sqlite://triton.db",
					EnvVar: "TRITON_DB",
				},
				cli.StringFlag{
					Name:   "client-name",
					Usage:  "name of triton client",
					EnvVar: "TRITON_CLIENT",
				},
			},
			Action: func(c *cli.Context) error {
				if c.String("client-name") == "" {
					cli.ShowSubcommandHelp(c)
					return cli.NewExitError("missing client name", 1)
				}

				if strings.Contains(c.String("client-name"), "-") {
					cli.ShowSubcommandHelp(c)
					return cli.NewExitError("client name cannot contain a -", 1)
				}

				checkpointStats(c.String("client-name"), c.String("checkpoint-db"))
				return nil
			},
		},
		{
			Name:  "shards",
			Usage: "list shards for stream",
			Flags: []cli.Flag{
				cli.StringFlag{
					Name:  "stream",
					Usage: "Named triton stream",
				}},
			Action: func(c *cli.Context) error {
				if c.String("stream") == "" {
					cli.ShowSubcommandHelp(c)
					return cli.NewExitError("stream name required", 1)
				}

				listShards(c.String("stream"))
				return nil
			},
		},
		{
			Name:  "cat",
			Usage: "cat stored triton data from s3",
			Flags: []cli.Flag{
				cli.StringFlag{
					Name:  "stream",
					Usage: "Named triton stream",
				},
				cli.StringFlag{
					Name:   "bucket",
					Usage:  "Source S3 bucket",
					EnvVar: "TRITON_BUCKET",
				},
				cli.StringFlag{
					Name:  "start-date",
					Usage: "Date to start streaming from YYYYMMDD",
				},
				cli.StringFlag{
					Name:  "end-date",
					Usage: "(optional) Date to stop streaming from YYYYMMDD",
				},
				cli.StringFlag{
					Name:   "client-name",
					Usage:  "optional name of triton client. Defaults to any",
					Value:  "",
					EnvVar: "TRITON_CLIENT",
				}},
			Action: func(c *cli.Context) error {
				if c.String("stream") == "" {
					cli.ShowSubcommandHelp(c)
					return cli.NewExitError("stream name required", 1)
				}

				if c.String("bucket") == "" {
					cli.ShowSubcommandHelp(c)
					return cli.NewExitError("bucket name required", 1)
				}

				if c.String("start-date") == "" {
					cli.ShowSubcommandHelp(c)
					return cli.NewExitError("start-date required", 1)
				}

				// TODO: configure region
				sess := session.New(&aws.Config{Region: aws.String("us-west-1")})
				s3Svc := s3.New(sess)

				start, err := time.Parse("20060102", c.String("start-date"))
				if err != nil {
					cli.ShowSubcommandHelp(c)
					return cli.NewExitError("invalid start-date", 1)
				}

				end := start
				if c.String("end-date") != "" {
					end, err = time.Parse("20060102", c.String("end-date"))
					if err != nil {
						cli.ShowSubcommandHelp(c)
						return cli.NewExitError("invalid end-date", 1)
					}
				}

				sc := openStreamConfig(c.String("stream"))

				set, err := triton.NewStoreReader(s3Svc, c.String("bucket"), c.String("client-name"), sc.StreamName, start, end)
				if err != nil {
					log.Fatalln("Failure listing archive:", err)
				}

				for {
					rec, err := set.ReadRecord()
					if err != nil {
						if err == io.EOF {
							break
						} else {
							log.Fatalln("Failed reading record", err)
						}
					}

					b, err := json.Marshal(rec)
					if err != nil {
						panic(err)
					}
					fmt.Println(string(b))
				}
				return nil
			},
		},
	}

	raven.CapturePanic(func() {
		app.Run(os.Args)
	}, nil)
}