Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# kitchen-oci CHANGELOG

# 2.0.0
- feat: set default value for `are_legacy_imds_endpoints_disabled` to `true`
> BREAKING CHANGE: This overrides the default value to `true` in accordance with latest [OCI secuirty guidelines](https://docs.oracle.com/en-us/iaas/Content/Compute/Tasks/gettingmetadata.htm)

# 1.28.0
- feat: add instance_options to compute instance type

Expand Down
22 changes: 17 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -121,11 +121,10 @@ These settings are optional:
- `volume_id`, If you wish to clone your volume from an existing volume set this to the source volume's ID. They must be in the same Availability Domain.
- `nsg_ids`, The option to connect up to 5 Network Security Groups to compute instance.
- `custom_metadata`, Add metadata to the compute instance request
- `instance_options`, A hash of optional mutable instance options.
Initially, the only option [supported in the Ruby SDK](https://docs.oracle.com/en-us/iaas/tools/ruby/latest/OCI/Core/Models/InstanceOptions.html)
is `are_legacy_imds_endpoints_disabled`.
Customers who have [migrated to IMDSv2](https://docs.oracle.com/en-us/iaas/Content/Compute/Tasks/gettingmetadata.htm#upgrading-v2)
should set this to `true`
- `instance_options`, A hash of optional mutable instance options.\
Available options [supported in the Ruby SDK](https://docs.oracle.com/en-us/iaas/tools/ruby/latest/OCI/Core/Models/InstanceOptions.html)
- `are_legacy_imds_endpoints_disabled`, Boolean (default: `true`)\
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can remove the \ in this line after (default: true)

image

> Customers who have not [migrated to IMDSv2](https://docs.oracle.com/en-us/iaas/Content/Compute/Tasks/gettingmetadata.htm#upgrading-v2) will need to set this to `false`. [[more](#imdsv2)]
- `all_plugins_disabled`, Whether Oracle Cloud Agent can run all the available plugins (default: `false`)
- `management_disabled`, Whether Oracle Cloud Agent can run all the available management plugins (default: `false`)
- `monitoring_disabled`, Whether Oracle Cloud Agent can gather performance metrics and monitor the instance using the monitoring plugins (default: `false`)
Expand Down Expand Up @@ -407,6 +406,19 @@ driver:
vpus_per_gb: 30
```

## IMDSv2
In accordance with [OCI security guidelines](https://docs.oracle.com/en-us/iaas/Content/Compute/Tasks/gettingmetadata.htm), the driver is disabling the IMDSv1 endpoint by default. This overrides the current default setting
in OCI and could cause issues with [unsupported images](https://docs.oracle.com/en-us/iaas/Content/Compute/Tasks/gettingmetadata.htm#upgrading-v2__supported-images). In the event legacy IMDS support is required,
the option can be provided to the driver:

```yml
---
driver:
name: oci
instance_options:
are_legacy_imds_endpoints_disabled: false
```

## Windows Support

When launching Oracle provided Windows images, it may be helpful to allow kitchen-oci to inject powershell to configure WinRM and to set a randomized password that does not need to be changed on first login. If the `setup_winrm` parameter is set to true then the following steps will happen:
Expand Down
7 changes: 0 additions & 7 deletions lib/kitchen/driver/oci/instance/compute.rb
Original file line number Diff line number Diff line change
Expand Up @@ -81,13 +81,6 @@ def instance_source_via_image
)
end

# Adds the instance options property to the launch details.
def instance_options
return if config[:instance_options].empty?

launch_details.instance_options = OCI::Core::Models::InstanceOptions.new(config[:instance_options])
end

# Adds the source_details property to the launch_details for an instance that is being created from a boot volume.
def instance_source_via_boot_volume
return unless config[:boot_volume_id]
Expand Down
32 changes: 32 additions & 0 deletions lib/kitchen/driver/oci/mixin/actions.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ def launch(state, inst)
state_details = inst.launch
state.merge!(state_details)
instance.transport.connection(state).wait_until_ready
instance_options(state, inst)
are_legacy_imds_endpoints_disbled?(state, inst)
end

# Executes the post script on the instance.
Expand Down Expand Up @@ -68,6 +70,36 @@ def execute_post_create_file(state)
end
end

# Applies instance options.
#
# @param state [Hash] (see Kitchen::StateFile)
# @param inst [Class] the specific class of instance being rebooted.
def instance_options(state, inst)
return unless instance_options?

inst.logger.info("Applying the following instance options:")
config[:instance_options].each { |o, v| inst.logger.info("- #{o}: #{v}") }
inst.api.compute.update_instance(state[:server_id], OCI::Core::Models::UpdateInstanceDetails.new(instance_options: OCI::Core::Models::InstanceOptions.new(config[:instance_options])))
end

# Attempts to disable IMDSv1 even if not explicitly specified in the config. This is in line with current security guidance from OCI.
# Acts as a guard for setting instance options.
def instance_options?
return false unless config[:instance_type] == "compute"

config[:instance_options].merge!(are_legacy_imds_endpoints_disabled: true) unless config[:instance_options].key?(:are_legacy_imds_endpoints_disabled)
# Basically tell me if there's more stuff in there than `are_legacy_imds_endpoints_disabled: false`. If so, then proceed to setting it.
config[:instance_options].reject { |o, v| o == :are_legacy_imds_endpoints_disabled && !v }.any?
end

# Checks if legacy metadata is disabled.
def are_legacy_imds_endpoints_disbled?(state, inst)
return unless config[:instance_type] == "compute"

imds = inst.api.compute.get_instance(state[:server_id]).data.instance_options.are_legacy_imds_endpoints_disabled
inst.logger.warn("Legacy IMDSv1 endpoint is enabled.") unless imds
end

# Reboots an instance.
#
# @param state [Hash] (see Kitchen::StateFile)
Expand Down
2 changes: 1 addition & 1 deletion lib/kitchen/driver/oci_version.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,6 @@ module Driver
# Version string for Oracle OCI Kitchen driver
#
# @author Stephen Pearson (<stephen.pearson@oracle.com>)
OCI_VERSION = "1.28.0"
OCI_VERSION = "2.0.0"
end
end
8 changes: 7 additions & 1 deletion spec/spec_helper/compute_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,13 @@
include_context "oci"
include_context "net"

let(:compute_driver_config) { base_driver_config.merge!({ capacity_reservation_id: capacity_reservation }) }
let(:compute_driver_config) { base_driver_config.merge!(capacity_reservation_id: capacity_reservation) }
let(:instance_ocid) { "ocid1.instance.oc1.fake.aaaaaaaaaabcdefghijklmnopqrstuvwxyz12345" }
let(:instance_options) {
OCI::Core::Models::UpdateInstanceDetails.new(
instance_options: OCI::Core::Models::InstanceOptions.new(are_legacy_imds_endpoints_disabled: true)
)
}
let(:instance_metadata) do
{
"ssh_authorized_keys" => ssh_pub_key,
Expand Down Expand Up @@ -111,5 +116,6 @@
allow(compute_client).to receive(:get_volume_attachment).with(pv_attachment_ocid).and_return(pv_attachment_response)
allow(compute_client).to receive(:detach_volume).with(iscsi_attachment_ocid).and_return(nil_response)
allow(compute_client).to receive(:detach_volume).with(pv_attachment_ocid).and_return(nil_response)
allow(compute_client).to receive(:update_instance).with(instance_ocid, instance_options).and_return(nil_response)
end
end
3 changes: 2 additions & 1 deletion spec/spec_helper/create_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@
let(:compute_response) do
OCI::Response.new(200, nil, OCI::Core::Models::Instance.new(id: instance_ocid,
image_id: image_ocid,
lifecycle_state: Lifecycle.compute("running")))
lifecycle_state: Lifecycle.compute("running"),
instance_options: OCI::Core::Models::InstanceOptions.new(are_legacy_imds_endpoints_disabled: true)))
end
let(:dbaas_response) do
OCI::Response.new(200, nil, OCI::Database::Models::DbSystem.new(id: db_system_ocid, lifecycle_state: Lifecycle.dbaas("available")))
Expand Down