Пример #1
0
func Validate(c *cli.Context, startTime time.Time) {
	gossConfig := getGossConfig(c)
	sys := system.New(c)
	outputer := getOutputer(c)

	sleep := c.Duration("sleep")
	retryTimeout := c.Duration("retry-timeout")
	i := 1
	for {
		iStartTime := time.Now()
		out := validate(sys, gossConfig, c.Int("max-concurrent"))
		exitCode := outputer.Output(os.Stdout, out, iStartTime)
		if retryTimeout == 0 || exitCode == 0 {
			os.Exit(exitCode)
		}
		elapsed := time.Since(startTime)
		if elapsed+sleep > retryTimeout {
			color.Red("\nERROR: Timeout of %s reached before tests entered a passing state", retryTimeout)
			os.Exit(3)
		}
		color.Red("Retrying in %s (elapsed/timeout time: %.3fs/%s)\n\n\n", sleep, elapsed.Seconds(), retryTimeout)
		// Reset cache
		sys = system.New(c)
		time.Sleep(sleep)
		i++
		fmt.Printf("Attempt #%d:\n", i)
	}
}
Пример #2
0
// Simple wrapper to add multiple resources
func AutoAddResources(fileName string, keys []string, c *cli.Context) error {
	setStoreFormatFromFileName(fileName)
	config := util.Config{
		IgnoreList: c.GlobalStringSlice("exclude-attr"),
		Timeout:    int(c.Duration("timeout") / time.Millisecond),
	}

	var gossConfig GossConfig
	if _, err := os.Stat(fileName); err == nil {
		gossConfig = ReadJSON(fileName)
	} else {
		gossConfig = *NewGossConfig()
	}

	sys := system.New(c)

	for _, key := range keys {
		if err := AutoAddResource(fileName, gossConfig, key, c, config, sys); err != nil {
			return err
		}
	}
	WriteJSON(fileName, gossConfig)

	return nil
}
Пример #3
0
func (h healthHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	log.Printf("%v: requesting health probe", r.RemoteAddr)
	var resp res
	tmp, found := h.cache.Get("res")
	if found {
		resp = tmp.(res)
	} else {
		h.gossMu.Lock()
		defer h.gossMu.Unlock()
		tmp, found := h.cache.Get("res")
		if found {
			resp = tmp.(res)
		} else {
			h.sys = system.New(h.c)
			log.Printf("%v: Stale cache, running tests", r.RemoteAddr)
			iStartTime := time.Now()
			out := validate(h.sys, h.gossConfig, h.maxConcurrent)
			var b bytes.Buffer
			exitCode := h.outputer.Output(&b, out, iStartTime)
			resp = res{exitCode: exitCode, b: b}
			h.cache.Set("res", resp, cache.DefaultExpiration)
		}
	}
	if h.contentType != "" {
		w.Header().Set("Content-Type", h.contentType)
	}
	if resp.exitCode == 0 {
		resp.b.WriteTo(w)
	} else {
		w.WriteHeader(http.StatusServiceUnavailable)
		resp.b.WriteTo(w)
	}
}
Пример #4
0
func AppendResource(fileName, resourceName, key string, c *cli.Context) error {
	ignoreList := c.GlobalStringSlice("exclude-attr")

	var configJSON ConfigJSON
	if _, err := os.Stat(fileName); err == nil {
		configJSON = ReadJSON(fileName)
	} else {
		configJSON = *NewConfigJSON()
	}

	sys := system.New(c)

	// Need to figure out a good way to refactor this
	switch resourceName {
	case "Addr":
		res, _ := configJSON.Addrs.AppendSysResource(key, sys, ignoreList)
		resourcePrint(fileName, res)
	case "Command":
		res, _ := configJSON.Commands.AppendSysResource(key, sys, ignoreList)
		resourcePrint(fileName, res)
	case "DNS":
		res, _ := configJSON.DNS.AppendSysResource(key, sys, ignoreList)
		resourcePrint(fileName, res)
	case "File":
		res, _ := configJSON.Files.AppendSysResource(key, sys, ignoreList)
		resourcePrint(fileName, res)
	case "Group":
		res, _ := configJSON.Groups.AppendSysResource(key, sys, ignoreList)
		resourcePrint(fileName, res)
	case "Package":
		res, _ := configJSON.Packages.AppendSysResource(key, sys, ignoreList)
		resourcePrint(fileName, res)
	case "Port":
		res, _ := configJSON.Ports.AppendSysResource(key, sys, ignoreList)
		resourcePrint(fileName, res)
	case "Process":
		res, _ := configJSON.Processes.AppendSysResource(key, sys, ignoreList)
		resourcePrint(fileName, res)
	case "Service":
		res, _ := configJSON.Services.AppendSysResource(key, sys, ignoreList)
		resourcePrint(fileName, res)
	case "User":
		res, _ := configJSON.Users.AppendSysResource(key, sys, ignoreList)
		resourcePrint(fileName, res)
	case "Gossfile":
		res, _ := configJSON.Gossfiles.AppendSysResource(key, sys, ignoreList)
		resourcePrint(fileName, res)
	}

	WriteJSON(fileName, configJSON)

	return nil
}
Пример #5
0
func Serve(c *cli.Context) {
	endpoint := c.String("endpoint")
	color.NoColor = true
	cache := cache.New(c.Duration("cache"), 30*time.Second)

	health := healthHandler{
		c:             c,
		gossConfig:    getGossConfig(c),
		sys:           system.New(c),
		outputer:      getOutputer(c),
		cache:         cache,
		gossMu:        &sync.Mutex{},
		maxConcurrent: c.Int("max-concurrent"),
	}
	if c.String("format") == "json" {
		health.contentType = "application/json"
	}
	http.Handle(endpoint, health)
	listenAddr := c.String("listen-addr")
	log.Printf("Starting to listen on: %s", listenAddr)
	log.Fatal(http.ListenAndServe(c.String("listen-addr"), nil))
}
Пример #6
0
func AutoAppendResource(fileName, key string, c *cli.Context) error {
	var configJSON ConfigJSON
	if _, err := os.Stat(fileName); err == nil {
		configJSON = ReadJSON(fileName)
	} else {
		configJSON = *NewConfigJSON()
	}

	sys := system.New(c)

	// file
	if strings.Contains(key, "/") {
		if res, _, ok := configJSON.Files.AppendSysResourceIfExists(key, sys); ok == true {
			resourcePrint(fileName, res)
		}
	}

	// group
	if res, _, ok := configJSON.Groups.AppendSysResourceIfExists(key, sys); ok == true {
		resourcePrint(fileName, res)
	}

	// package
	if res, _, ok := configJSON.Packages.AppendSysResourceIfExists(key, sys); ok == true {
		resourcePrint(fileName, res)
	}

	// port
	if res, _, ok := configJSON.Ports.AppendSysResourceIfExists(key, sys); ok == true {
		resourcePrint(fileName, res)
	}

	// process
	if res, sysres, ok := configJSON.Processes.AppendSysResourceIfExists(key, sys); ok == true {
		resourcePrint(fileName, res)
		ports := system.GetPorts(true)
		pids, _ := sysres.Pids()
		for _, pid := range pids {
			pidS := strconv.Itoa(pid)
			for port, entry := range ports {
				if entry.Pid == pidS {
					// port
					if res, _, ok := configJSON.Ports.AppendSysResourceIfExists(port, sys); ok == true {
						resourcePrint(fileName, res)
					}
				}
			}
		}
	}

	// Service
	if res, _, ok := configJSON.Services.AppendSysResourceIfExists(key, sys); ok == true {
		resourcePrint(fileName, res)
	}

	// user
	if res, _, ok := configJSON.Users.AppendSysResourceIfExists(key, sys); ok == true {
		resourcePrint(fileName, res)
	}

	WriteJSON(fileName, configJSON)

	return nil
}
Пример #7
0
func Run(specFile string, c *cli.Context) {
	sys := system.New(c)

	// handle stdin
	var fh *os.File
	var err error
	var path string
	if hasStdin() {
		fh = os.Stdin
	} else {
		path = filepath.Dir(specFile)
		fh, err = os.Open(specFile)
		if err != nil {
			fmt.Printf("Error: %v\n", err)
			os.Exit(1)
		}
	}
	data, err := ioutil.ReadAll(fh)
	if err != nil {
		fmt.Printf("Error: %v\n", err)
		os.Exit(1)
	}
	configJSON := mergeJSONData(ReadJSONData(data), 0, path)

	out := make(chan resource.TestResult)

	in := make(chan resource.Resource)

	go func() {
		for _, t := range configJSON.Resources() {
			in <- t
		}
		close(in)
	}()

	if os.Getenv("GOMAXPROCS") == "" {
		runtime.GOMAXPROCS(runtime.NumCPU())
	}
	gomaxprocs := runtime.GOMAXPROCS(-1)
	workerCount := gomaxprocs * 5
	if workerCount > 50 {
		workerCount = 50
	}
	var wg sync.WaitGroup
	for i := 0; i < workerCount; i++ {
		wg.Add(1)
		go func() {
			defer wg.Done()
			for f := range in {
				for _, r := range f.Validate(sys) {
					out <- r
				}
			}

		}()
	}

	go func() {
		wg.Wait()
		close(out)
	}()

	testCount := 0
	var failed []resource.TestResult
	for testResult := range out {
		//fmt.Printf("%v: %s.\n", testResult.Duration, testResult.Desc)
		if testResult.Result {
			fmt.Printf(".")
			testCount++
		} else {
			fmt.Printf("F")
			failed = append(failed, testResult)
			testCount++
		}
	}

	for _, testResult := range failed {
		fmt.Printf("\n%s\n", testResult.Desc)
	}

	fmt.Printf("\n\nCount: %d failed: %d\n", testCount, len(failed))
	if len(failed) > 0 {
		os.Exit(1)
	}
}
Пример #8
0
func Run(c *cli.Context, startTime time.Time) {
	sys := system.New(c)

	// handle stdin
	var fh *os.File
	var err error
	var path string
	if !c.GlobalIsSet("gossfile") && hasStdin() {
		fh = os.Stdin
	} else {
		specFile := c.GlobalString("gossfile")
		path = filepath.Dir(specFile)
		fh, err = os.Open(specFile)
		if err != nil {
			fmt.Printf("Error: %v\n", err)
			os.Exit(1)
		}
	}
	data, err := ioutil.ReadAll(fh)
	if err != nil {
		fmt.Printf("Error: %v\n", err)
		os.Exit(1)
	}
	configJSON := mergeJSONData(ReadJSONData(data), 0, path)

	out := make(chan []resource.TestResult)

	in := make(chan resource.Resource)

	go func() {
		for _, t := range configJSON.Resources() {
			in <- t
		}
		close(in)
	}()

	if os.Getenv("GOMAXPROCS") == "" {
		runtime.GOMAXPROCS(runtime.NumCPU())
	}
	gomaxprocs := runtime.GOMAXPROCS(-1)
	workerCount := gomaxprocs * 5
	if workerCount > 50 {
		workerCount = 50
	}
	var wg sync.WaitGroup
	for i := 0; i < workerCount; i++ {
		wg.Add(1)
		go func() {
			defer wg.Done()
			for f := range in {
				out <- f.Validate(sys)
			}

		}()
	}

	go func() {
		wg.Wait()
		close(out)
	}()

	//var outputer outputs.Outputer
	if c.Bool("no-color") {
		color.NoColor = true
	}

	outputer := outputs.GetOutputer(c.String("format"))

	exitCode := outputer.Output(out, startTime)
	os.Exit(exitCode)

}
Пример #9
0
func AppendResource(fileName, resourceName, key string, c *cli.Context) error {
	var configJSON ConfigJSON
	if _, err := os.Stat(fileName); err == nil {
		configJSON = ReadJSON(fileName)
	} else {
		configJSON = ConfigJSON{}
	}

	sys := system.New(c)

	// Need to figure out a good way to refactor this
	switch resourceName {
	case "Addr":
		sysResource := sys.NewAddr(key, sys)
		resource := resource.NewAddr(*sysResource)
		resourcePrint(fileName, resource)
		configJSON.Addrs = append(configJSON.Addrs, resource)
	case "Command":
		sysResource := sys.NewCommand(key, sys)
		resource := resource.NewCommand(*sysResource)
		resourcePrint(fileName, resource)
		configJSON.Commands = append(configJSON.Commands, resource)
	case "DNS":
		sysResource := sys.NewDNS(key, sys)
		resource := resource.NewDNS(*sysResource)
		resourcePrint(fileName, resource)
		configJSON.DNS = append(configJSON.DNS, resource)
	case "File":
		sysResource := sys.NewFile(key, sys)
		resource := resource.NewFile(*sysResource)
		resourcePrint(fileName, resource)
		configJSON.Files = append(configJSON.Files, resource)
	case "Group":
		sysResource := sys.NewGroup(key, sys)
		resource := resource.NewGroup(*sysResource)
		resourcePrint(fileName, resource)
		configJSON.Groups = append(configJSON.Groups, resource)
	case "Package":
		sysResource := sys.NewPackage(key, sys)
		resource := resource.NewPackage(sysResource)
		resourcePrint(fileName, resource)
		configJSON.Packages = append(configJSON.Packages, resource)
	case "Port":
		sysResource := sys.NewPort(key, sys)
		resource := resource.NewPort(*sysResource)
		resourcePrint(fileName, resource)
		configJSON.Ports = append(configJSON.Ports, resource)
	case "Process":
		sysResource := sys.NewProcess(key, sys)
		resource := resource.NewProcess(*sysResource)
		resourcePrint(fileName, resource)
		configJSON.Processes = append(configJSON.Processes, resource)
	case "Service":
		sysResource := sys.NewService(key, sys)
		resource := resource.NewService(sysResource)
		resourcePrint(fileName, resource)
		configJSON.Services = append(configJSON.Services, resource)
	case "User":
		sysResource := sys.NewUser(key, sys)
		resource := resource.NewUser(*sysResource)
		resourcePrint(fileName, resource)
		configJSON.Users = append(configJSON.Users, resource)
	case "Gossfile":
		sysResource := sys.NewGossfile(key, sys)
		resource := resource.NewGossfile(*sysResource)
		resourcePrint(fileName, resource)
		configJSON.Gossfiles = append(configJSON.Gossfiles, resource)
	}

	WriteJSON(fileName, configJSON)

	return nil
}
Пример #10
0
func AppendResource(fileName, resourceName, key string, c *cli.Context) error {
	config := util.Config{
		IgnoreList: c.GlobalStringSlice("exclude-attr"),
		Timeout:    int(c.Duration("timeout") / time.Millisecond),
	}

	var configJSON ConfigJSON
	if _, err := os.Stat(fileName); err == nil {
		configJSON = ReadJSON(fileName)
	} else {
		configJSON = *NewConfigJSON()
	}

	sys := system.New(c)

	// Need to figure out a good way to refactor this
	switch resourceName {
	case "Addr":
		res, err := configJSON.Addrs.AppendSysResource(key, sys, config)
		if err != nil {
			fmt.Println(err)
			os.Exit(1)
		}
		resourcePrint(fileName, res)
	case "Command":
		res, err := configJSON.Commands.AppendSysResource(key, sys, config)
		if err != nil {
			fmt.Println(err)
			os.Exit(1)
		}
		resourcePrint(fileName, res)
	case "DNS":
		res, err := configJSON.DNS.AppendSysResource(key, sys, config)
		if err != nil {
			fmt.Println(err)
			os.Exit(1)
		}
		resourcePrint(fileName, res)
	case "File":
		res, err := configJSON.Files.AppendSysResource(key, sys, config)
		if err != nil {
			fmt.Println(err)
			os.Exit(1)
		}
		resourcePrint(fileName, res)
	case "Group":
		res, err := configJSON.Groups.AppendSysResource(key, sys, config)
		if err != nil {
			fmt.Println(err)
			os.Exit(1)
		}
		resourcePrint(fileName, res)
	case "Package":
		res, err := configJSON.Packages.AppendSysResource(key, sys, config)
		if err != nil {
			fmt.Println(err)
			os.Exit(1)
		}
		resourcePrint(fileName, res)
	case "Port":
		res, err := configJSON.Ports.AppendSysResource(key, sys, config)
		if err != nil {
			fmt.Println(err)
			os.Exit(1)
		}
		resourcePrint(fileName, res)
	case "Process":
		res, err := configJSON.Processes.AppendSysResource(key, sys, config)
		if err != nil {
			fmt.Println(err)
			os.Exit(1)
		}
		resourcePrint(fileName, res)
	case "Service":
		res, err := configJSON.Services.AppendSysResource(key, sys, config)
		if err != nil {
			fmt.Println(err)
			os.Exit(1)
		}
		resourcePrint(fileName, res)
	case "User":
		res, err := configJSON.Users.AppendSysResource(key, sys, config)
		if err != nil {
			fmt.Println(err)
			os.Exit(1)
		}
		resourcePrint(fileName, res)
	case "Gossfile":
		res, err := configJSON.Gossfiles.AppendSysResource(key, sys, config)
		if err != nil {
			fmt.Println(err)
			os.Exit(1)
		}
		resourcePrint(fileName, res)
	}

	WriteJSON(fileName, configJSON)

	return nil
}