Skip to content

Commit

Permalink
Mesh Handler create CRDs and Services (#30)
Browse files Browse the repository at this point in the history
  • Loading branch information
dtomcej authored and mmatur committed Jun 13, 2019
1 parent b46c09d commit 84ede33
Show file tree
Hide file tree
Showing 6 changed files with 190 additions and 299 deletions.
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.

0 comments on commit 84ede33

Please sign in to comment.