// Poolhba right now this is simple, just read the template and spit it back // out, no substitutions are done right now, they will be in the future no doubt func Poolhba(cars []Rule) (string, error) { var hbaInfo HBAParameters hbaInfo.RULES_LIST = cars logit.Info.Println("here are the cars in Poolhba...") logInfo(hbaInfo) var path = util.GetBase() + "/conf/" + "pgpool/pool_hba.conf.template" contents, err := ioutil.ReadFile(path) if err != nil { return "", err } tmpl, err := template.New("pgpoolhba").Parse(string(contents)) if err != nil { return "", err } buff := bytes.NewBufferString("") err = tmpl.Execute(buff, hbaInfo) logit.Info.Println("Poolhba:" + buff.String()) return buff.String(), nil }
// Postgresql create a postgresql.conf file from a template and passed values, return the new file contents func Postgresql(mode string, info *PostgresqlParameters) (string, error) { logit.Info.Println("in template.Postgresql with TUNE_MWM=" + info.TUNE_MWM) var path string switch mode { case "standalone", "master", "standby": path = util.GetBase() + "/conf/" + mode + "/postgresql.conf.template" default: return "", errors.New("invalid mode in processPostgresql of " + mode) } contents, err := ioutil.ReadFile(path) if err != nil { return "", err } tmpl, err := template.New("postgresql").Parse(string(contents)) if err != nil { return "", err } buff := bytes.NewBufferString("") err = tmpl.Execute(buff, info) return buff.String(), nil }
// Poolconf generates a pgpool.conf file from a template and // values passed in func Poolconf(poolnames []string) (string, error) { var poolParams PGPoolParameters poolParams.HOST_LIST = poolnames var path = util.GetBase() + "/conf/" + "pgpool/pgpool.conf.template" contents, err := ioutil.ReadFile(path) if err != nil { return "", err } tmpl, err := template.New("pgpoolconf").Parse(string(contents)) if err != nil { return "", err } buff := bytes.NewBufferString("") err = tmpl.Execute(buff, poolParams) logit.Info.Println("Poolconf:" + buff.String()) return buff.String(), nil }
// Poolpasswd right now this is simple, just read the template and spit it back // out, no substitutions are done right now, they will be in the future no doubt func Poolpasswd() (string, error) { var info RecoveryParameters var path = util.GetBase() + "/conf/" + "pgpool/pool_passwd.template" contents, err := ioutil.ReadFile(path) if err != nil { return "", err } tmpl, err := template.New("pgpoolpasswd").Parse(string(contents)) if err != nil { return "", err } buff := bytes.NewBufferString("") err = tmpl.Execute(buff, info) logit.Info.Println("Poolpasswd:" + buff.String()) return buff.String(), nil }
// Recovery create a recovery.conf file based on passed values and a template, return the file contents func Recovery(masterhost string, port string, masteruser string) (string, error) { var info RecoveryParameters info.PG_PORT = port info.USER = masteruser info.PG_HOST_IP = masterhost var path string path = util.GetBase() + "/conf/" + "standby/recovery.conf.template" contents, err := ioutil.ReadFile(path) if err != nil { return "", err } tmpl, err := template.New("recovery").Parse(string(contents)) if err != nil { return "", err } buff := bytes.NewBufferString("") err = tmpl.Execute(buff, info) return buff.String(), nil }
func configureCluster(profile string, dbConn *sql.DB, cluster types.Cluster, autocluster bool) error { logit.Info.Println("configureCluster:GetCluster") //get master node for this cluster master, err := admindb.GetContainerMaster(dbConn, cluster.ID) if err != nil { logit.Error.Println(err.Error()) return err } var pgport types.Setting pgport, err = admindb.GetSetting(dbConn, "PG-PORT") if err != nil { logit.Error.Println(err.Error()) return err } var sleepSetting types.Setting sleepSetting, err = admindb.GetSetting(dbConn, "SLEEP-PROV") if err != nil { logit.Error.Println("configureCluster:" + err.Error()) return err } //logit.Info.Println("configureCluster:GetContainerMaster") //configure master postgresql.conf file var data string info := new(template.PostgresqlParameters) info.PG_PORT = pgport.Value err = template.GetTuningParms(dbConn, profile, info) if err != nil { logit.Error.Println("configureCluster:" + err.Error()) return err } if cluster.ClusterType == "synchronous" { info.CLUSTER_TYPE = "*" data, err = template.Postgresql("master", info) } else { //TODO verify these next 2 lines look erroneous info.CLUSTER_TYPE = "*" data, err = template.Postgresql("master", info) //info.CLUSTER_TYPE = "" //data, err = template.Postgresql("master", info) } if err != nil { logit.Error.Println(err.Error()) return err } logit.Info.Println("configureCluster:master postgresql.conf generated") //write master postgresql.conf file remotely _, err = cpmcontainerapi.RemoteWritefileClient("/pgdata/postgresql.conf", data, master.Name) if err != nil { logit.Error.Println(err.Error()) return err } logit.Info.Println("configureCluster:master postgresql.conf copied to remote") //get domain name var domainname types.Setting domainname, err = admindb.GetSetting(dbConn, "DOMAIN-NAME") if err != nil { logit.Error.Println(err.Error()) return err } //configure master pg_hba.conf file rules := make([]template.Rule, 0) data, err = template.Hba(dbConn, "master", master.Name, pgport.Value, cluster.ID, domainname.Value, rules) if err != nil { logit.Error.Println(err.Error()) return err } logit.Info.Println("configureCluster:master pg_hba.conf generated") //write master pg_hba.conf file remotely _, err = cpmcontainerapi.RemoteWritefileClient("/pgdata/pg_hba.conf", data, master.Name) if err != nil { logit.Error.Println(err.Error()) return err } logit.Info.Println("configureCluster:master pg_hba.conf copied remotely") //restart postgres after the config file changes var stopResp cpmcontainerapi.StopPGResponse stopResp, err = cpmcontainerapi.StopPGClient(master.Name) if err != nil { logit.Error.Println(err.Error()) return err } logit.Info.Println("configureCluster: master stoppg output was" + stopResp.Output) var startResp cpmcontainerapi.StartPGResponse startResp, err = cpmcontainerapi.StartPGClient(master.Name) if err != nil { logit.Error.Println(err.Error()) return err } logit.Info.Println("configureCluster:master startpg output was" + startResp.Output) //sleep loop until the master's PG can respond var sleepTime time.Duration sleepTime, err = time.ParseDuration(sleepSetting.Value) var found = false var currentStatus string var masterhost = master.Name for i := 0; i < 20; i++ { //currentStatus, err = GetPGStatus2(dbConn, master.Name, masterhost) currentStatus, err = util.FastPing(pgport.Value, master.Name) if currentStatus == "RUNNING" { logit.Info.Println("master is running...continuing") found = true break } else { logit.Info.Println("sleeping waiting on master..") time.Sleep(sleepTime) } } if !found { logit.Info.Println("configureCluster: timed out waiting on master pg to start") return errors.New("timeout waiting for master pg to respond") } standbynodes, err2 := admindb.GetAllStandbyContainers(dbConn, cluster.ID) if err2 != nil { logit.Error.Println(err.Error()) return err } //configure all standby nodes var stopPGResp cpmcontainerapi.StopPGResponse i := 0 for i = range standbynodes { if standbynodes[i].Role == STANDBY { //stop standby if !autocluster { stopPGResp, err = cpmcontainerapi.StopPGClient(standbynodes[i].Name) if err != nil { logit.Error.Println(err.Error()) logit.Error.Println("configureCluster:stop output was" + stopPGResp.Output) return err } //logit.Info.Println("configureCluster:stop output was" + stopPGResp.Output) } // var username = "******" var password = "******" //create base backup from master var backupresp cpmcontainerapi.BasebackupResponse backupresp, err = cpmcontainerapi.BasebackupClient(masterhost+"."+domainname.Value, standbynodes[i].Name, username, password) if err != nil { logit.Error.Println(err.Error()) logit.Error.Println("configureCluster:basebackup output was" + backupresp.Output) return err } //logit.Info.Println("configureCluster:basebackup output was" + backupresp.Output) data, err = template.Recovery(masterhost, pgport.Value, "postgres") if err != nil { logit.Error.Println(err.Error()) return err } logit.Info.Println("configureCluster:standby recovery.conf generated") //write standby recovery.conf file remotely _, err = cpmcontainerapi.RemoteWritefileClient("/pgdata/recovery.conf", data, standbynodes[i].Name) if err != nil { logit.Error.Println(err.Error()) return err } logit.Info.Println("configureCluster:standby recovery.conf copied remotely") info := new(template.PostgresqlParameters) info.PG_PORT = pgport.Value info.CLUSTER_TYPE = "" err = template.GetTuningParms(dbConn, profile, info) if err != nil { logit.Error.Println(err.Error()) return err } data, err = template.Postgresql(STANDBY, info) if err != nil { logit.Error.Println(err.Error()) return err } //write standby postgresql.conf file remotely _, err = cpmcontainerapi.RemoteWritefileClient("/pgdata/postgresql.conf", data, standbynodes[i].Name) if err != nil { logit.Error.Println(err.Error()) return err } logit.Info.Println("configureCluster:standby postgresql.conf copied remotely") //configure standby pg_hba.conf file data, err = template.Hba(dbConn, STANDBY, standbynodes[i].Name, pgport.Value, cluster.ID, domainname.Value, rules) if err != nil { logit.Error.Println(err.Error()) return err } logit.Info.Println("configureCluster:standby pg_hba.conf generated") //write standby pg_hba.conf file remotely _, err = cpmcontainerapi.RemoteWritefileClient("/pgdata/pg_hba.conf", data, standbynodes[i].Name) if err != nil { logit.Error.Println(err.Error()) return err } logit.Info.Println("configureCluster:standby pg_hba.conf copied remotely") //start standby var stResp cpmcontainerapi.StartPGOnStandbyResponse stResp, err = cpmcontainerapi.StartPGOnStandbyClient(standbynodes[i].Name) if err != nil { logit.Error.Println(err.Error()) return err } logit.Info.Println("configureCluster:standby startpg output was" + stResp.Output) } i++ } logit.Info.Println("configureCluster: sleeping 5 seconds before configuring pgpool...") clustersleepTime, _ := time.ParseDuration("5s") time.Sleep(clustersleepTime) pgpoolNode, err4 := admindb.GetContainerPgpool(dbConn, cluster.ID) //logit.Info.Println("configureCluster: lookup pgpool node") if err4 != nil { logit.Error.Println(err.Error()) return err } //logit.Info.Println("configureCluster:" + pgpoolNode.Name) //configure the pgpool includes all standby nodes AND the master node poolnames := make([]string, len(standbynodes)+1) i = 0 for i = range standbynodes { poolnames[i] = standbynodes[i].Name + "." + domainname.Value i++ } poolnames[i] = master.Name + "." + domainname.Value //generate pgpool.conf HOST_LIST data, err = template.Poolconf(poolnames) if err != nil { logit.Error.Println(err.Error()) return err } logit.Info.Println("configureCluster:pgpool pgpool.conf generated") //write pgpool.conf to remote pool node _, err = cpmcontainerapi.RemoteWritefileClient(util.GetBase()+"/bin/"+"pgpool.conf", data, pgpoolNode.Name) if err != nil { logit.Error.Println(err.Error()) return err } logit.Info.Println("configureCluster:pgpool pgpool.conf copied remotely") //generate pool_passwd data, err = template.Poolpasswd() if err != nil { logit.Error.Println(err.Error()) return err } logit.Info.Println("configureCluster:pgpool pool_passwd generated") //write pgpool.conf to remote pool node _, err = cpmcontainerapi.RemoteWritefileClient(util.GetBase()+"/bin/"+"pool_passwd", data, pgpoolNode.Name) if err != nil { logit.Error.Println(err.Error()) return err } logit.Info.Println("configureCluster:pgpool pool_passwd copied remotely") //g enerate pool_hba.conf cars := make([]template.Rule, 0) data, err = template.Poolhba(cars) if err != nil { logit.Error.Println(err.Error()) return err } logit.Info.Println("configureCluster:pgpool pool_hba generated") //write pgpool.conf to remote pool node _, err = cpmcontainerapi.RemoteWritefileClient(util.GetBase()+"/bin/"+"pool_hba.conf", data, pgpoolNode.Name) if err != nil { logit.Error.Println(err.Error()) return err } logit.Info.Println("configureCluster:pgpool pool_hba copied remotely") //start pgpool var startPoolResp cpmcontainerapi.StartPgpoolResponse startPoolResp, err = cpmcontainerapi.StartPgpoolClient(pgpoolNode.Name) if err != nil { logit.Error.Println(err.Error()) return err } logit.Info.Println("configureCluster: pgpool startpgpool output was" + startPoolResp.Output) //finally, update the cluster to show that it is //initialized! cluster.Status = "initialized" err = admindb.UpdateCluster(dbConn, cluster) if err != nil { logit.Error.Println(err.Error()) return err } return nil }
// Hba create a pg_hba.conf file from a template and passed values, return the new file contents func Hba(dbConn *sql.DB, mode string, hostname string, port string, clusterid string, domainname string, cars []Rule) (string, error) { var hbaInfo HBAParameters //hbaInfo.PG_HOST_IP = hostname + "." + domainname //hbaInfo.BACKUP_HOST = hostname + "-backup." + domainname //hbaInfo.MONITOR_HOST = "cpm-mon." + domainname //hbaInfo.ADMIN_HOST = "cpm-admin." + domainname hbaInfo.PG_HOST_IP = hostname hbaInfo.BACKUP_HOST = hostname + "-backup" hbaInfo.MONITOR_HOST = "cpm-mon" hbaInfo.ADMIN_HOST = "cpm-admin" hbaInfo.RULES_LIST = cars bridges, err := admindb.GetSetting(dbConn, "DOCKER-BRIDGES") if err != nil { logit.Error.Println("Hba:" + err.Error()) return "", err } var infoResponse swarmapi.DockerInfoResponse infoResponse, err = swarmapi.DockerInfo() if err != nil { logit.Error.Println("Hba:" + err.Error()) return "", err } servers := make([]types.Server, len(infoResponse.Output)) i := 0 for i = range infoResponse.Output { parts := strings.Split(infoResponse.Output[i], ":") servers[i].IPAddress = parts[0] i++ } i = 0 var allservers = "" //TODO make this configurable as a setting value var allbridges = bridges.Value for i = range servers { logit.Info.Println("Hba:" + servers[i].IPAddress) if allservers == "" { allservers = servers[i].IPAddress //allbridges = servers[i].DockerBridgeIP } else { allservers = allservers + ":" + servers[i].IPAddress //allbridges = allbridges + ":" + servers[i].DockerBridgeIP } } logit.Info.Println("Hba:processing serverlist=" + allservers) hbaInfo.SERVER_IP_LIST = strings.Split(allservers, ":") hbaInfo.BRIDGE_IP_LIST = strings.Split(allbridges, ":") var path string switch mode { case "unassigned": path = util.GetBase() + "/conf/standalone/pg_hba.conf.template" case "standalone", "master", "standby": path = util.GetBase() + "/conf/" + mode + "/pg_hba.conf.template" default: return "", errors.New("invalid mode in processHba of " + mode) } if mode == "standby" || mode == "master" { _, pgpoolNode, standbyList, err := getMasterValues(dbConn, clusterid, domainname) if err != nil { return "", err } hbaInfo.PGPOOL_HOST = pgpoolNode.Name + "." + domainname hbaInfo.STANDBY_LIST = standbyList } contents, err := ioutil.ReadFile(path) if err != nil { return "", err } tmpl, err := template.New("hba").Parse(string(contents)) if err != nil { return "", err } buff := bytes.NewBufferString("") logInfo(hbaInfo) err = tmpl.Execute(buff, hbaInfo) logit.Info.Println("Hba:" + buff.String()) return buff.String(), nil }
func templateChange(dbConn *sql.DB, containerName string, cars []ContainerAccessRule, containerRole string) error { var err error logit.Info.Println("templateChange called") //create pg_hba.conf var mode = containerRole domainname, err := admindb.GetSetting(dbConn, "DOMAIN-NAME") if err != nil { logit.Error.Println("templateChange:DOMAIN-NAME error " + err.Error()) return err } rules := make([]template.Rule, 0) var ar Rule for i := range cars { logit.Info.Println("templateChange cars found") if cars[i].Selected == "true" { logit.Info.Println("templateChange cars found to be true") rule := template.Rule{} ar, err = GetAccessRule(dbConn, cars[i].AccessRuleID) if err != nil { logit.Error.Println("templateChange:get access rule error " + err.Error()) return err } rule.Type = ar.Type rule.Database = ar.Database rule.User = ar.User rule.Address = ar.Address rule.Method = ar.Method rules = append(rules, rule) } } logit.Info.Printf("templateChange rules going to template %d\n", len(rules)) var data string fqdn := containerName + "." + domainname.Value //place pg_hba.conf on node if containerRole == "pgpool" { //generate pool_hba.conf data, err = template.Poolhba(rules) if err != nil { logit.Error.Println(err.Error()) return err } logit.Info.Println("configureCluster:pgpool pool_hba generated") //write pgpool.conf to remote pool node var dest = util.GetBase() + "/bin/pool_hba.conf" _, err = cpmcontainerapi.RemoteWritefileClient(dest, data, fqdn) if err != nil { logit.Error.Println(err.Error()) return err } logit.Info.Println("configureCluster:pgpool pool_hba copied remotely") } else { data, err = template.Hba(dbConn, mode, containerName, "", "", domainname.Value, rules) if err != nil { logit.Error.Println("templateChange:" + err.Error()) return err } _, err = cpmcontainerapi.RemoteWritefileClient("/pgdata/pg_hba.conf", data, fqdn) if err != nil { logit.Error.Println("templateChange:" + err.Error()) return err } } return err }