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

adding consolelink namespacedashboard #13

Merged
merged 12 commits into from
Apr 3, 2020
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -40,17 +40,21 @@ install: install-crds
kubectl apply -f deploy/service_account.yaml -n ${NAMESPACE}
kubectl apply -f deploy/role.yaml -n ${NAMESPACE}
kubectl apply -f deploy/role_binding.yaml -n ${NAMESPACE}
kubectl apply -f deploy/cluster_role.yaml
kubectl apply -f deploy/cluster_role_binding.yaml

.PHONY: install-crds
install-crds:
kubectl apply -f deploy/crds/atlasmap.io_atlasmaps_crd.yaml
kubectl apply -f deploy/crds/atlasmaps.atlasmap.io.crd.yaml

.PHONY: uninstall
uninstall:
kubectl delete -f deploy/crds/atlasmaps.atlasmap.io.crd.yaml
kubectl delete -f deploy/service_account.yaml -n ${NAMESPACE}
kubectl delete -f deploy/role.yaml -n ${NAMESPACE}
kubectl delete -f deploy/role_binding.yaml -n ${NAMESPACE}
kubectl delete -f deploy/cluster_role.yaml
kubectl delete -f deploy/cluster_role_binding.yaml

.PHONY: deploy
deploy:
Expand Down
14 changes: 14 additions & 0 deletions deploy/cluster_role.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: atlasmap-operator
rules:
- apiGroups:
- console.openshift.io
resources:
- consolelinks
verbs:
- get
- create
- update
- delete
12 changes: 12 additions & 0 deletions deploy/cluster_role_binding.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: atlasmap-operator
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: atlasmap-operator
subjects:
- kind: ServiceAccount
name: atlasmap-operator
namespace: placeholder
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,21 @@ spec:
- update
- watch
serviceAccountName: atlasmap-operator
clusterPermissions:
- rules:
- apiGroups:
- console.openshift.io
resources:
- consolelinks
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
serviceAccountName: atlasmap-operator
strategy: deployment
installModes:
- supported: true
Expand Down
12 changes: 10 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,11 @@ require (
sigs.k8s.io/controller-runtime v0.4.0
)

require github.com/operator-framework/operator-sdk v0.15.1
require (
github.com/Masterminds/semver v1.5.0
github.com/openshift/client-go v0.0.0-20190923180330-3b6373338c9b
github.com/operator-framework/operator-sdk v0.15.1
)

// Pinned to kubernetes-1.16.2
replace (
Expand Down Expand Up @@ -49,4 +53,8 @@ replace (

replace github.com/docker/docker => github.com/moby/moby v0.7.3-0.20190826074503-38ab9da00309 // Required by Helm

replace github.com/openshift/api => github.com/openshift/api v0.0.0-20190924102528-32369d4db2ad // Required until https://github.com/operator-framework/operator-lifecycle-manager/pull/1241 is resolved
//Openshift release-4.3
replace (
github.com/openshift/api => github.com/openshift/api v0.0.0-20200205145930-e9d93e317dd1
github.com/openshift/client-go => github.com/openshift/client-go v0.0.0-20191125132246-f6563a70e19a
)
8 changes: 5 additions & 3 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ github.com/JeffAshton/win_pdh v0.0.0-20161109143554-76bb4ee9f0ab/go.mod h1:3VYc5
github.com/MakeNowJust/heredoc v0.0.0-20170808103936-bb23615498cd/go.mod h1:64YHyfSL2R96J44Nlwm39UHepQbyR5q10x7iYa1ks2E=
github.com/MakeNowJust/heredoc v0.0.0-20171113091838-e9091a26100e/go.mod h1:64YHyfSL2R96J44Nlwm39UHepQbyR5q10x7iYa1ks2E=
github.com/Masterminds/goutils v1.1.0/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU=
github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww=
github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y=
github.com/Masterminds/semver/v3 v3.0.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs=
github.com/Masterminds/sprig/v3 v3.0.0/go.mod h1:NEUY/Qq8Gdm2xgYA+NwJM6wmfdRV9xkh8h/Rld20R0U=
Expand Down Expand Up @@ -544,9 +545,10 @@ github.com/opencontainers/runc v0.1.1/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59P
github.com/opencontainers/runc v1.0.0-rc2.0.20190611121236-6cc515888830/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
github.com/opencontainers/runtime-spec v1.0.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
github.com/opencontainers/selinux v1.2.2/go.mod h1:+BLncwf63G4dgOzykXAxcmnFlUaOlkDdmw/CqsW6pjs=
github.com/openshift/api v0.0.0-20190924102528-32369d4db2ad h1:MiZEukiPd7ll8BQDwBfc3LKBxbqyeXIx+wl4CzVj5EQ=
github.com/openshift/api v0.0.0-20190924102528-32369d4db2ad/go.mod h1:dh9o4Fs58gpFXGSYfnVxGR9PnV53I8TW84pQaJDdGiY=
github.com/openshift/client-go v0.0.0-20190923180330-3b6373338c9b/go.mod h1:6rzn+JTr7+WYS2E1TExP4gByoABxMznR6y2SnUIkmxk=
github.com/openshift/api v0.0.0-20200205145930-e9d93e317dd1 h1:9+nvzkAohurf7NS8mXalTntCldBkv5jMo0sLzDE2Op0=
github.com/openshift/api v0.0.0-20200205145930-e9d93e317dd1/go.mod h1:dh9o4Fs58gpFXGSYfnVxGR9PnV53I8TW84pQaJDdGiY=
github.com/openshift/client-go v0.0.0-20191125132246-f6563a70e19a h1:Otk3CuCAEHiMUr4Er6b+csq4Ar6qilAs9h93tbea+qM=
github.com/openshift/client-go v0.0.0-20191125132246-f6563a70e19a/go.mod h1:6rzn+JTr7+WYS2E1TExP4gByoABxMznR6y2SnUIkmxk=
github.com/openshift/origin v0.0.0-20160503220234-8f127d736703/go.mod h1:0Rox5r9C8aQn6j1oAOQ0c1uC86mYbUFObzjBRvUKHII=
github.com/openshift/prom-label-proxy v0.1.1-0.20191016113035-b8153a7f39f1/go.mod h1:p5MuxzsYP1JPsNGwtjtcgRHHlGziCJJfztff91nNixw=
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
Expand Down
24 changes: 22 additions & 2 deletions pkg/controller/atlasmap/action.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package atlasmap

import (
"context"
"github.com/Masterminds/semver"
"github.com/atlasmap/atlasmap-operator/pkg/util"
"k8s.io/client-go/rest"

Expand Down Expand Up @@ -36,18 +37,38 @@ func newOperatorActions(log logr.Logger, mgr manager.Manager) []action {
log.Error(err, "Failed to determine cluster version. Defaulting to Kubernetes mode.")
}

var consoleLink action
if isOpenShift {
openShiftSemVer := util.GetClusterVersionSemVer(mgr.GetConfig())
if openShiftSemVer != nil {
constraint43, _ := semver.NewConstraint(">= 4.3")
isOpenShift43Plus := constraint43.Check(openShiftSemVer)

if isOpenShift43Plus {
consoleLink = newConsoleLinkAction(log.WithValues("type", "create-consolelink"), mgr)
}
}

}

var routeAction action
if isOpenShift {
routeAction = newRouteAction(log.WithValues("type", "create-route"), mgr)
} else {
routeAction = newIngressAction(log.WithValues("type", "create-ingress"), mgr)
}

return []action{
actions := []action{
newServiceAction(log.WithValues("type", "service"), mgr),
routeAction,
newDeploymentAction(log.WithValues("type", "create-deployment"), mgr),
}

if consoleLink != nil {
actions = append(actions, consoleLink)
}

return actions
}

func newBaseAction(log logr.Logger, mgr manager.Manager, name string) baseAction {
Expand Down Expand Up @@ -80,4 +101,3 @@ func (action *baseAction) updatePhase(ctx context.Context, atlasMap *v1alpha1.At
}
}
}

124 changes: 124 additions & 0 deletions pkg/controller/atlasmap/action_consolelink.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
package atlasmap

import (
"context"
"github.com/atlasmap/atlasmap-operator/pkg/apis/atlasmap/v1alpha1"
"github.com/atlasmap/atlasmap-operator/pkg/util"
"github.com/go-logr/logr"
consolev1 "github.com/openshift/api/console/v1"
routev1 "github.com/openshift/api/route/v1"
"k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/manager"
)

const (
consoleLinkFinalizer = "finalizer.console.openshift.io"
)

type consoleLinkAction struct {
baseAction
}

func newConsoleLinkAction(log logr.Logger, mgr manager.Manager) action {
return &consoleLinkAction{
newBaseAction(log, mgr, "ConsoleLink"),
}
}
func (action *consoleLinkAction) getRoute(ctx context.Context, atlasMap *v1alpha1.AtlasMap) (*routev1.Route, error) {
route := &routev1.Route{}
err := action.client.Get(ctx, types.NamespacedName{Name: atlasMap.Name, Namespace: atlasMap.Namespace}, route)
if err != nil && errors.IsNotFound(err) {
return route, nil
} else if err != nil {
action.log.Error(err, "Error retrieving route.")
return nil, err
}
return route, err
}

func (action *consoleLinkAction) handle(ctx context.Context, atlasMap *v1alpha1.AtlasMap) error {
isOpenShift, err := util.IsOpenShift(action.config)
if err != nil {
return err
}

if isOpenShift {

route, err := action.getRoute(ctx, atlasMap)
if err != nil {
return err
}

consoleLinkName := atlasMap.Name + "-" + atlasMap.Namespace
consoleLink := &consolev1.ConsoleLink{}
err = action.client.Get(ctx, types.NamespacedName{Name: consoleLinkName}, consoleLink)
if err != nil && errors.IsNotFound(err) {
consoleLink = createNamespaceDashboardLink(consoleLinkName, route, atlasMap)
err = action.client.Create(ctx, consoleLink)
if err != nil {
return err
}

} else if err == nil && consoleLink != nil {

if atlasMap.DeletionTimestamp != nil {
err = action.client.Delete(ctx, consoleLink)
if err == nil {
action.log.Error(err, "Error deleting console link.")
}
}

if err := reconcileConsoleLink(route, consoleLink, action.client, ctx); err != nil {
return err
}
}
}

return nil
}

func reconcileConsoleLink(route *routev1.Route, link *consolev1.ConsoleLink, client client.Client, ctx context.Context) error {
url := "https://" + route.Spec.Host
if link.Spec.Href != url {
link.Spec.Href = url
if err := client.Update(ctx, link); err != nil {
return err
}
}

if link.Spec.Text != route.Name {
link.Spec.Text = route.Name
if err := client.Update(ctx, link); err != nil {
return err
}
}

return nil
}

func createNamespaceDashboardLink(name string, route *routev1.Route, atlasMap *v1alpha1.AtlasMap) *consolev1.ConsoleLink {
consoleLink := &consolev1.ConsoleLink{
ObjectMeta: metav1.ObjectMeta{
Name: name,
Labels: map[string]string{"app": atlasMap.Name},
},
Spec: consolev1.ConsoleLinkSpec{
Location: consolev1.NamespaceDashboard,
NamespaceDashboard: &consolev1.NamespaceDashboardSpec{
Namespaces: []string{atlasMap.Namespace},
},
},
}

setNamespaceDashboardLink(consoleLink, route)

return consoleLink
}

func setNamespaceDashboardLink(consoleLink *consolev1.ConsoleLink, route *routev1.Route) {
consoleLink.Spec.Link.Text = route.Name
consoleLink.Spec.Link.Href = "https://" + route.Spec.Host
}
55 changes: 48 additions & 7 deletions pkg/controller/atlasmap/atlasmap_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,16 @@ package atlasmap

akoserwal marked this conversation as resolved.
Show resolved Hide resolved
import (
"context"
consolev1 "github.com/openshift/api/console/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
"k8s.io/client-go/rest"
"reflect"

routev1 "github.com/openshift/api/route/v1"

"github.com/atlasmap/atlasmap-operator/pkg/apis/atlasmap/v1alpha1"
"github.com/atlasmap/atlasmap-operator/pkg/util"
routev1 "github.com/openshift/api/route/v1"
configv1client "github.com/openshift/client-go/config/clientset/versioned"
appsv1 "k8s.io/api/apps/v1"
"k8s.io/api/extensions/v1beta1"
"k8s.io/apimachinery/pkg/api/errors"
Expand All @@ -27,12 +31,23 @@ import (
// Add creates a new AtlasMap Controller and adds it to the Manager. The Manager will set fields on the Controller
// and Start it when the Manager is Started.
func Add(mgr manager.Manager) error {
return add(mgr, newReconciler(mgr))
}
err := consolev1.Install(mgr.GetScheme())
if err != nil {
return err
}

newReconciler := &ReconcileAtlasMap{
client: mgr.GetClient(),
config: mgr.GetConfig(),
scheme: mgr.GetScheme(),
}

// newReconciler returns a new reconcile.Reconciler
func newReconciler(mgr manager.Manager) reconcile.Reconciler {
return &ReconcileAtlasMap{client: mgr.GetClient(), scheme: mgr.GetScheme()}
configClient, err := configv1client.NewForConfig(mgr.GetConfig())
if err != nil {
return err
}
newReconciler.configClient = configClient
return add(mgr, newReconciler)
}

var actions []action
Expand Down Expand Up @@ -111,6 +126,8 @@ type ReconcileAtlasMap struct {
// that reads objects from the cache and writes to the apiserver
client client.Client
scheme *runtime.Scheme
config *rest.Config
configClient *configv1client.Clientset
}

// Reconcile reads that state of the cluster for a AtlasMap object and makes changes based on the state read
Expand All @@ -131,6 +148,13 @@ func (r *ReconcileAtlasMap) Reconcile(request reconcile.Request) (reconcile.Resu
// Request object not found, could have been deleted after reconcile request.
// Owned objects are automatically garbage collected. For additional cleanup logic use finalizers.
// Return and don't requeue
instance.ObjectMeta = metav1.ObjectMeta{
Name: request.Name,
Namespace: request.Namespace,
}
//Handling removable of cluster-scope object.
r.removeConsoleLink(instance)

return reconcile.Result{}, nil
}
// Error reading the object - requeue the request.
Expand All @@ -150,3 +174,20 @@ func (r *ReconcileAtlasMap) Reconcile(request reconcile.Request) (reconcile.Resu

return reconcile.Result{}, nil
}

func (r *ReconcileAtlasMap) removeConsoleLink(atlasMap *v1alpha1.AtlasMap) (request reconcile.Result, err error) {
consoleLinkName := atlasMap.Name + "-" + atlasMap.Namespace
consoleLink := &consolev1.ConsoleLink{}
err = r.client.Get(context.TODO(), types.NamespacedName{Name: consoleLinkName}, consoleLink)
if err != nil {
if !errors.IsNotFound(err) {
return reconcile.Result{}, err
}
} else {
err = r.client.Delete(context.TODO(), consoleLink)
if err != nil {
return reconcile.Result{}, err
}
}
return reconcile.Result{}, err
}
Loading