module Bosh
  module Director
    module Api
      class CloudConfigManager
        def update(cloud_config_yaml)
          cloud_config = Bosh::Director::Models::CloudConfig.new(
            properties: cloud_config_yaml
          )
          validate_manifest!(cloud_config)
          cloud_config.save
        end

        def list(limit)
          Bosh::Director::Models::CloudConfig.order(Sequel.desc(:id)).limit(limit).to_a
        end

        def latest
          list(1).first
        end

        private

        def validate_manifest!(cloud_config)
          # FIXME: pass in null ip/networking objects
          # these objects won't work if you actually try to reserve IPs with them since the cloud_planner is empty,
          # but we really just need to validate the manifest, we don't care about the subnets being able to reserve IPs here
          cloud_planner = Bosh::Director::DeploymentPlan::CloudPlanner.new({
              networks: [],
              disk_pools: [],
              availability_zones: [],
              resource_pools: [],
              compilation: nil,
            })
          ip_provider_factory = Bosh::Director::DeploymentPlan::IpProviderFactory.new(cloud_planner.model, Config.logger, global_networking: cloud_planner.using_global_networking?)
          global_network_resolver = Bosh::Director::DeploymentPlan::GlobalNetworkResolver.new(cloud_planner)

          parser = Bosh::Director::DeploymentPlan::CloudManifestParser.new(Config.logger)
          _ = parser.parse(cloud_config.manifest, ip_provider_factory, global_network_resolver) # valid if this doesn't blow up
        end
      end
    end
  end
end

module Bosh
  module Director
    module Api
      class CloudConfigManager
        def update(cloud_config_yaml)
          cloud_config = Bosh::Director::Models::CloudConfig.new(
            properties: cloud_config_yaml
          )
          validate_manifest!(cloud_config)
          cloud_config.save
        end

        def list(limit)
          Bosh::Director::Models::CloudConfig.order(Sequel.desc(:id)).limit(limit).to_a
        end

        def latest
          list(1).first
        end

        private

        def validate_manifest!(cloud_config)
          # FIXME: we really just need to validate the manifest, we don't care about the subnets being able to reserve IPs here
          ip_provider_factory = NullIpProviderFactory.new
          global_network_resolver = NullGlobalNetworkResolver.new

          parser = Bosh::Director::DeploymentPlan::CloudManifestParser.new(Config.logger)
          _ = parser.parse(cloud_config.manifest, ip_provider_factory, global_network_resolver) # valid if this doesn't blow up
        end

        class NullIpProviderFactory
          def create(*args)
            nil
          end
        end

        class NullGlobalNetworkResolver
          def reserved_legacy_ranges(something)
            []
          end
        end
      end
    end
  end
end

Make bad dependencies more obvious
Make bad dependencies more obvious

Use null objects since we're not expecting them to be used for anything.

We need the IpProviderFactory and GlobalNetworkResolver when parsing so
we can give subnets an IpProvider. This is kind of crazy, especially in
api/cloud_config_manager where we're really just trying to validate a
manifest, not reserve any IPs.

IP reservation probably needs a refactor so that parsing no longer
depends on these objects.

Signed-off-by: Luke Woydziak <5ec47d3d6d41d8ebc18a534604a07e736a0a4783@emc.com>
