Skip to content

Commit

Permalink
Add service auth annotation (#555)
Browse files Browse the repository at this point in the history
  • Loading branch information
diptadas authored and tamalsaha committed Dec 13, 2017
1 parent 21ddb8b commit cb76e98
Show file tree
Hide file tree
Showing 9 changed files with 467 additions and 7 deletions.
11 changes: 11 additions & 0 deletions hack/docker/voyager/templates/default-backend.cfg
@@ -1,4 +1,15 @@
{{- if .DefaultBackend.Auth }}
{{ template "userlist.cfg" .DefaultBackend.Auth }}
{{ end }}

backend {{ .DefaultBackend.Name }}
{{- if .DefaultBackend.Auth }}
{{- range $name, $users := .DefaultBackend.Auth.Users }}
acl __auth_ok__ http_auth({{ $name -}})
{{ end -}}
http-request auth {{ if not .DefaultBackend.Auth.Realm }}realm "{{ .DefaultBackend.Auth.Realm }}" {{ end }}if !__auth_ok__
{{ end }}

{{ if .DefaultBackend.Sticky }}cookie SERVERID insert indirect nocache{{- end -}}
{{- range $rule := .DefaultBackend.BackendRules }}
{{ $rule -}}
Expand Down
2 changes: 1 addition & 1 deletion hack/docker/voyager/templates/default-frontend.cfg
Expand Up @@ -9,7 +9,7 @@ frontend http-frontend
{{- range $name, $users := .Auth.Users }}
acl __auth_ok__ http_auth({{ $name -}})
{{ end -}}
http-request auth {{ if ne $.Auth.Realm "" }}realm "{{ $.Auth.Realm }}" {{ end }}if !__auth_ok__
http-request auth {{ if not $.Auth.Realm }}realm "{{ $.Auth.Realm }}" {{ end }}if !__auth_ok__
{{ end }}

{{- if .ProxyBodySize -}}
Expand Down
12 changes: 12 additions & 0 deletions hack/docker/voyager/templates/http-backend.cfg
@@ -1,5 +1,17 @@
{{- range $path := .Paths }}

{{- if $path.Backend.Auth }}
{{ template "userlist.cfg" $path.Backend.Auth }}
{{ end }}

backend {{ $path.Backend.Name }}
{{- if $path.Backend.Auth }}
{{- range $name, $users := $path.Backend.Auth.Users }}
acl __auth_ok__ http_auth({{ $name -}})
{{ end -}}
http-request auth {{ if not $path.Backend.Auth.Realm }}realm "{{ $path.Backend.Auth.Realm }}" {{ end }}if !__auth_ok__
{{ end }}

{{ if $path.Backend.Sticky }}cookie {{ $path.Backend.StickyCookieName }} insert indirect nocache{{- end -}}
{{- range $rule := $path.Backend.BackendRules }}
{{ $rule -}}
Expand Down
2 changes: 1 addition & 1 deletion hack/docker/voyager/templates/http-frontend.cfg
Expand Up @@ -27,7 +27,7 @@ frontend {{ .FrontendName }}
{{- range $name, $users := .Auth.Users }}
acl __auth_ok__ http_auth({{ $name -}})
{{ end -}}
http-request auth {{ if ne $.Auth.Realm "" }}realm "{{ $.Auth.Realm }}" {{ end }}if !__auth_ok__
http-request auth {{ if not $.Auth.Realm }}realm "{{ $.Auth.Realm }}" {{ end }}if !__auth_ok__
{{ end }}

{{- if .ProxyBodySize -}}
Expand Down
87 changes: 87 additions & 0 deletions pkg/haproxy/template_test.go
Expand Up @@ -512,3 +512,90 @@ func TestTemplateAuth(t *testing.T) {
}
}
}

func TestTemplateServiceAuth(t *testing.T) {
si := &SharedInfo{
DefaultBackend: &Backend{
Name: "default",
Endpoints: []*Endpoint{
{Name: "first", IP: "10.244.2.1", Port: "2323"},
{Name: "first", IP: "10.244.2.2", Port: "2324"},
},
Auth: &AuthConfig{
Realm: "Required",
Users: map[string][]AuthUser{
"auth": {
{
Username: "foo",
Password: "#bar",
Encrypted: true,
},
{
Username: "foo2",
Password: "bar2",
Encrypted: false,
},
},
},
},
},
}
testParsedConfig := TemplateData{
SharedInfo: si,
HTTPService: []*HTTPService{
{
SharedInfo: si,
FrontendName: "one",
Port: 80,
FrontendRules: []string{},
Paths: []*HTTPPath{
{
Path: "/elijah",
Backend: Backend{
Name: "elijah",
Endpoints: []*Endpoint{
{Name: "first", IP: "10.244.2.1", Port: "2323"},
{Name: "first", IP: "10.244.2.2", Port: "2324"},
},
Auth: &AuthConfig{
Realm: "Required",
Users: map[string][]AuthUser{
"auth-2": {
{
Username: "foo",
Password: "#bar",
Encrypted: true,
},
{
Username: "foo2",
Password: "bar2",
Encrypted: false,
},
},
},
},
},
},
{
Path: "/nicklause",
Backend: Backend{
Name: "nicklause",
Endpoints: []*Endpoint{
{Name: "first", IP: "10.244.2.1", Port: "2323"},
{Name: "first", IP: "10.244.2.2", Port: "2324", CheckHealth: true},
},
},
},
},
},
},
}
err := LoadTemplates(runtime.GOPath()+"/src/github.com/appscode/voyager/hack/docker/voyager/templates/*.cfg", "")
if assert.Nil(t, err) {
config, err := RenderConfig(testParsedConfig)
assert.Nil(t, err)
if testing.Verbose() {
fmt.Println(err, "\n", config)
}
}
}
1 change: 1 addition & 0 deletions pkg/haproxy/types.go
Expand Up @@ -86,6 +86,7 @@ func (svc TCPService) sortKey() string {

type Backend struct {
Name string
Auth *AuthConfig

BackendRules []string
// Deprecated
Expand Down
38 changes: 37 additions & 1 deletion pkg/ingress/parser.go
Expand Up @@ -150,6 +150,7 @@ func (c *controller) getEndpoints(s *apiv1.Service, servicePort *apiv1.ServicePo
}
}
return &haproxy.Backend{
Auth: c.getServiceAuth(s),
Endpoints: eps,
Sticky: c.Ingress.Sticky() || isServiceSticky(s.Annotations),
StickyCookieName: c.Ingress.StickySessionCookieName(),
Expand Down Expand Up @@ -236,6 +237,7 @@ func (c *controller) generateConfig() error {
}
si.DefaultBackend = &haproxy.Backend{
Name: "default-backend", // TODO: Use constant
Auth: bk.Auth,
Endpoints: bk.Endpoints,
BackendRules: c.Ingress.Spec.Backend.BackendRule,
RewriteRules: c.Ingress.Spec.Backend.RewriteRule,
Expand All @@ -250,7 +252,6 @@ func (c *controller) generateConfig() error {
si.Auth = &haproxy.AuthConfig{
Realm: c.Ingress.AuthRealm(),
}

secret, err := c.KubeClient.CoreV1().Secrets(c.Ingress.Namespace).Get(c.Ingress.AuthSecretName(), metav1.GetOptions{})
if err != nil {
return err
Expand Down Expand Up @@ -306,6 +307,7 @@ func (c *controller) generateConfig() error {
Path: path.Path,
Backend: haproxy.Backend{
Name: getBackendName(c.Ingress, path.Backend.IngressBackend),
Auth: bk.Auth,
Endpoints: bk.Endpoints,
BackendRules: path.Backend.BackendRule,
RewriteRules: path.Backend.RewriteRule,
Expand Down Expand Up @@ -492,3 +494,37 @@ func getEndpointName(ep apiv1.EndpointAddress) string {
}
return "pod-" + ep.IP
}

func (c *controller) getServiceAuth(s *apiv1.Service) *haproxy.AuthConfig {
if c.Ingress.AuthEnabled() { // global auth enabled
return nil
}

// Check auth type is basic; other auth mode is not supported
authType, ok := s.Annotations[api.AuthType]
if !ok || authType != "basic" {
return nil
}

authSecret, ok := s.Annotations[api.AuthSecret]
if !ok {
return nil
}

authRealm, ok := s.Annotations[api.AuthRealm]

secret, err := c.KubeClient.CoreV1().Secrets(c.Ingress.Namespace).Get(authSecret, metav1.GetOptions{})
if err != nil || secret.Data == nil {
return nil
}

users, err := getAuthUsers(secret.Data)
if err != nil {
return nil
}

return &haproxy.AuthConfig{
Realm: authRealm,
Users: users,
}
}

0 comments on commit cb76e98

Please sign in to comment.