mirror of
https://github.com/eliasstepanik/caddy-ingess.git
synced 2026-01-11 04:28:28 +00:00
init
This commit is contained in:
commit
835b4c018c
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
.DS_Store
|
||||
bin
|
||||
vendor
|
||||
3
Dockerfile
Normal file
3
Dockerfile
Normal file
@ -0,0 +1,3 @@
|
||||
FROM scratch
|
||||
COPY ./bin/ingress-controller .
|
||||
ENTRYPOINT ["/ingress-controller"]
|
||||
6
Makefile
Normal file
6
Makefile
Normal file
@ -0,0 +1,6 @@
|
||||
build:
|
||||
@mkdir -p bin
|
||||
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o ./bin/ingress-controller ./cmd/caddy
|
||||
|
||||
publish-docker:
|
||||
@echo 'TODO :- not implemented'
|
||||
132
cmd/caddy/main.go
Normal file
132
cmd/caddy/main.go
Normal file
@ -0,0 +1,132 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"bitbucket.org/lightcodelabs/ingress/internal/controller"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
"k8s.io/apimachinery/pkg/version"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
"k8s.io/client-go/tools/clientcmd"
|
||||
"k8s.io/klog"
|
||||
)
|
||||
|
||||
const (
|
||||
// High enough QPS to fit all expected use cases. QPS=0 is not set here, because
|
||||
// client code is overriding it.
|
||||
defaultQPS = 1e6
|
||||
|
||||
// High enough Burst to fit all expected use cases. Burst=0 is not set here, because
|
||||
// client code is overriding it.
|
||||
defaultBurst = 1e6
|
||||
)
|
||||
|
||||
func main() {
|
||||
klog.InitFlags(nil)
|
||||
|
||||
// get the namespace to monitor ingress resources for
|
||||
namespace := os.Getenv("KUBERNETES_NAMESPACE")
|
||||
if len(namespace) == 0 {
|
||||
namespace = v1.NamespaceAll
|
||||
klog.Warning("KUBERNETES_NAMESPACE is unset, will monitor ingresses in all namespaces.")
|
||||
}
|
||||
|
||||
// TODO :- implement
|
||||
// parse any flags required to configure the caddy ingress controller
|
||||
// cfg, err := parseFlags()
|
||||
// if err != nil {
|
||||
// klog.Fatal(err)
|
||||
// }
|
||||
|
||||
// get client to access the kubernetes service api
|
||||
kubeClient, err := createApiserverClient()
|
||||
if err != nil {
|
||||
msg := `
|
||||
Error while initiating a connection to the Kubernetes API server.
|
||||
This could mean the cluster is misconfigured (e.g. it has invalid API server certificates or Service Accounts configuration)
|
||||
`
|
||||
|
||||
klog.Fatalf(msg, err)
|
||||
}
|
||||
|
||||
var resource = "ingresses"
|
||||
restClient := kubeClient.ExtensionsV1beta1().RESTClient()
|
||||
|
||||
// start ingress controller
|
||||
c := controller.NewCaddyController(namespace, kubeClient, resource, restClient)
|
||||
|
||||
// TODO :-
|
||||
// create http server to expose controller health metrics
|
||||
|
||||
klog.Info("Starting the caddy ingress controller")
|
||||
|
||||
// start the ingress controller
|
||||
stopCh := make(chan struct{}, 1)
|
||||
defer close(stopCh)
|
||||
|
||||
go c.Run(stopCh)
|
||||
|
||||
select {}
|
||||
}
|
||||
|
||||
// createApiserverClient creates a new Kubernetes REST client. We assume the
|
||||
// controller runs inside Kubernetes and use the in-cluster config.
|
||||
func createApiserverClient() (*kubernetes.Clientset, error) {
|
||||
cfg, err := clientcmd.BuildConfigFromFlags("", "")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
cfg.QPS = defaultQPS
|
||||
cfg.Burst = defaultBurst
|
||||
cfg.ContentType = "application/vnd.kubernetes.protobuf"
|
||||
|
||||
klog.Infof("Creating API client for %s", cfg.Host)
|
||||
|
||||
client, err := kubernetes.NewForConfig(cfg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// The client may fail to connect to the API server in the first request
|
||||
defaultRetry := wait.Backoff{
|
||||
Steps: 10,
|
||||
Duration: 1 * time.Second,
|
||||
Factor: 1.5,
|
||||
Jitter: 0.1,
|
||||
}
|
||||
|
||||
klog.V(2).Info("Trying to discover Kubernetes version")
|
||||
|
||||
var v *version.Info
|
||||
var retries int
|
||||
var lastErr error
|
||||
err = wait.ExponentialBackoff(defaultRetry, func() (bool, error) {
|
||||
v, err = client.Discovery().ServerVersion()
|
||||
if err == nil {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
lastErr = err
|
||||
klog.V(2).Infof("Unexpected error discovering Kubernetes version (attempt %v): %v", retries, err)
|
||||
retries++
|
||||
return false, nil
|
||||
})
|
||||
|
||||
// err is returned in case of timeout in the exponential backoff (ErrWaitTimeout)
|
||||
if err != nil {
|
||||
return nil, lastErr
|
||||
}
|
||||
|
||||
// this should not happen, warn the user
|
||||
if retries > 0 {
|
||||
klog.Warningf("Initial connection to the Kubernetes API server was retried %d times.", retries)
|
||||
}
|
||||
|
||||
msg := "Running in Kubernetes cluster version v%v.%v (%v) - git (%v) commit %v - platform %v"
|
||||
klog.Infof(msg, v.Major, v.Minor, v.GitVersion, v.GitTreeState, v.GitCommit, v.Platform)
|
||||
|
||||
return client, nil
|
||||
}
|
||||
31
go.mod
Normal file
31
go.mod
Normal file
@ -0,0 +1,31 @@
|
||||
module bitbucket.org/lightcodelabs/ingress
|
||||
|
||||
go 1.12
|
||||
|
||||
require (
|
||||
github.com/gogo/protobuf v1.2.1 // indirect
|
||||
github.com/golang/protobuf v1.3.1 // indirect
|
||||
github.com/google/gofuzz v1.0.0 // indirect
|
||||
github.com/googleapis/gnostic v0.2.0 // indirect
|
||||
github.com/hashicorp/golang-lru v0.5.1 // indirect
|
||||
github.com/imdario/mergo v0.3.7 // indirect
|
||||
github.com/json-iterator/go v1.1.6 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.1 // indirect
|
||||
github.com/openshift/api v3.9.0+incompatible // indirect
|
||||
github.com/sirupsen/logrus v1.4.1 // indirect
|
||||
github.com/spf13/pflag v1.0.3
|
||||
github.com/stakater/IngressMonitorController v1.0.62
|
||||
golang.org/x/crypto v0.0.0-20190411191339-88737f569e3a // indirect
|
||||
golang.org/x/net v0.0.0-20190415100556-4a65cf94b679 // indirect
|
||||
golang.org/x/oauth2 v0.0.0-20190402181905-9f3314589c9a // indirect
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 // indirect
|
||||
gopkg.in/inf.v0 v0.9.1 // indirect
|
||||
gopkg.in/yaml.v2 v2.2.2 // indirect
|
||||
k8s.io/api v0.0.0-20190409021203-6e4e0e4f393b
|
||||
k8s.io/apimachinery v0.0.0-20190404173353-6a84e37a896d
|
||||
k8s.io/client-go v11.0.1-0.20190409021438-1a26190bd76a+incompatible
|
||||
k8s.io/klog v0.3.0
|
||||
k8s.io/utils v0.0.0-20190308190857-21c4ce38f2a7 // indirect
|
||||
sigs.k8s.io/yaml v1.1.0 // indirect
|
||||
)
|
||||
123
go.sum
Normal file
123
go.sum
Normal file
@ -0,0 +1,123 @@
|
||||
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM=
|
||||
github.com/elazarl/goproxy v0.0.0-20170405201442-c4fc26588b6e/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc=
|
||||
github.com/evanphx/json-patch v0.0.0-20190203023257-5858425f7550/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/gogo/protobuf v1.1.1 h1:72R+M5VuhED/KujmZVcIquuo8mBgX4oVda//DQb3PXo=
|
||||
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE=
|
||||
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
|
||||
github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903 h1:LbsanbbD6LieFkXbj9YNNBupiGHJgFeLpO0j0Fza1h8=
|
||||
github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg=
|
||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf h1:+RRA9JqSOZFfKrOeqr2z77+8R2RKyh8PG66dcu1V0ck=
|
||||
github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI=
|
||||
github.com/google/gofuzz v1.0.0 h1:A8PeW59pxE9IoFRqBp37U+mSNaQoZ46F1f0f863XSXw=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY=
|
||||
github.com/googleapis/gnostic v0.2.0 h1:l6N3VoaVzTncYYW+9yOz2LJJammFZGBO13sqgEhpy9g=
|
||||
github.com/googleapis/gnostic v0.2.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY=
|
||||
github.com/hashicorp/golang-lru v0.5.0 h1:CL2msUPvZTLb5O648aiLNJw3hnBxN2+1Jq8rCOH9wdo=
|
||||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU=
|
||||
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/imdario/mergo v0.3.7 h1:Y+UAYTZ7gDEuOfhxKWy+dvb5dRQ6rJjFSdX2HZY1/gI=
|
||||
github.com/imdario/mergo v0.3.7/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
|
||||
github.com/json-iterator/go v0.0.0-20180701071628-ab8a2e0c74be h1:AHimNtVIpiBjPUhEF5KNCkrUyqTSA5zWUl8sQ2bfGBE=
|
||||
github.com/json-iterator/go v0.0.0-20180701071628-ab8a2e0c74be/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||
github.com/json-iterator/go v1.1.6 h1:MrUvLMLTMxbqFJ9kzlvat/rYZqZnW3u4wkLzWTaFwKs=
|
||||
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI=
|
||||
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw=
|
||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/gomega v0.0.0-20190113212917-5533ce8a0da3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
github.com/openshift/api v3.9.0+incompatible h1:fJ/KsefYuZAjmrr3+5U9yZIZbTOpVkDDLDLFresAeYs=
|
||||
github.com/openshift/api v3.9.0+incompatible/go.mod h1:dh9o4Fs58gpFXGSYfnVxGR9PnV53I8TW84pQaJDdGiY=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/sirupsen/logrus v1.4.1 h1:GL2rEmy6nsikmW0r8opw9JIRScdMF5hA8cOYLH7In1k=
|
||||
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
|
||||
github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||
github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg=
|
||||
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||
github.com/stakater/IngressMonitorController v1.0.62 h1:KLC79Qo8YNEcNehPSEDrZ1vEtqPux1fnNnXC4m43Lhk=
|
||||
github.com/stakater/IngressMonitorController v1.0.62/go.mod h1:LXpqENu96n+xgxMr1GGSRKydCrVaszM21Y8PKTb+JK8=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190411191339-88737f569e3a h1:Igim7XhdOpBnWPuYJ70XcNpq8q3BCACtVgNfoJxOV7g=
|
||||
golang.org/x/crypto v0.0.0-20190411191339-88737f569e3a/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190206173232-65e2d4e15006/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190415100556-4a65cf94b679 h1:tzVWzOrXxwAwdSCMrf+mbNrZFxwS0+HLP4m2qxtfdhk=
|
||||
golang.org/x/net v0.0.0-20190415100556-4a65cf94b679/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/oauth2 v0.0.0-20190402181905-9f3314589c9a h1:tImsplftrFpALCYumobsd0K86vlAs/eXGFms2txfJfA=
|
||||
golang.org/x/oauth2 v0.0.0-20190402181905-9f3314589c9a/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e h1:nFYrTHrdrAOpShe27kaFHjsqYSEQ0KWqdWLu3xuZJts=
|
||||
golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.1-0.20181227161524-e6919f6577db h1:6/JqlYfC1CCaLnGceQTI+sDGhC9UBSPAsBqI0Gun6kU=
|
||||
golang.org/x/text v0.3.1-0.20181227161524-e6919f6577db/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 h1:SvFZT6jyqRaOeXpc5h/JSfZenJ2O330aBsf7JfSUXmQ=
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
google.golang.org/appengine v1.4.0 h1:/wp5JvzpHIxhs/dumFmF7BXTf3Z+dd4uXta4kVyO508=
|
||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||
gopkg.in/inf.v0 v0.9.0 h1:3zYtXIO92bvsdS3ggAdA8Gb4Azj0YU+TVY1uGYNFA8o=
|
||||
gopkg.in/inf.v0 v0.9.0/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
|
||||
gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
|
||||
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||
gopkg.in/yaml.v2 v2.2.1 h1:mUhvW9EsL+naU5Q3cakzfE91YhliOondGd6ZrsDBHQE=
|
||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
k8s.io/api v0.0.0-20190409021203-6e4e0e4f393b h1:aBGgKJUM9Hk/3AE8WaZIApnTxG35kbuQba2w+SXqezo=
|
||||
k8s.io/api v0.0.0-20190409021203-6e4e0e4f393b/go.mod h1:iuAfoD4hCxJ8Onx9kaTIt30j7jUFS00AXQi6QMi99vA=
|
||||
k8s.io/api v0.0.0-20190415132514-c2f1300cac21 h1:XGJCFakX0XXD6V2frIsafsr96sDU1q6Gcvm2JaFQVyM=
|
||||
k8s.io/api v0.0.0-20190415132514-c2f1300cac21/go.mod h1:5HMaKNcWJji8AGOBjOZxmFDwRutMItn4MrrXZcFANNo=
|
||||
k8s.io/api v0.0.0-20190417212520-7b2abe144378 h1:5MbuLXn4OcNwi6vnf6OqDuMvZQQFMG5Bl97Ji6U+v/I=
|
||||
k8s.io/apimachinery v0.0.0-20190404173353-6a84e37a896d h1:Jmdtdt1ZnoGfWWIIik61Z7nKYgO3J+swQJtPYsP9wHA=
|
||||
k8s.io/apimachinery v0.0.0-20190404173353-6a84e37a896d/go.mod h1:ccL7Eh7zubPUSh9A3USN90/OzHNSVN6zxzde07TDCL0=
|
||||
k8s.io/apimachinery v0.0.0-20190415132420-07d458fe0356 h1:IneIG23feOS594nIIsJVRUHK50ALz/g0/Co/3iML7RI=
|
||||
k8s.io/apimachinery v0.0.0-20190415132420-07d458fe0356/go.mod h1:jLjiXl596L+wVGdx8dRx6sSNnabzqnI2+nAJqqqyesQ=
|
||||
k8s.io/client-go v11.0.0+incompatible h1:LBbX2+lOwY9flffWlJM7f1Ct8V2SRNiMRDFeiwnJo9o=
|
||||
k8s.io/client-go v11.0.0+incompatible/go.mod h1:7vJpHMYJwNQCWgzmNV+VYUl1zCObLyodBc8nIyt8L5s=
|
||||
k8s.io/client-go v11.0.1-0.20190409021438-1a26190bd76a+incompatible h1:U5Bt+dab9K8qaUmXINrkXO135kA11/i5Kg1RUydgaMQ=
|
||||
k8s.io/client-go v11.0.1-0.20190409021438-1a26190bd76a+incompatible/go.mod h1:7vJpHMYJwNQCWgzmNV+VYUl1zCObLyodBc8nIyt8L5s=
|
||||
k8s.io/klog v0.0.0-20190306015804-8e90cee79f82/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk=
|
||||
k8s.io/klog v0.3.0 h1:0VPpR+sizsiivjIfIAQH/rl8tan6jvWkS7lU+0di3lE=
|
||||
k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk=
|
||||
k8s.io/kube-openapi v0.0.0-20190228160746-b3a7cee44a30 h1:TRb4wNWoBVrH9plmkp2q86FIDppkbrEXdXlxU3a3BMI=
|
||||
k8s.io/kube-openapi v0.0.0-20190228160746-b3a7cee44a30/go.mod h1:BXM9ceUBTj2QnfH2MK1odQs778ajze1RxcmP6S8RVVc=
|
||||
k8s.io/utils v0.0.0-20190308190857-21c4ce38f2a7 h1:8r+l4bNWjRlsFYlQJnKJ2p7s1YQPj4XyXiJVqDHRx7c=
|
||||
k8s.io/utils v0.0.0-20190308190857-21c4ce38f2a7/go.mod h1:8k8uAuAQ0rXslZKaEWd0c3oVhZz7sSzSiPnVZayjIX0=
|
||||
sigs.k8s.io/yaml v1.1.0 h1:4A07+ZFc2wgJwo8YNlQpr1rVlgUDlxXHhPJciaPY5gs=
|
||||
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
|
||||
24
hack/test/example-deployment.yaml
Normal file
24
hack/test/example-deployment.yaml
Normal file
@ -0,0 +1,24 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: example
|
||||
labels:
|
||||
app: example
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: example
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: example
|
||||
spec:
|
||||
containers:
|
||||
- name: httpecho
|
||||
image: hashicorp/http-echo
|
||||
args:
|
||||
- "-listen=:8080"
|
||||
- "-text=hello world"
|
||||
ports:
|
||||
- containerPort: 8080
|
||||
13
hack/test/example-ingress.yaml
Normal file
13
hack/test/example-ingress.yaml
Normal file
@ -0,0 +1,13 @@
|
||||
apiVersion: extensions/v1beta1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: example
|
||||
spec:
|
||||
rules:
|
||||
- host: hello-world.xyz
|
||||
http:
|
||||
paths:
|
||||
- path: /*
|
||||
backend:
|
||||
serviceName: example
|
||||
servicePort: 8080
|
||||
12
hack/test/example-service.yaml
Normal file
12
hack/test/example-service.yaml
Normal file
@ -0,0 +1,12 @@
|
||||
kind: Service
|
||||
apiVersion: v1
|
||||
metadata:
|
||||
name: example
|
||||
spec:
|
||||
type: NodePort
|
||||
selector:
|
||||
app: example
|
||||
ports:
|
||||
- protocol: TCP
|
||||
port: 80
|
||||
targetPort: 8080
|
||||
97
internal/controller/action.go
Normal file
97
internal/controller/action.go
Normal file
@ -0,0 +1,97 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"k8s.io/api/extensions/v1beta1"
|
||||
)
|
||||
|
||||
func (c *CaddyController) onResourceAdded(obj interface{}) {
|
||||
c.syncQueue.Add(ResourceAddedAction{
|
||||
resource: obj,
|
||||
})
|
||||
}
|
||||
|
||||
func (c *CaddyController) onResourceUpdated(old interface{}, new interface{}) {
|
||||
c.syncQueue.Add(ResourceUpdatedAction{
|
||||
resource: new,
|
||||
oldResource: old,
|
||||
})
|
||||
}
|
||||
|
||||
func (c *CaddyController) onResourceDeleted(obj interface{}) {
|
||||
c.syncQueue.Add(ResourceDeletedAction{
|
||||
resource: obj,
|
||||
})
|
||||
}
|
||||
|
||||
func (c *CaddyController) onSyncStatus(obj interface{}) {
|
||||
c.syncQueue.Add(SyncStatusAction{})
|
||||
}
|
||||
|
||||
// Action is an interface for ingress actions
|
||||
type Action interface {
|
||||
handle(c *CaddyController) error
|
||||
}
|
||||
|
||||
// ResourceAddedAction provides an implementation of the action interface
|
||||
type ResourceAddedAction struct {
|
||||
resource interface{}
|
||||
}
|
||||
|
||||
// ResourceUpdatedAction provides an implementation of the action interface
|
||||
type ResourceUpdatedAction struct {
|
||||
resource interface{}
|
||||
oldResource interface{}
|
||||
}
|
||||
|
||||
// ResourceDeletedAction provides an implementation of the action interface
|
||||
type ResourceDeletedAction struct {
|
||||
resource interface{}
|
||||
}
|
||||
|
||||
func (r ResourceAddedAction) handle(c *CaddyController) error {
|
||||
// configure caddy to handle this resource
|
||||
ing, ok := r.resource.(*v1beta1.Ingress)
|
||||
if !ok {
|
||||
return fmt.Errorf("ResourceAddedAction: incoming resource is not of type ingress")
|
||||
}
|
||||
|
||||
// 1. Parse ingress resource and convert to obj to configure caddy with
|
||||
// 2. Get current caddy config for rollback purposes
|
||||
// 3. Update internal caddy config
|
||||
// 4. Get ingress controller publish address
|
||||
// 5. call syncIngress for this specific resource
|
||||
// 6. Add this ingress to resource store
|
||||
|
||||
c.resourceStore.AddIngress(ing)
|
||||
|
||||
// ~~~~
|
||||
// when updating caddy config the ingress controller should bypass kube-proxy and get the ip address of
|
||||
// the pod that the deployment we are proxying to is running on so that we can proxy to that ip address port.
|
||||
// this is good for session affinity and increases performance (since we don't have to hit dns).
|
||||
|
||||
// example getting an ingress
|
||||
// ingClient := c.kubeClient.ExtensionsV1beta1().Ingresses(c.namespace) // get a client to update the ingress
|
||||
// ingClient.UpdateStatus(ing) // pass an ingress with the status.address field updated
|
||||
// ~~~
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r ResourceUpdatedAction) handle(c *CaddyController) error {
|
||||
// find the caddy config related to the oldResource and update it
|
||||
|
||||
fmt.Printf("\nUpdated resource:\n +%v\n\nOld resource: \n %+v\n", r.resource, r.oldResource)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r ResourceDeletedAction) handle(c *CaddyController) error {
|
||||
// delete all resources from caddy config that are associated with this resource
|
||||
// reload caddy config
|
||||
|
||||
fmt.Printf("\nDeleted resource:\n +%v\n", r.resource)
|
||||
|
||||
return nil
|
||||
}
|
||||
160
internal/controller/controller.go
Normal file
160
internal/controller/controller.go
Normal file
@ -0,0 +1,160 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"bitbucket.org/lightcodelabs/ingress/internal/store"
|
||||
"k8s.io/api/extensions/v1beta1"
|
||||
"k8s.io/apimachinery/pkg/fields"
|
||||
run "k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/util/runtime"
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
"k8s.io/client-go/rest"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
"k8s.io/client-go/util/workqueue"
|
||||
"k8s.io/klog"
|
||||
)
|
||||
|
||||
// ResourceMap are resources from where changes are going to be detected
|
||||
var ResourceMap = map[string]run.Object{
|
||||
"ingresses": &v1beta1.Ingress{},
|
||||
}
|
||||
|
||||
// how often we should attempt to keep ingress resource's source address in sync
|
||||
const syncInterval = time.Second * 60
|
||||
|
||||
// CaddyController represents an caddy ingress controller.
|
||||
type CaddyController struct {
|
||||
resourceStore *store.Store
|
||||
kubeClient *kubernetes.Clientset
|
||||
namespace string
|
||||
indexer cache.Indexer
|
||||
syncQueue workqueue.RateLimitingInterface
|
||||
statusQueue workqueue.RateLimitingInterface // statusQueue performs ingress status updates every 60 seconds but inserts the work into the sync queue
|
||||
informer cache.Controller
|
||||
}
|
||||
|
||||
// NewCaddyController returns an instance of the caddy ingress controller.
|
||||
func NewCaddyController(namespace string, kubeClient *kubernetes.Clientset, resource string, restClient rest.Interface) *CaddyController {
|
||||
controller := &CaddyController{
|
||||
kubeClient: kubeClient,
|
||||
namespace: namespace,
|
||||
syncQueue: workqueue.NewRateLimitingQueue(workqueue.DefaultControllerRateLimiter()),
|
||||
statusQueue: workqueue.NewRateLimitingQueue(workqueue.DefaultControllerRateLimiter()),
|
||||
}
|
||||
|
||||
ingressListWatcher := cache.NewListWatchFromClient(restClient, resource, namespace, fields.Everything())
|
||||
indexer, informer := cache.NewIndexerInformer(ingressListWatcher, ResourceMap[resource], 0, cache.ResourceEventHandlerFuncs{
|
||||
AddFunc: controller.onResourceAdded,
|
||||
UpdateFunc: controller.onResourceUpdated,
|
||||
DeleteFunc: controller.onResourceDeleted,
|
||||
}, cache.Indexers{})
|
||||
|
||||
controller.indexer = indexer
|
||||
controller.informer = informer
|
||||
controller.resourceStore = store.NewStore(controller.kubeClient)
|
||||
|
||||
// =======
|
||||
// TODO :- get info of the current pod, we'll need the ip address so we can forward requests to this ingress
|
||||
// controller
|
||||
|
||||
// podInfo, err := k8s.GetPodDetails(kubeClient)
|
||||
// if err != nil {
|
||||
// klog.Fatalf("Unexpected error obtaining pod information: %v", err)
|
||||
// }
|
||||
// =======
|
||||
|
||||
// TODO :- attempt to do initial sync with ingresses here
|
||||
|
||||
return controller
|
||||
}
|
||||
|
||||
// Shutdown stops the caddy controller.
|
||||
func (c *CaddyController) Shutdown() error {
|
||||
// TODO :- implement a graceful shutdown for the ingress controller and caddy server
|
||||
|
||||
// shutdown statusQueue
|
||||
|
||||
// shutdown syncQueue
|
||||
|
||||
// shutdownCaddy
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// handleErrs reports errors received from queue actions.
|
||||
func (c *CaddyController) handleErr(err error, action interface{}) {
|
||||
klog.Error(err)
|
||||
}
|
||||
|
||||
// Run method starts the ingress controller.
|
||||
func (c *CaddyController) Run(stopCh chan struct{}) {
|
||||
klog.Info("starting caddy ingress controller")
|
||||
|
||||
// TODO :- start an instance of caddy server
|
||||
|
||||
defer runtime.HandleCrash()
|
||||
defer c.syncQueue.ShutDown()
|
||||
|
||||
// start the ingress informer where we listen to new / updated ingress resources
|
||||
go c.informer.Run(stopCh)
|
||||
|
||||
// wait for all involved caches to be synced, before processing items from the queue is started
|
||||
if !cache.WaitForCacheSync(stopCh, c.informer.HasSynced) {
|
||||
runtime.HandleError(fmt.Errorf("Timed out waiting for caches to sync"))
|
||||
return
|
||||
}
|
||||
|
||||
// start processing events for syncing ingress resources
|
||||
go wait.Until(c.runWorker, time.Second, stopCh)
|
||||
|
||||
// start ingress status syncher
|
||||
go wait.Until(c.dispatchSync, syncInterval, stopCh)
|
||||
|
||||
<-stopCh
|
||||
klog.Info("stopping ingress controller")
|
||||
|
||||
exitCode := 0
|
||||
err := c.Shutdown()
|
||||
if err != nil {
|
||||
klog.Errorf("could not shutdown ingress controller properly")
|
||||
exitCode = 1
|
||||
}
|
||||
|
||||
os.Exit(exitCode)
|
||||
}
|
||||
|
||||
// TODO :- copy this for the status updater for ingress controllers
|
||||
// every 60 seconds attempt to update the statusIP for ingresses
|
||||
// add into the syncqueue
|
||||
|
||||
// process items in the event queue
|
||||
func (c *CaddyController) runWorker() {
|
||||
for c.processNextItem() {
|
||||
}
|
||||
}
|
||||
|
||||
// if there is an ingress item in the event queue process it
|
||||
func (c *CaddyController) processNextItem() bool {
|
||||
// Wait until there is a new item in the working queue
|
||||
action, quit := c.syncQueue.Get()
|
||||
if quit {
|
||||
return false
|
||||
}
|
||||
|
||||
// Tell the queue that we are done with processing this key. This unblocks the key for other workers
|
||||
// This allows safe parallel processing because two ingresses with the same key are never processed in
|
||||
// parallel.
|
||||
defer c.syncQueue.Done(action)
|
||||
|
||||
// Invoke the method containing the business logic
|
||||
err := action.(Action).handle(c)
|
||||
if err != nil {
|
||||
c.handleErr(err, action)
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
28
internal/controller/status.go
Normal file
28
internal/controller/status.go
Normal file
@ -0,0 +1,28 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"k8s.io/api/extensions/v1beta1"
|
||||
)
|
||||
|
||||
// dispatchSync is run every syncInterval duration to sync ingress source address fields.
|
||||
func (c *CaddyController) dispatchSync() {
|
||||
c.syncQueue.Add(SyncStatusAction{})
|
||||
}
|
||||
|
||||
// SyncStatusAction provides an implementation of the action interface
|
||||
type SyncStatusAction struct {
|
||||
}
|
||||
|
||||
func (r SyncStatusAction) handle(c *CaddyController) error {
|
||||
c.syncStatus(c.resourceStore.Ingresses)
|
||||
return nil
|
||||
}
|
||||
|
||||
// syncStatus ensures that the ingress source address points to this ingress controller's IP address.
|
||||
func (c *CaddyController) syncStatus(ings []*v1beta1.Ingress) {
|
||||
// TODO :- update source address to ingress controller published address
|
||||
|
||||
fmt.Println("Handle Synching Ingress Source Address")
|
||||
}
|
||||
3
internal/ingress/ingress.go
Normal file
3
internal/ingress/ingress.go
Normal file
@ -0,0 +1,3 @@
|
||||
package ingress
|
||||
|
||||
// handle getting ingress information here
|
||||
49
internal/store/store.go
Normal file
49
internal/store/store.go
Normal file
@ -0,0 +1,49 @@
|
||||
package store
|
||||
|
||||
import (
|
||||
"k8s.io/api/extensions/v1beta1"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
"k8s.io/klog"
|
||||
)
|
||||
|
||||
// Store represents a collection of ingresses and secrets that we are monitoring.
|
||||
type Store struct {
|
||||
Ingresses []*v1beta1.Ingress
|
||||
Secrets []interface{} // TODO :- should we store the secrets in the ingress object?
|
||||
}
|
||||
|
||||
// NewStore returns a new store that keeps track of ingresses and secrets. It will attempt to get
|
||||
// all current ingresses before returning.
|
||||
func NewStore(kubeClient *kubernetes.Clientset) *Store {
|
||||
ingresses, err := kubeClient.ExtensionsV1beta1().Ingresses("").List(v1.ListOptions{})
|
||||
if err != nil {
|
||||
klog.Errorf("could not get existing ingresses in cluster")
|
||||
return &Store{}
|
||||
}
|
||||
|
||||
s := &Store{
|
||||
Ingresses: make([]*v1beta1.Ingress, len(ingresses.Items)-1),
|
||||
}
|
||||
|
||||
for _, i := range ingresses.Items {
|
||||
s.Ingresses = append(s.Ingresses, &i)
|
||||
}
|
||||
|
||||
return s
|
||||
}
|
||||
|
||||
// AddIngress adds an ingress to the store
|
||||
func (s *Store) AddIngress(ing *v1beta1.Ingress) {
|
||||
isUniq := true
|
||||
|
||||
for _, i := range s.Ingresses {
|
||||
if i.GetUID() == ing.GetUID() {
|
||||
isUniq = false
|
||||
}
|
||||
}
|
||||
|
||||
if isUniq {
|
||||
s.Ingresses = append(s.Ingresses, ing)
|
||||
}
|
||||
}
|
||||
27
kubernetes/generated/clusterrole.yaml
Normal file
27
kubernetes/generated/clusterrole.yaml
Normal file
@ -0,0 +1,27 @@
|
||||
apiVersion: rbac.authorization.k8s.io/v1beta1
|
||||
kind: ClusterRole
|
||||
metadata:
|
||||
name: caddyingresscontroller-role
|
||||
rules:
|
||||
- apiGroups:
|
||||
- ""
|
||||
- "extensions"
|
||||
resources:
|
||||
- ingresses
|
||||
- routes
|
||||
verbs:
|
||||
- list
|
||||
- get
|
||||
- update
|
||||
- patch
|
||||
- watch
|
||||
- delete
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- services
|
||||
- pods
|
||||
verbs:
|
||||
- list
|
||||
- get
|
||||
- watch
|
||||
12
kubernetes/generated/clusterrolebinding.yaml
Normal file
12
kubernetes/generated/clusterrolebinding.yaml
Normal file
@ -0,0 +1,12 @@
|
||||
kind: ClusterRoleBinding
|
||||
apiVersion: rbac.authorization.k8s.io/v1beta1
|
||||
metadata:
|
||||
name: caddyingresscontroller-role-binding
|
||||
roleRef:
|
||||
kind: ClusterRole
|
||||
name: caddyingresscontroller-role
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: caddyingresscontroller
|
||||
namespace: default
|
||||
34
kubernetes/generated/deployment.yaml
Normal file
34
kubernetes/generated/deployment.yaml
Normal file
@ -0,0 +1,34 @@
|
||||
apiVersion: extensions/v1beta1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: caddyingresscontroller
|
||||
labels:
|
||||
app: caddyIngressController
|
||||
chart: "caddyingresscontroller-v0.1.0"
|
||||
release: "release-name"
|
||||
heritage: "Tiller"
|
||||
version: v0.1.0
|
||||
|
||||
spec:
|
||||
replicas: 1
|
||||
revisionHistoryLimit: 2
|
||||
selector:
|
||||
matchLabels:
|
||||
app: caddyIngressController
|
||||
release: "release-name"
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: caddyIngressController
|
||||
chart: "caddyingresscontroller-v0.1.0"
|
||||
release: "release-name"
|
||||
heritage: "Tiller"
|
||||
version: v0.1.0
|
||||
|
||||
spec:
|
||||
containers:
|
||||
- env:
|
||||
image: "caddy/ingresscontroller"
|
||||
imagePullPolicy: IfNotPresent
|
||||
name: caddyingresscontroller
|
||||
serviceAccountName: caddyingresscontroller
|
||||
10
kubernetes/generated/serviceaccount.yaml
Normal file
10
kubernetes/generated/serviceaccount.yaml
Normal file
@ -0,0 +1,10 @@
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: caddyingresscontroller
|
||||
labels:
|
||||
app: caddyIngressController
|
||||
chart: "caddyingresscontroller-v0.1.0"
|
||||
release: "release-name"
|
||||
heritage: "Tiller"
|
||||
version: v0.1.0
|
||||
4
kubernetes/helm/caddyingresscontroller/Chart.yaml
Normal file
4
kubernetes/helm/caddyingresscontroller/Chart.yaml
Normal file
@ -0,0 +1,4 @@
|
||||
apiVersion: v1
|
||||
description: A helm chart for the Caddy Kubernetes ingress controller
|
||||
name: caddyingresscontroller
|
||||
version: v0.1.0
|
||||
@ -0,0 +1,29 @@
|
||||
{{- if and ( .Values.caddyingresscontroller.rbac.create ) (eq .Values.caddyingresscontroller.watchNamespace "") }}
|
||||
apiVersion: rbac.authorization.k8s.io/v1beta1
|
||||
kind: ClusterRole
|
||||
metadata:
|
||||
name: {{ .Values.name }}-role
|
||||
rules:
|
||||
- apiGroups:
|
||||
- ""
|
||||
- "extensions"
|
||||
resources:
|
||||
- ingresses
|
||||
- routes
|
||||
verbs:
|
||||
- list
|
||||
- get
|
||||
- update
|
||||
- patch
|
||||
- watch
|
||||
- delete
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- services
|
||||
- pods
|
||||
verbs:
|
||||
- list
|
||||
- get
|
||||
- watch
|
||||
{{- end }}
|
||||
@ -0,0 +1,14 @@
|
||||
{{- if and ( .Values.caddyingresscontroller.rbac.create ) (eq .Values.caddyingresscontroller.watchNamespace "") }}
|
||||
kind: ClusterRoleBinding
|
||||
apiVersion: rbac.authorization.k8s.io/v1beta1
|
||||
metadata:
|
||||
name: {{ .Values.name }}-role-binding
|
||||
roleRef:
|
||||
kind: ClusterRole
|
||||
name: {{ .Values.name }}-role
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: {{ .Values.serviceAccountName }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
{{- end }}
|
||||
@ -0,0 +1,40 @@
|
||||
apiVersion: extensions/v1beta1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: {{ .Values.name }}
|
||||
labels:
|
||||
app: {{ .Values.name }}
|
||||
chart: "{{ .Chart.Name }}-{{ .Chart.Version }}"
|
||||
release: {{ .Release.Name | quote }}
|
||||
heritage: {{ .Release.Service | quote }}
|
||||
{{- if .Values.caddyingresscontroller.deployment.labels }}
|
||||
{{ toYaml .Values.caddyingresscontroller.deployment.labels | indent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
replicas: 1
|
||||
revisionHistoryLimit: 2
|
||||
selector:
|
||||
matchLabels:
|
||||
app: {{ .Values.name }}
|
||||
release: {{ .Release.Name | quote }}
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: {{ .Values.name }}
|
||||
chart: "{{ .Chart.Name }}-{{ .Chart.Version }}"
|
||||
release: {{ .Release.Name | quote }}
|
||||
heritage: {{ .Release.Service | quote }}
|
||||
{{- if .Values.caddyingresscontroller.deployment.labels }}
|
||||
{{ toYaml .Values.caddyingresscontroller.deployment.labels | indent 8 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
containers:
|
||||
- env:
|
||||
{{- if .Values.caddyingresscontroller.watchNamespace }}
|
||||
- name: KUBERNETES_NAMESPACE
|
||||
value: {{ .Values.caddyingresscontroller.watchNamespace | quote }}
|
||||
{{- end }}
|
||||
image: "{{ .Values.caddyingresscontroller.image.name }}:{{ .Values.caddyingresscontroller.image.tag }}"
|
||||
imagePullPolicy: {{ .Values.caddyingresscontroller.image.pullPolicy }}
|
||||
name: {{ .Values.name }}
|
||||
serviceAccountName: {{ .Values.serviceAccountName }}
|
||||
30
kubernetes/helm/caddyingresscontroller/templates/role.yaml
Normal file
30
kubernetes/helm/caddyingresscontroller/templates/role.yaml
Normal file
@ -0,0 +1,30 @@
|
||||
{{- if and ( .Values.caddyingresscontroller.rbac.create ) (.Values.caddyingresscontroller.watchNamespace) }}
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: Role
|
||||
metadata:
|
||||
name: {{ .Values.name }}-role
|
||||
namespace: {{ .Values.caddyingresscontroller.watchNamespace | quote }}
|
||||
rules:
|
||||
- apiGroups:
|
||||
- ""
|
||||
- "extensions"
|
||||
resources:
|
||||
- ingresses
|
||||
- routes
|
||||
verbs:
|
||||
- list
|
||||
- get
|
||||
- update
|
||||
- patch
|
||||
- watch
|
||||
- delete
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- services
|
||||
- pods
|
||||
verbs:
|
||||
- list
|
||||
- get
|
||||
- watch
|
||||
{{- end }}
|
||||
@ -0,0 +1,15 @@
|
||||
{{- if and ( .Values.caddyingresscontroller.rbac.create ) (.Values.caddyingresscontroller.watchNamespace) }}
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: RoleBinding
|
||||
metadata:
|
||||
name: {{ .Values.name }}-role-binding
|
||||
namespace: {{ .Values.caddyingresscontroller.watchNamespace | quote }}
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: Role
|
||||
name: {{ .Values.name }}-role
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: {{ .Values.serviceAccountName }}
|
||||
namespace: {{ .Release.Namespace | quote }}
|
||||
{{- end }}
|
||||
@ -0,0 +1,17 @@
|
||||
{{- if .Values.caddyingresscontroller.serviceAccount.create }}
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
labels:
|
||||
app: {{ .Values.name }}
|
||||
chart: "{{ .Chart.Name }}-{{ .Chart.Version }}"
|
||||
release: {{ .Release.Name | quote }}
|
||||
heritage: {{ .Release.Service | quote }}
|
||||
{{- if .Values.caddyingresscontroller.serviceAccount.labels }}
|
||||
{{ toYaml .Values.caddyingresscontroller.serviceAccount.labels | indent 4 }}
|
||||
{{- end }}
|
||||
{{- if .Values.caddyingresscontroller.matchLabels }}
|
||||
{{ toYaml .Values.caddyingresscontroller.matchLabels | indent 4 }}
|
||||
{{- end }}
|
||||
name: {{ .Values.serviceAccountName }}
|
||||
{{- end }}
|
||||
34
kubernetes/helm/caddyingresscontroller/values.yaml
Normal file
34
kubernetes/helm/caddyingresscontroller/values.yaml
Normal file
@ -0,0 +1,34 @@
|
||||
# Default values for caddyingresscontroller.
|
||||
# This is a YAML-formatted file.
|
||||
# Declare variables to be passed into your templates.
|
||||
|
||||
kubernetes:
|
||||
host: https://kubernetes.default
|
||||
|
||||
caddyingresscontroller:
|
||||
tolerations: {}
|
||||
watchNamespace: ""
|
||||
deployment:
|
||||
labels:
|
||||
version: "v0.1.0"
|
||||
config:
|
||||
labels:
|
||||
version: "v0.1.0"
|
||||
rbac:
|
||||
create: true
|
||||
# Service account config for the agent pods
|
||||
serviceAccount:
|
||||
# Specifies whether a ServiceAccount should be created
|
||||
create: true
|
||||
labels:
|
||||
version: "v0.1.0"
|
||||
# The name of the ServiceAccount to use.
|
||||
# If not set and create is true, a name is generated using the fullname template
|
||||
name: caddyIngressController
|
||||
image:
|
||||
name: caddy/ingresscontroller
|
||||
tag: "v0.1.0"
|
||||
pullPolicy: IfNotPresent
|
||||
|
||||
name: "caddyingresscontroller"
|
||||
serviceAccountName: "caddyingresscontroller"
|
||||
12
skaffold.yaml
Normal file
12
skaffold.yaml
Normal file
@ -0,0 +1,12 @@
|
||||
apiVersion: skaffold/v1beta8
|
||||
kind: Config
|
||||
build:
|
||||
artifacts:
|
||||
- image: caddy/ingresscontroller
|
||||
deploy:
|
||||
kubectl:
|
||||
manifests:
|
||||
- kubernetes/generated/clusterrole.yaml
|
||||
- kubernetes/generated/clusterrolebinding.yaml
|
||||
- kubernetes/generated/deployment.yaml
|
||||
- kubernetes/generated/serviceaccount.yaml
|
||||
Loading…
x
Reference in New Issue
Block a user