blob: 951656fbe48e77ab5b01e2be9cfb9bc6d48c14f4 [file]
/*
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 integrationplatform
import (
"context"
"fmt"
"strings"
v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1"
platformutil "github.com/apache/camel-k/v2/pkg/platform"
"github.com/apache/camel-k/v2/pkg/util/defaults"
"github.com/apache/camel-k/v2/pkg/util/openshift"
corev1 "k8s.io/api/core/v1"
)
// NewMonitorAction returns an action that monitors the integration platform after it's fully initialized.
func NewMonitorAction() Action {
return &monitorAction{}
}
type monitorAction struct {
baseAction
}
func (action *monitorAction) Name() string {
return "monitor"
}
//nolint:staticcheck
func (action *monitorAction) CanHandle(platform *v1.IntegrationPlatform) bool {
return platform.Status.Phase == v1.IntegrationPlatformPhaseReady || platform.Status.Phase == v1.IntegrationPlatformPhaseError
}
//nolint:staticcheck
func (action *monitorAction) Handle(ctx context.Context, platform *v1.IntegrationPlatform) (*v1.IntegrationPlatform, error) {
runtimeVersion := specOrDefault(platform.Spec.Build.RuntimeVersion)
if platform.Status.Build.RuntimeVersion != runtimeVersion {
action.L.Infof("IntegrationPlatform version updated from %s to %s", platform.Status.Build.RuntimeVersion, runtimeVersion)
// Reset the status to reinitialize the resource
platform.Status = v1.IntegrationPlatformStatus{}
return platform, nil
}
// Sync status configuration
if err := platformutil.ConfigureDefaults(ctx, action.client, platform, false); err != nil {
return nil, err
}
// Get the information about Camel version in the catalog
runtimeSpec := v1.RuntimeSpec{
Version: platform.Status.Build.RuntimeVersion,
Provider: platform.Status.Build.RuntimeProvider,
}
if runtimeSpec.Provider == v1.RuntimeProviderPlainQuarkus {
runtimeSpec.Version = defaults.CamelKRuntimeCatalogVersion
}
catalog, err := loadCatalog(ctx, action.client, platform.Namespace, runtimeSpec)
if catalog == nil || err != nil {
// error, a catalog must be available
platform.Status.Phase = v1.IntegrationPlatformPhaseError
platform.Status.SetCondition(
v1.IntegrationPlatformConditionCamelCatalogAvailable,
corev1.ConditionFalse,
v1.IntegrationPlatformConditionCamelCatalogAvailableReason,
fmt.Sprintf("camel catalog %s not available, please review given runtime version", runtimeSpec.Version))
return platform, err
}
// So far the ITP is good
platform.Status.Phase = v1.IntegrationPlatformPhaseReady
platform.Status.Build.RuntimeCoreVersion = catalog.Spec.GetCamelVersion()
// Registry condition
isOpenshift, err := openshift.IsOpenShift(action.client)
if err != nil {
return platform, err
}
//nolint: nestif
if isOpenshift && platform.Status.Build.PublishStrategy == v1.IntegrationPlatformBuildPublishStrategyS2I { //nolint:staticcheck
platform.Status.SetCondition(
v1.IntegrationPlatformConditionTypeRegistryAvailable,
corev1.ConditionFalse,
v1.IntegrationPlatformConditionTypeRegistryAvailableReason,
"registry not available because provided by Openshift S2I")
action.L.Infof("WARN: S2I publishing strategy is deprecated and may be removed in the future, use Jib strategy instead")
platform.Status.SetCondition(
"S2IPublishingStrategyDeprecated",
corev1.ConditionTrue,
"PublishingStrategyDeprecationNoticeReason",
"S2I publishing strategy is deprecated and may be removed in the future, use Jib strategy instead")
} else {
if platform.Status.Build.Registry.Address == "" {
// error, we need a registry if we're not on Openshift
platform.Status.Phase = v1.IntegrationPlatformPhaseError
platform.Status.SetCondition(
v1.IntegrationPlatformConditionTypeRegistryAvailable,
corev1.ConditionFalse,
v1.IntegrationPlatformConditionTypeRegistryAvailableReason,
"registry address not available, you need to set one")
} else {
platform.Status.SetCondition(
v1.IntegrationPlatformConditionTypeRegistryAvailable,
corev1.ConditionTrue,
v1.IntegrationPlatformConditionTypeRegistryAvailableReason,
"registry available at "+platform.Status.Build.Registry.Address)
// Warn if insecure registry
if platform.Status.Build.Registry.Insecure {
platform.Status.SetCondition(
v1.IntegrationPlatformConditionType("InsecureRegistryWarning"),
corev1.ConditionTrue,
"InsecureRegistryWarningReason",
"Registry is insecure. This setup should not be used in a production environment.")
action.L.Infof(
"WARN: provided container registry is insecure. This setup should not be used in a production environment.",
)
}
}
}
action.checkTraitAnnotationsDeprecatedNotice(platform)
action.checkMavenSettings(platform)
action.checkKameletsCatalogRepoDeprecatedNotice(platform)
platform.Status.SetCondition(
v1.IntegrationPlatformConditionType("IntegrationPlatformDeprecated"),
corev1.ConditionTrue,
"DeprecationNotice",
"The IntegrationPlatform custom resource is deprecated. Please, configure operator environment variables instead.",
)
return platform, nil
}
// Deprecated: to be removed in future versions, when we won't support any longer trait annotations into IntegrationPlatforms.
func (action *monitorAction) checkTraitAnnotationsDeprecatedNotice(platform *v1.IntegrationPlatform) {
if platform.Annotations != nil {
for k := range platform.Annotations {
if strings.HasPrefix(k, v1.TraitAnnotationPrefix) {
platform.Status.SetCondition(
v1.IntegrationPlatformConditionType("AnnotationTraitsDeprecated"),
corev1.ConditionTrue,
"DeprecationNotice",
"Annotation traits configuration is deprecated and will be removed soon. Use .spec.traits configuration instead.",
)
action.L.Infof(
"WARN: annotation traits configuration is deprecated and will be removed soon. Use .spec.traits configuration for %s platform instead.",
platform.Name,
)
return
}
}
}
}
// Deprecated: to be removed in future versions, when we won't support any longer Kamelets catalog into IntegrationPlatforms.
func (action *monitorAction) checkKameletsCatalogRepoDeprecatedNotice(platform *v1.IntegrationPlatform) {
if platform.Status.Kamelet.Repositories != nil {
platform.Status.SetCondition(
v1.IntegrationPlatformConditionType("KameletsCatalogRepositoryDeprecated"),
corev1.ConditionTrue,
"DeprecationNotice",
"Kamelets Catalog Repository is deprecated and will be removed soon. Bundle Kamelets into a Maven dependency instead.",
)
action.L.Infof(
"Kamelets Catalog Repository is deprecated and will be removed soon from IntegrationPlatform configuration. " +
"Bundle Kamelets into a Maven dependency instead")
}
}
//nolint:staticcheck
func (action *monitorAction) checkMavenSettings(platform *v1.IntegrationPlatform) {
if platform.Status.Build.Maven.Settings.ConfigMapKeyRef != nil ||
platform.Status.Build.Maven.Settings.SecretKeyRef != nil {
platform.Status.SetCondition(
v1.IntegrationPlatformConditionMavenSettingsAvailable,
corev1.ConditionTrue,
"MavenSettingsAvailable",
"Maven settings are available.",
)
} else {
platform.Status.SetCondition(
v1.IntegrationPlatformConditionMavenSettingsAvailable,
corev1.ConditionFalse,
"MavenSettingsAvailable",
"Maven settings are missing. You need to provide at least a Maven proxy configuration for performance reasons.",
)
action.L.Infof(
"WARN: Maven settings are missing for platform %s. "+
"You need to provide at least a Maven proxy configuration for performance reasons.",
platform.Name,
)
}
}
func specOrDefault(runtimeVersionSpec string) string {
if runtimeVersionSpec == "" {
return defaults.DefaultRuntimeVersion
}
return runtimeVersionSpec
}