1
0
mirror of https://github.com/openshift/installer.git synced 2026-02-05 15:47:14 +01:00

Add ORC API to local control plane

Signed-off-by: Stephen Finucane <stephenfin@redhat.com>
This commit is contained in:
Stephen Finucane
2025-11-19 13:03:14 +00:00
parent e184dc659a
commit a84719caef
44 changed files with 10478 additions and 68 deletions

7
go.mod
View File

@@ -112,7 +112,7 @@ require (
github.com/stretchr/testify v1.11.1
github.com/thedevsaddam/retry v0.0.0-20200324223450-9769a859cc6d
github.com/thoas/go-funk v0.9.3
github.com/ulikunitz/xz v0.5.12
github.com/ulikunitz/xz v0.5.15
github.com/vincent-petithory/dataurl v1.0.0
github.com/vmware/govmomi v0.51.0
go.uber.org/mock v0.6.0
@@ -155,7 +155,10 @@ require (
github.com/aws/aws-sdk-go-v2/service/resourcegroupstaggingapi v1.29.0
)
require github.com/aws/aws-sdk-go-v2/service/servicequotas v1.31.0
require (
github.com/aws/aws-sdk-go-v2/service/servicequotas v1.31.0
github.com/k-orc/openstack-resource-controller/v2 v2.3.0
)
require (
cel.dev/expr v0.24.0 // indirect

12
go.sum
View File

@@ -558,6 +558,8 @@ github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFF
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/k-orc/openstack-resource-controller/v2 v2.3.0 h1:jLI/GH/yzqy6MVzu54dMcimzFmpprBiWBrfHEc9eots=
github.com/k-orc/openstack-resource-controller/v2 v2.3.0/go.mod h1:3yPrdRJrWHP0qV0IVvLnEWbEQmK7TyWjwUZHiU5dmzA=
github.com/k0kubun/pp/v3 v3.1.0 h1:ifxtqJkRZhw3h554/z/8zm6AAbyO4LLKDlA5eV+9O8Q=
github.com/k0kubun/pp/v3 v3.1.0/go.mod h1:vIrP5CF0n78pKHm2Ku6GVerpZBJvscg48WepUYEk2gw=
github.com/karrick/godirwalk v1.8.0/go.mod h1:H5KPZjojv4lE+QYImBI8xVtrBRgYrIVsaRPx4tDPEn4=
@@ -685,8 +687,8 @@ github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vv
github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU=
github.com/onsi/ginkgo/v2 v2.0.0/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c=
github.com/onsi/ginkgo/v2 v2.27.1 h1:0LJC8MpUSQnfnp4n/3W3GdlmJP3ENGF0ZPzjQGLPP7s=
github.com/onsi/ginkgo/v2 v2.27.1/go.mod h1:wmy3vCqiBjirARfVhAqFpYt8uvX0yaFe+GudAqqcCqA=
github.com/onsi/ginkgo/v2 v2.27.2 h1:LzwLj0b89qtIy6SSASkzlNvX6WktqurSHwkk2ipF/Ns=
github.com/onsi/ginkgo/v2 v2.27.2/go.mod h1:ArE1D/XhNXBXCBkKOLkbsb2c81dQHCRcF5zwn/ykDRo=
github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
@@ -845,8 +847,8 @@ github.com/thedevsaddam/retry v0.0.0-20200324223450-9769a859cc6d/go.mod h1:2rz2m
github.com/thoas/go-funk v0.9.3 h1:7+nAEx3kn5ZJcnDm2Bh23N2yOtweO14bi//dvRtgLpw=
github.com/thoas/go-funk v0.9.3/go.mod h1:+IWnUfUmFO1+WVYQWQtIJHeRRdaIyyYglZN7xzUPe4Q=
github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
github.com/ulikunitz/xz v0.5.12 h1:37Nm15o69RwBkXM0J6A5OlE67RZTfzUxTj8fB3dfcsc=
github.com/ulikunitz/xz v0.5.12/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
github.com/ulikunitz/xz v0.5.15 h1:9DNdB5s+SgV3bQ2ApL10xRc35ck0DuIX/isZvIk+ubY=
github.com/ulikunitz/xz v0.5.15/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
github.com/vincent-petithory/dataurl v1.0.0 h1:cXw+kPto8NLuJtlMsI152irrVw9fRDX8AbShPRpg2CI=
github.com/vincent-petithory/dataurl v1.0.0/go.mod h1:FHafX5vmDzyP+1CQATJn7WFKc9CvnvxyvZy6I1MrG/U=
github.com/vmware/govmomi v0.51.0 h1:n3RLS9aw/irTOKbiIyJzAb6rOat4YOVv/uDoRsNTSQI=
@@ -898,8 +900,6 @@ go.opentelemetry.io/otel/trace v1.38.0 h1:Fxk5bKrDZJUH+AMyyIXGcFAPah0oRcT+LuNtJr
go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42sO++GHkg4wwhs=
go.opentelemetry.io/proto/otlp v1.7.1 h1:gTOMpGDb0WTBOP8JaO72iL3auEZhVmAQg4ipjOVAtj4=
go.opentelemetry.io/proto/otlp v1.7.1/go.mod h1:b2rVh6rfI/s2pHWNlB7ILJcRALpcNDzKhACevjI+ZnE=
go.uber.org/automaxprocs v1.6.0 h1:O3y2/QNTOdbF+e/dpXNNW7Rx2hZ4sTIPyybbxyNqTUs=
go.uber.org/automaxprocs v1.6.0/go.mod h1:ifeIMSnPZuznNm6jmdzmU3/bfk01Fe2fotchwEFJ8r8=
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
go.uber.org/mock v0.6.0 h1:hyF9dfmbgIX5EfOdasqLsWD6xqpNZlXblLB/Dbnwv3Y=

View File

@@ -7,6 +7,7 @@ import (
"path/filepath"
"runtime"
orcv1alpha1 "github.com/k-orc/openstack-resource-controller/v2/api/v1alpha1"
capnv1 "github.com/nutanix-cloud-native/cluster-api-provider-nutanix/api/v1beta1"
"github.com/sirupsen/logrus"
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
@@ -37,6 +38,8 @@ var (
func init() {
utilruntime.Must(clusterv1.AddToScheme(Scheme))
utilruntime.Must(orcv1alpha1.AddToScheme(Scheme))
utilruntime.Must(capav1beta1.AddToScheme(Scheme))
utilruntime.Must(capav1.AddToScheme(Scheme))
utilruntime.Must(capzv1.AddToScheme(Scheme))

View File

@@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
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.

View File

@@ -0,0 +1,99 @@
/*
Copyright 2024 The ORC Authors.
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 (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
// +kubebuilder:validation:MinLength:=1
// +kubebuilder:validation:MaxLength:=255
type NeutronDescription string
// NeutronTag represents a tag on a Neutron resource.
// It may not be empty and may not contain commas.
// +kubebuilder:validation:MinLength:=1
// +kubebuilder:validation:MaxLength:=255
type NeutronTag string
type FilterByNeutronTags struct {
// tags is a list of tags to filter by. If specified, the resource must
// have all of the tags specified to be included in the result.
// +listType=set
// +optional
// +kubebuilder:validation:MaxItems:=64
Tags []NeutronTag `json:"tags,omitempty"`
// tagsAny is a list of tags to filter by. If specified, the resource
// must have at least one of the tags specified to be included in the
// result.
// +listType=set
// +optional
// +kubebuilder:validation:MaxItems:=64
TagsAny []NeutronTag `json:"tagsAny,omitempty"`
// notTags is a list of tags to filter by. If specified, resources which
// contain all of the given tags will be excluded from the result.
// +listType=set
// +optional
// +kubebuilder:validation:MaxItems:=64
NotTags []NeutronTag `json:"notTags,omitempty"`
// notTagsAny is a list of tags to filter by. If specified, resources
// which contain any of the given tags will be excluded from the result.
// +listType=set
// +optional
// +kubebuilder:validation:MaxItems:=64
NotTagsAny []NeutronTag `json:"notTagsAny,omitempty"`
}
// +kubebuilder:validation:Enum:=4;6
type IPVersion int32
// +kubebuilder:validation:Format:=cidr
// +kubebuilder:validation:MinLength:=1
// +kubebuilder:validation:MaxLength:=49
type CIDR string
// +kubebuilder:validation:MinLength:=1
// +kubebuilder:validation:MaxLength:=45
type IPvAny string
// +kubebuilder:validation:MinLength:=1
// +kubebuilder:validation:MaxLength:=17
type MAC string
// +kubebuilder:validation:MinLength:=1
// +kubebuilder:validation:MaxLength:=255
type AvailabilityZoneHint string
type NeutronStatusMetadata struct {
// createdAt shows the date and time when the resource was created. The date and time stamp format is ISO 8601
// +optional
CreatedAt *metav1.Time `json:"createdAt,omitempty"`
// updatedAt shows the date and time when the resource was updated. The date and time stamp format is ISO 8601
// +optional
UpdatedAt *metav1.Time `json:"updatedAt,omitempty"`
// revisionNumber optionally set via extensions/standard-attr-revisions
// +optional
RevisionNumber *int64 `json:"revisionNumber,omitempty"`
}
// +kubebuilder:validation:MinLength:=1
// +kubebuilder:validation:MaxLength:=253
type KubernetesNameRef string

View File

@@ -0,0 +1,121 @@
/*
Copyright 2023 The ORC Authors.
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 (
"errors"
"slices"
"k8s.io/apimachinery/pkg/api/meta"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
const (
// Condition Reasons are machine-readable. Treat them like HTTP status
// codes: they categorise Reasons by 'what should we do about it', not
// 'what went wrong'. The latter should be in the human-readable
// Message.
// Normal progress: continue waiting.
ConditionReasonProgressing = "Progressing"
// The user must fix the configuration before trying again.
ConditionReasonInvalidConfiguration = "InvalidConfiguration"
// An error occurred which we can't recover from. It must be addressed
// before we can continue.
ConditionReasonUnrecoverableError = "UnrecoverableError"
// An error occurred which may go away eventually if we keep trying. The
// user likely wants to know about this if it persists.
ConditionReasonTransientError = "TransientError"
// The resource is ready for use.
ConditionReasonSuccess = "Success"
)
const (
ConditionAvailable = "Available"
ConditionProgressing = "Progressing"
)
// IsConditionReasonTerminal returns true if the given reason represents an error which should prevent further reconciliation.
func IsConditionReasonTerminal(reason string) bool {
return slices.Contains(
[]string{
ConditionReasonInvalidConfiguration,
ConditionReasonUnrecoverableError,
}, reason)
}
// ObjectWithConditions is a metav1.Object which also stores conditions in its status.
// +kubebuilder:object:generate:=false
type ObjectWithConditions interface {
metav1.Object
GetConditions() []metav1.Condition
}
// getUpToDateProgressing returns the progressing condition if and only if it
// exists and is up to date.
func getUpToDateProgressing(obj ObjectWithConditions) *metav1.Condition {
conditions := obj.GetConditions()
progressing := meta.FindStatusCondition(conditions, ConditionProgressing)
// Not complete if Progressing condition does not exist
if progressing == nil {
return nil
}
// Not complete if status is out of date
if progressing.ObservedGeneration != obj.GetGeneration() {
return nil
}
return progressing
}
// IsReconciliationComplete returns true if the given set of conditions indicate that reconciliation is complete, either success or failure.
func IsReconciliationComplete(obj ObjectWithConditions) bool {
progressing := getUpToDateProgressing(obj)
if progressing == nil {
return false
}
// Complete if we've either succeeded or failed terminally
return progressing.Reason == ConditionReasonSuccess || IsConditionReasonTerminal(progressing.Reason)
}
// GetTerminalError returns an error containing a descriptive message if reconciliation has failed terminally, or nil otherwise.
func GetTerminalError(obj ObjectWithConditions) error {
progressing := getUpToDateProgressing(obj)
if progressing == nil {
return nil
}
if IsConditionReasonTerminal(progressing.Reason) {
return errors.New(progressing.Message)
}
return nil
}
func IsAvailable(obj ObjectWithConditions) bool {
conditions := obj.GetConditions()
available := meta.FindStatusCondition(conditions, ConditionAvailable)
return available != nil && available.Status == metav1.ConditionTrue
}

View File

@@ -0,0 +1,65 @@
/*
Copyright 2024 The ORC Authors.
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
// +kubebuilder:validation:Enum:=managed;unmanaged
type ManagementPolicy string
const (
// ManagementPolicyManaged specifies that the controller will reconcile the
// state of the referenced OpenStack resource with the state of the ORC
// object.
ManagementPolicyManaged ManagementPolicy = "managed"
// ManagementPolicyUnmanaged specifies that the controller will expect the
// resource to either exist already or to be created externally. The
// controller will not make any changes to the referenced OpenStack
// resource.
ManagementPolicyUnmanaged ManagementPolicy = "unmanaged"
)
// +kubebuilder:validation:Enum:=delete;detach
type OnDelete string
const (
// OnDeleteDelete specifies that the OpenStack resource will be deleted
// when the managed ORC object is deleted.
OnDeleteDelete OnDelete = "delete"
// OnDeleteDetach specifies that the OpenStack resource will not be
// deleted when the managed ORC object is deleted.
OnDeleteDetach OnDelete = "detach"
)
type ManagedOptions struct {
// onDelete specifies the behaviour of the controller when the ORC
// object is deleted. Options are `delete` - delete the OpenStack resource;
// `detach` - do not delete the OpenStack resource. If not specified, the
// default is `delete`.
// +kubebuilder:default:=delete
// +optional
OnDelete OnDelete `json:"onDelete,omitempty"`
}
// GetOnDelete returns the delete behaviour from ManagedOptions. If called on a
// nil receiver it safely returns the default.
func (o *ManagedOptions) GetOnDelete() OnDelete {
if o == nil {
return OnDeleteDelete
}
return o.OnDelete
}

View File

@@ -0,0 +1,47 @@
/*
Copyright 2024 The ORC Authors.
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
const (
// CloudCredentialsConfigSecretKey is the key for the clouds configuration in the cloud credentials secret.
CloudCredentialsConfigSecretKey = "clouds.yaml"
// CloudCredencialsCASecretKey is the key for the CA certificate in the cloud credentials secret.
CloudCredencialsCASecretKey = "cacert"
)
// CloudCredentialsReference is a reference to a secret containing OpenStack credentials.
type CloudCredentialsReference struct {
// secretName is the name of a secret in the same namespace as the resource being provisioned.
// The secret must contain a key named `clouds.yaml` which contains an OpenStack clouds.yaml file.
// The secret may optionally contain a key named `cacert` containing a PEM-encoded CA certificate.
// +required
// +kubebuilder:validation:MinLength:=1
// +kubebuilder:validation:MaxLength:=253
SecretName string `json:"secretName,omitempty"`
// cloudName specifies the name of the entry in the clouds.yaml file to use.
// +required
// +kubebuilder:validation:MinLength:=1
// +kubebuilder:validation:MaxLength:=256
CloudName string `json:"cloudName,omitempty"`
}
// CloudCredentialsRefProvider is an interface for obtaining OpenStack credentials from an API object
// +kubebuilder:object:generate:=false
type CloudCredentialsRefProvider interface {
GetCloudCredentialsRef() (*string, *CloudCredentialsReference)
}

View File

@@ -0,0 +1,21 @@
/*
Copyright 2024.
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 contains API Schema definitions for the openstack v1alpha1 API group
// +kubebuilder:object:generate=true
// +groupName=openstack.k-orc.cloud
// +k8s:openapi-gen=true
package v1alpha1

View File

@@ -0,0 +1,133 @@
/*
Copyright 2024 The ORC Authors.
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
// FlavorResourceSpec contains the desired state of a flavor
// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="FlavorResourceSpec is immutable"
type FlavorResourceSpec struct {
// name will be the name of the created resource. If not specified, the
// name of the ORC object will be used.
// +optional
Name *OpenStackName `json:"name,omitempty"`
// description contains a free form description of the flavor.
// +kubebuilder:validation:MinLength:=1
// +kubebuilder:validation:MaxLength:=65535
// +optional
Description *string `json:"description,omitempty"`
// ram is the memory of the flavor, measured in MB.
// +kubebuilder:validation:Minimum=1
// +required
RAM int32 `json:"ram,omitempty"`
// vcpus is the number of vcpus for the flavor.
// +kubebuilder:validation:Minimum=1
// +required
Vcpus int32 `json:"vcpus,omitempty"`
// disk is the size of the root disk that will be created in GiB. If 0
// the root disk will be set to exactly the size of the image used to
// deploy the instance. However, in this case the scheduler cannot
// select the compute host based on the virtual image size. Therefore,
// 0 should only be used for volume booted instances or for testing
// purposes. Volume-backed instances can be enforced for flavors with
// zero root disk via the
// os_compute_api:servers:create:zero_disk_flavor policy rule.
// +kubebuilder:validation:Minimum=0
// +required
Disk int32 `json:"disk"`
// swap is the size of a dedicated swap disk that will be allocated, in
// MiB. If 0 (the default), no dedicated swap disk will be created.
// +kubebuilder:validation:Minimum=0
// +optional
Swap int32 `json:"swap,omitempty"`
// isPublic flags a flavor as being available to all projects or not.
// +optional
IsPublic *bool `json:"isPublic,omitempty"`
// ephemeral is the size of the ephemeral disk that will be created, in GiB.
// Ephemeral disks may be written over on server state changes. So should only
// be used as a scratch space for applications that are aware of its
// limitations. Defaults to 0.
// +kubebuilder:validation:Minimum=0
// +optional
Ephemeral int32 `json:"ephemeral,omitempty"`
}
// FlavorFilter defines an existing resource by its properties
// +kubebuilder:validation:MinProperties:=1
type FlavorFilter struct {
// name of the existing resource
// +optional
Name *OpenStackName `json:"name,omitempty"`
// ram is the memory of the flavor, measured in MB.
// +kubebuilder:validation:Minimum=1
// +optional
RAM *int32 `json:"ram,omitempty"`
// vcpus is the number of vcpus for the flavor.
// +kubebuilder:validation:Minimum=1
// +optional
Vcpus *int32 `json:"vcpus,omitempty"`
// disk is the size of the root disk in GiB.
// +kubebuilder:validation:Minimum=0
// +optional
Disk *int32 `json:"disk,omitempty"`
}
// FlavorResourceStatus represents the observed state of the resource.
type FlavorResourceStatus struct {
// name is a Human-readable name for the flavor. Might not be unique.
// +kubebuilder:validation:MaxLength=1024
// +optional
Name string `json:"name,omitempty"`
// description is a human-readable description for the resource.
// +kubebuilder:validation:MaxLength:=65535
// +optional
Description string `json:"description,omitempty"`
// ram is the memory of the flavor, measured in MB.
// +optional
RAM *int32 `json:"ram,omitempty"`
// vcpus is the number of vcpus for the flavor.
// +optional
Vcpus *int32 `json:"vcpus,omitempty"`
// disk is the size of the root disk that will be created in GiB.
// +optional
Disk *int32 `json:"disk,omitempty"`
// swap is the size of a dedicated swap disk that will be allocated, in
// MiB.
// +optional
Swap *int32 `json:"swap,omitempty"`
// isPublic flags a flavor as being available to all projects or not.
// +optional
IsPublic *bool `json:"isPublic,omitempty"`
// ephemeral is the size of the ephemeral disk, in GiB.
// +optional
Ephemeral *int32 `json:"ephemeral,omitempty"`
}

View File

@@ -0,0 +1,151 @@
/*
Copyright 2024 The ORC Authors.
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
// FloatingIPFilter specifies a query to select an OpenStack floatingip. At least one property must be set.
// +kubebuilder:validation:MinProperties:=1
type FloatingIPFilter struct {
// floatingIP is the floatingip address.
// +optional
FloatingIP *IPvAny `json:"floatingIP,omitempty"`
// description of the existing resource
// +optional
Description *NeutronDescription `json:"description,omitempty"`
// floatingNetworkRef is a reference to the ORC Network which this resource is associated with.
// +optional
FloatingNetworkRef *KubernetesNameRef `json:"floatingNetworkRef,omitempty"`
// portRef is a reference to the ORC Port which this resource is associated with.
// +optional
PortRef *KubernetesNameRef `json:"portRef,omitempty"`
// projectRef is a reference to the ORC Project this resource is associated with.
// Typically, only used by admin.
// +optional
ProjectRef *KubernetesNameRef `json:"projectRef,omitempty"`
// status is the status of the floatingip.
// +kubebuilder:validation:MaxLength=1024
// +optional
Status string `json:"status,omitempty"`
FilterByNeutronTags `json:",inline"`
}
// FloatingIPResourceSpec contains the desired state of a floating IP
// +kubebuilder:validation:XValidation:rule="has(self.floatingNetworkRef) != has(self.floatingSubnetRef)",message="Exactly one of 'floatingNetworkRef' or 'floatingSubnetRef' must be set"
type FloatingIPResourceSpec struct {
// description is a human-readable description for the resource.
// +optional
Description *NeutronDescription `json:"description,omitempty"`
// tags is a list of tags which will be applied to the floatingip.
// +kubebuilder:validation:MaxItems:=64
// +listType=set
// +optional
Tags []NeutronTag `json:"tags,omitempty"`
// floatingNetworkRef references the network to which the floatingip is associated.
// +optional
// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="floatingNetworkRef is immutable"
FloatingNetworkRef *KubernetesNameRef `json:"floatingNetworkRef,omitempty"`
// floatingSubnetRef references the subnet to which the floatingip is associated.
// +optional
// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="floatingSubnetRef is immutable"
FloatingSubnetRef *KubernetesNameRef `json:"floatingSubnetRef,omitempty"`
// floatingIP is the IP that will be assigned to the floatingip. If not set, it will
// be assigned automatically.
// +optional
// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="floatingIP is immutable"
FloatingIP *IPvAny `json:"floatingIP,omitempty"`
// portRef is a reference to the ORC Port which this resource is associated with.
// +optional
// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="portRef is immutable"
PortRef *KubernetesNameRef `json:"portRef,omitempty"`
// fixedIP is the IP address of the port to which the floatingip is associated.
// +optional
// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="fixedIP is immutable"
FixedIP *IPvAny `json:"fixedIP,omitempty"`
// projectRef is a reference to the ORC Project this resource is associated with.
// Typically, only used by admin.
// +optional
// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="projectRef is immutable"
ProjectRef *KubernetesNameRef `json:"projectRef,omitempty"`
}
type FloatingIPResourceStatus struct {
// description is a human-readable description for the resource.
// +kubebuilder:validation:MaxLength=1024
// +optional
Description string `json:"description,omitempty"`
// floatingNetworkID is the ID of the network to which the floatingip is associated.
// +kubebuilder:validation:MaxLength=1024
// +optional
FloatingNetworkID string `json:"floatingNetworkID,omitempty"`
// floatingIP is the IP address of the floatingip.
// +kubebuilder:validation:MaxLength=1024
// +optional
FloatingIP string `json:"floatingIP,omitempty"`
// portID is the ID of the port to which the floatingip is associated.
// +kubebuilder:validation:MaxLength=1024
// +optional
PortID string `json:"portID,omitempty"`
// fixedIP is the IP address of the port to which the floatingip is associated.
// +kubebuilder:validation:MaxLength=1024
// +optional
FixedIP string `json:"fixedIP,omitempty"`
// tenantID is the project owner of the resource.
// +kubebuilder:validation:MaxLength=1024
// +optional
TenantID string `json:"tenantID,omitempty"`
// projectID is the project owner of the resource.
// +kubebuilder:validation:MaxLength=1024
// +optional
ProjectID string `json:"projectID,omitempty"`
// status indicates the current status of the resource.
// +kubebuilder:validation:MaxLength=1024
// +optional
Status string `json:"status,omitempty"`
// routerID is the ID of the router to which the floatingip is associated.
// +kubebuilder:validation:MaxLength=1024
// +optional
RouterID string `json:"routerID,omitempty"`
// tags is the list of tags on the resource.
// +kubebuilder:validation:MaxItems:=64
// +kubebuilder:validation:items:MaxLength=1024
// +listType=atomic
// +optional
Tags []string `json:"tags,omitempty"`
NeutronStatusMetadata `json:",inline"`
}

View File

@@ -0,0 +1,44 @@
/*
Copyright 2024.
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.
*/
// +kubebuilder:object:generate=true
// +groupName=openstack.k-orc.cloud
// +k8s:openapi-gen=true
package v1alpha1
import (
"k8s.io/apimachinery/pkg/runtime/schema"
"sigs.k8s.io/controller-runtime/pkg/scheme"
)
// GroupName is the group name use in this package
const GroupName = "openstack.k-orc.cloud"
// SchemeGroupVersion is group version used to register these objects
var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: "v1alpha1"}
// Resource takes an unqualified resource and returns a Group qualified GroupResource
func Resource(resource string) schema.GroupResource {
return SchemeGroupVersion.WithResource(resource).GroupResource()
}
var (
// SchemeBuilder is used to add go types to the GroupVersionKind scheme
SchemeBuilder = &scheme.Builder{GroupVersion: SchemeGroupVersion}
// AddToScheme adds the types in this group-version to the given scheme.
AddToScheme = SchemeBuilder.AddToScheme
)

View File

@@ -0,0 +1,411 @@
/*
Copyright 2024 The ORC Authors.
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
// GlanceTag is the name of the go field tag in properties structs used to specify the Glance property name.
const GlanceTag = "glance"
// +kubebuilder:validation:MinLength:=1
// +kubebuilder:validation:MaxLength:=255
type ImageTag string
// +kubebuilder:validation:Enum:=ami;ari;aki;bare;ovf;ova;docker;compressed
type ImageContainerFormat string
const (
ImageContainerFormatAKI ImageContainerFormat = "aki"
ImageContainerFormatAMI ImageContainerFormat = "ami"
ImageContainerFormatARI ImageContainerFormat = "ari"
ImageContainerFormatBare ImageContainerFormat = "bare"
ImageContainerFormatCompressed ImageContainerFormat = "compressed"
ImageContainerFormatDocker ImageContainerFormat = "docker"
ImageContainerFormatOVA ImageContainerFormat = "ova"
ImageContainerFormatOVF ImageContainerFormat = "ovf"
)
// +kubebuilder:validation:Enum:=ami;ari;aki;vhd;vhdx;vmdk;raw;qcow2;vdi;ploop;iso
type ImageDiskFormat string
const (
ImageDiskFormatAMI ImageDiskFormat = "ami"
ImageDiskFormatARI ImageDiskFormat = "ari"
ImageDiskFormatAKI ImageDiskFormat = "aki"
ImageDiskFormatVHD ImageDiskFormat = "vhd"
ImageDiskFormatVHDX ImageDiskFormat = "vhdx"
ImageDiskFormatVMDK ImageDiskFormat = "vmdk"
ImageDiskFormatRaw ImageDiskFormat = "raw"
ImageDiskFormatQCOW2 ImageDiskFormat = "qcow2"
ImageDiskFormatVDI ImageDiskFormat = "vdi"
ImageDiskFormatPLoop ImageDiskFormat = "ploop"
ImageDiskFormatISO ImageDiskFormat = "iso"
)
// +kubebuilder:validation:Enum:=public;private;shared;community
type ImageVisibility string
const (
ImageVisibilityPublic ImageVisibility = "public"
ImageVisibilityPrivate ImageVisibility = "private"
ImageVisibilityShared ImageVisibility = "shared"
ImageVisibilityCommunity ImageVisibility = "community"
)
// +kubebuilder:validation:Enum:=md5;sha1;sha256;sha512
type ImageHashAlgorithm string
const (
ImageHashAlgorithmMD5 ImageHashAlgorithm = "md5"
ImageHashAlgorithmSHA1 ImageHashAlgorithm = "sha1"
ImageHashAlgorithmSHA256 ImageHashAlgorithm = "sha256"
ImageHashAlgorithmSHA512 ImageHashAlgorithm = "sha512"
)
// See https://docs.openstack.org/glance/latest/admin/useful-image-properties.html
// for a list of 'well known' image properties we might consider supporting explicitly.
//
// The set of supported properties is currently arbitrarily selective. We should
// add supported options here freely.
// ImageHWBus is a type of hardware bus.
//
// Permitted values are scsi, virtio, uml, xen, ide, usb, and lxc.
// +kubebuilder:validation:Enum:=scsi;virtio;uml;xen;ide;usb;lxc
type ImageHWBus string
type ImagePropertiesHardware struct {
// cpuSockets is the preferred number of sockets to expose to the guest
// +kubebuilder:validation:Minimum:=1
// +optional
CPUSockets *int32 `json:"cpuSockets,omitempty" glance:"hw_cpu_sockets"`
// cpuCores is the preferred number of cores to expose to the guest
// +kubebuilder:validation:Minimum:=1
// +optional
CPUCores *int32 `json:"cpuCores,omitempty" glance:"hw_cpu_cores"`
// cpuThreads is the preferred number of threads to expose to the guest
// +kubebuilder:validation:Minimum:=1
// +optional
CPUThreads *int32 `json:"cpuThreads,omitempty" glance:"hw_cpu_threads"`
// cpuPolicy is used to pin the virtual CPUs (vCPUs) of instances to the
// host's physical CPU cores (pCPUs). Host aggregates should be used to
// separate these pinned instances from unpinned instances as the latter
// will not respect the resourcing requirements of the former.
//
// Permitted values are shared (the default), and dedicated.
//
// shared: The guest vCPUs will be allowed to freely float across host
// pCPUs, albeit potentially constrained by NUMA policy.
//
// dedicated: The guest vCPUs will be strictly pinned to a set of host
// pCPUs. In the absence of an explicit vCPU topology request, the
// drivers typically expose all vCPUs as sockets with one core and one
// thread. When strict CPU pinning is in effect the guest CPU topology
// will be setup to match the topology of the CPUs to which it is
// pinned. This option implies an overcommit ratio of 1.0. For example,
// if a two vCPU guest is pinned to a single host core with two threads,
// then the guest will get a topology of one socket, one core, two
// threads.
// +kubebuilder:validation:Enum:=shared;dedicated
// +optional
CPUPolicy *string `json:"cpuPolicy,omitempty" glance:"hw_cpu_policy"`
// cpuThreadPolicy further refines a CPUPolicy of 'dedicated' by stating
// how hardware CPU threads in a simultaneous multithreading-based (SMT)
// architecture be used. SMT-based architectures include Intel
// processors with Hyper-Threading technology. In these architectures,
// processor cores share a number of components with one or more other
// cores. Cores in such architectures are commonly referred to as
// hardware threads, while the cores that a given core share components
// with are known as thread siblings.
//
// Permitted values are prefer (the default), isolate, and require.
//
// prefer: The host may or may not have an SMT architecture. Where an
// SMT architecture is present, thread siblings are preferred.
//
// isolate: The host must not have an SMT architecture or must emulate a
// non-SMT architecture. If the host does not have an SMT architecture,
// each vCPU is placed on a different core as expected. If the host does
// have an SMT architecture - that is, one or more cores have thread
// siblings - then each vCPU is placed on a different physical core. No
// vCPUs from other guests are placed on the same core. All but one
// thread sibling on each utilized core is therefore guaranteed to be
// unusable.
//
// require: The host must have an SMT architecture. Each vCPU is
// allocated on thread siblings. If the host does not have an SMT
// architecture, then it is not used. If the host has an SMT
// architecture, but not enough cores with free thread siblings are
// available, then scheduling fails.
// +kubebuilder:validation:Enum:=prefer;isolate;require
// +optional
CPUThreadPolicy *string `json:"cpuThreadPolicy,omitempty" glance:"hw_cpu_thread_policy"`
// cdromBus specifies the type of disk controller to attach CD-ROM devices to.
// +optional
CDROMBus *ImageHWBus `json:"cdromBus,omitempty" glance:"hw_cdrom_bus"`
// diskBus specifies the type of disk controller to attach disk devices to.
// +optional
DiskBus *ImageHWBus `json:"diskBus,omitempty" glance:"hw_disk_bus"`
// TODO: hw_machine_type seems important to support early, but how to
// select a supported set?
// scsiModel enables the use of VirtIO SCSI (virtio-scsi) to provide
// block device access for compute instances; by default, instances use
// VirtIO Block (virtio-blk). VirtIO SCSI is a para-virtualized SCSI
// controller device that provides improved scalability and performance,
// and supports advanced SCSI hardware.
//
// The only permitted value is virtio-scsi.
// +kubebuilder:validation:Enum:=virtio-scsi
// +optional
SCSIModel *string `json:"scsiModel,omitempty" glance:"hw_scsi_model"`
// vifModel specifies the model of virtual network interface device to use.
//
// Permitted values are e1000, e1000e, ne2k_pci, pcnet, rtl8139, virtio,
// and vmxnet3.
// +kubebuilder:validation:Enum:=e1000;e1000e;ne2k_pci;pcnet;rtl8139;virtio;vmxnet3
// +optional
VIFModel *string `json:"vifModel,omitempty" glance:"hw_vif_model"`
// rngModel adds a random-number generator device to the images instances.
// This image property by itself does not guarantee that a hardware RNG will be used;
// it expresses a preference that may or may not be satisfied depending upon Nova configuration.
// +kubebuilder:validation:MaxLength:=255
// +optional
RngModel *string `json:"rngModel,omitempty" glance:"hw_rng_model"`
// qemuGuestAgent enables QEMU guest agent.
// +optional
QemuGuestAgent *bool `json:"qemuGuestAgent,omitempty" glance:"hw_qemu_guest_agent"`
}
type ImagePropertiesOperatingSystem struct {
// distro is the common name of the operating system distribution in lowercase.
// +kubebuilder:validation:Enum:=arch;centos;debian;fedora;freebsd;gentoo;mandrake;mandriva;mes;msdos;netbsd;netware;openbsd;opensolaris;opensuse;rocky;rhel;sled;ubuntu;windows
// +optional
Distro *string `json:"distro,omitempty" glance:"os_distro"`
// version is the operating system version as specified by the distributor.
// +kubebuilder:validation:MaxLength:=255
// +optional
Version *string `json:"version,omitempty" glance:"os_version"`
}
type ImageProperties struct {
// architecture is the CPU architecture that must be supported by the hypervisor.
// +kubebuilder:validation:Enum:=aarch64;alpha;armv7l;cris;i686;ia64;lm32;m68k;microblaze;microblazeel;mips;mipsel;mips64;mips64el;openrisc;parisc;parisc64;ppc;ppc64;ppcemb;s390;s390x;sh4;sh4eb;sparc;sparc64;unicore32;x86_64;xtensa;xtensaeb
// +optional
Architecture *string `json:"architecture,omitempty" glance:"architecture"`
// hypervisorType is the hypervisor type
// +kubebuilder:validation:Enum:=hyperv;ironic;lxc;qemu;uml;vmware;xen
// +optional
HypervisorType *string `json:"hypervisorType,omitempty" glance:"hypervisor_type"`
// minDiskGB is the minimum amount of disk space in GB that is required to boot the image
// +kubebuilder:validation:Minimum:=1
// +optional
MinDiskGB *int32 `json:"minDiskGB,omitempty"`
// minMemoryMB is the minimum amount of RAM in MB that is required to boot the image.
// +kubebuilder:validation:Minimum:=1
// +optional
MinMemoryMB *int32 `json:"minMemoryMB,omitempty"`
// hardware is a set of properties which control the virtual hardware
// created by Nova.
// +optional
Hardware *ImagePropertiesHardware `json:"hardware,omitempty"`
// operatingSystem is a set of properties that specify and influence the behavior
// of the operating system within the virtual machine.
// +optional
OperatingSystem *ImagePropertiesOperatingSystem `json:"operatingSystem,omitempty"`
}
// +kubebuilder:validation:Enum:=xz;gz;bz2
type ImageCompression string
const (
ImageCompressionXZ ImageCompression = "xz"
ImageCompressionGZ ImageCompression = "gz"
ImageCompressionBZ2 ImageCompression = "bz2"
)
type ImageContent struct {
// containerFormat is the format of the image container.
// qcow2 and raw images do not usually have a container. This is specified as "bare", which is also the default.
// Permitted values are ami, ari, aki, bare, compressed, ovf, ova, and docker.
// +kubebuilder:default:=bare
// +optional
ContainerFormat ImageContainerFormat `json:"containerFormat,omitempty"`
// diskFormat is the format of the disk image.
// Normal values are "qcow2", or "raw". Glance may be configured to support others.
// +required
DiskFormat ImageDiskFormat `json:"diskFormat,omitempty"`
// download describes how to obtain image data by downloading it from a URL.
// Must be set when creating a managed image.
// +required
//nolint:kubeapilinter
Download *ImageContentSourceDownload `json:"download"`
}
type ImageContentSourceDownload struct {
// url containing image data
// +kubebuilder:validation:Format=uri
// +kubebuilder:validation:MaxLength=2048
// +required
URL string `json:"url"`
// decompress specifies that the source data must be decompressed with the
// given compression algorithm before being stored. Specifying Decompress
// will disable the use of Glance's web-download, as web-download cannot
// currently deterministically decompress downloaded content.
// +optional
Decompress *ImageCompression `json:"decompress,omitempty"`
// hash is a hash which will be used to verify downloaded data, i.e.
// before any decompression. If not specified, no hash verification will be
// performed. Specifying a Hash will disable the use of Glance's
// web-download, as web-download cannot currently deterministically verify
// the hash of downloaded content.
// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="hash is immutable"
// +optional
Hash *ImageHash `json:"hash,omitempty"`
}
type ImageHash struct {
// algorithm is the hash algorithm used to generate value.
// +required
Algorithm ImageHashAlgorithm `json:"algorithm,omitempty"`
// value is the hash of the image data using Algorithm. It must be hex encoded using lowercase letters.
// +kubebuilder:validation:MinLength:=1
// +kubebuilder:validation:MaxLength:=1024
// +kubebuilder:validation:Pattern:=`^[0-9a-f]+$`
// +required
Value string `json:"value,omitempty"`
}
// ImageResourceSpec contains the desired state of a Glance image
type ImageResourceSpec struct {
// name will be the name of the created Glance image. If not specified, the
// name of the Image object will be used.
// +optional
Name *OpenStackName `json:"name,omitempty"`
// protected specifies that the image is protected from deletion.
// If not specified, the default is false.
// +optional
Protected *bool `json:"protected,omitempty"`
// tags is a list of tags which will be applied to the image. A tag has a maximum length of 255 characters.
// +kubebuilder:validation:MaxItems:=64
// +listType=set
// +optional
Tags []ImageTag `json:"tags,omitempty"`
// visibility of the image
// +optional
Visibility *ImageVisibility `json:"visibility,omitempty"`
// properties is metadata available to consumers of the image
// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="properties is immutable"
// +optional
Properties *ImageProperties `json:"properties,omitempty"`
// content specifies how to obtain the image content.
// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="content is immutable"
// +optional
Content *ImageContent `json:"content,omitempty"`
}
// ImageFilter defines a Glance query
// +kubebuilder:validation:MinProperties:=1
type ImageFilter struct {
// name specifies the name of a Glance image
// +optional
Name *OpenStackName `json:"name,omitempty"`
// visibility specifies the visibility of a Glance image.
// +optional
Visibility *ImageVisibility `json:"visibility,omitempty"`
// tags is the list of tags on the resource.
// +kubebuilder:validation:MaxItems:=64
// +listType=set
// +optional
Tags []ImageTag `json:"tags,omitempty"`
}
// ImageResourceStatus represents the observed state of a Glance image
type ImageResourceStatus struct {
// name is a Human-readable name for the image. Might not be unique.
// +kubebuilder:validation:MaxLength=1024
// +optional
Name string `json:"name,omitempty"`
// status is the image status as reported by Glance
// +kubebuilder:validation:MaxLength=1024
// +optional
Status string `json:"status,omitempty"`
// protected specifies that the image is protected from deletion.
// +optional
Protected bool `json:"protected,omitempty"`
// visibility of the image
// +kubebuilder:validation:MaxLength=1024
// +optional
Visibility string `json:"visibility,omitempty"`
// hash is the hash of the image data published by Glance. Note that this is
// a hash of the data stored internally by Glance, which will have been
// decompressed and potentially format converted depending on server-side
// configuration which is not visible to clients. It is expected that this
// hash will usually differ from the download hash.
// +optional
Hash *ImageHash `json:"hash,omitempty"`
// sizeB is the size of the image data, in bytes
// +optional
SizeB *int64 `json:"sizeB,omitempty"`
// virtualSizeB is the size of the disk the image data represents, in bytes
// +optional
VirtualSizeB *int64 `json:"virtualSizeB,omitempty"`
// tags is the list of tags on the resource.
// +kubebuilder:validation:MaxItems:=64
// +kubebuilder:validation:items:MaxLength=1024
// +listType=atomic
// +optional
Tags []string `json:"tags,omitempty"`
}
type ImageStatusExtra struct {
// downloadAttempts is the number of times the controller has attempted to download the image contents
// +optional
DownloadAttempts *int32 `json:"downloadAttempts,omitempty"`
}

View File

@@ -0,0 +1,232 @@
/*
Copyright 2024 The ORC Authors.
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
type ProviderPropertiesStatus struct {
// networkType is the type of physical network that this
// network should be mapped to. Supported values are flat, vlan, vxlan, and gre.
// Valid values depend on the networking back-end.
// +kubebuilder:validation:MaxLength=1024
// +optional
NetworkType string `json:"networkType,omitempty"`
// physicalNetwork is the physical network where this network
// should be implemented. The Networking API v2.0 does not provide a
// way to list available physical networks. For example, the Open
// vSwitch plug-in configuration file defines a symbolic name that maps
// to specific bridges on each compute host.
// +kubebuilder:validation:MaxLength=1024
// +optional
PhysicalNetwork string `json:"physicalNetwork,omitempty"`
// segmentationID is the ID of the isolated segment on the
// physical network. The network_type attribute defines the
// segmentation model. For example, if the network_type value is vlan,
// this ID is a vlan identifier. If the network_type value is gre, this
// ID is a gre key.
// +optional
SegmentationID *int32 `json:"segmentationID,omitempty"`
}
// TODO: Much better DNSDomain validation
// +kubebuilder:validation:MinLength:=1
// +kubebuilder:validation:MaxLength:=255
// +kubebuilder:validation:Pattern:="^[A-Za-z0-9]{1,63}(.[A-Za-z0-9-]{1,63})*(.[A-Za-z]{2,63})*.?$"
type DNSDomain string
// +kubebuilder:validation:Minimum:=68
// +kubebuilder:validation:Maximum:=9216
type MTU int32
// NetworkResourceSpec contains the desired state of a network
type NetworkResourceSpec struct {
// name will be the name of the created resource. If not specified, the
// name of the ORC object will be used.
// +optional
Name *OpenStackName `json:"name,omitempty"`
// description is a human-readable description for the resource.
// +optional
Description *NeutronDescription `json:"description,omitempty"`
// tags is a list of tags which will be applied to the network.
// +kubebuilder:validation:MaxItems:=64
// +listType=set
// +optional
Tags []NeutronTag `json:"tags,omitempty"`
// adminStateUp is the administrative state of the network, which is up (true) or down (false)
// +optional
AdminStateUp *bool `json:"adminStateUp,omitempty"`
// dnsDomain is the DNS domain of the network
// +optional
// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="dnsDomain is immutable"
DNSDomain *DNSDomain `json:"dnsDomain,omitempty"`
// mtu is the the maximum transmission unit value to address
// fragmentation. Minimum value is 68 for IPv4, and 1280 for IPv6.
// Defaults to 1500.
// +optional
MTU *MTU `json:"mtu,omitempty"`
// portSecurityEnabled is the port security status of the network.
// Valid values are enabled (true) and disabled (false). This value is
// used as the default value of port_security_enabled field of a newly
// created port.
// +optional
PortSecurityEnabled *bool `json:"portSecurityEnabled,omitempty"`
// external indicates whether the network has an external routing
// facility thats not managed by the networking service.
// +optional
External *bool `json:"external,omitempty"`
// shared indicates whether this resource is shared across all
// projects. By default, only administrative users can change this
// value.
// +optional
Shared *bool `json:"shared,omitempty"`
// availabilityZoneHints is the availability zone candidate for the network.
// +kubebuilder:validation:MaxItems:=64
// +listType=set
// +optional
// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="availabilityZoneHints is immutable"
AvailabilityZoneHints []AvailabilityZoneHint `json:"availabilityZoneHints,omitempty"`
// projectRef is a reference to the ORC Project this resource is associated with.
// Typically, only used by admin.
// +optional
// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="projectRef is immutable"
ProjectRef *KubernetesNameRef `json:"projectRef,omitempty"`
}
// NetworkFilter defines an existing resource by its properties
// +kubebuilder:validation:MinProperties:=1
type NetworkFilter struct {
// name of the existing resource
// +optional
Name *OpenStackName `json:"name,omitempty"`
// description of the existing resource
// +optional
Description *NeutronDescription `json:"description,omitempty"`
// external indicates whether the network has an external routing
// facility thats not managed by the networking service.
// +optional
External *bool `json:"external,omitempty"`
// projectRef is a reference to the ORC Project this resource is associated with.
// Typically, only used by admin.
// +optional
ProjectRef *KubernetesNameRef `json:"projectRef,omitempty"`
FilterByNeutronTags `json:",inline"`
}
// NetworkResourceStatus represents the observed state of the resource.
type NetworkResourceStatus struct {
// name is a Human-readable name for the network. Might not be unique.
// +kubebuilder:validation:MaxLength=1024
// +optional
Name string `json:"name,omitempty"`
// description is a human-readable description for the resource.
// +kubebuilder:validation:MaxLength=1024
// +optional
Description string `json:"description,omitempty"`
// projectID is the project owner of the network.
// +kubebuilder:validation:MaxLength=1024
// +optional
ProjectID string `json:"projectID,omitempty"`
// status indicates whether network is currently operational. Possible values
// include `ACTIVE', `DOWN', `BUILD', or `ERROR'. Plug-ins might define
// additional values.
// +kubebuilder:validation:MaxLength=1024
// +optional
Status string `json:"status,omitempty"`
// tags is the list of tags on the resource.
// +kubebuilder:validation:MaxItems=64
// +kubebuilder:validation:items:MaxLength=1024
// +listType=atomic
// +optional
Tags []string `json:"tags,omitempty"`
NeutronStatusMetadata `json:",inline"`
// adminStateUp is the administrative state of the network,
// which is up (true) or down (false).
// +optional
AdminStateUp *bool `json:"adminStateUp"`
// availabilityZoneHints is the availability zone candidate for the
// network.
// +kubebuilder:validation:MaxItems=64
// +kubebuilder:validation:items:MaxLength=1024
// +listType=atomic
// +optional
AvailabilityZoneHints []string `json:"availabilityZoneHints,omitempty"`
// dnsDomain is the DNS domain of the network
// +kubebuilder:validation:MaxLength=1024
// +optional
DNSDomain string `json:"dnsDomain,omitempty"`
// mtu is the the maximum transmission unit value to address
// fragmentation. Minimum value is 68 for IPv4, and 1280 for IPv6.
// +optional
MTU *int32 `json:"mtu,omitempty"`
// portSecurityEnabled is the port security status of the network.
// Valid values are enabled (true) and disabled (false). This value is
// used as the default value of port_security_enabled field of a newly
// created port.
// +optional
PortSecurityEnabled *bool `json:"portSecurityEnabled,omitempty"`
// provider contains provider-network properties.
// +optional
Provider *ProviderPropertiesStatus `json:"provider,omitempty"`
// external defines whether the network may be used for creation of
// floating IPs. Only networks with this flag may be an external
// gateway for routers. The network must have an external routing
// facility that is not managed by the networking service. If the
// network is updated from external to internal the unused floating IPs
// of this network are automatically deleted when extension
// floatingip-autodelete-internal is present.
// +optional
External *bool `json:"external,omitempty"`
// shared specifies whether the network resource can be accessed by any
// tenant.
// +optional
Shared *bool `json:"shared,omitempty"`
// subnets associated with this network.
// +kubebuilder:validation:MaxItems=256
// +kubebuilder:validation:items:MaxLength=1024
// +listType=atomic
// +optional
Subnets []string `json:"subnets,omitempty"`
}

View File

@@ -0,0 +1,26 @@
/*
Copyright 2024 The ORC Authors.
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
// +kubebuilder:validation:Format:=uuid
// +kubebuilder:validation:MaxLength:=36
type UUID string
// +kubebuilder:validation:MinLength:=1
// +kubebuilder:validation:MaxLength:=255
// +kubebuilder:validation:Pattern:="^[^,]+$"
type OpenStackName string

View File

@@ -0,0 +1,268 @@
/*
Copyright 2024 The ORC Authors.
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
// PortFilter specifies a filter to select a port. At least one parameter must be specified.
// +kubebuilder:validation:MinProperties:=1
type PortFilter struct {
// name of the existing resource
// +optional
Name *OpenStackName `json:"name,omitempty"`
// description of the existing resource
// +optional
Description *NeutronDescription `json:"description,omitempty"`
// networkRef is a reference to the ORC Network which this port is associated with.
// +optional
NetworkRef KubernetesNameRef `json:"networkRef"`
// projectRef is a reference to the ORC Project this resource is associated with.
// Typically, only used by admin.
// +optional
ProjectRef *KubernetesNameRef `json:"projectRef,omitempty"`
FilterByNeutronTags `json:",inline"`
}
type AllowedAddressPair struct {
// ip contains an IP address which a server connected to the port can
// send packets with. It can be an IP Address or a CIDR (if supported
// by the underlying extension plugin).
// +required
IP IPvAny `json:"ip,omitempty"`
// mac contains a MAC address which a server connected to the port can
// send packets with. Defaults to the MAC address of the port.
// +optional
MAC *MAC `json:"mac,omitempty"`
}
type AllowedAddressPairStatus struct {
// ip contains an IP address which a server connected to the port can
// send packets with.
// +kubebuilder:validation:MaxLength=1024
// +optional
IP string `json:"ip,omitempty"`
// mac contains a MAC address which a server connected to the port can
// send packets with.
// +kubebuilder:validation:MaxLength=1024
// +optional
MAC string `json:"mac,omitempty"`
}
type Address struct {
// ip contains a fixed IP address assigned to the port. It must belong
// to the referenced subnet's CIDR. If not specified, OpenStack
// allocates an available IP from the referenced subnet.
// +optional
IP *IPvAny `json:"ip,omitempty"`
// subnetRef references the subnet from which to allocate the IP
// address.
// +required
SubnetRef KubernetesNameRef `json:"subnetRef,omitempty"`
}
type FixedIPStatus struct {
// ip contains a fixed IP address assigned to the port.
// +kubebuilder:validation:MaxLength=1024
// +optional
IP string `json:"ip,omitempty"`
// subnetID is the ID of the subnet this IP is allocated from.
// +kubebuilder:validation:MaxLength=1024
// +optional
SubnetID string `json:"subnetID,omitempty"`
}
// +kubebuilder:validation:XValidation:rule="has(self.portSecurity) && self.portSecurity == 'Disabled' ? !has(self.securityGroupRefs) : true",message="securityGroupRefs must be empty when portSecurity is set to Disabled"
// +kubebuilder:validation:XValidation:rule="has(self.portSecurity) && self.portSecurity == 'Disabled' ? !has(self.allowedAddressPairs) : true",message="allowedAddressPairs must be empty when portSecurity is set to Disabled"
type PortResourceSpec struct {
// name is a human-readable name of the port. If not set, the object's name will be used.
// +optional
Name *OpenStackName `json:"name,omitempty"`
// description is a human-readable description for the resource.
// +optional
Description *NeutronDescription `json:"description,omitempty"`
// networkRef is a reference to the ORC Network which this port is associated with.
// +required
// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="networkRef is immutable"
NetworkRef KubernetesNameRef `json:"networkRef,omitempty"`
// tags is a list of tags which will be applied to the port.
// +kubebuilder:validation:MaxItems:=64
// +listType=set
// +optional
Tags []NeutronTag `json:"tags,omitempty"`
// allowedAddressPairs are allowed addresses associated with this port.
// +kubebuilder:validation:MaxItems:=128
// +listType=atomic
// +optional
AllowedAddressPairs []AllowedAddressPair `json:"allowedAddressPairs,omitempty"`
// addresses are the IP addresses for the port.
// +kubebuilder:validation:MaxItems:=128
// +listType=atomic
// +optional
// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="addresses is immutable"
Addresses []Address `json:"addresses,omitempty"`
// securityGroupRefs are the names of the security groups associated
// with this port.
// +kubebuilder:validation:MaxItems:=64
// +listType=set
// +optional
SecurityGroupRefs []OpenStackName `json:"securityGroupRefs,omitempty"`
// vnicType specifies the type of vNIC which this port should be
// attached to. This is used to determine which mechanism driver(s) to
// be used to bind the port. The valid values are normal, macvtap,
// direct, baremetal, direct-physical, virtio-forwarder, smart-nic and
// remote-managed, although these values will not be validated in this
// API to ensure compatibility with future neutron changes or custom
// implementations. What type of vNIC is actually available depends on
// deployments. If not specified, the Neutron default value is used.
// +kubebuilder:validation:MaxLength:=64
// +optional
VNICType string `json:"vnicType,omitempty"`
// portSecurity controls port security for this port.
// When set to Enabled, port security is enabled.
// When set to Disabled, port security is disabled and SecurityGroupRefs must be empty.
// When set to Inherit (default), it takes the value from the network level.
// +kubebuilder:default=Inherit
// +optional
// +kubebuilder:validation:XValidation:rule="!(oldSelf != 'Inherit' && self == 'Inherit')",message="portSecurity cannot be changed to Inherit"
PortSecurity PortSecurityState `json:"portSecurity,omitempty"`
// projectRef is a reference to the ORC Project this resource is associated with.
// Typically, only used by admin.
// +optional
// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="projectRef is immutable"
ProjectRef *KubernetesNameRef `json:"projectRef,omitempty"`
}
type PortResourceStatus struct {
// name is the human-readable name of the resource. Might not be unique.
// +kubebuilder:validation:MaxLength=1024
// +optional
Name string `json:"name,omitempty"`
// description is a human-readable description for the resource.
// +kubebuilder:validation:MaxLength=1024
// +optional
Description string `json:"description,omitempty"`
// networkID is the ID of the attached network.
// +kubebuilder:validation:MaxLength=1024
// +optional
NetworkID string `json:"networkID,omitempty"`
// projectID is the project owner of the resource.
// +kubebuilder:validation:MaxLength=1024
// +optional
ProjectID string `json:"projectID,omitempty"`
// status indicates the current status of the resource.
// +kubebuilder:validation:MaxLength=1024
// +optional
Status string `json:"status,omitempty"`
// tags is the list of tags on the resource.
// +kubebuilder:validation:MaxItems=64
// +kubebuilder:validation:items:MaxLength=1024
// +listType=atomic
// +optional
Tags []string `json:"tags,omitempty"`
// adminStateUp is the administrative state of the port,
// which is up (true) or down (false).
// +optional
AdminStateUp *bool `json:"adminStateUp,omitempty"`
// macAddress is the MAC address of the port.
// +kubebuilder:validation:MaxLength=1024
// +optional
MACAddress string `json:"macAddress,omitempty"`
// deviceID is the ID of the device that uses this port.
// +kubebuilder:validation:MaxLength=1024
// +optional
DeviceID string `json:"deviceID,omitempty"`
// deviceOwner is the entity type that uses this port.
// +kubebuilder:validation:MaxLength=1024
// +optional
DeviceOwner string `json:"deviceOwner,omitempty"`
// allowedAddressPairs is a set of zero or more allowed address pair
// objects each where address pair object contains an IP address and
// MAC address.
// +kubebuilder:validation:MaxItems=128
// +listType=atomic
// +optional
AllowedAddressPairs []AllowedAddressPairStatus `json:"allowedAddressPairs,omitempty"`
// fixedIPs is a set of zero or more fixed IP objects each where fixed
// IP object contains an IP address and subnet ID from which the IP
// address is assigned.
// +kubebuilder:validation:MaxItems=128
// +listType=atomic
// +optional
FixedIPs []FixedIPStatus `json:"fixedIPs,omitempty"`
// securityGroups contains the IDs of security groups applied to the port.
// +kubebuilder:validation:MaxItems=64
// +kubebuilder:validation:items:MaxLength=1024
// +listType=atomic
// +optional
SecurityGroups []string `json:"securityGroups,omitempty"`
// propagateUplinkStatus represents the uplink status propagation of
// the port.
// +optional
PropagateUplinkStatus *bool `json:"propagateUplinkStatus,omitempty"`
// vnicType is the type of vNIC which this port is attached to.
// +kubebuilder:validation:MaxLength:=64
// +optional
VNICType string `json:"vnicType,omitempty"`
// portSecurityEnabled indicates whether port security is enabled or not.
// +optional
PortSecurityEnabled *bool `json:"portSecurityEnabled,omitempty"`
NeutronStatusMetadata `json:",inline"`
}
// PortSecurityState represents the security state of a port
// +kubebuilder:validation:Enum=Enabled;Disabled;Inherit
type PortSecurityState string
const (
// PortSecurityEnabled means port security is enabled
PortSecurityEnabled PortSecurityState = "Enabled"
// PortSecurityDisabled means port security is disabled
PortSecurityDisabled PortSecurityState = "Disabled"
// PortSecurityInherit means port security settings are inherited from the network
PortSecurityInherit PortSecurityState = "Inherit"
)

View File

@@ -0,0 +1,115 @@
/*
Copyright 2025 The ORC Authors.
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
// +kubebuilder:validation:MinLength:=1
// +kubebuilder:validation:MaxLength:=255
type KeystoneTag string
type FilterByKeystoneTags struct {
// tags is a list of tags to filter by. If specified, the resource must
// have all of the tags specified to be included in the result.
// +listType=set
// +optional
// +kubebuilder:validation:MaxItems:=80
Tags []KeystoneTag `json:"tags,omitempty"`
// tagsAny is a list of tags to filter by. If specified, the resource
// must have at least one of the tags specified to be included in the
// result.
// +listType=set
// +optional
// +kubebuilder:validation:MaxItems:=80
TagsAny []KeystoneTag `json:"tagsAny,omitempty"`
// notTags is a list of tags to filter by. If specified, resources which
// contain all of the given tags will be excluded from the result.
// +listType=set
// +optional
// +kubebuilder:validation:MaxItems:=80
NotTags []KeystoneTag `json:"notTags,omitempty"`
// notTagsAny is a list of tags to filter by. If specified, resources
// which contain any of the given tags will be excluded from the result.
// +listType=set
// +optional
// +kubebuilder:validation:MaxItems:=80
NotTagsAny []KeystoneTag `json:"notTagsAny,omitempty"`
}
// +kubebuilder:validation:MinLength:=1
// +kubebuilder:validation:MaxLength:=64
type KeystoneName string
// ProjectResourceSpec contains the desired state of a project
type ProjectResourceSpec struct {
// name will be the name of the created resource. If not specified, the
// name of the ORC object will be used.
// +optional
Name *KeystoneName `json:"name,omitempty"`
// description contains a free form description of the project.
// +kubebuilder:validation:MinLength:=1
// +kubebuilder:validation:MaxLength:=65535
// +optional
Description *string `json:"description,omitempty"`
// enabled defines whether a project is enabled or not. Default is true.
// +optional
Enabled *bool `json:"enabled,omitempty"`
// tags is list of simple strings assigned to a project.
// Tags can be used to classify projects into groups.
// +kubebuilder:validation:MaxItems:=80
// +listType=set
// +optional
Tags []KeystoneTag `json:"tags,omitempty"`
}
// ProjectFilter defines an existing resource by its properties
// +kubebuilder:validation:MinProperties:=1
type ProjectFilter struct {
// name of the existing resource
// +optional
Name *KeystoneName `json:"name,omitempty"`
FilterByKeystoneTags `json:",inline"`
}
// ProjectResourceStatus represents the observed state of the resource.
type ProjectResourceStatus struct {
// name is a Human-readable name for the project. Might not be unique.
// +kubebuilder:validation:MaxLength=1024
// +optional
Name string `json:"name,omitempty"`
// description is a human-readable description for the resource.
// +kubebuilder:validation:MaxLength:=65535
// +optional
Description string `json:"description,omitempty"`
// enabled represents whether a project is enabled or not.
// +optional
Enabled *bool `json:"enabled,omitempty"`
// tags is the list of tags on the resource.
// +kubebuilder:validation:MaxItems=80
// +kubebuilder:validation:items:MaxLength=1024
// +listType=atomic
// +optional
Tags []string `json:"tags,omitempty"`
}

View File

@@ -0,0 +1,131 @@
/*
Copyright 2024 The ORC Authors.
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 (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
// +genclient
// +kubebuilder:object:root=true
// +kubebuilder:resource:categories=openstack
// +kubebuilder:subresource:status
// +kubebuilder:printcolumn:name="Available",type="string",JSONPath=".status.conditions[?(@.type=='Available')].status",description="Availability status of resource"
// +kubebuilder:printcolumn:name="Message",type="string",JSONPath=".status.conditions[?(@.type=='Progressing')].message",description="Message describing current progress status"
// RouterInterface is the Schema for an ORC resource.
type RouterInterface struct {
metav1.TypeMeta `json:",inline"`
// metadata contains the object metadata.
// +optional
metav1.ObjectMeta `json:"metadata,omitempty"`
// spec specifies the desired state of the resource.
// +optional
Spec RouterInterfaceSpec `json:"spec,omitempty"`
// status defines the observed state of the resource.
// +optional
Status RouterInterfaceStatus `json:"status,omitempty"`
}
// +kubebuilder:object:root=true
// RouterInterfaceList contains a list of RouterInterface.
type RouterInterfaceList struct {
metav1.TypeMeta `json:",inline"`
// metadata contains the list metadata.
// +optional
metav1.ListMeta `json:"metadata,omitempty"`
// items contains a list of RouterInterface.
// +kubebuilder:validation:MaxItems:=64
// +required
Items []RouterInterface `json:"items"`
}
func (l *RouterInterfaceList) GetItems() []RouterInterface {
return l.Items
}
// +kubebuilder:validation:Enum:=Subnet
// +kubebuilder:validation:MinLength:=1
// +kubebuilder:validation:MaxLength:=8
type RouterInterfaceType string
const (
RouterInterfaceTypeSubnet RouterInterfaceType = "Subnet"
)
// +kubebuilder:validation:XValidation:rule="self.type == 'Subnet' ? has(self.subnetRef) : !has(self.subnetRef)",message="subnetRef is required when type is 'Subnet' and not permitted otherwise"
// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="RouterInterfaceResourceSpec is immutable"
type RouterInterfaceSpec struct {
// type specifies the type of the router interface.
// +required
// +unionDiscriminator
Type RouterInterfaceType `json:"type,omitempty"`
// routerRef references the router to which this interface belongs.
// +required
RouterRef KubernetesNameRef `json:"routerRef,omitempty"`
// subnetRef references the subnet the router interface is created on.
// +unionMember
// +optional
SubnetRef *KubernetesNameRef `json:"subnetRef,omitempty"`
}
type RouterInterfaceStatus struct {
// conditions represents the observed status of the object.
// Known .status.conditions.type are: "Available", "Progressing"
//
// Available represents the availability of the OpenStack resource. If it is
// true then the resource is ready for use.
//
// Progressing indicates whether the controller is still attempting to
// reconcile the current state of the OpenStack resource to the desired
// state. Progressing will be False either because the desired state has
// been achieved, or because some terminal error prevents it from ever being
// achieved and the controller is no longer attempting to reconcile. If
// Progressing is True, an observer waiting on the resource should continue
// to wait.
//
// +kubebuilder:validation:MaxItems:=32
// +patchMergeKey=type
// +patchStrategy=merge
// +listType=map
// +listMapKey=type
// +optional
Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type"`
// id is the unique identifier of the port created for the router interface
// +kubebuilder:validation:MaxLength=1024
// +optional
ID *string `json:"id,omitempty"`
}
var _ ObjectWithConditions = &Router{}
func (i *RouterInterface) GetConditions() []metav1.Condition {
return i.Status.Conditions
}
func init() {
SchemeBuilder.Register(&RouterInterface{}, &RouterInterfaceList{})
}

View File

@@ -0,0 +1,147 @@
/*
Copyright 2024 The ORC Authors.
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
// RouterFilter specifies a query to select an OpenStack router. At least one property must be set.
// +kubebuilder:validation:MinProperties:=1
type RouterFilter struct {
// name of the existing resource
// +optional
Name *OpenStackName `json:"name,omitempty"`
// description of the existing resource
// +optional
Description *NeutronDescription `json:"description,omitempty"`
// projectRef is a reference to the ORC Project this resource is associated with.
// Typically, only used by admin.
// +optional
ProjectRef *KubernetesNameRef `json:"projectRef,omitempty"`
FilterByNeutronTags `json:",inline"`
}
type ExternalGateway struct {
// networkRef is a reference to the ORC Network which the external
// gateway is on.
// +required
NetworkRef KubernetesNameRef `json:"networkRef,omitempty"`
}
type ExternalGatewayStatus struct {
// networkID is the ID of the network the gateway is on.
// +kubebuilder:validation:MaxLength=1024
// +optional
NetworkID string `json:"networkID,omitempty"`
}
type RouterResourceSpec struct {
// name is a human-readable name of the router. If not set, the
// object's name will be used.
// +optional
Name *OpenStackName `json:"name,omitempty"`
// description is a human-readable description for the resource.
// +optional
Description *NeutronDescription `json:"description,omitempty"`
// tags is a list of tags which will be applied to the router.
// +kubebuilder:validation:MaxItems:=64
// +listType=set
// +optional
Tags []NeutronTag `json:"tags,omitempty"`
// adminStateUp represents the administrative state of the resource,
// which is up (true) or down (false). Default is true.
// +optional
AdminStateUp *bool `json:"adminStateUp,omitempty"`
// externalGateways is a list of external gateways for the router.
// Multiple gateways are not currently supported by ORC.
// +kubebuilder:validation:MaxItems:=1
// +listType=atomic
// +optional
// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="externalGateways is immutable"
ExternalGateways []ExternalGateway `json:"externalGateways,omitempty"`
// distributed indicates whether the router is distributed or not. It
// is available when dvr extension is enabled.
// +optional
// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="distributed is immutable"
Distributed *bool `json:"distributed,omitempty"`
// availabilityZoneHints is the availability zone candidate for the router.
// +kubebuilder:validation:MaxItems:=64
// +listType=set
// +optional
// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="availabilityZoneHints is immutable"
AvailabilityZoneHints []AvailabilityZoneHint `json:"availabilityZoneHints,omitempty"`
// projectRef is a reference to the ORC Project this resource is associated with.
// Typically, only used by admin.
// +optional
// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="projectRef is immutable"
ProjectRef *KubernetesNameRef `json:"projectRef,omitempty"`
}
type RouterResourceStatus struct {
// name is the human-readable name of the resource. Might not be unique.
// +kubebuilder:validation:MaxLength=1024
// +optional
Name string `json:"name,omitempty"`
// description is a human-readable description for the resource.
// +kubebuilder:validation:MaxLength=1024
// +optional
Description string `json:"description,omitempty"`
// projectID is the project owner of the resource.
// +kubebuilder:validation:MaxLength=1024
// +optional
ProjectID string `json:"projectID,omitempty"`
// status indicates the current status of the resource.
// +kubebuilder:validation:MaxLength=1024
// +optional
Status string `json:"status,omitempty"`
// tags is the list of tags on the resource.
// +kubebuilder:validation:MaxItems:=64
// +kubebuilder:validation:items:MaxLength=1024
// +listType=atomic
// +optional
Tags []string `json:"tags,omitempty"`
// adminStateUp is the administrative state of the router,
// which is up (true) or down (false).
// +optional
AdminStateUp *bool `json:"adminStateUp"`
// externalGateways is a list of external gateways for the router.
// +kubebuilder:validation:MaxItems:=32
// +listType=atomic
// +optional
ExternalGateways []ExternalGatewayStatus `json:"externalGateways,omitempty"`
// availabilityZoneHints is the availability zone candidate for the
// router.
// +kubebuilder:validation:MaxItems:=64
// +kubebuilder:validation:items:MaxLength=1024
// +listType=atomic
// +optional
AvailabilityZoneHints []string `json:"availabilityZoneHints,omitempty"`
}

View File

@@ -0,0 +1,276 @@
/*
Copyright 2024 The ORC Authors.
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
// +kubebuilder:validation:Enum:=ingress;egress
type RuleDirection string
// +kubebuilder:validation:Enum:=ah;dccp;egp;esp;gre;icmp;icmpv6;igmp;ipip;ipv6-encap;ipv6-frag;ipv6-icmp;ipv6-nonxt;ipv6-opts;ipv6-route;ospf;pgm;rsvp;sctp;tcp;udp;udplite;vrrp
type Protocol string
const (
ProtocolAH Protocol = "ah"
ProtocolDCCP Protocol = "dccp"
ProtocolEGP Protocol = "egp"
ProtocolESP Protocol = "esp"
ProtocolGRE Protocol = "gre"
ProtocolICMP Protocol = "icmp"
ProtocolICMPV6 Protocol = "icmpv6"
ProtocolIGMP Protocol = "igmp"
ProtocolIPIP Protocol = "ipip"
ProtocolIPV6ENCAP Protocol = "ipv6-encap"
ProtocolIPV6FRAG Protocol = "ipv6-frag"
ProtocolIPV6ICMP Protocol = "ipv6-icmp"
ProtocolIPV6NONXT Protocol = "ipv6-nonxt"
ProtocolIPV6OPTS Protocol = "ipv6-opts"
ProtocolIPV6ROUTE Protocol = "ipv6-route"
ProtocolOSPF Protocol = "ospf"
ProtocolPGM Protocol = "pgm"
ProtocolRSVP Protocol = "rsvp"
ProtocolSCTP Protocol = "sctp"
ProtocolTCP Protocol = "tcp"
ProtocolUDP Protocol = "udp"
ProtocolUDPLITE Protocol = "udplite"
ProtocolVRRP Protocol = "vrrp"
)
// +kubebuilder:validation:Enum:=IPv4;IPv6
type Ethertype string
const (
EthertypeIPv4 Ethertype = "IPv4"
EthertypeIPv6 Ethertype = "IPv6"
)
// +kubebuilder:validation:Minimum:=0
// +kubebuilder:validation:Maximum:=65535
type PortNumber int32
type PortRangeSpec struct {
// min is the minimum port number in the range that is matched by the security group rule.
// If the protocol is TCP, UDP, DCCP, SCTP or UDP-Lite this value must be less than or equal
// to the port_range_max attribute value. If the protocol is ICMP, this value must be an ICMP type
// +required
Min PortNumber `json:"min"`
// max is the maximum port number in the range that is matched by the security group rule.
// If the protocol is TCP, UDP, DCCP, SCTP or UDP-Lite this value must be greater than or equal
// to the port_range_min attribute value. If the protocol is ICMP, this value must be an ICMP code.
// +required
Max PortNumber `json:"max"`
}
type PortRangeStatus struct {
// min is the minimum port number in the range that is matched by the security group rule.
// If the protocol is TCP, UDP, DCCP, SCTP or UDP-Lite this value must be less than or equal
// to the port_range_max attribute value. If the protocol is ICMP, this value must be an ICMP type
// +optional
Min int32 `json:"min"`
// max is the maximum port number in the range that is matched by the security group rule.
// If the protocol is TCP, UDP, DCCP, SCTP or UDP-Lite this value must be greater than or equal
// to the port_range_min attribute value. If the protocol is ICMP, this value must be an ICMP code.
// +optional
Max int32 `json:"max"`
}
// NOTE: A validation was removed from SecurityGroupRule until we bump minimum k8s to at least v1.31:
// - remoteIPPrefix matches the address family defined in ethertype: PR #336
// SecurityGroupRule defines a Security Group rule
// +kubebuilder:validation:MinProperties:=1
// +kubebuilder:validation:XValidation:rule="(!has(self.portRange)|| !(self.protocol == 'tcp'|| self.protocol == 'udp' || self.protocol == 'dccp' || self.protocol == 'sctp' || self.protocol == 'udplite') || (self.portRange.min <= self.portRange.max))",message="portRangeMax should be equal or greater than portRange.min"
// +kubebuilder:validation:XValidation:rule="!(self.protocol == 'icmp' || self.protocol == 'icmpv6') || !has(self.portRange)|| (self.portRange.min >= 0 && self.portRange.min <= 255)",message="When protocol is ICMP or ICMPv6 portRange.min should be between 0 and 255"
// +kubebuilder:validation:XValidation:rule="!(self.protocol == 'icmp' || self.protocol == 'icmpv6') || !has(self.portRange)|| (self.portRange.max >= 0 && self.portRange.max <= 255)",message="When protocol is ICMP or ICMPv6 portRange.max should be between 0 and 255"
type SecurityGroupRule struct {
// description is a human-readable description for the resource.
// +optional
Description *NeutronDescription `json:"description,omitempty"`
// direction represents the direction in which the security group rule
// is applied. Can be ingress or egress.
// +optional
Direction *RuleDirection `json:"direction,omitempty"`
// remoteIPPrefix is an IP address block. Should match the Ethertype (IPv4 or IPv6)
// +optional
RemoteIPPrefix *CIDR `json:"remoteIPPrefix,omitempty"`
// protocol is the IP protocol is represented by a string
// +optional
Protocol *Protocol `json:"protocol,omitempty"`
// ethertype must be IPv4 or IPv6, and addresses represented in CIDR
// must match the ingress or egress rules.
// +required
Ethertype Ethertype `json:"ethertype,omitempty"`
// portRange sets the minimum and maximum ports range that the security group rule
// matches. If the protocol is [tcp, udp, dccp sctp,udplite] PortRange.Min must be less than
// or equal to the PortRange.Max attribute value.
// If the protocol is ICMP, this PortRamge.Min must be an ICMP code and PortRange.Max
// should be an ICMP type
// +optional
PortRange *PortRangeSpec `json:"portRange,omitempty"`
}
type SecurityGroupRuleStatus struct {
// id is the ID of the security group rule.
// +kubebuilder:validation:MaxLength=1024
// +optional
ID string `json:"id,omitempty"`
// description is a human-readable description for the resource.
// +kubebuilder:validation:MaxLength=1024
// +optional
Description string `json:"description,omitempty"`
// direction represents the direction in which the security group rule
// is applied. Can be ingress or egress.
// +kubebuilder:validation:MaxLength=1024
// +optional
Direction string `json:"direction,omitempty"`
// RemoteAddressGroupId (Not in gophercloud)
// remoteGroupID is the remote group UUID to associate with this security group rule
// RemoteGroupID
// +kubebuilder:validation:MaxLength=1024
// +optional
RemoteGroupID string `json:"remoteGroupID,omitempty"`
// remoteIPPrefix is an IP address block. Should match the Ethertype (IPv4 or IPv6)
// +kubebuilder:validation:MaxLength=1024
// +optional
RemoteIPPrefix string `json:"remoteIPPrefix,omitempty"`
// protocol is the IP protocol can be represented by a string, an
// integer, or null
// +kubebuilder:validation:MaxLength=1024
// +optional
Protocol string `json:"protocol,omitempty"`
// ethertype must be IPv4 or IPv6, and addresses represented in CIDR
// must match the ingress or egress rules.
// +kubebuilder:validation:MaxLength=1024
// +optional
Ethertype string `json:"ethertype,omitempty"`
// portRange sets the minimum and maximum ports range that the security group rule
// matches. If the protocol is [tcp, udp, dccp sctp,udplite] PortRange.Min must be less than
// or equal to the PortRange.Max attribute value.
// If the protocol is ICMP, this PortRamge.Min must be an ICMP code and PortRange.Max
// should be an ICMP type
// +optional
PortRange *PortRangeStatus `json:"portRange,omitempty"`
// FIXME(mandre) This field is not yet returned by gophercloud
// BelongsToDefaultSG bool `json:"belongsToDefaultSG,omitempty"`
// FIXME(mandre) Technically, the neutron status metadata are returned
// for SG rules. Should we include them? Gophercloud does not
// implements this yet.
// NeutronStatusMetadata `json:",inline"`
}
// SecurityGroupResourceSpec contains the desired state of a security group
type SecurityGroupResourceSpec struct {
// name will be the name of the created resource. If not specified, the
// name of the ORC object will be used.
// +optional
Name *OpenStackName `json:"name,omitempty"`
// description is a human-readable description for the resource.
// +optional
Description *NeutronDescription `json:"description,omitempty"`
// tags is a list of tags which will be applied to the security group.
// +kubebuilder:validation:MaxItems:=64
// +listType=set
// +optional
Tags []NeutronTag `json:"tags,omitempty"`
// stateful indicates if the security group is stateful or stateless.
// +optional
// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="stateful is immutable"
Stateful *bool `json:"stateful,omitempty"`
// rules is a list of security group rules belonging to this SG.
// +kubebuilder:validation:MaxItems:=256
// +listType=atomic
// +optional
Rules []SecurityGroupRule `json:"rules,omitempty"`
// projectRef is a reference to the ORC Project this resource is associated with.
// Typically, only used by admin.
// +optional
// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="projectRef is immutable"
ProjectRef *KubernetesNameRef `json:"projectRef,omitempty"`
}
// SecurityGroupFilter defines an existing resource by its properties
// +kubebuilder:validation:MinProperties:=1
type SecurityGroupFilter struct {
// name of the existing resource
// +optional
Name *OpenStackName `json:"name,omitempty"`
// description of the existing resource
// +optional
Description *NeutronDescription `json:"description,omitempty"`
// projectRef is a reference to the ORC Project this resource is associated with.
// Typically, only used by admin.
// +optional
ProjectRef *KubernetesNameRef `json:"projectRef,omitempty"`
FilterByNeutronTags `json:",inline"`
}
// SecurityGroupResourceStatus represents the observed state of the resource.
type SecurityGroupResourceStatus struct {
// name is a Human-readable name for the security group. Might not be unique.
// +kubebuilder:validation:MaxLength=1024
// +optional
Name string `json:"name,omitempty"`
// description is a human-readable description for the resource.
// +kubebuilder:validation:MaxLength=1024
// +optional
Description string `json:"description,omitempty"`
// projectID is the project owner of the security group.
// +kubebuilder:validation:MaxLength=1024
// +optional
ProjectID string `json:"projectID,omitempty"`
// tags is the list of tags on the resource.
// +kubebuilder:validation:MaxItems:=64
// +kubebuilder:validation:items:MaxLength=1024
// +listType=atomic
// +optional
Tags []string `json:"tags,omitempty"`
// stateful indicates if the security group is stateful or stateless.
// +optional
Stateful bool `json:"stateful,omitempty"`
// rules is a list of security group rules belonging to this SG.
// +kubebuilder:validation:MaxItems:=256
// +listType=atomic
// +optional
Rules []SecurityGroupRuleStatus `json:"rules,omitempty"`
NeutronStatusMetadata `json:",inline"`
}

View File

@@ -0,0 +1,258 @@
/*
Copyright 2024 The ORC Authors.
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
// +kubebuilder:validation:MinLength:=1
// +kubebuilder:validation:MaxLength:=80
type ServerTag string
type FilterByServerTags struct {
// tags is a list of tags to filter by. If specified, the resource must
// have all of the tags specified to be included in the result.
// +listType=set
// +optional
// +kubebuilder:validation:MaxItems:=50
Tags []ServerTag `json:"tags,omitempty"`
// tagsAny is a list of tags to filter by. If specified, the resource
// must have at least one of the tags specified to be included in the
// result.
// +listType=set
// +optional
// +kubebuilder:validation:MaxItems:=50
TagsAny []ServerTag `json:"tagsAny,omitempty"`
// notTags is a list of tags to filter by. If specified, resources which
// contain all of the given tags will be excluded from the result.
// +listType=set
// +optional
// +kubebuilder:validation:MaxItems:=50
NotTags []ServerTag `json:"notTags,omitempty"`
// notTagsAny is a list of tags to filter by. If specified, resources
// which contain any of the given tags will be excluded from the result.
// +listType=set
// +optional
// +kubebuilder:validation:MaxItems:=50
NotTagsAny []ServerTag `json:"notTagsAny,omitempty"`
}
// +kubebuilder:validation:MinProperties:=1
// +kubebuilder:validation:MaxProperties:=1
type ServerPortSpec struct {
// portRef is a reference to a Port object. Server creation will wait for
// this port to be created and available.
// +optional
PortRef *KubernetesNameRef `json:"portRef,omitempty"`
}
// +kubebuilder:validation:MinProperties:=1
type ServerVolumeSpec struct {
// volumeRef is a reference to a Volume object. Server creation will wait for
// this volume to be created and available.
// +required
VolumeRef KubernetesNameRef `json:"volumeRef,omitempty"`
// device is the name of the device, such as `/dev/vdb`.
// Omit for auto-assignment
// +kubebuilder:validation:MaxLength:=255
// +optional
Device *string `json:"device,omitempty"`
}
type ServerVolumeStatus struct {
// id is the ID of a volume attached to the server.
// +kubebuilder:validation:MaxLength:=1024
// +optional
ID string `json:"id,omitempty"`
}
type ServerInterfaceFixedIP struct {
// ipAddress is the IP address assigned to the port.
// +kubebuilder:validation:MaxLength:=1024
// +optional
IPAddress string `json:"ipAddress,omitempty"`
// subnetID is the ID of the subnet from which the IP address is allocated.
// +kubebuilder:validation:MaxLength:=1024
// +optional
SubnetID string `json:"subnetID,omitempty"`
}
type ServerInterfaceStatus struct {
// portID is the ID of a port attached to the server.
// +kubebuilder:validation:MaxLength:=1024
// +optional
PortID string `json:"portID,omitempty"`
// netID is the ID of the network to which the interface is attached.
// +kubebuilder:validation:MaxLength:=1024
// +optional
NetID string `json:"netID,omitempty"`
// macAddr is the MAC address of the interface.
// +kubebuilder:validation:MaxLength:=1024
// +optional
MACAddr string `json:"macAddr,omitempty"`
// portState is the state of the port (e.g., ACTIVE, DOWN).
// +kubebuilder:validation:MaxLength:=1024
// +optional
PortState string `json:"portState,omitempty"`
// fixedIPs is the list of fixed IP addresses assigned to the interface.
// +kubebuilder:validation:MaxItems:=32
// +listType=atomic
// +optional
FixedIPs []ServerInterfaceFixedIP `json:"fixedIPs,omitempty"`
}
// ServerResourceSpec contains the desired state of a server
type ServerResourceSpec struct {
// name will be the name of the created resource. If not specified, the
// name of the ORC object will be used.
// +optional
Name *OpenStackName `json:"name,omitempty"`
// imageRef references the image to use for the server instance.
// NOTE: This is not required in case of boot from volume.
// +required
// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="imageRef is immutable"
ImageRef KubernetesNameRef `json:"imageRef,omitempty"`
// flavorRef references the flavor to use for the server instance.
// +required
// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="flavorRef is immutable"
FlavorRef KubernetesNameRef `json:"flavorRef,omitempty"`
// userData specifies data which will be made available to the server at
// boot time, either via the metadata service or a config drive. It is
// typically read by a configuration service such as cloud-init or ignition.
// +optional
// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="userData is immutable"
UserData *UserDataSpec `json:"userData,omitempty"`
// ports defines a list of ports which will be attached to the server.
// +kubebuilder:validation:MaxItems:=64
// +listType=atomic
// +required
Ports []ServerPortSpec `json:"ports,omitempty"`
// volumes is a list of volumes attached to the server.
// +kubebuilder:validation:MaxItems:=64
// +listType=atomic
// +optional
Volumes []ServerVolumeSpec `json:"volumes,omitempty"`
// serverGroupRef is a reference to a ServerGroup object. The server
// will be created in the server group.
// +optional
// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="serverGroupRef is immutable"
ServerGroupRef *KubernetesNameRef `json:"serverGroupRef,omitempty"`
// availabilityZone is the availability zone in which to create the server.
// +kubebuilder:validation:MaxLength=255
// +optional
// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="availabilityZone is immutable"
AvailabilityZone string `json:"availabilityZone,omitempty"`
// tags is a list of tags which will be applied to the server.
// +kubebuilder:validation:MaxItems:=50
// +listType=set
// +optional
Tags []ServerTag `json:"tags,omitempty"`
}
// +kubebuilder:validation:MinProperties:=1
// +kubebuilder:validation:MaxProperties:=1
type UserDataSpec struct {
// secretRef is a reference to a Secret containing the user data for this server.
// +optional
SecretRef *KubernetesNameRef `json:"secretRef,omitempty"`
}
// ServerFilter defines an existing resource by its properties
// +kubebuilder:validation:MinProperties:=1
type ServerFilter struct {
// name of the existing resource
// +optional
Name *OpenStackName `json:"name,omitempty"`
// availabilityZone is the availability zone of the existing resource
// +kubebuilder:validation:MaxLength=255
// +optional
AvailabilityZone string `json:"availabilityZone,omitempty"`
FilterByServerTags `json:",inline"`
}
// ServerResourceStatus represents the observed state of the resource.
type ServerResourceStatus struct {
// name is the human-readable name of the resource. Might not be unique.
// +kubebuilder:validation:MaxLength=1024
// +optional
Name string `json:"name,omitempty"`
// hostID is the host where the server is located in the cloud.
// +kubebuilder:validation:MaxLength=1024
// +optional
HostID string `json:"hostID,omitempty"`
// status contains the current operational status of the server,
// such as IN_PROGRESS or ACTIVE.
// +kubebuilder:validation:MaxLength=1024
// +optional
Status string `json:"status,omitempty"`
// imageID indicates the OS image used to deploy the server.
// +kubebuilder:validation:MaxLength=1024
// +optional
ImageID string `json:"imageID,omitempty"`
// availabilityZone is the availability zone where the server is located.
// +kubebuilder:validation:MaxLength=1024
// +optional
AvailabilityZone string `json:"availabilityZone,omitempty"`
// serverGroups is a slice of strings containing the UUIDs of the
// server groups to which the server belongs. Currently this can
// contain at most one entry.
// +kubebuilder:validation:MaxItems:=32
// +kubebuilder:validation:items:MaxLength=1024
// +listType=atomic
// +optional
ServerGroups []string `json:"serverGroups,omitempty"`
// volumes contains the volumes attached to the server.
// +kubebuilder:validation:MaxItems:=64
// +listType=atomic
// +optional
Volumes []ServerVolumeStatus `json:"volumes,omitempty"`
// interfaces contains the list of interfaces attached to the server.
// +kubebuilder:validation:MaxItems:=64
// +listType=atomic
// +optional
Interfaces []ServerInterfaceStatus `json:"interfaces,omitempty"`
// tags is the list of tags on the resource.
// +kubebuilder:validation:MaxItems:=50
// +kubebuilder:validation:items:MaxLength=1024
// +listType=atomic
// +optional
Tags []string `json:"tags,omitempty"`
}

View File

@@ -0,0 +1,100 @@
/*
Copyright 2024 The ORC Authors.
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
// +kubebuilder:validation:Enum:=affinity;anti-affinity;soft-affinity;soft-anti-affinity
type ServerGroupPolicy string
const (
// ServerGroupPolicyAffinity is a server group policy that restricts instances belonging to the server group to the same host.
ServerGroupPolicyAffinity ServerGroupPolicy = "affinity"
// ServerGroupPolicyAntiAffinity is a server group policy that restricts instances belonging to the server group to separate hosts.
ServerGroupPolicyAntiAffinity ServerGroupPolicy = "anti-affinity"
// ServerGroupPolicySoftAffinity is a server group policy that attempts to restrict instances belonging to the server group to the same host.
// Where it is not possible to schedule all instances on one host, they will be scheduled together on as few hosts as possible.
ServerGroupPolicySoftAffinity ServerGroupPolicy = "soft-affinity"
// ServerGroupPolicySoftAntiAffinity is a server group policy that attempts to restrict instances belonging to the server group to separate hosts.
// Where it is not possible to schedule all instances to separate hosts, they will be scheduled on as many separate hosts as possible.
ServerGroupPolicySoftAntiAffinity ServerGroupPolicy = "soft-anti-affinity"
)
type ServerGroupRules struct {
// maxServerPerHost specifies how many servers can reside on a single compute host.
// It can be used only with the "anti-affinity" policy.
// +optional
MaxServerPerHost int32 `json:"maxServerPerHost,omitempty"`
}
// ServerGroupResourceSpec contains the desired state of a servergroup
// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="ServerGroupResourceSpec is immutable"
// +kubebuilder:validation:XValidation:rule="has(self.rules) && self.rules.maxServerPerHost > 0 ? self.policy == 'anti-affinity' : true",message="maxServerPerHost can only be used with the anti-affinity policy"
type ServerGroupResourceSpec struct {
// name will be the name of the created resource. If not specified, the
// name of the ORC object will be used.
// +optional
Name *OpenStackName `json:"name,omitempty"`
// policy is the policy to use for the server group.
// +required
Policy ServerGroupPolicy `json:"policy,omitempty"`
// rules is the rules to use for the server group.
// +optional
Rules *ServerGroupRules `json:"rules,omitempty"`
}
// ServerGroupFilter defines an existing resource by its properties
// +kubebuilder:validation:MinProperties:=1
type ServerGroupFilter struct {
// name of the existing resource
// +optional
Name *OpenStackName `json:"name,omitempty"`
}
type ServerGroupRulesStatus struct {
// maxServerPerHost specifies how many servers can reside on a single compute host.
// It can be used only with the "anti-affinity" policy.
// +optional
MaxServerPerHost *int32 `json:"maxServerPerHost,omitempty"`
}
// ServerGroupResourceStatus represents the observed state of the resource.
type ServerGroupResourceStatus struct {
// name is a Human-readable name for the servergroup. Might not be unique.
// +kubebuilder:validation:MaxLength=1024
// +optional
Name string `json:"name,omitempty"`
// policy is the policy of the servergroup.
// +kubebuilder:validation:MaxLength=1024
// +optional
Policy string `json:"policy,omitempty"`
// projectID is the project owner of the resource.
// +kubebuilder:validation:MaxLength=1024
// +optional
ProjectID string `json:"projectID,omitempty"`
// userID of the server group.
// +kubebuilder:validation:MaxLength=1024
// +optional
UserID string `json:"userID,omitempty"`
// rules is the rules of the server group.
// +optional
Rules *ServerGroupRulesStatus `json:"rules,omitempty"`
}

View File

@@ -0,0 +1,338 @@
/*
Copyright 2024 The ORC Authors.
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
// TODO validations:
//
// * IP addresses in CIDR, AllocationPools, Gateway, DNSNameserver(?), and
// HostRoutes match the version in IPVersion (Spec and SubnetFilter)
// * IPv6 may only be set if IPVersion is 6 (Spec and SubnetFilter)
// * AllocationPools must be in CIDR
// SubnetFilter specifies a filter to select a subnet. At least one parameter must be specified.
// +kubebuilder:validation:MinProperties:=1
type SubnetFilter struct {
// name of the existing resource
// +optional
Name *OpenStackName `json:"name,omitempty"`
// description of the existing resource
// +optional
Description *NeutronDescription `json:"description,omitempty"`
// ipVersion of the existing resource
// +optional
IPVersion *IPVersion `json:"ipVersion,omitempty"`
// gatewayIP is the IP address of the gateway of the existing resource
// +optional
GatewayIP *IPvAny `json:"gatewayIP,omitempty"`
// cidr of the existing resource
// +optional
CIDR *CIDR `json:"cidr,omitempty"`
// ipv6 options of the existing resource
// +optional
IPv6 *IPv6Options `json:"ipv6,omitempty"`
// networkRef is a reference to the ORC Network which this subnet is associated with.
// +optional
NetworkRef KubernetesNameRef `json:"networkRef"`
// projectRef is a reference to the ORC Project this resource is associated with.
// Typically, only used by admin.
// +optional
ProjectRef *KubernetesNameRef `json:"projectRef,omitempty"`
FilterByNeutronTags `json:",inline"`
}
type SubnetResourceSpec struct {
// name is a human-readable name of the subnet. If not set, the object's name will be used.
// +optional
Name *OpenStackName `json:"name,omitempty"`
// description is a human-readable description for the resource.
// +optional
Description *NeutronDescription `json:"description,omitempty"`
// networkRef is a reference to the ORC Network which this subnet is associated with.
// +required
// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="networkRef is immutable"
NetworkRef KubernetesNameRef `json:"networkRef,omitempty"`
// tags is a list of tags which will be applied to the subnet.
// +kubebuilder:validation:MaxItems:=64
// +listType=set
// +optional
Tags []NeutronTag `json:"tags,omitempty"`
// ipVersion is the IP version for the subnet.
// +required
// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="ipVersion is immutable"
IPVersion IPVersion `json:"ipVersion"`
// cidr is the address CIDR of the subnet. It must match the IP version specified in IPVersion.
// +required
// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="cidr is immutable"
CIDR CIDR `json:"cidr,omitempty"`
// allocationPools are IP Address pools that will be available for DHCP. IP
// addresses must be in CIDR.
// +kubebuilder:validation:MaxItems:=32
// +listType=atomic
// +optional
AllocationPools []AllocationPool `json:"allocationPools,omitempty"`
// gateway specifies the default gateway of the subnet. If not specified,
// neutron will add one automatically. To disable this behaviour, specify a
// gateway with a type of None.
// +optional
Gateway *SubnetGateway `json:"gateway,omitempty"`
// enableDHCP will either enable to disable the DHCP service.
// +optional
EnableDHCP *bool `json:"enableDHCP,omitempty"`
// dnsNameservers are the nameservers to be set via DHCP.
// +kubebuilder:validation:MaxItems:=16
// +listType=set
// +optional
DNSNameservers []IPvAny `json:"dnsNameservers,omitempty"`
// dnsPublishFixedIP will either enable or disable the publication of
// fixed IPs to the DNS. Defaults to false.
// +optional
// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="dnsPublishFixedIP is immutable"
DNSPublishFixedIP *bool `json:"dnsPublishFixedIP,omitempty"`
// hostRoutes are any static host routes to be set via DHCP.
// +kubebuilder:validation:MaxItems:=256
// +listType=atomic
// +optional
HostRoutes []HostRoute `json:"hostRoutes,omitempty"`
// ipv6 contains IPv6-specific options. It may only be set if IPVersion is 6.
// +optional
// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="ipv6 is immutable"
IPv6 *IPv6Options `json:"ipv6,omitempty"`
// routerRef specifies a router to attach the subnet to
// +optional
// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="routerRef is immutable"
RouterRef *KubernetesNameRef `json:"routerRef,omitempty"`
// projectRef is a reference to the ORC Project this resource is associated with.
// Typically, only used by admin.
// +optional
// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="projectRef is immutable"
ProjectRef *KubernetesNameRef `json:"projectRef,omitempty"`
// TODO: Support service types
// TODO: Support subnet pools
}
type SubnetResourceStatus struct {
// name is the human-readable name of the subnet. Might not be unique.
// +kubebuilder:validation:MaxLength=1024
// +optional
Name string `json:"name,omitempty"`
// description is a human-readable description for the resource.
// +kubebuilder:validation:MaxLength=1024
// +optional
Description string `json:"description,omitempty"`
// ipVersion specifies IP version, either `4' or `6'.
// +optional
IPVersion *int32 `json:"ipVersion,omitempty"`
// cidr representing IP range for this subnet, based on IP version.
// +kubebuilder:validation:MaxLength=1024
// +optional
CIDR string `json:"cidr,omitempty"`
// gatewayIP is the default gateway used by devices in this subnet, if any.
// +kubebuilder:validation:MaxLength=1024
// +optional
GatewayIP string `json:"gatewayIP,omitempty"`
// dnsNameservers is a list of name servers used by hosts in this subnet.
// +kubebuilder:validation:MaxItems:=16
// +kubebuilder:validation:items:MaxLength=1024
// +listType=atomic
// +optional
DNSNameservers []string `json:"dnsNameservers,omitempty"`
// dnsPublishFixedIP specifies whether the fixed IP addresses are published to the DNS.
// +optional
DNSPublishFixedIP *bool `json:"dnsPublishFixedIP,omitempty"`
// allocationPools is a list of sub-ranges within CIDR available for dynamic
// allocation to ports.
// +kubebuilder:validation:MaxItems:=32
// +listType=atomic
// +optional
AllocationPools []AllocationPoolStatus `json:"allocationPools,omitempty"`
// hostRoutes is a list of routes that should be used by devices with IPs
// from this subnet (not including local subnet route).
// +kubebuilder:validation:MaxItems:=256
// +listType=atomic
// +optional
HostRoutes []HostRouteStatus `json:"hostRoutes,omitempty"`
// enableDHCP specifies whether DHCP is enabled for this subnet or not.
// +optional
EnableDHCP *bool `json:"enableDHCP,omitempty"`
// networkID is the ID of the network to which the subnet belongs.
// +kubebuilder:validation:MaxLength=1024
// +optional
NetworkID string `json:"networkID,omitempty"`
// projectID is the project owner of the subnet.
// +kubebuilder:validation:MaxLength=1024
// +optional
ProjectID string `json:"projectID,omitempty"`
// ipv6AddressMode specifies mechanisms for assigning IPv6 IP addresses.
// +kubebuilder:validation:MaxLength=1024
// +optional
IPv6AddressMode string `json:"ipv6AddressMode,omitempty"`
// ipv6RAMode is the IPv6 router advertisement mode. It specifies
// whether the networking service should transmit ICMPv6 packets.
// +kubebuilder:validation:MaxLength=1024
// +optional
IPv6RAMode string `json:"ipv6RAMode,omitempty"`
// subnetPoolID is the id of the subnet pool associated with the subnet.
// +kubebuilder:validation:MaxLength=1024
// +optional
SubnetPoolID string `json:"subnetPoolID,omitempty"`
// tags optionally set via extensions/attributestags
// +kubebuilder:validation:MaxItems:=64
// +kubebuilder:validation:items:MaxLength=1024
// +listType=atomic
// +optional
Tags []string `json:"tags,omitempty"`
NeutronStatusMetadata `json:",inline"`
}
// +kubebuilder:validation:Enum:=slaac;dhcpv6-stateful;dhcpv6-stateless
type IPv6AddressMode string
const (
IPv6AddressModeSLAAC = "slaac"
IPv6AddressModeDHCPv6Stateful = "dhcpv6-stateful"
IPv6AddressModeDHCPv6Stateless = "dhcpv6-stateless"
)
// +kubebuilder:validation:Enum:=slaac;dhcpv6-stateful;dhcpv6-stateless
type IPv6RAMode string
const (
IPv6RAModeSLAAC = "slaac"
IPv6RAModeDHCPv6Stateful = "dhcpv6-stateful"
IPv6RAModeDHCPv6Stateless = "dhcpv6-stateless"
)
// +kubebuilder:validation:MinProperties:=1
type IPv6Options struct {
// addressMode specifies mechanisms for assigning IPv6 IP addresses.
// +optional
AddressMode *IPv6AddressMode `json:"addressMode,omitempty"`
// raMode specifies the IPv6 router advertisement mode. It specifies whether
// the networking service should transmit ICMPv6 packets.
// +optional
RAMode *IPv6RAMode `json:"raMode,omitempty"`
}
type SubnetGatewayType string
const (
SubnetGatewayTypeNone = "None"
SubnetGatewayTypeAutomatic = "Automatic"
SubnetGatewayTypeIP = "IP"
)
type SubnetGateway struct {
// type specifies how the default gateway will be created. `Automatic`
// specifies that neutron will automatically add a default gateway. This is
// also the default if no Gateway is specified. `None` specifies that the
// subnet will not have a default gateway. `IP` specifies that the subnet
// will use a specific address as the default gateway, which must be
// specified in `IP`.
// +kubebuilder:validation:Enum:=None;Automatic;IP
// +required
Type SubnetGatewayType `json:"type,omitempty"`
// ip is the IP address of the default gateway, which must be specified if
// Type is `IP`. It must be a valid IP address, either IPv4 or IPv6,
// matching the IPVersion in SubnetResourceSpec.
// +optional
IP *IPvAny `json:"ip,omitempty"`
}
type AllocationPool struct {
// start is the first IP address in the allocation pool.
// +required
Start IPvAny `json:"start,omitempty"`
// end is the last IP address in the allocation pool.
// +required
End IPvAny `json:"end,omitempty"`
}
type AllocationPoolStatus struct {
// start is the first IP address in the allocation pool.
// +kubebuilder:validation:MaxLength=1024
// +optional
Start string `json:"start,omitempty"`
// end is the last IP address in the allocation pool.
// +kubebuilder:validation:MaxLength=1024
// +optional
End string `json:"end,omitempty"`
}
type HostRoute struct {
// destination for the additional route.
// +required
Destination CIDR `json:"destination,omitempty"`
// nextHop for the additional route.
// +required
NextHop IPvAny `json:"nextHop,omitempty"`
}
type HostRouteStatus struct {
// destination for the additional route.
// +kubebuilder:validation:MaxLength=1024
// +optional
Destination string `json:"destination,omitempty"`
// nextHop for the additional route.
// +kubebuilder:validation:MaxLength=1024
// +optional
NextHop string `json:"nextHop,omitempty"`
}

View File

@@ -0,0 +1,227 @@
/*
Copyright 2025 The ORC Authors.
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 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
// VolumeResourceSpec contains the desired state of the resource.
type VolumeResourceSpec struct {
// name will be the name of the created resource. If not specified, the
// name of the ORC object will be used.
// +optional
Name *OpenStackName `json:"name,omitempty"`
// description is a human-readable description for the resource.
// +kubebuilder:validation:MinLength:=1
// +kubebuilder:validation:MaxLength:=255
// +optional
Description *string `json:"description,omitempty"`
// size is the size of the volume, in gibibytes (GiB).
// +kubebuilder:validation:Minimum=1
// +required
// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="size is immutable"
Size int32 `json:"size,omitempty"`
// volumeTypeRef is a reference to the ORC VolumeType which this resource is associated with.
// +optional
// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="volumeTypeRef is immutable"
VolumeTypeRef *KubernetesNameRef `json:"volumeTypeRef,omitempty"`
// metadata key and value pairs to be associated with the volume.
// NOTE(mandre): gophercloud can't clear all metadata at the moment, we thus can't allow
// mutability for metadata as we might end up in a state that is not reconciliable
// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="metadata is immutable"
// +kubebuilder:validation:MaxItems:=64
// +listType=atomic
// +optional
Metadata []VolumeMetadata `json:"metadata,omitempty"`
}
// VolumeFilter defines an existing resource by its properties
// +kubebuilder:validation:MinProperties:=1
type VolumeFilter struct {
// name of the existing resource
// +optional
Name *OpenStackName `json:"name,omitempty"`
// description of the existing resource
// +kubebuilder:validation:MinLength:=1
// +kubebuilder:validation:MaxLength:=255
// +optional
Description *string `json:"description,omitempty"`
// size is the size of the volume in GiB.
// +kubebuilder:validation:Minimum=1
// +optional
Size *int32 `json:"size,omitempty"`
}
type VolumeAttachmentStatus struct {
// attachmentID represents the attachment UUID.
// +kubebuilder:validation:MaxLength=1024
// +optional
AttachmentID string `json:"attachmentID"`
// serverID is the UUID of the server to which the volume is attached.
// +kubebuilder:validation:MaxLength=1024
// +optional
ServerID string `json:"serverID"`
// device is the name of the device in the instance.
// +kubebuilder:validation:MaxLength=1024
// +optional
Device string `json:"device"`
// attachedAt shows the date and time when the resource was attached. The date and time stamp format is ISO 8601.
// +optional
AttachedAt *metav1.Time `json:"attachedAt"`
}
// VolumeResourceStatus represents the observed state of the resource.
type VolumeResourceStatus struct {
// name is a Human-readable name for the resource. Might not be unique.
// +kubebuilder:validation:MaxLength=1024
// +optional
Name string `json:"name,omitempty"`
// description is a human-readable description for the resource.
// +kubebuilder:validation:MaxLength=1024
// +optional
Description string `json:"description,omitempty"`
// size is the size of the volume in GiB.
// +optional
Size *int32 `json:"size,omitempty"`
// status represents the current status of the volume.
// +kubebuilder:validation:MaxLength=1024
// +optional
Status string `json:"status,omitempty"`
// availabilityZone is which availability zone the volume is in.
// +kubebuilder:validation:MaxLength=1024
// +optional
AvailabilityZone string `json:"availabilityZone,omitempty"`
// attachments is a list of attachments for the volume.
// +kubebuilder:validation:MaxItems:=32
// +listType=atomic
// +optional
Attachments []VolumeAttachmentStatus `json:"attachments"`
// volumeType is the name of associated the volume type.
// +kubebuilder:validation:MaxLength=1024
// +optional
VolumeType string `json:"volumeType,omitempty"`
// FIXME(mandre) Gophercloud doesn't return this field
// // volumeTypeID is the ID of the volumetype to which the resource is associated.
// // +kubebuilder:validation:MaxLength=1024
// // +optional
// VolumeTypeID string `json:"volumeTypeID,omitempty"`
// snapshotID is the ID of the snapshot from which the volume was created
// +kubebuilder:validation:MaxLength=1024
// +optional
SnapshotID string `json:"snapshotID,omitempty"`
// sourceVolID is the ID of another block storage volume from which the current volume was created
// +kubebuilder:validation:MaxLength=1024
// +optional
SourceVolID string `json:"sourceVolID,omitempty"`
// backupID is the ID of the backup from which the volume was restored
// +kubebuilder:validation:MaxLength=1024
// +optional
BackupID string `json:"backupID,omitempty"`
// metadata key and value pairs to be associated with the volume.
// +kubebuilder:validation:MaxItems:=64
// +listType=atomic
// +optional
Metadata []VolumeMetadataStatus `json:"metadata,omitempty"`
// userID is the ID of the user who created the volume.
// +kubebuilder:validation:MaxLength=1024
// +optional
UserID string `json:"userID,omitempty"`
// bootable indicates whether this is a bootable volume.
// +optional
Bootable *bool `json:"bootable,omitempty"`
// encrypted denotes if the volume is encrypted.
// +optional
Encrypted *bool `json:"encrypted,omitempty"`
// replicationStatus is the status of replication.
// +kubebuilder:validation:MaxLength=1024
// +optional
ReplicationStatus string `json:"replicationStatus,omitempty"`
// consistencyGroupID is the consistency group ID.
// +kubebuilder:validation:MaxLength=1024
// +optional
ConsistencyGroupID string `json:"consistencyGroupID,omitempty"`
// multiattach denotes if the volume is multi-attach capable.
// +optional
Multiattach *bool `json:"multiattach,omitempty"`
// host is the identifier of the host holding the volume.
// +kubebuilder:validation:MaxLength=1024
// +optional
Host string `json:"host,omitempty"`
// tenantID is the ID of the project that owns the volume.
// +kubebuilder:validation:MaxLength=1024
// +optional
TenantID string `json:"tenantID,omitempty"`
// createdAt shows the date and time when the resource was created. The date and time stamp format is ISO 8601
// +optional
CreatedAt *metav1.Time `json:"createdAt,omitempty"`
// updatedAt shows the date and time when the resource was updated. The date and time stamp format is ISO 8601
// +optional
UpdatedAt *metav1.Time `json:"updatedAt,omitempty"`
}
type VolumeMetadata struct {
// name is the name of the metadata
// +kubebuilder:validation:MaxLength:=255
// +required
Name string `json:"name"`
// value is the value of the metadata
// +kubebuilder:validation:MaxLength:=255
// +required
Value string `json:"value"`
}
type VolumeMetadataStatus struct {
// name is the name of the metadata
// +kubebuilder:validation:MaxLength:=255
// +optional
Name string `json:"name,omitempty"`
// value is the value of the metadata
// +kubebuilder:validation:MaxLength:=255
// +optional
Value string `json:"value,omitempty"`
}

View File

@@ -0,0 +1,106 @@
/*
Copyright 2025 The ORC Authors.
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
// VolumeTypeResourceSpec contains the desired state of the resource.
type VolumeTypeResourceSpec struct {
// name will be the name of the created resource. If not specified, the
// name of the ORC object will be used.
// +optional
Name *OpenStackName `json:"name,omitempty"`
// description is a human-readable description for the resource.
// +kubebuilder:validation:MinLength:=1
// +kubebuilder:validation:MaxLength:=255
// +optional
Description *string `json:"description,omitempty"`
// extraSpecs is a map of key-value pairs that define extra specifications for the volume type.
// +kubebuilder:validation:MaxItems:=64
// +listType=atomic
// +optional
ExtraSpecs []VolumeTypeExtraSpec `json:"extraSpecs,omitempty"`
// isPublic indicates whether the volume type is public.
// +optional
IsPublic *bool `json:"isPublic,omitempty"`
}
// VolumeTypeFilter defines an existing resource by its properties
// +kubebuilder:validation:MinProperties:=1
type VolumeTypeFilter struct {
// name of the existing resource
// +optional
Name *OpenStackName `json:"name,omitempty"`
// description of the existing resource
// +kubebuilder:validation:MinLength:=1
// +kubebuilder:validation:MaxLength:=255
// +optional
Description *string `json:"description,omitempty"`
// isPublic indicates whether the VolumeType is public.
// +optional
IsPublic *bool `json:"isPublic,omitempty"`
}
// VolumeTypeResourceStatus represents the observed state of the resource.
type VolumeTypeResourceStatus struct {
// name is a Human-readable name for the resource. Might not be unique.
// +kubebuilder:validation:MaxLength=1024
// +optional
Name string `json:"name,omitempty"`
// description is a human-readable description for the resource.
// +kubebuilder:validation:MaxLength=1024
// +optional
Description string `json:"description,omitempty"`
// extraSpecs is a map of key-value pairs that define extra specifications for the volume type.
// +kubebuilder:validation:MaxItems:=64
// +listType=atomic
// +optional
ExtraSpecs []VolumeTypeExtraSpecStatus `json:"extraSpecs"`
// isPublic indicates whether the VolumeType is public.
// +optional
IsPublic *bool `json:"isPublic"`
}
type VolumeTypeExtraSpec struct {
// name is the name of the extraspec
// +kubebuilder:validation:MaxLength:=255
// +required
Name string `json:"name"`
// value is the value of the extraspec
// +kubebuilder:validation:MaxLength:=255
// +required
Value string `json:"value"`
}
type VolumeTypeExtraSpecStatus struct {
// name is the name of the extraspec
// +kubebuilder:validation:MaxLength:=255
// +optional
Name string `json:"name,omitempty"`
// value is the value of the extraspec
// +kubebuilder:validation:MaxLength:=255
// +optional
Value string `json:"value,omitempty"`
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,177 @@
// Code generated by resource-generator. DO NOT EDIT.
/*
Copyright 2025 The ORC Authors.
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 (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
// FlavorImport specifies an existing resource which will be imported instead of
// creating a new one
// +kubebuilder:validation:MinProperties:=1
// +kubebuilder:validation:MaxProperties:=1
type FlavorImport struct {
// id contains the unique identifier of an existing OpenStack resource. Note
// that when specifying an import by ID, the resource MUST already exist.
// The ORC object will enter an error state if the resource does not exist.
// +optional
// +kubebuilder:validation:Format:=uuid
ID *string `json:"id,omitempty"`
// filter contains a resource query which is expected to return a single
// result. The controller will continue to retry if filter returns no
// results. If filter returns multiple results the controller will set an
// error state and will not continue to retry.
// +optional
Filter *FlavorFilter `json:"filter,omitempty"`
}
// FlavorSpec defines the desired state of an ORC object.
// +kubebuilder:validation:XValidation:rule="self.managementPolicy == 'managed' ? has(self.resource) : true",message="resource must be specified when policy is managed"
// +kubebuilder:validation:XValidation:rule="self.managementPolicy == 'managed' ? !has(self.__import__) : true",message="import may not be specified when policy is managed"
// +kubebuilder:validation:XValidation:rule="self.managementPolicy == 'unmanaged' ? !has(self.resource) : true",message="resource may not be specified when policy is unmanaged"
// +kubebuilder:validation:XValidation:rule="self.managementPolicy == 'unmanaged' ? has(self.__import__) : true",message="import must be specified when policy is unmanaged"
// +kubebuilder:validation:XValidation:rule="has(self.managedOptions) ? self.managementPolicy == 'managed' : true",message="managedOptions may only be provided when policy is managed"
type FlavorSpec struct {
// import refers to an existing OpenStack resource which will be imported instead of
// creating a new one.
// +optional
Import *FlavorImport `json:"import,omitempty"`
// resource specifies the desired state of the resource.
//
// resource may not be specified if the management policy is `unmanaged`.
//
// resource must be specified if the management policy is `managed`.
// +optional
Resource *FlavorResourceSpec `json:"resource,omitempty"`
// managementPolicy defines how ORC will treat the object. Valid values are
// `managed`: ORC will create, update, and delete the resource; `unmanaged`:
// ORC will import an existing resource, and will not apply updates to it or
// delete it.
// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="managementPolicy is immutable"
// +kubebuilder:default:=managed
// +optional
ManagementPolicy ManagementPolicy `json:"managementPolicy,omitempty"`
// managedOptions specifies options which may be applied to managed objects.
// +optional
ManagedOptions *ManagedOptions `json:"managedOptions,omitempty"`
// cloudCredentialsRef points to a secret containing OpenStack credentials
// +required
CloudCredentialsRef CloudCredentialsReference `json:"cloudCredentialsRef"`
}
// FlavorStatus defines the observed state of an ORC resource.
type FlavorStatus struct {
// conditions represents the observed status of the object.
// Known .status.conditions.type are: "Available", "Progressing"
//
// Available represents the availability of the OpenStack resource. If it is
// true then the resource is ready for use.
//
// Progressing indicates whether the controller is still attempting to
// reconcile the current state of the OpenStack resource to the desired
// state. Progressing will be False either because the desired state has
// been achieved, or because some terminal error prevents it from ever being
// achieved and the controller is no longer attempting to reconcile. If
// Progressing is True, an observer waiting on the resource should continue
// to wait.
//
// +kubebuilder:validation:MaxItems:=32
// +patchMergeKey=type
// +patchStrategy=merge
// +listType=map
// +listMapKey=type
// +optional
Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type"`
// id is the unique identifier of the OpenStack resource.
// +optional
ID *string `json:"id,omitempty"`
// resource contains the observed state of the OpenStack resource.
// +optional
Resource *FlavorResourceStatus `json:"resource,omitempty"`
}
var _ ObjectWithConditions = &Flavor{}
func (i *Flavor) GetConditions() []metav1.Condition {
return i.Status.Conditions
}
// +genclient
// +kubebuilder:object:root=true
// +kubebuilder:resource:categories=openstack
// +kubebuilder:subresource:status
// +kubebuilder:printcolumn:name="ID",type="string",JSONPath=".status.id",description="Resource ID"
// +kubebuilder:printcolumn:name="Available",type="string",JSONPath=".status.conditions[?(@.type=='Available')].status",description="Availability status of resource"
// +kubebuilder:printcolumn:name="Message",type="string",JSONPath=".status.conditions[?(@.type=='Progressing')].message",description="Message describing current progress status"
// Flavor is the Schema for an ORC resource.
type Flavor struct {
metav1.TypeMeta `json:",inline"`
// metadata contains the object metadata
// +optional
metav1.ObjectMeta `json:"metadata,omitempty"`
// spec specifies the desired state of the resource.
// +optional
Spec FlavorSpec `json:"spec,omitempty"`
// status defines the observed state of the resource.
// +optional
Status FlavorStatus `json:"status,omitempty"`
}
// +kubebuilder:object:root=true
// FlavorList contains a list of Flavor.
type FlavorList struct {
metav1.TypeMeta `json:",inline"`
// metadata contains the list metadata
// +optional
metav1.ListMeta `json:"metadata,omitempty"`
// items contains a list of Flavor.
// +required
Items []Flavor `json:"items"`
}
func (l *FlavorList) GetItems() []Flavor {
return l.Items
}
func init() {
SchemeBuilder.Register(&Flavor{}, &FlavorList{})
}
func (i *Flavor) GetCloudCredentialsRef() (*string, *CloudCredentialsReference) {
if i == nil {
return nil, nil
}
return &i.Namespace, &i.Spec.CloudCredentialsRef
}
var _ CloudCredentialsRefProvider = &Flavor{}

View File

@@ -0,0 +1,178 @@
// Code generated by resource-generator. DO NOT EDIT.
/*
Copyright 2025 The ORC Authors.
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 (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
// FloatingIPImport specifies an existing resource which will be imported instead of
// creating a new one
// +kubebuilder:validation:MinProperties:=1
// +kubebuilder:validation:MaxProperties:=1
type FloatingIPImport struct {
// id contains the unique identifier of an existing OpenStack resource. Note
// that when specifying an import by ID, the resource MUST already exist.
// The ORC object will enter an error state if the resource does not exist.
// +optional
// +kubebuilder:validation:Format:=uuid
ID *string `json:"id,omitempty"`
// filter contains a resource query which is expected to return a single
// result. The controller will continue to retry if filter returns no
// results. If filter returns multiple results the controller will set an
// error state and will not continue to retry.
// +optional
Filter *FloatingIPFilter `json:"filter,omitempty"`
}
// FloatingIPSpec defines the desired state of an ORC object.
// +kubebuilder:validation:XValidation:rule="self.managementPolicy == 'managed' ? has(self.resource) : true",message="resource must be specified when policy is managed"
// +kubebuilder:validation:XValidation:rule="self.managementPolicy == 'managed' ? !has(self.__import__) : true",message="import may not be specified when policy is managed"
// +kubebuilder:validation:XValidation:rule="self.managementPolicy == 'unmanaged' ? !has(self.resource) : true",message="resource may not be specified when policy is unmanaged"
// +kubebuilder:validation:XValidation:rule="self.managementPolicy == 'unmanaged' ? has(self.__import__) : true",message="import must be specified when policy is unmanaged"
// +kubebuilder:validation:XValidation:rule="has(self.managedOptions) ? self.managementPolicy == 'managed' : true",message="managedOptions may only be provided when policy is managed"
type FloatingIPSpec struct {
// import refers to an existing OpenStack resource which will be imported instead of
// creating a new one.
// +optional
Import *FloatingIPImport `json:"import,omitempty"`
// resource specifies the desired state of the resource.
//
// resource may not be specified if the management policy is `unmanaged`.
//
// resource must be specified if the management policy is `managed`.
// +optional
Resource *FloatingIPResourceSpec `json:"resource,omitempty"`
// managementPolicy defines how ORC will treat the object. Valid values are
// `managed`: ORC will create, update, and delete the resource; `unmanaged`:
// ORC will import an existing resource, and will not apply updates to it or
// delete it.
// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="managementPolicy is immutable"
// +kubebuilder:default:=managed
// +optional
ManagementPolicy ManagementPolicy `json:"managementPolicy,omitempty"`
// managedOptions specifies options which may be applied to managed objects.
// +optional
ManagedOptions *ManagedOptions `json:"managedOptions,omitempty"`
// cloudCredentialsRef points to a secret containing OpenStack credentials
// +required
CloudCredentialsRef CloudCredentialsReference `json:"cloudCredentialsRef"`
}
// FloatingIPStatus defines the observed state of an ORC resource.
type FloatingIPStatus struct {
// conditions represents the observed status of the object.
// Known .status.conditions.type are: "Available", "Progressing"
//
// Available represents the availability of the OpenStack resource. If it is
// true then the resource is ready for use.
//
// Progressing indicates whether the controller is still attempting to
// reconcile the current state of the OpenStack resource to the desired
// state. Progressing will be False either because the desired state has
// been achieved, or because some terminal error prevents it from ever being
// achieved and the controller is no longer attempting to reconcile. If
// Progressing is True, an observer waiting on the resource should continue
// to wait.
//
// +kubebuilder:validation:MaxItems:=32
// +patchMergeKey=type
// +patchStrategy=merge
// +listType=map
// +listMapKey=type
// +optional
Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type"`
// id is the unique identifier of the OpenStack resource.
// +optional
ID *string `json:"id,omitempty"`
// resource contains the observed state of the OpenStack resource.
// +optional
Resource *FloatingIPResourceStatus `json:"resource,omitempty"`
}
var _ ObjectWithConditions = &FloatingIP{}
func (i *FloatingIP) GetConditions() []metav1.Condition {
return i.Status.Conditions
}
// +genclient
// +kubebuilder:object:root=true
// +kubebuilder:resource:categories=openstack
// +kubebuilder:subresource:status
// +kubebuilder:printcolumn:name="ID",type="string",JSONPath=".status.id",description="Resource ID"
// +kubebuilder:printcolumn:name="Available",type="string",JSONPath=".status.conditions[?(@.type=='Available')].status",description="Availability status of resource"
// +kubebuilder:printcolumn:name="Address",type="string",JSONPath=".status.resource.floatingIP",description="Allocated IP address"
// +kubebuilder:printcolumn:name="Message",type="string",JSONPath=".status.conditions[?(@.type=='Progressing')].message",description="Message describing current progress status"
// FloatingIP is the Schema for an ORC resource.
type FloatingIP struct {
metav1.TypeMeta `json:",inline"`
// metadata contains the object metadata
// +optional
metav1.ObjectMeta `json:"metadata,omitempty"`
// spec specifies the desired state of the resource.
// +optional
Spec FloatingIPSpec `json:"spec,omitempty"`
// status defines the observed state of the resource.
// +optional
Status FloatingIPStatus `json:"status,omitempty"`
}
// +kubebuilder:object:root=true
// FloatingIPList contains a list of FloatingIP.
type FloatingIPList struct {
metav1.TypeMeta `json:",inline"`
// metadata contains the list metadata
// +optional
metav1.ListMeta `json:"metadata,omitempty"`
// items contains a list of FloatingIP.
// +required
Items []FloatingIP `json:"items"`
}
func (l *FloatingIPList) GetItems() []FloatingIP {
return l.Items
}
func init() {
SchemeBuilder.Register(&FloatingIP{}, &FloatingIPList{})
}
func (i *FloatingIP) GetCloudCredentialsRef() (*string, *CloudCredentialsReference) {
if i == nil {
return nil, nil
}
return &i.Namespace, &i.Spec.CloudCredentialsRef
}
var _ CloudCredentialsRefProvider = &FloatingIP{}

View File

@@ -0,0 +1,180 @@
// Code generated by resource-generator. DO NOT EDIT.
/*
Copyright 2025 The ORC Authors.
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 (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
// ImageImport specifies an existing resource which will be imported instead of
// creating a new one
// +kubebuilder:validation:MinProperties:=1
// +kubebuilder:validation:MaxProperties:=1
type ImageImport struct {
// id contains the unique identifier of an existing OpenStack resource. Note
// that when specifying an import by ID, the resource MUST already exist.
// The ORC object will enter an error state if the resource does not exist.
// +optional
// +kubebuilder:validation:Format:=uuid
ID *string `json:"id,omitempty"`
// filter contains a resource query which is expected to return a single
// result. The controller will continue to retry if filter returns no
// results. If filter returns multiple results the controller will set an
// error state and will not continue to retry.
// +optional
Filter *ImageFilter `json:"filter,omitempty"`
}
// ImageSpec defines the desired state of an ORC object.
// +kubebuilder:validation:XValidation:rule="self.managementPolicy == 'managed' ? has(self.resource) : true",message="resource must be specified when policy is managed"
// +kubebuilder:validation:XValidation:rule="self.managementPolicy == 'managed' ? !has(self.__import__) : true",message="import may not be specified when policy is managed"
// +kubebuilder:validation:XValidation:rule="self.managementPolicy == 'unmanaged' ? !has(self.resource) : true",message="resource may not be specified when policy is unmanaged"
// +kubebuilder:validation:XValidation:rule="self.managementPolicy == 'unmanaged' ? has(self.__import__) : true",message="import must be specified when policy is unmanaged"
// +kubebuilder:validation:XValidation:rule="has(self.managedOptions) ? self.managementPolicy == 'managed' : true",message="managedOptions may only be provided when policy is managed"
// +kubebuilder:validation:XValidation:rule="!has(self.__import__) ? has(self.resource.content) : true",message="resource content must be specified when not importing"
type ImageSpec struct {
// import refers to an existing OpenStack resource which will be imported instead of
// creating a new one.
// +optional
Import *ImageImport `json:"import,omitempty"`
// resource specifies the desired state of the resource.
//
// resource may not be specified if the management policy is `unmanaged`.
//
// resource must be specified if the management policy is `managed`.
// +optional
Resource *ImageResourceSpec `json:"resource,omitempty"`
// managementPolicy defines how ORC will treat the object. Valid values are
// `managed`: ORC will create, update, and delete the resource; `unmanaged`:
// ORC will import an existing resource, and will not apply updates to it or
// delete it.
// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="managementPolicy is immutable"
// +kubebuilder:default:=managed
// +optional
ManagementPolicy ManagementPolicy `json:"managementPolicy,omitempty"`
// managedOptions specifies options which may be applied to managed objects.
// +optional
ManagedOptions *ManagedOptions `json:"managedOptions,omitempty"`
// cloudCredentialsRef points to a secret containing OpenStack credentials
// +required
CloudCredentialsRef CloudCredentialsReference `json:"cloudCredentialsRef"`
}
// ImageStatus defines the observed state of an ORC resource.
type ImageStatus struct {
// conditions represents the observed status of the object.
// Known .status.conditions.type are: "Available", "Progressing"
//
// Available represents the availability of the OpenStack resource. If it is
// true then the resource is ready for use.
//
// Progressing indicates whether the controller is still attempting to
// reconcile the current state of the OpenStack resource to the desired
// state. Progressing will be False either because the desired state has
// been achieved, or because some terminal error prevents it from ever being
// achieved and the controller is no longer attempting to reconcile. If
// Progressing is True, an observer waiting on the resource should continue
// to wait.
//
// +kubebuilder:validation:MaxItems:=32
// +patchMergeKey=type
// +patchStrategy=merge
// +listType=map
// +listMapKey=type
// +optional
Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type"`
// id is the unique identifier of the OpenStack resource.
// +optional
ID *string `json:"id,omitempty"`
// resource contains the observed state of the OpenStack resource.
// +optional
Resource *ImageResourceStatus `json:"resource,omitempty"`
ImageStatusExtra `json:",inline"`
}
var _ ObjectWithConditions = &Image{}
func (i *Image) GetConditions() []metav1.Condition {
return i.Status.Conditions
}
// +genclient
// +kubebuilder:object:root=true
// +kubebuilder:resource:categories=openstack
// +kubebuilder:subresource:status
// +kubebuilder:printcolumn:name="ID",type="string",JSONPath=".status.id",description="Resource ID"
// +kubebuilder:printcolumn:name="Available",type="string",JSONPath=".status.conditions[?(@.type=='Available')].status",description="Availability status of resource"
// +kubebuilder:printcolumn:name="Message",type="string",JSONPath=".status.conditions[?(@.type=='Progressing')].message",description="Message describing current progress status"
// Image is the Schema for an ORC resource.
type Image struct {
metav1.TypeMeta `json:",inline"`
// metadata contains the object metadata
// +optional
metav1.ObjectMeta `json:"metadata,omitempty"`
// spec specifies the desired state of the resource.
// +optional
Spec ImageSpec `json:"spec,omitempty"`
// status defines the observed state of the resource.
// +optional
Status ImageStatus `json:"status,omitempty"`
}
// +kubebuilder:object:root=true
// ImageList contains a list of Image.
type ImageList struct {
metav1.TypeMeta `json:",inline"`
// metadata contains the list metadata
// +optional
metav1.ListMeta `json:"metadata,omitempty"`
// items contains a list of Image.
// +required
Items []Image `json:"items"`
}
func (l *ImageList) GetItems() []Image {
return l.Items
}
func init() {
SchemeBuilder.Register(&Image{}, &ImageList{})
}
func (i *Image) GetCloudCredentialsRef() (*string, *CloudCredentialsReference) {
if i == nil {
return nil, nil
}
return &i.Namespace, &i.Spec.CloudCredentialsRef
}
var _ CloudCredentialsRefProvider = &Image{}

View File

@@ -0,0 +1,177 @@
// Code generated by resource-generator. DO NOT EDIT.
/*
Copyright 2025 The ORC Authors.
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 (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
// NetworkImport specifies an existing resource which will be imported instead of
// creating a new one
// +kubebuilder:validation:MinProperties:=1
// +kubebuilder:validation:MaxProperties:=1
type NetworkImport struct {
// id contains the unique identifier of an existing OpenStack resource. Note
// that when specifying an import by ID, the resource MUST already exist.
// The ORC object will enter an error state if the resource does not exist.
// +optional
// +kubebuilder:validation:Format:=uuid
ID *string `json:"id,omitempty"`
// filter contains a resource query which is expected to return a single
// result. The controller will continue to retry if filter returns no
// results. If filter returns multiple results the controller will set an
// error state and will not continue to retry.
// +optional
Filter *NetworkFilter `json:"filter,omitempty"`
}
// NetworkSpec defines the desired state of an ORC object.
// +kubebuilder:validation:XValidation:rule="self.managementPolicy == 'managed' ? has(self.resource) : true",message="resource must be specified when policy is managed"
// +kubebuilder:validation:XValidation:rule="self.managementPolicy == 'managed' ? !has(self.__import__) : true",message="import may not be specified when policy is managed"
// +kubebuilder:validation:XValidation:rule="self.managementPolicy == 'unmanaged' ? !has(self.resource) : true",message="resource may not be specified when policy is unmanaged"
// +kubebuilder:validation:XValidation:rule="self.managementPolicy == 'unmanaged' ? has(self.__import__) : true",message="import must be specified when policy is unmanaged"
// +kubebuilder:validation:XValidation:rule="has(self.managedOptions) ? self.managementPolicy == 'managed' : true",message="managedOptions may only be provided when policy is managed"
type NetworkSpec struct {
// import refers to an existing OpenStack resource which will be imported instead of
// creating a new one.
// +optional
Import *NetworkImport `json:"import,omitempty"`
// resource specifies the desired state of the resource.
//
// resource may not be specified if the management policy is `unmanaged`.
//
// resource must be specified if the management policy is `managed`.
// +optional
Resource *NetworkResourceSpec `json:"resource,omitempty"`
// managementPolicy defines how ORC will treat the object. Valid values are
// `managed`: ORC will create, update, and delete the resource; `unmanaged`:
// ORC will import an existing resource, and will not apply updates to it or
// delete it.
// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="managementPolicy is immutable"
// +kubebuilder:default:=managed
// +optional
ManagementPolicy ManagementPolicy `json:"managementPolicy,omitempty"`
// managedOptions specifies options which may be applied to managed objects.
// +optional
ManagedOptions *ManagedOptions `json:"managedOptions,omitempty"`
// cloudCredentialsRef points to a secret containing OpenStack credentials
// +required
CloudCredentialsRef CloudCredentialsReference `json:"cloudCredentialsRef"`
}
// NetworkStatus defines the observed state of an ORC resource.
type NetworkStatus struct {
// conditions represents the observed status of the object.
// Known .status.conditions.type are: "Available", "Progressing"
//
// Available represents the availability of the OpenStack resource. If it is
// true then the resource is ready for use.
//
// Progressing indicates whether the controller is still attempting to
// reconcile the current state of the OpenStack resource to the desired
// state. Progressing will be False either because the desired state has
// been achieved, or because some terminal error prevents it from ever being
// achieved and the controller is no longer attempting to reconcile. If
// Progressing is True, an observer waiting on the resource should continue
// to wait.
//
// +kubebuilder:validation:MaxItems:=32
// +patchMergeKey=type
// +patchStrategy=merge
// +listType=map
// +listMapKey=type
// +optional
Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type"`
// id is the unique identifier of the OpenStack resource.
// +optional
ID *string `json:"id,omitempty"`
// resource contains the observed state of the OpenStack resource.
// +optional
Resource *NetworkResourceStatus `json:"resource,omitempty"`
}
var _ ObjectWithConditions = &Network{}
func (i *Network) GetConditions() []metav1.Condition {
return i.Status.Conditions
}
// +genclient
// +kubebuilder:object:root=true
// +kubebuilder:resource:categories=openstack
// +kubebuilder:subresource:status
// +kubebuilder:printcolumn:name="ID",type="string",JSONPath=".status.id",description="Resource ID"
// +kubebuilder:printcolumn:name="Available",type="string",JSONPath=".status.conditions[?(@.type=='Available')].status",description="Availability status of resource"
// +kubebuilder:printcolumn:name="Message",type="string",JSONPath=".status.conditions[?(@.type=='Progressing')].message",description="Message describing current progress status"
// Network is the Schema for an ORC resource.
type Network struct {
metav1.TypeMeta `json:",inline"`
// metadata contains the object metadata
// +optional
metav1.ObjectMeta `json:"metadata,omitempty"`
// spec specifies the desired state of the resource.
// +optional
Spec NetworkSpec `json:"spec,omitempty"`
// status defines the observed state of the resource.
// +optional
Status NetworkStatus `json:"status,omitempty"`
}
// +kubebuilder:object:root=true
// NetworkList contains a list of Network.
type NetworkList struct {
metav1.TypeMeta `json:",inline"`
// metadata contains the list metadata
// +optional
metav1.ListMeta `json:"metadata,omitempty"`
// items contains a list of Network.
// +required
Items []Network `json:"items"`
}
func (l *NetworkList) GetItems() []Network {
return l.Items
}
func init() {
SchemeBuilder.Register(&Network{}, &NetworkList{})
}
func (i *Network) GetCloudCredentialsRef() (*string, *CloudCredentialsReference) {
if i == nil {
return nil, nil
}
return &i.Namespace, &i.Spec.CloudCredentialsRef
}
var _ CloudCredentialsRefProvider = &Network{}

View File

@@ -0,0 +1,178 @@
// Code generated by resource-generator. DO NOT EDIT.
/*
Copyright 2025 The ORC Authors.
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 (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
// PortImport specifies an existing resource which will be imported instead of
// creating a new one
// +kubebuilder:validation:MinProperties:=1
// +kubebuilder:validation:MaxProperties:=1
type PortImport struct {
// id contains the unique identifier of an existing OpenStack resource. Note
// that when specifying an import by ID, the resource MUST already exist.
// The ORC object will enter an error state if the resource does not exist.
// +optional
// +kubebuilder:validation:Format:=uuid
ID *string `json:"id,omitempty"`
// filter contains a resource query which is expected to return a single
// result. The controller will continue to retry if filter returns no
// results. If filter returns multiple results the controller will set an
// error state and will not continue to retry.
// +optional
Filter *PortFilter `json:"filter,omitempty"`
}
// PortSpec defines the desired state of an ORC object.
// +kubebuilder:validation:XValidation:rule="self.managementPolicy == 'managed' ? has(self.resource) : true",message="resource must be specified when policy is managed"
// +kubebuilder:validation:XValidation:rule="self.managementPolicy == 'managed' ? !has(self.__import__) : true",message="import may not be specified when policy is managed"
// +kubebuilder:validation:XValidation:rule="self.managementPolicy == 'unmanaged' ? !has(self.resource) : true",message="resource may not be specified when policy is unmanaged"
// +kubebuilder:validation:XValidation:rule="self.managementPolicy == 'unmanaged' ? has(self.__import__) : true",message="import must be specified when policy is unmanaged"
// +kubebuilder:validation:XValidation:rule="has(self.managedOptions) ? self.managementPolicy == 'managed' : true",message="managedOptions may only be provided when policy is managed"
type PortSpec struct {
// import refers to an existing OpenStack resource which will be imported instead of
// creating a new one.
// +optional
Import *PortImport `json:"import,omitempty"`
// resource specifies the desired state of the resource.
//
// resource may not be specified if the management policy is `unmanaged`.
//
// resource must be specified if the management policy is `managed`.
// +optional
Resource *PortResourceSpec `json:"resource,omitempty"`
// managementPolicy defines how ORC will treat the object. Valid values are
// `managed`: ORC will create, update, and delete the resource; `unmanaged`:
// ORC will import an existing resource, and will not apply updates to it or
// delete it.
// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="managementPolicy is immutable"
// +kubebuilder:default:=managed
// +optional
ManagementPolicy ManagementPolicy `json:"managementPolicy,omitempty"`
// managedOptions specifies options which may be applied to managed objects.
// +optional
ManagedOptions *ManagedOptions `json:"managedOptions,omitempty"`
// cloudCredentialsRef points to a secret containing OpenStack credentials
// +required
CloudCredentialsRef CloudCredentialsReference `json:"cloudCredentialsRef"`
}
// PortStatus defines the observed state of an ORC resource.
type PortStatus struct {
// conditions represents the observed status of the object.
// Known .status.conditions.type are: "Available", "Progressing"
//
// Available represents the availability of the OpenStack resource. If it is
// true then the resource is ready for use.
//
// Progressing indicates whether the controller is still attempting to
// reconcile the current state of the OpenStack resource to the desired
// state. Progressing will be False either because the desired state has
// been achieved, or because some terminal error prevents it from ever being
// achieved and the controller is no longer attempting to reconcile. If
// Progressing is True, an observer waiting on the resource should continue
// to wait.
//
// +kubebuilder:validation:MaxItems:=32
// +patchMergeKey=type
// +patchStrategy=merge
// +listType=map
// +listMapKey=type
// +optional
Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type"`
// id is the unique identifier of the OpenStack resource.
// +optional
ID *string `json:"id,omitempty"`
// resource contains the observed state of the OpenStack resource.
// +optional
Resource *PortResourceStatus `json:"resource,omitempty"`
}
var _ ObjectWithConditions = &Port{}
func (i *Port) GetConditions() []metav1.Condition {
return i.Status.Conditions
}
// +genclient
// +kubebuilder:object:root=true
// +kubebuilder:resource:categories=openstack
// +kubebuilder:subresource:status
// +kubebuilder:printcolumn:name="ID",type="string",JSONPath=".status.id",description="Resource ID"
// +kubebuilder:printcolumn:name="Available",type="string",JSONPath=".status.conditions[?(@.type=='Available')].status",description="Availability status of resource"
// +kubebuilder:printcolumn:name="Addresses",type="string",JSONPath=".status.resource.fixedIPs[*].ip",description="Allocated IP addresses"
// +kubebuilder:printcolumn:name="Message",type="string",JSONPath=".status.conditions[?(@.type=='Progressing')].message",description="Message describing current progress status"
// Port is the Schema for an ORC resource.
type Port struct {
metav1.TypeMeta `json:",inline"`
// metadata contains the object metadata
// +optional
metav1.ObjectMeta `json:"metadata,omitempty"`
// spec specifies the desired state of the resource.
// +optional
Spec PortSpec `json:"spec,omitempty"`
// status defines the observed state of the resource.
// +optional
Status PortStatus `json:"status,omitempty"`
}
// +kubebuilder:object:root=true
// PortList contains a list of Port.
type PortList struct {
metav1.TypeMeta `json:",inline"`
// metadata contains the list metadata
// +optional
metav1.ListMeta `json:"metadata,omitempty"`
// items contains a list of Port.
// +required
Items []Port `json:"items"`
}
func (l *PortList) GetItems() []Port {
return l.Items
}
func init() {
SchemeBuilder.Register(&Port{}, &PortList{})
}
func (i *Port) GetCloudCredentialsRef() (*string, *CloudCredentialsReference) {
if i == nil {
return nil, nil
}
return &i.Namespace, &i.Spec.CloudCredentialsRef
}
var _ CloudCredentialsRefProvider = &Port{}

View File

@@ -0,0 +1,177 @@
// Code generated by resource-generator. DO NOT EDIT.
/*
Copyright 2025 The ORC Authors.
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 (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
// ProjectImport specifies an existing resource which will be imported instead of
// creating a new one
// +kubebuilder:validation:MinProperties:=1
// +kubebuilder:validation:MaxProperties:=1
type ProjectImport struct {
// id contains the unique identifier of an existing OpenStack resource. Note
// that when specifying an import by ID, the resource MUST already exist.
// The ORC object will enter an error state if the resource does not exist.
// +optional
// +kubebuilder:validation:Format:=uuid
ID *string `json:"id,omitempty"`
// filter contains a resource query which is expected to return a single
// result. The controller will continue to retry if filter returns no
// results. If filter returns multiple results the controller will set an
// error state and will not continue to retry.
// +optional
Filter *ProjectFilter `json:"filter,omitempty"`
}
// ProjectSpec defines the desired state of an ORC object.
// +kubebuilder:validation:XValidation:rule="self.managementPolicy == 'managed' ? has(self.resource) : true",message="resource must be specified when policy is managed"
// +kubebuilder:validation:XValidation:rule="self.managementPolicy == 'managed' ? !has(self.__import__) : true",message="import may not be specified when policy is managed"
// +kubebuilder:validation:XValidation:rule="self.managementPolicy == 'unmanaged' ? !has(self.resource) : true",message="resource may not be specified when policy is unmanaged"
// +kubebuilder:validation:XValidation:rule="self.managementPolicy == 'unmanaged' ? has(self.__import__) : true",message="import must be specified when policy is unmanaged"
// +kubebuilder:validation:XValidation:rule="has(self.managedOptions) ? self.managementPolicy == 'managed' : true",message="managedOptions may only be provided when policy is managed"
type ProjectSpec struct {
// import refers to an existing OpenStack resource which will be imported instead of
// creating a new one.
// +optional
Import *ProjectImport `json:"import,omitempty"`
// resource specifies the desired state of the resource.
//
// resource may not be specified if the management policy is `unmanaged`.
//
// resource must be specified if the management policy is `managed`.
// +optional
Resource *ProjectResourceSpec `json:"resource,omitempty"`
// managementPolicy defines how ORC will treat the object. Valid values are
// `managed`: ORC will create, update, and delete the resource; `unmanaged`:
// ORC will import an existing resource, and will not apply updates to it or
// delete it.
// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="managementPolicy is immutable"
// +kubebuilder:default:=managed
// +optional
ManagementPolicy ManagementPolicy `json:"managementPolicy,omitempty"`
// managedOptions specifies options which may be applied to managed objects.
// +optional
ManagedOptions *ManagedOptions `json:"managedOptions,omitempty"`
// cloudCredentialsRef points to a secret containing OpenStack credentials
// +required
CloudCredentialsRef CloudCredentialsReference `json:"cloudCredentialsRef"`
}
// ProjectStatus defines the observed state of an ORC resource.
type ProjectStatus struct {
// conditions represents the observed status of the object.
// Known .status.conditions.type are: "Available", "Progressing"
//
// Available represents the availability of the OpenStack resource. If it is
// true then the resource is ready for use.
//
// Progressing indicates whether the controller is still attempting to
// reconcile the current state of the OpenStack resource to the desired
// state. Progressing will be False either because the desired state has
// been achieved, or because some terminal error prevents it from ever being
// achieved and the controller is no longer attempting to reconcile. If
// Progressing is True, an observer waiting on the resource should continue
// to wait.
//
// +kubebuilder:validation:MaxItems:=32
// +patchMergeKey=type
// +patchStrategy=merge
// +listType=map
// +listMapKey=type
// +optional
Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type"`
// id is the unique identifier of the OpenStack resource.
// +optional
ID *string `json:"id,omitempty"`
// resource contains the observed state of the OpenStack resource.
// +optional
Resource *ProjectResourceStatus `json:"resource,omitempty"`
}
var _ ObjectWithConditions = &Project{}
func (i *Project) GetConditions() []metav1.Condition {
return i.Status.Conditions
}
// +genclient
// +kubebuilder:object:root=true
// +kubebuilder:resource:categories=openstack
// +kubebuilder:subresource:status
// +kubebuilder:printcolumn:name="ID",type="string",JSONPath=".status.id",description="Resource ID"
// +kubebuilder:printcolumn:name="Available",type="string",JSONPath=".status.conditions[?(@.type=='Available')].status",description="Availability status of resource"
// +kubebuilder:printcolumn:name="Message",type="string",JSONPath=".status.conditions[?(@.type=='Progressing')].message",description="Message describing current progress status"
// Project is the Schema for an ORC resource.
type Project struct {
metav1.TypeMeta `json:",inline"`
// metadata contains the object metadata
// +optional
metav1.ObjectMeta `json:"metadata,omitempty"`
// spec specifies the desired state of the resource.
// +optional
Spec ProjectSpec `json:"spec,omitempty"`
// status defines the observed state of the resource.
// +optional
Status ProjectStatus `json:"status,omitempty"`
}
// +kubebuilder:object:root=true
// ProjectList contains a list of Project.
type ProjectList struct {
metav1.TypeMeta `json:",inline"`
// metadata contains the list metadata
// +optional
metav1.ListMeta `json:"metadata,omitempty"`
// items contains a list of Project.
// +required
Items []Project `json:"items"`
}
func (l *ProjectList) GetItems() []Project {
return l.Items
}
func init() {
SchemeBuilder.Register(&Project{}, &ProjectList{})
}
func (i *Project) GetCloudCredentialsRef() (*string, *CloudCredentialsReference) {
if i == nil {
return nil, nil
}
return &i.Namespace, &i.Spec.CloudCredentialsRef
}
var _ CloudCredentialsRefProvider = &Project{}

View File

@@ -0,0 +1,177 @@
// Code generated by resource-generator. DO NOT EDIT.
/*
Copyright 2025 The ORC Authors.
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 (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
// RouterImport specifies an existing resource which will be imported instead of
// creating a new one
// +kubebuilder:validation:MinProperties:=1
// +kubebuilder:validation:MaxProperties:=1
type RouterImport struct {
// id contains the unique identifier of an existing OpenStack resource. Note
// that when specifying an import by ID, the resource MUST already exist.
// The ORC object will enter an error state if the resource does not exist.
// +optional
// +kubebuilder:validation:Format:=uuid
ID *string `json:"id,omitempty"`
// filter contains a resource query which is expected to return a single
// result. The controller will continue to retry if filter returns no
// results. If filter returns multiple results the controller will set an
// error state and will not continue to retry.
// +optional
Filter *RouterFilter `json:"filter,omitempty"`
}
// RouterSpec defines the desired state of an ORC object.
// +kubebuilder:validation:XValidation:rule="self.managementPolicy == 'managed' ? has(self.resource) : true",message="resource must be specified when policy is managed"
// +kubebuilder:validation:XValidation:rule="self.managementPolicy == 'managed' ? !has(self.__import__) : true",message="import may not be specified when policy is managed"
// +kubebuilder:validation:XValidation:rule="self.managementPolicy == 'unmanaged' ? !has(self.resource) : true",message="resource may not be specified when policy is unmanaged"
// +kubebuilder:validation:XValidation:rule="self.managementPolicy == 'unmanaged' ? has(self.__import__) : true",message="import must be specified when policy is unmanaged"
// +kubebuilder:validation:XValidation:rule="has(self.managedOptions) ? self.managementPolicy == 'managed' : true",message="managedOptions may only be provided when policy is managed"
type RouterSpec struct {
// import refers to an existing OpenStack resource which will be imported instead of
// creating a new one.
// +optional
Import *RouterImport `json:"import,omitempty"`
// resource specifies the desired state of the resource.
//
// resource may not be specified if the management policy is `unmanaged`.
//
// resource must be specified if the management policy is `managed`.
// +optional
Resource *RouterResourceSpec `json:"resource,omitempty"`
// managementPolicy defines how ORC will treat the object. Valid values are
// `managed`: ORC will create, update, and delete the resource; `unmanaged`:
// ORC will import an existing resource, and will not apply updates to it or
// delete it.
// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="managementPolicy is immutable"
// +kubebuilder:default:=managed
// +optional
ManagementPolicy ManagementPolicy `json:"managementPolicy,omitempty"`
// managedOptions specifies options which may be applied to managed objects.
// +optional
ManagedOptions *ManagedOptions `json:"managedOptions,omitempty"`
// cloudCredentialsRef points to a secret containing OpenStack credentials
// +required
CloudCredentialsRef CloudCredentialsReference `json:"cloudCredentialsRef"`
}
// RouterStatus defines the observed state of an ORC resource.
type RouterStatus struct {
// conditions represents the observed status of the object.
// Known .status.conditions.type are: "Available", "Progressing"
//
// Available represents the availability of the OpenStack resource. If it is
// true then the resource is ready for use.
//
// Progressing indicates whether the controller is still attempting to
// reconcile the current state of the OpenStack resource to the desired
// state. Progressing will be False either because the desired state has
// been achieved, or because some terminal error prevents it from ever being
// achieved and the controller is no longer attempting to reconcile. If
// Progressing is True, an observer waiting on the resource should continue
// to wait.
//
// +kubebuilder:validation:MaxItems:=32
// +patchMergeKey=type
// +patchStrategy=merge
// +listType=map
// +listMapKey=type
// +optional
Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type"`
// id is the unique identifier of the OpenStack resource.
// +optional
ID *string `json:"id,omitempty"`
// resource contains the observed state of the OpenStack resource.
// +optional
Resource *RouterResourceStatus `json:"resource,omitempty"`
}
var _ ObjectWithConditions = &Router{}
func (i *Router) GetConditions() []metav1.Condition {
return i.Status.Conditions
}
// +genclient
// +kubebuilder:object:root=true
// +kubebuilder:resource:categories=openstack
// +kubebuilder:subresource:status
// +kubebuilder:printcolumn:name="ID",type="string",JSONPath=".status.id",description="Resource ID"
// +kubebuilder:printcolumn:name="Available",type="string",JSONPath=".status.conditions[?(@.type=='Available')].status",description="Availability status of resource"
// +kubebuilder:printcolumn:name="Message",type="string",JSONPath=".status.conditions[?(@.type=='Progressing')].message",description="Message describing current progress status"
// Router is the Schema for an ORC resource.
type Router struct {
metav1.TypeMeta `json:",inline"`
// metadata contains the object metadata
// +optional
metav1.ObjectMeta `json:"metadata,omitempty"`
// spec specifies the desired state of the resource.
// +optional
Spec RouterSpec `json:"spec,omitempty"`
// status defines the observed state of the resource.
// +optional
Status RouterStatus `json:"status,omitempty"`
}
// +kubebuilder:object:root=true
// RouterList contains a list of Router.
type RouterList struct {
metav1.TypeMeta `json:",inline"`
// metadata contains the list metadata
// +optional
metav1.ListMeta `json:"metadata,omitempty"`
// items contains a list of Router.
// +required
Items []Router `json:"items"`
}
func (l *RouterList) GetItems() []Router {
return l.Items
}
func init() {
SchemeBuilder.Register(&Router{}, &RouterList{})
}
func (i *Router) GetCloudCredentialsRef() (*string, *CloudCredentialsReference) {
if i == nil {
return nil, nil
}
return &i.Namespace, &i.Spec.CloudCredentialsRef
}
var _ CloudCredentialsRefProvider = &Router{}

View File

@@ -0,0 +1,177 @@
// Code generated by resource-generator. DO NOT EDIT.
/*
Copyright 2025 The ORC Authors.
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 (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
// SecurityGroupImport specifies an existing resource which will be imported instead of
// creating a new one
// +kubebuilder:validation:MinProperties:=1
// +kubebuilder:validation:MaxProperties:=1
type SecurityGroupImport struct {
// id contains the unique identifier of an existing OpenStack resource. Note
// that when specifying an import by ID, the resource MUST already exist.
// The ORC object will enter an error state if the resource does not exist.
// +optional
// +kubebuilder:validation:Format:=uuid
ID *string `json:"id,omitempty"`
// filter contains a resource query which is expected to return a single
// result. The controller will continue to retry if filter returns no
// results. If filter returns multiple results the controller will set an
// error state and will not continue to retry.
// +optional
Filter *SecurityGroupFilter `json:"filter,omitempty"`
}
// SecurityGroupSpec defines the desired state of an ORC object.
// +kubebuilder:validation:XValidation:rule="self.managementPolicy == 'managed' ? has(self.resource) : true",message="resource must be specified when policy is managed"
// +kubebuilder:validation:XValidation:rule="self.managementPolicy == 'managed' ? !has(self.__import__) : true",message="import may not be specified when policy is managed"
// +kubebuilder:validation:XValidation:rule="self.managementPolicy == 'unmanaged' ? !has(self.resource) : true",message="resource may not be specified when policy is unmanaged"
// +kubebuilder:validation:XValidation:rule="self.managementPolicy == 'unmanaged' ? has(self.__import__) : true",message="import must be specified when policy is unmanaged"
// +kubebuilder:validation:XValidation:rule="has(self.managedOptions) ? self.managementPolicy == 'managed' : true",message="managedOptions may only be provided when policy is managed"
type SecurityGroupSpec struct {
// import refers to an existing OpenStack resource which will be imported instead of
// creating a new one.
// +optional
Import *SecurityGroupImport `json:"import,omitempty"`
// resource specifies the desired state of the resource.
//
// resource may not be specified if the management policy is `unmanaged`.
//
// resource must be specified if the management policy is `managed`.
// +optional
Resource *SecurityGroupResourceSpec `json:"resource,omitempty"`
// managementPolicy defines how ORC will treat the object. Valid values are
// `managed`: ORC will create, update, and delete the resource; `unmanaged`:
// ORC will import an existing resource, and will not apply updates to it or
// delete it.
// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="managementPolicy is immutable"
// +kubebuilder:default:=managed
// +optional
ManagementPolicy ManagementPolicy `json:"managementPolicy,omitempty"`
// managedOptions specifies options which may be applied to managed objects.
// +optional
ManagedOptions *ManagedOptions `json:"managedOptions,omitempty"`
// cloudCredentialsRef points to a secret containing OpenStack credentials
// +required
CloudCredentialsRef CloudCredentialsReference `json:"cloudCredentialsRef"`
}
// SecurityGroupStatus defines the observed state of an ORC resource.
type SecurityGroupStatus struct {
// conditions represents the observed status of the object.
// Known .status.conditions.type are: "Available", "Progressing"
//
// Available represents the availability of the OpenStack resource. If it is
// true then the resource is ready for use.
//
// Progressing indicates whether the controller is still attempting to
// reconcile the current state of the OpenStack resource to the desired
// state. Progressing will be False either because the desired state has
// been achieved, or because some terminal error prevents it from ever being
// achieved and the controller is no longer attempting to reconcile. If
// Progressing is True, an observer waiting on the resource should continue
// to wait.
//
// +kubebuilder:validation:MaxItems:=32
// +patchMergeKey=type
// +patchStrategy=merge
// +listType=map
// +listMapKey=type
// +optional
Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type"`
// id is the unique identifier of the OpenStack resource.
// +optional
ID *string `json:"id,omitempty"`
// resource contains the observed state of the OpenStack resource.
// +optional
Resource *SecurityGroupResourceStatus `json:"resource,omitempty"`
}
var _ ObjectWithConditions = &SecurityGroup{}
func (i *SecurityGroup) GetConditions() []metav1.Condition {
return i.Status.Conditions
}
// +genclient
// +kubebuilder:object:root=true
// +kubebuilder:resource:categories=openstack
// +kubebuilder:subresource:status
// +kubebuilder:printcolumn:name="ID",type="string",JSONPath=".status.id",description="Resource ID"
// +kubebuilder:printcolumn:name="Available",type="string",JSONPath=".status.conditions[?(@.type=='Available')].status",description="Availability status of resource"
// +kubebuilder:printcolumn:name="Message",type="string",JSONPath=".status.conditions[?(@.type=='Progressing')].message",description="Message describing current progress status"
// SecurityGroup is the Schema for an ORC resource.
type SecurityGroup struct {
metav1.TypeMeta `json:",inline"`
// metadata contains the object metadata
// +optional
metav1.ObjectMeta `json:"metadata,omitempty"`
// spec specifies the desired state of the resource.
// +optional
Spec SecurityGroupSpec `json:"spec,omitempty"`
// status defines the observed state of the resource.
// +optional
Status SecurityGroupStatus `json:"status,omitempty"`
}
// +kubebuilder:object:root=true
// SecurityGroupList contains a list of SecurityGroup.
type SecurityGroupList struct {
metav1.TypeMeta `json:",inline"`
// metadata contains the list metadata
// +optional
metav1.ListMeta `json:"metadata,omitempty"`
// items contains a list of SecurityGroup.
// +required
Items []SecurityGroup `json:"items"`
}
func (l *SecurityGroupList) GetItems() []SecurityGroup {
return l.Items
}
func init() {
SchemeBuilder.Register(&SecurityGroup{}, &SecurityGroupList{})
}
func (i *SecurityGroup) GetCloudCredentialsRef() (*string, *CloudCredentialsReference) {
if i == nil {
return nil, nil
}
return &i.Namespace, &i.Spec.CloudCredentialsRef
}
var _ CloudCredentialsRefProvider = &SecurityGroup{}

View File

@@ -0,0 +1,177 @@
// Code generated by resource-generator. DO NOT EDIT.
/*
Copyright 2025 The ORC Authors.
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 (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
// ServerImport specifies an existing resource which will be imported instead of
// creating a new one
// +kubebuilder:validation:MinProperties:=1
// +kubebuilder:validation:MaxProperties:=1
type ServerImport struct {
// id contains the unique identifier of an existing OpenStack resource. Note
// that when specifying an import by ID, the resource MUST already exist.
// The ORC object will enter an error state if the resource does not exist.
// +optional
// +kubebuilder:validation:Format:=uuid
ID *string `json:"id,omitempty"`
// filter contains a resource query which is expected to return a single
// result. The controller will continue to retry if filter returns no
// results. If filter returns multiple results the controller will set an
// error state and will not continue to retry.
// +optional
Filter *ServerFilter `json:"filter,omitempty"`
}
// ServerSpec defines the desired state of an ORC object.
// +kubebuilder:validation:XValidation:rule="self.managementPolicy == 'managed' ? has(self.resource) : true",message="resource must be specified when policy is managed"
// +kubebuilder:validation:XValidation:rule="self.managementPolicy == 'managed' ? !has(self.__import__) : true",message="import may not be specified when policy is managed"
// +kubebuilder:validation:XValidation:rule="self.managementPolicy == 'unmanaged' ? !has(self.resource) : true",message="resource may not be specified when policy is unmanaged"
// +kubebuilder:validation:XValidation:rule="self.managementPolicy == 'unmanaged' ? has(self.__import__) : true",message="import must be specified when policy is unmanaged"
// +kubebuilder:validation:XValidation:rule="has(self.managedOptions) ? self.managementPolicy == 'managed' : true",message="managedOptions may only be provided when policy is managed"
type ServerSpec struct {
// import refers to an existing OpenStack resource which will be imported instead of
// creating a new one.
// +optional
Import *ServerImport `json:"import,omitempty"`
// resource specifies the desired state of the resource.
//
// resource may not be specified if the management policy is `unmanaged`.
//
// resource must be specified if the management policy is `managed`.
// +optional
Resource *ServerResourceSpec `json:"resource,omitempty"`
// managementPolicy defines how ORC will treat the object. Valid values are
// `managed`: ORC will create, update, and delete the resource; `unmanaged`:
// ORC will import an existing resource, and will not apply updates to it or
// delete it.
// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="managementPolicy is immutable"
// +kubebuilder:default:=managed
// +optional
ManagementPolicy ManagementPolicy `json:"managementPolicy,omitempty"`
// managedOptions specifies options which may be applied to managed objects.
// +optional
ManagedOptions *ManagedOptions `json:"managedOptions,omitempty"`
// cloudCredentialsRef points to a secret containing OpenStack credentials
// +required
CloudCredentialsRef CloudCredentialsReference `json:"cloudCredentialsRef"`
}
// ServerStatus defines the observed state of an ORC resource.
type ServerStatus struct {
// conditions represents the observed status of the object.
// Known .status.conditions.type are: "Available", "Progressing"
//
// Available represents the availability of the OpenStack resource. If it is
// true then the resource is ready for use.
//
// Progressing indicates whether the controller is still attempting to
// reconcile the current state of the OpenStack resource to the desired
// state. Progressing will be False either because the desired state has
// been achieved, or because some terminal error prevents it from ever being
// achieved and the controller is no longer attempting to reconcile. If
// Progressing is True, an observer waiting on the resource should continue
// to wait.
//
// +kubebuilder:validation:MaxItems:=32
// +patchMergeKey=type
// +patchStrategy=merge
// +listType=map
// +listMapKey=type
// +optional
Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type"`
// id is the unique identifier of the OpenStack resource.
// +optional
ID *string `json:"id,omitempty"`
// resource contains the observed state of the OpenStack resource.
// +optional
Resource *ServerResourceStatus `json:"resource,omitempty"`
}
var _ ObjectWithConditions = &Server{}
func (i *Server) GetConditions() []metav1.Condition {
return i.Status.Conditions
}
// +genclient
// +kubebuilder:object:root=true
// +kubebuilder:resource:categories=openstack
// +kubebuilder:subresource:status
// +kubebuilder:printcolumn:name="ID",type="string",JSONPath=".status.id",description="Resource ID"
// +kubebuilder:printcolumn:name="Available",type="string",JSONPath=".status.conditions[?(@.type=='Available')].status",description="Availability status of resource"
// +kubebuilder:printcolumn:name="Message",type="string",JSONPath=".status.conditions[?(@.type=='Progressing')].message",description="Message describing current progress status"
// Server is the Schema for an ORC resource.
type Server struct {
metav1.TypeMeta `json:",inline"`
// metadata contains the object metadata
// +optional
metav1.ObjectMeta `json:"metadata,omitempty"`
// spec specifies the desired state of the resource.
// +optional
Spec ServerSpec `json:"spec,omitempty"`
// status defines the observed state of the resource.
// +optional
Status ServerStatus `json:"status,omitempty"`
}
// +kubebuilder:object:root=true
// ServerList contains a list of Server.
type ServerList struct {
metav1.TypeMeta `json:",inline"`
// metadata contains the list metadata
// +optional
metav1.ListMeta `json:"metadata,omitempty"`
// items contains a list of Server.
// +required
Items []Server `json:"items"`
}
func (l *ServerList) GetItems() []Server {
return l.Items
}
func init() {
SchemeBuilder.Register(&Server{}, &ServerList{})
}
func (i *Server) GetCloudCredentialsRef() (*string, *CloudCredentialsReference) {
if i == nil {
return nil, nil
}
return &i.Namespace, &i.Spec.CloudCredentialsRef
}
var _ CloudCredentialsRefProvider = &Server{}

View File

@@ -0,0 +1,177 @@
// Code generated by resource-generator. DO NOT EDIT.
/*
Copyright 2025 The ORC Authors.
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 (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
// ServerGroupImport specifies an existing resource which will be imported instead of
// creating a new one
// +kubebuilder:validation:MinProperties:=1
// +kubebuilder:validation:MaxProperties:=1
type ServerGroupImport struct {
// id contains the unique identifier of an existing OpenStack resource. Note
// that when specifying an import by ID, the resource MUST already exist.
// The ORC object will enter an error state if the resource does not exist.
// +optional
// +kubebuilder:validation:Format:=uuid
ID *string `json:"id,omitempty"`
// filter contains a resource query which is expected to return a single
// result. The controller will continue to retry if filter returns no
// results. If filter returns multiple results the controller will set an
// error state and will not continue to retry.
// +optional
Filter *ServerGroupFilter `json:"filter,omitempty"`
}
// ServerGroupSpec defines the desired state of an ORC object.
// +kubebuilder:validation:XValidation:rule="self.managementPolicy == 'managed' ? has(self.resource) : true",message="resource must be specified when policy is managed"
// +kubebuilder:validation:XValidation:rule="self.managementPolicy == 'managed' ? !has(self.__import__) : true",message="import may not be specified when policy is managed"
// +kubebuilder:validation:XValidation:rule="self.managementPolicy == 'unmanaged' ? !has(self.resource) : true",message="resource may not be specified when policy is unmanaged"
// +kubebuilder:validation:XValidation:rule="self.managementPolicy == 'unmanaged' ? has(self.__import__) : true",message="import must be specified when policy is unmanaged"
// +kubebuilder:validation:XValidation:rule="has(self.managedOptions) ? self.managementPolicy == 'managed' : true",message="managedOptions may only be provided when policy is managed"
type ServerGroupSpec struct {
// import refers to an existing OpenStack resource which will be imported instead of
// creating a new one.
// +optional
Import *ServerGroupImport `json:"import,omitempty"`
// resource specifies the desired state of the resource.
//
// resource may not be specified if the management policy is `unmanaged`.
//
// resource must be specified if the management policy is `managed`.
// +optional
Resource *ServerGroupResourceSpec `json:"resource,omitempty"`
// managementPolicy defines how ORC will treat the object. Valid values are
// `managed`: ORC will create, update, and delete the resource; `unmanaged`:
// ORC will import an existing resource, and will not apply updates to it or
// delete it.
// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="managementPolicy is immutable"
// +kubebuilder:default:=managed
// +optional
ManagementPolicy ManagementPolicy `json:"managementPolicy,omitempty"`
// managedOptions specifies options which may be applied to managed objects.
// +optional
ManagedOptions *ManagedOptions `json:"managedOptions,omitempty"`
// cloudCredentialsRef points to a secret containing OpenStack credentials
// +required
CloudCredentialsRef CloudCredentialsReference `json:"cloudCredentialsRef"`
}
// ServerGroupStatus defines the observed state of an ORC resource.
type ServerGroupStatus struct {
// conditions represents the observed status of the object.
// Known .status.conditions.type are: "Available", "Progressing"
//
// Available represents the availability of the OpenStack resource. If it is
// true then the resource is ready for use.
//
// Progressing indicates whether the controller is still attempting to
// reconcile the current state of the OpenStack resource to the desired
// state. Progressing will be False either because the desired state has
// been achieved, or because some terminal error prevents it from ever being
// achieved and the controller is no longer attempting to reconcile. If
// Progressing is True, an observer waiting on the resource should continue
// to wait.
//
// +kubebuilder:validation:MaxItems:=32
// +patchMergeKey=type
// +patchStrategy=merge
// +listType=map
// +listMapKey=type
// +optional
Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type"`
// id is the unique identifier of the OpenStack resource.
// +optional
ID *string `json:"id,omitempty"`
// resource contains the observed state of the OpenStack resource.
// +optional
Resource *ServerGroupResourceStatus `json:"resource,omitempty"`
}
var _ ObjectWithConditions = &ServerGroup{}
func (i *ServerGroup) GetConditions() []metav1.Condition {
return i.Status.Conditions
}
// +genclient
// +kubebuilder:object:root=true
// +kubebuilder:resource:categories=openstack
// +kubebuilder:subresource:status
// +kubebuilder:printcolumn:name="ID",type="string",JSONPath=".status.id",description="Resource ID"
// +kubebuilder:printcolumn:name="Available",type="string",JSONPath=".status.conditions[?(@.type=='Available')].status",description="Availability status of resource"
// +kubebuilder:printcolumn:name="Message",type="string",JSONPath=".status.conditions[?(@.type=='Progressing')].message",description="Message describing current progress status"
// ServerGroup is the Schema for an ORC resource.
type ServerGroup struct {
metav1.TypeMeta `json:",inline"`
// metadata contains the object metadata
// +optional
metav1.ObjectMeta `json:"metadata,omitempty"`
// spec specifies the desired state of the resource.
// +optional
Spec ServerGroupSpec `json:"spec,omitempty"`
// status defines the observed state of the resource.
// +optional
Status ServerGroupStatus `json:"status,omitempty"`
}
// +kubebuilder:object:root=true
// ServerGroupList contains a list of ServerGroup.
type ServerGroupList struct {
metav1.TypeMeta `json:",inline"`
// metadata contains the list metadata
// +optional
metav1.ListMeta `json:"metadata,omitempty"`
// items contains a list of ServerGroup.
// +required
Items []ServerGroup `json:"items"`
}
func (l *ServerGroupList) GetItems() []ServerGroup {
return l.Items
}
func init() {
SchemeBuilder.Register(&ServerGroup{}, &ServerGroupList{})
}
func (i *ServerGroup) GetCloudCredentialsRef() (*string, *CloudCredentialsReference) {
if i == nil {
return nil, nil
}
return &i.Namespace, &i.Spec.CloudCredentialsRef
}
var _ CloudCredentialsRefProvider = &ServerGroup{}

View File

@@ -0,0 +1,177 @@
// Code generated by resource-generator. DO NOT EDIT.
/*
Copyright 2025 The ORC Authors.
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 (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
// SubnetImport specifies an existing resource which will be imported instead of
// creating a new one
// +kubebuilder:validation:MinProperties:=1
// +kubebuilder:validation:MaxProperties:=1
type SubnetImport struct {
// id contains the unique identifier of an existing OpenStack resource. Note
// that when specifying an import by ID, the resource MUST already exist.
// The ORC object will enter an error state if the resource does not exist.
// +optional
// +kubebuilder:validation:Format:=uuid
ID *string `json:"id,omitempty"`
// filter contains a resource query which is expected to return a single
// result. The controller will continue to retry if filter returns no
// results. If filter returns multiple results the controller will set an
// error state and will not continue to retry.
// +optional
Filter *SubnetFilter `json:"filter,omitempty"`
}
// SubnetSpec defines the desired state of an ORC object.
// +kubebuilder:validation:XValidation:rule="self.managementPolicy == 'managed' ? has(self.resource) : true",message="resource must be specified when policy is managed"
// +kubebuilder:validation:XValidation:rule="self.managementPolicy == 'managed' ? !has(self.__import__) : true",message="import may not be specified when policy is managed"
// +kubebuilder:validation:XValidation:rule="self.managementPolicy == 'unmanaged' ? !has(self.resource) : true",message="resource may not be specified when policy is unmanaged"
// +kubebuilder:validation:XValidation:rule="self.managementPolicy == 'unmanaged' ? has(self.__import__) : true",message="import must be specified when policy is unmanaged"
// +kubebuilder:validation:XValidation:rule="has(self.managedOptions) ? self.managementPolicy == 'managed' : true",message="managedOptions may only be provided when policy is managed"
type SubnetSpec struct {
// import refers to an existing OpenStack resource which will be imported instead of
// creating a new one.
// +optional
Import *SubnetImport `json:"import,omitempty"`
// resource specifies the desired state of the resource.
//
// resource may not be specified if the management policy is `unmanaged`.
//
// resource must be specified if the management policy is `managed`.
// +optional
Resource *SubnetResourceSpec `json:"resource,omitempty"`
// managementPolicy defines how ORC will treat the object. Valid values are
// `managed`: ORC will create, update, and delete the resource; `unmanaged`:
// ORC will import an existing resource, and will not apply updates to it or
// delete it.
// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="managementPolicy is immutable"
// +kubebuilder:default:=managed
// +optional
ManagementPolicy ManagementPolicy `json:"managementPolicy,omitempty"`
// managedOptions specifies options which may be applied to managed objects.
// +optional
ManagedOptions *ManagedOptions `json:"managedOptions,omitempty"`
// cloudCredentialsRef points to a secret containing OpenStack credentials
// +required
CloudCredentialsRef CloudCredentialsReference `json:"cloudCredentialsRef"`
}
// SubnetStatus defines the observed state of an ORC resource.
type SubnetStatus struct {
// conditions represents the observed status of the object.
// Known .status.conditions.type are: "Available", "Progressing"
//
// Available represents the availability of the OpenStack resource. If it is
// true then the resource is ready for use.
//
// Progressing indicates whether the controller is still attempting to
// reconcile the current state of the OpenStack resource to the desired
// state. Progressing will be False either because the desired state has
// been achieved, or because some terminal error prevents it from ever being
// achieved and the controller is no longer attempting to reconcile. If
// Progressing is True, an observer waiting on the resource should continue
// to wait.
//
// +kubebuilder:validation:MaxItems:=32
// +patchMergeKey=type
// +patchStrategy=merge
// +listType=map
// +listMapKey=type
// +optional
Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type"`
// id is the unique identifier of the OpenStack resource.
// +optional
ID *string `json:"id,omitempty"`
// resource contains the observed state of the OpenStack resource.
// +optional
Resource *SubnetResourceStatus `json:"resource,omitempty"`
}
var _ ObjectWithConditions = &Subnet{}
func (i *Subnet) GetConditions() []metav1.Condition {
return i.Status.Conditions
}
// +genclient
// +kubebuilder:object:root=true
// +kubebuilder:resource:categories=openstack
// +kubebuilder:subresource:status
// +kubebuilder:printcolumn:name="ID",type="string",JSONPath=".status.id",description="Resource ID"
// +kubebuilder:printcolumn:name="Available",type="string",JSONPath=".status.conditions[?(@.type=='Available')].status",description="Availability status of resource"
// +kubebuilder:printcolumn:name="Message",type="string",JSONPath=".status.conditions[?(@.type=='Progressing')].message",description="Message describing current progress status"
// Subnet is the Schema for an ORC resource.
type Subnet struct {
metav1.TypeMeta `json:",inline"`
// metadata contains the object metadata
// +optional
metav1.ObjectMeta `json:"metadata,omitempty"`
// spec specifies the desired state of the resource.
// +optional
Spec SubnetSpec `json:"spec,omitempty"`
// status defines the observed state of the resource.
// +optional
Status SubnetStatus `json:"status,omitempty"`
}
// +kubebuilder:object:root=true
// SubnetList contains a list of Subnet.
type SubnetList struct {
metav1.TypeMeta `json:",inline"`
// metadata contains the list metadata
// +optional
metav1.ListMeta `json:"metadata,omitempty"`
// items contains a list of Subnet.
// +required
Items []Subnet `json:"items"`
}
func (l *SubnetList) GetItems() []Subnet {
return l.Items
}
func init() {
SchemeBuilder.Register(&Subnet{}, &SubnetList{})
}
func (i *Subnet) GetCloudCredentialsRef() (*string, *CloudCredentialsReference) {
if i == nil {
return nil, nil
}
return &i.Namespace, &i.Spec.CloudCredentialsRef
}
var _ CloudCredentialsRefProvider = &Subnet{}

View File

@@ -0,0 +1,177 @@
// Code generated by resource-generator. DO NOT EDIT.
/*
Copyright 2025 The ORC Authors.
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 (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
// VolumeImport specifies an existing resource which will be imported instead of
// creating a new one
// +kubebuilder:validation:MinProperties:=1
// +kubebuilder:validation:MaxProperties:=1
type VolumeImport struct {
// id contains the unique identifier of an existing OpenStack resource. Note
// that when specifying an import by ID, the resource MUST already exist.
// The ORC object will enter an error state if the resource does not exist.
// +optional
// +kubebuilder:validation:Format:=uuid
ID *string `json:"id,omitempty"`
// filter contains a resource query which is expected to return a single
// result. The controller will continue to retry if filter returns no
// results. If filter returns multiple results the controller will set an
// error state and will not continue to retry.
// +optional
Filter *VolumeFilter `json:"filter,omitempty"`
}
// VolumeSpec defines the desired state of an ORC object.
// +kubebuilder:validation:XValidation:rule="self.managementPolicy == 'managed' ? has(self.resource) : true",message="resource must be specified when policy is managed"
// +kubebuilder:validation:XValidation:rule="self.managementPolicy == 'managed' ? !has(self.__import__) : true",message="import may not be specified when policy is managed"
// +kubebuilder:validation:XValidation:rule="self.managementPolicy == 'unmanaged' ? !has(self.resource) : true",message="resource may not be specified when policy is unmanaged"
// +kubebuilder:validation:XValidation:rule="self.managementPolicy == 'unmanaged' ? has(self.__import__) : true",message="import must be specified when policy is unmanaged"
// +kubebuilder:validation:XValidation:rule="has(self.managedOptions) ? self.managementPolicy == 'managed' : true",message="managedOptions may only be provided when policy is managed"
type VolumeSpec struct {
// import refers to an existing OpenStack resource which will be imported instead of
// creating a new one.
// +optional
Import *VolumeImport `json:"import,omitempty"`
// resource specifies the desired state of the resource.
//
// resource may not be specified if the management policy is `unmanaged`.
//
// resource must be specified if the management policy is `managed`.
// +optional
Resource *VolumeResourceSpec `json:"resource,omitempty"`
// managementPolicy defines how ORC will treat the object. Valid values are
// `managed`: ORC will create, update, and delete the resource; `unmanaged`:
// ORC will import an existing resource, and will not apply updates to it or
// delete it.
// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="managementPolicy is immutable"
// +kubebuilder:default:=managed
// +optional
ManagementPolicy ManagementPolicy `json:"managementPolicy,omitempty"`
// managedOptions specifies options which may be applied to managed objects.
// +optional
ManagedOptions *ManagedOptions `json:"managedOptions,omitempty"`
// cloudCredentialsRef points to a secret containing OpenStack credentials
// +required
CloudCredentialsRef CloudCredentialsReference `json:"cloudCredentialsRef"`
}
// VolumeStatus defines the observed state of an ORC resource.
type VolumeStatus struct {
// conditions represents the observed status of the object.
// Known .status.conditions.type are: "Available", "Progressing"
//
// Available represents the availability of the OpenStack resource. If it is
// true then the resource is ready for use.
//
// Progressing indicates whether the controller is still attempting to
// reconcile the current state of the OpenStack resource to the desired
// state. Progressing will be False either because the desired state has
// been achieved, or because some terminal error prevents it from ever being
// achieved and the controller is no longer attempting to reconcile. If
// Progressing is True, an observer waiting on the resource should continue
// to wait.
//
// +kubebuilder:validation:MaxItems:=32
// +patchMergeKey=type
// +patchStrategy=merge
// +listType=map
// +listMapKey=type
// +optional
Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type"`
// id is the unique identifier of the OpenStack resource.
// +optional
ID *string `json:"id,omitempty"`
// resource contains the observed state of the OpenStack resource.
// +optional
Resource *VolumeResourceStatus `json:"resource,omitempty"`
}
var _ ObjectWithConditions = &Volume{}
func (i *Volume) GetConditions() []metav1.Condition {
return i.Status.Conditions
}
// +genclient
// +kubebuilder:object:root=true
// +kubebuilder:resource:categories=openstack
// +kubebuilder:subresource:status
// +kubebuilder:printcolumn:name="ID",type="string",JSONPath=".status.id",description="Resource ID"
// +kubebuilder:printcolumn:name="Available",type="string",JSONPath=".status.conditions[?(@.type=='Available')].status",description="Availability status of resource"
// +kubebuilder:printcolumn:name="Message",type="string",JSONPath=".status.conditions[?(@.type=='Progressing')].message",description="Message describing current progress status"
// Volume is the Schema for an ORC resource.
type Volume struct {
metav1.TypeMeta `json:",inline"`
// metadata contains the object metadata
// +optional
metav1.ObjectMeta `json:"metadata,omitempty"`
// spec specifies the desired state of the resource.
// +optional
Spec VolumeSpec `json:"spec,omitempty"`
// status defines the observed state of the resource.
// +optional
Status VolumeStatus `json:"status,omitempty"`
}
// +kubebuilder:object:root=true
// VolumeList contains a list of Volume.
type VolumeList struct {
metav1.TypeMeta `json:",inline"`
// metadata contains the list metadata
// +optional
metav1.ListMeta `json:"metadata,omitempty"`
// items contains a list of Volume.
// +required
Items []Volume `json:"items"`
}
func (l *VolumeList) GetItems() []Volume {
return l.Items
}
func init() {
SchemeBuilder.Register(&Volume{}, &VolumeList{})
}
func (i *Volume) GetCloudCredentialsRef() (*string, *CloudCredentialsReference) {
if i == nil {
return nil, nil
}
return &i.Namespace, &i.Spec.CloudCredentialsRef
}
var _ CloudCredentialsRefProvider = &Volume{}

View File

@@ -0,0 +1,177 @@
// Code generated by resource-generator. DO NOT EDIT.
/*
Copyright 2025 The ORC Authors.
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 (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
// VolumeTypeImport specifies an existing resource which will be imported instead of
// creating a new one
// +kubebuilder:validation:MinProperties:=1
// +kubebuilder:validation:MaxProperties:=1
type VolumeTypeImport struct {
// id contains the unique identifier of an existing OpenStack resource. Note
// that when specifying an import by ID, the resource MUST already exist.
// The ORC object will enter an error state if the resource does not exist.
// +optional
// +kubebuilder:validation:Format:=uuid
ID *string `json:"id,omitempty"`
// filter contains a resource query which is expected to return a single
// result. The controller will continue to retry if filter returns no
// results. If filter returns multiple results the controller will set an
// error state and will not continue to retry.
// +optional
Filter *VolumeTypeFilter `json:"filter,omitempty"`
}
// VolumeTypeSpec defines the desired state of an ORC object.
// +kubebuilder:validation:XValidation:rule="self.managementPolicy == 'managed' ? has(self.resource) : true",message="resource must be specified when policy is managed"
// +kubebuilder:validation:XValidation:rule="self.managementPolicy == 'managed' ? !has(self.__import__) : true",message="import may not be specified when policy is managed"
// +kubebuilder:validation:XValidation:rule="self.managementPolicy == 'unmanaged' ? !has(self.resource) : true",message="resource may not be specified when policy is unmanaged"
// +kubebuilder:validation:XValidation:rule="self.managementPolicy == 'unmanaged' ? has(self.__import__) : true",message="import must be specified when policy is unmanaged"
// +kubebuilder:validation:XValidation:rule="has(self.managedOptions) ? self.managementPolicy == 'managed' : true",message="managedOptions may only be provided when policy is managed"
type VolumeTypeSpec struct {
// import refers to an existing OpenStack resource which will be imported instead of
// creating a new one.
// +optional
Import *VolumeTypeImport `json:"import,omitempty"`
// resource specifies the desired state of the resource.
//
// resource may not be specified if the management policy is `unmanaged`.
//
// resource must be specified if the management policy is `managed`.
// +optional
Resource *VolumeTypeResourceSpec `json:"resource,omitempty"`
// managementPolicy defines how ORC will treat the object. Valid values are
// `managed`: ORC will create, update, and delete the resource; `unmanaged`:
// ORC will import an existing resource, and will not apply updates to it or
// delete it.
// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="managementPolicy is immutable"
// +kubebuilder:default:=managed
// +optional
ManagementPolicy ManagementPolicy `json:"managementPolicy,omitempty"`
// managedOptions specifies options which may be applied to managed objects.
// +optional
ManagedOptions *ManagedOptions `json:"managedOptions,omitempty"`
// cloudCredentialsRef points to a secret containing OpenStack credentials
// +required
CloudCredentialsRef CloudCredentialsReference `json:"cloudCredentialsRef"`
}
// VolumeTypeStatus defines the observed state of an ORC resource.
type VolumeTypeStatus struct {
// conditions represents the observed status of the object.
// Known .status.conditions.type are: "Available", "Progressing"
//
// Available represents the availability of the OpenStack resource. If it is
// true then the resource is ready for use.
//
// Progressing indicates whether the controller is still attempting to
// reconcile the current state of the OpenStack resource to the desired
// state. Progressing will be False either because the desired state has
// been achieved, or because some terminal error prevents it from ever being
// achieved and the controller is no longer attempting to reconcile. If
// Progressing is True, an observer waiting on the resource should continue
// to wait.
//
// +kubebuilder:validation:MaxItems:=32
// +patchMergeKey=type
// +patchStrategy=merge
// +listType=map
// +listMapKey=type
// +optional
Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type"`
// id is the unique identifier of the OpenStack resource.
// +optional
ID *string `json:"id,omitempty"`
// resource contains the observed state of the OpenStack resource.
// +optional
Resource *VolumeTypeResourceStatus `json:"resource,omitempty"`
}
var _ ObjectWithConditions = &VolumeType{}
func (i *VolumeType) GetConditions() []metav1.Condition {
return i.Status.Conditions
}
// +genclient
// +kubebuilder:object:root=true
// +kubebuilder:resource:categories=openstack
// +kubebuilder:subresource:status
// +kubebuilder:printcolumn:name="ID",type="string",JSONPath=".status.id",description="Resource ID"
// +kubebuilder:printcolumn:name="Available",type="string",JSONPath=".status.conditions[?(@.type=='Available')].status",description="Availability status of resource"
// +kubebuilder:printcolumn:name="Message",type="string",JSONPath=".status.conditions[?(@.type=='Progressing')].message",description="Message describing current progress status"
// VolumeType is the Schema for an ORC resource.
type VolumeType struct {
metav1.TypeMeta `json:",inline"`
// metadata contains the object metadata
// +optional
metav1.ObjectMeta `json:"metadata,omitempty"`
// spec specifies the desired state of the resource.
// +optional
Spec VolumeTypeSpec `json:"spec,omitempty"`
// status defines the observed state of the resource.
// +optional
Status VolumeTypeStatus `json:"status,omitempty"`
}
// +kubebuilder:object:root=true
// VolumeTypeList contains a list of VolumeType.
type VolumeTypeList struct {
metav1.TypeMeta `json:",inline"`
// metadata contains the list metadata
// +optional
metav1.ListMeta `json:"metadata,omitempty"`
// items contains a list of VolumeType.
// +required
Items []VolumeType `json:"items"`
}
func (l *VolumeTypeList) GetItems() []VolumeType {
return l.Items
}
func init() {
SchemeBuilder.Register(&VolumeType{}, &VolumeTypeList{})
}
func (i *VolumeType) GetCloudCredentialsRef() (*string, *CloudCredentialsReference) {
if i == nil {
return nil, nil
}
return &i.Namespace, &i.Spec.CloudCredentialsRef
}
var _ CloudCredentialsRefProvider = &VolumeType{}

View File

@@ -1,9 +1,5 @@
# TODO list
## Release v0.5.x
1. Support check flag in gxz command.
## Release v0.6
1. Review encoder and check for lzma improvements under xz.
@@ -86,6 +82,19 @@
## Log
## 2025-08-28
Release v0.5.14 addresses the security vulnerability CVE-2025-58058. If you put
bytes in from of a LZMA stream, the header might not be read correctly and
memory for the dictionary buffer allocated. I have implemented mitigations for
the problem.
### 2025-08-20
Release v0.5.13 addressed issue #61 regarding handling of multiple WriteClosers
together. So I added a new package xio with a WriteCloserStack to address the
issue.
### 2024-04-03
Release v0.5.12 updates README.md and SECURITY.md to address the supply chain

View File

@@ -60,36 +60,36 @@ const noHeaderSize uint64 = 1<<64 - 1
// HeaderLen provides the length of the LZMA file header.
const HeaderLen = 13
// header represents the header of an LZMA file.
type header struct {
properties Properties
dictCap int
// uncompressed size; negative value if no size is given
size int64
// Header represents the Header of an LZMA file.
type Header struct {
Properties Properties
DictSize uint32
// uncompressed Size; negative value if no Size is given
Size int64
}
// marshalBinary marshals the header.
func (h *header) marshalBinary() (data []byte, err error) {
if err = h.properties.verify(); err != nil {
func (h *Header) marshalBinary() (data []byte, err error) {
if err = h.Properties.verify(); err != nil {
return nil, err
}
if !(0 <= h.dictCap && int64(h.dictCap) <= MaxDictCap) {
if !(h.DictSize <= MaxDictCap) {
return nil, fmt.Errorf("lzma: DictCap %d out of range",
h.dictCap)
h.DictSize)
}
data = make([]byte, 13)
// property byte
data[0] = h.properties.Code()
data[0] = h.Properties.Code()
// dictionary capacity
putUint32LE(data[1:5], uint32(h.dictCap))
putUint32LE(data[1:5], uint32(h.DictSize))
// uncompressed size
var s uint64
if h.size > 0 {
s = uint64(h.size)
if h.Size > 0 {
s = uint64(h.Size)
} else {
s = noHeaderSize
}
@@ -99,20 +99,20 @@ func (h *header) marshalBinary() (data []byte, err error) {
}
// unmarshalBinary unmarshals the header.
func (h *header) unmarshalBinary(data []byte) error {
func (h *Header) unmarshalBinary(data []byte) error {
if len(data) != HeaderLen {
return errors.New("lzma.unmarshalBinary: data has wrong length")
}
// properties
var err error
if h.properties, err = PropertiesForCode(data[0]); err != nil {
if h.Properties, err = PropertiesForCode(data[0]); err != nil {
return err
}
// dictionary capacity
h.dictCap = int(uint32LE(data[1:]))
if h.dictCap < 0 {
h.DictSize = uint32LE(data[1:])
if int(h.DictSize) < 0 {
return errors.New(
"LZMA header: dictionary capacity exceeds maximum " +
"integer")
@@ -121,10 +121,10 @@ func (h *header) unmarshalBinary(data []byte) error {
// uncompressed size
s := uint64LE(data[5:])
if s == noHeaderSize {
h.size = -1
h.Size = -1
} else {
h.size = int64(s)
if h.size < 0 {
h.Size = int64(s)
if h.Size < 0 {
return errors.New(
"LZMA header: uncompressed size " +
"out of int64 range")
@@ -134,9 +134,9 @@ func (h *header) unmarshalBinary(data []byte) error {
return nil
}
// validDictCap checks whether the dictionary capacity is correct. This
// validDictSize checks whether the dictionary capacity is correct. This
// is used to weed out wrong file headers.
func validDictCap(dictcap int) bool {
func validDictSize(dictcap int) bool {
if int64(dictcap) == MaxDictCap {
return true
}
@@ -155,13 +155,16 @@ func validDictCap(dictcap int) bool {
// dictionary sizes of 2^n or 2^n+2^(n-1) with n >= 10 or 2^32-1. If
// there is an explicit size it must not exceed 256 GiB. The length of
// the data argument must be HeaderLen.
//
// This function should be disregarded because there is no guarantee that LZMA
// files follow the constraints.
func ValidHeader(data []byte) bool {
var h header
var h Header
if err := h.unmarshalBinary(data); err != nil {
return false
}
if !validDictCap(h.dictCap) {
if !validDictSize(int(h.DictSize)) {
return false
}
return h.size < 0 || h.size <= 1<<38
return h.Size < 0 || h.Size <= 1<<38
}

View File

@@ -6,25 +6,32 @@
// Reader and Writer support the classic LZMA format. Reader2 and
// Writer2 support the decoding and encoding of LZMA2 streams.
//
// The package is written completely in Go and doesn't rely on any external
// The package is written completely in Go and does not rely on any external
// library.
package lzma
import (
"errors"
"fmt"
"io"
)
// ReaderConfig stores the parameters for the reader of the classic LZMA
// format.
type ReaderConfig struct {
// Since v0.5.14 this parameter sets an upper limit for a .lzma file's
// dictionary size. This helps to mitigate problems with mangled
// headers.
DictCap int
}
// fill converts the zero values of the configuration to the default values.
func (c *ReaderConfig) fill() {
if c.DictCap == 0 {
c.DictCap = 8 * 1024 * 1024
// set an upper limit of 2 GiB-1 for dictionary capacity
// to address the zero prefix security issue.
c.DictCap = (1 << 31) - 1
// original: c.DictCap = 8 * 1024 * 1024
}
}
@@ -39,9 +46,32 @@ func (c *ReaderConfig) Verify() error {
}
// Reader provides a reader for LZMA files or streams.
//
// # Security concerns
//
// Note that LZMA format doesn't support a magic marker in the header. So
// [NewReader] cannot determine whether it reads the actual header. For instance
// the LZMA stream might have a zero byte in front of the reader, leading to
// larger dictionary sizes and file sizes. The code will detect later that there
// are problems with the stream, but the dictionary has already been allocated
// and this might consume a lot of memory.
//
// Version 0.5.14 introduces built-in mitigations:
//
// - The [ReaderConfig] DictCap field is now interpreted as a limit for the
// dictionary size.
// - The default is 2 Gigabytes minus 1 byte (2^31-1 bytes).
// - Users can check with the [Reader.Header] method what the actual values are in
// their LZMA files and set a smaller limit using [ReaderConfig].
// - The dictionary size doesn't exceed the larger of the file size and
// the minimum dictionary size. This is another measure to prevent huge
// memory allocations for the dictionary.
// - The code supports stream sizes only up to a pebibyte (1024^5).
type Reader struct {
lzma io.Reader
h header
header Header
// headerOrig stores the original header read from the stream.
headerOrig Header
d *decoder
}
@@ -51,8 +81,37 @@ func NewReader(lzma io.Reader) (r *Reader, err error) {
return ReaderConfig{}.NewReader(lzma)
}
// ErrDictSize reports about an error of the dictionary size.
type ErrDictSize struct {
ConfigDictCap int
HeaderDictSize uint32
Message string
}
// Error returns the error message.
func (e *ErrDictSize) Error() string {
return e.Message
}
func newErrDictSize(messageformat string,
configDictCap int, headerDictSize uint32,
args ...interface{}) *ErrDictSize {
newArgs := make([]interface{}, len(args)+2)
newArgs[0] = configDictCap
newArgs[1] = headerDictSize
copy(newArgs[2:], args)
return &ErrDictSize{
ConfigDictCap: configDictCap,
HeaderDictSize: headerDictSize,
Message: fmt.Sprintf(messageformat, newArgs...),
}
}
// We support only files not larger than 1 << 50 bytes (a pebibyte, 1024^5).
const maxStreamSize = 1 << 50
// NewReader creates a new reader for an LZMA stream in the classic
// format. The function reads and verifies the the header of the LZMA
// format. The function reads and verifies the header of the LZMA
// stream.
func (c ReaderConfig) NewReader(lzma io.Reader) (r *Reader, err error) {
if err = c.Verify(); err != nil {
@@ -66,29 +125,63 @@ func (c ReaderConfig) NewReader(lzma io.Reader) (r *Reader, err error) {
return nil, err
}
r = &Reader{lzma: lzma}
if err = r.h.unmarshalBinary(data); err != nil {
if err = r.header.unmarshalBinary(data); err != nil {
return nil, err
}
if r.h.dictCap < MinDictCap {
r.h.dictCap = MinDictCap
r.headerOrig = r.header
dictSize := int64(r.header.DictSize)
if int64(c.DictCap) < dictSize {
return nil, newErrDictSize(
"lzma: header dictionary size %[2]d exceeds configured dictionary capacity %[1]d",
c.DictCap, uint32(dictSize),
)
}
dictCap := r.h.dictCap
if c.DictCap > dictCap {
dictCap = c.DictCap
if dictSize < MinDictCap {
dictSize = MinDictCap
}
// original code: disabled this because there is no point in increasing
// the dictionary above what is stated in the file.
/*
if int64(c.DictCap) > int64(dictSize) {
dictSize = int64(c.DictCap)
}
*/
size := r.header.Size
if size >= 0 && size < dictSize {
dictSize = size
}
// Protect against modified or malicious headers.
if size > maxStreamSize {
return nil, fmt.Errorf(
"lzma: stream size %d exceeds a pebibyte (1024^5)",
size)
}
if dictSize < MinDictCap {
dictSize = MinDictCap
}
state := newState(r.h.properties)
dict, err := newDecoderDict(dictCap)
r.header.DictSize = uint32(dictSize)
state := newState(r.header.Properties)
dict, err := newDecoderDict(int(dictSize))
if err != nil {
return nil, err
}
r.d, err = newDecoder(ByteReader(lzma), state, dict, r.h.size)
r.d, err = newDecoder(ByteReader(lzma), state, dict, r.header.Size)
if err != nil {
return nil, err
}
return r, nil
}
// Header returns the header as read from the LZMA stream. It is intended to
// allow the user to understand what parameters are typically provided in the
// headers of the LZMA files and set the DictCap field in [ReaderConfig]
// accordingly.
func (r *Reader) Header() (h Header, ok bool) {
return r.headerOrig, r.d != nil
}
// EOSMarker indicates that an EOS marker has been encountered.
func (r *Reader) EOSMarker() bool {
return r.d.eosMarker

View File

@@ -96,21 +96,21 @@ func (c *WriterConfig) Verify() error {
}
// header returns the header structure for this configuration.
func (c *WriterConfig) header() header {
h := header{
properties: *c.Properties,
dictCap: c.DictCap,
size: -1,
func (c *WriterConfig) header() Header {
h := Header{
Properties: *c.Properties,
DictSize: uint32(c.DictCap),
Size: -1,
}
if c.SizeInHeader {
h.size = c.Size
h.Size = c.Size
}
return h
}
// Writer writes an LZMA stream in the classic format.
type Writer struct {
h header
h Header
bw io.ByteWriter
buf *bufio.Writer
e *encoder
@@ -130,12 +130,12 @@ func (c WriterConfig) NewWriter(lzma io.Writer) (w *Writer, err error) {
w.buf = bufio.NewWriter(lzma)
w.bw = w.buf
}
state := newState(w.h.properties)
m, err := c.Matcher.new(w.h.dictCap)
state := newState(w.h.Properties)
m, err := c.Matcher.new(int(w.h.DictSize))
if err != nil {
return nil, err
}
dict, err := newEncoderDict(w.h.dictCap, c.BufSize, m)
dict, err := newEncoderDict(int(w.h.DictSize), c.BufSize, m)
if err != nil {
return nil, err
}
@@ -171,8 +171,8 @@ func (w *Writer) writeHeader() error {
// Write puts data into the Writer.
func (w *Writer) Write(p []byte) (n int, err error) {
if w.h.size >= 0 {
m := w.h.size
if w.h.Size >= 0 {
m := w.h.Size
m -= w.e.Compressed() + int64(w.e.dict.Buffered())
if m < 0 {
m = 0
@@ -192,9 +192,9 @@ func (w *Writer) Write(p []byte) (n int, err error) {
// Close closes the writer stream. It ensures that all data from the
// buffer will be compressed and the LZMA stream will be finished.
func (w *Writer) Close() error {
if w.h.size >= 0 {
if w.h.Size >= 0 {
n := w.e.Compressed() + int64(w.e.dict.Buffered())
if n != w.h.size {
if n != w.h.Size {
return errSize
}
}

5
vendor/modules.txt vendored
View File

@@ -1131,6 +1131,9 @@ github.com/josharian/intern
# github.com/json-iterator/go v1.1.12
## explicit; go 1.12
github.com/json-iterator/go
# github.com/k-orc/openstack-resource-controller/v2 v2.3.0
## explicit; go 1.23.0
github.com/k-orc/openstack-resource-controller/v2/api/v1alpha1
# github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51
## explicit
github.com/kballard/go-shellquote
@@ -1641,7 +1644,7 @@ github.com/thedevsaddam/retry
# github.com/thoas/go-funk v0.9.3
## explicit; go 1.13
github.com/thoas/go-funk
# github.com/ulikunitz/xz v0.5.12
# github.com/ulikunitz/xz v0.5.15
## explicit; go 1.12
github.com/ulikunitz/xz
github.com/ulikunitz/xz/internal/hash