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
11 changes: 11 additions & 0 deletions PROJECT
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ resources:
kind: BMCSecret
path: github.com/ironcore-dev/metal-operator/api/v1alpha1
version: v1alpha1
webhooks:
validation: true
webhookVersion: v1
- api:
crdVersion: v1
controller: true
Expand Down Expand Up @@ -107,6 +110,14 @@ resources:
webhooks:
validation: true
webhookVersion: v1
- api:
crdVersion: v1
controller: true
domain: ironcore.dev
group: metal
kind: User
path: github.com/ironcore-dev/metal-operator/api/v1alpha1
version: v1alpha1
- api:
crdVersion: v1
controller: true
Expand Down
20 changes: 20 additions & 0 deletions api/v1alpha1/bmc_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,15 @@ const (
ProtocolRedfishKube = "RedfishKube"
)

type PasswordPolicy string

const (
// PasswordPolicyExternal indicates that the password policy is managed externally, such as by an external identity provider.
PasswordPolicyExternal PasswordPolicy = "External"
// PasswordPolicyInternal indicates that the password policy is managed internally, such as by the BMC itself.
PasswordPolicyInternal PasswordPolicy = "Internal"
)

// BMCSpec defines the desired state of BMC
// +kubebuilder:validation:XValidation:rule="has(self.access) != has(self.endpointRef)",message="exactly one of access or endpointRef needs to be set"
type BMCSpec struct {
Expand Down Expand Up @@ -47,6 +56,12 @@ type BMCSpec struct {
// +required
BMCSecretRef v1.LocalObjectReference `json:"bmcSecretRef"`

// AdminUserRef is a reference to the Kubernetes Secret object that contains the credentials to access the BMC.
// This secret is used for administrative access to the BMC and may include elevated privileges.
// It will replqce the BMCSecretRef for administrative operations.
// +optional
AdminUserRef *v1.LocalObjectReference `json:"adminUserRef,omitempty"`

// Protocol specifies the protocol to be used for communicating with the BMC.
// It could be a standard protocol such as IPMI or Redfish.
// +required
Expand All @@ -57,6 +72,11 @@ type BMCSpec struct {
// +optional
ConsoleProtocol *ConsoleProtocol `json:"consoleProtocol,omitempty"`

// UserAccounts is a list of user accounts that can be used to access the BMC.
// Each account includes a name, role ID, description, and other relevant details.
// +optional
UserRefs []UserSpec `json:"userRefs,omitempty"`

// BMCSettingRef is a reference to a BMCSettings object that specifies
// the BMC configuration for this BMC.
// +optional
Expand Down
2 changes: 2 additions & 0 deletions api/v1alpha1/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ const (
OperationAnnotationRetry = "retry"
// InstanceTypeAnnotation is used to specify the type of Server.
InstanceTypeAnnotation = "metal.ironcore.dev/instance-type"
// OperationAnnotationRotateCredentials is used to indicate that credentials should be rotated.
OperationAnnotationRotateCredentials = "rotate-credentials"
// ForceUpdateAnnotation is used to indicate that the spec should be forcefully updated.
ForceUpdateAnnotation = "metal.ironcore.dev/force-update-resource"
// OperationAnnotationForceUpdateOrDeleteInProgress allows update/Delete of a resource even if it is in progress.
Expand Down
59 changes: 59 additions & 0 deletions api/v1alpha1/user_types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
// SPDX-FileCopyrightText: 2024 SAP SE or an SAP affiliate company and IronCore contributors
// SPDX-License-Identifier: Apache-2.0

package v1alpha1

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

// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN!
// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized.

// UserSpec defines the desired state of User
type UserSpec struct {
UserName string `json:"userName"`
RoleID string `json:"roleID"`
Description string `json:"description,omitempty"`
RotationPolicy *metav1.Duration `json:"rotationPeriod,omitempty"`
BMCSecretRef *v1.LocalObjectReference `json:"bmcSecretRef,omitempty"`
BMCRef *v1.LocalObjectReference `json:"bmcRef,omitempty"`
Enabled bool `json:"enabled"`
// set if the user should be used by the BMC reconciler to access the system.
UseForBMCAccess bool `json:"useForBMCAccess,omitempty"`
}

// UserStatus defines the observed state of User
type UserStatus struct {
EffectiveBMCSecretRef *v1.LocalObjectReference `json:"effectiveBMCSecretRef,omitempty"`
LastRotation *metav1.Time `json:"lastRotation,omitempty"`
PasswordExpiration string `json:"passwordExpiration,omitempty"`
ID string `json:"id,omitempty"` // ID of the user in the BMC system
}

// +kubebuilder:object:root=true
// +kubebuilder:resource:scope=Cluster
// +kubebuilder:subresource:status

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

Spec UserSpec `json:"spec,omitempty"`
Status UserStatus `json:"status,omitempty"`
}

// +kubebuilder:object:root=true

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

func init() {
SchemeBuilder.Register(&User{}, &UserList{})
}
125 changes: 125 additions & 0 deletions api/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions bmc/bmc.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,12 @@ type BMC interface {
// WaitForServerPowerState waits for the server to reach the specified power state.
WaitForServerPowerState(ctx context.Context, systemURI string, powerState redfish.PowerState) error

// CreateOrUpdateAccount creates or updates a BMC user account.
CreateOrUpdateAccount(ctx context.Context, userName, role, password string, enabled bool) error

// GetAccounts retrieves all BMC user accounts.
GetAccounts(ctx context.Context) ([]*redfish.ManagerAccount, error)

// UpgradeBMCVersion upgrades the BMC version for the system.
UpgradeBMCVersion(ctx context.Context, manufacturer string, parameters *redfish.SimpleUpdateParameters) (string, bool, error)

Expand Down
41 changes: 40 additions & 1 deletion bmc/mockup.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@

package bmc

import "github.com/stmcginnis/gofish/redfish"
import (
"github.com/stmcginnis/gofish/common"
"github.com/stmcginnis/gofish/redfish"
)

// RedfishMockUps is an implementation of the BMC interface for Redfish.
type RedfishMockUps struct {
Expand All @@ -21,6 +24,8 @@ type RedfishMockUps struct {
BMCUpgradingVersion string
BMCUpgradeTaskIndex int
BMCUpgradeTaskStatus []redfish.Task

Accounts map[string]*redfish.ManagerAccount
}

func (r *RedfishMockUps) InitializeDefaults() {
Expand Down Expand Up @@ -104,6 +109,40 @@ func (r *RedfishMockUps) InitializeDefaults() {
PercentComplete: 100,
},
}

r.Accounts = map[string]*redfish.ManagerAccount{
"foo": {
Entity: common.Entity{
ID: "0",
},
UserName: "foo",
Enabled: true,
RoleID: "ReadOnly",
Locked: false,
Password: "bar",
},
"admin": {
Entity: common.Entity{
ID: "1",
},

UserName: "admin",
Enabled: true,
RoleID: "Administrator",
Locked: false,
Password: "adminpass",
},
"user": {
Entity: common.Entity{
ID: "2",
},
UserName: "user",
Enabled: true,
RoleID: "ReadOnly",
Locked: false,
Password: "userpass",
},
}
}

func (r *RedfishMockUps) ResetBIOSSettings() {
Expand Down
Loading
Loading