Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Getting error "undefined method `body' for nil:NilClass" when I am trying to test Azure Load Balancer with inspec using the API calls. #206

Closed
nsr99 opened this issue Dec 24, 2018 · 10 comments

Comments

@nsr99
Copy link

nsr99 commented Dec 24, 2018

I am trying to test Azure Load Balancer with inspec using the API calls. My control file looks like below:

Control file:

control "file_check" do
    http_request = http('https://management.azure.com/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx/resourceGroups/myResourceGroupSLB/providers/Microsoft.Network/loadBalancers/myLoadBalancer/backendAddressPools/myBackendPool?api-version=2018-08-01',
                                    headers: {
                                        'Accept' => 'application/json',
                                        'Authorization' => 'Bearer <my-API-token>'
                                     })
    describe json(content: http_request.body) do
      its('name') { should eq 'hello' }
    end
end

Profile file inspec.yml

name: new_profile
title: Checking compliance of resources
license: Apache-2.0
summary: Inspec test for compliance
version: 1.0
inspec_version: '>= 2.1.81'
depends:
  - name: inspec-azure
    url: https://github.com/inspec/inspec-azure/archive/master.tar.gz
supports:
  - platform: azure

When running the test I am getting below error:

× file_check: /home/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx/newtest/test/integration/new_profile/controls/basic.rb:13
× Control Source Code Error /home/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx/new-test/test/integration/new_profile/controls/basic.rb:13
undefined method `body' for nil:NilClass

Seems like nothing is stored in http_request, Can anyone suggest where is the issue?

Originally posted by @nsr99 in inspec/inspec#2394 (comment)

@nellshamrell nellshamrell self-assigned this Jan 30, 2019
@nellshamrell
Copy link

Looking at this now.

@nellshamrell
Copy link

I was able to replicate this with InSpec 3.9.3:

I used this Terraform config to spin up a basic Azure cluster (including a load balancer).

I then used this code:

inspec.yml

name: nell_test_profile
title: Checking compliance of resources
license: Apache-2.0
summary: Inspec test for compliance
version: 1.0
inspec_version: '>= 2.1.81'
depends:
  - name: inspec-azure
    url: https://github.com/inspec/inspec-azure/archive/master.tar.gz
supports:
  - platform: azure

example.rb

# encoding: utf-8
# copyright: 2018, The Authors

title 'sample section'

# you add controls here
control "file_check" do
  http_request = http('https://management.azure.com/subscriptions/<my_subscription_id>/resourceGroups/nellresourcegroup/providers/Microsoft.Network/loadBalancers/NellLB/backendAddressPools/BackEndAddressPool?api-version=2018-08-01',
                                  headers: {
                                      'Accept' => 'application/json',
                                      'Authorization' => 'Bearer <my_bearer_token>'
                                   })
  describe json(content: http_request.body) do
    its('name') { should eq 'hello' }
  end
end

When running this control, I received the same error.

16:04:22-nellshamrell~/Projects/test_inspec_profiles/nell_test_profile$ inspec exec controls/example.rb -t azure://

Profile: tests from controls/example.rb (tests from controls.example.rb)
Version: (not specified)
Target:  azure://f53e4a14-9a89-4bfe-94e4-088bda9224ab

  ×  file_check: controls/example.rb:7
     ×  Control Source Code Error controls/example.rb:7 
     undefined method `body' for nil:NilClass


Profile Summary: 0 successful controls, 1 control failure, 0 controls skipped
Test Summary: 0 successful, 1 failure, 0 skipped

@nellshamrell
Copy link

Now to build InSpec from master and see if it is fixed in InSpec 4.

@nellshamrell
Copy link

Confirmed - this is still an issue with the most recent master - digging into this more!

16:12:53-nellshamrell~/Projects/test_inspec_profiles/nell_test_profile$ inspec exec controls/example.rb -t azure://
+---------------------------------------------+
            Chef License Acceptance

Before you can continue, 1 product license
must be accepted. View the license at
https://www.chef.io/end-user-license-agreement/

License that need accepting:
  * InSpec

Do you accept the 1 product license (yes/no)?

> yes

Persisting 1 product license...
✔ 1 product license persisted.

+---------------------------------------------+

Profile: tests from controls/example.rb (tests from controls.example.rb)
Version: (not specified)
Target:  azure://f53e4a14-9a89-4bfe-94e4-088bda9224ab

  ×  file_check: controls/example.rb:7
     ×  Control Source Code Error controls/example.rb:7 
     undefined method `body' for nil:NilClass


Profile Summary: 0 successful controls, 1 control failure, 0 controls skipped
Test Summary: 0 successful, 1 failure, 0 skipped

@nellshamrell
Copy link

nellshamrell commented Apr 18, 2019

Problem appears to be here:

inspec/lib/resources/http.rb

def body
  @worker.body
end

When I run the above control when trying to connect to Azure, @worker is nil. When I try to run the above control locally, @worker is set properly.

@nellshamrell
Copy link

This is where that error is being generated - in the instance_eval method used in the Rule object
inspec/lib/inspec/rule.rb

     begin
        instance_eval(&block)
      rescue StandardError => e
        # We've encountered an exception while trying to eval the code inside the
        # control block. We need to prevent the exception from bubbling up, and
        # fail the control. Controls are failed by having a failed resource within
        # them; but since our control block is unsafe (and opaque) to us, let's
        # make a dummy and fail that.
        location = block.source_location.compact.join(':')
        describe 'Control Source Code Error' do
          # Rubocop thinks we are raising an exception - we're actually calling RSpec's fail()
          its(location) { fail e.message } # rubocop: disable Style/SignalException
      end

@nellshamrell
Copy link

nellshamrell commented Apr 18, 2019

I believe the way to solve this is to handle the case where an http response does not have a body. Working on that.

@nellshamrell
Copy link

Though I'm still wondering how @worker can be nil in this block of code:
inspec/lib/resources/http.rb

def body
  @worker.body
end

Many of the http resource methods depend on worker NOT being nil - and I don't think we want to write handling for each one of them.

@nellshamrell
Copy link

Aha!

The problem is here:

 @worker = Worker::Remote.new(inspec, http_method, url, opts)

In the case of the control being run on the Azure LB, opts is nil (though I'm not sure why). That means that this method (required to instantiate the @worker)

    def http_method
      @opts.fetch(:method, 'GET')
    end

Will return an error, which means @worker will not be created.

I went through some of this thought process when working on a similar issue, I don't know why opts is being set to nil, but it's something we need to at least add handling for.

@nellshamrell nellshamrell removed their assignment Apr 24, 2019
@miah miah transferred this issue from inspec/inspec Oct 7, 2019
@omerdemirok
Copy link
Contributor

This issue should be resolved by using the inspec-azure resource pack.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants