Skip to content

Commit 9636d70

Browse files
authored
Merge pull request #500 from vshn/develop
🔀 Merge develop into master (Release)
2 parents 3f3a96b + a5d575e commit 9636d70

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

59 files changed

+3479
-44
lines changed

apis/codey/dbaas_vshn_codey.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,10 +137,15 @@ func (v *CodeyInstance) GetAllowedNamespaces() []string {
137137
func (v *CodeyInstance) GetBackupRetention() vshnv1.K8upRetentionPolicy {
138138
return vshnv1.K8upRetentionPolicy{}
139139
}
140+
140141
func (v *CodeyInstance) GetBackupSchedule() string {
141142
return ""
142143
}
143144

145+
func (v *CodeyInstance) IsBackupEnabled() bool {
146+
return false
147+
}
148+
144149
func (v *CodeyInstance) GetServiceName() string {
145150
return "codey"
146151
}

apis/vshn/v1/billing_service.go

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
package v1
2+
3+
import (
4+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
5+
)
6+
7+
const (
8+
// BillingServiceFinalizer is the finalizer used to protect BillingService resources from deletion
9+
BillingServiceFinalizer = "billing.appcat.vshn.io/delete-protection"
10+
)
11+
12+
// +kubebuilder:object:root=true
13+
// +kubebuilder:subresource:status
14+
// +kubebuilder:object:generate=true
15+
// +kubebuilder:resource:scope=Namespaced,categories=appcat
16+
// +kubebuilder:printcolumn:name="READY",type="string",JSONPath=".status.conditions[?(@.type=='Ready')].status"
17+
// +kubebuilder:printcolumn:name="SYNCED",type="string",JSONPath=".status.conditions[?(@.type=='Synced')].status"
18+
// +kubebuilder:printcolumn:name="AGE",type="date",JSONPath=".metadata.creationTimestamp"
19+
20+
// BillingService represents a service instance for billing purposes
21+
type BillingService struct {
22+
metav1.TypeMeta `json:",inline"`
23+
metav1.ObjectMeta `json:"metadata,omitempty"`
24+
25+
// Spec defines the desired state of a BillingService
26+
Spec BillingServiceSpec `json:"spec"`
27+
28+
// Status reflects the observed state of a BillingService
29+
Status BillingServiceStatus `json:"status,omitempty"`
30+
}
31+
32+
// BillingServiceSpec defines the desired state of a BillingService
33+
type BillingServiceSpec struct {
34+
// KeepAfterDeletion defines how many days to keep billing records after service deletion
35+
KeepAfterDeletion int `json:"keepAfterDeletion,omitempty"`
36+
37+
// Odoo contains Odoo-specific billing configuration
38+
Odoo OdooSpec `json:"odoo,omitempty"`
39+
}
40+
41+
// OdooSpec defines Odoo-specific billing configuration
42+
type OdooSpec struct {
43+
// InstanceID uniquely identifies the service instance in Odoo
44+
InstanceID string `json:"instanceID"`
45+
46+
// ProductID identifies the product in the billing system
47+
ProductID string `json:"productID"`
48+
49+
// SalesOrderID identifies the sales order in Odoo
50+
SalesOrderID string `json:"salesOrderID,omitempty"`
51+
52+
// UnitID defines the billing unit type in Odoo
53+
UnitID string `json:"unitID"`
54+
55+
// Size represents the size of the service instance
56+
Size string `json:"size,omitempty"`
57+
58+
// ItemGroupDescription describes the billing item group
59+
ItemGroupDescription string `json:"itemGroupDescription"`
60+
61+
// ItemDescription is a human readable description of the billing item
62+
ItemDescription string `json:"itemDescription"`
63+
}
64+
65+
// BillingServiceStatus defines the observed state of a BillingService
66+
type BillingServiceStatus struct {
67+
// Events contains the history of billing events
68+
Events []BillingEventStatus `json:"events,omitempty"`
69+
70+
// Conditions represent the latest available observations of the billing service's state
71+
Conditions []metav1.Condition `json:"conditions,omitempty"`
72+
}
73+
74+
// BillingEventStatus represents the status of a billing event
75+
type BillingEventStatus struct {
76+
// Type is the type of billing event (created, deleted, scaled)
77+
// +kubebuilder:validation:Enum="created";"deleted";"scaled"
78+
Type string `json:"type"`
79+
80+
// ProductID identifies the product in the billing system
81+
ProductID string `json:"productId"`
82+
83+
// Size represents the size/plan at the time of the event
84+
Size string `json:"size"`
85+
86+
// Timestamp when the event occurred
87+
Timestamp metav1.Time `json:"timestamp"`
88+
89+
// State represents the current state of the event (sent, pending, failed, superseded)
90+
// +kubebuilder:validation:Enum="sent";"pending";"failed";"superseded"
91+
State string `json:"state"`
92+
93+
// RetryCount tracks the number of retry attempts for failed events
94+
// +kubebuilder:default=0
95+
RetryCount int `json:"retryCount,omitempty"`
96+
97+
// LastAttemptTime is when we last tried to send this event
98+
LastAttemptTime metav1.Time `json:"lastAttemptTime,omitempty"`
99+
}
100+
101+
// +kubebuilder:object:root=true
102+
// +kubebuilder:object:generate=true
103+
104+
// BillingServiceList contains a list of BillingService
105+
type BillingServiceList struct {
106+
metav1.TypeMeta `json:",inline"`
107+
metav1.ListMeta `json:"metadata,omitempty"`
108+
Items []BillingService `json:"items"`
109+
}

apis/vshn/v1/dbaas_vshn_mariadb.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,10 @@ type VSHNMariaDBStatus struct {
145145
// CurrentInstances tracks the current amount of instances.
146146
// Mainly used to detect if there was a change in instances
147147
CurrentInstances int `json:"currentInstances,omitempty"`
148+
// MariaDBVersion contains the current MariaDB server version
149+
MariaDBVersion string `json:"mariadbVersion,omitempty"`
150+
// InitialMaintenanceRan tracks if the initial maintenance job has been triggered
151+
InitialMaintenanceRan bool `json:"initialMaintenanceRan,omitempty"`
148152
// ResourceStatus represents the observed state of a managed resource.
149153
xpv1.ResourceStatus `json:",inline"`
150154
}

apis/vshn/v1/dbaas_vshn_postgresql.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"fmt"
55

66
xpv1 "github.com/crossplane/crossplane-runtime/apis/common/v1"
7+
cpv1 "github.com/crossplane/crossplane/apis/apiextensions/v1"
78
sgv1 "github.com/vshn/appcat/v4/apis/stackgres/v1"
89
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
910
"k8s.io/apimachinery/pkg/runtime"
@@ -36,7 +37,8 @@ type VSHNPostgreSQL struct {
3637
// VSHNPostgreSQLSpec defines the desired state of a VSHNPostgreSQL.
3738
type VSHNPostgreSQLSpec struct {
3839
// Parameters are the configurable fields of a VSHNPostgreSQL.
39-
Parameters VSHNPostgreSQLParameters `json:"parameters,omitempty"`
40+
Parameters VSHNPostgreSQLParameters `json:"parameters,omitempty"`
41+
CompositionRef cpv1.CompositionReference `json:"compositionRef,omitempty"`
4042
xpv1.ResourceSpec `json:",inline"`
4143
}
4244

apis/vshn/v1/dbaas_vshn_redis.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,7 @@ func (v *VSHNRedis) GetSize() VSHNSizeSpec {
295295
Memory: v.Spec.Parameters.Size.MemoryRequests,
296296
},
297297
Disk: v.Spec.Parameters.Size.Disk,
298+
Plan: v.Spec.Parameters.Size.Plan,
298299
}
299300
}
300301

apis/vshn/v1/groupversion_info.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ var (
2222

2323
func init() {
2424
SchemeBuilder.Register(
25+
&BillingService{},
26+
&BillingServiceList{},
27+
2528
&VSHNPostgreSQL{},
2629
&VSHNPostgreSQLList{},
2730
&XVSHNPostgreSQL{},

apis/vshn/v1/zz_generated.deepcopy.go

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

cmd/controller.go

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,10 @@ import (
77
"github.com/spf13/cobra"
88
"github.com/spf13/viper"
99
"github.com/vshn/appcat/v4/pkg"
10+
"github.com/vshn/appcat/v4/pkg/controller/billing"
1011
"github.com/vshn/appcat/v4/pkg/controller/events"
1112
"github.com/vshn/appcat/v4/pkg/controller/webhooks"
13+
"github.com/vshn/appcat/v4/pkg/odoo"
1214
"k8s.io/apimachinery/pkg/runtime"
1315
ctrl "sigs.k8s.io/controller-runtime"
1416
"sigs.k8s.io/controller-runtime/pkg/healthz"
@@ -26,6 +28,7 @@ type controller struct {
2628
enableProviderWebhooks bool
2729
enableQuotas bool
2830
enableEventForwarding bool
31+
enableBilling bool
2932
certDir string
3033
}
3134

@@ -51,6 +54,7 @@ func init() {
5154
ControllerCMD.Flags().StringVar(&c.certDir, "certdir", "/etc/webhook/certs", "Set the webhook certificate directory")
5255
ControllerCMD.Flags().BoolVar(&c.enableQuotas, "quotas", false, "Enable the quota webhooks, is only active if webhooks is also true")
5356
ControllerCMD.Flags().BoolVar(&c.enableEventForwarding, "event-forwarding", true, "Disable event-forwarding")
57+
ControllerCMD.Flags().BoolVar(&c.enableBilling, "billing", true, "Disable billing")
5458
viper.AutomaticEnv()
5559
if !viper.IsSet("PLANS_NAMESPACE") {
5660
viper.Set("PLANS_NAMESPACE", "syn-appcat")
@@ -79,6 +83,30 @@ func (c *controller) executeController(cmd *cobra.Command, _ []string) error {
7983
return err
8084
}
8185

86+
if c.enableBilling {
87+
opts := odoo.Options{
88+
BaseURL: viper.GetString("ODOO_BASE_URL"),
89+
DB: viper.GetString("ODOO_DB"),
90+
ClientID: viper.GetString("ODOO_CLIENT_ID"),
91+
ClientSecret: viper.GetString("ODOO_CLIENT_SECRET"),
92+
TokenURL: viper.GetString("ODOO_TOKEN_URL"),
93+
}
94+
95+
if opts.BaseURL == "" || opts.DB == "" || opts.ClientID == "" || opts.ClientSecret == "" || opts.TokenURL == "" {
96+
return fmt.Errorf("billing is enabled but Odoo configuration is incomplete")
97+
}
98+
99+
odooClient, err := odoo.NewClient(cmd.Context(), opts)
100+
if err != nil {
101+
return fmt.Errorf("initialize Odoo client: %w", err)
102+
}
103+
104+
b := billing.New(mgr.GetClient(), mgr.GetScheme(), odooClient)
105+
if err := b.SetupWithManager(mgr); err != nil {
106+
return err
107+
}
108+
}
109+
82110
if c.enableEventForwarding {
83111
events := &events.EventHandler{
84112
Client: mgr.GetClient(),

0 commit comments

Comments
 (0)