Пример #1
0
// NewCoreManager creates a new core plugin manager.
func NewCoreManager(instanceIdPtr *string, regionPtr *string, log logger.T) (cm *CoreManager, err error) {

	// initialize appconfig
	var config appconfig.SsmagentConfig
	if config, err = appconfig.Config(false); err != nil {
		log.Errorf("Could not load config file: %v", err)
		return
	}

	// initialize region
	if *regionPtr != "" {
		if err = platform.SetRegion(*regionPtr); err != nil {
			log.Errorf("error occured setting the region, %v", err)
			return
		}
	}

	var region string
	if region, err = platform.Region(); err != nil {
		log.Errorf("error fetching the region, %v", err)
		return
	}
	log.Debug("Using region:", region)

	// initialize instance ID
	if *instanceIdPtr != "" {
		if err = platform.SetInstanceID(*instanceIdPtr); err != nil {
			log.Errorf("error occured setting the instance ID, %v", err)
			return
		}
	}

	var instanceId string
	if instanceId, err = platform.InstanceID(); err != nil {
		log.Errorf("error fetching the instanceID, %v", err)
		return
	}
	log.Debug("Using instanceID:", instanceId)

	if err = fileutil.HardenDataFolder(); err != nil {
		log.Errorf("error initializing SSM data folder with hardened ACL, %v", err)
		return
	}

	//Initialize all folders where interim states of executing commands will be stored.
	if !initializeBookkeepingLocations(log, instanceId) {
		log.Error("unable to initialize. Exiting")
		return
	}

	context := context.Default(log, config).With("[instanceID=" + instanceId + "]")
	corePlugins := coreplugins.RegisteredCorePlugins(context)

	return &CoreManager{
		context:     context,
		corePlugins: *corePlugins,
	}, nil
}
Пример #2
0
func main() {
	defer log.Flush()
	commandPtr := flag.String("c", "", "a command")
	scriptFilePtr := flag.String("f", "", "a script file")
	dirPtr := flag.String("d", "", "working directory")
	bucketNamePtr := flag.String("b", "", "bucket name")
	keyPrefixPtr := flag.String("k", "", "bucket key prefix")
	cancelPtr := flag.Bool("cancel", false, "cancel command on key press")
	typePtr := flag.String("type", "", "instance type (windows, ubuntu or aml)")
	instanceIDPtr := flag.String("i", "", "instance id")
	regionPtr := flag.String("r", "us-east-1", "instance region")
	flag.Parse()
	var timeout int64 = 10000
	timeoutPtr := &timeout
	var err error
	err = platform.SetRegion(*regionPtr)
	if err != nil {
		log.Error("please specify the region to use.")
		return
	}

	if *commandPtr == "" && *scriptFilePtr == "" {
		fmt.Println("No commands specified (use either -c or -f).")
		flag.Usage()
		return
	}
	if *keyPrefixPtr == "" {
		keyPrefixPtr = nil
	}
	if *bucketNamePtr == "" {
		bucketNamePtr = nil
		if keyPrefixPtr != nil {
			defaultBucket := "ec2configservice-ssm-logs"
			bucketNamePtr = &defaultBucket
		}
	}

	var cc consoleConfig
	err = jsonutil.UnmarshalFile("integration-cli.json", &cc)
	if err != nil {
		log.Error("error parsing consoleConfig ", err)
		return
	}

	// specific instance is provided use only that
	if *instanceIDPtr != "" {
		cc.Instances = make(map[string]string)
		if *typePtr != "" {
			cc.Instances[*instanceIDPtr] = *typePtr
		} else {
			cc.Instances[*instanceIDPtr] = "aml"
		}
	} else {
		// other wise select or filter from the consoleConfig file list
		if *typePtr != "" {
			for instanceID, instanceType := range cc.Instances {
				if instanceType != *typePtr {
					delete(cc.Instances, instanceID)
				}
			}
			if len(cc.Instances) == 0 {
				log.Error("no instances of type ", *typePtr)
				return
			}
		}
	}

	ssmSvc := ssm.NewService()
	if ssmSvc == nil {
		log.Error("couldn't create ssm service.")
		return
	}

	var instanceIDs []string
	// first get windows instances (bug in SSM if first instance is not win)
	for instanceID, instanceType := range cc.Instances {
		if instanceType == "windows" {
			instanceIDs = append(instanceIDs, instanceID)
		}
	}
	// then get rest of the instances
	for instanceID, instanceType := range cc.Instances {
		if instanceType != "windows" {
			instanceIDs = append(instanceIDs, instanceID)
		}
	}
	docName := "AWS-BETA-RunShellScript"
	if runtime.GOOS == "windows" {
		docName = "AWS-RunPowerShellScript"
	}

	var commands []string
	if *commandPtr != "" {
		commands = []string{*commandPtr}
	} else {
		f, err := os.Open(*scriptFilePtr)
		if err != nil {
			log.Error(err)
			return
		}
		scanner := bufio.NewScanner(f)
		for scanner.Scan() {
			commands = append(commands, scanner.Text())
		}
	}

	for i := 0; i < len(commands); i++ {
		// escape backslashes
		commands[i] = strings.Replace(commands[i], `\`, `\\`, -1)

		// escape double quotes
		commands[i] = strings.Replace(commands[i], `"`, `\"`, -1)

		// escape single quotes
		//		commands[i] = strings.Replace(commands[i], `'`, `\'`, -1)
	}

	parameters := map[string][]*string{
		"commands":         aws.StringSlice(commands),
		"workingDirectory": aws.StringSlice([]string{*dirPtr}),
	}

	log.Infof("Sending command %v", parameters)

	cmd, err := ssmSvc.SendCommand(log, docName, instanceIDs, parameters, timeoutPtr, bucketNamePtr, keyPrefixPtr)
	if cmd == nil || cmd.Command == nil || cmd.Command.CommandId == nil {
		log.Error("command was not created. Aborting!")
		return
	}

	if *cancelPtr {
		log.Info("Press any key to cancel command")
		var b = make([]byte, 1)
		os.Stdin.Read(b)
		log.Info("Canceling command ")
		ssmSvc.CancelCommand(log, *cmd.Command.CommandId, instanceIDs)
	}

	log.Info("================== Looping for results ================")
	log.Flush()
	time.Sleep(1000 * time.Millisecond)
	for {
		done := true
	inst:
		for instanceID, instanceType := range cc.Instances {
			descr := fmt.Sprintf("%v [%v]", instanceID, instanceType)
			out, err := ssmSvc.ListCommandInvocations(log, instanceID, *cmd.Command.CommandId)
			if err != nil {
				continue
			}
			for _, inv := range out.CommandInvocations {
				if *inv.Status == "Pending" {
					log.Infof("Instance %v is in status %v; waiting some more", descr, *inv.Status)
					done = false
					continue inst
				}

				data, err := json.Marshal(inv)
				if err != nil {
					log.Error(err)
					continue
				}
				log.Debug(jsonutil.Indent(string(data)))

				for _, cp := range inv.CommandPlugins {
					if cp.Output == nil {
						log.Errorf("Output Nil for %v", descr)
						continue
					}

					var o interface{}
					err := json.Unmarshal([]byte(*cp.Output), &o)
					if err != nil {
						log.Errorf("error parsing %v\n err=%v", *cp.Output, err)
					}
					log.Info(descr, " : ", prettyPrint(o, 0))
				}
			}
		}
		if done {
			break
		}
		time.Sleep(3000 * time.Millisecond)
	}

	//	c.Wait()*/
}