Skip to content

Commit 0126a7d

Browse files
authored
feat: initial invite implementation (#97)
* feat: initial invite implementation * chore: review comments * chore: test coverage * chore: test coverage * fix: handle error in JSON encoding for user response in TestSubroutineProcess * chore: port PR to mcruntime
1 parent 440dec3 commit 0126a7d

23 files changed

+979
-239
lines changed

PROJECT

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,4 +25,11 @@ resources:
2525
kind: AuthorizationModel
2626
path: github.com/platform-mesh/security-operator/api/v1alpha1
2727
version: v1alpha1
28+
- api:
29+
crdVersion: v1
30+
domain: platform-mesh.io
31+
group: core
32+
kind: Invite
33+
path: github.com/platform-mesh/security-operator/api/v1alpha1
34+
version: v1alpha1
2835
version: "3"

api/v1alpha1/invite_types.go

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
package v1alpha1
2+
3+
import (
4+
lifecycleapi "github.com/platform-mesh/golang-commons/controller/lifecycle/api"
5+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
6+
)
7+
8+
// InviteSpec defines the desired state of Invite
9+
type InviteSpec struct {
10+
Email string `json:"email"`
11+
}
12+
13+
// InviteStatus defines the observed state of Invite.
14+
type InviteStatus struct {
15+
Conditions []metav1.Condition `json:"conditions,omitempty"`
16+
}
17+
18+
// +kubebuilder:object:root=true
19+
// +kubebuilder:subresource:status
20+
// +kubebuilder:resource:scope=Cluster
21+
22+
// Invite is the Schema for the invites API
23+
type Invite struct {
24+
metav1.TypeMeta `json:",inline"`
25+
26+
// metadata is a standard object metadata
27+
// +optional
28+
metav1.ObjectMeta `json:"metadata,omitempty,omitzero"`
29+
30+
// spec defines the desired state of Invite
31+
// +required
32+
Spec InviteSpec `json:"spec"`
33+
34+
// status defines the observed state of Invite
35+
// +optional
36+
Status InviteStatus `json:"status,omitempty,omitzero"`
37+
}
38+
39+
// GetConditions implements api.RuntimeObjectConditions.
40+
func (in *Invite) GetConditions() []metav1.Condition {
41+
return in.Status.Conditions
42+
}
43+
44+
// SetConditions implements api.RuntimeObjectConditions.
45+
func (in *Invite) SetConditions(c []metav1.Condition) {
46+
in.Status.Conditions = c
47+
}
48+
49+
// +kubebuilder:object:root=true
50+
51+
// InviteList contains a list of Invite
52+
type InviteList struct {
53+
metav1.TypeMeta `json:",inline"`
54+
metav1.ListMeta `json:"metadata,omitempty"`
55+
Items []Invite `json:"items"`
56+
}
57+
58+
var _ lifecycleapi.RuntimeObjectConditions = &Invite{}
59+
60+
func init() {
61+
SchemeBuilder.Register(&Invite{}, &InviteList{})
62+
}

api/v1alpha1/zz_generated.deepcopy.go

Lines changed: 96 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

cmd/operator.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,10 @@ var operatorCmd = &cobra.Command{
153153
log.Error().Err(err).Str("controller", "authorizationmodel").Msg("unable to create controller")
154154
return err
155155
}
156+
if err = controller.NewInviteReconciler(ctx, mgr, &appCfg, log).SetupWithManager(mgr, defaultCfg, log); err != nil {
157+
log.Error().Err(err).Str("controller", "invite").Msg("unable to create controller")
158+
return err
159+
}
156160
// +kubebuilder:scaffold:builder
157161

158162
if err := mgr.AddHealthzCheck("healthz", healthz.Ping); err != nil {

cmd/root.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,9 @@ func init() {
4141
if err := platformeshconfig.BindConfigToFlags(v, initializerCmd, &appCfg); err != nil {
4242
panic(err)
4343
}
44+
if err := platformeshconfig.BindConfigToFlags(v, operatorCmd, &appCfg); err != nil {
45+
panic(err)
46+
}
4447

4548
cobra.OnInitialize(initLog)
4649
}
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
---
2+
apiVersion: apiextensions.k8s.io/v1
3+
kind: CustomResourceDefinition
4+
metadata:
5+
annotations:
6+
controller-gen.kubebuilder.io/version: v0.16.4
7+
name: invites.core.platform-mesh.io
8+
spec:
9+
group: core.platform-mesh.io
10+
names:
11+
kind: Invite
12+
listKind: InviteList
13+
plural: invites
14+
singular: invite
15+
scope: Cluster
16+
versions:
17+
- name: v1alpha1
18+
schema:
19+
openAPIV3Schema:
20+
description: Invite is the Schema for the invites API
21+
properties:
22+
apiVersion:
23+
description: |-
24+
APIVersion defines the versioned schema of this representation of an object.
25+
Servers should convert recognized schemas to the latest internal value, and
26+
may reject unrecognized values.
27+
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
28+
type: string
29+
kind:
30+
description: |-
31+
Kind is a string value representing the REST resource this object represents.
32+
Servers may infer this from the endpoint the client submits requests to.
33+
Cannot be updated.
34+
In CamelCase.
35+
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
36+
type: string
37+
metadata:
38+
type: object
39+
spec:
40+
description: spec defines the desired state of Invite
41+
properties:
42+
email:
43+
type: string
44+
required:
45+
- email
46+
type: object
47+
status:
48+
description: status defines the observed state of Invite
49+
properties:
50+
conditions:
51+
items:
52+
description: Condition contains details for one aspect of the current
53+
state of this API Resource.
54+
properties:
55+
lastTransitionTime:
56+
description: |-
57+
lastTransitionTime is the last time the condition transitioned from one status to another.
58+
This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.
59+
format: date-time
60+
type: string
61+
message:
62+
description: |-
63+
message is a human readable message indicating details about the transition.
64+
This may be an empty string.
65+
maxLength: 32768
66+
type: string
67+
observedGeneration:
68+
description: |-
69+
observedGeneration represents the .metadata.generation that the condition was set based upon.
70+
For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date
71+
with respect to the current state of the instance.
72+
format: int64
73+
minimum: 0
74+
type: integer
75+
reason:
76+
description: |-
77+
reason contains a programmatic identifier indicating the reason for the condition's last transition.
78+
Producers of specific condition types may define expected values and meanings for this field,
79+
and whether the values are considered a guaranteed API.
80+
The value should be a CamelCase string.
81+
This field may not be empty.
82+
maxLength: 1024
83+
minLength: 1
84+
pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
85+
type: string
86+
status:
87+
description: status of the condition, one of True, False, Unknown.
88+
enum:
89+
- "True"
90+
- "False"
91+
- Unknown
92+
type: string
93+
type:
94+
description: type of condition in CamelCase or in foo.example.com/CamelCase.
95+
maxLength: 316
96+
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
97+
type: string
98+
required:
99+
- lastTransitionTime
100+
- message
101+
- reason
102+
- status
103+
- type
104+
type: object
105+
type: array
106+
type: object
107+
required:
108+
- spec
109+
type: object
110+
served: true
111+
storage: true
112+
subresources:
113+
status: {}

config/crd/kustomization.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
resources:
55
- bases/core.platform-mesh.io_stores.yaml
66
- bases/core.platform-mesh.io_authorizationmodels.yaml
7+
- bases/core.platform-mesh.io_invites.yaml
78
# +kubebuilder:scaffold:crdkustomizeresource
89

910
patches:

config/rbac/invite_admin_role.yaml

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# This rule is not used by the project security-operator itself.
2+
# It is provided to allow the cluster admin to help manage permissions for users.
3+
#
4+
# Grants full permissions ('*') over core.platform-mesh.io.
5+
# This role is intended for users authorized to modify roles and bindings within the cluster,
6+
# enabling them to delegate specific permissions to other users or groups as needed.
7+
8+
apiVersion: rbac.authorization.k8s.io/v1
9+
kind: ClusterRole
10+
metadata:
11+
labels:
12+
app.kubernetes.io/name: security-operator
13+
app.kubernetes.io/managed-by: kustomize
14+
name: invite-admin-role
15+
rules:
16+
- apiGroups:
17+
- core.platform-mesh.io
18+
resources:
19+
- invites
20+
verbs:
21+
- '*'
22+
- apiGroups:
23+
- core.platform-mesh.io
24+
resources:
25+
- invites/status
26+
verbs:
27+
- get
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# This rule is not used by the project security-operator itself.
2+
# It is provided to allow the cluster admin to help manage permissions for users.
3+
#
4+
# Grants permissions to create, update, and delete resources within the core.platform-mesh.io.
5+
# This role is intended for users who need to manage these resources
6+
# but should not control RBAC or manage permissions for others.
7+
8+
apiVersion: rbac.authorization.k8s.io/v1
9+
kind: ClusterRole
10+
metadata:
11+
labels:
12+
app.kubernetes.io/name: security-operator
13+
app.kubernetes.io/managed-by: kustomize
14+
name: invite-editor-role
15+
rules:
16+
- apiGroups:
17+
- core.platform-mesh.io
18+
resources:
19+
- invites
20+
verbs:
21+
- create
22+
- delete
23+
- get
24+
- list
25+
- patch
26+
- update
27+
- watch
28+
- apiGroups:
29+
- core.platform-mesh.io
30+
resources:
31+
- invites/status
32+
verbs:
33+
- get

0 commit comments

Comments
 (0)