inspec / inspec-gcp

InSpec GCP (Google Cloud Platform) Resource Pack
https://www.inspec.io/
Other
148 stars 72 forks source link

google_compute_instance examples return errors #258

Open mattbowes opened 4 years ago

mattbowes commented 4 years ago

from the google_compute_instance examples

control 'network' do
    describe google_compute_instance(project: project, zone: zone, name: vm) do
        its('first_network_interface_nat_ip_exists'){ should be true }
        its('first_network_interface_name'){ should eq "external-nat" }
        its('first_network_interface_type'){ should eq "one_to_one_nat" }
    end
end

returns

 ×  network: Instance kitchtest-1zr (3 failed)
     ×  Instance test-1zr first_network_interface_nat_ip_exists
     undefined method `[]' for nil:NilClass
     ×  Instance test-1zr first_network_interface_name
     undefined method `[]' for nil:NilClass
     ×  Instance test-1zr first_network_interface_type
     undefined method `[]' for nil:NilClass

Tried on profile version 1.0-1.5

Describe the problem

Possible Solution

slevenick commented 4 years ago

Fixed via https://github.com/inspec/inspec-gcp/pull/259

enutrofff commented 4 years ago

Any updates?

slevenick commented 4 years ago

I believe that these methods do work if the instance exists. Are you able to throw in a it { should exist } assertion before calling those?

We use these in the integration tests which currently pass

enutrofff commented 4 years ago

I believe that these methods do work if the instance exists. Are you able to throw in a it { should exist } assertion before calling those?

yes. I did.

    this_instance = google_compute_instance(project: gcp_project_id, zone: zone, name: vm_name)

    describe this_instance do
        it { should exist }
        # wait up to 15 minutes if the Compute Engine instance is not yet ready
        its('status', retry: 45, retry_wait: 20){should eq 'RUNNING'}
        its('machine_type') { should match machine_type }
        ##[cut here]
        ### Below check doesn't work
        its('first_network_interface_nat_ip_exists'){ should be false }

We able to test that a GCP compute instance has a single public IP address, but we can't test that a GCP compute instance doesn't have a single public IP address

that step:

  its('first_network_interface_nat_ip_exists'){ should be false }

please find the output when we have an external IP address:

 ×  Instance win-toolbox-vm-01 first_network_interface_nat_ip_exists is expected to equal false
 expected false
           got true

please find the output when instance doesn't have an external IP address:

  ×  Instance win-toolbox-vm-01 first_network_interface_nat_ip_exists
       undefined method `[]' for nil:NilClass

please find related .rb code here: https://github.com/inspec/inspec-gcp/blob/master/libraries/google_compute_instance.rb

enutrofff commented 4 years ago

The reason is:


  def parse
    @network_interfaces = GoogleInSpec::Compute::Property::InstanceNetworkInterfacesArray.parse(@fetched['networkInterfaces'], to_s)

[cut here]

  def first_network_interface_nat_ip_exists
    !@network_interfaces[0].access_configs[0].nat_ip.nil?
  end

According to Google API: access_configs : An array of configurations for this interface. Currently, only one access config, ONE_TO_ONE_NAT, is supported. If there are no accessConfigs specified, then this instance will have no external internet access.

So with first_network_interface_nat_ip_exists we cannot check that first_network_interface_nat_ip_exists doesn't; exist.

enutrofff commented 4 years ago

So my question here: how can we check that VM instance doesn't have external IP? This is the most common variant to check.

slevenick commented 4 years ago

Loop through the network_interfaces array and check that access_configs is always empty?

this_instance.network_interfaces.each do |network_interface|
  describe network_interface do
    its('size') { should cmp 0 }
  end
end
enutrofff commented 4 years ago

Loop through the network_interfaces array and check that access_configs is always empty?

It doesn't work, got following:

×  Instance win-toolbox-vm-01 InstanceNetworkInterfaces size
     undefined method `size' for #<#<Class:0x00007fffd0b5dee8>::GoogleInSpec::Compute::Property::InstanceNetworkInterfaces:0x00007fa0b3affb80>
slevenick commented 4 years ago

Errr, try its('count')

I mixed up my ruby methods

enutrofff commented 4 years ago

Errr, try its('count')

Unfortunately still the same issue

     ×  Instance win-toolbox-vm-01 InstanceNetworkInterfaces count
     undefined method `count' for #<#<Class:0x00007fffc6f5fbe0>::GoogleInSpec::Compute::Property::InstanceNetworkInterfaces:0x00007fffc792cee8>