Repository: cloud-custodian/cloud-custodian

Issue:
gcp.instance - set-labels action fails on 'remove' with no 'add'
**Describe the bug**
When running a policy with a set-labels action

**To Reproduce**
1. [Here](https://gist.github.com/MichaelDavisTSN/4289a97125ca130e241a1030b59a6ba3) is a policy that failed. The set-labels action must have a 'remove' parameter with no other parameters (per @jtroberts83, 'remove' works when combined with an 'add').

This fails to effect the removal of a test label and throws the following error:

2020-10-15 07:35:21,605: c7n_org:ERROR Exception running policy:compute-label-compliance-shared-services-untag account:EntApps Lab region:global error:'NoneType' object has no attribute 'items'

**Expected behavior**
The label is removed with no errors message.


**Background (please complete the following information):**
 - OS: CentOS Linux release 7.8.2003 (Core)
 - Python Version: Python 3.6.8
 - Custodian Version: 0.9.6
 - Tool Version: 
     c7n-gcp                  0.4.5
     c7n-org                  0.6.5
 - Cloud Provider: gcp
 - Policy: [please exclude any account/sensitive information]
```
vars:
    global-vars: &costcenter file:/home/frank/costcenter.txt

policies:

- name: compute-label-compliance-shared-services-untag
  description: |
   Untags any marked assets that are in compliance.
  resource: gcp.instance
  filters:
    - "tag:mdtest": present
    - "tag:name": present
    - "tag:owner": present
    - type: value
      key: "tag:costcenter"
      op: in
      value_from:
        url: *costcenter
        format: txt
    - type: value
      key: "tag:appid"
      op: lt
      value_type: integer
      value: 10000
    - or:
      - "tag:custodian-tag-compliance": present
      - "tag:custodian-resource-tag-compliance": present
    - or:
      - "tag:origin": "migrated-gcp"
      - "tag:origin": "net-new-gcp"
      - "tag:origin": "migrated-aws"
      - "tag:origin": "net-new-aws"
    - or:
      - "tag:dataclassification": "public"
      - "tag:dataclassification": "internal"
      - "tag:dataclassification": "confidential"
      - "tag:dataclassification": "restricted-confidential"
      - "tag:dataclassification": "tyson-restricted-confidential"
    - or:
      - "tag:drtier": "tier1"
      - "tag:drtier": "tier2"
      - "tag:drtier": "tier3"
    - or:
      - "tag:regulatorycompliance": "na"
      - "tag:regulatorycompliance": "sox"
      - "tag:regulatorycompliance": "pci"
      - "tag:regulatorycompliance": "hipaa"
      - "tag:regulatorycompliance": "usda"
  actions:
    - type: set-labels
      remove: [custodian-tag-compliance]
```
 - Traceback: [if applicable, please exclude sensitive/account information]

Traceback (most recent call last):
  File "/opt/custodian/lib64/python3.6/site-packages/c7n_org/cli.py", line 550, in run_account
    resources = p.run()
  File "/opt/custodian/lib64/python3.6/site-packages/c7n/policy.py", line 1175, in __call__
    resources = mode.run()
  File "/opt/custodian/lib64/python3.6/site-packages/c7n/policy.py", line 313, in run
    results = a.process(resources)
  File "/opt/custodian/lib64/python3.6/site-packages/c7n_gcp/actions/core.py", line 66, in process
    self.process_resource_set(client, model, resource_set)
  File "/opt/custodian/lib64/python3.6/site-packages/c7n_gcp/actions/core.py", line 73, in process_resource_set
    params = self.get_resource_params(model, resource)
  File "/opt/custodian/lib64/python3.6/site-packages/c7n_gcp/actions/labels.py", line 42, in get_resource_params
    new_labels = self.get_labels_to_add(resource)
  File "/opt/custodian/lib64/python3.6/site-packages/c7n_gcp/actions/labels.py", line 115, in get_labels_to_add
    return {k: Lookup.extract(v, resource) for k, v in self.data.get('labels').items()}
AttributeError: 'NoneType' object has no attribute 'items'
> /opt/custodian/lib64/python3.6/site-packages/c7n_gcp/actions/labels.py(115)get_labels_to_add()
-> return {k: Lookup.extract(v, resource) for k, v in self.data.get('labels').items()}
(Pdb)


 - `custodian version --debug` output

Custodian:   0.9.6
Python:      3.6.8 (default, Apr  2 2020, 13:34:55)
             [GCC 4.8.5 20150623 (Red Hat 4.8.5-39)]
Platform:    posix.uname_result(sysname='Linux', nodename='gcplpcc1', release='3.10.0-1127.19.1.el7.x86_64', version='#1 SMP Tue Aug 25 17:23:54 UTC 2020', machine='x86_64')
Using venv:  True
Docker: False
Installed:

argcomplete==1.12.1
attrs==20.2.0
boto3==1.15.16
botocore==1.18.16
c7n==0.9.6
cachetools==4.1.1
certifi==2020.6.20
cffi==1.14.3
chardet==3.0.4
docutils==0.15.2
google-api-core==1.22.4
google-api-python-client==1.12.3
google-auth==1.22.1
google-auth-httplib2==0.0.4
google-cloud-core==1.4.3
google-cloud-logging==1.15.1
google-cloud-monitoring==0.34.0
google-cloud-storage==1.31.2
google-crc32c==1.0.0
google-resumable-media==1.1.0
googleapis-common-protos==1.52.0
httplib2==0.18.1
idna==2.10
importlib-metadata==2.0.0
jmespath==0.10.0
jsonschema==3.2.0
protobuf==3.13.0
pyasn1==0.4.8
pyasn1-modules==0.2.8
pycparser==2.20
pyrsistent==0.16.1
python-dateutil==2.8.1
pytz==2020.1
pyyaml==5.3.1
ratelimiter==1.2.0.post0
requests==2.24.0
retrying==1.3.3
rsa==4.6
s3transfer==0.3.3
setuptools==39.2.0
six==1.15.0
tabulate==0.8.7
uritemplate==3.0.1
urllib3==1.25.10
zipp==3.3.0

**Additional context**




Discussion:

Resolving patch:
diff --git a/tools/c7n_gcp/c7n_gcp/actions/labels.py b/tools/c7n_gcp/c7n_gcp/actions/labels.py
--- a/tools/c7n_gcp/c7n_gcp/actions/labels.py
+++ b/tools/c7n_gcp/c7n_gcp/actions/labels.py
@@ -112,7 +112,7 @@ def validate(self):
             raise FilterValidationError("Must specify one of labels or remove")
 
     def get_labels_to_add(self, resource):
-        return {k: Lookup.extract(v, resource) for k, v in self.data.get('labels').items()}
+        return {k: Lookup.extract(v, resource) for k, v in self.data.get('labels', {}).items()}
 
     def get_labels_to_delete(self, resource):
         return self.data.get('remove')


Test patch: