Skip to content

Api endpoint to get deployment manifest with expanded runtime config #2532

Open
@gberche-orange

Description

Is your feature request related to a problem? Please describe.

As a bosh operator, in order to record a reliable current state of a bosh deployment, I need a deployment manifest with the applied runtime config. Then I archive this deployment manifest (typically in git) in order to track history of changes applied by my automation pipelines.

Currently, the runtime config may change, but the current endpoint has not yet options to render the applied runtime config. For cloud-config, it does support indicating the cloud-config within the deployment is outdated, see

it 'mark cloud-config outdated if it references a deleted config' do
deleted_cloud_config = Models::Config.make(:cloud, raw_manifest: {}, deleted: true)
Models::Deployment.create(
name: 'deployment-4',
).tap do |deployment|
deployment.cloud_configs = [deleted_cloud_config]
end
get '/', {}, {}
expect(last_response.status).to eq(200)
body = JSON.parse(last_response.body)
expect(body).to eq(
[
{
'name' => 'deployment-1',
'releases' => [
{ 'name' => 'release-1', 'version' => '1' },
{ 'name' => 'release-1', 'version' => '2' },
],
'stemcells' => [
{ 'name' => 'stemcell-1', 'version' => '1' },
{ 'name' => 'stemcell-2', 'version' => '1' },
],
'cloud_config' => 'outdated',
'teams' => %w[dabest daworst],
'locked' => false,
},

Describe the solution you'd like

A new param to the /deployments/<deployment> endpoint to render the deployment manifest along with the add-ons.

Describe alternatives you've considered

I looked for existing task debug traces and could not find a dumped rendered manifest.

Looking at source code, the planner below seems to perform the manifest merge but does not yet dump it

def parse_from_manifest(manifest, cloud_config_consolidator, runtime_configs, options)
runtime_config_consolidator = Bosh::Director::RuntimeConfig::RuntimeConfigsConsolidator.new(runtime_configs)
@manifest_validator.validate(manifest.manifest_hash)
cloud_manifest = manifest.cloud_config_hash
manifest.resolve_aliases
manifest_hash = manifest.manifest_hash
@logger.debug("Deployment manifest:\n#{manifest_hash}")
@logger.debug("Cloud config manifest:\n#{cloud_manifest}")
name = manifest_hash['name']
deployment_model = @deployment_repo.find_or_create_by_name(name, options)
deployment_model.add_variable_set(created_at: Time.now, writable: true) if deployment_model.variable_sets.empty?
plan_options = {
'is_deploy_action' => !!options['deploy'],
'recreate' => !!options['recreate'],
'recreate_persistent_disks' => options['recreate_persistent_disks'] == true,
'fix' => !!options['fix'],
'skip_drain' => options['skip_drain'],
'job_states' => options['job_states'] || {},
'max_in_flight' => validate_and_get_argument(options['max_in_flight'], 'max_in_flight'),
'canaries' => validate_and_get_argument(options['canaries'], 'canaries'),
'tags' => parse_tags(manifest_hash, runtime_config_consolidator),
}
@logger.info('Creating deployment plan')
@logger.info("Deployment plan options: #{plan_options}")
deployment = Planner.new(
name,
manifest.manifest_hash,
manifest.manifest_text,
cloud_config_consolidator.cloud_configs,
[],
deployment_model,
plan_options,
manifest_hash.fetch('properties', {}),
)
deployment.cloud_planner = CloudManifestParser.new(@logger).parse(cloud_manifest)
DeploymentSpecParser.new(deployment, Config.event_log, @logger).parse(manifest_hash, plan_options)
unless deployment.addons.empty?
deployment.addons.each do |addon|
addon.add_to_deployment(deployment)
end
end
variables_spec_parser = Bosh::Director::DeploymentPlan::VariablesSpecParser.new(@logger, deployment.model)
variables_interpolator = Bosh::Director::ConfigServer::VariablesInterpolator.new
runtime_configs.each do |runtime_config|
parsed_runtime_config = RuntimeConfig::RuntimeManifestParser.new(@logger, variables_spec_parser).parse(variables_interpolator.interpolate_runtime_manifest(runtime_config.raw_manifest, name))
runtime_config_applies = false
runtime_config_applies = true if parsed_runtime_config.addons.empty?
parsed_runtime_config.get_applicable_releases(deployment).each do |release|
runtime_config_applies = true
release.add_to_deployment(deployment)
end
parsed_runtime_config.addons.each do |addon|
runtime_config_applies = true
addon.add_to_deployment(deployment)
end
deployment.add_variables(parsed_runtime_config.variables)
if runtime_config_applies
deployment.runtime_configs.push(runtime_config)
end
end
DeploymentValidator.new.validate(deployment)
deployment
end

A clear and concise description of what you want to happen.

I'm also considering fetching the full manifest directly from the director db, but would need guidance into the current director db schema, as https://github.com/cloudfoundry/bosh/tree/main/docs/director_schema seems outdated

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    • Status

      Waiting for Changes | Open for Contribution

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions