123 lines
4.7 KiB
Python
123 lines
4.7 KiB
Python
#
|
|
# Copyright 2022 Google LLC
|
|
#
|
|
# 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.
|
|
#
|
|
|
|
import re
|
|
import time
|
|
|
|
from collections import defaultdict
|
|
from pydoc import doc
|
|
from collections import defaultdict
|
|
from google.protobuf import field_mask_pb2
|
|
from . import metrics, networks, limits
|
|
|
|
|
|
def get_firewalls_dict(config: dict):
|
|
'''
|
|
Calls the Asset Inventory API to get all VPC Firewall Rules under the GCP organization.
|
|
|
|
Parameters:
|
|
config (dict): The dict containing config like clients and limits
|
|
Returns:
|
|
firewalls_dict (dictionary of dictionary: int): Keys are projects, subkeys are networks, values count #of VPC Firewall Rules
|
|
'''
|
|
|
|
firewalls_dict = defaultdict(int)
|
|
read_mask = field_mask_pb2.FieldMask()
|
|
read_mask.FromJsonString('name,versionedResources')
|
|
|
|
response = config["clients"]["asset_client"].search_all_resources(
|
|
request={
|
|
"scope": f"organizations/{config['organization']}",
|
|
"asset_types": ["compute.googleapis.com/Firewall"],
|
|
"read_mask": read_mask,
|
|
"page_size": config["page_size"],
|
|
})
|
|
for resource in response:
|
|
project_id = re.search("(compute.googleapis.com/projects/)([\w\-\d]+)",
|
|
resource.name).group(2)
|
|
network_name = ""
|
|
for versioned in resource.versioned_resources:
|
|
for field_name, field_value in versioned.resource.items():
|
|
if field_name == "network":
|
|
network_name = re.search("[a-z0-9\-]*$", field_value).group(0)
|
|
firewalls_dict[project_id] = defaultdict(
|
|
int
|
|
) if not project_id in firewalls_dict else firewalls_dict[project_id]
|
|
firewalls_dict[project_id][
|
|
network_name] = 1 if not network_name in firewalls_dict[
|
|
project_id] else firewalls_dict[project_id][network_name] + 1
|
|
break
|
|
break
|
|
return firewalls_dict
|
|
|
|
|
|
def get_firewalls_data(config, metrics_dict, project_quotas_dict,
|
|
firewalls_dict):
|
|
'''
|
|
Gets the data for VPC Firewall Rules per VPC Network and writes it to the metric defined in vpc_firewalls_metric.
|
|
|
|
Parameters:
|
|
config (dict): The dict containing config like clients and limits
|
|
metrics_dict (dictionary of dictionary of string: string): metrics names and descriptions.
|
|
project_quotas_dict (dictionary of string:int): Dictionary with the network link as key and the limit as value.
|
|
firewalls_dict (dictionary of of dictionary of string: string): Keys are projects, subkeys are networks, values count #of VPC Firewall Rules
|
|
Returns:
|
|
None
|
|
'''
|
|
|
|
timestamp = time.time()
|
|
for project_id in config["monitored_projects"]:
|
|
|
|
current_quota_limit = project_quotas_dict[project_id]['global']["firewalls"]
|
|
if current_quota_limit is None:
|
|
print(
|
|
f"Could not determine VPC firewal rules metric for projects/{project_id} due to missing quotas"
|
|
)
|
|
continue
|
|
|
|
network_dict = networks.get_networks(config, project_id)
|
|
|
|
project_usage = 0
|
|
for net in network_dict:
|
|
usage = 0
|
|
if project_id in firewalls_dict and net['network_name'] in firewalls_dict[
|
|
project_id]:
|
|
usage = firewalls_dict[project_id][net['network_name']]
|
|
project_usage += usage
|
|
metric_labels = {
|
|
'project': project_id,
|
|
'network_name': net['network_name']
|
|
}
|
|
metrics.append_data_to_series_buffer(
|
|
config,
|
|
metrics_dict["metrics_per_project"][f"firewalls"]["usage"]["name"],
|
|
usage, metric_labels, timestamp=timestamp)
|
|
|
|
metric_labels = {'project': project_id}
|
|
# firewall quotas are per project, not per single VPC
|
|
metrics.append_data_to_series_buffer(
|
|
config,
|
|
metrics_dict["metrics_per_project"][f"firewalls"]["limit"]["name"],
|
|
current_quota_limit['limit'], metric_labels, timestamp=timestamp)
|
|
metrics.append_data_to_series_buffer(
|
|
config, metrics_dict["metrics_per_project"][f"firewalls"]["utilization"]
|
|
["name"], project_usage / current_quota_limit['limit']
|
|
if current_quota_limit['limit'] != 0 else 0, metric_labels,
|
|
timestamp=timestamp)
|
|
print(
|
|
f"Buffered number of VPC Firewall Rules to metric for projects/{project_id}"
|
|
)
|