зеркало из https://github.com/mozilla/mig.git
Merge pull request #410 from ameihm0912/mig-pkg-style
style related code cleanup in mig top-level package
This commit is contained in:
Коммит
910338e57d
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
|
||||
|
|
Загрузка…
Ссылка в новой задаче