github.com/google/cloudprober@v0.11.3/rds/kubernetes/kubernetes.go (about)

     1  // Copyright 2019 The Cloudprober Authors.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //      http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  /*
    16  Package kubernetes implements a kubernetes resources provider for
    17  ResourceDiscovery server.
    18  
    19  See:
    20   ResourceTypes variable for the list of supported resource types.
    21   SupportedFilters variable for the list of supported filters.
    22  
    23  
    24  Kubernetes provider is configured through a protobuf based config file
    25  (proto/config.proto). Example config:
    26  	{
    27  		pods {}
    28  	}
    29  */
    30  package kubernetes
    31  
    32  import (
    33  	"fmt"
    34  	"strings"
    35  	"time"
    36  
    37  	"github.com/google/cloudprober/logger"
    38  	configpb "github.com/google/cloudprober/rds/kubernetes/proto"
    39  	pb "github.com/google/cloudprober/rds/proto"
    40  )
    41  
    42  // DefaultProviderID is the povider id to use for this provider if a provider
    43  // id is not configured explicitly.
    44  const DefaultProviderID = "k8s"
    45  
    46  // ResourceTypes declares resource types supported by the Kubernetes provider.
    47  var ResourceTypes = struct {
    48  	Pods, Endpoints, Services, Ingresses string
    49  }{
    50  	"pods",
    51  	"endpoints",
    52  	"services",
    53  	"ingresses",
    54  }
    55  
    56  /*
    57  SupportedFilters defines filters supported by this provider.
    58   Example filters:
    59   filter {
    60  	 key: "name"
    61  	 value: "cloudprober.*"
    62   }
    63   filter {
    64  	 key: "namespace"
    65  	 value: "teamx.*"
    66   }
    67   filter {
    68  	 key: "port"
    69  	 value: "http.*"
    70   }
    71   filter {
    72  	 key: "labels.app"
    73  	 value: "service-a"
    74   }
    75  */
    76  var SupportedFilters = struct {
    77  	RegexFilterKeys []string
    78  	LabelsFilter    bool
    79  }{
    80  	// Note: the port filter applies only to endpoints and services.
    81  	[]string{"name", "namespace", "port"},
    82  	true,
    83  }
    84  
    85  type lister interface {
    86  	listResources(*pb.ListResourcesRequest) ([]*pb.Resource, error)
    87  }
    88  
    89  // Provider implements a Kubernetes (K8s) provider for use with a
    90  // ResourceDiscovery server.
    91  type Provider struct {
    92  	listers map[string]lister
    93  }
    94  
    95  // kMetadata represents metadata for all Kubernetes resources.
    96  type kMetadata struct {
    97  	Name      string
    98  	Namespace string
    99  	Labels    map[string]string
   100  }
   101  
   102  type resourceKey struct {
   103  	namespace, name string
   104  }
   105  
   106  // ListResources returns the list of resources from the cache.
   107  func (p *Provider) ListResources(req *pb.ListResourcesRequest) (*pb.ListResourcesResponse, error) {
   108  	tok := strings.SplitN(req.GetResourcePath(), "/", 2)
   109  
   110  	resType := tok[0]
   111  
   112  	lr := p.listers[resType]
   113  	if lr == nil {
   114  		return nil, fmt.Errorf("kubernetes: unsupported resource type: %s", resType)
   115  	}
   116  	resources, err := lr.listResources(req)
   117  	return &pb.ListResourcesResponse{Resources: resources}, err
   118  }
   119  
   120  // New creates a Kubernetes (k8s) provider for RDS server, based on the
   121  // provided config.
   122  func New(c *configpb.ProviderConfig, l *logger.Logger) (*Provider, error) {
   123  	client, err := newClient(c, l)
   124  	if err != nil {
   125  		return nil, fmt.Errorf("error while creating the kubernetes client: %v", err)
   126  	}
   127  
   128  	p := &Provider{
   129  		listers: make(map[string]lister),
   130  	}
   131  
   132  	reEvalInterval := time.Duration(c.GetReEvalSec()) * time.Second
   133  
   134  	// Enable Pods lister if configured.
   135  	if c.GetPods() != nil {
   136  		lr, err := newPodsLister(c.GetPods(), c.GetNamespace(), reEvalInterval, client, l)
   137  		if err != nil {
   138  			return nil, err
   139  		}
   140  		p.listers[ResourceTypes.Pods] = lr
   141  	}
   142  
   143  	// Enable Endpoints lister if configured.
   144  	if c.GetEndpoints() != nil {
   145  		lr, err := newEndpointsLister(c.GetEndpoints(), c.GetNamespace(), reEvalInterval, client, l)
   146  		if err != nil {
   147  			return nil, err
   148  		}
   149  		p.listers[ResourceTypes.Endpoints] = lr
   150  	}
   151  
   152  	// Enable Services lister if configured.
   153  	if c.GetServices() != nil {
   154  		lr, err := newServicesLister(c.GetServices(), c.GetNamespace(), reEvalInterval, client, l)
   155  		if err != nil {
   156  			return nil, err
   157  		}
   158  		p.listers[ResourceTypes.Services] = lr
   159  	}
   160  
   161  	// Enable Ingresses lister if configured.
   162  	if c.GetIngresses() != nil {
   163  		lr, err := newIngressesLister(c.GetIngresses(), c.GetNamespace(), reEvalInterval, client, l)
   164  		if err != nil {
   165  			return nil, err
   166  		}
   167  		p.listers[ResourceTypes.Ingresses] = lr
   168  	}
   169  
   170  	return p, nil
   171  }