зеркало из https://github.com/mozilla/mig.git
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:
Родитель
d4edb097d7
Коммит
034de6f3da
8
acl.go
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
|
||||
|
|
70
action.go
70
action.go
|
@ -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, "", " ")
|
||||
|
|
7
agent.go
7
agent.go
|
@ -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"`
|
||||
|
|
13
command.go
13
command.go
|
@ -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
|
||||
}
|
||||
|
|
18
constants.go
18
constants.go
|
@ -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"
|
||||
|
|
38
loader.go
38
loader.go
|
@ -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()
|
||||
|
|
47
manifest.go
47
manifest.go
|
@ -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
|
||||
|
|
Загрузка…
Ссылка в новой задаче