Commit af689368 authored by Thomas Gelf's avatar Thomas Gelf
Browse files

Refactor code, add LB and EC2 instance support

parent b76da2d6
......@@ -2,7 +2,6 @@
namespace Icinga\Module\Aws;
use Aws\AutoScaling\AutoScalingClient;
use Aws\Common\Aws;
use Icinga\Application\Config;
......@@ -23,35 +22,93 @@ class AwsClient
public function getAutoscalingConfig()
{
$groups = array();
$lbClient = $this->client()->get('AutoScaling');
$res = $lbClient->describeAutoScalingGroups();
foreach ($res->get('AutoScalingGroups') as $grp) {
$group = (object) array(
'name' => $grp['AutoScalingGroupName'],
'launch_config' => $grp['LaunchConfigurationName'],
'ctime' => strtotime($grp['CreatedTime']),
'zones' => $grp['AvailabilityZones'],
// 'current_size' => count($grp['Instances']),
'desired_size' => (int) $grp['DesiredCapacity'],
'min_size' => (int) $grp['MinSize'],
'max_size' => (int) $grp['MaxSize'],
// 'instances' => $grp['Instances'],
'lb_names' => $grp['LoadBalancerNames'],
'health_check_type' => $grp['HealthCheckType'],
'tags' => (object) array(),
);
$objects = array();
$client = $this->client()->get('AutoScaling');
$res = $client->describeAutoScalingGroups();
foreach ($res->get('AutoScalingGroups') as $entry) {
$objects[] = $object = $this->extractAttributes($entry, array(
'name' => 'AutoScalingGroupName',
'launch_config' => 'LaunchConfigurationName',
'zones' => 'AvailabilityZones',
'lb_names' => 'LoadBalancerNames',
'health_check_type' => 'HealthCheckType',
));
$object->ctime = strtotime($entry['CreatedTime']);
$object->desired_size = (int) $entry['DesiredCapacity'];
$object->min_size = (int) $entry['MinSize'];
$object->max_size = (int) $entry['MaxSize'];
$this->extractTags($entry, $object);
}
return $this->sortByName($objects);
}
foreach ($grp['Tags'] as $t) {
$group->tags->{$t['Key']} = $t['Value'];
public function getLoadBalancers()
{
$client = $this->client()->get('ElasticLoadBalancing');
$res = $client->describeLoadBalancers();
$objects = array();
foreach ($res->get('LoadBalancerDescriptions') as $entry) {
$objects[] = $object = $this->extractAttributes($entry, array(
'name' => 'LoadBalancerName',
'dnsname' => 'DNSName',
'scheme' => 'Scheme',
'zones' => 'AvailabilityZones',
));
$object->health_check = $entry['HealthCheck']['Target'];
$object->listeners = (object) array();
foreach ($entry['ListenerDescriptions'] as $l) {
$listener = $l['Listener'];
$object->listeners->{$listener['LoadBalancerPort']} = $this->extractAttributes(
$listener,
array(
'port' => 'LoadBalancerPort',
'protocol' => 'Protocol',
'instance_port' => 'InstancePort',
'instance_protocol' => 'InstanceProtocol',
)
);
}
$groups[] = $group;
}
return $groups;
return $this->sortByName($objects);
}
public function getEc2Instances()
{
$client = $this->client()->get('Ec2');
$res = $client->describeInstances();
$objects = array();
foreach ($res->get('Reservations') as $reservation) {
foreach ($reservation['Instances'] as $entry) {
$objects[] = $object = $this->extractAttributes($entry, array(
'name' => 'InstanceId',
'image' => 'ImageId',
'architecture' => 'Architecture',
'root_device_type' => 'RootDeviceType',
'root_device_name' => 'RootDeviceName',
'hypervisor' => 'Hypervisor',
'virt_type' => 'VirtualizationType',
), array(
'public_ip' => 'PublicIpAddress',
'public_dns' => 'PublicDnsName',
'private_ip' => 'PrivateIpAddress',
'private_dns' => 'PrivateDnsName',
));
$object->monitoring_state = $entry['Monitoring']['State'];
$this->extractTags($entry, $object);
}
}
return $this->sortByName($objects);
}
public static function enumRegions()
......@@ -70,6 +127,47 @@ class AwsClient
);
}
protected function sortByName($objects)
{
usort($objects, array($this, 'compareName'));
return $objects;
}
protected function extractAttributes($entry, $required, $optional = array(), $subkey = null)
{
$result = (object) array();
if ($subkey !== null) {
$entry = $entry[$subkey];
}
foreach ($required as $alias => $key) {
$result->$alias = $entry[$key];
}
foreach ($optional as $alias => $key) {
if (array_key_exists($key, $entry)) {
$result->$alias = $entry[$key];
} else {
$result->$alias = null;
}
}
return $result;
}
protected function extractTags($entry, $result)
{
$result->tags = (object) array();
foreach ($entry['Tags'] as $t) {
$result->tags->{$t['Key']} = $t['Value'];
}
}
protected function compareName($a, $b)
{
return strcmp($a->name, $b->name);
}
protected function client()
{
if ($this->client === null) {
......
......@@ -19,27 +19,81 @@ class ImportSource extends ImportSourceHook
$this->getSetting('aws_region')
);
return $client->getAutoscalingConfig();
switch ($this->getObjectType()) {
case 'asg':
return $client->getAutoscalingConfig();
case 'lb':
return $client->getLoadBalancers();
case 'ec2instance':
return $client->getEc2Instances();
}
}
protected function getObjectType()
{
// Compat for old configs, asg used to be the only available type:
$type = $this->getSetting('object_type', 'asg');
if (! in_array($type, array('asg', 'lb', 'ec2instance'))) {
throw new ConfigurationError(
'Got no invalid AWS object type: "%s"',
$type
);
}
return $type;
}
public function listColumns()
{
return array(
'name',
'launch_config',
'ctime',
'zones',
'desired_size',
'min_size',
'max_size',
'lb_names',
'health_check_type',
'tags',
'tags.Name',
'tags.aws:cloudformation:logical-id',
'tags.aws:cloudformation:stack-id',
'tags.aws:cloudformation:stack-name',
);
switch ($this->getObjectType()) {
case 'asg':
return array(
'name',
'launch_config',
'ctime',
'zones',
'desired_size',
'min_size',
'max_size',
'lb_names',
'health_check_type',
'tags',
'tags.Name',
'tags.aws:cloudformation:logical-id',
'tags.aws:cloudformation:stack-id',
'tags.aws:cloudformation:stack-name',
);
case 'lb':
return array(
'name',
'dnsname',
'scheme',
'zones',
'listeners',
'health_check',
);
case 'ec2instance':
return array(
'name',
'image',
'architecture',
'root_device_type',
'root_device_name',
'hypervisor',
'virt_type',
'public_ip',
'public_dns',
'private_ip',
'private_dns',
'monitoring_state',
'tags',
'tags.Name',
'tags.aws:autoscaling:groupName',
'tags.aws:cloudformation:logical-id',
'tags.aws:cloudformation:stack-id',
'tags.aws:cloudformation:stack-name',
);
}
}
public static function getDefaultKeyColumnName()
......@@ -65,5 +119,26 @@ class ImportSource extends ImportSourceHook
'multiOptions' => $form->optionalEnum(AwsKey::enumKeyNames()),
'class' => 'autosubmit',
));
$form->addElement('select', 'object_type', array(
'label' => 'Object type',
'required' => true,
'description' => $form->translate(
'AWS object type'
),
'multiOptions' => $form->optionalEnum(
static::enumObjectTypes($form)
),
'class' => 'autosubmit',
));
}
protected static function enumObjectTypes($form)
{
return array(
'asg' => $form->translate('Auto Scaling Groups'),
'lb' => $form->translate('Elastic Load Balancers'),
'ec2instance' => $form->translate('EC2 Instances'),
);
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment