Skip to content

Instantly share code, notes, and snippets.

@jdeathe
Last active September 25, 2016 23:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jdeathe/e4e7943e48b23f48e16460630ac004a6 to your computer and use it in GitHub Desktop.
Save jdeathe/e4e7943e48b23f48e16460630ac004a6 to your computer and use it in GitHub Desktop.
Mock a Cloud-Init metadata service for cloud-config testing with VirtualBox Guest VM
<?php
date_default_timezone_set(
'UTC'
);
// Mock Cloud-Init metadata service for cloud-config
// From VirtualBox host machine run:
// env METADATA_INSTANCE_ID="iid-5cd832f4bc69" sudo -E php -S 0.0.0.0:80 Cloud-Init_MetadataRouter.php
// http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-metadata.html
// http://docs.cloudstack.apache.org/projects/cloudstack-administration/en/latest/virtual_machines.html#user-data-and-meta-data
function getUuid() {
return sprintf(
'%04x%04x-%04x-%04x-%04x-%04x%04x%04x',
mt_rand(0, 0xffff),
mt_rand(0, 0xffff),
mt_rand(0, 0xffff),
mt_rand(0, 0x0fff) | 0x4000,
mt_rand(0, 0x3fff) | 0x8000,
mt_rand(0, 0xffff),
mt_rand(0, 0xffff),
mt_rand(0, 0xffff)
);
}
function getInstanceId($uuid = '') {
if (
! is_string($uuid)
) {
$uuid = '';
}
return sprintf(
'iid-%s',
substr(
sha1 (
! empty($uuid)
? $uuid
: getUuid()
),
0,
12
)
);
}
$metadataVersions = array(
'latest'
);
$metadataVersionPatterns = array(
'/^\/\/?latest/'
);
$requestUri = isset($_SERVER["REQUEST_URI"])
? $_SERVER["REQUEST_URI"]
: "/"
;
// Normalise URI
// - Replace double leading // with single /
// - Replace version URI slug with placeholder
$requestUriPattern = preg_replace(
$metadataVersionPatterns,
'/{{METADATA_VERSION}}',
$requestUri
);
$userDataFile = realpath(
__DIR__ . '/user-data'
);
$timeStamp = strftime(
'[%d/%b/%Y:%T %z]'
);
$headers = array(
$timeStamp
);
if ( ! empty($_SERVER)) {
foreach ($_SERVER as $key => $value) {
// Limit headers
if ( ! preg_match(
'/^(HTTP_|REMOTE_ADDR|SERVER_NAME|SERVER_PORT|REQUEST_URI|REQUEST_METHOD)/',
$key
)) {
continue;
}
$headers[] = sprintf(
'%s: %s',
preg_replace(
'/_/',
'-',
mb_convert_case(
$key,
MB_CASE_TITLE,
'UTF-8'
)
),
$value
);
}
}
// Basic request logging
file_put_contents(
"var/log/metadata_log",
! empty($headers)
? implode(PHP_EOL, $headers) . PHP_EOL
: ''
);
switch ($requestUriPattern) {
case '/':
header(
'Content-Type: text/plain; charset=UTF-8',
true,
200
);
print implode(
PHP_EOL,
$metadataVersions
) . PHP_EOL;
break;
case '/{{METADATA_VERSION}}':
case '/{{METADATA_VERSION}}/':
header(
'Content-Type: text/plain; charset=UTF-8',
true,
200
);
print implode(
PHP_EOL,
array(
'meta-data',
'user-data'
)
) . PHP_EOL;
break;
case '/{{METADATA_VERSION}}/meta-data':
case '/{{METADATA_VERSION}}/meta-data/':
header(
'Content-Type: text/plain; charset=UTF-8',
true,
200
);
print implode(
PHP_EOL,
array(
'hostname',
'instance-id'
)
) . PHP_EOL;
break;
case '/{{METADATA_VERSION}}/meta-data/hostname':
header(
'Content-Type: text/plain; charset=UTF-8',
true,
200
);
print ( ! empty(getenv('METADATA_HOSTNAME'))
? getenv('METADATA_HOSTNAME')
: substr(
sha1 (
! empty($uuid)
? $uuid
: getUuid()
),
0,
12
)
) . PHP_EOL;
break;
case '/{{METADATA_VERSION}}/meta-data/local-hostname':
header(
'Content-Type: text/plain; charset=UTF-8',
true,
200
);
print ( ! empty(getenv('METADATA_LOCAL_HOSTNAME'))
? getenv('METADATA_LOCAL_HOSTNAME')
: substr(
sha1 (
! empty($uuid)
? $uuid
: getUuid()
),
0,
12
)
) . PHP_EOL;
break;
case '/{{METADATA_VERSION}}/meta-data/instance-id':
header(
'Content-Type: text/plain; charset=UTF-8',
true,
200
);
print ( ! empty(getenv('METADATA_INSTANCE_ID'))
? getenv('METADATA_INSTANCE_ID')
: getInstanceId()
) . PHP_EOL;
break;
case '/{{METADATA_VERSION}}/user-data':
if ($userDataFile !== false) {
header(
'Content-Type: text/plain; charset=UTF-8',
true,
200
);
readfile(
$userDataFile
);
} else {
header(
'Content-Type: text/plain; charset=UTF-8',
true,
404
);
print '404 - Not Found' . PHP_EOL;
}
break;
default:
header(
'Content-Type: text/plain; charset=UTF-8',
true,
404
);
print '404 - Not Found' . PHP_EOL;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment