Last active
December 9, 2019 03:23
-
-
Save AnyISalIn/7a66c5d08228da0402d19fa3eea6614c to your computer and use it in GitHub Desktop.
TerraformWrapper
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import delegator | |
| import os | |
| import json | |
| from service import TerraformManagerService | |
| class Provider: | |
| def __init__(self, config): | |
| self.config = config | |
| class Template: | |
| def __init__(self, providers, resources, outputs, datasources, variables, user_variables): | |
| self.providers = providers | |
| self.resources = resources | |
| self.outputs = outputs | |
| self.datasources = datasources | |
| self.variables = variables | |
| self.user_variables = variables | |
| class Instance: | |
| def __init__(self, name, template, variables=None): | |
| self.name = name | |
| self.template = template | |
| self.variables = variables or dict() | |
| self.states = None | |
| self.status = None | |
| self.terraform_service = TerraformManagerService() | |
| self.shell_output = None | |
| @property | |
| def path(self): | |
| return self.terraform_service.plan_template_dir.joinpath(self.name) | |
| def init(self): | |
| self.status = 'INITIALIZATION' | |
| self.generate_plan_files() | |
| init_cmd = self.terraform_service.init() | |
| cmd = delegator.run(' '.join(init_cmd), cwd=str(self.path)) | |
| self.shell_output = cmd.err or cmd.out | |
| if cmd.return_code != 0: | |
| self.status = 'INITIALIZATION_ERROR' | |
| else: | |
| self.status = 'INITIALIZATION_SUCCEED' | |
| self.graph() | |
| def generate_plan_files(self): | |
| if not os.path.exists(self.path): | |
| os.mkdir(self.path) | |
| with open(os.path.join(self.path, 'providers.tf'), 'wb') as f: | |
| data = '\n'.join([_.config for _ in self.template.providers]) | |
| f.write(data.encode()) | |
| with open(os.path.join(self.path, 'resources.tf'), 'wb') as f: | |
| f.write(self.template.resources.encode()) | |
| with open(os.path.join(self.path, 'outputs.tf'), 'wb') as f: | |
| f.write(self.template.outputs.encode()) | |
| with open(os.path.join(self.path, 'variables.tf'), 'wb') as f: | |
| f.write(self.template.variables.encode()) | |
| with open(os.path.join(self.path, 'datasources.tf'), 'wb') as f: | |
| f.write(self.template.datasources.encode()) | |
| def build_variables(self): | |
| for variable in self.variables: | |
| yield f'''-var "{variable['key']}={variable['value']}"''' | |
| def apply(self): | |
| self.init() | |
| self.status = 'APPLYING' | |
| variables_args = ' '.join(list(self.build_variables())) | |
| apply_cmd = ' '.join(self.terraform_service.apply(variables_args, str(self.path))) | |
| cmd = delegator.run(f'{apply_cmd}', cwd=str(self.path)) | |
| self.shell_output = cmd.err or cmd.out | |
| if cmd.return_code != 0: | |
| self.status = 'APPLY_ERROR' | |
| else: | |
| self.status = 'APPLY_SUCCEED' | |
| def destroy(self): | |
| self.status = 'DESTROYING' | |
| destroy_cmd = ' '.join(self.terraform_service.destroy()) | |
| cmd = delegator.run(f'{destroy_cmd}', cwd=str(self.path)) | |
| if cmd.return_code == 0: | |
| shutil.rmtree(str(self.path)) | |
| return | |
| self.shell_output = cmd.err | |
| self.status = 'DESTROY_ERROR' | |
| raise CommandExecuteError | |
| def show(self): | |
| show_cmd = ' '.join(self.terraform_service.show()) | |
| cmd = delegator.run(f'{show_cmd}', cwd=str(self.path)) | |
| if cmd.return_code == 0: | |
| self.states = json.loads(cmd.out) | |
| return self.states | |
| self.shell_output = cmd.err | |
| raise CommandExecuteError | |
| def refresh(self): | |
| refresh_cmd = ' '.join(self.terraform_service.refresh()) | |
| self.status = 'SYNCING' | |
| cmd = delegator.run(f'{refresh_cmd}', cwd=str(self.path)) | |
| if cmd.return_code == 0: | |
| self.shell_output = cmd.out | |
| self.status = 'SYNC_SUCCEED' | |
| return self.show() | |
| self.shell_output = cmd.err | |
| self.status = 'SYNC_ERROR' | |
| raise CommandExecuteError | |
| def graph(self): | |
| graph_cmd = ' '.join(self.terraform_service.graph()) | |
| cmd = delegator.run(f'{graph_cmd}', cwd=str(self.path)) | |
| self.graph_output = cmd.out | |
| return self.graph_output | |
| def plan(self): | |
| self.generate_plan_files() | |
| variables_args = ' '.join(list(self.build_variables())) | |
| plan_cmd = ' '.join(self.terraform_service.plan(variables_args)) | |
| cmd = delegator.run(f'{plan_cmd}', cwd=str(self.path)) | |
| self.shell_output = cmd.out | |
| return self.shell_output | |
| def __repr__(self): | |
| return f'<Instance {self.path}>' |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import pathlib | |
| class TerraformManagerService(object): | |
| def __init__(self, terraform_bin=None, plan_template_dir=None): | |
| self.terraform_bin = terraform_bin or '/usr/local/bin/terraform' | |
| self.plan_template_dir = pathlib.Path(plan_template_dir or '/Users/anyisalin/codes/terraform_test/instances') | |
| def validate(self, *args): | |
| return [self.terraform_bin, 'validate'] + list(args) | |
| def apply(self, *args): | |
| return [self.terraform_bin, 'apply', '-auto-approve'] + list(args) | |
| def init(self, *args): | |
| return [self.terraform_bin, 'init'] + list(args) | |
| def show(self, *args): | |
| return [self.terraform_bin, 'show', '-json'] + list(args) | |
| def refresh(self, *args): | |
| return [self.terraform_bin, 'refresh'] + list(args) | |
| def destroy(self, *args): | |
| return [self.terraform_bin, 'destroy', '-auto-approve'] + list(args) | |
| def graph(self, *args): | |
| return [self.terraform_bin, 'graph'] + list(args) | |
| def plan(self, *args): | |
| return [self.terraform_bin, 'plan'] + list(args) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| from models import Template, Instance, Provider | |
| from service import TerraformManagerService | |
| provider = ''' | |
| provider "openstack" { | |
| region = "RegionOne" | |
| insecure = "true" | |
| } | |
| ''' | |
| resources = ''' | |
| resource "openstack_compute_instance_v2" "terraform" { | |
| name = "${var.vm_name}" | |
| image_name = "${var.image}" | |
| flavor_name = "${var.flavor}" | |
| key_pair = "terraform" | |
| security_groups = ["terraform"] | |
| network { | |
| uuid = "${var.network}" | |
| } | |
| } | |
| ''' | |
| variables = ''' | |
| variable "image" { | |
| default = "Ubuntu 16.04" | |
| } | |
| variable "flavor" { | |
| default = "m1.small" | |
| } | |
| variable "ssh_key_file" { | |
| default = "~/.ssh/id_rsa" | |
| } | |
| variable "ssh_user_name" { | |
| default = "ubuntu" | |
| } | |
| variable "pool" { | |
| default = "Public" | |
| } | |
| variable "network" { | |
| default = "f5a2c66a-f465-4578-ac96-676c4e767f8d" | |
| } | |
| variable "vm_name" { | |
| default = "terraform" | |
| } | |
| ''' | |
| datasources = '' | |
| outputs = '' | |
| openstack_provider = Provider(config=provider) | |
| template = Template(providers=[openstack_provider], | |
| resources=resources, | |
| datasources=datasources, | |
| outputs=outputs, | |
| variables=variables, | |
| user_variables=[ | |
| {'key': 'vm_name', 'default': 'test', 'required': False} | |
| ] | |
| ) | |
| instance = Instance(name='instance-test', template=template, variables=[{'key': 'vm_name', 'value': 'instance1'}]) | |
| instance.init() | |
| instance.apply() | |
| instance.show() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment