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

Add Kamel CLI download link to OpenShift Web console #983

Merged
merged 2 commits into from
Oct 9, 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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ module github.com/apache/camel-k

require (
contrib.go.opencensus.io/exporter/prometheus v0.1.0 // indirect
contrib.go.opencensus.io/exporter/stackdriver v0.12.2
contrib.go.opencensus.io/exporter/stackdriver v0.12.2 // indirect
github.com/Masterminds/semver v1.4.2
github.com/alecthomas/jsonschema v0.0.0-20190122210438-a6952de1bbe6
github.com/coreos/prometheus-operator v0.29.0
Expand All @@ -14,7 +14,7 @@ require (
github.com/mitchellh/mapstructure v1.1.2
github.com/onsi/ginkgo v1.8.0 // indirect
github.com/onsi/gomega v1.5.0
github.com/openshift/api v3.9.0+incompatible
github.com/openshift/api v0.0.0-20190927182313-d4a64ec2cbd8+incompatible
github.com/operator-framework/operator-sdk v0.10.0
github.com/pkg/errors v0.8.1
github.com/radovskyb/watcher v1.0.6
Expand Down
72 changes: 2 additions & 70 deletions go.sum

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions pkg/client/fastmapper.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ var allowedAPIGroups = map[string]bool{
"camel.apache.org": true,
"project.openshift.io": true, // used in e2e tests
"rbac.authorization.k8s.io": true,
"console.openshift.io": true, // OpenShift console resources
}

// newFastDiscoveryRESTMapper comes from https://github.com/kubernetes-sigs/controller-runtime/pull/592.
Expand Down
2 changes: 1 addition & 1 deletion pkg/cmd/install.go
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ func (o *installCmdOptions) install(cobraCmd *cobra.Command, _ []string) error {
// Let's use a client provider during cluster installation, to eliminate the problem of CRD object caching
clientProvider := client.Provider{Get: o.NewCmdClient}

err := install.SetupClusterwideResourcesOrCollect(o.Context, clientProvider, collection)
err := install.SetupClusterWideResourcesOrCollect(o.Context, clientProvider, collection)
if err != nil && k8serrors.IsForbidden(err) {
fmt.Println("Current user is not authorized to create cluster-wide objects like custom resource definitions or cluster roles: ", err)

Expand Down
15 changes: 8 additions & 7 deletions pkg/install/cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,8 @@ import (
k8sclient "sigs.k8s.io/controller-runtime/pkg/client"
)

// SetupClusterwideResources --
func SetupClusterwideResources(ctx context.Context, clientProvider client.Provider) error {
return SetupClusterwideResourcesOrCollect(ctx, clientProvider, nil)
}

// SetupClusterwideResourcesOrCollect --
func SetupClusterwideResourcesOrCollect(ctx context.Context, clientProvider client.Provider, collection *kubernetes.Collection) error {
// SetupClusterWideResourcesOrCollect --
func SetupClusterWideResourcesOrCollect(ctx context.Context, clientProvider client.Provider, collection *kubernetes.Collection) error {
// Get a client to install the CRD
c, err := clientProvider.Get()
if err != nil {
Expand Down Expand Up @@ -86,6 +81,12 @@ func SetupClusterwideResourcesOrCollect(ctx context.Context, clientProvider clie
}
}

// Install OpenShift Console download links if possible
err = installOpenShiftConsoleDownloadLink(ctx, c)
if err != nil {
return err
}

// Wait for all CRDs to be installed before proceeding
if err := WaitForAllCRDInstallation(ctx, clientProvider, 25*time.Second); err != nil {
return err
Expand Down
140 changes: 140 additions & 0 deletions pkg/install/openshift.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
/*
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package install

import (
"context"
"fmt"
"reflect"

"k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"

console "github.com/openshift/api/console/v1"

"github.com/apache/camel-k/pkg/client"
"github.com/apache/camel-k/pkg/util/defaults"

"github.com/Masterminds/semver"
)

const (
kamelCliDownloadName = "kamel-cli"
kamelVersionAnnotation = "camel.apache.org/version"
)

func installOpenShiftConsoleDownloadLink(ctx context.Context, c client.Client) error {
// Check the ConsoleCLIDownload CRD is present, which should be starting OpenShift version 4.2.
// That check is also enough to exclude Kubernetes clusters.
ok, err := isAPIResourceInstalled(c, "console.openshift.io/v1", reflect.TypeOf(console.ConsoleCLIDownload{}).Name())
if err != nil {
return err
} else if !ok {
return nil
}

// Check for an existing ConsoleCLIDownload resource
existing := &console.ConsoleCLIDownload{}
err = c.Get(ctx, types.NamespacedName{Name: kamelCliDownloadName}, existing)
if err != nil {
if errors.IsNotFound(err) {
existing = nil
} else {
return err
}
}

if existing != nil {
if version, ok := existing.Annotations[kamelVersionAnnotation]; ok {
current, err := semver.NewVersion(version)
if err != nil {
return err
}
this, err := semver.NewVersion(defaults.Version)
if err != nil {
return err
}
if this.LessThan(current) {
// Keep the most recent version
return nil
}
// Else delete the older version
err = c.Delete(ctx, existing)
if err != nil {
return err
}
}
}

// Create the ConsoleCLIDownload for Kamel CLI
link := console.ConsoleCLIDownload{
ObjectMeta: metav1.ObjectMeta{
Annotations: map[string]string{
kamelVersionAnnotation: defaults.Version,
},
Name: kamelCliDownloadName,
},
Spec: console.ConsoleCLIDownloadSpec{
DisplayName: "kamel - Apache Camel K Command Line Interface",
Description: "Apache Camel K is a lightweight integration platform, born on Kubernetes, with serverless superpowers.\n\n" +
"The `kamel` binary can be used to both configure the cluster and run integrations. " +
"Once you've downloaded the `kamel` binary, log into the cluster using the `oc` client tool and start using the `kamel` CLI.\n\n" +
"You can run `kamel help` to list the available commands or go to the [Camel K Website](https://camel.apache.org/projects/camel-k/) for more information.",
Links: []console.Link{
{
Text: "Download the kamel binary for Linux",
Href: fmt.Sprintf("https://github.com/apache/camel-k/releases/download/%s/camel-k-client-%s-linux-64bit.tar.gz", defaults.Version, defaults.Version),
},
{
Text: "Download the kamel binary for Mac",
Href: fmt.Sprintf("https://github.com/apache/camel-k/releases/download/%s/camel-k-client-%s-mac-64bit.tar.gz", defaults.Version, defaults.Version),
},
{
Text: "Download the kamel binary for Windows",
Href: fmt.Sprintf("https://github.com/apache/camel-k/releases/download/%s/camel-k-client-%s-windows-64bit.tar.gz", defaults.Version, defaults.Version),
},
},
},
}

err = c.Create(ctx, &link)
if err != nil {
return err
}

return nil
}

func isAPIResourceInstalled(c client.Client, groupVersion string, kind string) (bool, error) {
resources, err := c.Discovery().ServerResourcesForGroupVersion(groupVersion)
if err != nil {
if errors.IsNotFound(err) {
return false, nil
}
return false, err
}

for _, resource := range resources.APIResources {
if resource.Kind == kind {
return true, nil
}
}

return false, nil
}
24 changes: 15 additions & 9 deletions pkg/util/openshift/register.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,18 @@ limitations under the License.
package openshift

import (
"github.com/apache/camel-k/pkg/util/log"
"k8s.io/apimachinery/pkg/runtime"

apps "github.com/openshift/api/apps/v1"
authorization "github.com/openshift/api/authorization/v1"
build "github.com/openshift/api/build/v1"
console "github.com/openshift/api/console/v1"
image "github.com/openshift/api/image/v1"
project "github.com/openshift/api/project/v1"
route "github.com/openshift/api/route/v1"
template "github.com/openshift/api/template/v1"
"k8s.io/apimachinery/pkg/runtime"

"github.com/apache/camel-k/pkg/util/log"
)

type registerFunction func(*runtime.Scheme) error
Expand All @@ -37,13 +40,16 @@ func AddToScheme(scheme *runtime.Scheme) error {
var err error

// Standardized groups
err = doAdd(apps.AddToScheme, scheme, err)
err = doAdd(template.AddToScheme, scheme, err)
err = doAdd(image.AddToScheme, scheme, err)
err = doAdd(route.AddToScheme, scheme, err)
err = doAdd(build.AddToScheme, scheme, err)
err = doAdd(authorization.AddToScheme, scheme, err)
err = doAdd(project.AddToScheme, scheme, err)
err = doAdd(apps.Install, scheme, err)
err = doAdd(template.Install, scheme, err)
err = doAdd(image.Install, scheme, err)
err = doAdd(route.Install, scheme, err)
err = doAdd(build.Install, scheme, err)
err = doAdd(authorization.Install, scheme, err)
err = doAdd(project.Install, scheme, err)

// OpenShift console API
err = doAdd(console.Install, scheme, err)

return err
}
Expand Down