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

Mesh Handler create CRDs and Services #30

Merged
merged 4 commits into from
Jun 13, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
9 changes: 0 additions & 9 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,15 +64,6 @@ func runCommand() func(cmd *cobra.Command, args []string) {
log.Fatalf("Error verifying cluster: %v", err)
}

var meshConfig *utils.TraefikMeshConfig
if meshConfig, err = utils.CreateMeshConfig(clients.KubeClient); err != nil {
log.Fatalf("Error creating mesh config: %v", err)
}

if err = utils.CreateRoutingConfigMap(clients.KubeClient, meshConfig); err != nil {
log.Fatalf("Error creating routing config map: %v", err)
}

// Create a new controller.
controller := meshcontroller.NewMeshController()

Expand Down
16 changes: 3 additions & 13 deletions meshcontroller/meshcontroller.go → meshcontroller/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,15 @@ package meshcontroller
import (
"github.com/containous/i3o/controller"
"github.com/containous/i3o/utils"
traefik_v1alpha1 "github.com/containous/traefik/pkg/provider/kubernetes/crd/traefik/v1alpha1"
log "github.com/sirupsen/logrus"
apiv1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
)

type MeshController struct {
serviceController *controller.Controller
endpointController *controller.Controller
namespaceController *controller.Controller
crdController *controller.Controller
handler *Handler
serviceController *controller.Controller
handler *Handler
}

// New is used to build the informers and other required components of the mesh controller,
Expand All @@ -28,12 +24,9 @@ func NewMeshController() *MeshController {
func (m *MeshController) Init(clients *utils.ClientWrapper) {
ignoredNamespaces := []string{metav1.NamespaceSystem, utils.MeshNamespace}

m.handler = NewHandler(ignoredNamespaces)
m.handler = NewHandler(clients, ignoredNamespaces)
// Create the new subcontrollers
m.serviceController = controller.NewController(clients, apiv1.Service{}, ignoredNamespaces, m.handler)
m.endpointController = controller.NewController(clients, apiv1.Endpoints{}, ignoredNamespaces, m.handler)
m.namespaceController = controller.NewController(clients, apiv1.Namespace{}, ignoredNamespaces, m.handler)
m.crdController = controller.NewController(clients, traefik_v1alpha1.IngressRoute{}, ignoredNamespaces, m.handler)
}

// Run is the main entrypoint for the controller
Expand All @@ -45,9 +38,6 @@ func (m *MeshController) Run(stopCh <-chan struct{}) error {

// run the informer to start listing and watching resources
go m.serviceController.Run(stopCh)
go m.endpointController.Run(stopCh)
go m.namespaceController.Run(stopCh)
go m.crdController.Run(stopCh)

<-stopCh
log.Info("Shutting down workers")
Expand Down
181 changes: 181 additions & 0 deletions meshcontroller/handler.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
package meshcontroller

import (
"github.com/containous/i3o/utils"
crdclientset "github.com/containous/traefik/pkg/provider/kubernetes/crd/generated/clientset/versioned"
traefikv1alpha1 "github.com/containous/traefik/pkg/provider/kubernetes/crd/traefik/v1alpha1"
log "github.com/sirupsen/logrus"
apiv1 "k8s.io/api/core/v1"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/intstr"
"k8s.io/client-go/kubernetes"
)

// MeshControllerHandler is an implementation of Handler.
type Handler struct {
Clients *utils.ClientWrapper
IgnoredNamespaces []string
}

func NewHandler(clients *utils.ClientWrapper, namespaces []string) *Handler {
h := &Handler{
Clients: clients,
IgnoredNamespaces: namespaces,
}

if err := h.Init(); err != nil {
log.Errorln("Could not initialize MeshControllerHandler")
}

return h
}

// Init handles any handler initialization.
func (h *Handler) Init() error {
log.Debugln("MeshControllerHandler.Init")
return nil
}

// ObjectCreated is called when an object is created.
func (h *Handler) ObjectCreated(obj interface{}) {
// assert the type to an object to pull out relevant data
service := obj.(*corev1.Service)
if utils.Contains(h.IgnoredNamespaces, service.Namespace) {
return
}

log.Debugf("MeshControllerHandler ObjectCreated with type: *corev1.Service: %s/%s", service.Namespace, service.Name)

log.Debugf("Verifying associated mesh service for service: %s/%s", service.Namespace, service.Name)
if err := verifyMeshServiceExists(h.Clients.KubeClient, service); err != nil {
log.Errorf("Could not verify mesh service exists: %v", err)
return
}

log.Debugf("Verifying associated mesh ingressroute for service: %s/%s", service.Namespace, service.Name)
if err := verifyMeshIngressRouteExists(h.Clients.CrdClient, service); err != nil {
log.Errorf("Could not verify mesh ingressroute exists: %v", err)
}

}

// ObjectDeleted is called when an object is deleted.
func (h *Handler) ObjectDeleted(obj interface{}) {
// assert the type to an object to pull out relevant data
service := obj.(*corev1.Service)

if utils.Contains(h.IgnoredNamespaces, service.Namespace) {
return
}
log.Debugln("MeshControllerHandler.ObjectDeleted")
if err := verifyMeshServiceDeleted(h.Clients.KubeClient, service); err != nil {
log.Errorf("Could not verify mesh service deleted: %v", err)
return
}

if err := verifyMeshIngressRouteDeleted(h.Clients.CrdClient, service); err != nil {
log.Errorf("Could not verify mesh ingressroute deleted: %v", err)
}
}

// ObjectUpdated is called when an object is updated.
func (h *Handler) ObjectUpdated(objOld, objNew interface{}) {
log.Debugln("MeshControllerHandler.ObjectUpdated")
}

func verifyMeshServiceExists(client kubernetes.Interface, service *apiv1.Service) error {
meshServiceName := utils.ServiceToMeshName(service.Name, service.Namespace)
meshServiceInstance, err := client.CoreV1().Services(utils.MeshNamespace).Get(meshServiceName, metav1.GetOptions{})
if meshServiceInstance == nil || err != nil {
svc := &apiv1.Service{
ObjectMeta: metav1.ObjectMeta{
Name: meshServiceName,
Namespace: utils.MeshNamespace,
},
Spec: apiv1.ServiceSpec{
Ports: []apiv1.ServicePort{
{
Name: "web",
Port: 80,
TargetPort: intstr.FromInt(8000),
},
},
Selector: map[string]string{
"app": "traefik-mesh-node",
},
},
}

if _, err := client.CoreV1().Services(utils.MeshNamespace).Create(svc); err != nil {
return err
}
}

return nil
}

func verifyMeshServiceDeleted(client kubernetes.Interface, service *apiv1.Service) error {
meshServiceName := utils.ServiceToMeshName(service.Name, service.Namespace)
meshServiceInstance, err := client.CoreV1().Services(utils.MeshNamespace).Get(meshServiceName, metav1.GetOptions{})
if err != nil {
return err
}

if meshServiceInstance != nil {
// Service exists, delete
if err := client.CoreV1().Services(utils.MeshNamespace).Delete(meshServiceName, &metav1.DeleteOptions{}); err != nil {
return err
}
}

return nil
}

func verifyMeshIngressRouteExists(client crdclientset.Interface, service *apiv1.Service) error {
meshIngressRouteName := utils.ServiceToMeshName(service.Name, service.Namespace)
meshIngressRouteInstance, err := client.TraefikV1alpha1().IngressRoutes(service.Namespace).Get(meshIngressRouteName, metav1.GetOptions{})
if meshIngressRouteInstance == nil || err != nil {
ir := &traefikv1alpha1.IngressRoute{
ObjectMeta: metav1.ObjectMeta{
Name: meshIngressRouteName,
Namespace: service.Namespace,
},
Spec: traefikv1alpha1.IngressRouteSpec{
Routes: []traefikv1alpha1.Route{
{
Services: []traefikv1alpha1.Service{
{
Name: service.Name,
Port: service.Spec.Ports[0].Port,
},
},
},
},
},
}
if _, err := client.TraefikV1alpha1().IngressRoutes(metav1.NamespaceAll).Create(ir); err != nil {
return err
}

}

return nil
}

func verifyMeshIngressRouteDeleted(client crdclientset.Interface, service *apiv1.Service) error {
meshIngressRouteName := utils.ServiceToMeshName(service.Name, service.Namespace)
meshIngressRouteInstance, err := client.TraefikV1alpha1().IngressRoutes(service.Namespace).Get(meshIngressRouteName, metav1.GetOptions{})
if err != nil {
return err
}

if meshIngressRouteInstance != nil {
// CRD exists, delete
if err := client.TraefikV1alpha1().IngressRoutes(service.Namespace).Delete(meshIngressRouteName, &metav1.DeleteOptions{}); err != nil {
return err
}
}

return nil
}
67 changes: 0 additions & 67 deletions meshcontroller/meshcontrollerhandler.go

This file was deleted.

31 changes: 0 additions & 31 deletions templates/traefik-routing.tpl

This file was deleted.