func GetConfigValue(session *ini.Section, key string) (string, error) { if session.HasKey(key) { return session.Key(key).String(), nil } else { return "", fmt.Errorf("Can not find %s configuration", key) } }
// Currently supported: []string, []int (32 bit). // TODO: struct tags for int size, struct tags for separator, more types. func processSliceField(field reflect.Value, section *ini.Section, kvName string) reflect.Value { // Prepare list: stringList := strings.Split(section.Key(kvName).String(), ",") for idx, val := range stringList { stringList[idx] = strings.TrimSpace(val) } // Get contained type: fieldKind := field.Type().Elem().Kind() // Handle each type differently. // Strings are just returned. if fieldKind == reflect.String { return reflect.ValueOf(stringList) // Ints are converted by base 10, length 32 bits. } else if fieldKind == reflect.Int { intList := []int{} for _, str := range stringList { i, err := strconv.ParseInt(str, 10, 32) if err != nil { infoLogger.Fatalln("Error parsing 32 bit integer for field "+ string(kvName), err) } intList = append(intList, int(i)) } return reflect.ValueOf(intList) // Everything else should trigger an error. } else { infoLogger.Fatalln("Do not know what to do with slice of " + string(fieldKind)) } // Failsafe if the error fails: Empty new iface satisfying the type. return reflect.New(field.Type()).Elem() }
func execCommand(log *logging.Logger, section *ini.Section, command string) error { var buff *bufio.Reader var conn net.Conn var cmd common.JSONMessage var res common.JSONResult var err error var result []byte if section.Key(command).String() != "" { conn, err = network.GetSocket(section) if err != nil { return errorMsg(log, 1, "Connection with "+command+" failed: "+err.Error()) } defer conn.Close() buff = bufio.NewReader(conn) cmd = common.JSONMessage{} cmd.Context = "system" cmd.Command.Name = "exec" cmd.Command.Cmd = section.Key(command).String() if err = cmd.Send(conn); err != nil { return errorMsg(log, 2, "Sending "+command+" failed: "+err.Error()) } else { result, err = buff.ReadBytes('\n') if err != nil { log.Error("Receive " + command + " result failed: " + err.Error()) } err = json.Unmarshal(result, &res) if err != nil { msg := "Response result for " + command + " failed: " + err.Error() log.Error(msg) return errorMsg(log, 3, msg) } if res.Result == "ok" { log.Debug("Executed " + command) return nil } else { return errorMsg(log, 4, "Error in "+command+" execution: "+res.Message) } } } else { return nil } }
func GetSocket(cfg *ini.Section) (net.Conn, error) { var conn net.Conn var err error host := cfg.Key("host").String() port := cfg.Key("port").String() address := host + ":" + port if _, err = net.ResolveTCPAddr("tcp", address); err != nil { return nil, err } if cfg.Key("ssl").MustBool() { key := cfg.Key("sslcert").String() private := cfg.Key("sslkey").String() cert, err := tls.LoadX509KeyPair(key, private) if err != nil { err = errors.New("Error when loading SSL certificate: " + err.Error()) return nil, err } caCert, err := ioutil.ReadFile(key) if err != nil { return nil, err } caCertPool := x509.NewCertPool() caCertPool.AppendCertsFromPEM(caCert) config := tls.Config{ RootCAs: caCertPool, Certificates: []tls.Certificate{cert}, } now := time.Now() config.Time = func() time.Time { return now } config.Rand = rand.Reader conn, err = tls.Dial("tcp", address, &config) if err != nil { return nil, err } } else { conn, err = net.Dial("tcp", address) if err != nil { return nil, err } } return conn, err }
// Currently supported: string, int. // TODO: struct tags for int size, more types. func processField(field reflect.Value, section *ini.Section, kvName string) reflect.Value { // Get contained type: fieldKind := field.Kind() // Per type treatment: // Strings are trimmed then assigned directly. if fieldKind == reflect.String { strVal := strings.TrimSpace(section.Key(kvName).String()) return reflect.ValueOf(strVal) // Integers are converted by base 10, length 32 bits. } else if fieldKind == reflect.Int { intVal, err := section.Key(kvName).Int() if err != nil { infoLogger.Fatalf("Unable to parse %s='%s' as int.", kvName, section.Key(kvName).String()) } return reflect.ValueOf(intVal) } else { infoLogger.Fatalln("Do not know what to do with type " + string(fieldKind)) } // Failsafe if the error fails: Empty new iface satisfying the type. return reflect.New(field.Type()).Elem() }