diff --git a/config.go b/config.go index 049204f..9334560 100644 --- a/config.go +++ b/config.go @@ -6,17 +6,26 @@ import ( "log" "os" "strconv" + "strings" "github.com/joho/godotenv" + "gopkg.in/yaml.v3" ) const ( - ConfigEmail = "EMAIL" - ConfigToken = "API_TOKEN" + ConfigEmail = "EMAIL" + ConfigToken = "API_TOKEN" ConfigDomain = "DOMAIN" - ConfigHosts = "HOSTS" + ConfigHosts = "HOSTS" ) +type ConfigModel struct { + Email string `yaml:"Email"` + Token string `yaml:"Token"` + Domain string `yaml:"Domain"` + Hosts []string `yaml:"Hosts"` +} + type ConfigClient struct{} func NewConfigClient() ConfigClient { @@ -26,6 +35,35 @@ func NewConfigClient() ConfigClient { return c } +func (cc *ConfigClient) LoadConfig() ConfigModel { + // load yaml first + + model, err := LoadYaml("config.yaml") + if err != nil { + log.Print(err) + } + + // refresh env to make sure its current + cc.RefreshEnv() + + // if no domains pulled from yaml, load from env + if len(model.Hosts) == 0 { + envHosts := cc.GetConfig(ConfigHosts) + model.Hosts = append(model.Hosts, strings.Split(envHosts, ",")...) + } + if model.Domain == "" { + model.Domain = cc.GetConfig(ConfigDomain) + } + if model.Email == "" { + model.Email = cc.GetConfig(ConfigEmail) + } + if model.Token == "" { + model.Token = cc.GetConfig(ConfigToken) + } + + return model +} + func (cc *ConfigClient) GetConfig(key string) string { res, filled := os.LookupEnv(key) if !filled { @@ -69,4 +107,34 @@ func loadEnvFile() { if err != nil { log.Fatalln(err) } -} \ No newline at end of file +} + +func (cc *ConfigClient) IsConfigInCurrentDirectory(fileName string) error { + _, err := os.Stat(fileName) + if err != nil { + return err + } + return nil +} + +func LoadYaml(yamlFile string) (ConfigModel, error) { + var results = ConfigModel{} + + // check for the config in the current directory + _, err := os.Stat(yamlFile) + if err != nil { + return ConfigModel{}, err + } + + content, err := os.ReadFile(yamlFile) + if err != nil { + return ConfigModel{}, err + } + + err = yaml.Unmarshal(content, &results) + if err != nil { + return ConfigModel{}, err + } + + return results, nil +} diff --git a/cron.go b/cron.go index bf5dc02..2ec596d 100644 --- a/cron.go +++ b/cron.go @@ -7,7 +7,7 @@ import ( "github.com/robfig/cron/v3" ) -type cronClient struct{ +type cronClient struct { scheduler *cron.Cron } @@ -37,17 +37,18 @@ func (c cronClient) RunCloudflareCheck(ApiToken string, Email string, Domain str log.Println(err) return } - + for _, host := range Hosts { hostname := fmt.Sprintf("%v.%v", host, Domain) log.Printf("Reviewing '%v'", hostname) dns, err := cf.GetDnsEntriesByDomain(domainDetails.Result[0].ID, host, Domain) if err != nil { log.Println("failed to collect dns entry") - return + return } - - if dns.Result[0].Content != currentIp { + + var result = dns.Result[0] + if result.Content != currentIp { log.Println("IP Address no longer matches, sending an update") err = cf.UpdateDnsEntry(domainDetails.Result[0].ID, dns, currentIp) if err != nil { @@ -56,4 +57,8 @@ func (c cronClient) RunCloudflareCheck(ApiToken string, Email string, Domain str } } log.Println("Done!") -} \ No newline at end of file +} + +func (c cronClient) HelloWorldJob() { + log.Print("Hello World") +} diff --git a/go.sum b/go.sum index d00a98e..9f45437 100644 --- a/go.sum +++ b/go.sum @@ -2,3 +2,6 @@ github.com/joho/godotenv v1.4.0 h1:3l4+N6zfMWnkbPEXKng2o2/MR5mSwTrBih4ZEkkz1lg= github.com/joho/godotenv v1.4.0/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs= github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/main.go b/main.go index 80b7a0a..fdc25dc 100644 --- a/main.go +++ b/main.go @@ -5,16 +5,15 @@ import ( "io" "log" "net/http" - "strings" "time" ) var ( - ErrInvalidStatusCode error = errors.New("did not get an acceptiable status code from the server") + ErrInvalidStatusCode error = errors.New("did not get an acceptiable status code from the server") ErrFailedToDecodeBody error = errors.New("unable to decode the body") ErrFailedToDecodeJson error = errors.New("unexpected json format was returned") - ErrWasNotJson error = errors.New("response from server was not json") - ErrDomainNotFound error = errors.New("unable to find requested domain on cloudflare") + ErrWasNotJson error = errors.New("response from server was not json") + ErrDomainNotFound error = errors.New("unable to find requested domain on cloudflare") ) func GetCurrentIpAddress() (string, error) { @@ -38,33 +37,36 @@ func GetCurrentIpAddress() (string, error) { func main() { config := NewConfigClient() - email := config.GetConfig(ConfigEmail) - if email == "" { + cfg := config.LoadConfig() + + if cfg.Email == "" { log.Println("Unable to find 'EMAIL' env value.") return } - token := config.GetConfig(ConfigToken) - if token == "" { + if cfg.Token == "" { log.Println("Unable to find 'API_TOKEN' env value.") + return } - domain := config.GetConfig(ConfigDomain) - if token == "" { + if cfg.Domain == "" { log.Println("Unable to find 'DOMAIN' env value.") + return } - hosts := config.GetConfig(ConfigHosts) - if token == "" { + if len(cfg.Hosts) == 0 { log.Println("Unable to find 'HOSTS' env value.") } - hostsArray := strings.Split(hosts, ",") - log.Println("Env Check: OK") + + log.Println("Config Check: OK") cron := NewCron() log.Println("Cloudflare Check will run every 15 minutes.") - cron.scheduler.AddFunc("0,15,30,45 * * * *", func() { - cron.RunCloudflareCheck(token, email, domain, hostsArray) + cron.scheduler.AddFunc("0/5 * * * *", func() { + cron.RunCloudflareCheck(cfg.Token, cfg.Email, cfg.Domain, cfg.Hosts) + }) + cron.scheduler.AddFunc("0/1 * * * *", func() { + cron.HelloWorldJob() }) cron.scheduler.Start() @@ -74,4 +76,3 @@ func main() { } } -