Merge pull request #410 from ameihm0912/mig-pkg-style

style related code cleanup in mig top-level package
This commit is contained in:
Aaron Meihm 2017-10-26 16:19:34 -05:00 коммит произвёл GitHub
Родитель d4edb097d7 034de6f3da
Коммит 910338e57d
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