mirror of
https://github.com/trailofbits/algo.git
synced 2025-08-01 18:33:06 +02:00
GCP: Refactoring, remove deprecated modules
This commit is contained in:
parent
7dfb916466
commit
92a12a635a
5 changed files with 197 additions and 215 deletions
|
@ -1,139 +0,0 @@
|
|||
#!/usr/bin/python
|
||||
# Copyright 2013 Google Inc.
|
||||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
|
||||
from __future__ import absolute_import, division, print_function
|
||||
__metaclass__ = type
|
||||
|
||||
|
||||
ANSIBLE_METADATA = {'metadata_version': '1.1',
|
||||
'status': ['preview'],
|
||||
'supported_by': 'community'}
|
||||
|
||||
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: gce_region_facts
|
||||
version_added: "5.3"
|
||||
short_description: Gather facts about GCE regions.
|
||||
description:
|
||||
- Gather facts about GCE regions.
|
||||
options:
|
||||
service_account_email:
|
||||
version_added: "1.6"
|
||||
description:
|
||||
- service account email
|
||||
required: false
|
||||
default: null
|
||||
aliases: []
|
||||
pem_file:
|
||||
version_added: "1.6"
|
||||
description:
|
||||
- path to the pem file associated with the service account email
|
||||
This option is deprecated. Use 'credentials_file'.
|
||||
required: false
|
||||
default: null
|
||||
aliases: []
|
||||
credentials_file:
|
||||
version_added: "2.1.0"
|
||||
description:
|
||||
- path to the JSON file associated with the service account email
|
||||
required: false
|
||||
default: null
|
||||
aliases: []
|
||||
project_id:
|
||||
version_added: "1.6"
|
||||
description:
|
||||
- your GCE project ID
|
||||
required: false
|
||||
default: null
|
||||
aliases: []
|
||||
requirements:
|
||||
- "python >= 2.6"
|
||||
- "apache-libcloud >= 0.13.3, >= 0.17.0 if using JSON credentials"
|
||||
author: "Jack Ivanov (@jackivanov)"
|
||||
'''
|
||||
|
||||
EXAMPLES = '''
|
||||
# Gather facts about all regions
|
||||
- gce_region_facts:
|
||||
'''
|
||||
|
||||
RETURN = '''
|
||||
regions:
|
||||
returned: on success
|
||||
description: >
|
||||
Each element consists of a dict with all the information related
|
||||
to that region.
|
||||
type: list
|
||||
sample: "[{
|
||||
"name": "asia-east1",
|
||||
"status": "UP",
|
||||
"zones": [
|
||||
{
|
||||
"name": "asia-east1-a",
|
||||
"status": "UP"
|
||||
},
|
||||
{
|
||||
"name": "asia-east1-b",
|
||||
"status": "UP"
|
||||
},
|
||||
{
|
||||
"name": "asia-east1-c",
|
||||
"status": "UP"
|
||||
}
|
||||
]
|
||||
}]"
|
||||
'''
|
||||
try:
|
||||
from libcloud.compute.types import Provider
|
||||
from libcloud.compute.providers import get_driver
|
||||
from libcloud.common.google import GoogleBaseError, QuotaExceededError, ResourceExistsError, ResourceNotFoundError
|
||||
_ = Provider.GCE
|
||||
HAS_LIBCLOUD = True
|
||||
except ImportError:
|
||||
HAS_LIBCLOUD = False
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.gce import gce_connect, unexpected_error_msg
|
||||
|
||||
|
||||
def main():
|
||||
module = AnsibleModule(
|
||||
argument_spec=dict(
|
||||
service_account_email=dict(),
|
||||
pem_file=dict(type='path'),
|
||||
credentials_file=dict(type='path'),
|
||||
project_id=dict(),
|
||||
)
|
||||
)
|
||||
|
||||
if not HAS_LIBCLOUD:
|
||||
module.fail_json(msg='libcloud with GCE support (0.17.0+) required for this module')
|
||||
|
||||
gce = gce_connect(module)
|
||||
|
||||
changed = False
|
||||
gce_regions = []
|
||||
|
||||
try:
|
||||
regions = gce.ex_list_regions()
|
||||
for r in regions:
|
||||
gce_region = {}
|
||||
gce_region['name'] = r.name
|
||||
gce_region['status'] = r.status
|
||||
gce_region['zones'] = []
|
||||
for z in r.zones:
|
||||
gce_zone = {}
|
||||
gce_zone['name'] = z.name
|
||||
gce_zone['status'] = z.status
|
||||
gce_region['zones'].append(gce_zone)
|
||||
gce_regions.append(gce_region)
|
||||
json_output = { 'regions': gce_regions }
|
||||
module.exit_json(changed=False, results=json_output)
|
||||
except ResourceNotFoundError:
|
||||
pass
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
93
library/gcp_compute_location_info.py
Normal file
93
library/gcp_compute_location_info.py
Normal file
|
@ -0,0 +1,93 @@
|
|||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from __future__ import absolute_import, division, print_function
|
||||
|
||||
__metaclass__ = type
|
||||
|
||||
################################################################################
|
||||
# Documentation
|
||||
################################################################################
|
||||
|
||||
ANSIBLE_METADATA = {'metadata_version': '1.1', 'status': ["preview"], 'supported_by': 'community'}
|
||||
|
||||
################################################################################
|
||||
# Imports
|
||||
################################################################################
|
||||
from ansible.module_utils.gcp_utils import navigate_hash, GcpSession, GcpModule, GcpRequest
|
||||
import json
|
||||
|
||||
################################################################################
|
||||
# Main
|
||||
################################################################################
|
||||
|
||||
|
||||
def main():
|
||||
module = GcpModule(argument_spec=dict(filters=dict(type='list', elements='str'), scope=dict(required=True, type='str')))
|
||||
|
||||
if module._name == 'gcp_compute_image_facts':
|
||||
module.deprecate("The 'gcp_compute_image_facts' module has been renamed to 'gcp_compute_regions_info'", version='2.13')
|
||||
|
||||
if not module.params['scopes']:
|
||||
module.params['scopes'] = ['https://www.googleapis.com/auth/compute']
|
||||
|
||||
items = fetch_list(module, collection(module), query_options(module.params['filters']))
|
||||
if items.get('items'):
|
||||
items = items.get('items')
|
||||
else:
|
||||
items = []
|
||||
return_value = {'resources': items}
|
||||
module.exit_json(**return_value)
|
||||
|
||||
|
||||
def collection(module):
|
||||
return "https://www.googleapis.com/compute/v1/projects/{project}/{scope}".format(**module.params)
|
||||
|
||||
|
||||
def fetch_list(module, link, query):
|
||||
auth = GcpSession(module, 'compute')
|
||||
response = auth.get(link, params={'filter': query})
|
||||
return return_if_object(module, response)
|
||||
|
||||
|
||||
def query_options(filters):
|
||||
if not filters:
|
||||
return ''
|
||||
|
||||
if len(filters) == 1:
|
||||
return filters[0]
|
||||
else:
|
||||
queries = []
|
||||
for f in filters:
|
||||
# For multiple queries, all queries should have ()
|
||||
if f[0] != '(' and f[-1] != ')':
|
||||
queries.append("(%s)" % ''.join(f))
|
||||
else:
|
||||
queries.append(f)
|
||||
|
||||
return ' '.join(queries)
|
||||
|
||||
|
||||
def return_if_object(module, response):
|
||||
# If not found, return nothing.
|
||||
if response.status_code == 404:
|
||||
return None
|
||||
|
||||
# If no content, return nothing.
|
||||
if response.status_code == 204:
|
||||
return None
|
||||
|
||||
try:
|
||||
module.raise_for_status(response)
|
||||
result = response.json()
|
||||
except getattr(json.decoder, 'JSONDecodeError', ValueError) as inst:
|
||||
module.fail_json(msg="Invalid JSON response with error: %s" % inst)
|
||||
|
||||
if navigate_hash(result, ['error', 'errors']):
|
||||
module.fail_json(msg=navigate_hash(result, ['error', 'errors']))
|
||||
|
||||
return result
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
|
@ -2,60 +2,83 @@
|
|||
- name: Build python virtual environment
|
||||
import_tasks: venv.yml
|
||||
|
||||
- name: Include prompts
|
||||
import_tasks: prompts.yml
|
||||
|
||||
- name: Network configured
|
||||
gcp_compute_network:
|
||||
auth_kind: serviceaccount
|
||||
service_account_file: "{{ credentials_file_path }}"
|
||||
project: "{{ project_id }}"
|
||||
name: algovpn
|
||||
auto_create_subnetworks: true
|
||||
routing_config:
|
||||
routing_mode: REGIONAL
|
||||
register: gcp_compute_network
|
||||
|
||||
- name: Firewall configured
|
||||
gcp_compute_firewall:
|
||||
auth_kind: serviceaccount
|
||||
service_account_file: "{{ credentials_file_path }}"
|
||||
project: "{{ project_id }}"
|
||||
name: algovpn
|
||||
network: "{{ gcp_compute_network }}"
|
||||
direction: INGRESS
|
||||
allowed:
|
||||
- ip_protocol: udp
|
||||
ports:
|
||||
- '500'
|
||||
- '4500'
|
||||
- '{{ wireguard_port|string }}'
|
||||
- ip_protocol: tcp
|
||||
ports:
|
||||
- '22'
|
||||
- ip_protocol: icmp
|
||||
|
||||
- block:
|
||||
- name: Include prompts
|
||||
import_tasks: prompts.yml
|
||||
|
||||
- name: Network configured
|
||||
gce_net:
|
||||
- name: External IP allocated
|
||||
gcp_compute_address:
|
||||
auth_kind: serviceaccount
|
||||
service_account_file: "{{ credentials_file_path }}"
|
||||
project: "{{ project_id }}"
|
||||
name: "{{ algo_server_name }}"
|
||||
fwname: "{{ algo_server_name }}-fw"
|
||||
allowed: "udp:500,4500,{{ wireguard_port }};tcp:22"
|
||||
state: "present"
|
||||
mode: auto
|
||||
src_range: 0.0.0.0/0
|
||||
service_account_email: "{{ service_account_email }}"
|
||||
credentials_file: "{{ credentials_file_path }}"
|
||||
project_id: "{{ project_id }}"
|
||||
region: "{{ algo_region }}"
|
||||
register: gcp_compute_address
|
||||
|
||||
- block:
|
||||
- name: External IP allocated
|
||||
gce_eip:
|
||||
service_account_email: "{{ service_account_email }}"
|
||||
credentials_file: "{{ credentials_file_path }}"
|
||||
project_id: "{{ project_id }}"
|
||||
name: "{{ algo_server_name }}"
|
||||
region: "{{ algo_region.split('-')[0:2] | join('-') }}"
|
||||
state: present
|
||||
register: gce_eip
|
||||
- name: Set External IP as a fact
|
||||
set_fact:
|
||||
external_ip: "{{ gcp_compute_address.address }}"
|
||||
when: cloud_providers.gce.external_static_ip
|
||||
|
||||
- name: Set External IP as a fact
|
||||
set_fact:
|
||||
external_ip: "{{ gce_eip.address }}"
|
||||
when: cloud_providers.gce.external_static_ip
|
||||
|
||||
- name: "Creating a new instance..."
|
||||
gce:
|
||||
instance_names: "{{ algo_server_name }}"
|
||||
zone: "{{ algo_region }}"
|
||||
external_ip: "{{ external_ip | default('ephemeral') }}"
|
||||
machine_type: "{{ cloud_providers.gce.size }}"
|
||||
image: "{{ cloud_providers.gce.image }}"
|
||||
service_account_email: "{{ service_account_email }}"
|
||||
credentials_file: "{{ credentials_file_path }}"
|
||||
project_id: "{{ project_id }}"
|
||||
metadata:
|
||||
ssh-keys: "ubuntu:{{ ssh_public_key_lookup }}"
|
||||
user-data: |
|
||||
#!/bin/bash
|
||||
sudo apt-get remove -y --purge sshguard
|
||||
network: "{{ algo_server_name }}"
|
||||
tags:
|
||||
- name: Instance created
|
||||
gcp_compute_instance:
|
||||
auth_kind: serviceaccount
|
||||
service_account_file: "{{ credentials_file_path }}"
|
||||
project: "{{ project_id }}"
|
||||
name: "{{ algo_server_name }}"
|
||||
zone: "{{ algo_zone }}"
|
||||
machine_type: "{{ cloud_providers.gce.size }}"
|
||||
disks:
|
||||
- auto_delete: true
|
||||
boot: true
|
||||
initialize_params:
|
||||
source_image: "projects/ubuntu-os-cloud/global/images/family/{{ cloud_providers.gce.image }}"
|
||||
metadata:
|
||||
ssh-keys: "ubuntu:{{ ssh_public_key_lookup }}"
|
||||
user-data: |
|
||||
#!/bin/bash
|
||||
sudo apt-get remove -y --purge sshguard
|
||||
network_interfaces:
|
||||
- network: "{{ gcp_compute_network }}"
|
||||
access_configs:
|
||||
- name: "{{ algo_server_name }}"
|
||||
nat_ip: "{{ gcp_compute_address|default(None) }}"
|
||||
type: ONE_TO_ONE_NAT
|
||||
tags:
|
||||
items:
|
||||
- "environment-algo"
|
||||
register: google_vm
|
||||
register: gcp_compute_instance
|
||||
|
||||
- set_fact:
|
||||
cloud_instance_ip: "{{ google_vm.instance_data[0].public_ip }}"
|
||||
ansible_ssh_user: ubuntu
|
||||
environment:
|
||||
PYTHONPATH: "{{ gce_venv }}/lib/python2.7/site-packages/"
|
||||
- set_fact:
|
||||
cloud_instance_ip: "{{ gcp_compute_instance.networkInterfaces[0].accessConfigs[0].natIP }}"
|
||||
ansible_ssh_user: ubuntu
|
||||
|
|
|
@ -21,36 +21,32 @@
|
|||
|
||||
- block:
|
||||
- name: Get regions
|
||||
gce_region_facts:
|
||||
service_account_email: "{{ credentials_file_lookup.client_email }}"
|
||||
credentials_file: "{{ credentials_file_path }}"
|
||||
project_id: "{{ credentials_file_lookup.project_id }}"
|
||||
register: _gce_regions
|
||||
gcp_compute_location_info:
|
||||
auth_kind: serviceaccount
|
||||
service_account_file: "{{ credentials_file_path }}"
|
||||
project: "{{ project_id }}"
|
||||
scope: regions
|
||||
filters: status=UP
|
||||
register: gcp_compute_regions_info
|
||||
|
||||
- name: Set facts about the regions
|
||||
set_fact:
|
||||
gce_regions: >-
|
||||
[{%- for region in _gce_regions.results.regions | sort(attribute='name') -%}
|
||||
{% if region.status == "UP" %}
|
||||
{% for zone in region.zones | sort(attribute='name') %}
|
||||
{% if zone.status == "UP" %}
|
||||
'{{ zone.name }}'
|
||||
{% endif %}{% if not loop.last %},{% endif %}
|
||||
{% endfor %}
|
||||
{% endif %}{% if not loop.last %},{% endif %}
|
||||
[{%- for region in gcp_compute_regions_info.resources | sort(attribute='name') -%}
|
||||
'{{ region.name }}'{% if not loop.last %},{% endif %}
|
||||
{%- endfor -%}]
|
||||
|
||||
- name: Set facts about the default region
|
||||
set_fact:
|
||||
default_region: >-
|
||||
{% for region in gce_regions %}
|
||||
{%- if region == "us-east1-b" %}{{ loop.index }}{% endif %}
|
||||
{%- if region == "us-east1" %}{{ loop.index }}{% endif %}
|
||||
{%- endfor %}
|
||||
|
||||
- pause:
|
||||
prompt: |
|
||||
What region should the server be located in?
|
||||
(https://cloud.google.com/compute/docs/regions-zones/)
|
||||
(https://cloud.google.com/compute/docs/regions-zones/#locations)
|
||||
{% for r in gce_regions %}
|
||||
{{ loop.index }}. {{ r }}
|
||||
{% endfor %}
|
||||
|
@ -60,8 +56,24 @@
|
|||
register: _gce_region
|
||||
when: region is undefined
|
||||
|
||||
- set_fact:
|
||||
- name: Set region as a fact
|
||||
set_fact:
|
||||
algo_region: >-
|
||||
{% if region is defined %}{{ region }}
|
||||
{%- elif _gce_region.user_input %}{{ gce_regions[_gce_region.user_input | int -1 ] }}
|
||||
{%- else %}{{ gce_regions[default_region | int - 1] }}{% endif %}
|
||||
|
||||
- name: Get zones
|
||||
gcp_compute_location_info:
|
||||
auth_kind: serviceaccount
|
||||
service_account_file: "{{ credentials_file_path }}"
|
||||
project: "{{ project_id }}"
|
||||
scope: zones
|
||||
filters:
|
||||
- "name={{ algo_region }}-*"
|
||||
- "status=UP"
|
||||
register: gcp_compute_zone_info
|
||||
|
||||
- name: Set random available zone as a fact
|
||||
set_fact:
|
||||
algo_zone: "{{ (gcp_compute_zone_info.resources | random(seed=algo_server_name + algo_region + project_id) ).name }}"
|
||||
|
|
|
@ -1,14 +1,7 @@
|
|||
---
|
||||
- name: Clean up the environment
|
||||
file:
|
||||
dest: "{{ gce_venv }}"
|
||||
state: absent
|
||||
when: clean_environment
|
||||
|
||||
- name: Install requirements
|
||||
pip:
|
||||
name:
|
||||
- apache-libcloud
|
||||
- requests>=2.18.4
|
||||
- google-auth>=1.3.0
|
||||
state: latest
|
||||
virtualenv: "{{ gce_venv }}"
|
||||
virtualenv_python: python2.7
|
||||
|
|
Loading…
Add table
Reference in a new issue