Skip to content
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
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,9 @@ In this tutorial, a Kubernetes namespace called `test` is used for examples, whi
- [ComputeWorkspace](docs/compute_workspace.md)
- [ComputeFlinkDeployment](docs/compute_flink_deployment.md)
- [StreamNative Cloud Secret](docs/secret.md)
- [StreamNative Cloud APIKey](docs/apikey.md)
- [StreamNative Cloud ServiceAccount](docs/serviceaccount.md)
- [StreamNative Cloud ServiceAccountBinding](docs/serviceaccountbinding.md)

# Contributing

Expand Down
138 changes: 138 additions & 0 deletions api/v1alpha1/apikey_types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
// Copyright 2025 StreamNative
//
// Licensed 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 v1alpha1

import (
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

// APIKeySpec defines the desired state of APIKey
type APIKeySpec struct {
// APIServerRef is the reference to the StreamNativeCloudConnection
// +required
APIServerRef corev1.LocalObjectReference `json:"apiServerRef"`

// InstanceName is the name of the instance this API key is for
// +optional
InstanceName string `json:"instanceName,omitempty"`

// ServiceAccountName is the name of the service account this API key is for
// +optional
ServiceAccountName string `json:"serviceAccountName,omitempty"`

// Description is a user defined description of the key
// +optional
Description string `json:"description,omitempty"`

// ExpirationTime is a timestamp that defines when this API key will expire
// This can only be set on initial creation and not updated later
// +optional
ExpirationTime *metav1.Time `json:"expirationTime,omitempty"`

// Revoke indicates whether this API key should be revoked
// +optional
Revoke bool `json:"revoke,omitempty"`

// EncryptionKey contains the public key used to encrypt the token
// +optional
EncryptionKey *EncryptionKey `json:"encryptionKey,omitempty"`

// ExportPlaintextToken indicates whether the token should be exported in plaintext
// +optional
ExportPlaintextToken *bool `json:"exportPlaintextToken,omitempty"`
}

// EncryptionKey contains a public key used for encryption
// +structType=atomic
type EncryptionKey struct {
// PEM is the public key in PEM format
// +optional
PEM string `json:"pem,omitempty"`
}

// APIKeyStatus defines the observed state of APIKey
type APIKeyStatus struct {
// Conditions represent the latest available observations of an object's state
// +optional
Conditions []metav1.Condition `json:"conditions,omitempty"`

// ObservedGeneration is the last observed generation
// +optional
ObservedGeneration int64 `json:"observedGeneration,omitempty"`

// KeyID is a generated field that is a uid for the token
// +optional
KeyID *string `json:"keyId,omitempty"`

// IssuedAt is a timestamp of when the key was issued
// +optional
IssuedAt *metav1.Time `json:"issuedAt,omitempty"`

// ExpiresAt is a timestamp of when the key expires
// +optional
ExpiresAt *metav1.Time `json:"expiresAt,omitempty"`

// Token is the plaintext security token issued for the key
// +optional
Token *string `json:"token,omitempty"`

// EncryptedToken is the encrypted security token issued for the key
// +optional
EncryptedToken *EncryptedToken `json:"encryptedToken,omitempty"`

// RevokedAt is a timestamp of when the key was revoked, it triggers revocation action
// +optional
RevokedAt *metav1.Time `json:"revokedAt,omitempty"`
}

// EncryptedToken is token that is encrypted using an encryption key
// +structType=atomic
type EncryptedToken struct {
// JWE is the token as a JSON Web Encryption (JWE) message
// For RSA public keys, the key encryption algorithm is RSA-OAEP, and the content encryption algorithm is AES GCM
// +optional
JWE *string `json:"jwe,omitempty"`
}

//+kubebuilder:object:root=true
//+kubebuilder:subresource:status
//+kubebuilder:resource:scope=Namespaced,categories={streamnative,all}
//+kubebuilder:printcolumn:name="AGE",type="date",JSONPath=".metadata.creationTimestamp"
//+kubebuilder:printcolumn:name="READY",type="string",JSONPath=".status.conditions[?(@.type==\"Ready\")].status"
//+k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object

// APIKey is the Schema for the APIKeys API
type APIKey struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`

Spec APIKeySpec `json:"spec,omitempty"`
Status APIKeyStatus `json:"status,omitempty"`
}

//+kubebuilder:object:root=true
//+k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object

// APIKeyList contains a list of APIKey
type APIKeyList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []APIKey `json:"items"`
}

func init() {
SchemeBuilder.Register(&APIKey{}, &APIKeyList{})
}
76 changes: 76 additions & 0 deletions api/v1alpha1/serviceaccount_types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
// Copyright 2025 StreamNative
//
// Licensed 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 v1alpha1

import (
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

// ServiceAccountSpec defines the desired state of ServiceAccount
type ServiceAccountSpec struct {
// APIServerRef is the reference to the StreamNativeCloudConnection
// +required
APIServerRef corev1.LocalObjectReference `json:"apiServerRef"`
}

// ServiceAccountStatus defines the observed state of ServiceAccount
type ServiceAccountStatus struct {
// Conditions represent the latest available observations of an object's state
// +optional
Conditions []metav1.Condition `json:"conditions,omitempty"`

// ObservedGeneration is the last observed generation
// +optional
ObservedGeneration int64 `json:"observedGeneration,omitempty"`

// PrivateKeyType indicates the type of private key information
// +optional
PrivateKeyType string `json:"privateKeyType,omitempty"`

// PrivateKeyData provides the private key data (in base-64 format) for authentication purposes
// +optional
PrivateKeyData string `json:"privateKeyData,omitempty"`
}

//+kubebuilder:object:root=true
//+kubebuilder:subresource:status
//+kubebuilder:resource:scope=Namespaced,categories={streamnative,all}
//+kubebuilder:printcolumn:name="AGE",type="date",JSONPath=".metadata.creationTimestamp"
//+kubebuilder:printcolumn:name="READY",type="string",JSONPath=".status.conditions[?(@.type==\"Ready\")].status"
//+k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object

// ServiceAccount is the Schema for the ServiceAccounts API
type ServiceAccount struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`

Spec ServiceAccountSpec `json:"spec,omitempty"`
Status ServiceAccountStatus `json:"status,omitempty"`
}

//+kubebuilder:object:root=true
//+k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object

// ServiceAccountList contains a list of ServiceAccount
type ServiceAccountList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []ServiceAccount `json:"items"`
}

func init() {
SchemeBuilder.Register(&ServiceAccount{}, &ServiceAccountList{})
}
77 changes: 77 additions & 0 deletions api/v1alpha1/serviceaccountbinding_types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
// Copyright 2025 StreamNative
//
// Licensed 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 v1alpha1

import (
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

// ServiceAccountBindingSpec defines the desired state of ServiceAccountBinding
type ServiceAccountBindingSpec struct {
// ServiceAccountName refers to the ServiceAccount under the same namespace as this binding object
// +required
ServiceAccountName string `json:"serviceAccountName"`

// APIServerRef is the reference to the StreamNativeCloudConnection
// If not provided, it will be retrieved from the referenced ServiceAccount
// +optional
APIServerRef *corev1.LocalObjectReference `json:"apiServerRef,omitempty"`

// PoolMemberRefs refers to a list of PoolMembers in the current namespace or other namespaces
// +required
PoolMemberRefs []PoolMemberReference `json:"poolMemberRefs"`
}

// ServiceAccountBindingStatus defines the observed state of ServiceAccountBinding
type ServiceAccountBindingStatus struct {
// Conditions represent the latest available observations of an object's state
// +optional
Conditions []metav1.Condition `json:"conditions,omitempty"`

// ObservedGeneration is the last observed generation
// +optional
ObservedGeneration int64 `json:"observedGeneration,omitempty"`
}

//+kubebuilder:object:root=true
//+kubebuilder:subresource:status
//+kubebuilder:resource:scope=Namespaced,categories={streamnative,all}
//+kubebuilder:printcolumn:name="AGE",type="date",JSONPath=".metadata.creationTimestamp"
//+kubebuilder:printcolumn:name="READY",type="string",JSONPath=".status.conditions[?(@.type==\"Ready\")].status"
//+k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object

// ServiceAccountBinding is the Schema for the ServiceAccountBindings API
type ServiceAccountBinding struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`

Spec ServiceAccountBindingSpec `json:"spec,omitempty"`
Status ServiceAccountBindingStatus `json:"status,omitempty"`
}

//+kubebuilder:object:root=true
//+k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object

// ServiceAccountBindingList contains a list of ServiceAccountBinding
type ServiceAccountBindingList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []ServiceAccountBinding `json:"items"`
}

func init() {
SchemeBuilder.Register(&ServiceAccountBinding{}, &ServiceAccountBindingList{})
}
Loading
Loading