Giter Site home page Giter Site logo

28mm / blast-radius Goto Github PK

View Code? Open in Web Editor NEW
2.0K 33.0 243.0 1017 KB

Interactive visualizations of Terraform dependency graphs using d3.js

Home Page: https://28mm.github.io/blast-radius-docs/

License: MIT License

Makefile 0.30% Python 12.28% CSS 3.01% JavaScript 81.65% HTML 2.31% Shell 0.32% Dockerfile 0.14%
terraform graphviz interactive-visualizations diagram

blast-radius's Introduction

Blast Radius

CircleCI PyPI version

Blast Radius is a tool for reasoning about Terraform dependency graphs with interactive visualizations.

Use Blast Radius to:

  • Learn about Terraform or one of its providers through real examples
  • Document your infrastructure
  • Reason about relationships between resources and evaluate changes to them
  • Interact with the diagram below (and many others) in the docs

screenshot

Prerequisites

Note: For macOS you can brew install graphviz

Quickstart

The fastest way to get up and running with Blast Radius is to install it with pip to your pre-existing environment:

pip install blastradius

Once installed just point Blast Radius at any initialized Terraform directory:

blast-radius --serve /path/to/terraform/directory

And you will shortly be rewarded with a browser link http://127.0.0.1:5000/.

Docker

To launch Blast Radius for a local directory by manually running:

docker run --rm -it -p 5000:5000 \
  -v $(pwd):/data:ro \
  --security-opt apparmor:unconfined \
  --cap-add=SYS_ADMIN \
  28mm/blast-radius

A slightly more customized variant of this is also available as an example docker-compose.yml usecase for Workspaces.

Docker configurations

Terraform module links are saved as absolute paths in relative to the project root (note .terraform/modules/<uuid>). Given these paths will vary betwen Docker and the host, we mount the volume as read-only, assuring we don't ever interfere with your real environment.

However, in order for Blast Radius to actually work with Terraform, it needs to be initialized. To accomplish this, the container creates an overlayfs that exists within the container, overlaying your own, so that it can operate independently. To do this, certain runtime privileges are required -- specifically --cap-add=SYS_ADMIN.

For more information on how this works and what it means for your host, check out the runtime privileges documentation.

Docker & Subdirectories

If you organized your Terraform project using stacks and modules, Blast Radius must be called from the project root and reference them as subdirectories -- don't forget to prefix --serve!

For example, let's create a Terraform project with the following:

$ tree -d
`-- project/
    |-- modules/
    |   |-- foo
    |   |-- bar
    |   `-- dead
    `-- stacks/
        `-- beef/
             `-- .terraform

It consists of 3 modules foo, bar and dead, followed by one beef stack. To apply Blast Radius to the beef stack, you would want to run the container with the following:

$ cd project
$ docker run --rm -it -p 5000:5000 \
    -v $(pwd):/data:ro \
    --security-opt apparmor:unconfined \
    --cap-add=SYS_ADMIN \
    28mm/blast-radius --serve stacks/beef

Embedded Figures

You may wish to embed figures produced with Blast Radius in other documents. You will need the following:

  1. An svg file and json document representing the graph and its layout.
  2. javascript and css found in .../blastradius/server/static
  3. A uniquely identified DOM element, where the <svg> should appear.

You can read more details in the documentation

Implementation Details

Blast Radius uses the [Graphviz][] package to layout graph diagrams, PyHCL to parse Terraform configuration, and d3.js to implement interactive features and animations.

Further Reading

The development of Blast Radius is documented in a series of blog posts:

  • part 1: motivations, d3 force-directed layouts vs. vanilla graphviz.
  • part 2: d3-enhanced graphviz layouts, meaningful coloration, animations.
  • part 3: limiting horizontal sprawl, supporting modules.
  • part 4: search, pan/zoom, prune-to-selection, docker.

A catalog of example Terraform configurations, and their dependency graphs can be found here.

These examples are drawn primarily from the examples/ directory distributed with various Terraform providers, and aren't necessarily ideal. Additional examples, particularly demonstrations of best-practices, or of multi-cloud configurations strongly desired.

blast-radius's People

Contributors

28mm avatar bucrogers avatar clebio avatar davewongillies avatar gkapkowski avatar ltomes avatar maklipsa avatar miroadamy avatar starefossen avatar syntaqx avatar tiddnet avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

blast-radius's Issues

Feature: Interactive UI Refinements

It'd be nice to add some basic GUI bits to the web interface. This issue is to track progress and provide a mechanism for comment. Initial goals listed below, along with a mockup.

  • zoom in/out (via svg-pan-zoom.js)
  • search/selection of elements (via selectize.js)
  • download svg (via a modified svg-crowbar script)
  • help menu:
    • links to documentation
    • report working directory
    • report terraform version / arch
  • thoughts for later:
    • configurable tooltips
    • link to resource implementations on GitHub
    • link to (or bundle) resource help
    • replace "(M)" in modules with a FontAwesome based icon

screen shot 2018-01-28 at 4 12 32 pm

Feature Request: Highlighting inbound / upstream connections.

When clicking on a particular entity, it highlights all the outbound (downstream) connections but excludes all the inbound (upstream connections).

Any particular reason you chose to do this?

Perhaps you could have a toggle where users can choose whether to highlight:

  • Inbounds Only.
  • Outbounds Only.
  • Inbounds and Outbounds.

Feature: Resource Property Display--Optional, Computed, ForceNew

Blast Radius displays resource definitions as json blobs, without syntax highlighting or annotations of any kind. (json rather than hcl because pyHCL made this easier.)

Because the primary concern of Blast Radius is understanding the scope of change-sets, it would be useful if resource properties were marked to indicate whether:

  • required : true, or
  • ForceNew : true

In order to build a library of resource auto-completions, the vim-terraform project collects the top 100(?) projects from GitHub that match the pattern terraform-provider-*, then applies some perl or what-have-you to obtain resource names and associated properties.

It would be interesting to borrow as much of this code as is easily adaptable, and do something similiar for Blast Radius. I expect the ForceNew property to be of particular interest.

Unexpected identifier TF

TF version v.12.9
azure rm
running on windows 10.
I cant see how to witch debug mode on tried --debug, but if you can let me know I'll try again to get more info.

127.0.0.1 - - [13/Oct/2019 16:06:46] "GET / HTTP/1.1" 200 -
127.0.0.1 - - [13/Oct/2019 16:06:49] "GET /graph.svg HTTP/1.1" 200 -
[2019-10-13 16:06:50,729] ERROR in app: Exception on /graph.json [GET]
Traceback (most recent call last):
File "C:\Python37\lib\site-packages\flask\app.py", line 2446, in wsgi_app
response = self.full_dispatch_request()
File "C:\Python37\lib\site-packages\flask\app.py", line 1951, in full_dispatch_request
rv = self.handle_user_exception(e)
File "C:\Python37\lib\site-packages\flask\app.py", line 1820, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "C:\Python37\lib\site-packages\flask_compat.py", line 39, in reraise
raise value
File "C:\Python37\lib\site-packages\flask\app.py", line 1949, in full_dispatch_request
rv = self.dispatch_request()
File "C:\Python37\lib\site-packages\flask\app.py", line 1935, in dispatch_request
return self.view_functionsrule.endpoint
File "C:\Python37\lib\site-packages\blastradius\server\server.py", line 61, in graph_json
tf = Terraform(os.getcwd())
File "C:\Python37\lib\site-packages\blastradius\handlers\terraform.py", line 26, in init
self.config = hcl.load(config_io)
File "C:\Python37\lib\site-packages\hcl\api.py", line 54, in load
return loads(fp.read())
File "C:\Python37\lib\site-packages\hcl\api.py", line 66, in loads
return HclParser().parse(s)
File "C:\Python37\lib\site-packages\hcl\parser.py", line 326, in parse
return self.yacc.parse(s, lexer=Lexer())
File "C:\Python37\lib\site-packages\ply\yacc.py", line 333, in parse
return self.parseopt_notrack(input, lexer, debug, tracking, tokenfunc)
File "C:\Python37\lib\site-packages\ply\yacc.py", line 1201, in parseopt_notrack
tok = call_errorfunc(self.errorfunc, errtoken, self)
File "C:\Python37\lib\site-packages\ply\yacc.py", line 192, in call_errorfunc
r = errorfunc(token)
File "C:\Python37\lib\site-packages\hcl\parser.py", line 318, in p_error
raise ValueError(msg)
ValueError: Line 55, column 1607: unexpected IDENTIFIER
127.0.0.1 - - [13/Oct/2019 16:06:50] "GET /graph.json HTTP/1.1" 500 -

Getting 500 error for GET /graph.json

Hello, my infra graph is displaying properly with the CSV but I get this error for the graph.json endpoint. Here is the command I am running.

blast-radius --port 3000 --serve --module-depth 3

127.0.0.1 - - [26/Sep/2018 02:59:50] "GET / HTTP/1.1" 200 -
127.0.0.1 - - [26/Sep/2018 02:59:54] "GET /graph.svg HTTP/1.1" 200 -
[2018-09-26 02:59:57,836] ERROR in app: Exception on /graph.json [GET]
Traceback (most recent call last):
  File "/usr/local/lib/python3.6/site-packages/flask/app.py", line 2292, in wsgi_app
    response = self.full_dispatch_request()
  File "/usr/local/lib/python3.6/site-packages/flask/app.py", line 1815, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/usr/local/lib/python3.6/site-packages/flask/app.py", line 1718, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "/usr/local/lib/python3.6/site-packages/flask/_compat.py", line 35, in reraise
    raise value
  File "/usr/local/lib/python3.6/site-packages/flask/app.py", line 1813, in full_dispatch_request
    rv = self.dispatch_request()
  File "/usr/local/lib/python3.6/site-packages/flask/app.py", line 1799, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "/usr/local/lib/python3.6/site-packages/blastradius/server/server.py", line 57, in graph_json
    tf = Terraform(os.getcwd())
  File "/usr/local/lib/python3.6/site-packages/blastradius/handlers/terraform.py", line 67, in __init__
    self.modules[name] = Terraform(directory=self.directory+'/'+source, settings=mod)
  File "/usr/local/lib/python3.6/site-packages/blastradius/handlers/terraform.py", line 26, in __init__
    self.config = hcl.load(config_io)
  File "/usr/local/lib/python3.6/site-packages/hcl/api.py", line 51, in load
    return loads(fp.read())
  File "/usr/local/lib/python3.6/site-packages/hcl/api.py", line 62, in loads
    return HclParser().parse(s)
  File "/usr/local/lib/python3.6/site-packages/hcl/parser.py", line 307, in parse
    return self.yacc.parse(s, lexer=Lexer())
  File "/usr/local/lib/python3.6/site-packages/ply/yacc.py", line 331, in parse
    return self.parseopt_notrack(input, lexer, debug, tracking, tokenfunc)
  File "/usr/local/lib/python3.6/site-packages/ply/yacc.py", line 1199, in parseopt_notrack
    tok = call_errorfunc(self.errorfunc, errtoken, self)
  File "/usr/local/lib/python3.6/site-packages/ply/yacc.py", line 193, in call_errorfunc
    r = errorfunc(token)
  File "/usr/local/lib/python3.6/site-packages/hcl/parser.py", line 300, in p_error
    raise ValueError(msg)
ValueError: Line 131, column 4912: unexpected RIGHTBRACE
127.0.0.1 - - [26/Sep/2018 02:59:57] "GET /graph.json HTTP/1.1" 500 -

New project

Traceback (most recent call last):
File "/usr/bin/blast-radius", line 14, in
from blastradius.handlers.dot import DotGraph, Format, DotNode
File "/usr/lib/python3.4/site-packages/blastradius/handlers/dot.py", line 394
self.fmt = {**self.fmt, **kwargs}
^
SyntaxError: invalid syntax

Terraform Version in Docker container

The version of Terraform included in the Docker image is relatively old now. If you are using remote state and a newer version of Terraform, you cannot run blast-radius without editing the Dockerfile, update the TF_VERSION variable, and building a new image.

I'd like to propose building/maintaining multiple versions of the blast-radius container for x number of current versions of Terraform, and using tags to pull the proper version.

I don't see any CI stuff in the repository, otherwise I'd submit a PR against that.

Run without internet connection

Hi,

I have to work in an airgapped environment (without internet connection) where it is not possible to simply run "terraform init" or anything like this. We developed some helper framework to run terraform through a WebProxy but any call to terraform involves a lot of environment variables and a special setup of credential files for AWS and such. When I try using blast-radius I always get errors like "Failed to load backend" due to invalid credentials and the missing internet connection.
Is it somehow possible to run blast-radius off a pre created graph file? Something that does not involve any "terraform" call inside the docker container?
I already tried --graph like

docker run --cap-add=SYS_ADMIN -it --rm -p 5000:5000 -v $(pwd):/workdir:ro docker.registry.local/joerg/blast-radius --serve --graph global/my.graph global

but this gives the before mentioned errors. Interestingly it works with --json, --dot and --svg which gives me a huge JSON output

docker run --cap-add=SYS_ADMIN -it --rm -p 5000:5000 -v $(pwd):/workdir:ro docker.registry.local/joerg/blast-radius --json --graph global/my.graph global

No HCL object could be decoded

When I attempt to run blast-radius against some of my larger Terraform modules, I'm getting the following:

127.0.0.1 - - [24/Apr/2018 13:46:40] "GET / HTTP/1.1" 200 -
127.0.0.1 - - [24/Apr/2018 13:46:42] "GET /graph.svg HTTP/1.1" 200 -
[2018-04-24 13:46:43,373] ERROR in app: Exception on /graph.json [GET]
Traceback (most recent call last):
  File "my_home/.local/share/virtualenvs/blast-radius-g0pBURgw/lib/python3.5/site-packages/flask/app.py", line 1982, in wsgi_app
    response = self.full_dispatch_request()
  File "my_home/.local/share/virtualenvs/blast-radius-g0pBURgw/lib/python3.5/site-packages/flask/app.py", line 1614, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "my_home/.local/share/virtualenvs/blast-radius-g0pBURgw/lib/python3.5/site-packages/flask/app.py", line 1517, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "my_home/.local/share/virtualenvs/blast-radius-g0pBURgw/lib/python3.5/site-packages/flask/_compat.py", line 33, in reraise
    raise value
  File "my_home/.local/share/virtualenvs/blast-radius-g0pBURgw/lib/python3.5/site-packages/flask/app.py", line 1612, in full_dispatch_request
    rv = self.dispatch_request()
  File "my_home/.local/share/virtualenvs/blast-radius-g0pBURgw/lib/python3.5/site-packages/flask/app.py", line 1598, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "my_home/.local/share/virtualenvs/blast-radius-g0pBURgw/lib/python3.5/site-packages/blastradius/server/server.py", line 57, in graph_json
    tf = Terraform(os.getcwd())
  File "my_home/.local/share/virtualenvs/blast-radius-g0pBURgw/lib/python3.5/site-packages/blastradius/handlers/terraform.py", line 49, in __init__
    self.modules[name] = Terraform(directory=self.directory+'/'+source, settings=mod)
  File "my_home/.local/share/virtualenvs/blast-radius-g0pBURgw/lib/python3.5/site-packages/blastradius/handlers/terraform.py", line 26, in __init__
    self.config = hcl.load(config_io)
  File "my_home/.local/share/virtualenvs/blast-radius-g0pBURgw/lib/python3.5/site-packages/hcl/api.py", line 51, in load
    return loads(fp.read())
  File "my_home/.local/share/virtualenvs/blast-radius-g0pBURgw/lib/python3.5/site-packages/hcl/api.py", line 61, in loads
    if isHcl(s):
  File "my_home/.local/share/virtualenvs/blast-radius-g0pBURgw/lib/python3.5/site-packages/hcl/api.py", line 39, in isHcl
    raise ValueError("No HCL object could be decoded")
ValueError: No HCL object could be decoded

This module in particular has 243 edges:

$ terraform graph | grep -c '\->'
243

When I run blast-radius against my smaller modules, it can generate the graph.json just fine.

Loading / Status Dialog

Hi, just a quick suggestion to add a loading indicator, of some sort.

I've been trying to get Blast Radius to work all day and couldn't figure out why the graph.svg file would hang in my Chrome inspector. It just says "(pending)" for a long while and I thought something had been misconfigured or wasn't working properly.

After finding #25, however, I realized that nothing was wrong, after all, and it was just taking a while for the graph to be generated (~8 minutes), presumably because our Terraform config is relatively large (though, it's really not HUGE by any reasonable standard).

With that said, Blast Radius does not provide any indication that the graph is being generated behind the scenes and I think its very easy for people to assume that it's broken when nothing appears. So, I think the user should be informed about the ongoing render process in some way, if at all possible.

Of course I realize that this project probably doesn't justify a ton of time and expense and that it was created as a sort of proof-of-concept, but, still, I thought it would be useful for me to share my experience and provide the suggestion.

A few other notes:

  • Refocusing the graph causes another, long, delay, which could probably, also, benefit from a loading indicator. (It also makes me wonder if some data could be cached for performance)
  • graph.json laggs behind graph.svg, which is also not obvious.

Anyway, thanks for the awesome utility!

blast-radius not working with latest terraform version

blast-radius is not working with latest terraform version.
On inspection, blast-radius builds out terraform version 0.12.3, if a user is using a newer version of terraform they will get the following error:
Error refreshing state: state snapshot was created by Terraform v0.12.12, which is newer than current v0.12.3; upgrade to Terraform v0.12.12 or greater to work with this state

I have updated the terraform version in this PR: #70

Temporary mediation for compose users:
Create a docker-compose file like so:

version: '3.7'
services:
  graph:
    cap_add:
      - SYS_ADMIN
    image: gemini-blast-radius # 28mm/blast-radius
    build:
      context: ./
      dockerfile: ./Dockerfile
    ports:
      - "5000:5000"
    expose:
      - "5000"
    volumes:
      - "./:/data"

Create a Dockerfile with the following properties:

ARG TF_VERSION=0.12.12
ARG PYTHON_VERSION=3.7

FROM hashicorp/terraform:$TF_VERSION AS terraform_latest
FROM 28mm/blast-radius

COPY --from=terraform_latest /bin/terraform /bin/terraform

The above compose file pulls blast-radius as is, and then forces the terraform 0.12.12 binary into the blast radius container.

To call blast-radius just call docker--compose graph from the working directory of your terraform files.

Feature: presenting terraform apply progress in realtime

I've been following this project from the beginning and this is very interesting. You've thought about this before in a blog post :
It would be nice to have an option to monitor the terraform state file and mutate the graph when things are getting deployed.

I'm wondering how the current architecture is ready for this.

Basic Architecture Diagram?

I've spend a few hours looking at blast radius and it looks great!

What I was aiming to achieve was automatically generating Architecture diagrams anytime our terraform script changed.

My issue is that the level of detail is very detailed, I'm wanting a diagram that shows S3 connects to lambda, which goes to dyno then a SNS queue etc.

I'm wondering if theres a way to restrict the UI being served to only show the top level of each terraform resource we are defining not the variables (as we have heaps of tags and other stuff).

Any suggestions?

Installation fails while building wheel for BlastRadius

I attempted to use pip3 to install this app, and didn't find the app due to it being named "BlastRadius" and not "blast-radius" in the pip directory.

Once I was able to find the correct casing for the app, the installer yielded the following:

$ sudo pip3 install BlastRadius
Collecting BlastRadius
Using cached BlastRadius-0.1.4.tar.gz
Requirement already satisfied: Flask in /usr/local/lib/python3.5/dist-packages (from BlastRadius)
Requirement already satisfied: jinja2 in /usr/lib/python3/dist-packages (from BlastRadius)
Requirement already satisfied: pyhcl in /usr/local/lib/python3.5/dist-packages (from BlastRadius)
Requirement already satisfied: requests in /usr/lib/python3/dist-packages (from BlastRadius)
Requirement already satisfied: BeautifulSoup4 in /usr/local/lib/python3.5/dist-packages (from BlastRadius)
Requirement already satisfied: itsdangerous>=0.21 in /usr/local/lib/python3.5/dist-packages (from Flask->BlastRadius)
Requirement already satisfied: click>=2.0 in /usr/local/lib/python3.5/dist-packages (from Flask->BlastRadius)
Requirement already satisfied: Werkzeug>=0.7 in /usr/local/lib/python3.5/dist-packages (from Flask->BlastRadius)
Requirement already satisfied: MarkupSafe in /usr/lib/python3/dist-packages (from jinja2->BlastRadius)
Requirement already satisfied: ply==3.10 in /usr/local/lib/python3.5/dist-packages (from pyhcl->BlastRadius)
Building wheels for collected packages: BlastRadius
Running setup.py bdist_wheel for BlastRadius ... error
Complete output from command /usr/bin/python3 -u -c "import setuptools, tokenize;file='/tmp/pip-build-4gaediim/BlastRadius/setup.py';f=getattr(tokenize, 'open', open)(file);code=f.read().replace('\r\n', '\n');f.close();exec(compile(code, file, 'exec'))" bdist_wheel -d /tmp/tmpw8ouc3sjpip-wheel- --python-tag cp35:
running bdist_wheel
running build
running build_py
creating build
creating build/lib
creating build/lib/blastradius
copying blastradius/init.py -> build/lib/blastradius
copying blastradius/graph.py -> build/lib/blastradius
copying blastradius/util.py -> build/lib/blastradius
creating build/lib/blastradius/handlers
copying blastradius/handlers/init.py -> build/lib/blastradius/handlers
copying blastradius/handlers/apply.py -> build/lib/blastradius/handlers
copying blastradius/handlers/dot.py -> build/lib/blastradius/handlers
copying blastradius/handlers/plan.py -> build/lib/blastradius/handlers
copying blastradius/handlers/terraform.py -> build/lib/blastradius/handlers
creating build/lib/blastradius/server
copying blastradius/server/init.py -> build/lib/blastradius/server
copying blastradius/server/server.py -> build/lib/blastradius/server
error: can't copy 'blastradius/pycache': doesn't exist or not a regular file


Failed building wheel for BlastRadius
Running setup.py clean for BlastRadius
Failed to build BlastRadius
Installing collected packages: BlastRadius
Running setup.py install for BlastRadius ... error
Complete output from command /usr/bin/python3 -u -c "import setuptools, tokenize;file='/tmp/pip-build-4gaediim/BlastRadius/setup.py';f=getattr(tokenize, 'open', open)(file);code=f.read().replace('\r\n', '\n');f.close();exec(compile(code, file, 'exec'))" install --record /tmp/pip-kw55m4su-record/install-record.txt --single-version-externally-managed --compile:
running install
running build
running build_py
creating build
creating build/lib
creating build/lib/blastradius
copying blastradius/init.py -> build/lib/blastradius
copying blastradius/graph.py -> build/lib/blastradius
copying blastradius/util.py -> build/lib/blastradius
creating build/lib/blastradius/handlers
copying blastradius/handlers/init.py -> build/lib/blastradius/handlers
copying blastradius/handlers/apply.py -> build/lib/blastradius/handlers
copying blastradius/handlers/dot.py -> build/lib/blastradius/handlers
copying blastradius/handlers/plan.py -> build/lib/blastradius/handlers
copying blastradius/handlers/terraform.py -> build/lib/blastradius/handlers
creating build/lib/blastradius/server
copying blastradius/server/init.py -> build/lib/blastradius/server
copying blastradius/server/server.py -> build/lib/blastradius/server
error: can't copy 'blastradius/pycache': doesn't exist or not a regular file

----------------------------------------

Command "/usr/bin/python3 -u -c "import setuptools, tokenize;file='/tmp/pip-build-4gaediim/BlastRadius/setup.py';f=getattr(tokenize, 'open', open)(file);code=f.read().replace('\r\n', '\n');f.close();exec(compile(code, file, 'exec'))" install --record /tmp/pip-kw55m4su-record/install-record.txt --single-version-externally-managed --compile" failed with error code 1 in /tmp/pip-build-4gaediim/BlastRadius/

the directory exists, is there a globbing issue with your installer path?

host = self.public_ip ValueError: unexpected IDENTIFIER

It trips up on the host = self.public_ip line.

  connection {
    type        = "ssh"
    host        = self.public_ip
    user        = "ec2-user"
    private_key = "${file(var.private_key_path)}"
  }

to give this error message:

ValueError: Line 27, column 496: unexpected IDENTIFIER
127.0.0.1 - - [15/Aug/2019 21:38:44] "GET /graph.json HTTP/1.1" 500 -

Works fine if I remove that line.

Access Denied error on Mac

Mac OSX 10.13.6 (High Sierra)
Python version: 2.7.10
Running : blast-radius --serve .

 * Debug mode: off
 * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
127.0.0.1 - - [28/Nov/2018 10:50:24] "GET / HTTP/1.1" 200 -
Error loading state: AccessDenied: Access Denied
	status code: 403, request id: F5D440E18F1778DA, host id: hWAk0q67MYM+a7gao50Ytkw4+b0s8jPfeFZl7CEbmOIyU4EavpMuLxf7pNJzYra3sSCmApBQxwA=
[2018-11-28 10:50:27,048] ERROR in app: Exception on /graph.svg [GET]
Traceback (most recent call last):
  File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 2292, in wsgi_app
    response = self.full_dispatch_request()
  File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 1815, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 1718, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "/usr/local/lib/python3.7/site-packages/flask/_compat.py", line 35, in reraise
    raise value
  File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 1813, in full_dispatch_request
    rv = self.dispatch_request()
  File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 1799, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "/usr/local/lib/python3.7/site-packages/blastradius/server/server.py", line 32, in graph_svg
    dot = DotGraph('', file_contents=run_tf_graph())
  File "/usr/local/lib/python3.7/site-packages/blastradius/server/server.py", line 71, in run_tf_graph
    raise
RuntimeError: No active exception to reraise
127.0.0.1 - - [28/Nov/2018 10:50:27] "GET /graph.svg HTTP/1.1" 500 -

Any Hints?

Build error

Hi, it seems that the last two builds in CircleCI were broken and as a result, the Docker Image was not updated to using Terraform 0.12.12.

No matching distribution found for blast-radius

hey there - i get this message when trying to install your amazing tool!

pip3 install blast-radius
Collecting blast-radius
  Could not find a version that satisfies the requirement blast-radius (from versions: )
No matching distribution found for blast-radius

graph.json crashing with coreos tectonic vmware terraform

COREOS TECTONIC VERSION
curl -O https://releases.tectonic.com/releases/tectonic_1.8.4-tectonic.3.zip

ERROR
tf = Terraform(os.getcwd())
File "/usr/lib/python3.6/site-packages/blastradius/handlers/terraform.py", line 49, in init
self.modules[name] = Terraform(directory=self.directory+'/'+source, settings=mod)
File "/usr/lib/python3.6/site-packages/blastradius/handlers/terraform.py", line 26, in init
self.config = hcl.load(config_io)
File "/usr/lib/python3.6/site-packages/hcl/api.py", line 51, in load
return loads(fp.read())
File "/usr/lib/python3.6/site-packages/hcl/api.py", line 62, in loads
return HclParser().parse(s)
File "/usr/lib/python3.6/site-packages/hcl/parser.py", line 307, in parse
return self.yacc.parse(s, lexer=Lexer())
File "/usr/lib/python3.6/site-packages/ply/yacc.py", line 331, in parse
return self.parseopt_notrack(input, lexer, debug, tracking, tokenfunc)
File "/usr/lib/python3.6/site-packages/ply/yacc.py", line 1061, in parseopt_notrack
lookahead = get_token() # Get the next token
File "/usr/lib/python3.6/site-packages/hcl/lexer.py", line 275, in token
return self.lex.token()
File "/usr/lib/python3.6/site-packages/ply/lex.py", line 406, in token
newtok = self.lexeoff(tok)
File "/usr/lib/python3.6/site-packages/hcl/lexer.py", line 222, in t_heredoc_eof
_raise_error(t, 'EOF before closing heredoc')
File "/usr/lib/python3.6/site-packages/hcl/lexer.py", line 17, in _raise_error
raise ValueError("Line %d, column %d, index %d: %s" % (lineno, column, lexpos, message))
ValueError: Line 438, column 1, index 12356: EOF before closing heredoc

Narrowed it down to these source objects and resources
modules/ignition
'ignition_masters': {'source': '../../modules/ignition', 'base_domain': '${var.tectonic_base_domain}', 'bootstrap_upgrade_cl': '${var.tectonic_bootstrap_upgrade_cl}', 'cluster_name': '${var.tectonic_cluster_name}', 'container_images': '${var.tectonic_container_images}', 'etcd_advertise_name_list': '${data.template_file.etcd_hostname_list..rendered}', 'etcd_count': '${length(data.template_file.etcd_hostname_list..rendered)}', 'etcd_initial_cluster_list': '${data.template_file.etcd_hostname_list.*.rendered}', 'etcd_tls_enabled': '${var.tectonic_etcd_tls_enabled}', 'image_re': '${var.tectonic_image_re}', 'kube_dns_service_ip': '${module.bootkube.kube_dns_service_ip}', 'kubelet_cni_bin_dir': '${var.tectonic_networking == "calico" || var.tectonic_networking == "canal" ? "/var/lib/cni/bin" : "" }', 'kubelet_debug_config': '${var.tectonic_kubelet_debug_config}', 'kubelet_node_label': 'node-role.kubernetes.io/master', 'kubelet_node_taints': 'node-role.kubernetes.io/master=:NoSchedule', 'use_metadata': False, 'tectonic_vanilla_k8s': '${var.tectonic_vanilla_k8s}'},

modules/vmware/node
'masters': {'source': '../../modules/vmware/node', 'base_domain': '${var.tectonic_base_domain}', 'container_images': '${var.tectonic_container_images}', 'core_public_keys': ['${var.tectonic_vmware_ssh_authorized_key}'], 'dns_server': '${var.tectonic_vmware_node_dns}', 'gateways': '${var.tectonic_vmware_master_gateways}', 'hostname': '${var.tectonic_vmware_master_hostnames}', 'ign_bootkube_path_unit_id': '${module.bootkube.systemd_path_unit_id}', 'ign_bootkube_service_id': '${module.bootkube.systemd_service_id}', 'ign_docker_dropin_id': '${module.ignition_masters.docker_dropin_id}', 'ign_installer_kubelet_env_id': '${module.ignition_masters.installer_kubelet_env_id}', 'ign_installer_runtime_mappings_id': '${module.ignition_masters.installer_runtime_mappings_id}', 'ign_k8s_node_bootstrap_service_id': '${module.ignition_masters.k8s_node_bootstrap_service_id}', 'ign_kubelet_service_id': '${module.ignition_masters.kubelet_service_id}', 'ign_locksmithd_service_id': '${module.ignition_masters.locksmithd_service_id}', 'ign_max_user_watches_id': '${module.ignition_masters.max_user_watches_id}', 'ign_tectonic_path_unit_id': '${var.tectonic_vanilla_k8s ? "" : module.tectonic.systemd_path_unit_id}', 'ign_tectonic_service_id': '${module.tectonic.systemd_service_id}', 'image_re': '${var.tectonic_image_re}', 'instance_count': '${var.tectonic_master_count}', 'ip_address': '${var.tectonic_vmware_master_ip}', 'kubeconfig': '${module.bootkube.kubeconfig}', 'private_key': '${var.tectonic_vmware_ssh_private_key_path}', 'vm_disk_datastore': '${var.tectonic_vmware_master_datastore}', 'vm_disk_template': '${var.tectonic_vmware_vm_template}', 'vm_disk_template_folder': '${var.tectonic_vmware_vm_template_folder}', 'vm_memory': '${var.tectonic_vmware_master_memory}', 'vm_network_labels': '${var.tectonic_vmware_master_networks}', 'vm_vcpu': '${var.tectonic_vmware_master_vcpu}', 'vmware_clusters': '${var.tectonic_vmware_master_clusters}', 'vmware_datacenters': '${var.tectonic_vmware_master_datacenters}', 'vmware_folder': '${vsphere_folder.tectonic_vsphere_folder.path}', 'vmware_resource_pool': '${var.tectonic_vmware_master_resource_pool}'},

Docker with AWS credentials stored externally

I store my AWS credentials far, far away from my Terraform source code, preferring per-project access keys and a profile configured via aws configure. I add 2 additional options to my docker run command:

  -v ~/.aws:/root/.aws -e AWS_PROFILE=projectprofile \

Adding the volume ~/.aws gives the scripts access to the saved keys I have, and the environment tells which one to use.

Hope this may help somebody.

Docker support

@brogersyh -- just merged your changes from #6 . Really wonderful stuff. I'm a faltering and infrequent user of docker, but managed to upload to the docker hub under 28mm/blast-radius, and will make this part of the release process.

Cutting an issue for discussion.

  • Sometimes label text overflows its bounding box. I suspect this is to do with the fonts Graphviz uses under the alpine linux image being differently sized/proportioned than on macos.
  • docker-entrypoint.sh runs terraform init. If a .terraform directory already maybe it should run terraform get, instead?
  • Documentation. I've got some other changes planned in this area, so I'll probably tackle this soon.

Anyway, would be glad to have your thoughts, and happy new years 🥂

docker: cd: /workdir-rw: No such file or directory

Hi

I have tried example from README and got error:

gcp-tf $ docker run --cap-add=SYS_ADMIN -it --rm -p 5000:5000 -v $(pwd):/workdir:ro 28mm/blast-radius
mount: /tmp/overlay: cannot mount tmpfs read-only.
/src/docker-entrypoint.sh: line 14: cd: /workdir-rw: No such file or directory

Error when reading one of my state files

Terraform v0.11.10

Im seeing this error (this is a valid tf config that applies successfully). Some other tf state it seems to work fine with, but this one it no like

  • Debug mode: off
  • Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
    127.0.0.1 - - [21/Jan/2019 09:38:05] "GET / HTTP/1.1" 200 -
    127.0.0.1 - - [21/Jan/2019 09:38:10] "GET / HTTP/1.1" 200 -
    127.0.0.1 - - [21/Jan/2019 09:38:12] "GET /graph.svg HTTP/1.1" 200 -
    [2019-01-21 09:38:14,328] ERROR in app: Exception on /graph.json [GET]
    Traceback (most recent call last):
    File "/Users/meee/.pyenv/versions/3.6.5/lib/python3.6/site-packages/flask/app.py", line 2292, in wsgi_app
    response = self.full_dispatch_request()
    File "/Users/meee/.pyenv/versions/3.6.5/lib/python3.6/site-packages/flask/app.py", line 1815, in full_dispatch_request
    rv = self.handle_user_exception(e)
    File "/Users/meee/.pyenv/versions/3.6.5/lib/python3.6/site-packages/flask/app.py", line 1718, in handle_user_exception
    reraise(exc_type, exc_value, tb)
    File "/Users/meee/.pyenv/versions/3.6.5/lib/python3.6/site-packages/flask/_compat.py", line 35, in reraise
    raise value
    File "/Users/meee/.pyenv/versions/3.6.5/lib/python3.6/site-packages/flask/app.py", line 1813, in full_dispatch_request
    rv = self.dispatch_request()
    File "/Users/meee/.pyenv/versions/3.6.5/lib/python3.6/site-packages/flask/app.py", line 1799, in dispatch_request
    return self.view_functionsrule.endpoint
    File "/Users/meee/.pyenv/versions/3.6.5/lib/python3.6/site-packages/blastradius/server/server.py", line 61, in graph_json
    tf = Terraform(os.getcwd())
    File "/Users/meee/.pyenv/versions/3.6.5/lib/python3.6/site-packages/blastradius/handlers/terraform.py", line 26, in init
    self.config = hcl.load(config_io)
    File "/Users/meee/.pyenv/versions/3.6.5/lib/python3.6/site-packages/hcl/api.py", line 51, in load
    return loads(fp.read())
    File "/Users/meee/.pyenv/versions/3.6.5/lib/python3.6/site-packages/hcl/api.py", line 62, in loads
    return HclParser().parse(s)
    File "/Users/meee/.pyenv/versions/3.6.5/lib/python3.6/site-packages/hcl/parser.py", line 307, in parse
    return self.yacc.parse(s, lexer=Lexer())
    File "/Users/meee/.pyenv/versions/3.6.5/lib/python3.6/site-packages/ply/yacc.py", line 331, in parse
    return self.parseopt_notrack(input, lexer, debug, tracking, tokenfunc)
    File "/Users/meee/.pyenv/versions/3.6.5/lib/python3.6/site-packages/ply/yacc.py", line 1199, in parseopt_notrack
    tok = call_errorfunc(self.errorfunc, errtoken, self)
    File "/Users/meee/.pyenv/versions/3.6.5/lib/python3.6/site-packages/ply/yacc.py", line 193, in call_errorfunc
    r = errorfunc(token)
    File "/Users/meee/.pyenv/versions/3.6.5/lib/python3.6/site-packages/hcl/parser.py", line 300, in p_error
    raise ValueError(msg)
    ValueError: Line 171, column 6458: unexpected RIGHTBRACE
    127.0.0.1 - - [21/Jan/2019 09:38:14] "GET /graph.json HTTP/1.1" 500 -

Getting 500 error for graph.svg

No graph/icon is displayed on either Chrome or Firefox; run in directory that has 'terraform init --reconfigure'; I generated a graph.svg in the same directory

ProductName:	Mac OS X
ProductVersion:	10.12.6
BuildVersion:	16G1212

Google Chrome 64.0.3282.186
blast-radius --serve                                                                                                       
 * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
127.0.0.1 - - [26/Feb/2018 10:55:05] "GET / HTTP/1.1" 200 -
127.0.0.1 - - [26/Feb/2018 10:55:07] "GET /graph.svg HTTP/1.1" 500 -
127.0.0.1 - - [26/Feb/2018 10:56:26] "GET / HTTP/1.1" 200 -
127.0.0.1 - - [26/Feb/2018 10:56:28] "GET /graph.svg HTTP/1.1" 500 -
127.0.0.1 - - [26/Feb/2018 10:57:28] "GET /static/js/bootstrap.min.js.map HTTP/1.1" 404 -
127.0.0.1 - - [26/Feb/2018 10:57:28] "GET /static/css/bootstrap.min.css.map HTTP/1.1" 404 -

Also tried using blast-radius --serve . and blast-radius --serve /full_path/foo/bar
image

unexpected identifier error

Hello, I'm trying this out with a terraform 0.12 project (which I suspect could be the root issue). The terraform is planned/applied successfully. The blast-radius graph draws on the screen but is not interactive. The blast-radius server shows this output:

[2019-05-30 13:06:33,958] ERROR in app: Exception on /graph.json [GET]
Traceback (most recent call last):
  File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 2311, in wsgi_app
    response = self.full_dispatch_request()
  File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 1834, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 1737, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "/usr/local/lib/python3.7/site-packages/flask/_compat.py", line 36, in reraise
    raise value
  File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 1832, in full_dispatch_request
    rv = self.dispatch_request()
  File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 1818, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "/usr/local/lib/python3.7/site-packages/blastradius/server/server.py", line 61, in graph_json
    tf = Terraform(os.getcwd())
  File "/usr/local/lib/python3.7/site-packages/blastradius/handlers/terraform.py", line 26, in __init__
    self.config = hcl.load(config_io)
  File "/usr/local/lib/python3.7/site-packages/hcl/api.py", line 54, in load
    return loads(fp.read())
  File "/usr/local/lib/python3.7/site-packages/hcl/api.py", line 66, in loads
    return HclParser().parse(s)
  File "/usr/local/lib/python3.7/site-packages/hcl/parser.py", line 326, in parse
    return self.yacc.parse(s, lexer=Lexer())
  File "/usr/local/lib/python3.7/site-packages/ply/yacc.py", line 333, in parse
    return self.parseopt_notrack(input, lexer, debug, tracking, tokenfunc)
  File "/usr/local/lib/python3.7/site-packages/ply/yacc.py", line 1201, in parseopt_notrack
    tok = call_errorfunc(self.errorfunc, errtoken, self)
  File "/usr/local/lib/python3.7/site-packages/ply/yacc.py", line 192, in call_errorfunc
    r = errorfunc(token)
  File "/usr/local/lib/python3.7/site-packages/hcl/parser.py", line 318, in p_error
    raise ValueError(msg)
ValueError: Line 18, column 423: unexpected IDENTIFIER
172.27.192.130 - - [30/May/2019 13:06:33] "GET /graph.json HTTP/1.1" 500 -

Is there a way to find the unexpected identifier to debug further? I tried running blast-radius with --debug but it was not a valid flag.

Feature Request: Better error reporting in --serve mode

Blast Radius , when launched in --serve mode, does some pretty weak error reporting, and does nothing to help users resolve problems. It asks the user to look into several possible issues, rather than checking itself...

To observe the current (undesired) behavior, run Blast Radius in an empty directory:

[...]$ mkdir tmp
[...]$ cd tmp
[...]$ blast-radius --serve

A short list of tests/checks to automate:

  • Check if graphviz is installed (is dot in its path?)
  • Check if terraform is installed (is terraform in its path?)
  • Is the current project initialized?
    • maybe it is, but a module is missing and terraform get needs to run...
    • maybe it is, but it's initialized for the run arch/os...
  • For that matter, does this directory contain files ending in .tf or .tfvars?

The error page could link to relevant documentation, including the Blast Radius online documentation at https://28mm.github.io/blast-radius-docs

issue rendering json

Currently getting the following version using terraform 12.18

The hardcoded 12.12 version is affected by a git bug that prevents modules from working.

I am running the following in a docker container

ARG TF_VERSION=latest
ARG PYTHON_VERSION=3.7

FROM hashicorp/terraform:$TF_VERSION AS terraform

FROM python:$PYTHON_VERSION-alpine
RUN pip install -U pip ply \
 && apk add --update --no-cache graphviz ttf-freefont

COPY --from=terraform /bin/terraform /bin/terraform
COPY ./docker-entrypoint.sh /bin/docker-entrypoint.sh
RUN chmod +x /bin/docker-entrypoint.sh

WORKDIR /src
COPY . .
RUN pip install -e .

WORKDIR /data

ENTRYPOINT ["/bin/docker-entrypoint.sh"]
CMD ["blast-radius", "--serve"]

Getting an error 500 in chrome and firefox visiting the site.

I did try and upgrade all the python libraries. Could you point me in a good direction? seems like the json parsing isn't right.

* Serving Flask app "blastradius.server.server" (lazy loading)
 * Environment: production
   WARNING: This is a development server. Do not use it in a production deployment.
   Use a production WSGI server instead.
 * Debug mode: off
 * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
172.17.0.1 - - [19/Jan/2020 17:35:13] "GET / HTTP/1.1" 200 -
172.17.0.1 - - [19/Jan/2020 17:35:21] "GET /graph.svg HTTP/1.1" 200 -
[2020-01-19 17:35:27,651] ERROR in app: Exception on /graph.json [GET]
Traceback (most recent call last):
  File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 2311, in wsgi_app
    response = self.full_dispatch_request()
  File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 1834, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 1737, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "/usr/local/lib/python3.7/site-packages/flask/_compat.py", line 36, in reraise
    raise value
  File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 1832, in full_dispatch_request
    rv = self.dispatch_request()
  File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 1818, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "/src/blastradius/server/server.py", line 61, in graph_json
    tf = Terraform(os.getcwd())
  File "/src/blastradius/handlers/terraform.py", line 26, in __init__
    self.config = hcl.load(config_io)
  File "/usr/local/lib/python3.7/site-packages/hcl/api.py", line 54, in load
    return loads(fp.read())
  File "/usr/local/lib/python3.7/site-packages/hcl/api.py", line 66, in loads
    return HclParser().parse(s)
  File "/usr/local/lib/python3.7/site-packages/hcl/parser.py", line 326, in parse
    return self.yacc.parse(s, lexer=Lexer())
  File "/usr/local/lib/python3.7/site-packages/ply/yacc.py", line 333, in parse
    return self.parseopt_notrack(input, lexer, debug, tracking, tokenfunc)
  File "/usr/local/lib/python3.7/site-packages/ply/yacc.py", line 1201, in parseopt_notrack
    tok = call_errorfunc(self.errorfunc, errtoken, self)
  File "/usr/local/lib/python3.7/site-packages/ply/yacc.py", line 192, in call_errorfunc
    r = errorfunc(token)
  File "/usr/local/lib/python3.7/site-packages/hcl/parser.py", line 318, in p_error
    raise ValueError(msg)
ValueError: Line 10, column 216: unexpected IDENTIFIER
172.17.0.1 - - [19/Jan/2020 17:35:27] "GET /graph.json HTTP/1.1" 500 -

Support windows (it's pretty easy)

To support windows :

In server.py just change a few lines:
def index():
# we need terraform, graphviz, and an init-ed terraform project.
if not which('terraform') or not which('dot'):
if not which('terraform.exe') or not which('dot.exe'):
return render_template('error.html')
if not os.path.exists('.terraform'):
return render_template('error.html')

Not working with s3 backend

Hi I followed all the steps to generate graph.svg, but I keep getting 400 resource not found when running blast-radius

Fresh install ubuntu error

Blast Radius fresh install on ubuntu is failing to execute.

terraform-repo >pip install BlastRadius --no-cache-dir                                                                                                                                                                                                         16:41:19

Collecting BlastRadius
  Downloading BlastRadius-0.1.10.tar.gz (560kB)
    100% |████████████████████████████████| 563kB 772kB/s 
Collecting BeautifulSoup4 (from BlastRadius)
  Downloading beautifulsoup4-4.6.0-py2-none-any.whl (86kB)
    100% |████████████████████████████████| 92kB 1.1MB/s 
Collecting Flask (from BlastRadius)
  Downloading Flask-0.12.2-py2.py3-none-any.whl (83kB)
    100% |████████████████████████████████| 92kB 959kB/s 
Collecting jinja2 (from BlastRadius)
  Downloading Jinja2-2.10-py2.py3-none-any.whl (126kB)
    100% |████████████████████████████████| 133kB 996kB/s 
Collecting pyhcl (from BlastRadius)
  Downloading pyhcl-0.3.9.tar.gz
Collecting requests (from BlastRadius)
  Downloading requests-2.18.4-py2.py3-none-any.whl (88kB)
    100% |████████████████████████████████| 92kB 1.3MB/s 
Collecting itsdangerous>=0.21 (from Flask->BlastRadius)
  Downloading itsdangerous-0.24.tar.gz (46kB)
    100% |████████████████████████████████| 51kB 1.5MB/s 
Collecting Werkzeug>=0.7 (from Flask->BlastRadius)
  Downloading Werkzeug-0.14.1-py2.py3-none-any.whl (322kB)
    100% |████████████████████████████████| 327kB 976kB/s 
Collecting click>=2.0 (from Flask->BlastRadius)
  Downloading click-6.7-py2.py3-none-any.whl (71kB)
    100% |████████████████████████████████| 71kB 1.2MB/s 
Collecting MarkupSafe>=0.23 (from jinja2->BlastRadius)
  Downloading MarkupSafe-1.0.tar.gz
Collecting ply==3.10 (from pyhcl->BlastRadius)
  Downloading ply-3.10.tar.gz (150kB)
    100% |████████████████████████████████| 153kB 988kB/s 
Collecting idna<2.7,>=2.5 (from requests->BlastRadius)
  Downloading idna-2.6-py2.py3-none-any.whl (56kB)
    100% |████████████████████████████████| 61kB 1.4MB/s 
Collecting urllib3<1.23,>=1.21.1 (from requests->BlastRadius)
  Downloading urllib3-1.22-py2.py3-none-any.whl (132kB)
    100% |████████████████████████████████| 133kB 1.2MB/s 
Collecting certifi>=2017.4.17 (from requests->BlastRadius)
  Downloading certifi-2018.1.18-py2.py3-none-any.whl (151kB)
    100% |████████████████████████████████| 153kB 1.1MB/s 
Collecting chardet<3.1.0,>=3.0.2 (from requests->BlastRadius)
  Downloading chardet-3.0.4-py2.py3-none-any.whl (133kB)
    100% |████████████████████████████████| 143kB 1.4MB/s 
Installing collected packages: BeautifulSoup4, itsdangerous, MarkupSafe, jinja2, Werkzeug, click, Flask, ply, pyhcl, idna, urllib3, certifi, chardet, requests, BlastRadius
  Running setup.py install for itsdangerous ... done
  Running setup.py install for MarkupSafe ... done
  Running setup.py install for ply ... done
  Running setup.py install for pyhcl ... done
  Running setup.py install for BlastRadius ... done
Successfully installed BeautifulSoup4-4.6.0 BlastRadius-0.1.10 Flask-0.12.2 MarkupSafe-1.0 Werkzeug-0.14.1 certifi-2018.1.18 chardet-3.0.4 click-6.7 idna-2.6 itsdangerous-0.24 jinja2-2.10 ply-3.10 pyhcl-0.3.9 requests-2.18.4 urllib3-1.22

user >cd Documents/Work/terraform-repo/                                                                                                                                                                                                                   16:36:15

terraform-repo >blast-radius --serve .                                                                                                                                                                                                                         16:36:18

Traceback (most recent call last):
  File "/usr/bin/blast-radius", line 14, in <module>
    from blastradius.handlers.dot import DotGraph, Format, DotNode
  File "/home/user/.local/lib/python2.7/site-packages/blastradius/handlers/dot.py", line 391
    print('Error processing format param: ' + 'p', file=sys.stderr)
                                                       ^
SyntaxError: invalid syntax

terraform-repo >pip --version 16:36:26

ppip 9.0.1 from /usr/lib/python2.7/dist-packages (python 2.7)
terraform-repo >python --version 16:38:01

Python 2.7.14
terraform-repo >lsb_release -a 16:38:02
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 17.10
Release: 17.10
Codename: artful

Hosting on Azure

Hi, has anyone tried hosting this awesome tool on Azure? Either App Service or Azure Function is fine.
I tried a few things but I am a python beginner so I am basically just asking for any clues on how to get it running :)

Handling (removed) modules

I ran into this issue which I think has to do with the specify svg graph as I wasn't able to open the svg with certain program like GIMP (but can open with other program and terraform graph itself doesn't show error). I don't know much about svg to know why it'd cause such error.

terraform graph | blast-radius --svg > graph.svg                          
Traceback (most recent call last):
  File "/Users/antho/Library/Python/3.6/bin//blast-radius", line 95, in <module>
    main()
  File "/Users/antho/Library/Python/3.6/bin//blast-radius", line 53, in main
    dot = DotGraph('', file_contents=sys.stdin.read())
  File "/Users/antho/Library/Python/3.6/lib/python/site-packages/blastradius/handlers/dot.py", line 56, in __init__
    self.nodes.append(DotNode(e.target))
  File "/Users/antho/Library/Python/3.6/lib/python/site-packages/blastradius/handlers/dot.py", line 414, in __init__
    self.module         = DotNode._module(label) # for module groupings. 'root' or 'module.foo.module.bar'
  File "/Users/antho/Library/Python/3.6/lib/python/site-packages/blastradius/handlers/dot.py", line 448, in _module
    return m.groupdict()['module']
AttributeError: 'NoneType' object has no attribute 'groupdict'```

HTTP 500 internal server error: unexpected LEFTBRACKET

fwiw, this happens using https://github.com/crossbario/terraform-aws-crossbar :

Bildschirmfoto von 2020-07-11 00-56-53

27.0.0.1 - - [11/Jul/2020 00:56:49] "GET /graph.svg HTTP/1.1" 200 -
[2020-07-11 00:56:50,110] ERROR in app: Exception on /graph.json [GET]
Traceback (most recent call last):
  File "/home/oberstet/cpy382_1/lib/python3.8/site-packages/flask/app.py", line 2447, in wsgi_app
    response = self.full_dispatch_request()
  File "/home/oberstet/cpy382_1/lib/python3.8/site-packages/flask/app.py", line 1952, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/home/oberstet/cpy382_1/lib/python3.8/site-packages/flask/app.py", line 1821, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "/home/oberstet/cpy382_1/lib/python3.8/site-packages/flask/_compat.py", line 39, in reraise
    raise value
  File "/home/oberstet/cpy382_1/lib/python3.8/site-packages/flask/app.py", line 1950, in full_dispatch_request
    rv = self.dispatch_request()
  File "/home/oberstet/cpy382_1/lib/python3.8/site-packages/flask/app.py", line 1936, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "/home/oberstet/cpy382_1/lib/python3.8/site-packages/blastradius/server/server.py", line 61, in graph_json
    tf = Terraform(os.getcwd())
  File "/home/oberstet/cpy382_1/lib/python3.8/site-packages/blastradius/handlers/terraform.py", line 67, in __init__
    self.modules[name] = Terraform(directory=self.directory+'/'+source, settings=mod)
  File "/home/oberstet/cpy382_1/lib/python3.8/site-packages/blastradius/handlers/terraform.py", line 26, in __init__
    self.config = hcl.load(config_io)
  File "/home/oberstet/cpy382_1/lib/python3.8/site-packages/hcl/api.py", line 62, in load
    return loads(fp.read(), export_comments=export_comments)
  File "/home/oberstet/cpy382_1/lib/python3.8/site-packages/hcl/api.py", line 81, in loads
    return HclParser().parse(s, export_comments=export_comments)
  File "/home/oberstet/cpy382_1/lib/python3.8/site-packages/hcl/parser.py", line 642, in parse
    return self.yacc.parse(
  File "/home/oberstet/cpy382_1/lib/python3.8/site-packages/hcl/ply/yacc.py", line 503, in parse
    tok = self.errorfunc(errtoken)
  File "/home/oberstet/cpy382_1/lib/python3.8/site-packages/hcl/parser.py", line 634, in p_error
    raise ValueError(msg)
ValueError: Line 1353, column 41614: unexpected LEFTBRACKET; expected COMMA, IDENTIFIER, STRING, COMMENT, MULTICOMMENT, MINUS, NUMBER, FLOAT, $end, RIGHTBRACE, RIGHTBRACKET, RIGHTPAREN, PERIOD
127.0.0.1 - - [11/Jul/2020 00:56:50] "GET /graph.json HTTP/1.1" 500 -

ERROR in app: Exception on /graph.json [GET]

127.0.0.1 - - [14/Nov/2018 15:41:27] "GET /graph.svg HTTP/1.1" 200 -
[2018-11-14 15:41:30,641] ERROR in app: Exception on /graph.json [GET]
.....
raise ValueError("Line %d, column %d, index %d: %s" % (lineno, column, lexpos, message))
ValueError: Line 25, column 0, index 595: Found '*/' before start of multiline comment

Add options for simplified graph display

The display of complex graphs quickly becomes confusing, especially when modules are used. Terraform itself supports a --module-depth option, that eliminate the display of deeply nested modules.

This ticket proposes several mechanisms for simplifying the display of these graphs.

  1. --module-depth -- the same as Terraform
  2. --focus -- present only a given node and its dependencies.
  3. --center -- same as --focus but also include nodes that depend on the given node.

Container without CAP_SYS_ADMIN

I'd like to just see the picture of my config without installing too much libs on my system to avoid breaking things. But it doesn't work.

✗ terraform graph -draw-cycles | docker run -i 28mm/blast-radius
mount: /tmp/overlay: permission denied.
/src/docker-entrypoint.sh: line 14: cd: /workdir-rw: No such file or directory

I read that using CAP_SYS_ADMIN is a bad security practice. Is it possible to build container without it? Or make it optional.

https://www.slideshare.net/jpetazzo/linux-containers-lxc-docker-and-security/19-HoweverCAPSYSADMIN_is_a_big_can

Getting chmod: cannot access

i download the zip code and extract. put one *.tf file in same directory. after running the below command, i got error mentioned below:
command:

docker build -t blast-radius - < Dockerfile

error:

chmod: cannot access './docker-build.sh': No such file or directory

HCL Parser Error

I get the following error with blast-radius 0.1.12:

  • Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
    172.17.0.1 - - [23/Mar/2018 14:22:37] "GET / HTTP/1.1" 200 -
    172.17.0.1 - - [23/Mar/2018 14:22:42] "GET /graph.svg HTTP/1.1" 200 -
    [2018-03-23 14:22:44,757] ERROR in app: Exception on /graph.json [GET]
    Traceback (most recent call last):
    File "/usr/local/lib/python3.6/dist-packages/flask/app.py", line 1982, in wsgi_app
    response = self.full_dispatch_request()
    File "/usr/local/lib/python3.6/dist-packages/flask/app.py", line 1614, in full_dispatch_request
    rv = self.handle_user_exception(e)
    File "/usr/local/lib/python3.6/dist-packages/flask/app.py", line 1517, in handle_user_exception
    reraise(exc_type, exc_value, tb)
    File "/usr/local/lib/python3.6/dist-packages/flask/_compat.py", line 33, in reraise
    raise value
    File "/usr/local/lib/python3.6/dist-packages/flask/app.py", line 1612, in full_dispatch_request
    rv = self.dispatch_request()
    File "/usr/local/lib/python3.6/dist-packages/flask/app.py", line 1598, in dispatch_request
    return self.view_functionsrule.endpoint
    File "/src/blastradius/server/server.py", line 57, in graph_json
    tf = Terraform(os.getcwd())
    File "/src/blastradius/handlers/terraform.py", line 26, in init
    self.config = hcl.load(config_io)
    File "/usr/local/lib/python3.6/dist-packages/hcl/api.py", line 51, in load
    return loads(fp.read())
    File "/usr/local/lib/python3.6/dist-packages/hcl/api.py", line 62, in loads
    return HclParser().parse(s)
    File "/usr/local/lib/python3.6/dist-packages/hcl/parser.py", line 307, in parse
    return self.yacc.parse(s, lexer=Lexer())
    File "/usr/local/lib/python3.6/dist-packages/ply/yacc.py", line 331, in parse
    return self.parseopt_notrack(input, lexer, debug, tracking, tokenfunc)
    File "/usr/local/lib/python3.6/dist-packages/ply/yacc.py", line 1199, in parseopt_notrack
    tok = call_errorfunc(self.errorfunc, errtoken, self)
    File "/usr/local/lib/python3.6/dist-packages/ply/yacc.py", line 193, in call_errorfunc
    r = errorfunc(token)
    File "/usr/local/lib/python3.6/dist-packages/hcl/parser.py", line 300, in p_error
    raise ValueError(msg)
    ValueError: Line 628, column 22458: unexpected RIGHTBRACE
    172.17.0.1 - - [23/Mar/2018 14:22:44] "GET /graph.json HTTP/1.1" 500 -

A debug mode would be helpful for finding the file that the parser doesn't like. Terraform plan/apply works fine so it's happy with the HCL blast-radius is parsing.

Produce styled SVG

Is it possible to produce colored SVG from command line? Right now it is colored by JavaScript and it is not clear how to get a picture from command line.

Possibly to display only partially graph?

This is a question; with terraform it is possible to display specific resource/module by using the target feature with plan, e.g:

terraform plan -target=resource.foo -o=plan.tfplan
terraform graph -verbose plan.tfplan | dot -Tpng > graph.png

Is that also possible to display only that specific graph with blast-radius?

Currently if I use apply the same specific graph with:

terraform graph -verbose plan.tfplan | blast-radius --svg > graph.svg

It would still display the entire graph (unlike in graph.png) (perhaps due to the parsing of the HCL which isn't targeted)

Feature Request: Filter by resource type

I would be awesome if you could filter by resource type, especially for stacks that use a large number of vars.

For instance, in our AWS terraform stack, a good majority of our nodes are either vars or cloudwatch resources, and it would be cool to be able to filter those out and show just the "important" stuff.

blast fails to run in MacOS

Any ideas why I'm getting this error:

$ blast-radius 
Traceback (most recent call last):
  File "/Users/xxx/Library/Python/2.7/bin/blast-radius", line 14, in <module>
    from blastradius.handlers.dot import DotGraph, Format, DotNode
  File "/Users/xxx/Library/Python/2.7/lib/python/site-packages/blastradius/handlers/dot.py", line 391
    print('Error processing format param: ' + 'p', file=sys.stderr)
                                                       ^
SyntaxError: invalid syntax

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.