Skip to content

Commit

Permalink
ARO-13380 - metrics: cwp status
Browse files Browse the repository at this point in the history
  • Loading branch information
Lini Kurien authored and LiniSusan committed Dec 30, 2024
1 parent 447bf0c commit 0303459
Show file tree
Hide file tree
Showing 168 changed files with 125,699 additions and 0 deletions.
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ require (
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/keyvault/armkeyvault v1.4.0
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/msi/armmsi v1.2.0
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork/v2 v2.2.1
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork/v6 v6.2.0
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/storage/armstorage v1.5.0
github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azsecrets v1.1.0
github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.3.2
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/msi/armmsi v1.2.0 h1:z4Yei
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/msi/armmsi v1.2.0/go.mod h1:rko9SzMxcMk0NJsNAxALEGaTYyy79bNRwxgJfrH0Spw=
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork/v2 v2.2.1 h1:bWh0Z2rOEDfB/ywv/l0iHN1JgyazE6kW/aIA89+CEK0=
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork/v2 v2.2.1/go.mod h1:Bzf34hhAE9NSxailk8xVeLEZbUjOXcC+GnU1mMKdhLw=
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork/v6 v6.2.0 h1:HYGD75g0bQ3VO/Omedm54v4LrD3B1cGImuRF3AJ5wLo=
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork/v6 v6.2.0/go.mod h1:ulHyBFJOI0ONiRL4vcJTmS7rx18jQQlEPmAgo80cRdM=
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources v1.2.0 h1:Dd+RhdJn0OTtVGaeDLZpcumkIVCtA/3/Fo42+eoYvVM=
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources v1.2.0/go.mod h1:5kakwfW5CjC9KK+Q4wjXAg+ShuIm2mBMua0ZFj2C8PE=
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/storage/armstorage v1.5.0 h1:AifHbc4mg0x9zW52WOpKbsHaDKuRhlI7TVl47thgQ70=
Expand Down
1 change: 1 addition & 0 deletions pkg/monitor/cluster/cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,7 @@ func (mon *Monitor) Monitor(ctx context.Context) (errs []error) {
mon.emitCertificateExpirationStatuses,
mon.emitEtcdCertificateExpiry,
mon.emitPrometheusAlerts, // at the end for now because it's the slowest/least reliable
mon.emitCWPStatus,
} {
err = f(ctx)
if err != nil {
Expand Down
250 changes: 250 additions & 0 deletions pkg/monitor/cluster/clusterwideproxystatus.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,250 @@
package cluster

// Copyright (c) Microsoft Corporation.
// Licensed under the Apache License 2.0.

import (
"context"
"fmt"
"log"
"net/url"
"strconv"
"strings"

"github.com/Azure/azure-sdk-for-go/sdk/azidentity"
"github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork/v6"
"github.com/Azure/go-autorest/autorest/azure"
"github.com/sirupsen/logrus"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

apisubnet "github.com/Azure/ARO-RP/pkg/api/util/subnet"
arov1alpha1 "github.com/Azure/ARO-RP/pkg/operator/apis/aro.openshift.io/v1alpha1"
)

const (
cwp = "clusterWideProxy.status"
cwpErrorMessage = "NoProxy entries are incorrect"
)

var mandatory_no_proxies = "localhost,127.0.0.1,.svc,.cluster.local.,168.63.129.16,169.254.169.254"

func contains(slice []string, item string) bool {
if strings.Contains(fmt.Sprint(slice), item) {
return true
} else {
return false
}
}

func (mon *Monitor) emitCWPStatus(ctx context.Context) error {
mon.hourlyRun = true
proxyConfig, err := mon.configcli.ConfigV1().Proxies().Get(ctx, "cluster", metav1.GetOptions{})
if err != nil {
log.Fatalf("Error in getting the cluster wide proxy: %v", err)
}
if proxyConfig.Spec.HTTPProxy == "" && proxyConfig.Spec.HTTPSProxy == "" && proxyConfig.Spec.NoProxy == "" {
mon.emitGauge(cwp, 1, map[string]string{
"status": strconv.FormatBool(false),
"Message": "CWP not enabled",
})
} else {
no_proxy_list := strings.Split(proxyConfig.Spec.NoProxy, ",")
for _, mandatory_no_proxy := range strings.Split(mandatory_no_proxies, ",") {
if !contains(no_proxy_list, mandatory_no_proxy) {
mon.emitGauge(cwp, 1, map[string]string{
"status": "True",
"Message": "CWP enabled but missing " + mandatory_no_proxy + " in the no_proxy list",
})
if mon.hourlyRun {
mon.log.WithFields(logrus.Fields{
"metric": cwp,
"status": strconv.FormatBool(true),
"message": "CWP enabled but missing " + mandatory_no_proxy + " in the no_proxy list",
}).Print()
}
}
}
cred, err := azidentity.NewDefaultAzureCredential(nil)
if err != nil {
log.Fatalf("failed to obtain a credential: %v", err)
}
mastersubnetID, err := azure.ParseResourceID(mon.oc.Properties.MasterProfile.SubnetID)
if err != nil {
return err
}
clientFactory, err := armnetwork.NewClientFactory(mastersubnetID.SubscriptionID, cred, nil)
if err != nil {
log.Fatalf("failed to create client: %v", err)
}
masterVnetID, _, err := apisubnet.Split(mon.oc.Properties.MasterProfile.SubnetID)
if err != nil {
return err
}
mastervnetId, err := azure.ParseResourceID(masterVnetID)
if err != nil {
return err
}
res, err := clientFactory.NewSubnetsClient().Get(ctx, mastersubnetID.ResourceGroup, mastervnetId.ResourceName, mastersubnetID.ResourceName, &armnetwork.SubnetsClientGetOptions{Expand: nil})
if err != nil {
log.Fatalf("failed to finish the request: %v", err)
}
mastermachineCIDR := *res.Properties.AddressPrefix
if !contains(no_proxy_list, mastermachineCIDR) {
mon.emitGauge(cwp, 1, map[string]string{
"status": strconv.FormatBool(true),
"Message": "CWP enabled but missing master machineCIDR " + mastermachineCIDR + " in the no_proxy list",
})
if mon.hourlyRun {
mon.log.WithFields(logrus.Fields{
"metric": cwp,
"status": true,
"message": "CWP enabled but missing master machineCIDR " + mastermachineCIDR + " in the no_proxy list",
}).Print()
}
}
for _, workerProfile := range mon.oc.Properties.WorkerProfiles {
workersubnetID, err := azure.ParseResourceID(workerProfile.SubnetID)
if err != nil {
return err
}
workerVnetID, _, err := apisubnet.Split(workerProfile.SubnetID)
if err != nil {
return err
}
workervnetId, err := azure.ParseResourceID(workerVnetID)
if err != nil {
return err
}
workerres, err := clientFactory.NewSubnetsClient().Get(ctx, workersubnetID.ResourceGroup, workervnetId.ResourceName, workersubnetID.ResourceName, &armnetwork.SubnetsClientGetOptions{Expand: nil})
if err != nil {
log.Fatalf("failed to finish the request: %v", err)
}
workermachinesCIDR := *workerres.Properties.AddressPrefix
if !contains(no_proxy_list, mastermachineCIDR) {
mon.emitGauge(cwp, 1, map[string]string{
"status": strconv.FormatBool(true),
"Message": "CWP enabled but missing Worker machine CIDR " + workermachinesCIDR + " in the no_proxy list",
})
if mon.hourlyRun {
mon.log.WithFields(logrus.Fields{
"metric": cwp,
"status": true,
"message": "CWP enabled but missing Worker machine CIDR " + workermachinesCIDR + " in the no_proxy list",
}).Print()
}
}
}
networkConfig, err := mon.configcli.ConfigV1().Networks().Get(ctx, "cluster", metav1.GetOptions{})
if err != nil {
log.Fatalf("Error in getting network info: %v", err)
}
for _, network := range networkConfig.Spec.ClusterNetwork {
if !contains(no_proxy_list, network.CIDR) {
mon.emitGauge(cwp, 1, map[string]string{
"status": strconv.FormatBool(true),
"Message": "CWP enabled but missing PodCIDR " + network.CIDR + " in the no_proxy list",
})
if mon.hourlyRun {
mon.log.WithFields(logrus.Fields{
"metric": cwp,
"status": true,
"message": "CWP enabled but missing PodCIDR " + network.CIDR + " in the no_proxy list",
}).Print()
}
}
}
for _, network := range networkConfig.Spec.ServiceNetwork {
if !contains(no_proxy_list, network) {
mon.emitGauge(cwp, 1, map[string]string{
"status": strconv.FormatBool(true),
"Message": "CWP enabled but missing ServiceCIDR " + network + " in the no_proxy list",
})
if mon.hourlyRun {
mon.log.WithFields(logrus.Fields{
"metric": cwp,
"status": true,
"message": "CWP enabled but Service CIDR " + network + " is missing or incorrect",
}).Print()
}
}
}
cluster, err := mon.arocli.AroV1alpha1().Clusters().Get(ctx, arov1alpha1.SingletonClusterName, metav1.GetOptions{})
if err != nil {
return err
}
for _, gatewayDomain := range cluster.Spec.GatewayDomains {
if !contains(no_proxy_list, gatewayDomain) {
mon.emitGauge(cwp, 1, map[string]string{
"status": strconv.FormatBool(true),
"Message": "CWP enabled but missing Gateway domain " + gatewayDomain + " in the no_proxy list",
})
if mon.hourlyRun {
mon.log.WithFields(logrus.Fields{
"metric": cwp,
"status": true,
"message": "CWP enabled but Gateway domain " + gatewayDomain + "is missing or incorrect",
}).Print()
}
}
}
infraConfig, err := mon.configcli.ConfigV1().Infrastructures().Get(ctx, "cluster", metav1.GetOptions{})
if err != nil {
log.Fatalf("Error in getting network info: %v", err)
}
apiServerIntURL, err := url.Parse(infraConfig.Status.APIServerInternalURL)
if err != nil {
return err
}
apiServerIntdomain := strings.Split(apiServerIntURL.Host, ":")[0]
if !contains(no_proxy_list, apiServerIntdomain) {
mon.emitGauge(cwp, 1, map[string]string{
"status": strconv.FormatBool(true),
"Message": "CWP enabled but missing APIServerInternal URL " + apiServerIntdomain + " in the no_proxy list",
})
if mon.hourlyRun {
mon.log.WithFields(logrus.Fields{
"metric": cwp,
"status": true,
"message": "CWP enabled but APIServerInternal URL " + apiServerIntdomain + " is missing or incorrect",
}).Print()
}
}
apiServerProfileURL, err := url.Parse(mon.oc.Properties.APIServerProfile.URL)
if err != nil {
return err
}
apiServerProfiledomain := strings.Split(apiServerProfileURL.Host, ":")[0]
if !contains(no_proxy_list, apiServerProfiledomain) {
mon.emitGauge(cwp, 1, map[string]string{
"status": strconv.FormatBool(true),
"Message": "CWP enabled but missing APiServerProfile URL " + apiServerProfiledomain + " in the no_proxy list",
})
if mon.hourlyRun {
mon.log.WithFields(logrus.Fields{
"metric": cwp,
"status": true,
"message": "CWP enabled but APiServerProfile URL " + apiServerProfiledomain + " is missing or incorrect",
}).Print()
}
}
consolProfileURL, err := url.Parse(mon.oc.Properties.ConsoleProfile.URL)
if err != nil {
return err
}
consoleProfiledomain := strings.Split(consolProfileURL.Host, ":")[0]
if !contains(no_proxy_list, consoleProfiledomain) {
mon.emitGauge(cwp, 1, map[string]string{
"status": strconv.FormatBool(true),
"Message": "CWP enabled but missing Console Profile URL " + consoleProfiledomain + " in the no_proxy list",
})
if mon.hourlyRun {
mon.log.WithFields(logrus.Fields{
"metric": cwp,
"status": true,
"message": "CWP enabled but Console Profile URL " + consoleProfiledomain + " is missing or incorrect",
}).Print()
}
}
}
return nil
}
Loading

0 comments on commit 0303459

Please sign in to comment.