Beispiel #1
0
// request wraps HTTP requests to the postmaster server. It is used internally
// by other functions to make various API requests. It uses a request object and
// a pointer to an empty repsonse object from the api package.
func (client *Client) request(endpoint string, req interface{}, res interface{}) error {
	hClient, err := client.getHttpClient()
	if err != nil {
		return err
	}

	http.DefaultClient.Timeout = 0
	requestBytes, err := json.Marshal(req)
	url := fmt.Sprintf("http://%s/%s", client.Host, endpoint)
	reader := bytes.NewReader(requestBytes)
	resp, err := hClient.Post(url, "application/json", reader)
	if err != nil {
		return err
	}
	responseData, _ := ioutil.ReadAll(resp.Body)
	if client.ShowRequests == true {
		fmt.Printf("URL: %s\nRequest: %s\nResponse: %s\n", url, string(requestBytes),
			string(responseData))
	}
	if resp.StatusCode == 404 {
		return errors.New("API endpoint not found")
	}
	if resp.StatusCode == 426 {
		log.Warn("Server version does not match")
	}
	if resp.StatusCode != 200 {
		var errorResponse api.ApiError
		json.Unmarshal(responseData, &errorResponse)
		return errors.New(errorResponse.Error)
	}
	return json.Unmarshal(responseData, &res)
}
Beispiel #2
0
// Start loads the web server and begins listening.
func Start(addr string) error {
	if serverRunning == true {
		return nil
	}

	if mailbox.DB == nil {
		mailbox.OpenDB()
		if _, err := os.Stat("mailboxes.db"); os.IsNotExist(err) {
			err := mailbox.CreateDB()
			if err != nil {
				panic(err)
			}
		}
	}

	cleanupTicker := time.Tick(1 * time.Hour)
	go func() {
		for {
			select {
			case <-cleanupTicker:
				err := cleanupFiles()
				if err != nil {
					log.Warn(err.Error())
				}
			}
		}
	}()

	endpoints := EndPointHandler{}
	svr := &http.Server{
		Addr:         addr,
		ReadTimeout:  12 * time.Minute,
		WriteTimeout: 12 * time.Minute,
	}

	endpoints.Add("GET", `/upgrade`, sendConduitBinary)
	endpoints.Add("POST", `/get`, getMessage)
	endpoints.Add("POST", "/put", putMessage)
	endpoints.Add("POST", "/stats/clients", clientStats)
	endpoints.Add("POST", "/stats", systemStats)
	endpoints.Add("POST", "/delete", deleteMessage)
	endpoints.Add("POST", "/deploy/list", deployInfo)
	endpoints.Add("POST", "/deploy/respond", deployRespond)
	endpoints.Add("POST", "/register", register)
	endpoints.Add("POST", "/deregister", deregister)
	endpoints.Add("POST", "/upload", acceptFile)
	endpoints.Add("POST", "/checkfile", checkfile)
	endpoints.Add("POST", "/asset", getAsset)
	http.Handle("/", &endpoints)
	serverRunning = true
	err := svr.ListenAndServe()
	return err
}
Beispiel #3
0
func cleanupFiles() error {
	files, _ := ioutil.ReadDir(filesPath())
	for _, f := range files {
		pending, err := mailbox.AssetPending(f.Name())
		if err == nil && !pending {
			log.Infof("Cleaning up file %s", f.Name())
			err := os.Remove(filepath.Join(filesPath(), f.Name()))
			if err != nil {
				log.Warn("File clenaup " + err.Error())
			}
		} else if err != nil {
			return err
		} else {
			if time.Since(f.ModTime()) > 720*time.Hour {
				err := os.Remove(filepath.Join(filesPath(), f.Name()))
				if err != nil {
					log.Warn("File clenaup " + err.Error())
				}
			}
		}
	}
	return nil
}
Beispiel #4
0
func runClient(noLoop bool) {
	viper.SetDefault("script_timeout", 300)
	log.LogFile = true
	if viper.GetBool("master.enabled") {
		log.Info("Launching master server")
		go runProxy()
	}
	log.Info("Waiting for messages...")

	client, _ := ClientFromConfig()

	if viper.IsSet("master.host") {
		client.UseProxy = true
		client.ProxyAddress = "http://" + viper.GetString("master.host")
	}

	var persistantScripts = []*engine.ScriptEngine{}

	if viper.IsSet("agents") {
		engine.Agents = viper.GetStringMapString("agents")
		engine.AgentAccessKey = viper.GetString("access_key")
	}

	// Begin polling cycle
	for {
		time.Sleep(time.Duration(rand.Intn(1000)+2000) * time.Millisecond)
		resp, err := client.Get()

		// If an error is returned by the client we will begin an exponential back
		// off in retrying. The backoff caps out at 15 retries.
		if err != nil {
			log.Error("Error getting messages: " + err.Error())
			if errorCount < 15 {
				errorCount++
			}
			expBackoff := int(math.Pow(float64(errorCount), 2))
			displacement := rand.Intn(errorCount + 1)
			sleepTime := expBackoff + displacement
			time.Sleep(time.Duration(sleepTime) * time.Second)
			continue
		}

		// A response was received but it might be an empty response from the
		// server timing out the long poll.
		errorCount = 0
		if resp.Body != "" {
			log.Infof("Script receieved (%s)", resp.Message)
			eng := engine.New()
			eng.Constant("DEPLOYMENT_ID", resp.Deployment)
			eng.Constant("SCRIPT_ID", resp.Message)

			persistant, _ := eng.GetVar("$persistant", resp.Body)
			if p, ok := persistant.(bool); ok {
				if p {
					persistantScripts = append(persistantScripts, eng)
				}
			}

			if resp.Asset != "" {
				assetPath, err := client.DownloadAsset(resp.Asset)
				if err != nil {
					client.Respond(resp.Message, "Could not download asset", true)
					log.Error("Could not download asset")
					_, err = client.Delete(resp.Message)
					continue
				} else {
					log.Infof("Downloaded asset to %s", assetPath)
				}
				eng.SetAsset(assetPath)
			}

			executionStartTime := time.Now()
			errChan := make(chan string, 1)
			timeoutSeconds := viper.GetInt("script_timeout")
			go func() {
				err = eng.Execute(resp.Body)
				if err != nil {
					errChan <- err.Error()
				} else {
					errChan <- ""
				}
			}()
			select {
			case e := <-errChan:
				if e != "" {
					err = errors.New(e)
				}
			case <-time.After(time.Second * time.Duration(timeoutSeconds)):
				log.Warn("Timing out script")
				err = errors.New("Scirpt timeed out")
			}
			executionTime := time.Since(executionStartTime)
			log.Infof("Script executed in %s", executionTime)
			if err != nil {
				log.Error("Error executing script " + resp.Message)
				log.Debug(err.Error())
				client.Respond(resp.Message, err.Error(), true)
			}
			_, err = client.Delete(resp.Message)
			if err != nil {
				log.Debug(err.Error())
				log.Error("Could not confirm script.")
			} else {
				log.Debug("Script confirmed: " + resp.Message)
			}
		}
		if noLoop == true {
			break
		}
	}
}
Beispiel #5
0
		client, err := ClientFromConfig()
		if err != nil {
			log.Debug(err.Error())
			log.Fatal("Could not configure client")
		}
		limitToken := (cmd.Flag("all").Value.String() == "false")
		count, _ := strconv.ParseInt(cmd.Flag("count").Value.String(), 10, 64)
		resp, err := client.ListDeploys(cmd.Flag("name").Value.String(),
			limitToken, int(count))
		if err != nil {
			log.Debug(err.Error())
			log.Error("Could not list deploys")
			return
		}
		if len(resp.Deployments) == 0 {
			log.Warn("There are no open deployments")
		}
		for _, dep := range resp.Deployments {
			log.Alertf("%s:", dep.Name)
			log.Infof("   Deployed at: %s",
				dep.CreatedAt.Format("01/02 03:04 PM"))
			log.Infof("   Deployed by: %s", dep.DeployedBy)
			log.Infof("   Executions: %d/%d",
				dep.MessageCount-dep.PendingCount, dep.MessageCount)
			log.Infof("   Repsonses: %d/%d", dep.ResponseCount, dep.MessageCount)
		}
	},
}

func init() {
	deployCmd.AddCommand(listCmd)