coredns/middleware/kubernetes/k8sclient/k8sclient.go
Michael Richmond 3f4ec783d2 Adding wildcard support (#190)
* Commenting out unused functions. TODO: remove when it is not needed

* Update README with namespace and template example

* Adding note about changing the record name format via a template

* Adding test scripts to automate k8s startup

* Automating k8s namespace creation

* Adding automation to start 4 k8s services

* Updating documentation for k8s tests

* Avoid downloading kubectl if already exists

* Adding debug statement when namespace is not exposed.

* Adding basic kubernetes integration tests

* Makefile now contains a "testk8s" target. This target requires k8s to
  be running.
* Adding test/kubernetes_test.go file with a couple of basic A record
  tests.

* Updating k8s integration tests to only run k8s integration tests

* Adding support for namespace wildcards

* Refactoring to move filtering logic to kubernetes.go file

* go fmt fixes

* Adding wildcard support for namespaces and service names

* Kubernetes integration tests updated for A records.
* Expanded record name assembly for answer section not yet implemented.
* Refactoring to focus k8sclient code just on accessing k8s API.
 Filtering now handled in kubernetes.go

* Adding wildcard test cases

* Adding skydns startup script. (To allow side by side testing of wildcards.)
* Commenting out record name assmebly based on NameTemplate. Need to improve template before this makes sense.

* Adding basic SRV integration tests

* Need to add verification for additional answer section

* Fixing comments and formatting

* Moving wildcard constants to vars

* Travis test execution appears to be failing on access to these
 constants

* Fixing access to util package

* Trying to work around Travis test bug

* Reverting to access kubernetes/util as "util"

Travis breakage is due to "Infoblox-CTO" in src path
2016-07-14 23:50:14 +02:00

133 lines
2.7 KiB
Go

package k8sclient
import (
"errors"
"fmt"
"net/url"
"strings"
)
// API strings
const (
apiBase = "/api/v1"
apiNamespaces = "/namespaces"
apiServices = "/services"
)
// Defaults
const (
defaultBaseURL = "http://localhost:8080"
)
type K8sConnector struct {
baseURL string
}
func (c *K8sConnector) SetBaseURL(u string) error {
url, error := url.Parse(u)
if error != nil {
return error
}
if !url.IsAbs() {
return errors.New("k8sclient: Kubernetes endpoint url must be an absolute URL")
}
c.baseURL = url.String()
return nil
}
func (c *K8sConnector) GetBaseURL() string {
return c.baseURL
}
// URL constructor separated from code to support dependency injection
// for unit tests.
var makeURL = func(parts []string) string {
return strings.Join(parts, "")
}
func (c *K8sConnector) GetResourceList() (*ResourceList, error) {
resources := new(ResourceList)
url := makeURL([]string{c.baseURL, apiBase})
err := parseJson(url, resources)
// TODO: handle no response from k8s
if err != nil {
fmt.Printf("[ERROR] Response from kubernetes API for GetResourceList() is: %v\n", err)
return nil, err
}
return resources, nil
}
func (c *K8sConnector) GetNamespaceList() (*NamespaceList, error) {
namespaces := new(NamespaceList)
url := makeURL([]string{c.baseURL, apiBase, apiNamespaces})
err := parseJson(url, namespaces)
if err != nil {
fmt.Printf("[ERROR] Response from kubernetes API for GetNamespaceList() is: %v\n", err)
return nil, err
}
return namespaces, nil
}
func (c *K8sConnector) GetServiceList() (*ServiceList, error) {
services := new(ServiceList)
url := makeURL([]string{c.baseURL, apiBase, apiServices})
err := parseJson(url, services)
// TODO: handle no response from k8s
if err != nil {
fmt.Printf("[ERROR] Response from kubernetes API for GetServiceList() is: %v\n", err)
return nil, err
}
return services, nil
}
// GetServicesByNamespace returns a map of
// namespacename :: [ kubernetesServiceItem ]
func (c *K8sConnector) GetServicesByNamespace() (map[string][]ServiceItem, error) {
items := make(map[string][]ServiceItem)
k8sServiceList, err := c.GetServiceList()
if err != nil {
fmt.Printf("[ERROR] Getting service list produced error: %v", err)
return nil, err
}
// TODO: handle no response from k8s
if k8sServiceList == nil {
return nil, nil
}
k8sItemList := k8sServiceList.Items
for _, i := range k8sItemList {
namespace := i.Metadata.Namespace
items[namespace] = append(items[namespace], i)
}
return items, nil
}
func NewK8sConnector(baseURL string) *K8sConnector {
k := new(K8sConnector)
if baseURL == "" {
baseURL = defaultBaseURL
}
err := k.SetBaseURL(baseURL)
if err != nil {
return nil
}
return k
}