package main

import (
	"encoding/json"
	"fmt"
	"strings"

	"github.com/golang/glog"
	admission "k8s.io/api/admission/v1beta1"
	networking "k8s.io/api/networking/v1beta1"
	meta "k8s.io/apimachinery/pkg/apis/meta/v1"
)

// ingressFilter is a filter which allows or denies the creation of an ingress
// backing a given domain with a namespace. It does so by operating on an
// explicit list of allowed namespace/domain pairs, where each domain is either
// a single domain or a DNS wildcard at a given root.
// By default every domain is allowed in every namespace. However, the moment
// an entry is added for a given domain (or wildcard that matches some
// domains), this domain will only be allowed in that namespace.
//
// For example, with the given allowed domains:
// -  ns: example, domain: one.example.com
// -  ns: example, domain: *.google.com
// The logic will be as follows:
// -  one.example.com will be only allowed in the example namespace
// -  any .google.com domain will be only allowed in the example namespace
// -  all other domains will be allowed everywhere.
//
// This logic allows for the easy use of arbitrary domains by k8s users within
// their personal namespaces, but allows critical domains to only be allowed in
// trusted namespaces.
//
// ingressFilter can be used straight away after constructing it as an empty
// type.
type ingressFilter struct {
	// allowed is a map from namespace to list of domain matchers.
	allowed map[string][]*domain

	// anythingGoesNamespaces are namespaces that are opted out of security
	// checks.
	anythingGoesNamespaces []string
}

// domain is a matcher for either a single given domain, or a domain wildcard.
// If this is a wildcard matcher, any amount of dot-delimited levels under the
// domain will be permitted.
type domain struct {
	// dns is either the domain name matched by this matcher (if wildcard ==
	// false), or the root of a wildcard represented by this matcher (if
	// wildcard == true).
	dns      string
	wildcard bool
}

// match returns whether this matcher matches a given domain.
func (d *domain) match(dns string) bool {
	if !d.wildcard {
		return dns == d.dns
	}
	return strings.HasSuffix(dns, "."+d.dns)
}

// allow adds a given (namespace, dns) pair to the filter. The dns variable is
// a string that is either a simple domain name, or a wildcard like
// *.foo.example.com. An error is returned if the dns stirng could not be
// parsed.
func (i *ingressFilter) allow(ns, dns string) error {
	// If the filter is brand new, initialize it.
	if i.allowed == nil {
		i.allowed = make(map[string][]*domain)
	}

	// Try to parse the name as a wildcard.
	parts := strings.Split(dns, ".")
	wildcard := false
	for i, part := range parts {
		if i == 0 && part == "*" {
			wildcard = true
			continue
		}
		// Do some basic validation of the name.
		if part == "" || strings.Contains(part, "*") {
			return fmt.Errorf("invalid domain")
		}
	}
	if wildcard {
		if len(parts) < 2 {
			return fmt.Errorf("invalid domain")
		}
		dns = strings.Join(parts[1:], ".")
	}
	i.allowed[ns] = append(i.allowed[ns], &domain{
		dns:      dns,
		wildcard: wildcard,
	})
	return nil
}

// domainAllowed returns whether a given domain is allowed to be backed by an
// ingress within a given namespace.
func (i *ingressFilter) domainAllowed(ns, domain string) bool {
	if i.allowed == nil {
		return true
	}

	domainFound := false
	// TODO(q3k): if this becomes too slow, build some inverted index for this.
	for n, ds := range i.allowed {
		for _, d := range ds {
			if !d.match(domain) {
				continue
			}
			// Domain matched, see if allowed in this namespace.
			domainFound = true
			if n == ns {
				return true
			}
		}
		// Otherwise, maybe it's allowed in another domain.
	}
	// No direct match found - if this domain has been at all matched before,
	// it means that it's a restriected domain and the requested namespace is
	// not one that's allowed to host it. Refuse.
	if domainFound {
		return false
	}
	// No direct match found, and this domain is not restricted. Allow.
	return true
}

func (i *ingressFilter) admit(req *admission.AdmissionRequest) (*admission.AdmissionResponse, error) {
	if req.Kind.Group != "networking.k8s.io" || req.Kind.Kind != "Ingress" {
		return nil, fmt.Errorf("not an ingress")
	}

	result := func(s string, args ...interface{}) (*admission.AdmissionResponse, error) {
		res := &admission.AdmissionResponse{
			UID: req.UID,
		}
		if s == "" {
			res.Allowed = true
		} else {
			res.Allowed = false
			res.Result = &meta.Status{
				Code:    403,
				Message: fmt.Sprintf("admitomatic: %s", fmt.Sprintf(s, args...)),
			}
		}
		return res, nil
	}

	// Permit any actions on critical system namespaes. See:
	// https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/
	// “Avoiding operating on the kube-system namespace”
	if req.Namespace == "kube-system" {
		return result("")
	}
	for _, ns := range i.anythingGoesNamespaces {
		if ns == req.Namespace {
			return result("")
		}
	}

	switch req.Operation {
	case "CREATE":
	case "UPDATE":
	default:
		// We only care about creations/updates, everything else is referred to plain RBAC.
		return result("")
	}

	ingress := networking.Ingress{}
	err := json.Unmarshal(req.Object.Raw, &ingress)
	if err != nil {
		glog.Errorf("Unmarshaling Ingress failed: %v", err)
		return result("invalid object")
	}

	// Check TLS config for hosts.
	for j, t := range ingress.Spec.TLS {
		for k, h := range t.Hosts {
			if strings.Contains(h, "*") {
				// TODO(q3k): support wildcards
				return result("wildcard host %q (%d in TLS entry %d) is not permitted", h, k, j)
			}
			if !i.domainAllowed(req.Namespace, h) {
				return result("host %q (%d) in TLS entry %d is not allowed in namespace %q", h, k, j, req.Namespace)
			}
		}
	}

	// Check rules for hosts.
	for j, r := range ingress.Spec.Rules {
		h := r.Host
		// Per IngressRule spec:
		//   If the host is unspecified, the Ingress routes all traffic based
		//   on the specified IngressRuleValue. Host can be "precise" which is
		//   a domain name without the terminating dot of a network host (e.g.
		//   "foo.bar.com") or "wildcard", which is a domain name prefixed with
		//   a single wildcard label (e.g. "*.foo.com").
		//
		// We reject everything other than precise hosts.
		if h == "" {
			return result("empty host %q (in rule %d) is not permitted", h, j)
		}
		if strings.Contains(h, "*") {
			// TODO(q3k): support wildcards
			return result("wildcard host %q (in rule %d) is not permitted", h, j)
		}
		if !i.domainAllowed(req.Namespace, h) {
			return result("host %q (in rule %d) is not allowed in namespace %q", h, j, req.Namespace)
		}
	}

	// Only allow a trusted subset of n-i-c annotations.
	// TODO(q3k): allow opt-out for some namespaces
	allowed := map[string]bool{
		"proxy-body-size":  true,
		"ssl-redirect":     true,
		"backend-protocol": true,
		"use-regex":        true,
		// Used by cert-manager
		"whitelist-source-range": true,
	}
	prefix := "nginx.ingress.kubernetes.io/"
	for k, _ := range ingress.Annotations {
		if !strings.HasPrefix(k, prefix) {
			continue
		}
		k = strings.TrimPrefix(k, prefix)
		if !allowed[k] {
			return result("forbidden annotation %q", k)
		}
	}

	// All clear, accept this Ingress.
	return result("")
}
