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 }