require "pharos/host/configurer"
require "pharos/phases/configure_kubelet"

describe Pharos::Phases::ConfigureKubelet do
  let(:host_resolvconf) { Pharos::Configuration::ResolvConf.new(
      nameserver_localhost: false,
      systemd_resolved_stub: false,
  ) }
  let(:host_osrelease) { Pharos::Configuration::OsRelease.new(
    id: 'ubuntu',
    version: '16.04',
  ) }

  let(:environment_config) { {} }

  let(:host) do
    Pharos::Configuration::Host.new(
      {
        address: 'test',
        private_address: '192.168.42.1'
      }.merge(environment_config)
    )
  end

  let(:config_network) { { }}
  let(:control_plane_config) { {} }

  let(:config) do
    Pharos::Config.new(
      {
        hosts: [host],
        network: config_network,
        addons: {},
        etcd: {},
        kubelet: {read_only_port: false}
      }.merge(control_plane_config)
    )
  end

  subject { described_class.new(host, config: config) }

  before :all do
    Pharos::Host::Configurer.load_configurers
  end

  before do
    host.resolvconf = host_resolvconf
    allow(host).to receive(:cpu_arch).and_return(double(:cpu_arch, name: 'amd64'))
    allow(host).to receive(:os_release).and_return(host_osrelease)
  end

  describe '#build_systemd_dropin' do
    context 'without proxy settings' do
      it "returns a systemd unit" do
        expect(subject.build_systemd_dropin).to eq <<~EOM
          [Service]
          Environment='KUBELET_EXTRA_ARGS=--rotate-server-certificates --fail-swap-on=false --node-ip=192.168.42.1 --hostname-override= --pod-infra-container-image=docker.io/kontenapharos/pause:3.1'
          ExecStartPre=-/sbin/swapoff -a
        EOM
      end
    end

    context 'with proxy settings' do
      let(:environment_config) { { environment: { 'http_proxy' => 'proxy.example.com', 'NO_PROXY' => '127.0.0.1' } } }

      context 'when control_plane use_proxy is true' do
        let(:control_plane_config) { { control_plane: { use_proxy: true } } }

        it "returns a systemd unit" do
          expect(subject.build_systemd_dropin).to eq <<~EOM
            [Service]
            Environment='KUBELET_EXTRA_ARGS=--rotate-server-certificates --fail-swap-on=false --node-ip=192.168.42.1 --hostname-override= --pod-infra-container-image=docker.io/kontenapharos/pause:3.1'
            Environment='http_proxy=proxy.example.com'
            Environment='NO_PROXY=127.0.0.1'
            ExecStartPre=-/sbin/swapoff -a
          EOM
        end
      end

      context 'when control_plane use_proxy is false' do
        it "returns a systemd unit" do
          expect(subject.build_systemd_dropin).to eq <<~EOM
            [Service]
            Environment='KUBELET_EXTRA_ARGS=--rotate-server-certificates --fail-swap-on=false --node-ip=192.168.42.1 --hostname-override= --pod-infra-container-image=docker.io/kontenapharos/pause:3.1'
            ExecStartPre=-/sbin/swapoff -a
          EOM
        end
      end
    end

  end

  describe "#kubelet_extra_args" do
    it 'returns extra args array' do
      expect(subject.kubelet_extra_args).to include(
        '--node-ip=192.168.42.1',
        '--hostname-override='
      )
    end

    context 'with cloud provider' do
      let(:config) { Pharos::Config.new(
        hosts: [host],
        network: {
          service_cidr: '172.255.0.0/16',
        },
        cloud: {
          provider: 'aws',
          config: './cloud-config'
        },
        etcd: {},
        kubelet: {}
      ) }

      it 'adds cloud-provider arg' do
        expect(subject.kubelet_extra_args).to include(
          '--cloud-provider=aws'
        )
      end

      it 'adds cloud-config arg' do
        expect(subject.kubelet_extra_args).to include(
          '--cloud-config=/etc/pharos/kubelet/cloud-config'
        )
      end

      it 'does not add node ip' do
        expect(subject.kubelet_extra_args).not_to include(
          "--node-ip=#{host.peer_address}"
        )
      end
    end

    context "for a CentOS host" do
      let(:host_osrelease) { Pharos::Configuration::OsRelease.new(
        id: 'centos',
        version: '7',
      ) }

      it "configures --cgroup-driver" do
        expect(subject.kubelet_extra_args).to include '--cgroup-driver=cgroupfs'
      end
    end
  end
end
