Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add long running operation types, conditions, and helpers #1610

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions api/v1alpha3/azurecluster_conversion.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,8 @@ func (src *AzureCluster) ConvertTo(dstRaw conversion.Hub) error { // nolint
}
}

dst.Status.LongRunningOperationStates = restored.Status.LongRunningOperationStates

return nil
}

Expand Down Expand Up @@ -304,3 +306,15 @@ func Convert_v1alpha3_VnetSpec_To_v1alpha4_VnetSpec(in *VnetSpec, out *infrav1al
func Convert_v1alpha4_LoadBalancerSpec_To_v1alpha3_LoadBalancerSpec(in *infrav1alpha4.LoadBalancerSpec, out *LoadBalancerSpec, s apiconversion.Scope) error {
return autoConvert_v1alpha4_LoadBalancerSpec_To_v1alpha3_LoadBalancerSpec(in, out, s)
}

// Convert_v1alpha3_Future_To_v1alpha4_Future is an autogenerated conversion function.
func Convert_v1alpha3_Future_To_v1alpha4_Future(in *Future, out *infrav1alpha4.Future, s apiconversion.Scope) error {
out.Data = in.FutureData
return autoConvert_v1alpha3_Future_To_v1alpha4_Future(in, out, s)
}

// Convert_v1alpha4_Future_To_v1alpha3_Future is an autogenerated conversion function.
func Convert_v1alpha4_Future_To_v1alpha3_Future(in *infrav1alpha4.Future, out *Future, s apiconversion.Scope) error {
out.FutureData = in.Data
return autoConvert_v1alpha4_Future_To_v1alpha3_Future(in, out, s)
}
2 changes: 2 additions & 0 deletions api/v1alpha3/azuremachine_conversion.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ func (src *AzureMachine) ConvertTo(dstRaw conversion.Hub) error { // nolint

dst.Spec.SubnetName = restored.Spec.SubnetName

dst.Status.LongRunningOperationStates = restored.Status.LongRunningOperationStates

return nil
}

Expand Down
37 changes: 15 additions & 22 deletions api/v1alpha3/zz_generated.conversion.go

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

19 changes: 18 additions & 1 deletion api/v1alpha4/azurecluster_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,11 +96,18 @@ type AzureClusterStatus struct {
// Conditions defines current service state of the AzureCluster.
// +optional
Conditions clusterv1.Conditions `json:"conditions,omitempty"`

// LongRunningOperationStates saves the states for Azure long-running operations so they can be continued on the
// next reconciliation loop.
// +optional
LongRunningOperationStates Futures `json:"longRunningOperationStates,omitempty"`
}

// +kubebuilder:object:root=true
// +kubebuilder:printcolumn:name="Cluster",type="string",JSONPath=".metadata.labels.cluster\\.x-k8s\\.io/cluster-name",description="Cluster to which this AzureCluster belongs"
// +kubebuilder:printcolumn:name="Ready",type="boolean",JSONPath=".status.ready"
// +kubebuilder:printcolumn:name="Ready",type="string",JSONPath=".status.conditions[?(@.type=='Ready')].status"
CecileRobertMichon marked this conversation as resolved.
Show resolved Hide resolved
// +kubebuilder:printcolumn:name="Reason",type="string",JSONPath=".status.conditions[?(@.type=='Ready')].reason"
// +kubebuilder:printcolumn:name="Message",type="string",priority=1,JSONPath=".status.conditions[?(@.type=='Ready')].message"
// +kubebuilder:printcolumn:name="Resource Group",type="string",priority=1,JSONPath=".spec.resourceGroup"
// +kubebuilder:printcolumn:name="SubscriptionID",type="string",priority=1,JSONPath=".spec.subscriptionID"
// +kubebuilder:printcolumn:name="Location",type="string",priority=1,JSONPath=".spec.location"
Expand Down Expand Up @@ -137,6 +144,16 @@ func (c *AzureCluster) SetConditions(conditions clusterv1.Conditions) {
c.Status.Conditions = conditions
}

// GetFutures returns the list of long running operation states for an AzureCluster API object.
func (c *AzureCluster) GetFutures() Futures {
return c.Status.LongRunningOperationStates
}

// SetFutures will set the given long running operation states on an AzureCluster object.
func (c *AzureCluster) SetFutures(futures Futures) {
c.Status.LongRunningOperationStates = futures
}

func init() {
SchemeBuilder.Register(&AzureCluster{}, &AzureClusterList{})
}
15 changes: 15 additions & 0 deletions api/v1alpha4/azuremachine_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,11 @@ type AzureMachineStatus struct {
// Conditions defines current service state of the AzureMachine.
// +optional
Conditions clusterv1.Conditions `json:"conditions,omitempty"`

// LongRunningOperationStates saves the states for Azure long-running operations so they can be continued on the
// next reconciliation loop.
// +optional
LongRunningOperationStates Futures `json:"longRunningOperationStates,omitempty"`
}

// +kubebuilder:object:root=true
Expand Down Expand Up @@ -216,6 +221,16 @@ func (m *AzureMachine) SetConditions(conditions clusterv1.Conditions) {
m.Status.Conditions = conditions
}

// GetFutures returns the list of long running operation states for an AzureMachine API object.
func (m *AzureMachine) GetFutures() Futures {
return m.Status.LongRunningOperationStates
}

// SetFutures will set the given long running operation states on an AzureMachine object.
func (m *AzureMachine) SetFutures(futures Futures) {
m.Status.LongRunningOperationStates = futures
}

func init() {
SchemeBuilder.Register(&AzureMachine{}, &AzureMachineList{})
}
45 changes: 43 additions & 2 deletions api/v1alpha4/conditions_consts.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,6 @@ import clusterv1 "sigs.k8s.io/cluster-api/api/v1alpha4"

// AzureCluster Conditions and Reasons.
const (
// NetworkInfrastructureReadyCondition reports of current status of cluster infrastructure.
NetworkInfrastructureReadyCondition clusterv1.ConditionType = "NetworkInfrastructureReady"
// NamespaceNotAllowedByIdentity used to indicate cluster in a namespace not allowed by identity.
NamespaceNotAllowedByIdentity = "NamespaceNotAllowedByIdentity"
)
Expand Down Expand Up @@ -75,3 +73,46 @@ const (
// ScaleSetModelOutOfDateReason describes the machine pool model being out of date.
ScaleSetModelOutOfDateReason = "ScaleSetModelOutOfDate"
)

// Azure Services Conditions and Reasons.
const (
// ResourceGroupReadyCondition means the resource group exists and is ready to be used.
ResourceGroupReadyCondition clusterv1.ConditionType = "ResourceGroupReady"
// VNetReadyCondition means the virtual network exists and is ready to be used.
VNetReadyCondition clusterv1.ConditionType = "VNetReady"
// SecurityGroupsReadyCondition means the security groups exist and are ready to be used.
SecurityGroupsReadyCondition clusterv1.ConditionType = "SecurityGroupsReady"
// RouteTablesReadyCondition means the route tables exist and are ready to be used.
RouteTablesReadyCondition clusterv1.ConditionType = "RouteTablesReady"
// PublicIPsReadyCondition means the public IPs exist and are ready to be used.
PublicIPsReadyCondition clusterv1.ConditionType = "PublicIPsReady"
// NATGatewaysReadyCondition means the NAT gateways exist and are ready to be used.
NATGatewaysReadyCondition clusterv1.ConditionType = "NATGatewaysReady"
// SubnetsReadyCondition means the subnets exist and are ready to be used.
SubnetsReadyCondition clusterv1.ConditionType = "SubnetsReady"
// LoadBalancersReadyCondition means the load balancers exist and are ready to be used.
LoadBalancersReadyCondition clusterv1.ConditionType = "LoadBalancersReady"
// PrivateDNSReadyCondition means the private DNS exists and is ready to be used.
PrivateDNSReadyCondition clusterv1.ConditionType = "PrivateDNSReady"
// BastionHostReadyCondition means the bastion host exists and is ready to be used.
BastionHostReadyCondition clusterv1.ConditionType = "BastionHostReady"
// InboundNATRulesReadyCondition means the inbound NAT rules exist and are ready to be used.
InboundNATRulesReadyCondition clusterv1.ConditionType = "InboundNATRulesReady"
// AvailabilitySetReadyCondition means the availability set exists and is ready to be used.
AvailabilitySetReadyCondition clusterv1.ConditionType = "AvailabilitySetReady"
// RoleAssignmentReadyCondition means the role assignment exists and is ready to be used.
RoleAssignmentReadyCondition clusterv1.ConditionType = "RoleAssignmentReady"

// CreatingReason means the resource is being created.
CreatingReason = "Creating"
// FailedReason means the resource failed to be created.
FailedReason = "Failed"
// DeletingReason means the resource is being deleted.
DeletingReason = "Deleting"
// DeletedReason means the resource was deleted.
DeletedReason = "Deleted"
// DeletionFailedReason means the resource failed to be deleted.
DeletionFailedReason = "DeletionFailed"
// UpdatingReason means the resource is being updated.
UpdatingReason = "Updating"
)
30 changes: 23 additions & 7 deletions api/v1alpha4/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,21 +29,37 @@ const (
Node string = "node"
)

// Futures is a slice of Future.
type Futures []Future

const (
// PatchFuture is a future that was derived from a PATCH request.
PatchFuture string = "PATCH"
// PutFuture is a future that was derived from a PUT request.
PutFuture string = "PUT"
// DeleteFuture is a future that was derived from a DELETE request.
DeleteFuture string = "DELETE"
)

// Future contains the data needed for an Azure long-running operation to continue across reconcile loops.
type Future struct {
// Type describes the type of future, update, create, delete, etc
// Type describes the type of future, such as update, create, delete, etc.
Type string `json:"type"`

// ResourceGroup is the Azure resource group for the resource
// ResourceGroup is the Azure resource group for the resource.
// +optional
ResourceGroup string `json:"resourceGroup,omitempty"`

// Name is the name of the Azure resource
// +optional
Name string `json:"name,omitempty"`
// ServiceName is the name of the Azure service.
// Together with the name of the resource, this forms the unique identifier for the future.
ServiceName string `json:"serviceName"`

// Name is the name of the Azure resource.
// Together with the service name, this forms the unique identifier for the future.
Name string `json:"name"`

// FutureData is the base64 url encoded json Azure AutoRest Future
FutureData string `json:"futureData,omitempty"`
// Data is the base64 url encoded json Azure AutoRest Future.
Data string `json:"data,omitempty"`
}

// NetworkSpec specifies what the Azure networking resources should look like.
Expand Down
29 changes: 29 additions & 0 deletions api/v1alpha4/zz_generated.deepcopy.go

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

54 changes: 54 additions & 0 deletions azure/converters/futures.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*
Copyright 2021 The Kubernetes 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 converters

import (
"encoding/base64"

azureautorest "github.com/Azure/go-autorest/autorest/azure"
"github.com/pkg/errors"
infrav1 "sigs.k8s.io/cluster-api-provider-azure/api/v1alpha4"
)

// SDKToFuture converts an SDK future to an infrav1.Future.
func SDKToFuture(future azureautorest.FutureAPI, futureType, service, resourceName, rgName string) (*infrav1.Future, error) {
CecileRobertMichon marked this conversation as resolved.
Show resolved Hide resolved
jsonData, err := future.MarshalJSON()
if err != nil {
return nil, errors.Wrap(err, "failed to marshal async future")
}

return &infrav1.Future{
Type: futureType,
ResourceGroup: rgName,
ServiceName: service,
Name: resourceName,
Data: base64.URLEncoding.EncodeToString(jsonData),
}, nil
}

// FutureToSDK converts an infrav1.Future to an SDK future.
func FutureToSDK(future infrav1.Future) (azureautorest.FutureAPI, error) {
futureData, err := base64.URLEncoding.DecodeString(future.Data)
if err != nil {
return nil, errors.Wrap(err, "failed to base64 decode future data")
}
var genericFuture azureautorest.Future
if err := genericFuture.UnmarshalJSON(futureData); err != nil {
return nil, errors.Wrap(err, "failed to unmarshal future data")
}
return &genericFuture, nil
}
Loading