Exemplo n.º 1
0
func (gc *GlobalConfig) Parse(data map[interface{}]interface{}, config *entity.Config) (err error) {

	if config == nil {
		config = entity.NewConfig()
	}

	//Parse default section.
	defaultSection, ok := data["default"].(map[interface{}]interface{})
	if ok {
		config.DefaultCredential.User, ok = defaultSection["user"].(string)
		config.DefaultCredential.Pass, ok = defaultSection["pass"].(string)
		config.DefaultCredential.Identity, ok = defaultSection["identity"].(string)
	}

	//Parse host section.
	hostSection, ok := data["host"].(map[interface{}]interface{})
	if ok {
		var tmpCred *entity.Credential
		for hostName, _ := range hostSection {
			hostEntry, ok := hostSection[hostName.(string)].(map[interface{}]interface{})
			if !ok {
				err = errors.New("Invalid host section entry. host name: " + hostName.(string))
				return
			}
			tmpCred = entity.NewCredential()
			tmpCred.User, ok = hostEntry["user"].(string)
			tmpCred.Pass, ok = hostEntry["pass"].(string)
			tmpCred.Identity, ok = hostEntry["identity"].(string)

			config.Hosts[hostName.(string)] = tmpCred
		}
	}
	return
}
Exemplo n.º 2
0
// Parse data from given byte slices.
func (c *Config) Parse(data []byte, conf *entity.Config) (err error) {
	var parseResult interface{}
	err = yaml.Unmarshal(data, &parseResult)
	if err != nil {
		return
	}

	if conf == nil {
		conf = entity.NewConfig()
	}

	// Get "input" section.
	inputSettingSection, ok := parseResult.(map[interface{}]interface{})["input"]
	if !ok {
		err = errors.New("'input' section not found.")
		return
	}
	inputSettingEntries, _ := inputSettingSection.(map[interface{}]interface{})
	for name, entry := range inputSettingEntries {
		err = c.parseInputSectionEntry(conf, name.(string), entry.(map[interface{}]interface{}))
		if err != nil {
			return
		}
	}

	logSection, ok := parseResult.(map[interface{}]interface{})["log"].(map[interface{}]interface{})
	if ok {
		err = c.parseLogSection(conf, logSection)
		if err != nil {
			return
		}
	}

	return
}
Exemplo n.º 3
0
func TestGetDefaultCrediential(t *testing.T) {

	config := entity.NewConfig()

	defaultCred := entity.NewCredential()
	defaultCred.User = "******"

	hostACred := entity.NewCredential()
	hostACred.User = "******"

	hostBCred := entity.NewCredential()
	hostBCred.User = "******"

	config.DefaultCredential = defaultCred
	config.Hosts["host-a"] = hostACred
	config.Hosts["host-b"] = hostBCred

	result := config.GetDefaultCredential("host-a")
	if result.User != "host-a-user" {
		t.Log("host-a user not matched.")
		t.Fail()
	}

	result = config.GetDefaultCredential("host-b")
	if result.User != "host-b-user" {
		t.Log("host-b user not matched.")
		t.Fail()
	}

	result = config.GetDefaultCredential("host-c")
	if result.User != "default-user" {
		t.Log("host-c user not matched.")
		t.Fail()
	}

	result = config.GetDefaultCredential("")
	if result.User != "default-user" {
		t.Log("empty host user not matched.")
		t.Fail()
	}
}
Exemplo n.º 4
0
func TestCreateEntitiesFromData(t *testing.T) {

	yamlString := []byte(`input:
  logA:
    type: ssh
    host:
      - 1.1.1.1
      - 2.2.2.2
    user: test
    pass: password
    command: abc
  logB:
    type: ssh
    host: 3.3.3.3
    user: test2
    pass: password2
    command: abc
`)

	var yamlData interface{}
	err := yaml.Unmarshal(yamlString, &yamlData)
	if err != nil {
		t.Log("Failed to parse yaml.")
		t.Fail()
		return
	}

	inputSection, ok := yamlData.(map[interface{}]interface{})["input"].(map[interface{}]interface{})
	if !ok {
		t.Log("Failed to find input section.")
		t.Fail()
		return
	}

	var entries []entity.InputEntry
	var tempEntries []entity.InputEntry
	config := entity.NewConfig()
	inputEntryParser := extssh.NewInputEntryParser()
	for name, inputEntry := range inputSection {
		input, ok := inputEntry.(map[interface{}]interface{})
		if !ok {
			t.Log("Failed to find input entry.")
			t.Fail()
			return
		}

		tempEntries, err = inputEntryParser.CreateInputEntriesFromData(config, name.(string), input)
		if err != nil {
			t.Log("Failed to parse input entry.")
			t.Fail()
			return
		}
		entries = append(entries, tempEntries...)
	}

	if len(entries) != 3 {
		t.Logf("Config entry count does not matched. expected: 3, actual: %d", len(entries))
		t.Fail()
		return
	}

	expects := []map[string]string{
		{"host": "1.1.1.1", "name": "logA", "user": "******"},
		{"host": "2.2.2.2", "name": "logA", "user": "******"},
		{"host": "3.3.3.3", "name": "logB", "user": "******"},
	}

	for i, expected := range expects {
		entry := entries[i].(*extssh.InputEntry)

		if entry.Host != expected["host"] {
			t.Logf("Host is not expected. index=%d: value=%s", i, entry.Host)
			t.Fail()
		}
		if entry.Name != expected["name"] {
			t.Logf("Log name is not expected. index=%d: value=%s", i, entry.Name)
			t.Fail()
		}
		if entry.Cred.User != expected["user"] {
			t.Logf("user is not expected. index=%d: value=%s", i, entry.Cred.User)
			t.Fail()
		}
	}

}
Exemplo n.º 5
0
func TestParse(t *testing.T) {

	extensionManager := lib.NewExtensionManager()
	extensionManager.RegisterExtensionPoint(ext.POINT_INPUT_CONFIG_PARSER, extssh.NewInputEntryParser())

	cs := service.NewConfig(extensionManager)

	yaml := []byte(`
input:
  test01:
    type: ssh
    host:
      - example.com
      - example02.com
    user: user_name
    identity: identity-file-name
    command: testtest
log:
  logging: true
  path: /tmp/test.log
`)

	conf := entity.NewConfig()
	err := cs.Parse(yaml, conf)
	if err != nil {
		t.Logf(err.Error())
		t.Fail()
	}

	if len(conf.InputEntries) != 2 {
		t.Logf("input handler count. expected: 1, actual: %d", len(conf.InputEntries))
		t.Fail()
	}

	inputSsh := conf.InputEntries[0].(*extssh.InputEntry)
	if inputSsh.Name != "test01" {
		t.Logf("input handler name not matched. expected: test01, actual: %s", inputSsh.Name)
		t.Fail()
	}
	if inputSsh.Host != "example.com" {
		t.Logf("host name not matched. expected: example.com, actual: %s", inputSsh.Host)
		t.Fail()
	}

	inputSsh2 := conf.InputEntries[1].(*extssh.InputEntry)
	if inputSsh2.Name != "test01" {
		t.Logf("input handler name not matched. expected: test01, actual: %s", inputSsh2.Name)
		t.Fail()
	}
	if inputSsh2.Host != "example02.com" {
		t.Logf("host name not matched. expected: example02.com, actual: %s", inputSsh2.Host)
		t.Fail()
	}

	if conf.Logging != true {
		t.Logf("Logging not enabled.")
		t.Fail()
	}
	if conf.LogPath != "/tmp/test.log" {
		t.Logf("LogPath not matched. actual: " + conf.LogPath)
		t.Fail()
	}
}
Exemplo n.º 6
0
// This function is application main procedure.
// Open input handlers and read them output until all input handler ends.
func (a *Application) mainCommand(options *StartupOptions) {
	var err error

	a.config = entity.NewConfig()
	err = a.loadConfig(options.ConfigFile, a.config)
	if err != nil {
		log.Println(err.Error())
		return
	}

	//Prepare logging if needed.
	if a.config.Logging {
		err = a.initLogging(a.config.LogPath)
		if err != nil {
			log.Println(err.Error())
			return
		}
	}

	//Create output channel.
	//All input handler communicate with this channel.
	outputData := make(chan entity.InputData, 0)

	//Initialize input handlers.
	inputHandlers := make(map[string]ext.InputHandler)
	endFlagList := make(map[string]bool)
	for _, inputEntry := range a.config.InputEntries {
		inputHandlerFactory, found := a.extensionManager.GetExtensionPoint(ext.POINT_INPUT_HANDLER_FACTORY, inputEntry.GetType())
		if !found {
			panic(fmt.Sprintf("invalid input handler: %s", inputEntry.GetType()))
		}
		inputHandler := inputHandlerFactory.(ext.InputHandlerFactory).NewInputHandler(inputEntry)
		inputHandlers[inputHandler.GetName()] = inputHandler
	}

	//Start listen.
	//Handler runs asynchronously in goroutine.
	for name, ih := range inputHandlers {
		go ih.ReadInput(outputData)
		endFlagList[name] = false
	}

	//Wait outputData channel receive a data.
	//This loop continues until all input handler exits.
	var inputData entity.InputData
	allEndFlag := false
	for {
		inputData = <-outputData

		if inputData.State == entity.INPUT_DATA_END {
			endFlagList[inputData.Name] = true
		}

		allEndFlag = true
		for _, isEnd := range endFlagList {
			if !isEnd {
				allEndFlag = false
			}
		}
		if allEndFlag {
			log.Println("all handler stopped correctly.")
			break
		}

		//Output read data line by line.
		a.outputLines(inputData.Name, inputData.Data)
	}

}
Exemplo n.º 7
0
func TestGlobalConfigParse(t *testing.T) {
	globalConfigService := service.NewGlobalConfig()

	yamlData := []byte(`default:
  user: default-user
  pass: default-pass
  identity: default-identity

host:
  host-a:
    user: host-a-user
    pass: host-a-pass
    identity: host-a-identity
  host-b:
    user: host-b-user
    pass: host-b-pass
    identity: host-b-identity
`)

	var data map[interface{}]interface{}
	data = make(map[interface{}]interface{})
	err := yaml.Unmarshal(yamlData, data)
	if err != nil {
		t.Log(err.Error())
		t.Fail()
		return
	}

	config := entity.NewConfig()
	err = globalConfigService.Parse(data, config)
	if err != nil {
		t.Log(err.Error())
		t.Fail()
		return
	}

	if config.DefaultCredential.User != "default-user" {
		t.Log("DefaultCredential.User not matched.")
		t.Logf("%#v", config.DefaultCredential)
		t.Fail()
	}
	if config.DefaultCredential.Pass != "default-pass" {
		t.Log("DefaultCredential.Pass not matched.")
		t.Fail()
	}
	if config.DefaultCredential.Identity != "default-identity" {
		t.Log("DefaultCredential.Identity not matched.")
		t.Fail()
	}

	hosts := map[string]map[string]string{
		"host-a": {"user": "******", "pass": "******", "identity": "host-a-identity"},
		"host-b": {"user": "******", "pass": "******", "identity": "host-b-identity"},
	}

	for hostName, host := range hosts {
		hostCredential := config.Hosts[hostName]

		if config.Hosts[hostName].User != host["user"] {
			t.Logf("host '%s': user does not matched.", hostCredential.User)
			t.Fail()
			return
		}

		if config.Hosts[hostName].Pass != host["pass"] {
			t.Logf("host '%s': pass does not matched.", hostCredential.Pass)
			t.Fail()
			return
		}
		if config.Hosts[hostName].Identity != host["identity"] {
			t.Logf("host '%s': identity does not matched.", hostCredential.Identity)
			t.Fail()
			return
		}
	}
}