style related code cleanup in mig top-level package

Fix a bunch of godoc issues, removes exchange and queue names which were
no longer being utilized, and the GenB32ID function which was also not
being used. Renames some constant values to remove mixture of all caps
and underscores in constants.
This commit is contained in:
Aaron Meihm 2017-10-26 15:27:44 -05:00
Родитель d4edb097d7
Коммит 034de6f3da
17 изменённых файлов: 207 добавлений и 182 удалений

8
acl.go
Просмотреть файл

@ -35,12 +35,12 @@ func verifyPermission(moduleName string, acl ACL, fingerprints []string) error {
// No ACL entry found for this module name, see if we can find a default
aclent, ok = acl["default"]
if !ok {
return fmt.Errorf("No ACL entry found for %v, and no default present", moduleName)
return fmt.Errorf("no ACL entry found for %v, and no default present", moduleName)
}
aclname = "default"
}
if aclent.MinimumWeight < 1 {
return fmt.Errorf("Invalid ACL %v, weight must be > 0", aclname)
return fmt.Errorf("invalid ACL %v, weight must be > 0", aclname)
}
var seenFp []string
signaturesWeight := 0
@ -48,7 +48,7 @@ func verifyPermission(moduleName string, acl ACL, fingerprints []string) error {
// if the same key is used to sign multiple times, return an error
for _, seen := range seenFp {
if seen == fp {
return fmt.Errorf("Permission violation: key %v used to sign multiple times", fp)
return fmt.Errorf("permission violation: key %v used to sign multiple times", fp)
}
}
for _, signer := range aclent.Investigators {
@ -59,7 +59,7 @@ func verifyPermission(moduleName string, acl ACL, fingerprints []string) error {
seenFp = append(seenFp, fp)
}
if signaturesWeight < aclent.MinimumWeight {
return fmt.Errorf("Permission denied for operation %v, insufficient signatures weight"+
return fmt.Errorf("permission denied for operation %v, insufficient signatures weight"+
" (need %v, got %v)", moduleName, aclent.MinimumWeight, signaturesWeight)
}
return nil

Просмотреть файл

@ -16,7 +16,6 @@ import (
"io"
"io/ioutil"
"os"
"strconv"
"sync"
"time"
@ -26,7 +25,7 @@ import (
// ActionVersion is the version of the syntax that is expected
const ActionVersion uint16 = 2
// an Action is the json object that is created by an investigator
// Action is the json object that is created by an investigator
// and provided to the MIG platform. It must be PGP signed.
type Action struct {
ID float64 `json:"id"`
@ -47,7 +46,7 @@ type Action struct {
SyntaxVersion uint16 `json:"syntaxversion,omitempty"`
}
// Some counters used to track the completion of an action
// ActionCounters are counters used to track the completion of an action
type ActionCounters struct {
Sent int `json:"sent,omitempty"`
Done int `json:"done,omitempty"`
@ -59,7 +58,7 @@ type ActionCounters struct {
TimeOut int `json:"timeout,omitempty"`
}
// a description is a simple object that contains detail about the
// Description is a simple object that contains detail about the
// action's author, and it's revision.
type Description struct {
Author string `json:"author,omitempty"`
@ -68,8 +67,8 @@ type Description struct {
Revision float64 `json:"revision,omitempty"`
}
// a threat provides the investigator with an idea of how dangerous
// a the compromission might be, if the indicators return positive
// Threat provides the investigator with details on a threat indicator
// if included in an action
type Threat struct {
Ref string `json:"ref,omitempty"`
Level string `json:"level,omitempty"`
@ -77,8 +76,8 @@ type Threat struct {
Type string `json:"type,omitempty"`
}
// an operation is an object that maps to an agent module.
// the parameters of the operation are passed to the module as an argument,
// Operation is an object that maps to an agent module.
// The parameters of the operation are passed to the module as an argument,
// and thus their format depends on the module itself.
type Operation struct {
Module string `json:"module"`
@ -93,7 +92,7 @@ type Operation struct {
WantCompressed bool `json:"want_compressed,omitempty"`
}
// Compress the parameters stored within an operation
// CompressOperationParam compresses the parameters stored within an operation
func (op *Operation) CompressOperationParam() (err error) {
defer func() {
if e := recover(); e != nil {
@ -118,7 +117,7 @@ func (op *Operation) CompressOperationParam() (err error) {
return
}
// Decompress the parameters stored within an operation
// DecompressOperationParam decompresses the parameters stored within an operation
func (op *Operation) DecompressOperationParam() (err error) {
defer func() {
if e := recover(); e != nil {
@ -150,14 +149,14 @@ func (op *Operation) DecompressOperationParam() (err error) {
return
}
// ActionFromFile() reads an action from a local file on the file system
// ActionFromFile reads an action from a local file on the file system
// and returns a mig.Action structure
func ActionFromFile(path string) (Action, error) {
var err error
var a Action
defer func() {
if e := recover(); e != nil {
err = fmt.Errorf("mig.ActionFromFile(): %v", e)
err = fmt.Errorf("ActionFromFile() -> %v", e)
}
}()
// parse the json of the action into a mig.Action
@ -208,7 +207,7 @@ type id struct {
var globalID id
// GenID() returns a float64 ID number that is unique to this process. The ID is initialized
// GenID returns a float64 ID number that is unique to this process. The ID is initialized
// at the number of seconds since MIG's creation date, shifted 16 bits to the right and incremented
// by one every time a new ID is requested. The resulting value must fit in 53 bits of precision
// provided by the float64 type.
@ -222,47 +221,40 @@ func GenID() float64 {
tmpid = tmpid << 16
globalID.value = float64(tmpid)
return globalID.value
} else {
globalID.value++
return globalID.value
}
}
// GenHexID returns a string with an hexadecimal encoded ID
func GenB32ID() string {
id := GenID()
return strconv.FormatUint(uint64(id), 36)
globalID.value++
return globalID.value
}
// Validate verifies that the Action received contained all the
// necessary fields, and returns an error when it doesn't.
func (a Action) Validate() (err error) {
if a.Name == "" {
return errors.New("Action.Name is empty. Expecting string.")
return errors.New("action name is empty")
}
if a.Target == "" {
return errors.New("Action.Target is empty. Expecting string.")
return errors.New("action target is empty")
}
if a.SyntaxVersion != ActionVersion {
return fmt.Errorf("Wrong Syntax Version integer. Expection version %d", ActionVersion)
return fmt.Errorf("wring syntax version, expected %v", ActionVersion)
}
if a.ValidFrom.String() == "" {
return errors.New("Action.ValidFrom is empty. Expecting string.")
return errors.New("action validfrom is empty")
}
if a.ExpireAfter.String() == "" {
return errors.New("Action.ExpireAfter is empty. Expecting string.")
return errors.New("action expireafter is empty")
}
if a.ValidFrom.After(a.ExpireAfter) {
return errors.New("Action.ExpireAfter is set before Action.ValidFrom.")
return errors.New("action expireafter is set before action validfrom")
}
if time.Now().After(a.ExpireAfter) {
return errors.New("Action.ExpireAfter is passed. Action has expired.")
return errors.New("action expireafter is in the past")
}
if a.Operations == nil {
return errors.New("Action.Operations is nil. Expecting string.")
return errors.New("action operations is empty")
}
if len(a.PGPSignatures) < 1 {
return errors.New("Action.PGPSignatures is empty. Expecting array of strings.")
return errors.New("action pgpsignatures is empty")
}
return
}
@ -307,11 +299,11 @@ func (a Action) VerifySignatures(keyring io.Reader) (err error) {
}()
astr, err := a.String()
if err != nil {
return errors.New("Failed to stringify action")
return errors.New("failed to stringify action")
}
// If the action does not contain any signatures, treat this as an error condition
if a.PGPSignatures == nil || len(a.PGPSignatures) == 0 {
return errors.New("Action contained no valid signatures")
return errors.New("action contained no valid signatures")
}
// Create a copy of the keyring we can use during validation of each
// signature. We don't want to use the keyring reader directly as it is
@ -325,10 +317,10 @@ func (a Action) VerifySignatures(keyring io.Reader) (err error) {
keyrdr := bytes.NewBuffer(keycopy)
valid, _, err := pgp.Verify(astr, sig, keyrdr)
if err != nil {
return errors.New("Failed to verify PGP Signature")
return errors.New("failed to verify PGP Signature")
}
if !valid {
return errors.New("Invalid PGP Signature")
return errors.New("invalid PGP Signature")
}
}
return
@ -354,7 +346,7 @@ func (a Action) VerifyACL(acl ACL, keyring io.Reader, onlyVerifyPubKey bool) (er
var fingerprints []string
astr, err := a.String()
if err != nil {
return errors.New("Failed to stringify action")
return errors.New("failed to stringify action")
}
// Create a copy of the keyring we can use during validation of each
// signature. We don't want to use the keyring reader directly as it is
@ -368,13 +360,13 @@ func (a Action) VerifyACL(acl ACL, keyring io.Reader, onlyVerifyPubKey bool) (er
keyrdr := bytes.NewBuffer(keycopy)
fp, err := pgp.GetFingerprintFromSignature(astr, sig, keyrdr)
if err != nil {
return fmt.Errorf("Failed to retrieve fingerprint from signatures: %v", err)
return fmt.Errorf("failed to retrieve fingerprint from signatures: %v", err)
}
fingerprints = append(fingerprints, fp)
}
if len(fingerprints) == 0 {
return errors.New("No valid fingerprints found.")
return errors.New("no valid fingerprints found")
}
if onlyVerifyPubKey {
@ -416,7 +408,7 @@ func (a Action) PrintCounters() {
fmt.Fprintf(os.Stderr, "%s\n", out)
}
// Return the an indented JSON string representing the action suitable for
// IndentedString returns an indented JSON string representing the action suitable for
// display
func (a Action) IndentedString() (string, error) {
buf, err := json.MarshalIndent(a, "", " ")

Просмотреть файл

@ -8,6 +8,7 @@ package mig /* import "mig.ninja/mig" */
import "time"
// Various agent status values
const (
AgtStatusOnline string = "online"
AgtStatusDestroyed string = "destroyed"
@ -49,7 +50,7 @@ type AgentEnv struct {
Modules []string `json:"modules,omitempty"`
}
// Stores AWS specific agent environment values
// AgentEnvAWS stores AWS specific agent environment values
type AgentEnvAWS struct {
InstanceID string `json:"instanceid,omitempty"`
LocalIPV4 string `json:"localipv4,omitempty"`
@ -57,6 +58,8 @@ type AgentEnvAWS struct {
InstanceType string `json:"instancetype,omitempty"`
}
// AgentsStats stores information about the global MIG environment, primarily used
// in command line tools and the API/scheduler
type AgentsStats struct {
Timestamp time.Time `json:"timestamp"`
OnlineAgents float64 `json:"onlineagents"`
@ -71,6 +74,8 @@ type AgentsStats struct {
FlappingEndpoints float64 `json:"flappingendpoints"`
}
// AgentsVersionsSum stores information on the count of agents at a specific version
// level, primarily used in command line tools and the API/scheduler
type AgentsVersionsSum struct {
Version string `json:"version"`
Count float64 `json:"count"`

Просмотреть файл

@ -15,6 +15,8 @@ import (
"time"
)
// Command describes an action as applied to a single agent, and will include
// results
type Command struct {
ID float64 `json:"id"`
Action Action `json:"action"`
@ -34,6 +36,7 @@ type Command struct {
FinishTime time.Time `json:"finishtime"`
}
// Various command status values
const (
StatusSent string = "sent"
StatusSuccess string = "success"
@ -43,12 +46,12 @@ const (
StatusTimeout string = "timeout"
)
// FromFile reads a command from a local file on the file system
// CmdFromFile reads a command from a local file on the file system
// and return the mig.Command structure
func CmdFromFile(path string) (cmd Command, err error) {
defer func() {
if e := recover(); e != nil {
err = fmt.Errorf("mig.CmdFromFile()-> %v", e)
err = fmt.Errorf("CmdFromFile() -> %v", e)
}
}()
jsonCmd, err := ioutil.ReadFile(path)
@ -71,13 +74,13 @@ func CmdFromFile(path string) (cmd Command, err error) {
// necessary fields, and returns an error when it doesn't.
func checkCmd(cmd Command) error {
if cmd.Agent.Name == "" {
return errors.New("cmd.Agent.Name is empty. Expecting string.")
return errors.New("command agent name is empty")
}
if cmd.Agent.QueueLoc == "" {
return errors.New("cmd.Agent.QueueLoc is empty. Expecting string.")
return errors.New("command queue location is empty")
}
if cmd.Status == "" {
return errors.New("cmd.Status is empty. Expecting string.")
return errors.New("command status is empty")
}
return nil
}

Просмотреть файл

@ -6,18 +6,10 @@
package mig /* import "mig.ninja/mig" */
// Various constants that indicate exchange and queue names used in RabbitMQ
const (
// rabbitmq exchanges and common queues
Mq_Ex_ToAgents = "toagents"
Mq_Ex_ToSchedulers = "toschedulers"
Mq_Q_Heartbeat = "mig.agt.heartbeats"
Mq_Q_Results = "mig.agt.results"
// event queues
Ev_Q_Agt_Auth_Fail = "agent.authentication.failure"
Ev_Q_Agt_New = "agent.new"
Ev_Q_Cmd_Res = "command.results"
// dummy queue for scheduler heartbeats to the relays
Ev_Q_Sched_Hb = "scheduler.heartbeat"
ExchangeToAgents = "toagents"
ExchangeToSchedulers = "toschedulers"
QueueAgentHeartbeat = "mig.agt.heartbeats"
QueueAgentResults = "mig.agt.results"
)

Просмотреть файл

@ -11,6 +11,7 @@ import (
"time"
)
// Investigator describes a single MIG investigator
type Investigator struct {
ID float64 `json:"id,omitempty"`
Name string `json:"name"`
@ -25,7 +26,7 @@ type Investigator struct {
Permissions InvestigatorPerms `json:"permissions"`
}
// Check an investigator has given permission pv
// CheckPermission validates if an investigator has given permission pv
func (i *Investigator) CheckPermission(pv int64) bool {
switch pv {
case PermSearch:
@ -68,7 +69,7 @@ func (i *Investigator) CheckPermission(pv int64) bool {
return false
}
// Describes permissions assigned to an investigator
// InvestigatorPerms describes permissions assigned to an investigator
type InvestigatorPerms struct {
Search bool `json:"search"`
Action bool `json:"action"`
@ -91,7 +92,7 @@ type InvestigatorPerms struct {
InvestigatorUpdate bool `json:"investigator_update"`
}
// Convert a permission bit mask into a boolean permission set
// FromMask converts a permission bit mask into a boolean permission set
func (ip *InvestigatorPerms) FromMask(mask int64) {
if (mask & PermSearch) != 0 {
ip.Search = true
@ -152,7 +153,7 @@ func (ip *InvestigatorPerms) FromMask(mask int64) {
}
}
// Convert a boolean permission set to a permission bit mask
// ToMask converts a boolean permission set to a permission bit mask
func (ip *InvestigatorPerms) ToMask() (ret int64) {
if ip.Search {
ret |= PermSearch
@ -214,9 +215,8 @@ func (ip *InvestigatorPerms) ToMask() (ret int64) {
return ret
}
// Convert an existing boolean permission set to a descriptive string, used
// primarily in mig-console for summarizing permissions assigned to an
// investigator
// ToDescriptive converts an existing boolean permission set to a descriptive string, used
// primarily in mig-console for summarizing permissions assigned to an investigator
func (ip *InvestigatorPerms) ToDescriptive() string {
cf := func(want int64, have int64) (bool, int64) {
var (
@ -289,11 +289,11 @@ func (ip *InvestigatorPerms) ToDescriptive() string {
return ret
}
// Describe permission sets that can be applied; note default is omitted as this
// PermSets describes permission sets that can be applied; note default is omitted as this
// is currently always applied
var PermSets = []string{"PermManifest", "PermLoader", "PermAdmin"}
// Apply permission sets in slice sl to the investigator
// FromSetList applies permission sets in slice sl to the investigator
func (ip *InvestigatorPerms) FromSetList(sl []string) error {
for _, x := range sl {
switch x {
@ -310,7 +310,7 @@ func (ip *InvestigatorPerms) FromSetList(sl []string) error {
return nil
}
// Set a default set of permissions on the investigator
// DefaultSet sets a default set of permissions on the investigator
func (ip *InvestigatorPerms) DefaultSet() {
ip.Search = true
ip.Action = true
@ -320,7 +320,7 @@ func (ip *InvestigatorPerms) DefaultSet() {
ip.Dashboard = true
}
// Set manifest related permissions on the investigator
// ManifestSet sets manifest related permissions on the investigator
func (ip *InvestigatorPerms) ManifestSet() {
ip.Manifest = true
ip.ManifestSign = true
@ -329,7 +329,7 @@ func (ip *InvestigatorPerms) ManifestSet() {
ip.ManifestLoaders = true
}
// Set loader related permissions on the investigator
// LoaderSet sets loader related permissions on the investigator
func (ip *InvestigatorPerms) LoaderSet() {
ip.Loader = true
ip.LoaderStatus = true
@ -338,7 +338,7 @@ func (ip *InvestigatorPerms) LoaderSet() {
ip.LoaderNew = true
}
// Set administrative permissions on the investigator
// AdminSet sets administrative permissions on the investigator
func (ip *InvestigatorPerms) AdminSet() {
ip.Investigator = true
ip.InvestigatorCreate = true
@ -368,6 +368,7 @@ const (
PermInvestigatorUpdate
)
// Possible status values for an investigator
const (
StatusActiveInvestigator string = "active"
StatusDisabledInvestigator string = "disabled"

Просмотреть файл

@ -13,7 +13,7 @@ import (
"time"
)
// Describes a loader entry stored in the database
// LoaderEntry describes a loader entry stored in the database
type LoaderEntry struct {
ID float64 `json:"id"` // Loader ID
Name string `json:"name"` // Loader name
@ -25,6 +25,7 @@ type LoaderEntry struct {
ExpectEnv string `json:"expectenv"` // Expected environment
}
// Validate validates a loader entry
func (le *LoaderEntry) Validate() (err error) {
if le.Key != "" {
err = ValidateLoaderPrefixAndKey(le.Prefix + le.Key)
@ -32,8 +33,8 @@ func (le *LoaderEntry) Validate() (err error) {
return nil
}
// Small helper type used primarily during the loader authentication
// process between the API and database code, temporarily stores
// LoaderAuthDetails is a small helper type used primarily during the loader
// authentication process between the API and database code, temporarily stores
// authentication information
type LoaderAuthDetails struct {
ID float64
@ -41,6 +42,7 @@ type LoaderAuthDetails struct {
Salt []byte
}
// Validate validates a LoaderAuthDetails type
func (lad *LoaderAuthDetails) Validate() error {
if len(lad.Hash) != LoaderHashedKeyLength ||
len(lad.Salt) != LoaderSaltLength {
@ -49,24 +51,32 @@ func (lad *LoaderAuthDetails) Validate() error {
return nil
}
// Generate a new loader prefix value
// GenerateLoaderPrefix will generate a new loader prefix value
func GenerateLoaderPrefix() string {
return RandAPIKeyString(LoaderPrefixLength)
}
// Generate a new loader key value
// GenerateLoaderKey will generate a new loader key value
func GenerateLoaderKey() string {
return RandAPIKeyString(LoaderKeyLength)
}
// Various constants related to properties of the loader keys
const LoaderPrefixAndKeyLength = 40 // Key length including prefix
const LoaderPrefixLength = 8 // Prefix length
const LoaderKeyLength = 32 // Length excluding prefix
const LoaderHashedKeyLength = 32 // Length of hashed key in the database
const LoaderSaltLength = 16 // Length of salt
// LoaderPrefixAndKeyLength is the key length for a loader key including the prefix
const LoaderPrefixAndKeyLength = 40
// Validate a loader key, returns nil if it is valid
// LoaderPrefixLength is the length of the loader prefix
const LoaderPrefixLength = 8
// LoaderKeyLength is the length of the loader key
const LoaderKeyLength = 32
// LoaderHashedKeyLength is the length of the hashed loader key in the database
const LoaderHashedKeyLength = 32
// LoaderSaltLength is the length of the salt applied to loader keys
const LoaderSaltLength = 16
// ValidateLoaderKey validates a loader key, returns nil if it is valid
func ValidateLoaderKey(key string) error {
repstr := fmt.Sprintf("^[A-Za-z0-9]{%v}$", LoaderKeyLength)
ok, err := regexp.MatchString(repstr, key)
@ -76,7 +86,7 @@ func ValidateLoaderKey(key string) error {
return nil
}
// Validate a loader prefix value, returns nil if it is valid
// ValidateLoaderPrefix validates a loader prefix value, returns nil if it is valid
func ValidateLoaderPrefix(prefix string) error {
repstr := fmt.Sprintf("^[A-Za-z0-9]{%v}$", LoaderPrefixLength)
ok, err := regexp.MatchString(repstr, prefix)
@ -86,7 +96,7 @@ func ValidateLoaderPrefix(prefix string) error {
return nil
}
// Validate a loader key that includes the prefix
// ValidateLoaderPrefixAndKey validates a loader key that includes the prefix
func ValidateLoaderPrefixAndKey(pk string) error {
if len(pk) != LoaderPrefixAndKeyLength {
return fmt.Errorf("loader key is incorrect length")

Просмотреть файл

@ -17,9 +17,9 @@ import (
)
const (
MODE_STDOUT = 1 << iota
MODE_FILE
MODE_SYSLOG
logModeStdout = 1 << iota
logModeFile
logModeSyslog
)
// Logging stores the attributes needed to perform the logging
@ -42,6 +42,7 @@ type Log struct {
Priority syslog.Priority
}
// Emerg sets Log entry level to emergency
func (l Log) Emerg() (mlog Log) {
mlog = l
mlog.Priority = syslog.LOG_EMERG
@ -49,6 +50,7 @@ func (l Log) Emerg() (mlog Log) {
return
}
// Alert sets Log entry level to alert
func (l Log) Alert() (mlog Log) {
mlog = l
mlog.Priority = syslog.LOG_ALERT
@ -56,6 +58,7 @@ func (l Log) Alert() (mlog Log) {
return
}
// Crit sets Log entry level to critical
func (l Log) Crit() (mlog Log) {
mlog = l
mlog.Priority = syslog.LOG_CRIT
@ -63,6 +66,7 @@ func (l Log) Crit() (mlog Log) {
return
}
// Err sets Log entry level to error
func (l Log) Err() (mlog Log) {
mlog = l
mlog.Priority = syslog.LOG_ERR
@ -70,6 +74,7 @@ func (l Log) Err() (mlog Log) {
return
}
// Warning sets Log entry level to warning
func (l Log) Warning() (mlog Log) {
mlog = l
mlog.Priority = syslog.LOG_WARNING
@ -77,6 +82,7 @@ func (l Log) Warning() (mlog Log) {
return
}
// Notice sets Log entry level to notice
func (l Log) Notice() (mlog Log) {
mlog = l
mlog.Priority = syslog.LOG_NOTICE
@ -84,6 +90,7 @@ func (l Log) Notice() (mlog Log) {
return
}
// Info sets Log entry level to info
func (l Log) Info() (mlog Log) {
mlog = l
mlog.Priority = syslog.LOG_INFO
@ -91,6 +98,7 @@ func (l Log) Info() (mlog Log) {
return
}
// Debug sets log entry level to debug
func (l Log) Debug() (mlog Log) {
mlog = l
mlog.Priority = syslog.LOG_DEBUG
@ -98,7 +106,7 @@ func (l Log) Debug() (mlog Log) {
return
}
// Custom type to satisfy io.Writer to use as file logging output, handles
// rotateLogWriter is a custom type to satisfy io.Writer to use as file logging output, handles
// log file rotation
type rotateLogWriter struct {
sync.Mutex
@ -177,29 +185,29 @@ func (r *rotateLogWriter) initAndCheck() (err error) {
// InitLogger prepares the context for logging based on the configuration
// in Logging
func InitLogger(orig_logctx Logging, progname string) (logctx Logging, err error) {
func InitLogger(origLogctx Logging, progname string) (logctx Logging, err error) {
defer func() {
if e := recover(); e != nil {
err = fmt.Errorf("mig.InitLogger() -> %v", e)
err = fmt.Errorf("InitLogger() -> %v", e)
}
}()
logctx = orig_logctx
logctx = origLogctx
switch logctx.Mode {
case "stdout":
logctx.logmode = MODE_STDOUT
logctx.logmode = logModeStdout
logctx, err = initLogStdOut(logctx)
if err != nil {
panic(err)
}
case "file":
logctx.logmode = MODE_FILE
logctx.logmode = logModeFile
logctx, err = initLogFile(logctx)
if err != nil {
panic(err)
}
case "syslog":
logctx.logmode = MODE_SYSLOG
logctx.logmode = logModeSyslog
logctx, err = initSyslog(logctx, progname)
if err != nil {
panic(err)
@ -207,7 +215,7 @@ func InitLogger(orig_logctx Logging, progname string) (logctx Logging, err error
default:
log.Println("Logging mode is missing. Assuming stdout.")
logctx.Mode = "stdout"
logctx.logmode = MODE_STDOUT
logctx.logmode = logModeStdout
logctx, err = initLogStdOut(logctx)
if err != nil {
panic(err)
@ -237,14 +245,14 @@ func InitLogger(orig_logctx Logging, progname string) (logctx Logging, err error
}
// initSyslog creates a connection to syslog and stores the handler in ctx
func initSyslog(orig_logctx Logging, progname string) (logctx Logging, err error) {
func initSyslog(origLogctx Logging, progname string) (logctx Logging, err error) {
defer func() {
if e := recover(); e != nil {
err = fmt.Errorf("mig.initSyslog() -> %v", e)
err = fmt.Errorf("initSyslog() -> %v", e)
}
}()
logctx = orig_logctx
logctx = origLogctx
if logctx.Host == "" {
panic("Syslog host is missing")
}
@ -266,14 +274,14 @@ func initSyslog(orig_logctx Logging, progname string) (logctx Logging, err error
}
// initLogFile creates a logfile and stores the descriptor in ctx
func initLogFile(orig_logctx Logging) (logctx Logging, err error) {
func initLogFile(origLogctx Logging) (logctx Logging, err error) {
defer func() {
if e := recover(); e != nil {
err = fmt.Errorf("mig.InitLogFile() -> %v", e)
err = fmt.Errorf("initLogFile() -> %v", e)
}
}()
logctx = orig_logctx
logctx = origLogctx
err = logctx.rotateWriter.new(logctx.File, logctx.MaxFileSize)
if err != nil {
panic(err)
@ -284,18 +292,18 @@ func initLogFile(orig_logctx Logging) (logctx Logging, err error) {
// initLogStdOut does nothing except storing in ctx that logs should be
// sent to stdout directly
func initLogStdOut(orig_logctx Logging) (logctx Logging, err error) {
logctx = orig_logctx
func initLogStdOut(origLogctx Logging) (logctx Logging, err error) {
logctx = origLogctx
return
}
// processLog receives events and perform logging and evaluationg of the log
// if the log is too critical, Analyze will trigger a scheduler shutdown
// ProcessLog receives events and performs logging and evaluation of the log
// severity level, in the event of an emergency level entry stop will be true
func ProcessLog(logctx Logging, l Log) (stop bool, err error) {
stop = false
defer func() {
if e := recover(); e != nil {
err = fmt.Errorf("mig.ProcessLog() -> %v", e)
err = fmt.Errorf("ProcessLog() -> %v", e)
}
}()
@ -339,12 +347,12 @@ func ProcessLog(logctx Logging, l Log) (stop bool, err error) {
if l.Desc != "" {
logline += l.Desc
} else {
err = fmt.Errorf("Missing mandatory description in logent")
err = fmt.Errorf("missing mandatory description in logent")
return
}
switch logctx.logmode {
case MODE_SYSLOG:
case logModeSyslog:
switch l.Priority {
// emergency logging causes the scheduler to shut down
case syslog.LOG_EMERG:
@ -376,10 +384,10 @@ func ProcessLog(logctx Logging, l Log) (stop bool, err error) {
err = logctx.syslogfd.Info(logline)
return
}
case MODE_STDOUT:
case logModeStdout:
log.Println(logline)
return
case MODE_FILE:
case logModeFile:
log.Println(logline)
return
default:
@ -388,6 +396,8 @@ func ProcessLog(logctx Logging, l Log) (stop bool, err error) {
}
}
// Destroy can be used to indicate no further logging with the given logging context
// will take place
func (logctx Logging) Destroy() {
if logctx.Mode == "syslog" {
logctx.syslogfd.Close()

Просмотреть файл

@ -17,9 +17,9 @@ import (
)
const (
MODE_STDOUT = 1 << iota
MODE_FILE
MODE_EVENTLOG
logModeStdout = 1 << iota
logModeFile
logModeEventlog
)
// Logging stores the attributes needed to perform the logging
@ -42,6 +42,7 @@ type Log struct {
Priority int
}
// Emerg sets Log entry level to emergency
func (l Log) Emerg() (mlog Log) {
mlog = l
mlog.Priority = eventlog.Error
@ -49,6 +50,7 @@ func (l Log) Emerg() (mlog Log) {
return
}
// Alert sets Log entry level to alert
func (l Log) Alert() (mlog Log) {
mlog = l
mlog.Priority = eventlog.Error
@ -56,6 +58,7 @@ func (l Log) Alert() (mlog Log) {
return
}
// Crit sets Log entry level to critical
func (l Log) Crit() (mlog Log) {
mlog = l
mlog.Priority = eventlog.Error
@ -63,6 +66,7 @@ func (l Log) Crit() (mlog Log) {
return
}
// Err sets Log entry level to error
func (l Log) Err() (mlog Log) {
mlog = l
mlog.Priority = eventlog.Error
@ -70,6 +74,7 @@ func (l Log) Err() (mlog Log) {
return
}
// Warning sets Log entry level to warning
func (l Log) Warning() (mlog Log) {
mlog = l
mlog.Priority = eventlog.Warning
@ -77,6 +82,7 @@ func (l Log) Warning() (mlog Log) {
return
}
// Notice sets Log entry level to notice
func (l Log) Notice() (mlog Log) {
mlog = l
mlog.Priority = eventlog.Warning
@ -84,6 +90,7 @@ func (l Log) Notice() (mlog Log) {
return
}
// Info sets Log entry level to info
func (l Log) Info() (mlog Log) {
mlog = l
mlog.Priority = eventlog.Info
@ -91,7 +98,8 @@ func (l Log) Info() (mlog Log) {
return
}
// don't log debug messages on windows
// Debug sets log entry level to debug, we don't log debug
// messages on Windows
func (l Log) Debug() (mlog Log) {
mlog = l
mlog.Priority = 999
@ -99,7 +107,7 @@ func (l Log) Debug() (mlog Log) {
return
}
// Custom type to satisfy io.Writer to use as file logging output, handles
// rotateLogWriter is a custom type to satisfy io.Writer to use as file logging output, handles
// log file rotation
type rotateLogWriter struct {
sync.Mutex
@ -181,29 +189,29 @@ func (r *rotateLogWriter) initAndCheck() (err error) {
// InitLogger prepares the context for logging based on the configuration
// in Logging
func InitLogger(orig_logctx Logging, progname string) (logctx Logging, err error) {
func InitLogger(origLogctx Logging, progname string) (logctx Logging, err error) {
defer func() {
if e := recover(); e != nil {
err = fmt.Errorf("mig.InitLogger() -> %v", e)
err = fmt.Errorf("InitLogger() -> %v", e)
}
}()
logctx = orig_logctx
logctx = origLogctx
switch logctx.Mode {
case "stdout":
logctx.logmode = MODE_STDOUT
logctx.logmode = logModeStdout
logctx, err = initLogStdOut(logctx)
if err != nil {
panic(err)
}
case "file":
logctx.logmode = MODE_FILE
logctx.logmode = logModeFile
logctx, err = initLogFile(logctx)
if err != nil {
panic(err)
}
case "syslog":
logctx.logmode = MODE_EVENTLOG
logctx.logmode = logModeEventlog
logctx, err = initEventlog(logctx, progname)
if err != nil {
panic(err)
@ -211,7 +219,7 @@ func InitLogger(orig_logctx Logging, progname string) (logctx Logging, err error
default:
log.Println("Logging mode is missing. Assuming stdout.")
logctx.Mode = "stdout"
logctx.logmode = MODE_STDOUT
logctx.logmode = logModeStdout
logctx, err = initLogStdOut(logctx)
if err != nil {
panic(err)
@ -242,11 +250,11 @@ func InitLogger(orig_logctx Logging, progname string) (logctx Logging, err error
}
// initEventlog creates a connection to event logs and stores the handler in ctx
func initEventlog(orig_logctx Logging, progname string) (logctx Logging, err error) {
logctx = orig_logctx
func initEventlog(origLogctx Logging, progname string) (logctx Logging, err error) {
logctx = origLogctx
defer func() {
if e := recover(); e != nil {
err = fmt.Errorf("mig.initEventlog() -> %v", e)
err = fmt.Errorf("initEventlog() -> %v", e)
}
}()
const name = "mylog"
@ -263,14 +271,14 @@ func initEventlog(orig_logctx Logging, progname string) (logctx Logging, err err
}
// initLogFile creates a logfile and stores the descriptor in ctx
func initLogFile(orig_logctx Logging) (logctx Logging, err error) {
func initLogFile(origLogctx Logging) (logctx Logging, err error) {
defer func() {
if e := recover(); e != nil {
err = fmt.Errorf("mig.InitLogFile() -> %v", e)
err = fmt.Errorf("initLogFile() -> %v", e)
}
}()
logctx = orig_logctx
logctx = origLogctx
err = logctx.rotateWriter.new(logctx.File, logctx.MaxFileSize)
if err != nil {
panic(err)
@ -281,18 +289,18 @@ func initLogFile(orig_logctx Logging) (logctx Logging, err error) {
// initLogStdOut does nothing except storing in ctx that logs should be
// sent to stdout directly
func initLogStdOut(orig_logctx Logging) (logctx Logging, err error) {
logctx = orig_logctx
func initLogStdOut(origLogctx Logging) (logctx Logging, err error) {
logctx = origLogctx
return
}
// processLog receives events and perform logging and evaluationg of the log
// if the log is too critical, Analyze will trigger a scheduler shutdown
// ProcessLog receives events and performs logging and evaluation of the log
// severity level, in the event of an emergency level entry stop will be true
func ProcessLog(logctx Logging, l Log) (stop bool, err error) {
stop = false
defer func() {
if e := recover(); e != nil {
err = fmt.Errorf("mig.ProcessLog() -> %v", e)
err = fmt.Errorf("ProcessLog() -> %v", e)
}
}()
@ -336,12 +344,12 @@ func ProcessLog(logctx Logging, l Log) (stop bool, err error) {
if l.Desc != "" {
logline += l.Desc
} else {
err = fmt.Errorf("Missing mandatory description in logent")
err = fmt.Errorf("missing mandatory description in logent")
return
}
switch logctx.logmode {
case MODE_EVENTLOG:
case logModeEventlog:
switch l.Priority {
case eventlog.Error:
err = logctx.fd.Error(1, logline)
@ -360,10 +368,10 @@ func ProcessLog(logctx Logging, l Log) (stop bool, err error) {
err = logctx.fd.Info(3, logline)
return
}
case MODE_STDOUT:
case logModeStdout:
log.Println(logline)
return
case MODE_FILE:
case logModeFile:
log.Println(logline)
return
default:
@ -373,6 +381,8 @@ func ProcessLog(logctx Logging, l Log) (stop bool, err error) {
return
}
// Destroy can be used to indicate no further logging with the given logging context
// will take place
func (logctx Logging) Destroy() {
if logctx.Mode == "syslog" {
_ = logctx.fd.Close()

Просмотреть файл

@ -27,7 +27,7 @@ import (
"time"
)
// Describes a manifest record stored within the MIG database
// ManifestRecord describes a manifest record stored within the MIG database
type ManifestRecord struct {
ID float64 `json:"id"` // Manifest record ID
Name string `json:"name"` // The name of the manifest record
@ -38,7 +38,7 @@ type ManifestRecord struct {
Signatures []string `json:"signatures"` // Signatures applied to the record
}
// Validate an existing manifest record
// Validate validates an existing manifest record
func (m *ManifestRecord) Validate() (err error) {
if m.Name == "" {
return fmt.Errorf("manifest has invalid name")
@ -57,7 +57,7 @@ func (m *ManifestRecord) Validate() (err error) {
return
}
// Sign a manifest record
// Sign will sign a manifest record using the indicated key ID
func (m *ManifestRecord) Sign(keyid string, secring io.Reader) (sig string, err error) {
defer func() {
if e := recover(); e != nil {
@ -83,7 +83,7 @@ func (m *ManifestRecord) Sign(keyid string, secring io.Reader) (sig string, err
return
}
// Convert a manifest record into a manifest response
// ManifestResponse converts a manifest record into a manifest response
func (m *ManifestRecord) ManifestResponse() (ManifestResponse, error) {
ret := ManifestResponse{}
@ -137,7 +137,7 @@ func (m *ManifestRecord) ManifestResponse() (ManifestResponse, error) {
return ret, nil
}
// Returns the requested file object as a gzip compressed byte slice
// ManifestObject returns the requested file object as a gzip compressed byte slice
// from the manifest record
func (m *ManifestRecord) ManifestObject(obj string) ([]byte, error) {
var bufw bytes.Buffer
@ -195,8 +195,8 @@ func (m *ManifestRecord) ManifestObject(obj string) ([]byte, error) {
return ret, nil
}
// Load manifest content from a file on the file system (a gzip'd tar file),
// primarily utilized by mig-console during manifest creation operations.
// ContentFromFile loads manifest content from a file on the file system (a gzip'd tar file),
// primarily utilized by mig-console during manifest creation operations
func (m *ManifestRecord) ContentFromFile(path string) (err error) {
var buf bytes.Buffer
fd, err := os.Open(path)
@ -218,7 +218,7 @@ func (m *ManifestRecord) ContentFromFile(path string) (err error) {
return
}
// Write manifest content to a file on the file system
// FileFromContent writes manifest content to a file on the file system
func (m *ManifestRecord) FileFromContent(path string) (err error) {
fd, err := os.Create(path)
if err != nil {
@ -238,20 +238,20 @@ func (m *ManifestRecord) FileFromContent(path string) (err error) {
return nil
}
// Manifest parameters are sent from the loader to the API as part of
// ManifestParameters are sent from the loader to the API as part of
// a manifest request.
type ManifestParameters struct {
AgentIdentifier Agent `json:"agent"` // Agent context information
Object string `json:"object"` // Object being requested
}
// Validate parameters included in a manifest request
// Validate validetes a ManifestParameters type for correct formatting
func (m *ManifestParameters) Validate() error {
return nil
}
// Validate parameters included in a manifest request with an object fetch
// component
// ValidateFetch validates the parameters included in a manifest request with an
// object fetch component
func (m *ManifestParameters) ValidateFetch() error {
err := m.Validate()
if err != nil {
@ -263,19 +263,19 @@ func (m *ManifestParameters) ValidateFetch() error {
return m.Validate()
}
// The response to a manifest object fetch
// ManifestFetchResponse is the response to a manifest object fetch
type ManifestFetchResponse struct {
Data []byte `json:"data"`
}
// The response to a standard manifest request
// ManifestResponse is the response to a standard manifest request
type ManifestResponse struct {
LoaderName string `json:"loader_name"`
Entries []ManifestEntry `json:"entries"`
Signatures []string `json:"signatures"`
}
// Validate a manifest response
// Validate validates a ManifestResponse type ensuring required content is present
func (m *ManifestResponse) Validate() error {
if m.LoaderName == "" {
return fmt.Errorf("manifest response has no loader name")
@ -283,8 +283,9 @@ func (m *ManifestResponse) Validate() error {
return nil
}
// Validates signatures stored in the manifest against keys in keyring, returns
// the number of valid signature matches
// VerifySignatures verifies the signatures present in a manifest response against the keys
// present in keyring. It returns the number of valid unique signatures identified in the
// ManifestResponse.
func (m *ManifestResponse) VerifySignatures(keyring io.Reader) (validcnt int, err error) {
var sigs []string
@ -335,20 +336,17 @@ func (m *ManifestResponse) VerifySignatures(keyring io.Reader) (validcnt int, er
return
}
// Describes individual file elements within a manifest
// ManifestEntry describes an individual file element within a manifest
type ManifestEntry struct {
Name string `json:"name"` // Corresponds to a bundle name
SHA256 string `json:"sha256"` // SHA256 of entry
}
// The bundle dictionary is used to map tokens within the loader manifest to
// BundleDictionaryEntry is used to map tokens within the loader manifest to
// objects on the file system. We don't allow specification of an exact path
// for interrogation or manipulation in the manifest. This results in some
// restrictions but hardens the loader against making unauthorized changes
// to the file system.
//
// If a Transform function is set on the entry, this is used to transform
// bytes into the data set prior to hash calculation
type BundleDictionaryEntry struct {
Name string
Path string
@ -393,12 +391,15 @@ var bundleEntryWindows = []BundleDictionaryEntry{
{"loaderconfig", "C:\\mig\\mig-loader.cfg", "", 0600},
}
// BundleDictionary maps GOOS platform names to specific bundle entry values
var BundleDictionary = map[string][]BundleDictionaryEntry{
"linux": bundleEntryLinux,
"darwin": bundleEntryDarwin,
"windows": bundleEntryWindows,
}
// GetHostBundle returns the correct BundleDictionaryEntry given the platform the
// code is executing on
func GetHostBundle() ([]BundleDictionaryEntry, error) {
switch runtime.GOOS {
case "linux":
@ -411,7 +412,7 @@ func GetHostBundle() ([]BundleDictionaryEntry, error) {
return nil, fmt.Errorf("no entry for %v in bundle dictionary", runtime.GOOS)
}
// Populates a slice of BundleDictionaryEntrys, adding the SHA256 checksums
// HashBundle populates a slice of BundleDictionaryEntrys, adding the SHA256 checksums
// from the file system
func HashBundle(b []BundleDictionaryEntry) ([]BundleDictionaryEntry, error) {
ret := b

Просмотреть файл

@ -889,7 +889,7 @@ func sendResults(ctx *Context, result mig.Command) (err error) {
panic(err)
}
err = publish(ctx, mig.Mq_Ex_ToSchedulers, mig.Mq_Q_Results, body)
err = publish(ctx, mig.ExchangeToSchedulers, mig.QueueAgentResults, body)
if err != nil {
panic(err)
}
@ -930,7 +930,7 @@ func heartbeat(ctx *Context) (err error) {
}
desc := fmt.Sprintf("heartbeat %q", body)
ctx.Channels.Log <- mig.Log{Desc: desc}.Debug()
publish(ctx, mig.Mq_Ex_ToSchedulers, mig.Mq_Q_Heartbeat, body)
publish(ctx, mig.ExchangeToSchedulers, mig.QueueAgentHeartbeat, body)
// update the local heartbeat file
err = ioutil.WriteFile(path.Join(ctx.Agent.RunDir, "mig-agent.ok"), []byte(time.Now().String()), 0644)
if err != nil {

Просмотреть файл

@ -498,10 +498,10 @@ func initMQ(orig_ctx Context, try_proxy bool, proxy string) (ctx Context, err er
}
err = ctx.MQ.Chan.QueueBind(ctx.MQ.Bind.Queue, // Queue name
ctx.MQ.Bind.Key, // Routing key name
mig.Mq_Ex_ToAgents, // Exchange name
false, // is noWait
nil) // AMQP args
ctx.MQ.Bind.Key, // Routing key name
mig.ExchangeToAgents, // Exchange name
false, // is noWait
nil) // AMQP args
if err != nil {
panic(err)
}

Просмотреть файл

@ -24,12 +24,12 @@ func startHeartbeatsListener(ctx Context) (heartbeatChan <-chan amqp.Delivery, e
ctx.Channels.Log <- mig.Log{OpID: ctx.OpID, Desc: "leaving startHeartbeatsListener()"}.Debug()
}()
_, err = ctx.MQ.Chan.QueueDeclare(mig.Mq_Q_Heartbeat, true, false, false, false, nil)
_, err = ctx.MQ.Chan.QueueDeclare(mig.QueueAgentHeartbeat, true, false, false, false, nil)
if err != nil {
panic(err)
}
err = ctx.MQ.Chan.QueueBind(mig.Mq_Q_Heartbeat, mig.Mq_Q_Heartbeat, mig.Mq_Ex_ToSchedulers, false, nil)
err = ctx.MQ.Chan.QueueBind(mig.QueueAgentHeartbeat, mig.QueueAgentHeartbeat, mig.ExchangeToSchedulers, false, nil)
if err != nil {
panic(err)
}
@ -39,7 +39,7 @@ func startHeartbeatsListener(ctx Context) (heartbeatChan <-chan amqp.Delivery, e
panic(err)
}
heartbeatChan, err = ctx.MQ.Chan.Consume(mig.Mq_Q_Heartbeat, "", true, false, false, false, nil)
heartbeatChan, err = ctx.MQ.Chan.Consume(mig.QueueAgentHeartbeat, "", true, false, false, false, nil)
if err != nil {
panic(err)
}
@ -176,12 +176,12 @@ func startResultsListener(ctx Context) (resultsChan <-chan amqp.Delivery, err er
ctx.Channels.Log <- mig.Log{OpID: ctx.OpID, Desc: "leaving startResultsListener()"}.Debug()
}()
_, err = ctx.MQ.Chan.QueueDeclare(mig.Mq_Q_Results, true, false, false, false, nil)
_, err = ctx.MQ.Chan.QueueDeclare(mig.QueueAgentResults, true, false, false, false, nil)
if err != nil {
panic(err)
}
err = ctx.MQ.Chan.QueueBind(mig.Mq_Q_Results, mig.Mq_Q_Results, mig.Mq_Ex_ToSchedulers, false, nil)
err = ctx.MQ.Chan.QueueBind(mig.QueueAgentResults, mig.QueueAgentResults, mig.ExchangeToSchedulers, false, nil)
if err != nil {
panic(err)
}
@ -191,7 +191,7 @@ func startResultsListener(ctx Context) (resultsChan <-chan amqp.Delivery, err er
panic(err)
}
resultsChan, err = ctx.MQ.Chan.Consume(mig.Mq_Q_Results, "", true, false, false, false, nil)
resultsChan, err = ctx.MQ.Chan.Consume(mig.QueueAgentResults, "", true, false, false, false, nil)
if err != nil {
panic(err)
}

Просмотреть файл

@ -290,12 +290,12 @@ func initRelay(orig_ctx Context) (ctx Context, err error) {
panic(err)
}
// declare the "toagents" exchange used for communication from schedulers to agents
err = ctx.MQ.Chan.ExchangeDeclare(mig.Mq_Ex_ToAgents, "direct", true, false, false, false, nil)
err = ctx.MQ.Chan.ExchangeDeclare(mig.ExchangeToAgents, "direct", true, false, false, false, nil)
if err != nil {
panic(err)
}
// declare the "toschedulers" exchange used for communication from agents to schedulers
err = ctx.MQ.Chan.ExchangeDeclare(mig.Mq_Ex_ToSchedulers, "direct", true, false, false, false, nil)
err = ctx.MQ.Chan.ExchangeDeclare(mig.ExchangeToSchedulers, "direct", true, false, false, false, nil)
if err != nil {
panic(err)
}

Просмотреть файл

@ -228,7 +228,7 @@ func sendCommands(cmds []mig.Command, ctx Context) (err error) {
}
agtQueue := fmt.Sprintf("mig.agt.%s", cmd.Agent.QueueLoc)
go func() {
err = ctx.MQ.Chan.Publish(mig.Mq_Ex_ToAgents, agtQueue, true, false, msg)
err = ctx.MQ.Chan.Publish(mig.ExchangeToAgents, agtQueue, true, false, msg)
if err != nil {
ctx.Channels.Log <- mig.Log{OpID: ctx.OpID, ActionID: cmd.Action.ID, CommandID: cmd.ID, Desc: "publishing failed to queue" + agtQueue}.Err()
} else {

Просмотреть файл

@ -6,7 +6,8 @@
package mig /* import "mig.ninja/mig" */
// Describes results that are produced by mig-runner
// RunnerResult describes results that are produced by mig-runner. This data
// would be consumed by mig-runner plugins.
type RunnerResult struct {
Action Action `json:"action"`
Commands []Command `json:"commands"`

Просмотреть файл

@ -10,7 +10,7 @@ package mig /* import "mig.ninja/mig" */
// components. You'd typically want to set this during install using flags
// such as -ldflags "-X mig.ninja/mig.Version=20170913-0.06824ce0.dev" when
// calling the go build tools.
var Version string = ""
var Version = ""
func init() {
// If the default value of Version is not being specified using the build