Skip to content
Open
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
8 changes: 8 additions & 0 deletions .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,11 @@ version: "2"

run:
timeout: 10m

linters:
exclusions:
rules:
# TODO(#241): Remove once TargetNamespace field is fully removed
- linters:
- staticcheck
text: "SA1019:.*TargetNamespace"
7 changes: 3 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,11 @@ apiVersion: operator.shipwright.io/v1alpha1
kind: ShipwrightBuild
metadata:
name: shipwright-operator
spec:
targetNamespace: shipwright-build
spec: {}
```

The operator will deploy Shipwright Builds in the provided `targetNamespace`.
When `.spec.targetNamespace` is not set, the namespace will default to `shipwright-build`.
The operator will deploy Shipwright Builds in the operator's own namespace by default.
The `.spec.targetNamespace` field is **deprecated** — if set, it is still honored but logs a deprecation warning. It will be removed in a future release.

To deploy [Shipwright Triggers](https://github.com/shipwright-io/triggers), add the `triggers` field:

Expand Down
2 changes: 2 additions & 0 deletions api/v1alpha1/shipwrightbuild_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ type TriggersSpec struct {
// ShipwrightBuildSpec defines the configuration of a Shipwright Build deployment.
type ShipwrightBuildSpec struct {
// TargetNamespace is the target namespace where Shipwright's build controller will be deployed.
//
// Deprecated: will be removed in a future release. Defaults to the operator's namespace.
TargetNamespace string `json:"targetNamespace,omitempty"`

// Triggers configures the deployment of the Shipwright Triggers component.
Expand Down
6 changes: 4 additions & 2 deletions bundle/manifests/operator.shipwright.io_shipwrightbuilds.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,10 @@ spec:
Build deployment.
properties:
targetNamespace:
description: TargetNamespace is the target namespace where Shipwright's
build controller will be deployed.
description: |-
TargetNamespace is the target namespace where Shipwright's build controller will be deployed.

Deprecated: will be removed in a future release. Defaults to the operator's namespace.
type: string
triggers:
description: |-
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,7 @@ metadata:
"metadata": {
"name": "shipwright-build"
},
"spec": {
"targetNamespace": "shipwright-build"
}
"spec": {}
}
]
capabilities: Basic Install
Expand Down Expand Up @@ -682,6 +680,10 @@ spec:
env:
- name: USE_MANAGED_WEBHOOK_CERTS
value: "true"
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
image: ko://github.com/shipwright-io/operator
livenessProbe:
httpGet:
Expand Down
6 changes: 4 additions & 2 deletions config/crd/bases/operator.shipwright.io_shipwrightbuilds.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,10 @@ spec:
Build deployment.
properties:
targetNamespace:
description: TargetNamespace is the target namespace where Shipwright's
build controller will be deployed.
description: |-
TargetNamespace is the target namespace where Shipwright's build controller will be deployed.

Deprecated: will be removed in a future release. Defaults to the operator's namespace.
type: string
triggers:
description: |-
Expand Down
4 changes: 4 additions & 0 deletions config/manager/manager.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ spec:
env:
- name: USE_MANAGED_WEBHOOK_CERTS
value: "true"
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
image: ko://github.com/shipwright-io/operator
name: manager
securityContext:
Expand Down
3 changes: 1 addition & 2 deletions config/samples/operator_v1alpha1_shipwrightbuild.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,4 @@ apiVersion: operator.shipwright.io/v1alpha1
kind: ShipwrightBuild
metadata:
name: shipwright-build
spec:
targetNamespace: shipwright-build
spec: {}
46 changes: 22 additions & 24 deletions controllers/shipwrightbuild_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,6 @@ import (
const (
// FinalizerAnnotation annotation string appended on finalizer slice.
FinalizerAnnotation = "finalizer.operator.shipwright.io"
// defaultTargetNamespace fallback namespace when `.spec.namepace` is not informed.
defaultTargetNamespace = "shipwright-build"

// Ready object is providing service.
ConditionReady = "Ready"
Expand All @@ -64,6 +62,7 @@ type ShipwrightBuildReconciler struct {
TektonManifest manifestival.Manifest // Tekton release manifest render
BuildStrategyManifest manifestival.Manifest // Build strategies manifest to render
TriggersManifest manifestival.Manifest // Triggers manifest to render
OperatorNamespace string // namespace the operator is running in
}

type TektonCheckResult struct {
Expand Down Expand Up @@ -235,34 +234,33 @@ func (r *ShipwrightBuildReconciler) Reconcile(ctx context.Context, req ctrl.Requ
return Requeue()
}

// selecting the target namespace based on the CRD information, when not informed using the
// default namespace instead
targetNamespace := b.Spec.TargetNamespace
if targetNamespace == "" {
logger.Info(
"Namespace is not informed! Target namespace is selected from default settings instead",
"defaultTargetNamespace", defaultTargetNamespace,
if targetNamespace != "" && targetNamespace != r.OperatorNamespace {
logger.Info("spec.targetNamespace is deprecated, will be removed in a future release",
"targetNamespace", targetNamespace,
"operatorNamespace", r.OperatorNamespace,
)
targetNamespace = defaultTargetNamespace
}
logger = logger.WithValues("targetNamespace", targetNamespace)
// create if it does not exist
ns := &corev1.Namespace{}
if err := r.Get(ctx, types.NamespacedName{Name: targetNamespace}, ns); err != nil {
if !errors.IsNotFound(err) {
logger.Info("retrieving target namespace %s error: %s", targetNamespace, err.Error())
return RequeueOnError(err)
}
ns.Name = targetNamespace

if err = r.Create(ctx, ns, &client.CreateOptions{Raw: &metav1.CreateOptions{}}); err != nil {
if !errors.IsAlreadyExists(err) {
logger.Info("creating target namespace %s error: %s", targetNamespace, err.Error())
// Deprecated path: create the target namespace if it does not exist
ns := &corev1.Namespace{}
if err := r.Get(ctx, types.NamespacedName{Name: targetNamespace}, ns); err != nil {
if !errors.IsNotFound(err) {
logger.Info("retrieving target namespace %s error: %s", targetNamespace, err.Error())
return RequeueOnError(err)
}
ns.Name = targetNamespace

if err = r.Create(ctx, ns, &client.CreateOptions{Raw: &metav1.CreateOptions{}}); err != nil {
if !errors.IsAlreadyExists(err) {
logger.Info("creating target namespace %s error: %s", targetNamespace, err.Error())
return RequeueOnError(err)
}
}
logger.Info("created target namespace")
}
logger.Info("created target namespace")
} else {
targetNamespace = r.OperatorNamespace
}
logger = logger.WithValues("targetNamespace", targetNamespace)

// ReconcileCertManager
if common.BoolFromEnvVar(UseManagedWebhookCerts) {
Expand Down
7 changes: 5 additions & 2 deletions controllers/shipwrightbuild_controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ import (
"sigs.k8s.io/controller-runtime/pkg/reconcile"
)

// testOperatorNamespace is the namespace used as the operator's namespace in unit tests.
const testOperatorNamespace = "shipwright-operator"

// bootstrapShipwrightBuildReconciler start up a new instance of ShipwrightBuildReconciler which is
// ready to interact with Manifestival, returning the Manifestival instance and the client.
func bootstrapShipwrightBuildReconciler(
Expand Down Expand Up @@ -76,7 +79,7 @@ func bootstrapShipwrightBuildReconciler(
} else {
toClient = tektonoperatorv1alpha1client.NewSimpleClientset(tcfg)
}
r := &ShipwrightBuildReconciler{CRDClient: crdClient.ApiextensionsV1(), TektonOperatorClient: toClient.OperatorV1alpha1(), Client: c, Scheme: s, Logger: logger}
r := &ShipwrightBuildReconciler{CRDClient: crdClient.ApiextensionsV1(), TektonOperatorClient: toClient.OperatorV1alpha1(), Client: c, Scheme: s, Logger: logger, OperatorNamespace: testOperatorNamespace}

// creating targetNamespace on which Shipwright-Build will be deployed against, before the other
// tests takes place
Expand Down Expand Up @@ -248,7 +251,7 @@ func TestShipwrightBuildReconciler_Reconcile(t *testing.T) {
targetNamespace: "namespace",
}, {
testName: "target namespace is not informed",
targetNamespace: defaultTargetNamespace,
targetNamespace: testOperatorNamespace,
}}

for _, tt := range tests {
Expand Down
1 change: 1 addition & 0 deletions controllers/shipwrightbuild_rbac.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ package controllers
// +kubebuilder:rbac:groups=apps,resources=deployments/finalizers,resourceNames=shipwright-build-controller,verbs=update
// +kubebuilder:rbac:groups=apps,resources=deployments,resourceNames=shipwright-build-webhook,verbs=update;patch;delete
// +kubebuilder:rbac:groups=apps,resources=deployments/finalizers,resourceNames=shipwright-build-webhook,verbs=update
// TODO(#241): Reduce to get;list;watch once TargetNamespace field is fully removed
// +kubebuilder:rbac:groups=core,resources=namespaces,verbs=get;list;watch;create;update;patch;delete
// +kubebuilder:rbac:groups=core,resources=pods;events;configmaps;secrets;limitranges;namespaces;services,verbs=get;list;watch;create;update;patch;delete
// +kubebuilder:rbac:groups=core,resources=serviceaccounts,verbs=get;list;watch;create
Expand Down
1 change: 1 addition & 0 deletions controllers/suite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,7 @@ var _ = BeforeSuite(func() {
Client: mgr.GetClient(),
Scheme: scheme.Scheme,
Logger: ctrl.Log.WithName("controllers").WithName("shipwrightbuild"),
OperatorNamespace: testOperatorNamespace,
}).SetupWithManager(mgr)
Expect(err).NotTo(HaveOccurred())

Expand Down
2 changes: 1 addition & 1 deletion docs/shipwrightbuild.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,6 @@ When the `ShipwrightBuild` instance is created, the following components are ins

| Field | Description |
| ----- | ----------- |
| spec.targetNamespace | The target namespace where Shipwright Build will be deployed. If omitted, this will default to `shipwright-build` |
| spec.targetNamespace | **Deprecated.** The target namespace where Shipwright Build will be deployed. If omitted, operands are deployed in the operator's own namespace (determined by the `POD_NAMESPACE` environment variable). Setting this field still works but logs a deprecation warning. This field will be removed in a future release. |
| spec.triggers.deployment | When set to `Enabled`, deploys Shipwright Triggers alongside Build. Triggers are not deployed when this field is omitted or set to `Disabled`. Defaults to `Disabled`. |
| status.conditions | Conditions which report the status of Shipwright Build. Current reported conditions:<br><br>- `Ready` |
8 changes: 8 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import (

operatorv1alpha1 "github.com/shipwright-io/operator/api/v1alpha1"
"github.com/shipwright-io/operator/controllers"
"github.com/shipwright-io/operator/pkg/common"
// +kubebuilder:scaffold:imports
)

Expand Down Expand Up @@ -99,12 +100,19 @@ func main() {
os.Exit(1)
}

operatorNamespace := common.OperatorNamespace()
if operatorNamespace == "" {
operatorNamespace = common.DefaultNamespace
setupLog.Info("POD_NAMESPACE not set, falling back to default namespace for local development", "namespace", operatorNamespace)
}

if err = (&controllers.ShipwrightBuildReconciler{
CRDClient: crdClient,
TektonOperatorClient: tektonOperatorClient,
Client: mgr.GetClient(),
Scheme: mgr.GetScheme(),
Logger: ctrl.Log.WithName("controllers").WithName("ShipwrightBuild"),
OperatorNamespace: operatorNamespace,
}).SetupWithManager(mgr); err != nil {
setupLog.Error(err, "unable to create controller", "controller", "ShipwrightBuild")
os.Exit(1)
Expand Down
5 changes: 5 additions & 0 deletions pkg/common/const.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@ const (
koDataPathEnv = "KO_DATA_PATH"
ShipwrightImagePrefix = "IMAGE_SHIPWRIGHT_"

// OperatorNamespaceEnvVar holds the operator pod's namespace.
OperatorNamespaceEnvVar = "POD_NAMESPACE"
// DefaultNamespace is the fallback namespace when POD_NAMESPACE is unset.
DefaultNamespace = "shipwright-build"

TektonOpMinSupportedVersion = "v0.50.0"
TektonOpMinSupportedMajor = 0
TektonOpMinSupportedMinor = 50
Expand Down
5 changes: 5 additions & 0 deletions pkg/common/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -242,3 +242,8 @@ func itemInSlice(item string, items []string) bool {
func IsOpenShiftPlatform() bool {
return os.Getenv("PLATFORM") == "openshift"
}

// OperatorNamespace returns the operator pod's namespace from POD_NAMESPACE.
func OperatorNamespace() string {
return os.Getenv(OperatorNamespaceEnvVar)
}
Loading