Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
c55cf5d
add ManagedControlPlane type
Diaphteiros Jul 29, 2025
60a310b
refactor ManagedControlPlane type and oidc configuration based on rec…
Diaphteiros Jul 30, 2025
dd4229f
implement createOrUpdate path of mcp controller
Diaphteiros Aug 1, 2025
88f9b9e
fix linting issues
Diaphteiros Aug 1, 2025
0bf2cd6
split mcp access management into smaller helper functions
Diaphteiros Aug 1, 2025
fc27d7d
implement delete path of mcp controller
Diaphteiros Aug 5, 2025
e6580a0
add unit tests for the mcp controller (part 1)
Diaphteiros Aug 5, 2025
42404bb
add unit tests for the mcp controller (part 2)
Diaphteiros Aug 6, 2025
33752c9
add unit tests for the mcp controller (part 3)
Diaphteiros Aug 7, 2025
f1d9dd2
make mcp controller runnable
Diaphteiros Aug 7, 2025
99acd4b
rename v2 MCP resource in controller
Diaphteiros Aug 15, 2025
a6bfddf
make access in mcp status optional
Diaphteiros Aug 15, 2025
e0c285c
implement MCP namespace
Diaphteiros Aug 15, 2025
8e4f7d2
improve config
Diaphteiros Aug 15, 2025
eb09572
fix config and test
Diaphteiros Aug 27, 2025
1962de1
add lib replace statement to go.mod
Diaphteiros Aug 27, 2025
796ab0f
change mcp controller to platform service
Diaphteiros Aug 29, 2025
00e8aef
fix init bugs
Diaphteiros Aug 29, 2025
8948069
add missing platform cluster initialization
Diaphteiros Aug 29, 2025
b835446
pass config to mcp platform service
Diaphteiros Aug 29, 2025
a748b42
pacify linter
Diaphteiros Aug 29, 2025
21dc9a4
propagate extra volumes and volume mounts also into init job
Diaphteiros Aug 29, 2025
47bde01
fix rbac
Diaphteiros Aug 29, 2025
053f21f
add missing defaulting
Diaphteiros Aug 29, 2025
b31c2ca
fix wrong constant
Diaphteiros Aug 29, 2025
484fb50
fix condition prefix
Diaphteiros Aug 29, 2025
82bacb4
adapt to new AccessRequest structure
Diaphteiros Sep 2, 2025
f232a8a
fix readme
Diaphteiros Sep 2, 2025
8629ff3
fix todo
Diaphteiros Sep 2, 2025
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
46 changes: 27 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -124,25 +124,33 @@ spec:
name: my-cluster
namespace: default

permissions:
# Role
- namespace: default
rules:
- apiGroups:
- ""
resources:
- "secrets"
verbs:
- "*"
# ClusterRole
- rules:
- apiGroups:
- ""
resources:
- "configmaps"
verbs:
- "*"

token:
permissions:
# Role + RoleBinding
- namespace: default
rules:
- apiGroups:
- ""
resources:
- "secrets"
verbs:
- "*"
# ClusterRole + ClusterRoleBinding
- rules:
- apiGroups:
- ""
resources:
- "configmaps"
verbs:
- "*"
roleRefs:
# bind to existing Role
- kind: Role
name: my-role
namespace: my-namespace
# bind to existing ClusterRole
- kind: ClusterRole
name: cluster-admin
```

This will result in a `ServiceAccount` on the referenced `Cluster` with the specified permissions applied.
Expand Down
4 changes: 2 additions & 2 deletions api/clusters/v1alpha1/cluster_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,8 +130,8 @@ func (c *Cluster) GetTenancyCount() int {
func (c *Cluster) GetRequestUIDs() sets.Set[string] {
res := sets.New[string]()
for _, fin := range c.Finalizers {
if strings.HasPrefix(fin, RequestFinalizerOnClusterPrefix) {
res.Insert(strings.TrimPrefix(fin, RequestFinalizerOnClusterPrefix))
if uid, ok := strings.CutPrefix(fin, RequestFinalizerOnClusterPrefix); ok {
res.Insert(uid)
}
}
return res
Expand Down
15 changes: 9 additions & 6 deletions api/clusters/v1alpha1/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,13 +84,16 @@ const (
// SecretKeyCreationTimestamp is the name of the key in the AccessRequest secret that contains the creation timestamp.
// This value is optional and must not be set for non-expiring authentication methods.
SecretKeyCreationTimestamp = "creationTimestamp"
// SecretKeyCAData is the name of the key in the AccessRequest secret that contains the CA data.
// This value is optional and must not be set.
SecretKeyCAData = "caData"
// SecretKeyHost is the name of the key in the AccessRequest secret that contains the host.
// This value is optional and must not be set.
SecretKeyHost = "host"
// SecretKeyClientID is the name of the key in the AccessRequest secret that contains the client ID.
// This value is optional and must not be set for non-OIDC-based authentication methods.
SecretKeyClientID = "clientID"
// SecretKeyHost is the name of the key in the AccessRequest secret that contains the host of the cluster.
// This value is optional.
SecretKeyHost = "host"
// SecretKeyCA is the name of the key in the AccessRequest secret that contains the CA certificate of the cluster.
// This value is optional.
SecretKeyCA = "ca.crt"
// SecretKeyToken is the name of the key in the AccessRequest secret that contains the token.
// This value is optional.
SecretKeyToken = "token"
)
14 changes: 14 additions & 0 deletions api/clusters/v1alpha1/constants/reasons.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,18 @@ const (
ReasonConfigurationProblem = "ConfigurationProblem"
// ReasonInternalError indicates that something went wrong internally.
ReasonInternalError = "InternalError"
// ReasonWaitingForNamespaceDeletion indicates that something is waiting for a namespace to be deleted.
ReasonWaitingForNamespaceDeletion = "WaitingForNamespaceDeletion"
// ReasonWaitingForClusterRequest indicates that something is waiting for a ClusterRequest to become ready.
ReasonWaitingForClusterRequest = "WaitingForClusterRequest"
// ReasonWaitingForClusterRequestDeletion indicates that something is waiting for a ClusterRequest to be deleted.
ReasonWaitingForClusterRequestDeletion = "WaitingForClusterRequestDeletion"
// ReasonWaitingForAccessRequest indicates that something is waiting for an AccessRequest to become ready.
ReasonWaitingForAccessRequest = "WaitingForAccessRequest"
// ReasonWaitingForAccessRequestDeletion indicates that something is waiting for an AccessRequest to be deleted.
ReasonWaitingForAccessRequestDeletion = "WaitingForAccessRequestDeletion"
// ReasonWaitingForServices indicates that something is waiting for one or more service providers to do something.
ReasonWaitingForServices = "WaitingForServices"
// ReasonWaitingForServiceDeletion indicates that something is waiting for a service to be deleted.
ReasonWaitingForServiceDeletion = "WaitingForServiceDeletion"
)
25 changes: 25 additions & 0 deletions api/core/v2alpha1/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,29 @@ package v2alpha1
const (
// DefaultOIDCProviderName is the identifier for the default OIDC provider.
DefaultOIDCProviderName = "default"
// DefaultMCPClusterPurpose is the default purpose for ManagedControlPlane clusters.
DefaultMCPClusterPurpose = "mcp"
)

const (
MCPNameLabel = GroupName + "/mcp-name"
MCPNamespaceLabel = GroupName + "/mcp-namespace"
OIDCProviderLabel = GroupName + "/oidc-provider"

MCPFinalizer = GroupName + "/mcp"

// ServiceDependencyFinalizerPrefix is the prefix for the dependency finalizers that are added to MCP resources by associated services.
ServiceDependencyFinalizerPrefix = "services.openmcp.cloud/"
// ClusterRequestFinalizerPrefix is the prefix for the finalizers that are added to MCP resources for cluster requests.
ClusterRequestFinalizerPrefix = "request.clusters.openmcp.cloud/"
)

const (
ConditionMeta = "Meta"

ConditionClusterRequestReady = "ClusterRequestReady"
ConditionPrefixOIDCAccessReady = "OIDCAccessReady:"
ConditionAllAccessReady = "AllAccessReady"
ConditionAllServicesDeleted = "AllServicesDeleted"
ConditionAllClusterRequestsDeleted = "AllClusterRequestsDeleted"
)
4 changes: 3 additions & 1 deletion api/core/v2alpha1/groupversion_info.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,11 @@ import (
"sigs.k8s.io/controller-runtime/pkg/scheme"
)

const GroupName = "core.openmcp.cloud"

var (
// GroupVersion is group version used to register these objects
GroupVersion = schema.GroupVersion{Group: "core.openmcp.cloud", Version: "v2alpha1"}
GroupVersion = schema.GroupVersion{Group: GroupName, Version: "v2alpha1"}

// SchemeBuilder is used to add go types to the GroupVersionKind scheme
SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion}
Expand Down
3 changes: 2 additions & 1 deletion api/core/v2alpha1/managedcontrolplane_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ type ManagedControlPlaneV2Status struct {
// Each referenced secret is expected to contain a 'kubeconfig' key with the kubeconfig that was generated for the respective OIDC provider for the ManagedControlPlaneV2.
// The default OIDC provider, if configured, uses the name "default" in this mapping.
// The "default" key is also used if the ClusterProvider does not support OIDC-based access and created a serviceaccount with a token instead.
Access map[string]commonapi.LocalObjectReference `json:"access"`
// +optional
Access map[string]commonapi.LocalObjectReference `json:"access,omitempty"`
}

type IAMConfig struct {
Expand Down
Loading