Skip to content

Commit

Permalink
gcp - add autoscalers resource, actions, docs (cloud-custodian#4538)
Browse files Browse the repository at this point in the history
  • Loading branch information
PMitrafanau authored and kapilt committed Aug 21, 2019
1 parent 9b263e6 commit 64535c8
Show file tree
Hide file tree
Showing 13 changed files with 1,526 additions and 942 deletions.
26 changes: 26 additions & 0 deletions docs/source/gcp/examples/gce-autoscaler.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
Compute Engine - Enforce minimal CPU utilization target for autoscalers
=======================================================================

In the example below, the policy checks the CPU utilization target of newly added autoscalers and modifies it when needed
guaranteeing the target won't be less than 80%.

.. code-block:: yaml
vars:
min-utilization-target: &min-utilization-target 0.8
policies:
- name: gcp-autoscalers-enforced
resource: gcp.autoscaler
mode:
type: gcp-audit
methods:
- v1.compute.autoscalers.insert
filters:
- type: value
key: autoscalingPolicy.cpuUtilization.utilizationTarget
op: less-than
value: *min-utilization-target
actions:
- type: set
cpuUtilization:
utilizationTarget: 0.8
133 changes: 133 additions & 0 deletions tools/c7n_gcp/c7n_gcp/resources/compute.py
Original file line number Diff line number Diff line change
Expand Up @@ -232,3 +232,136 @@ def get_resource_params(self, m, r):
r['selfLink']).groups()
return {'project': project,
'instanceTemplate': instance_template}


@resources.register('autoscaler')
class Autoscaler(QueryResourceManager):
"""GCP resource: https://cloud.google.com/compute/docs/reference/rest/v1/autoscalers"""
class resource_type(TypeInfo):
service = 'compute'
version = 'v1'
component = 'autoscalers'
id = 'name'
enum_spec = ('aggregatedList', 'items.*.autoscalers[]', None)

@staticmethod
def get(client, resource_info):
project, zone, autoscaler = re.match(
'projects/(.*?)/zones/(.*?)/autoscalers/(.*)',
resource_info['resourceName']).groups()

return client.execute_command(
'get', {'project': project,
'zone': zone,
'autoscaler': autoscaler})


@Autoscaler.action_registry.register('set')
class AutoscalerSet(MethodAction):
"""
`Patches <https://cloud.google.com/compute/docs/reference/rest/v1/autoscalers/patch>`_
configuration parameters for the autoscaling algorithm.
The `coolDownPeriodSec` specifies the number of seconds that the autoscaler
should wait before it starts collecting information from a new instance.
The `cpuUtilization.utilizationTarget` specifies the target CPU utilization that the
autoscaler should maintain.
The `loadBalancingUtilization.utilizationTarget` specifies fraction of backend capacity
utilization (set in HTTP(S) load balancing configuration) that autoscaler should maintain.
The `minNumReplicas` specifies the minimum number of replicas that the autoscaler can
scale down to.
The `maxNumReplicas` specifies the maximum number of instances that the autoscaler can
scale up to.
:Example:
.. code-block:: yaml
policies:
- name: gcp-autoscaler-set
resource: gcp.autoscaler
filters:
- type: value
key: name
value: instance-group-2
actions:
- type: set
coolDownPeriodSec: 20
cpuUtilization:
utilizationTarget: 0.7
loadBalancingUtilization:
utilizationTarget: 0.7
minNumReplicas: 1
maxNumReplicas: 4
"""
schema = type_schema('set',
**{
'coolDownPeriodSec': {
'type': 'integer',
'minimum': 15
},
'cpuUtilization': {
'type': 'object',
'required': ['utilizationTarget'],
'properties': {
'utilizationTarget': {
'type': 'number',
'exclusiveMinimum': 0,
'maximum': 1
}
},
},
'loadBalancingUtilization': {
'type': 'object',
'required': ['utilizationTarget'],
'properties': {
'utilizationTarget': {
'type': 'number',
'exclusiveMinimum': 0,
'maximum': 1
}
}
},
'maxNumReplicas': {
'type': 'integer',
'exclusiveMinimum': 0
},
'minNumReplicas': {
'type': 'integer',
'exclusiveMinimum': 0
}
})
method_spec = {'op': 'patch'}
path_param_re = re.compile('.*?/projects/(.*?)/zones/(.*?)/autoscalers/(.*)')

def get_resource_params(self, model, resource):
project, zone, autoscaler = self.path_param_re.match(resource['selfLink']).groups()
body = {}

if 'coolDownPeriodSec' in self.data:
body['coolDownPeriodSec'] = self.data['coolDownPeriodSec']

if 'cpuUtilization' in self.data:
body['cpuUtilization'] = self.data['cpuUtilization']

if 'loadBalancingUtilization' in self.data:
body['loadBalancingUtilization'] = self.data['loadBalancingUtilization']

if 'maxNumReplicas' in self.data:
body['maxNumReplicas'] = self.data['maxNumReplicas']

if 'minNumReplicas' in self.data:
body['minNumReplicas'] = self.data['minNumReplicas']

result = {'project': project,
'zone': zone,
'autoscaler': autoscaler,
'body': {
'autoscalingPolicy': body
}}

return result
36 changes: 36 additions & 0 deletions tools/c7n_gcp/tests/data/events/autoscaler-insert.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
{
"protoPayload": {
"@type": "type.googleapis.com/google.cloud.audit.AuditLog",
"authenticationInfo": {
"principalEmail": "[email protected]"
},
"requestMetadata": {
"callerIp": "86.57.255.94",
"callerSuppliedUserAgent": "Mozilla/5.0"
},
"serviceName": "compute.googleapis.com",
"methodName": "v1.compute.autoscalers.insert",
"resourceName": "projects/mitrop-custodian/zones/us-central1-a/autoscalers/instance-group-1",
"request": {
"@type": "type.googleapis.com/compute.autoscalers.insert"
}
},
"insertId": "-usokkzd2z2q",
"resource": {
"type": "gce_autoscaler",
"labels": {
"project_id": "mitrop-custodian",
"location": "us-central1-a",
"autoscaler_id": "5429453110968806653"
}
},
"timestamp": "2019-08-01T11:50:44.355Z",
"severity": "NOTICE",
"logName": "projects/mitrop-custodian/logs/cloudaudit.googleapis.com%2Factivity",
"operation": {
"id": "operation-1564660241223-58f0cd9df4f28-a10f4a9b-180f61fb",
"producer": "compute.googleapis.com",
"last": true
},
"receiveTimestamp": "2019-08-01T11:50:44.900727394Z"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
{
"body": {
"status": "ACTIVE",
"kind": "compute#autoscaler",
"target": "https://www.googleapis.com/compute/v1/projects/mitrop-custodian/zones/us-central1-a/instanceGroupManagers/instance-group-1",
"zone": "https://www.googleapis.com/compute/v1/projects/mitrop-custodian/zones/us-central1-a",
"autoscalingPolicy": {
"maxNumReplicas": 10,
"cpuUtilization": {
"utilizationTarget": 0.6
},
"minNumReplicas": 1,
"coolDownPeriodSec": 60
},
"creationTimestamp": "2019-08-01T04:50:42.846-07:00",
"id": "5429453110968806653",
"selfLink": "https://www.googleapis.com/compute/v1/projects/mitrop-custodian/zones/us-central1-a/autoscalers/instance-group-1",
"name": "instance-group-1"
},
"headers": {
"status": "200",
"content-length": "710",
"x-xss-protection": "0",
"content-location": "https://www.googleapis.com/compute/v1/projects/mitrop-custodian/zones/us-central1-a/autoscalers/instance-group-1?alt=json",
"x-content-type-options": "nosniff",
"transfer-encoding": "chunked",
"vary": "Origin, X-Origin, Referer",
"server": "ESF",
"etag": "U3Hub-fnYwxz_B40C0r-WLK-ITk=/AhL5qFuurUay6pe6bo2RDy7W_uM=",
"cache-control": "private",
"date": "Thu, 01 Aug 2019 12:41:57 GMT",
"x-frame-options": "SAMEORIGIN",
"alt-svc": "quic=\":443\"; ma=2592000; v=\"46,43,39\"",
"content-type": "application/json; charset=UTF-8",
"-content-encoding": "gzip"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
{
"body": {
"items": {
"zones/us-central1-a": {
"autoscalers": [
{
"status": "ACTIVE",
"kind": "compute#autoscaler",
"target": "https://www.googleapis.com/compute/v1/projects/cloud-custodian/zones/us-central1-a/instanceGroupManagers/micro-instance-group-1-to-10",
"zone": "https://www.googleapis.com/compute/v1/projects/cloud-custodian/zones/us-central1-a",
"autoscalingPolicy": {
"maxNumReplicas": 10,
"cpuUtilization": {
"utilizationTarget": 0.6
},
"minNumReplicas": 1,
"coolDownPeriodSec": 60
},
"creationTimestamp": "2019-06-10T07:56:43.615-07:00",
"id": "3503520257074778436",
"selfLink": "https://www.googleapis.com/compute/v1/projects/cloud-custodian/zones/us-central1-a/autoscalers/micro-instance-group-1-to-10",
"name": "micro-instance-group-1-to-10"
}
]
}
},
"kind": "compute#autoscalerAggregatedList",
"id": "projects/cloud-custodian/aggregated/autoscalers",
"selfLink": "https://www.googleapis.com/compute/v1/projects/cloud-custodian/aggregated/autoscalers"
},
"headers": {
"status": "200",
"content-length": "22703",
"x-xss-protection": "1; mode=block",
"content-location": "https://www.googleapis.com/compute/v1/projects/cloud-custodian/aggregated/autoscalers?alt=json",
"x-content-type-options": "nosniff",
"transfer-encoding": "chunked",
"expires": "Mon, 10 Jun 2019 15:30:40 GMT",
"vary": "Origin, X-Origin",
"server": "GSE",
"-content-encoding": "gzip",
"etag": "\"MrcvN7ChCTB9ru9NDAWX9W-A0rg=/XvUjxb2s6a37Q0G7NF3Qbxv0tik=\"",
"cache-control": "private, max-age=0, must-revalidate, no-transform",
"date": "Mon, 10 Jun 2019 15:30:40 GMT",
"x-frame-options": "SAMEORIGIN",
"alt-svc": "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"",
"content-type": "application/json; charset=UTF-8"
}
}
Loading

0 comments on commit 64535c8

Please sign in to comment.