-
Notifications
You must be signed in to change notification settings - Fork 339
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(kuma-dp) add coredns server to kuma-dp (#1811)
* feat(kuma-dp) add functionality to run dns server Signed-off-by: Bart Smykla <bartek@smykla.com> * feat(*) add building coredns to workflow Signed-off-by: Bart Smykla <bartek@smykla.com> (cherry picked from commit 49c85ea) # Conflicts: # app/kuma-dp/cmd/run.go # pkg/config/app/kuma-dp/config.go # pkg/config/app/kuma-dp/config_test.go # pkg/config/app/kuma-dp/testdata/default-config.golden.yaml
- Loading branch information
1 parent
ab2e601
commit aa2515c
Showing
17 changed files
with
673 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
package dnsserver | ||
|
||
import ( | ||
"io/ioutil" | ||
"os" | ||
"path/filepath" | ||
|
||
"github.com/pkg/errors" | ||
|
||
kuma_dp "github.com/kumahq/kuma/pkg/config/app/kuma-dp" | ||
) | ||
|
||
func GenerateConfigFile(cfg kuma_dp.DNS, config []byte) (string, error) { | ||
configFile := filepath.Join(cfg.ConfigDir, "Corefile") | ||
if err := writeFile(configFile, config, 0600); err != nil { | ||
return "", errors.Wrap(err, "failed to persist Envoy bootstrap config on disk") | ||
} | ||
return configFile, nil | ||
} | ||
|
||
func writeFile(filename string, data []byte, perm os.FileMode) error { | ||
if err := os.MkdirAll(filepath.Dir(filename), 0755); err != nil { | ||
return err | ||
} | ||
return ioutil.WriteFile(filename, data, perm) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
package dnsserver | ||
|
||
import ( | ||
"io/ioutil" | ||
"os" | ||
"path/filepath" | ||
|
||
. "github.com/onsi/ginkgo" | ||
. "github.com/onsi/gomega" | ||
|
||
kuma_dp "github.com/kumahq/kuma/pkg/config/app/kuma-dp" | ||
) | ||
|
||
var _ = Describe("Config File", func() { | ||
Describe("GenerateConfigFile(..)", func() { | ||
|
||
var configDir string | ||
|
||
BeforeEach(func() { | ||
var err error | ||
configDir, err = ioutil.TempDir("", "") | ||
Expect(err).ToNot(HaveOccurred()) | ||
}) | ||
AfterEach(func() { | ||
if configDir != "" { | ||
// when | ||
err := os.RemoveAll(configDir) | ||
// then | ||
Expect(err).ToNot(HaveOccurred()) | ||
} | ||
}) | ||
|
||
It("should create DNS Server config file on disk", func() { | ||
// given | ||
config := `. { | ||
errors | ||
}` | ||
// and | ||
dnsConfig := kuma_dp.DNS{ | ||
ConfigDir: configDir, | ||
} | ||
|
||
// when | ||
filename, err := GenerateConfigFile(dnsConfig, []byte(config)) | ||
// then | ||
Expect(err).ToNot(HaveOccurred()) | ||
// and | ||
Expect(filename).To(Equal(filepath.Join(configDir, "Corefile"))) | ||
|
||
// when | ||
actual, err := ioutil.ReadFile(filename) | ||
// then | ||
Expect(err).ToNot(HaveOccurred()) | ||
// and | ||
Expect(actual).To(Equal([]byte(`. { | ||
errors | ||
}`))) | ||
}) | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,184 @@ | ||
package dnsserver | ||
|
||
import ( | ||
"bytes" | ||
"context" | ||
"io" | ||
"os" | ||
"os/exec" | ||
"path/filepath" | ||
"text/template" | ||
|
||
"github.com/pkg/errors" | ||
|
||
kuma_dp "github.com/kumahq/kuma/pkg/config/app/kuma-dp" | ||
"github.com/kumahq/kuma/pkg/core" | ||
) | ||
|
||
var ( | ||
runLog = core.Log.WithName("kuma-dp").WithName("run").WithName("dns-server") | ||
) | ||
|
||
type DNSServer struct { | ||
opts *Opts | ||
} | ||
|
||
type Opts struct { | ||
Config kuma_dp.Config | ||
Stdout io.Writer | ||
Stderr io.Writer | ||
Quit chan struct{} | ||
} | ||
|
||
const DefaultCoreFileTemplate = `.:{{ .CoreDNSPort }} { | ||
forward . 127.0.0.1:{{ .EnvoyDNSPort }} | ||
alternate NXDOMAIN,SERVFAIL,REFUSED . /etc/resolv.conf | ||
prometheus localhost:{{ .PrometheusPort }} | ||
errors | ||
} | ||
.:{{ .CoreDNSEmptyPort }} { | ||
template ANY ANY . { | ||
rcode NXDOMAIN | ||
} | ||
}` | ||
|
||
func getSelfPath() (string, error) { | ||
ex, err := os.Executable() | ||
if err != nil { | ||
return "", err | ||
} | ||
|
||
return filepath.Dir(ex), nil | ||
} | ||
|
||
func lookupBinaryPath(candidatePaths []string) (string, error) { | ||
for _, candidatePath := range candidatePaths { | ||
path, err := exec.LookPath(candidatePath) | ||
if err == nil { | ||
return path, nil | ||
} | ||
} | ||
|
||
return "", errors.Errorf("could not find binary in any of the following paths: %v", candidatePaths) | ||
} | ||
|
||
func lookupDNSServerPath(configuredPath string) (string, error) { | ||
selfPath, err := getSelfPath() | ||
if err != nil { | ||
return "", err | ||
} | ||
|
||
cwd, err := os.Getwd() | ||
if err != nil { | ||
return "", err | ||
} | ||
|
||
path, err := lookupBinaryPath([]string{ | ||
configuredPath, | ||
selfPath + "/coredns", | ||
cwd + "/coredns", | ||
}) | ||
if err != nil { | ||
return "", err | ||
} | ||
|
||
return path, nil | ||
} | ||
|
||
func New(opts *Opts) (*DNSServer, error) { | ||
if _, err := lookupDNSServerPath(opts.Config.DNS.CoreDNSBinaryPath); err != nil { | ||
runLog.Error(err, "could not find the DNS Server executable in your path") | ||
return nil, err | ||
} | ||
|
||
return &DNSServer{opts: opts}, nil | ||
} | ||
|
||
func (s *DNSServer) NeedLeaderElection() bool { | ||
return false | ||
} | ||
|
||
func (s *DNSServer) Start(stop <-chan struct{}) error { | ||
ctx, cancel := context.WithCancel(context.Background()) | ||
defer cancel() | ||
|
||
dnsConfig := s.opts.Config.DNS | ||
|
||
var tmpl *template.Template | ||
|
||
if dnsConfig.CoreDNSConfigTemplatePath != "" { | ||
t, err := template.ParseFiles(dnsConfig.CoreDNSConfigTemplatePath) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
tmpl = t | ||
} else { | ||
t, err := template.New("Corefile").Parse(DefaultCoreFileTemplate) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
tmpl = t | ||
} | ||
|
||
bs := bytes.NewBuffer([]byte{}) | ||
|
||
if err := tmpl.Execute(bs, dnsConfig); err != nil { | ||
return err | ||
} | ||
|
||
configFile, err := GenerateConfigFile(dnsConfig, bs.Bytes()) | ||
if err != nil { | ||
return err | ||
} | ||
runLog.Info("configuration saved to a file", "file", configFile) | ||
|
||
binaryPathConfig := dnsConfig.CoreDNSBinaryPath | ||
resolvedPath, err := lookupDNSServerPath(binaryPathConfig) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
args := []string{ | ||
"-conf", configFile, | ||
"-q", | ||
} | ||
|
||
command := exec.CommandContext(ctx, resolvedPath, args...) | ||
command.Stdout = s.opts.Stdout | ||
command.Stderr = s.opts.Stderr | ||
|
||
runLog.Info("starting DNS Server (coredns)", "args", args) | ||
|
||
if err := command.Start(); err != nil { | ||
runLog.Error(err, "the DNS Server executable was found at "+resolvedPath+" but an error occurred when executing it") | ||
return err | ||
} | ||
|
||
done := make(chan error, 1) | ||
|
||
go func() { | ||
done <- command.Wait() | ||
}() | ||
|
||
select { | ||
case <-stop: | ||
runLog.Info("stopping DNS Server") | ||
cancel() | ||
return nil | ||
case err := <-done: | ||
if err != nil { | ||
runLog.Error(err, "DNS Server terminated with an error") | ||
} else { | ||
runLog.Info("DNS Server terminated successfully") | ||
} | ||
|
||
if s.opts.Quit != nil { | ||
close(s.opts.Quit) | ||
} | ||
|
||
return err | ||
} | ||
} |
13 changes: 13 additions & 0 deletions
13
app/kuma-dp/pkg/dataplane/dnsserver/dnsserver_suite_test.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
package dnsserver | ||
|
||
import ( | ||
"testing" | ||
|
||
. "github.com/onsi/ginkgo" | ||
. "github.com/onsi/gomega" | ||
) | ||
|
||
func TestEnvoy(t *testing.T) { | ||
RegisterFailHandler(Fail) | ||
RunSpecs(t, "DNS Server Suite") | ||
} |
Oops, something went wrong.