Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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`)
> 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