ManageIQ/ovirt

View on GitHub

Showing 54 of 54 total issues

Method resource_options has a Cognitive Complexity of 7 (exceeds 5 allowed). Consider refactoring.
Open

    def resource_options
      headers = merge_headers(
        'Version' => '3',
        'Prefer'  => 'persistent-auth',
      )
Severity: Minor
Found in lib/ovirt/service.rb - About 35 mins to fix

Cognitive Complexity

Cognitive Complexity is a measure of how difficult a unit of code is to intuitively understand. Unlike Cyclomatic Complexity, which determines how difficult your code will be to test, Cognitive Complexity tells you how difficult your code will be to read and comprehend.

A method's cognitive complexity is based on a few simple rules:

  • Code is not considered more complex when it uses shorthand that the language provides for collapsing multiple statements into one
  • Code is considered more complex for each "break in the linear flow of the code"
  • Code is considered more complex when "flow breaking structures are nested"

Further reading

Method paginate_resource_get has a Cognitive Complexity of 7 (exceeds 5 allowed). Consider refactoring.
Open

    def paginate_resource_get(path = nil, sort_by = :name, direction = :asc)
      log_header = "#{self.class.name}#paginate_resource_get"
      page       = 1
      full_xml   = nil
      loop do
Severity: Minor
Found in lib/ovirt/service.rb - About 35 mins to fix

Cognitive Complexity

Cognitive Complexity is a measure of how difficult a unit of code is to intuitively understand. Unlike Cyclomatic Complexity, which determines how difficult your code will be to test, Cognitive Complexity tells you how difficult your code will be to read and comprehend.

A method's cognitive complexity is based on a few simple rules:

  • Code is not considered more complex when it uses shorthand that the language provides for collapsing multiple statements into one
  • Code is considered more complex for each "break in the linear flow of the code"
  • Code is considered more complex when "flow breaking structures are nested"

Further reading

Method parse_node_extended has a Cognitive Complexity of 7 (exceeds 5 allowed). Consider refactoring.
Open

    def self.parse_node_extended(node, hash)
      parse_first_node(node, :status,  hash, :node => [:state])
      parse_first_node(node, :storage, hash, :node => [:type, :address, :path])
      parse_first_node(node, :storage, hash, :attribute => [:id])

Severity: Minor
Found in lib/ovirt/storage_domain.rb - About 35 mins to fix

Cognitive Complexity

Cognitive Complexity is a measure of how difficult a unit of code is to intuitively understand. Unlike Cyclomatic Complexity, which determines how difficult your code will be to test, Cognitive Complexity tells you how difficult your code will be to read and comprehend.

A method's cognitive complexity is based on a few simple rules:

  • Code is not considered more complex when it uses shorthand that the language provides for collapsing multiple statements into one
  • Code is considered more complex for each "break in the linear flow of the code"
  • Code is considered more complex when "flow breaking structures are nested"

Further reading

Method operation has a Cognitive Complexity of 6 (exceeds 5 allowed). Consider refactoring.
Open

    def operation(method, *_args)
      if @operations.key?(method.to_sym)
        builder = Nokogiri::XML::Builder.new do |xml|
          xml.action { yield xml if block_given? }
        end
Severity: Minor
Found in lib/ovirt/base.rb - About 25 mins to fix

Cognitive Complexity

Cognitive Complexity is a measure of how difficult a unit of code is to intuitively understand. Unlike Cyclomatic Complexity, which determines how difficult your code will be to test, Cognitive Complexity tells you how difficult your code will be to read and comprehend.

A method's cognitive complexity is based on a few simple rules:

  • Code is not considered more complex when it uses shorthand that the language provides for collapsing multiple statements into one
  • Code is considered more complex for each "break in the linear flow of the code"
  • Code is considered more complex when "flow breaking structures are nested"

Further reading

Method create_new_disks_from_template has a Cognitive Complexity of 6 (exceeds 5 allowed). Consider refactoring.
Open

    def create_new_disks_from_template(vm, options)
      disks.each do |disk_object|
        disk_options            = disk_object.attributes_for_new_disk
        disk_options[:sparse]   = options[:sparse]  unless options[:sparse].nil?
        disk_options[:storage]  = options[:storage] unless options[:storage].blank?
Severity: Minor
Found in lib/ovirt/template.rb - About 25 mins to fix

Cognitive Complexity

Cognitive Complexity is a measure of how difficult a unit of code is to intuitively understand. Unlike Cyclomatic Complexity, which determines how difficult your code will be to test, Cognitive Complexity tells you how difficult your code will be to read and comprehend.

A method's cognitive complexity is based on a few simple rules:

  • Code is not considered more complex when it uses shorthand that the language provides for collapsing multiple statements into one
  • Code is considered more complex for each "break in the linear flow of the code"
  • Code is considered more complex when "flow breaking structures are nested"

Further reading

Method start has a Cognitive Complexity of 6 (exceeds 5 allowed). Consider refactoring.
Open

    def start
      if block_given?
        operation(:start) { |xml| yield xml }
      else
        operation(:start)
Severity: Minor
Found in lib/ovirt/vm.rb - About 25 mins to fix

Cognitive Complexity

Cognitive Complexity is a measure of how difficult a unit of code is to intuitively understand. Unlike Cyclomatic Complexity, which determines how difficult your code will be to test, Cognitive Complexity tells you how difficult your code will be to read and comprehend.

A method's cognitive complexity is based on a few simple rules:

  • Code is not considered more complex when it uses shorthand that the language provides for collapsing multiple statements into one
  • Code is considered more complex for each "break in the linear flow of the code"
  • Code is considered more complex when "flow breaking structures are nested"

Further reading

Method clone_to_vm has a Cognitive Complexity of 6 (exceeds 5 allowed). Consider refactoring.
Open

    def clone_to_vm(options)
      # Create a VM based on this template
      REQUIRED_CLONE_PARAMETERS.each do |key|
        raise ArgumentError, "#{key.inspect} cannot be blank" if options[key].blank?
      end
Severity: Minor
Found in lib/ovirt/template.rb - About 25 mins to fix

Cognitive Complexity

Cognitive Complexity is a measure of how difficult a unit of code is to intuitively understand. Unlike Cyclomatic Complexity, which determines how difficult your code will be to test, Cognitive Complexity tells you how difficult your code will be to read and comprehend.

A method's cognitive complexity is based on a few simple rules:

  • Code is not considered more complex when it uses shorthand that the language provides for collapsing multiple statements into one
  • Code is considered more complex for each "break in the linear flow of the code"
  • Code is considered more complex when "flow breaking structures are nested"

Further reading

Method has too many optional parameters. [4/3]
Open

    def standard_collection(uri_suffix, element_name = nil, paginate = false, sort_by = :name, direction = :asc)
      if paginate
        doc = paginate_resource_get(uri_suffix, sort_by, direction)
      else
        xml = resource_get(uri_suffix)
Severity: Minor
Found in lib/ovirt/service.rb by rubocop

Checks for methods with too many parameters.

The maximum number of parameters is configurable. Keyword arguments can optionally be excluded from the total count, as they add less complexity than positional or optional parameters.

Any number of arguments for initialize method inside a block of Struct.new and Data.define like this is always allowed:

Struct.new(:one, :two, :three, :four, :five, keyword_init: true) do
  def initialize(one:, two:, three:, four:, five:)
  end
end

This is because checking the number of arguments of the initialize method does not make sense.

NOTE: Explicit block argument &block is not counted to prevent erroneous change that is avoided by making block argument implicit.

Example: Max: 3

# good
def foo(a, b, c = 1)
end

Example: Max: 2

# bad
def foo(a, b, c = 1)
end

Example: CountKeywordArgs: true (default)

# counts keyword args towards the maximum

# bad (assuming Max is 3)
def foo(a, b, c, d: 1)
end

# good (assuming Max is 3)
def foo(a, b, c: 1)
end

Example: CountKeywordArgs: false

# don't count keyword args towards the maximum

# good (assuming Max is 3)
def foo(a, b, c, d: 1)
end

This cop also checks for the maximum number of optional parameters. This can be configured using the MaxOptionalParameters config option.

Example: MaxOptionalParameters: 3 (default)

# good
def foo(a = 1, b = 2, c = 3)
end

Example: MaxOptionalParameters: 2

# bad
def foo(a = 1, b = 2, c = 3)
end

Method getCfg has a Cognitive Complexity of 6 (exceeds 5 allowed). Consider refactoring.
Open

    def getCfg(_snap = nil)
      # TODO: Remove the following MiqException and any others
      raise MiqException::MiqVimError, "Failed to retrieve configuration information for VM" if attributes.nil?

      cfg_hash = {}
Severity: Minor
Found in lib/ovirt/template.rb - About 25 mins to fix

Cognitive Complexity

Cognitive Complexity is a measure of how difficult a unit of code is to intuitively understand. Unlike Cyclomatic Complexity, which determines how difficult your code will be to test, Cognitive Complexity tells you how difficult your code will be to read and comprehend.

A method's cognitive complexity is based on a few simple rules:

  • Code is not considered more complex when it uses shorthand that the language provides for collapsing multiple statements into one
  • Code is considered more complex for each "break in the linear flow of the code"
  • Code is considered more complex when "flow breaking structures are nested"

Further reading

Method relationship has a Cognitive Complexity of 6 (exceeds 5 allowed). Consider refactoring.
Open

    def relationship(rel)
      if @relationships.key?(rel.to_sym)
        rel_str  = rel.to_s
        rel_str  = 'storage_domains' if rel_str == 'storagedomains'
        rel_str  = 'data_centers'    if rel_str == 'datacenters'
Severity: Minor
Found in lib/ovirt/base.rb - About 25 mins to fix

Cognitive Complexity

Cognitive Complexity is a measure of how difficult a unit of code is to intuitively understand. Unlike Cyclomatic Complexity, which determines how difficult your code will be to test, Cognitive Complexity tells you how difficult your code will be to read and comprehend.

A method's cognitive complexity is based on a few simple rules:

  • Code is not considered more complex when it uses shorthand that the language provides for collapsing multiple statements into one
  • Code is considered more complex for each "break in the linear flow of the code"
  • Code is considered more complex when "flow breaking structures are nested"

Further reading

Similar blocks of code found in 2 locations. Consider refactoring.
Open

destination = source.create_vm(
  :name       => VM_NAME,
  :clone_type => :full,
  :cluster    => Ovirt::Cluster.find_by_id(rhevm, source[:cluster][:id]),
  :sparse     => :false,
Severity: Minor
Found in examples/create_vm_from_template_full_clone_example.rb and 1 other location - About 20 mins to fix
examples/create_vm_from_template_skeletal_clone_example.rb on lines 15..21

Duplicated Code

Duplicated code can lead to software that is hard to understand and difficult to change. The Don't Repeat Yourself (DRY) principle states:

Every piece of knowledge must have a single, unambiguous, authoritative representation within a system.

When you violate DRY, bugs and maintenance problems are sure to follow. Duplicated code has a tendency to both continue to replicate and also to diverge (leaving bugs as two similar implementations differ in subtle ways).

Tuning

This issue has a mass of 28.

We set useful threshold defaults for the languages we support but you may want to adjust these settings based on your project guidelines.

The threshold configuration represents the minimum mass a code block must have to be analyzed for duplication. The lower the threshold, the more fine-grained the comparison.

If the engine is too easily reporting duplication, try raising the threshold. If you suspect that the engine isn't catching enough duplication, try lowering the threshold. The best setting tends to differ from language to language.

See codeclimate-duplication's documentation for more information about tuning the mass threshold in your .codeclimate.yml.

Refactorings

Further Reading

Similar blocks of code found in 2 locations. Consider refactoring.
Open

destination = source.create_vm(
  :name       => DESTINATION_VM_NAME,
  :clone_type => :skeletal,
  :cluster    => Ovirt::Cluster.find_by_id(rhevm, source[:cluster][:id]),
  :sparse     => :false,
Severity: Minor
Found in examples/create_vm_from_template_skeletal_clone_example.rb and 1 other location - About 20 mins to fix
examples/create_vm_from_template_full_clone_example.rb on lines 15..21

Duplicated Code

Duplicated code can lead to software that is hard to understand and difficult to change. The Don't Repeat Yourself (DRY) principle states:

Every piece of knowledge must have a single, unambiguous, authoritative representation within a system.

When you violate DRY, bugs and maintenance problems are sure to follow. Duplicated code has a tendency to both continue to replicate and also to diverge (leaving bugs as two similar implementations differ in subtle ways).

Tuning

This issue has a mass of 28.

We set useful threshold defaults for the languages we support but you may want to adjust these settings based on your project guidelines.

The threshold configuration represents the minimum mass a code block must have to be analyzed for duplication. The lower the threshold, the more fine-grained the comparison.

If the engine is too easily reporting duplication, try raising the threshold. If you suspect that the engine isn't catching enough duplication, try lowering the threshold. The best setting tends to differ from language to language.

See codeclimate-duplication's documentation for more information about tuning the mass threshold in your .codeclimate.yml.

Refactorings

Further Reading

Use sort_by(&:to_s) instead of sort { |a, b| a.to_s <=> b.to_s }.
Open

    base.relationships.keys.sort { |a, b| a.to_s <=> b.to_s }.each do |rel|
Severity: Minor
Found in examples/event_monitor_example.rb by rubocop

This cop identifies places where sort { |a, b| a.foo <=> b.foo } can be replaced by sort_by(&:foo). This cop also checks max and min methods.

Example:

# bad
array.sort { |a, b| a.foo <=> b.foo }
array.max { |a, b| a.foo <=> b.foo }
array.min { |a, b| a.foo <=> b.foo }
array.sort { |a, b| a[:foo] <=> b[:foo] }

# good
array.sort_by(&:foo)
array.sort_by { |v| v.foo }
array.sort_by do |var|
  var.foo
end
array.max_by(&:foo)
array.min_by(&:foo)
array.sort_by { |a| a[:foo] }

Duplicate branch body detected.
Open

      when :linked   then clone_to_vm(options)
Severity: Minor
Found in lib/ovirt/template.rb by rubocop

Checks that there are no repeated bodies within if/unless, case-when, case-in and rescue constructs.

With IgnoreLiteralBranches: true, branches are not registered as offenses if they return a basic literal value (string, symbol, integer, float, rational, complex, true, false, or nil), or return an array, hash, regexp or range that only contains one of the above basic literal values.

With IgnoreConstantBranches: true, branches are not registered as offenses if they return a constant value.

Example:

# bad
if foo
  do_foo
  do_something_else
elsif bar
  do_foo
  do_something_else
end

# good
if foo || bar
  do_foo
  do_something_else
end

# bad
case x
when foo
  do_foo
when bar
  do_foo
else
  do_something_else
end

# good
case x
when foo, bar
  do_foo
else
  do_something_else
end

# bad
begin
  do_something
rescue FooError
  handle_error
rescue BarError
  handle_error
end

# good
begin
  do_something
rescue FooError, BarError
  handle_error
end

Example: IgnoreLiteralBranches: true

# good
case size
when "small" then 100
when "medium" then 250
when "large" then 1000
else 250
end

Example: IgnoreConstantBranches: true

# good
case size
when "small" then SMALL_SIZE
when "medium" then MEDIUM_SIZE
when "large" then LARGE_SIZE
else MEDIUM_SIZE
end

Prefer using YAML.safe_load over YAML.load.
Open

      raw_content          = YAML.load(content)
Severity: Minor
Found in lib/ovirt/vm.rb by rubocop

Checks for the use of YAML class methods which have potential security issues leading to remote code execution when loading from an untrusted source.

NOTE: Ruby 3.1+ (Psych 4) uses Psych.load as Psych.safe_load by default.

Safety:

The behavior of the code might change depending on what was in the YAML payload, since YAML.safe_load is more restrictive.

Example:

# bad
YAML.load("--- !ruby/object:Foo {}") # Psych 3 is unsafe by default

# good
YAML.safe_load("--- !ruby/object:Foo {}", [Foo])                    # Ruby 2.5  (Psych 3)
YAML.safe_load("--- !ruby/object:Foo {}", permitted_classes: [Foo]) # Ruby 3.0- (Psych 3)
YAML.load("--- !ruby/object:Foo {}", permitted_classes: [Foo])      # Ruby 3.1+ (Psych 4)
YAML.dump(foo)

Use match? instead of =~ when MatchData is not used.
Open

      raise VmNotReadyToBoot, [err.message, err] if err.message =~ /disks .+ are locked/
Severity: Minor
Found in lib/ovirt/vm.rb by rubocop

In Ruby 2.4, String#match?, Regexp#match? and Symbol#match? have been added. The methods are faster than match. Because the methods avoid creating a MatchData object or saving backref. So, when MatchData is not used, use match? instead of match.

Example:

# bad
def foo
  if x =~ /re/
    do_something
  end
end

# bad
def foo
  if x.match(/re/)
    do_something
  end
end

# bad
def foo
  if /re/ === x
    do_something
  end
end

# good
def foo
  if x.match?(/re/)
    do_something
  end
end

# good
def foo
  if x =~ /re/
    do_something(Regexp.last_match)
  end
end

# good
def foo
  if x.match(/re/)
    do_something($~)
  end
end

# good
def foo
  if /re/ === x
    do_something($~)
  end
end

Avoid hard coding large quantities of data in code. Prefer reading the data from an external source.
Open

    EVENT_CODES = {
      # Code   Description
      0     => "UNASSIGNED",
      1     => "VDC_START",
      2     => "VDC_STOP",
Severity: Minor
Found in lib/ovirt/event.rb by rubocop

Checks for literals with extremely many entries. This is indicative of configuration or data that may be better extracted somewhere else, like a database, fetched from an API, or read from a non-code file (CSV, JSON, YAML, etc.).

Example:

# bad
# Huge Array literal
[1, 2, '...', 999_999_999]

# bad
# Huge Hash literal
{ 1 => 1, 2 => 2, '...' => '...', 999_999_999 => 999_999_999}

# bad
# Huge Set "literal"
Set[1, 2, '...', 999_999_999]

# good
# Reasonably sized Array literal
[1, 2, '...', 10]

# good
# Reading huge Array from external data source
# File.readlines('numbers.txt', chomp: true).map!(&:to_i)

# good
# Reasonably sized Hash literal
{ 1 => 1, 2 => 2, '...' => '...', 10 => 10}

# good
# Reading huge Hash from external data source
CSV.foreach('numbers.csv', headers: true).each_with_object({}) do |row, hash|
  hash[row["key"].to_i] = row["value"].to_i
end

# good
# Reasonably sized Set "literal"
Set[1, 2, '...', 10]

# good
# Reading huge Set from external data source
SomeFramework.config_for(:something)[:numbers].to_set

Call super to initialize state of the parent class.
Open

    def initialize(*_args)
    end
Severity: Minor
Found in lib/ovirt/null_logger.rb by rubocop

Checks for the presence of constructors and lifecycle callbacks without calls to super.

This cop does not consider method_missing (and respond_to_missing?) because in some cases it makes sense to overtake what is considered a missing method. In other cases, the theoretical ideal handling could be challenging or verbose for no actual gain.

Autocorrection is not supported because the position of super cannot be determined automatically.

Object and BasicObject are allowed by this cop because of their stateless nature. However, sometimes you might want to allow other parent classes from this cop, for example in the case of an abstract class that is not meant to be called with super. In those cases, you can use the AllowedParentClasses option to specify which classes should be allowed in addition to Object and BasicObject.

Example:

# bad
class Employee < Person
  def initialize(name, salary)
    @salary = salary
  end
end

# good
class Employee < Person
  def initialize(name, salary)
    super(name)
    @salary = salary
  end
end

# bad
Employee = Class.new(Person) do
  def initialize(name, salary)
    @salary = salary
  end
end

# good
Employee = Class.new(Person) do
  def initialize(name, salary)
    super(name)
    @salary = salary
  end
end

# bad
class Parent
  def self.inherited(base)
    do_something
  end
end

# good
class Parent
  def self.inherited(base)
    super
    do_something
  end
end

# good
class ClassWithNoParent
  def initialize
    do_something
  end
end

Example: AllowedParentClasses: [MyAbstractClass]

# good
class MyConcreteClass < MyAbstractClass
  def initialize
    do_something
  end
end

Do not suppress exceptions.
Open

      rescue VmIsNotRunning
Severity: Minor
Found in lib/ovirt/vm.rb by rubocop

Checks for rescue blocks with no body.

Example:

# bad
def some_method
  do_something
rescue
end

# bad
begin
  do_something
rescue
end

# good
def some_method
  do_something
rescue
  handle_exception
end

# good
begin
  do_something
rescue
  handle_exception
end

Example: AllowComments: true (default)

# good
def some_method
  do_something
rescue
  # do nothing
end

# good
begin
  do_something
rescue
  # do nothing
end

Example: AllowComments: false

# bad
def some_method
  do_something
rescue
  # do nothing
end

# bad
begin
  do_something
rescue
  # do nothing
end

Example: AllowNil: true (default)

# good
def some_method
  do_something
rescue
  nil
end

# good
begin
  do_something
rescue
  # do nothing
end

# good
do_something rescue nil

Example: AllowNil: false

# bad
def some_method
  do_something
rescue
  nil
end

# bad
begin
  do_something
rescue
  nil
end

# bad
do_something rescue nil

Remove unnecessary require statement.
Open

require 'pp'
Severity: Minor
Found in examples/example_helper.rb by rubocop

Checks for unnecessary require statement.

The following features are unnecessary require statement because they are already loaded. e.g. Ruby 2.2:

ruby -ve 'p $LOADED_FEATURES.reject { |feature| %r|/| =~ feature }'
ruby 2.2.8p477 (2017-09-14 revision 59906) [x86_64-darwin13]
["enumerator.so", "rational.so", "complex.so", "thread.rb"]

Below are the features that each TargetRubyVersion targets.

* 2.0+ ... `enumerator`
* 2.1+ ... `thread`
* 2.2+ ... Add `rational` and `complex` above
* 2.5+ ... Add `pp` above
* 2.7+ ... Add `ruby2_keywords` above
* 3.1+ ... Add `fiber` above
* 3.2+ ... `set`

This cop target those features.

Example:

# bad
require 'unloaded_feature'
require 'thread'

# good
require 'unloaded_feature'
Severity
Category
Status
Source
Language