k9s/internal/resource/ing.go

140 lines
2.9 KiB
Go

package resource
import (
"strings"
"github.com/derailed/k9s/internal/k8s"
"github.com/rs/zerolog/log"
v1 "k8s.io/api/core/v1"
"k8s.io/api/extensions/v1beta1"
)
// Ingress tracks a kubernetes resource.
type Ingress struct {
*Base
instance *v1beta1.Ingress
}
// NewIngressList returns a new resource list.
func NewIngressList(ns string) List {
return NewIngressListWithArgs(ns, NewIngress())
}
// NewIngressListWithArgs returns a new resource list.
func NewIngressListWithArgs(ns string, res Resource) List {
return newList(ns, "ing", res, AllVerbsAccess|DescribeAccess)
}
// NewIngress instantiates a new Endpoint.
func NewIngress() *Ingress {
return NewIngressWithArgs(k8s.NewIngress())
}
// NewIngressWithArgs instantiates a new Endpoint.
func NewIngressWithArgs(r k8s.Res) *Ingress {
ep := &Ingress{
Base: &Base{
caller: r,
},
}
ep.creator = ep
return ep
}
// NewInstance builds a new Endpoint instance from a k8s resource.
func (*Ingress) NewInstance(i interface{}) Columnar {
cm := NewIngress()
switch i.(type) {
case *v1beta1.Ingress:
cm.instance = i.(*v1beta1.Ingress)
case v1beta1.Ingress:
ii := i.(v1beta1.Ingress)
cm.instance = &ii
default:
log.Fatal().Msgf("Unknown %#v", i)
}
cm.path = cm.namespacedName(cm.instance.ObjectMeta)
return cm
}
// Marshal resource to yaml.
func (r *Ingress) Marshal(path string) (string, error) {
ns, n := namespaced(path)
i, err := r.caller.Get(ns, n)
if err != nil {
return "", err
}
ing := i.(*v1beta1.Ingress)
ing.TypeMeta.APIVersion = "extensions/v1beta1"
ing.TypeMeta.Kind = "Ingress"
return r.marshalObject(ing)
}
// Header return resource header.
func (*Ingress) Header(ns string) Row {
hh := Row{}
if ns == AllNamespaces {
hh = append(hh, "NAMESPACE")
}
return append(hh, "NAME", "HOSTS", "ADDRESS", "PORT", "AGE")
}
// Fields retrieves displayable fields.
func (r *Ingress) Fields(ns string) Row {
ff := make([]string, 0, len(r.Header(ns)))
i := r.instance
if ns == AllNamespaces {
ff = append(ff, i.Namespace)
}
return append(ff,
i.Name,
r.toHosts(i.Spec.Rules),
r.toAddress(i.Status.LoadBalancer),
r.toPorts(i.Spec.TLS),
toAge(i.ObjectMeta.CreationTimestamp),
)
}
// ExtFields returns extended fields in relation to headers.
func (*Ingress) ExtFields() Properties {
return Properties{}
}
// Helpers...
func (*Ingress) toAddress(lbs v1.LoadBalancerStatus) string {
ings := lbs.Ingress
res := make([]string, 0, len(ings))
for _, lb := range ings {
if len(lb.IP) > 0 {
res = append(res, lb.IP)
} else if len(lb.Hostname) != 0 {
res = append(res, lb.Hostname)
}
}
return strings.Join(res, ",")
}
func (*Ingress) toPorts(tls []v1beta1.IngressTLS) string {
if len(tls) != 0 {
return "80, 443"
}
return "80"
}
func (*Ingress) toHosts(rr []v1beta1.IngressRule) string {
var s string
var i int
for _, r := range rr {
s += r.Host
if i < len(rr)-1 {
s += ","
}
i++
}
return s
}