Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New ingress converter and haproxy types (part 1) #289

Merged
merged 3 commits into from
Jan 29, 2019
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
avoid conflict with haproxy package name
  • Loading branch information
jcmoraisjr committed Jan 27, 2019
commit c9424942893c981846e19f69a4436f9e55e17886
114 changes: 57 additions & 57 deletions pkg/controller/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ func NewHAProxyController() *HAProxyController {
}

// Info provides controller name and repository infos
func (haproxy *HAProxyController) Info() *ingress.BackendInfo {
func (hc *HAProxyController) Info() *ingress.BackendInfo {
return &ingress.BackendInfo{
Name: "HAProxy",
Release: version.RELEASE,
Expand All @@ -69,52 +69,52 @@ func (haproxy *HAProxyController) Info() *ingress.BackendInfo {
}

// Start starts the controller
func (haproxy *HAProxyController) Start() {
haproxy.controller = controller.NewIngressController(haproxy)
if *haproxy.reloadStrategy == "multibinder" {
func (hc *HAProxyController) Start() {
hc.controller = controller.NewIngressController(hc)
if *hc.reloadStrategy == "multibinder" {
glog.Warningf("multibinder is deprecated, using reusesocket strategy instead. update your deployment configuration")
}
haproxy.controller.Start()
hc.controller.Start()
}

// Stop shutdown the controller process
func (haproxy *HAProxyController) Stop() error {
err := haproxy.controller.Stop()
func (hc *HAProxyController) Stop() error {
err := hc.controller.Stop()
return err
}

// Name provides the complete name of the controller
func (haproxy *HAProxyController) Name() string {
func (hc *HAProxyController) Name() string {
return "HAProxy Ingress Controller"
}

// DefaultIngressClass returns the ingress class name
func (haproxy *HAProxyController) DefaultIngressClass() string {
func (hc *HAProxyController) DefaultIngressClass() string {
return "haproxy"
}

// Check health check implementation
func (haproxy *HAProxyController) Check(_ *http.Request) error {
func (hc *HAProxyController) Check(_ *http.Request) error {
return nil
}

// SetListers give access to the store listers
func (haproxy *HAProxyController) SetListers(lister *ingress.StoreLister) {
haproxy.storeLister = lister
func (hc *HAProxyController) SetListers(lister *ingress.StoreLister) {
hc.storeLister = lister
}

// UpdateIngressStatus custom callback used to update the status in an Ingress rule
// If the function returns nil the standard functions will be executed.
func (haproxy *HAProxyController) UpdateIngressStatus(*extensions.Ingress) []api.LoadBalancerIngress {
func (hc *HAProxyController) UpdateIngressStatus(*extensions.Ingress) []api.LoadBalancerIngress {
return nil
}

// ConfigureFlags allow to configure more flags before the parsing of
// command line arguments
func (haproxy *HAProxyController) ConfigureFlags(flags *pflag.FlagSet) {
haproxy.reloadStrategy = flags.String("reload-strategy", "native",
func (hc *HAProxyController) ConfigureFlags(flags *pflag.FlagSet) {
hc.reloadStrategy = flags.String("reload-strategy", "native",
`Name of the reload strategy. Options are: native (default) or reusesocket`)
haproxy.maxOldConfigFiles = flags.Int("max-old-config-files", 0,
hc.maxOldConfigFiles = flags.Int("max-old-config-files", 0,
`Maximum old haproxy timestamped config files to allow before being cleaned up. A value <= 0 indicates a single non-timestamped config file will be used`)
ingressClass := flags.Lookup("ingress-class")
if ingressClass != nil {
Expand All @@ -124,33 +124,33 @@ func (haproxy *HAProxyController) ConfigureFlags(flags *pflag.FlagSet) {
}

// OverrideFlags allows controller to override command line parameter flags
func (haproxy *HAProxyController) OverrideFlags(flags *pflag.FlagSet) {
haproxy.configDir = "/etc/haproxy"
haproxy.configFilePrefix = "haproxy"
haproxy.configFileSuffix = ".cfg"
haproxy.haproxyTemplate = newTemplate("haproxy.tmpl", "/etc/haproxy/template/haproxy.tmpl", 16384)
haproxy.modsecConfigFile = "/etc/haproxy/spoe-modsecurity.conf"
haproxy.modsecTemplate = newTemplate("spoe-modsecurity.tmpl", "/etc/haproxy/modsecurity/spoe-modsecurity.tmpl", 1024)
haproxy.command = "/haproxy-reload.sh"

if !(*haproxy.reloadStrategy == "native" || *haproxy.reloadStrategy == "reusesocket" || *haproxy.reloadStrategy == "multibinder") {
glog.Fatalf("Unsupported reload strategy: %v", *haproxy.reloadStrategy)
func (hc *HAProxyController) OverrideFlags(flags *pflag.FlagSet) {
hc.configDir = "/etc/haproxy"
hc.configFilePrefix = "haproxy"
hc.configFileSuffix = ".cfg"
hc.haproxyTemplate = newTemplate("haproxy.tmpl", "/etc/haproxy/template/haproxy.tmpl", 16384)
hc.modsecConfigFile = "/etc/haproxy/spoe-modsecurity.conf"
hc.modsecTemplate = newTemplate("spoe-modsecurity.tmpl", "/etc/haproxy/modsecurity/spoe-modsecurity.tmpl", 1024)
hc.command = "/haproxy-reload.sh"

if !(*hc.reloadStrategy == "native" || *hc.reloadStrategy == "reusesocket" || *hc.reloadStrategy == "multibinder") {
glog.Fatalf("Unsupported reload strategy: %v", *hc.reloadStrategy)
}
}

// SetConfig receives the ConfigMap the user has configured
func (haproxy *HAProxyController) SetConfig(configMap *api.ConfigMap) {
haproxy.configMap = configMap
func (hc *HAProxyController) SetConfig(configMap *api.ConfigMap) {
hc.configMap = configMap
}

// BackendDefaults defines default values to the ingress core
func (haproxy *HAProxyController) BackendDefaults() defaults.Backend {
return newHAProxyConfig(haproxy).Backend
func (hc *HAProxyController) BackendDefaults() defaults.Backend {
return newHAProxyConfig(hc).Backend
}

// DefaultEndpoint returns the Endpoint to use as default when the
// referenced service does not exists
func (haproxy *HAProxyController) DefaultEndpoint() ingress.Endpoint {
func (hc *HAProxyController) DefaultEndpoint() ingress.Endpoint {
return ingress.Endpoint{
Address: "127.0.0.1",
Port: "8181",
Expand All @@ -162,38 +162,38 @@ func (haproxy *HAProxyController) DefaultEndpoint() ingress.Endpoint {
// DrainSupport indicates whether or not this controller supports a "drain" mode where
// unavailable and terminating pods are included in the list of returned pods and used to
// direct certain traffic (e.g., traffic using persistence) to terminating/unavailable pods.
func (haproxy *HAProxyController) DrainSupport() (drainSupport bool) {
if haproxy.currentConfig != nil {
drainSupport = haproxy.currentConfig.Cfg.DrainSupport
func (hc *HAProxyController) DrainSupport() (drainSupport bool) {
if hc.currentConfig != nil {
drainSupport = hc.currentConfig.Cfg.DrainSupport
}
return
}

// OnUpdate regenerate the configuration file of the backend
func (haproxy *HAProxyController) OnUpdate(cfg ingress.Configuration) error {
updatedConfig, err := newControllerConfig(&cfg, haproxy)
func (hc *HAProxyController) OnUpdate(cfg ingress.Configuration) error {
updatedConfig, err := newControllerConfig(&cfg, hc)
if err != nil {
return err
}

reloadRequired := !dynconfig.ConfigBackends(haproxy.currentConfig, updatedConfig)
haproxy.currentConfig = updatedConfig
reloadRequired := !dynconfig.ConfigBackends(hc.currentConfig, updatedConfig)
hc.currentConfig = updatedConfig

modSecConf, err := haproxy.modsecTemplate.execute(updatedConfig)
modSecConf, err := hc.modsecTemplate.execute(updatedConfig)
if err != nil {
return err
}

if err := haproxy.writeModSecConfigFile(modSecConf); err != nil {
if err := hc.writeModSecConfigFile(modSecConf); err != nil {
return err
}

data, err := haproxy.haproxyTemplate.execute(updatedConfig)
data, err := hc.haproxyTemplate.execute(updatedConfig)
if err != nil {
return err
}

configFile, err := haproxy.rewriteConfigFiles(data)
configFile, err := hc.rewriteConfigFiles(data)
if err != nil {
return err
}
Expand All @@ -203,31 +203,31 @@ func (haproxy *HAProxyController) OnUpdate(cfg ingress.Configuration) error {
return nil
}

reloadCmd := exec.Command(haproxy.command, *haproxy.reloadStrategy, configFile)
reloadCmd := exec.Command(hc.command, *hc.reloadStrategy, configFile)
out, err := reloadCmd.CombinedOutput()
if len(out) > 0 {
glog.Infof("HAProxy[pid=%v] output:\n%v", reloadCmd.Process.Pid, string(out))
}
return err
}

func (haproxy *HAProxyController) writeModSecConfigFile(data []byte) error {
if err := ioutil.WriteFile(haproxy.modsecConfigFile, data, 644); err != nil {
func (hc *HAProxyController) writeModSecConfigFile(data []byte) error {
if err := ioutil.WriteFile(hc.modsecConfigFile, data, 644); err != nil {
glog.Warningf("Error writing modsecurity config file: %v", err)
return err
}
return nil
}

// RewriteConfigFiles safely replaces configuration files with new contents after validation
func (haproxy *HAProxyController) rewriteConfigFiles(data []byte) (string, error) {
func (hc *HAProxyController) rewriteConfigFiles(data []byte) (string, error) {
// Include timestamp in config file name to aid troubleshooting. When using a single, ever-changing config file it
// was difficult to know what config was loaded by any given haproxy process
timestamp := ""
if *haproxy.maxOldConfigFiles > 0 {
if *hc.maxOldConfigFiles > 0 {
timestamp = time.Now().Format("-20060102-150405.000")
}
configFile := haproxy.configDir + "/" + haproxy.configFilePrefix + timestamp + haproxy.configFileSuffix
configFile := hc.configDir + "/" + hc.configFilePrefix + timestamp + hc.configFileSuffix

// Write directly to configFile
if err := ioutil.WriteFile(configFile, data, 644); err != nil {
Expand All @@ -240,17 +240,17 @@ func (haproxy *HAProxyController) rewriteConfigFiles(data []byte) (string, error
return "", err
}

if *haproxy.maxOldConfigFiles > 0 {
if err := haproxy.removeOldConfigFiles(); err != nil {
if *hc.maxOldConfigFiles > 0 {
if err := hc.removeOldConfigFiles(); err != nil {
glog.Warningf("Problem removing old config files, but continuing in case it was a fluke. err=%v", err)
}
}

return configFile, nil
}

func (haproxy *HAProxyController) removeOldConfigFiles() error {
files, err := ioutil.ReadDir(haproxy.configDir)
func (hc *HAProxyController) removeOldConfigFiles() error {
files, err := ioutil.ReadDir(hc.configDir)
if err != nil {
return err
}
Expand All @@ -262,11 +262,11 @@ func (haproxy *HAProxyController) removeOldConfigFiles() error {

matchesFound := 0
for _, f := range files {
if !f.IsDir() && strings.HasPrefix(f.Name(), haproxy.configFilePrefix) && strings.HasSuffix(f.Name(), haproxy.configFileSuffix) {
if !f.IsDir() && strings.HasPrefix(f.Name(), hc.configFilePrefix) && strings.HasSuffix(f.Name(), hc.configFileSuffix) {
matchesFound = matchesFound + 1
if matchesFound > *haproxy.maxOldConfigFiles {
filePath := haproxy.configDir + "/" + f.Name()
glog.Infof("Removing old config file (%v). maxOldConfigFiles=%v", filePath, *haproxy.maxOldConfigFiles)
if matchesFound > *hc.maxOldConfigFiles {
filePath := hc.configDir + "/" + f.Name()
glog.Infof("Removing old config file (%v). maxOldConfigFiles=%v", filePath, *hc.maxOldConfigFiles)
if err := os.Remove(filePath); err != nil {
return err
}
Expand Down