Beispiel #1
0
// sendConduitBinary will transmit the application's binary. It is used by
// clients to perform version syncs.
func sendConduitBinary(w http.ResponseWriter, r *http.Request) {
	log.Info("Upgrade requested")
	w.Header().Set("Content-Disposition", "attachment; filename=conduit")
	w.Header().Set("Content-Type", r.Header.Get("Content-Type"))
	defer r.Body.Close()

	exePath, _ := osext.Executable()
	http.ServeFile(w, r, exePath)
}
Beispiel #2
0
// getDeploymentInfo returns the information about a deployment.
func getDeploymentInfo(depId string, consolidate bool) {
	client, _ := ClientFromConfig()
	stats, err := client.PollDeployment(depId,
		func(stats *api.DeploymentStats) bool {
			return false
		})
	if err != nil {
		log.Debug(err.Error())
		log.Error("Could not get deployment results")
		return
	}
	log.Info("")
	log.Alert(depId)
	log.Info("")
	log.Infof("Total messages: %d", stats.MessageCount)
	log.Infof("Pending messages: %d", stats.PendingCount)
	log.Infof("Total responses: %d", stats.ResponseCount)
	if len(stats.Responses) > 0 {
		log.Alert("\nResponses:")
	}
	stats.Responses.Sort()
	displayResponses(stats.Responses, consolidate)
	log.Info("")
}
Beispiel #3
0
// Put sends a message to a series of mailboxes. An array of mailboxes can be
// provided, as well as a pattern using '*' as wildcards. The message will by
// sent to all matching mailboxes.
func (client *Client) Put(mbxs []string, pattern string, msg string,
	deploymentName string, asset string) (*api.PutMessageResponse, error) {
	md5, _ := client.hashFile(asset)
	if asset != "" {
		exists, err := client.CheckRemoteFile(md5)
		if err != nil {
			return nil, err
		}
		if exists == true {
			log.Info("File exists on server, skipping upload")
		} else {
			_, err := client.Upload(asset)
			if err != nil {
				log.Debug(err.Error())
				return nil, errors.New("Could not upload asset")
			}
		}
	}

	request := api.PutMessageRequest{
		Mailboxes:      mbxs,
		Body:           msg,
		Pattern:        pattern,
		DeploymentName: deploymentName,
		Asset:          md5,
	}
	request.Sign(client.AccessKeyName, client.AccessKey)
	var response api.PutMessageResponse
	err := client.request("put", request, &response)
	if err != nil {
		return nil, err
	}
	if !response.Validate(client.AccessKey) {
		return nil, errors.New("Server responded with an invalid signature")
	}
	return &response, nil
}
Beispiel #4
0
	"conduit/log"
	"github.com/spf13/cobra"
	"postmaster/mailbox"
)

// acessListCmd represents the acessList command
var accessListCmd = &cobra.Command{
	Use:   "list",
	Short: "List all administrative access keys",
	Long: `Display a list of all administrative access keys that have been
generated using 'conduit server access'. The server must be stopped when
running this command.`,
	Run: func(cmd *cobra.Command, args []string) {
		mailbox.OpenDB()
		keys, err := mailbox.AdminKeys()
		if err != nil {
			log.Debug(err.Error())
			log.Fatal("Could not list keys")
		}
		log.Alert("Access keys:")
		for _, k := range keys {
			log.Info(k.Name)
		}
		mailbox.CloseDB()
	},
}

func init() {
	accessCmd.AddCommand(accessListCmd)
}
Beispiel #5
0
that can manage the Conduit service.

For audit purposes the access key can be given a name. If no name is specified a
randomly generated identifier will be used.`,
	Run: func(cmd *cobra.Command, args []string) {
		mailbox.OpenDB()
		key := mailbox.AccessKey{FullAccess: true}
		if len(args) > 0 {
			key.Name = args[0]
		}
		err := key.Create()
		if err != nil {
			log.Debug(err.Error())
			log.Fatal("Could not create access key.")
		}
		log.Info("Access key created: ")
		log.Info("  Access key name: " + key.Name)
		log.Info("  Access key: " + key.Secret)
	},
}

func init() {
	serverCmd.AddCommand(accessCmd)

	// Here you will define your flags and configuration settings.

	// Cobra supports Persistent Flags which will work for this command
	// and all subcommands, e.g.:
	// accessCmd.PersistentFlags().String("foo", "", "A help for foo")

	// Cobra supports local flags which will only run when this command
Beispiel #6
0
func _system_exit(call otto.FunctionCall) otto.Value {
	log.Info("Shutdown from script.")
	os.Exit(0)
	return otto.Value{}
}
Beispiel #7
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 #8
0
	"conduit/log"
	"conduit/queue"
	"conduit/storage"
	"github.com/spf13/cobra"
)

var s string

// watchCmd represents the watch command
var watchCmd = &cobra.Command{
	Use:   "watch",
	Short: "Begin watching for commands.",
	Long: `Start processing the command queue. Conduit will run and wait for a
command to be delivered to it for processing.`,
	Run: func(cmd *cobra.Command, args []string) {
		log.Info("Starting...")
		q := queue.GetQueue()
		mgr := storage.GetStorage()
		for {
			cmd, err := q.Get()
			if err != nil {
				log.Error(err.Error())
			}
			if cmd != nil {
				scriptBody, err := mgr.GetScript(cmd.RemoteScriptUrl)
				if err != nil {
					log.Error(err.Error())
				} else {
					err := engine.Execute(scriptBody)
					if err != nil {
						log.Error(err.Error())
Beispiel #9
0
		if err != nil {
			log.Fatal(err.Error())
		}
		eng := engine.New()
		err = eng.Validate(string(data))
		if err != nil {
			log.Error(err.Error())
			log.Fatal("Bad script syntax")
		}
		res, err := eng.ExecuteFunction("$local", string(data))
		if err != nil {
			log.Debug(err.Error())
			log.Fatal("Local execution error")
		}
		if res != "" && res != "undefined" {
			log.Info("Local: " + res)
		}
		resp, err := client.Put(mailboxes, pattern, string(data),
			cmd.Flag("name").Value.String(), cmd.Flag("attach").Value.String())
		if err != nil {
			log.Debug(err.Error())
			log.Error("Could not deploy script")
		}
		if err != nil {
			log.Fatal(err.Error())
		}
		log.Infof("Script deployed to %d mailboxes (%d bytes)",
			len(resp.Mailboxes), len(data))
		log.Infof("Deployment name: %s", resp.Deployment)

		if cmd.Flag("no-results").Value.String() == "true" {
Beispiel #10
0
To run as an agent an address and port must be specified in the config file.
This is the interface and port to listen on. It should match the configuration
on the handler. For example:

agent_host: 10.0.100.15:2222

Agents must also have the same access_key as their handler in the config file.`,
	Run: func(cmd *cobra.Command, args []string) {
		agent.Address = viper.GetString("agent_host")
		agent.AccessKey = viper.GetString("access_key")
		if agent.Address == "" {
			cmd.Help()
			log.Fatal("\nThe 'agent_host' field in the config file is not present.")
		}
		log.Info("Starting agent on " + agent.Address)
		agent.Start()
	},
}

func init() {
	RootCmd.AddCommand(agentCmd)

	// Here you will define your flags and configuration settings.

	// Cobra supports Persistent Flags which will work for this command
	// and all subcommands, e.g.:
	// agentCmd.PersistentFlags().String("foo", "", "A help for foo")

	// Cobra supports local flags which will only run when this command
	// is called directly, e.g.:
Beispiel #11
0
	"github.com/spf13/cobra"
	"postmaster"
)

// serverCmd represents the server command
var serverCmd = &cobra.Command{
	Use:   "server",
	Short: "A brief description of your command",
	Long: `A longer description that spans multiple lines and likely contains examples
and usage of using your command. For example:

Cobra is a CLI library for Go that empowers applications.
This application is a tool to generate the needed files
to quickly create a Cobra application.`,
	Run: func(cmd *cobra.Command, args []string) {
		log.Info("Starting")
		postmaster.Start(":8080")
	},
}

func init() {
	RootCmd.AddCommand(serverCmd)

	// Here you will define your flags and configuration settings.

	// Cobra supports Persistent Flags which will work for this command
	// and all subcommands, e.g.:
	// serverCmd.PersistentFlags().String("foo", "", "A help for foo")

	// Cobra supports local flags which will only run when this command
	// is called directly, e.g.:
Beispiel #12
0
	Use:   "revoke",
	Short: "Revoke an access key",
	Long: `This will remove an access key from the database. It will no longer
be able to be used. The server must be stopped to perform this operation.`,
	Example: "conduit server access revoke mykey",
	Run: func(cmd *cobra.Command, args []string) {
		if len(args) == 0 {
			cmd.Help()
			return
		}
		mailbox.OpenDB()
		err := mailbox.Revoke(args[0])
		if err != nil {
			log.Fatal(err.Error())
		} else {
			log.Info("Access key revoked")
		}
		mailbox.CloseDB()
	},
}

func init() {
	accessCmd.AddCommand(serverAccessRevokeCmd)

	// Here you will define your flags and configuration settings.

	// Cobra supports Persistent Flags which will work for this command
	// and all subcommands, e.g.:
	// serverAccessRevokeCmd.PersistentFlags().String("foo", "", "A help for foo")

	// Cobra supports local flags which will only run when this command