#!/usr/bin/env perl use strict; use warnings; use v5.10; use App::Rad; use Net::OpenStack::Attack; use Net::OpenStack::Compute; use Time::SoFar qw(runtime); App::Rad->run(); sub setup { my $c = shift; $c->register_commands({ bad => 'send invalid requests', servers => 'send get /servers requests [--detail]', images => 'send get /images requests [--detail]', flavors => 'send get /flavors requests [--detail]', create => 'create servers [--image|-i]', delete => 'delete all stackattack servers [--all|-a] (deletes ALL servers)', rebuild => 'rebuild all stackattack servers [--all|-a] [--image|-i]', }); } sub pre_process { my $c = shift; my $cmd = $c->cmd; return if $cmd eq 'help' or !$c->is_command($cmd); my $msg = "%s env var is missing. Did you forget to source novarc?\n"; die sprintf($msg, 'NOVA_URL or OS_AUTH_URL') unless $ENV{NOVA_URL} || $ENV{OS_AUTH_URL}; die sprintf($msg, 'NOVA_USERNAME or OS_USERNAME') unless $ENV{NOVA_USERNAME} || $ENV{OS_USERNAME}; die sprintf($msg, 'NOVA_PASSWORD or NOVA_API_KEY or OS_PASSWORD') unless $ENV{NOVA_PASSWORD} || $ENV{NOVA_API_KEY} || $ENV{OS_PASSWORD}; my $compute = Net::OpenStack::Compute->new( auth_url => $ENV{NOVA_URL} || $ENV{OS_AUTH_URL}, user => $ENV{NOVA_USERNAME} || $ENV{OS_USERNAME}, password => $ENV{NOVA_PASSWORD} || $ENV{NOVA_API_KEY} || $ENV{OS_PASSWORD}, project_id => $ENV{NOVA_PROJECT_ID} || $ENV{OS_TENANT_NAME}, region => $ENV{NOVA_REGION_NAME} || $ENV{OS_AUTH_REGION}, service_name => $ENV{NOVA_SERVICE_NAME}, is_rax_auth => $ENV{NOVA_RAX_AUTH}, verify_ssl => 0, ); $c->stash->{attack} = Net::OpenStack::Attack->new(compute => $compute); $c->getopt('all|a', 'detail') or die "See help for valid options\n"; $c->stash->{num_runs} = $c->argv->[0] || 1; } sub create { my $c = shift; $c->getopt('image|i=s'); my $num_runs = $c->argv->[0] || 1; my $attack = $c->stash->{attack}; my $image = $c->options->{image}; say "Creating $num_runs servers ..."; return _msg($attack->create_servers($num_runs, $image)); } sub delete { my $c = shift; my $attack = $c->stash->{attack}; my $servers = _filter_servers($c); say "Deleting " . @$servers . " servers ..."; return _msg($attack->delete_servers($servers)); } sub rebuild { my $c = shift; my $attack = $c->stash->{attack}; my $servers = _filter_servers($c); say "Rebuilding " . @$servers . " servers ..."; return _msg($attack->rebuild_servers($servers)); } sub bad { _get(shift, '/bad') } sub servers { _get(shift, '/servers') } sub images { _get(shift, '/images') } sub flavors { _get(shift, '/flavors') } sub _get { my ($c, $url) = @_; $url .= '/detail' if $c->options->{detail}; my $num_runs = $c->stash->{num_runs}; my $attack = $c->stash->{attack}; say "Sending $num_runs $url requests ..."; return _msg($attack->attack(GET => $url, $num_runs)); } sub _msg { my $data = shift; return sprintf "Successes: %s Failures: %s Time: %s ", $data->{successes}, $data->{failures}, runtime(); } sub _filter_servers { my $c = shift; my $attack = $c->stash->{attack}; my $servers = $attack->compute->get_servers(detail => 0); return $servers if $c->options->{all}; return [ grep { $_->{name} eq 'stackattack' } @$servers ]; } # PODNAME: stackattack __END__ =pod =head1 NAME stackattack =head1 VERSION version 1.0500 =head1 SYNOPSIS Usage: stackattack command [arguments] Available Commands: bad send invalid requests create create servers [--image|-i] delete delete all stackattack servers [--all|-a] (deletes ALL servers) get send get servers requests get-images send image list requests help show syntax and available commands rebuild rebuild all stackattack servers [--all|-a] [--image|-i] Examples: # Create a server $ stackattack create # Create 10 servers in parallel $ stackattack create 10 # Create 10 servers with an explicit image id $ stackattack create -i b79cf9f9-cea9-44c7-a3ac-74a6668eb78b 10 # Delete all servers $ stackattack delete -a =head1 DESCRIPTION This is a command line utility for stress testing an OpenStack deployment. All http requests are run in parallel using L. =head1 AUTHORS =over 4 =item * William Wolf =item * Naveed Massjouni =back =head1 COPYRIGHT AND LICENSE This software is copyright (c) 2011 by Naveed Massjouni. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =cut