-
Notifications
You must be signed in to change notification settings - Fork 41
/
promoperator_component.go
283 lines (243 loc) · 10.2 KB
/
promoperator_component.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
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
// Copyright (c) 2022, 2023, Oracle and/or its affiliates.
// Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl.
package operator
import (
"context"
"path/filepath"
"github.com/verrazzano/verrazzano/pkg/k8s/ready"
"github.com/verrazzano/verrazzano/pkg/k8sutil"
"github.com/verrazzano/verrazzano/pkg/vzcr"
vzapi "github.com/verrazzano/verrazzano/platform-operator/apis/verrazzano/v1alpha1"
installv1beta1 "github.com/verrazzano/verrazzano/platform-operator/apis/verrazzano/v1beta1"
"github.com/verrazzano/verrazzano/platform-operator/constants"
"github.com/verrazzano/verrazzano/platform-operator/controllers/verrazzano/component/authproxy"
cmconstants "github.com/verrazzano/verrazzano/platform-operator/controllers/verrazzano/component/certmanager/constants"
"github.com/verrazzano/verrazzano/platform-operator/controllers/verrazzano/component/common"
"github.com/verrazzano/verrazzano/platform-operator/controllers/verrazzano/component/helm"
"github.com/verrazzano/verrazzano/platform-operator/controllers/verrazzano/component/networkpolicies"
"github.com/verrazzano/verrazzano/platform-operator/controllers/verrazzano/component/nginx"
"github.com/verrazzano/verrazzano/platform-operator/controllers/verrazzano/component/spi"
"github.com/verrazzano/verrazzano/platform-operator/controllers/verrazzano/component/vmo"
"github.com/verrazzano/verrazzano/platform-operator/internal/config"
networkv1 "k8s.io/api/networking/v1"
"k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/types"
clipkg "sigs.k8s.io/controller-runtime/pkg/client"
)
// ComponentName is the name of the component
const ComponentName = common.PrometheusOperatorComponentName
// ComponentNamespace is the namespace of the component
const ComponentNamespace = common.PrometheusOperatorComponentNamespace
// ComponentJSONName is the JSON name of the component in the CRD
const ComponentJSONName = "prometheusOperator"
const chartDir = "prometheus-community/kube-prometheus-stack"
const (
prometheusHostName = "prometheus.vmi.system"
prometheusCertificateName = "system-tls-prometheus"
istioPrometheus = "prometheus-server"
alertmanagerHostName = "alertmanager"
alertmanagerCertificateName = "system-tls-alertmanager"
)
type prometheusComponent struct {
helm.HelmComponent
}
func NewComponent() spi.Component {
return prometheusComponent{
helm.HelmComponent{
ReleaseName: ComponentName,
JSONName: ComponentJSONName,
ChartDir: filepath.Join(config.GetThirdPartyDir(), chartDir),
ChartNamespace: ComponentNamespace,
IgnoreNamespaceOverride: true,
SupportsOperatorInstall: true,
SupportsOperatorUninstall: true,
MinVerrazzanoVersion: constants.VerrazzanoVersion1_3_0,
ImagePullSecretKeyname: "global.imagePullSecrets[0].name",
ValuesFile: filepath.Join(config.GetHelmOverridesDir(), "prometheus-operator-values.yaml"),
// the dependency on the VMO is to ensure that a persistent volume is retained and the claim is released
// so that persistent storage can be migrated to the new Prometheus
Dependencies: []string{networkpolicies.ComponentName, nginx.ComponentName, cmconstants.CertManagerComponentName, vmo.ComponentName},
AppendOverridesFunc: AppendOverrides,
GetInstallOverridesFunc: GetOverrides,
},
}
}
// IsEnabled returns true if the Prometheus Operator is enabled or if the component is not specified
// in the Verrazzano CR.
func (c prometheusComponent) IsEnabled(effectiveCR runtime.Object) bool {
return vzcr.IsPrometheusOperatorEnabled(effectiveCR)
}
// IsReady checks if the Prometheus Operator deployment is ready
func (c prometheusComponent) IsReady(ctx spi.ComponentContext) bool {
if c.HelmComponent.IsReady(ctx) {
return isPrometheusOperatorReady(ctx)
}
return false
}
func (c prometheusComponent) IsAvailable(ctx spi.ComponentContext) (reason string, available vzapi.ComponentAvailability) {
listOptions, err := prometheusOperatorListOptions()
if err != nil {
return err.Error(), vzapi.ComponentUnavailable
}
return (&ready.AvailabilityObjects{DeploymentSelectors: []clipkg.ListOption{listOptions}}).IsAvailable(ctx.Log(), ctx.Client())
}
// MonitorOverrides checks whether monitoring is enabled for install overrides sources
func (c prometheusComponent) MonitorOverrides(ctx spi.ComponentContext) bool {
if ctx.EffectiveCR().Spec.Components.PrometheusOperator == nil {
return false
}
if ctx.EffectiveCR().Spec.Components.PrometheusOperator.MonitorChanges != nil {
return *ctx.EffectiveCR().Spec.Components.PrometheusOperator.MonitorChanges
}
return true
}
// PreInstall updates resources necessary for the Prometheus Operator Component installation
func (c prometheusComponent) PreInstall(ctx spi.ComponentContext) error {
if err := preInstallUpgrade(ctx); err != nil {
return err
}
if err := deleteNetworkPolicy(ctx); err != nil {
return err
}
return c.HelmComponent.PreInstall(ctx)
}
// PreUpgrade updates resources necessary for the Prometheus Operator Component installation
func (c prometheusComponent) PreUpgrade(ctx spi.ComponentContext) error {
if err := deleteNetworkPolicy(ctx); err != nil {
return err
}
if err := preInstallUpgrade(ctx); err != nil {
return err
}
return c.HelmComponent.PreUpgrade(ctx)
}
// PostInstall creates/updates associated resources after this component is installed
func (c prometheusComponent) PostInstall(ctx spi.ComponentContext) error {
if err := postInstallUpgrade(ctx); err != nil {
return err
}
// these need to be set for helm component post install processing
c.IngressNames = c.GetIngressNames(ctx)
c.Certificates = c.GetCertificateNames(ctx)
return c.HelmComponent.PostInstall(ctx)
}
// PostInstall creates/updates associated resources after this component is upgraded
func (c prometheusComponent) PostUpgrade(ctx spi.ComponentContext) error {
if err := postInstallUpgrade(ctx); err != nil {
return err
}
return c.HelmComponent.PostUpgrade(ctx)
}
// ValidateInstall verifies the installation of the Verrazzano object
func (c prometheusComponent) ValidateInstall(vz *vzapi.Verrazzano) error {
convertedVZ := installv1beta1.Verrazzano{}
if err := common.ConvertVerrazzanoCR(vz, &convertedVZ); err != nil {
return err
}
if err := checkExistingCNEPrometheus(vz); err != nil {
return err
}
return c.validatePrometheusOperator(&convertedVZ)
}
// ValidateUpgrade verifies the upgrade of the Verrazzano object
func (c prometheusComponent) ValidateUpdate(old *vzapi.Verrazzano, new *vzapi.Verrazzano) error {
convertedVZ := installv1beta1.Verrazzano{}
if err := common.ConvertVerrazzanoCR(new, &convertedVZ); err != nil {
return err
}
return c.validatePrometheusOperator(&convertedVZ)
}
// ValidateInstall verifies the installation of the Verrazzano object
func (c prometheusComponent) ValidateInstallV1Beta1(vz *installv1beta1.Verrazzano) error {
if err := checkExistingCNEPrometheus(vz); err != nil {
return err
}
return c.validatePrometheusOperator(vz)
}
// ValidateUpgrade verifies the upgrade of the Verrazzano object
func (c prometheusComponent) ValidateUpdateV1Beta1(old *installv1beta1.Verrazzano, new *installv1beta1.Verrazzano) error {
return c.validatePrometheusOperator(new)
}
// getIngressNames - gets the names of the ingresses associated with this component
func (c prometheusComponent) GetIngressNames(ctx spi.ComponentContext) []types.NamespacedName {
var ingressNames []types.NamespacedName
if !vzcr.IsPrometheusEnabled(ctx.EffectiveCR()) || !vzcr.IsNGINXEnabled(ctx.EffectiveCR()) {
return ingressNames
}
ns := constants.VerrazzanoSystemNamespace
if vzcr.IsAuthProxyEnabled(ctx.EffectiveCR()) {
ns = authproxy.ComponentNamespace
}
ingressNames = append(ingressNames, types.NamespacedName{
Namespace: ns,
Name: constants.PrometheusIngress,
})
alertmanagerEnabled, err := vzcr.IsAlertmanagerEnabled(ctx.EffectiveCR(), ctx)
if err != nil {
ctx.Log().Errorf("error checking if alertmanager is enabled , %v", err)
}
if alertmanagerEnabled {
ingressNames = append(ingressNames, types.NamespacedName{
Namespace: ns,
Name: constants.AlertmanagerIngress,
})
}
return ingressNames
}
// getCertificateNames - gets the names of the TLS ingress certificates associated with this component
func (c prometheusComponent) GetCertificateNames(ctx spi.ComponentContext) []types.NamespacedName {
var certificateNames []types.NamespacedName
if !vzcr.IsPrometheusEnabled(ctx.EffectiveCR()) || !vzcr.IsNGINXEnabled(ctx.EffectiveCR()) {
return certificateNames
}
ns := constants.VerrazzanoSystemNamespace
if vzcr.IsAuthProxyEnabled(ctx.EffectiveCR()) {
ns = authproxy.ComponentNamespace
}
return append(certificateNames, types.NamespacedName{
Namespace: ns,
Name: prometheusCertificateName,
})
}
// checkExistingCNEPrometheus checks if Prometheus is already installed
// OLCNE Istio module may have Prometheus installed in istio-system namespace
func checkExistingCNEPrometheus(vz runtime.Object) error {
if !vzcr.IsPrometheusEnabled(vz) {
return nil
}
if err := k8sutil.ErrorIfDeploymentExists(constants.IstioSystemNamespace, istioPrometheus); err != nil {
return err
}
if err := k8sutil.ErrorIfServiceExists(constants.IstioSystemNamespace, istioPrometheus); err != nil {
return err
}
return nil
}
// PostUninstall is the Prometheus Operator PostInstall SPI function
func (c prometheusComponent) PostUninstall(ctx spi.ComponentContext) error {
return deletePrometheusStackIngresses(ctx)
}
// deletePrometheusStackIngresses deletes Prometheus and Alertmanager ingresses
func deletePrometheusStackIngresses(ctx spi.ComponentContext) error {
err := deleteIngress(constants.PrometheusIngress, ctx)
if err != nil {
return err
}
return deleteIngress(constants.AlertmanagerIngress, ctx)
}
func deleteIngress(ingressName string, ctx spi.ComponentContext) error {
ingress := &networkv1.Ingress{
ObjectMeta: metav1.ObjectMeta{
Name: ingressName,
Namespace: constants.VerrazzanoSystemNamespace,
},
}
err := ctx.Client().Delete(context.TODO(), ingress)
if err != nil && !errors.IsNotFound(err) {
ctx.Log().Errorf("Error deleting ingress %s, %v", ingressName, err)
return err
}
return nil
}