cert-manager-webhook-sthome/pkg/dns/utils.go

167 lines
4.0 KiB
Go

// private repo workaround
// Will use this file and remove same content from main.go when github repo is made public
package dns
import (
"encoding/json"
"fmt"
"io"
"os"
"sync"
"time"
extapi "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
"k8s.io/klog/v2"
)
var (
wg sync.WaitGroup // wg is used to wait for the program to finish.
mutex sync.Mutex // mutex is used to define a critical section of code.
)
// loadConfig is a small helper function that decodes JSON configuration into
// the typed config struct.
func LoadConfig(cfgJSON *extapi.JSON) (LocalDNSProviderConfig, error) {
cfg := LocalDNSProviderConfig{}
// handle the 'base case' where no configuration has been provided
if cfgJSON == nil {
return cfg, nil
}
if err := json.Unmarshal(cfgJSON.Raw, &cfg); err != nil {
return cfg, fmt.Errorf("error decoding solver config: %v", err)
}
return cfg, nil
}
func setupWorkdir() {
err := createWorkdir()
if err != nil {
panic(err)
}
updateWorkdir()
}
func updateWorkdir() {
wg.Add(4) // Add a count, one for each goroutine.
go updateIfStale(AuthScript, AuthScriptMode)
go updateIfStale(DnsUpdScript, DnsUpdScriptMode)
go updateIfStale(KrbConf, KrbConfMode)
go updateIfStale(Keytab, KeytabMode)
wg.Wait() // Wait for the goroutines to finish.
}
func createWorkdir() error {
defer mutex.Unlock()
mutex.Lock()
finfo, err := os.Stat(Workdir)
if os.IsNotExist(err) {
klog.Infof("Creating folder \"%s\".", Workdir)
err = os.Mkdir(Workdir, 0755)
if err != nil {
panic(err)
}
} else if !finfo.IsDir() {
return fmt.Errorf("\"%s\" exists, but it's not a folder", Workdir)
}
return nil
}
func updateIfStale(filename string, mode os.FileMode) error {
defer wg.Done() // Schedule the call to Done to tell main we are done.
mutex.Lock()
sourceFile := AcmeDir + "/" + filename
destFile := Workdir + "/" + filename
result, err := cmpModTime(sourceFile, destFile)
if result > 0 {
err = CopyFile(sourceFile, destFile, mode)
if err == nil {
klog.Infof("Updated \"%s\" from \"%s\" folder.", destFile, AcmeDir)
}
}
mutex.Unlock()
return err
}
func cmpModTime(file1 string, file2 string) (int, error) {
// Get the fileinfo
fileInfo, err := os.Stat(file1)
if err != nil {
klog.Fatal(err)
}
modtime1 := fileInfo.ModTime()
fileInfo, err = os.Stat(file2)
// if file2 does not exist, return as if file1.modtime > file2.modtime
if os.IsNotExist(err) {
return 1, nil
}
// for any other error, return fatal err
if err != nil {
klog.Fatal(err)
}
modtime2 := fileInfo.ModTime()
diff := modtime1.Sub(modtime2)
if diff < (time.Duration(0) * time.Second) {
return -1, nil
}
if diff > (time.Duration(0) * time.Second) {
return 1, nil
}
return 0, nil
}
func CopyFile(sourceFile string, destFile string, mode os.FileMode) error {
source, err := os.Open(sourceFile) //open the source file
if err != nil {
panic(err)
}
defer source.Close()
destination, err := os.Create(destFile) //create the destination file
if err != nil {
panic(err)
}
defer destination.Close()
_, err = io.Copy(destination, source) //copy the contents of source to destination file
if err != nil {
panic(err)
}
err = os.Chmod(destFile, mode)
//klog.Infof("Copied %s to %s.", sourceFile, destFile)
return err
}
/*
// quote quotes the provide value
func quote(value string) string {
return fmt.Sprintf("\"%s\"", value)
}
// findRRSet searches through te list of rrsets for a matching entry
// based on type and name.
func findRRSet(rrsets []sthome.RRset, rrtype sthome.RRType, name string) *sthome.RRset {
for _, rrset := range rrsets {
if (rrset.Type != nil && *rrset.Type == sthome.RRTypeTXT) &&
(rrset.Name != nil && *rrset.Name == name) {
return &rrset
}
}
return nil
}
// findRecord locates the record entry with the matching content.
func findRecord(records []sthome.Record, content string) (int, bool) {
for indx, record := range records {
if record.Content != nil && *record.Content == content {
return indx, true
}
}
return -1, false
}
*/
// end of private repo workaround