diff options
| -rw-r--r-- | lib/gitlab/kubernetes/kube_client.rb | 47 | ||||
| -rw-r--r-- | spec/lib/gitlab/kubernetes/kube_client_spec.rb | 129 | 
2 files changed, 59 insertions, 117 deletions
diff --git a/lib/gitlab/kubernetes/kube_client.rb b/lib/gitlab/kubernetes/kube_client.rb index 588238de608..0125b6005cf 100644 --- a/lib/gitlab/kubernetes/kube_client.rb +++ b/lib/gitlab/kubernetes/kube_client.rb @@ -19,6 +19,8 @@ module Gitlab          'apis/extensions'        ].freeze +      LATEST_EXTENSIONS_VERSION = 'v1beta1' +        # Core API methods delegates to the core api group client        delegate :get_pods,          :get_secrets, @@ -55,48 +57,39 @@ module Gitlab          :watch_pod_log,          to: :core_client -      def initialize(api_prefix, api_groups = ['api'], api_version = 'v1', **kubeclient_options) -        raise ArgumentError unless check_api_groups_supported?(api_groups) +      attr_reader :api_prefix, :kubeclient_options, :default_api_version +      def initialize(api_prefix, default_api_version = 'v1', **kubeclient_options)          @api_prefix = api_prefix -        @api_groups = api_groups -        @api_version = api_version          @kubeclient_options = kubeclient_options -      end +        @default_api_version = default_api_version -      def discover! -        clients.each(&:discover) +        @hashed_clients = {}        end -      def clients -        hashed_clients.values +      def core_client(api_version: default_api_version) +        build_kubeclient('api', api_version)        end -      def core_client -        hashed_clients['api'] +      def rbac_client(api_version: default_api_version) +        build_kubeclient('apis/rbac.authorization.k8s.io', api_version)        end -      def rbac_client -        hashed_clients['apis/rbac.authorization.k8s.io'] +      def extensions_client(api_version: LATEST_EXTENSIONS_VERSION) +        build_kubeclient('apis/extensions', api_version)        end -      def extensions_client -        hashed_clients['apis/extensions'] -      end +      private -      def hashed_clients -        strong_memoize(:hashed_clients) do -          @api_groups.map do |api_group| -            api_url = join_api_url(@api_prefix, api_group) -            [api_group, ::Kubeclient::Client.new(api_url, @api_version, **@kubeclient_options)] -          end.to_h -        end -      end +      def build_kubeclient(api_group, api_version) +        raise ArgumentError, "Unknown api group #{api_group}" unless SUPPORTED_API_GROUPS.include?(api_group) -      private +        key = api_group_with_version(api_group, api_version) +        @hashed_clients[key] ||= ::Kubeclient::Client.new(join_api_url(api_prefix, api_group), api_version, **kubeclient_options) +      end -      def check_api_groups_supported?(api_groups) -        api_groups.all? {|api_group| SUPPORTED_API_GROUPS.include?(api_group) } +      def api_group_with_version(api_group, api_version) +        api_group + '/' + api_version        end        def join_api_url(api_prefix, api_path) diff --git a/spec/lib/gitlab/kubernetes/kube_client_spec.rb b/spec/lib/gitlab/kubernetes/kube_client_spec.rb index 53c5a4e7c94..ba38e2c31ea 100644 --- a/spec/lib/gitlab/kubernetes/kube_client_spec.rb +++ b/spec/lib/gitlab/kubernetes/kube_client_spec.rb @@ -6,103 +6,87 @@ describe Gitlab::Kubernetes::KubeClient do    include KubernetesHelpers    let(:api_url) { 'https://kubernetes.example.com/prefix' } -  let(:api_groups) { ['api', 'apis/rbac.authorization.k8s.io'] }    let(:api_version) { 'v1' }    let(:kubeclient_options) { { auth_options: { bearer_token: 'xyz' } } } -  let(:client) { described_class.new(api_url, api_groups, api_version, kubeclient_options) } +  let(:client) { described_class.new(api_url, api_version, kubeclient_options) }    before do      stub_kubeclient_discover(api_url)    end -  describe '#hashed_clients' do -    subject { client.hashed_clients } - -    it 'has keys from api groups' do -      expect(subject.keys).to match_array api_groups +  shared_examples 'a Kubeclient' do +    it 'is a Kubeclient::Client' do +      is_expected.to be_an_instance_of Kubeclient::Client      end -    it 'has values of Kubeclient::Client' do -      expect(subject.values).to all(be_an_instance_of Kubeclient::Client) +    it 'has the kubeclient options' do +      expect(subject.auth_options).to eq({ bearer_token: 'xyz' })      end    end -  describe '#clients' do -    subject { client.clients } - -    it 'is not empty' do -      is_expected.to be_present -    end - -    it 'is an array of Kubeclient::Client objects' do -      is_expected.to all(be_an_instance_of Kubeclient::Client) -    end - -    it 'has each API group url' do -      expected_urls = api_groups.map { |group| "#{api_url}/#{group}" } +  describe '#core_client' do +    subject { client.core_client } -      expect(subject.map(&:api_endpoint).map(&:to_s)).to match_array(expected_urls) -    end +    it_behaves_like 'a Kubeclient' -    it 'has the kubeclient options' do -      subject.each do |client| -        expect(client.auth_options).to eq({ bearer_token: 'xyz' }) -      end +    it 'has the core API endpoint' do +      expect(subject.api_endpoint.to_s).to match(%r{\/api\Z})      end      it 'has the api_version' do -      subject.each do |client| -        expect(client.instance_variable_get(:@api_version)).to eq('v1') -      end +      expect(subject.instance_variable_get(:@api_version)).to eq('v1')      end -  end - -  describe '#core_client' do -    subject { client.core_client } -    it 'is a Kubeclient::Client' do -      is_expected.to be_an_instance_of Kubeclient::Client -    end +    context 'different api version' do +      subject { client.core_client(api_version: 'v2') } -    it 'has the core API endpoint' do -      expect(subject.api_endpoint.to_s).to match(%r{\/api\Z}) +      it 'has the api_version' do +        expect(subject.instance_variable_get(:@api_version)).to eq('v2') +      end      end    end    describe '#rbac_client' do      subject { client.rbac_client } -    it 'is a Kubeclient::Client' do -      is_expected.to be_an_instance_of Kubeclient::Client -    end +    it_behaves_like 'a Kubeclient'      it 'has the RBAC API group endpoint' do        expect(subject.api_endpoint.to_s).to match(%r{\/apis\/rbac.authorization.k8s.io\Z})      end + +    it 'has the api_version' do +      expect(subject.instance_variable_get(:@api_version)).to eq('v1') +    end + +    context 'different api version' do +      subject { client.rbac_client(api_version: 'v2') } + +      it 'has the api_version' do +        expect(subject.instance_variable_get(:@api_version)).to eq('v2') +      end +    end    end    describe '#extensions_client' do      subject { client.extensions_client } -    let(:api_groups) { ['apis/extensions'] } - -    it 'is a Kubeclient::Client' do -      is_expected.to be_an_instance_of Kubeclient::Client -    end +    it_behaves_like 'a Kubeclient'      it 'has the extensions API group endpoint' do        expect(subject.api_endpoint.to_s).to match(%r{\/apis\/extensions\Z})      end -  end -  describe '#discover!' do -    it 'makes a discovery request for each API group' do -      client.discover! +    it 'has the api_version' do +      expect(subject.instance_variable_get(:@api_version)).to eq('v1beta1') +    end -      api_groups.each do |api_group| -        discovery_url = api_url + '/' + api_group + '/v1' -        expect(WebMock).to have_requested(:get, discovery_url).once +    context 'different api version' do +      subject { client.extensions_client(api_version: 'v2') } + +      it 'has the api_version' do +        expect(subject.instance_variable_get(:@api_version)).to eq('v2')        end      end    end @@ -156,14 +140,6 @@ describe Gitlab::Kubernetes::KubeClient do          it 'responds to the method' do            expect(client).to respond_to method          end - -        context 'no rbac client' do -          let(:api_groups) { ['api'] } - -          it 'throws an error' do -            expect { client.public_send(method) }.to raise_error(Module::DelegationError) -          end -        end        end      end    end @@ -181,22 +157,11 @@ describe Gitlab::Kubernetes::KubeClient do        it 'responds to the method' do          expect(client).to respond_to :get_deployments        end - -      context 'no extensions client' do -        let(:api_groups) { ['api'] } -        let(:api_version) { 'v1' } - -        it 'throws an error' do -          expect { client.get_deployments }.to raise_error(Module::DelegationError) -        end -      end      end    end    describe 'non-entity methods' do      it 'does not proxy for non-entity methods' do -      expect(client.clients.first).to respond_to :proxy_url -        expect(client).not_to respond_to :proxy_url      end @@ -211,14 +176,6 @@ describe Gitlab::Kubernetes::KubeClient do      it 'is delegated to the core client' do        expect(client).to delegate_method(:get_pod_log).to(:core_client)      end - -    context 'when no core client' do -      let(:api_groups) { ['apis/extensions'] } - -      it 'throws an error' do -        expect { client.get_pod_log('pod-name') }.to raise_error(Module::DelegationError) -      end -    end    end    describe '#watch_pod_log' do @@ -227,14 +184,6 @@ describe Gitlab::Kubernetes::KubeClient do      it 'is delegated to the core client' do        expect(client).to delegate_method(:watch_pod_log).to(:core_client)      end - -    context 'when no core client' do -      let(:api_groups) { ['apis/extensions'] } - -      it 'throws an error' do -        expect { client.watch_pod_log('pod-name') }.to raise_error(Module::DelegationError) -      end -    end    end    describe 'methods that do not exist on any client' do  | 
