mirror of
https://github.com/cloudflare/cloudflared.git
synced 2025-07-27 12:39:58 +00:00
AUTH-2588 add DoH to service mode
This commit is contained in:
53
overwatch/app_manager.go
Normal file
53
overwatch/app_manager.go
Normal file
@@ -0,0 +1,53 @@
|
||||
package overwatch
|
||||
|
||||
// AppManager is the default implementation of overwatch service management
|
||||
type AppManager struct {
|
||||
services map[string]Service
|
||||
errorChan chan error
|
||||
}
|
||||
|
||||
// NewAppManager creates a new overwatch manager
|
||||
func NewAppManager(errorChan chan error) Manager {
|
||||
return &AppManager{services: make(map[string]Service), errorChan: errorChan}
|
||||
}
|
||||
|
||||
// Add takes in a new service to manage.
|
||||
// It stops the service if it already exist in the manager and is running
|
||||
// It then starts the newly added service
|
||||
func (m *AppManager) Add(service Service) {
|
||||
// check for existing service
|
||||
if currentService, ok := m.services[service.Name()]; ok {
|
||||
if currentService.Hash() == service.Hash() {
|
||||
return // the exact same service, no changes, so move along
|
||||
}
|
||||
currentService.Shutdown() //shutdown the listener since a new one is starting
|
||||
}
|
||||
m.services[service.Name()] = service
|
||||
|
||||
//start the service!
|
||||
go m.serviceRun(service)
|
||||
}
|
||||
|
||||
// Remove shutdowns the service by name and removes it from its current management list
|
||||
func (m *AppManager) Remove(name string) {
|
||||
if currentService, ok := m.services[name]; ok {
|
||||
currentService.Shutdown()
|
||||
}
|
||||
delete(m.services, name)
|
||||
}
|
||||
|
||||
// Services returns all the current Services being managed
|
||||
func (m *AppManager) Services() []Service {
|
||||
values := []Service{}
|
||||
for _, value := range m.services {
|
||||
values = append(values, value)
|
||||
}
|
||||
return values
|
||||
}
|
||||
|
||||
func (m *AppManager) serviceRun(service Service) {
|
||||
err := service.Run()
|
||||
if err != nil && m.errorChan != nil {
|
||||
m.errorChan <- err
|
||||
}
|
||||
}
|
17
overwatch/manager.go
Normal file
17
overwatch/manager.go
Normal file
@@ -0,0 +1,17 @@
|
||||
package overwatch
|
||||
|
||||
// Service is the required functions for an object to be managed by the overwatch Manager
|
||||
type Service interface {
|
||||
Name() string
|
||||
Type() string
|
||||
Hash() string
|
||||
Shutdown()
|
||||
Run() error
|
||||
}
|
||||
|
||||
// Manager is based type to manage running services
|
||||
type Manager interface {
|
||||
Add(Service)
|
||||
Remove(string)
|
||||
Services() []Service
|
||||
}
|
74
overwatch/manager_test.go
Normal file
74
overwatch/manager_test.go
Normal file
@@ -0,0 +1,74 @@
|
||||
package overwatch
|
||||
|
||||
import (
|
||||
"crypto/md5"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
type mockService struct {
|
||||
serviceName string
|
||||
serviceType string
|
||||
runError error
|
||||
}
|
||||
|
||||
func (s *mockService) Name() string {
|
||||
return s.serviceName
|
||||
}
|
||||
|
||||
func (s *mockService) Type() string {
|
||||
return s.serviceType
|
||||
}
|
||||
|
||||
func (s *mockService) Hash() string {
|
||||
h := md5.New()
|
||||
io.WriteString(h, s.serviceName)
|
||||
io.WriteString(h, s.serviceType)
|
||||
return fmt.Sprintf("%x", h.Sum(nil))
|
||||
}
|
||||
|
||||
func (s *mockService) Shutdown() {
|
||||
}
|
||||
|
||||
func (s *mockService) Run() error {
|
||||
return s.runError
|
||||
}
|
||||
|
||||
func TestManagerAddAndRemove(t *testing.T) {
|
||||
m := NewAppManager(nil)
|
||||
|
||||
first := &mockService{serviceName: "first", serviceType: "mock"}
|
||||
second := &mockService{serviceName: "second", serviceType: "mock"}
|
||||
m.Add(first)
|
||||
m.Add(second)
|
||||
assert.Len(t, m.Services(), 2, "expected 2 services in the list")
|
||||
|
||||
m.Remove(first.Name())
|
||||
services := m.Services()
|
||||
assert.Len(t, services, 1, "expected 1 service in the list")
|
||||
assert.Equal(t, second.Hash(), services[0].Hash(), "hashes should match. Wrong service was removed")
|
||||
}
|
||||
|
||||
func TestManagerDuplicate(t *testing.T) {
|
||||
m := NewAppManager(nil)
|
||||
|
||||
first := &mockService{serviceName: "first", serviceType: "mock"}
|
||||
m.Add(first)
|
||||
m.Add(first)
|
||||
assert.Len(t, m.Services(), 1, "expected 1 service in the list")
|
||||
}
|
||||
|
||||
func TestManagerErrorChannel(t *testing.T) {
|
||||
errChan := make(chan error)
|
||||
m := NewAppManager(errChan)
|
||||
|
||||
err := errors.New("test error")
|
||||
first := &mockService{serviceName: "first", serviceType: "mock", runError: err}
|
||||
m.Add(first)
|
||||
respErr := <-errChan
|
||||
assert.Equal(t, err, respErr, "errors don't match")
|
||||
}
|
Reference in New Issue
Block a user