/
flow_reconciler.go
131 lines (109 loc) · 4.61 KB
/
flow_reconciler.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
// Copyright (c) 2023 SAP SE or an SAP affiliate company. All rights reserved. This file is licensed under the Apache Software License, v. 2 except as noted otherwise in the LICENSE file
// 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 infrastructure
import (
"context"
"github.com/gardener/gardener/extensions/pkg/controller"
extensionsv1alpha1 "github.com/gardener/gardener/pkg/apis/extensions/v1alpha1"
"github.com/go-logr/logr"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/client-go/rest"
"sigs.k8s.io/controller-runtime/pkg/client"
"github.com/gardener/gardener-extension-provider-azure/pkg/apis/azure/helper"
"github.com/gardener/gardener-extension-provider-azure/pkg/controller/infrastructure/infraflow"
"github.com/gardener/gardener-extension-provider-azure/pkg/internal"
infrainternal "github.com/gardener/gardener-extension-provider-azure/pkg/internal/infrastructure"
)
// FlowReconciler an implementation of an infrastructure reconciler using native SDKs.
type FlowReconciler struct {
client client.Client
restConfig *rest.Config
log logr.Logger
disableProjectedTokenMount bool
}
// NewFlowReconciler creates a new flow reconciler.
func NewFlowReconciler(a *actuator, log logr.Logger, projToken bool) (Reconciler, error) {
return &FlowReconciler{
client: a.client,
restConfig: a.restConfig,
log: log,
disableProjectedTokenMount: projToken,
}, nil
}
// Reconcile reconciles the infrastructure and returns the status (state of the world), the state (input for the next loops) and any errors that occurred.
func (f *FlowReconciler) Reconcile(ctx context.Context, infra *extensionsv1alpha1.Infrastructure, cluster *controller.Cluster) error {
infraState, err := helper.InfrastructureStateFromRaw(infra.Status.State)
if err != nil {
return err
}
tf, err := internal.NewTerraformer(f.log, f.restConfig, infrainternal.TerraformerPurpose, infra, f.disableProjectedTokenMount)
if err != nil {
return err
}
if !tf.IsStateEmpty(ctx) {
// this is a special case when migrating from Terraform. If TF had created any resources (meaning there is an actual tf.state written)
// we mark that there are infra resources created.
infraState.Data[infraflow.CreatedResourcesExistKey] = "true"
}
auth, err := internal.GetClientAuthData(ctx, f.client, infra.Spec.SecretRef, false)
if err != nil {
return err
}
factory, err := NewAzureClientFactory(ctx, f.client, infra.Spec.SecretRef)
if err != nil {
return err
}
persistFunc := func(ctx context.Context, state *runtime.RawExtension) error {
return patchProviderStatusAndState(ctx, f.client, infra, nil, state)
}
fctx, err := infraflow.NewFlowContext(factory, auth, f.log, infra, cluster, infraState, persistFunc)
if err != nil {
return err
}
status, state, err := fctx.Reconcile(ctx)
if err != nil {
return err
}
if err := patchProviderStatusAndState(ctx, f.client, infra, status, state); err != nil {
return err
}
return CleanupTerraformerResources(ctx, tf)
}
// Delete deletes the infrastructure resource using the flow reconciler.
func (f *FlowReconciler) Delete(ctx context.Context, infra *extensionsv1alpha1.Infrastructure, cluster *controller.Cluster) error {
factory, err := NewAzureClientFactory(ctx, f.client, infra.Spec.SecretRef)
if err != nil {
return err
}
infraState, err := helper.InfrastructureStateFromRaw(infra.Status.State)
if err != nil {
return err
}
fctx, err := infraflow.NewFlowContext(factory, nil, f.log, infra, cluster, infraState, nil)
if err != nil {
return err
}
err = fctx.Delete(ctx)
if err != nil {
return err
}
tf, err := internal.NewTerraformer(f.log, f.restConfig, infrainternal.TerraformerPurpose, infra, f.disableProjectedTokenMount)
if err != nil {
return err
}
return CleanupTerraformerResources(ctx, tf)
}
// Restore implements the restoration of an infrastructure resource during the control plane migration.
func (f *FlowReconciler) Restore(ctx context.Context, infra *extensionsv1alpha1.Infrastructure, cluster *controller.Cluster) error {
return f.Reconcile(ctx, infra, cluster)
}