Merge pull request #994 from freehan/revendor-godep

Revendor godep
This commit is contained in:
Nick Sardo 2017-07-26 17:32:18 -07:00 committed by GitHub
commit 16a213c076
1271 changed files with 186289 additions and 303314 deletions

3
.gitignore vendored
View file

@ -2,6 +2,9 @@
._*
.DS_Store
# intellij files
.idea/*
# Eclipse files
.classpath
.project

1092
Godeps/Godeps.json generated

File diff suppressed because it is too large Load diff

View file

@ -26,10 +26,11 @@ import (
"github.com/golang/glog"
compute "google.golang.org/api/compute/v1"
v1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/intstr"
"k8s.io/apimachinery/pkg/util/sets"
api_v1 "k8s.io/client-go/pkg/api/v1"
"k8s.io/ingress/controllers/gce/healthchecks"
"k8s.io/ingress/controllers/gce/instances"
@ -161,7 +162,7 @@ func (b *Backends) Init(pp probeProvider) {
// Get returns a single backend.
func (b *Backends) Get(port int64) (*compute.BackendService, error) {
be, err := b.cloud.GetBackendService(b.namer.BeName(port))
be, err := b.cloud.GetGlobalBackendService(b.namer.BeName(port))
if err != nil {
return nil, err
}
@ -203,7 +204,7 @@ func (b *Backends) create(namedPort *compute.NamedPort, hcLink string, sp Servic
Port: namedPort.Port,
PortName: namedPort.Name,
}
if err := b.cloud.CreateBackendService(bs); err != nil {
if err := b.cloud.CreateGlobalBackendService(bs); err != nil {
return nil, err
}
return b.Get(namedPort.Port)
@ -248,7 +249,7 @@ func (b *Backends) Add(p ServicePort) error {
be.Protocol = string(p.Protocol)
be.HealthChecks = []string{hcLink}
be.Description = p.Description()
if err = b.cloud.UpdateBackendService(be); err != nil {
if err = b.cloud.UpdateGlobalBackendService(be); err != nil {
return err
}
}
@ -282,7 +283,7 @@ func (b *Backends) Delete(port int64) (err error) {
}
}()
// Try deleting health checks even if a backend is not found.
if err = b.cloud.DeleteBackendService(name); err != nil && !utils.IsHTTPErrorCode(err, http.StatusNotFound) {
if err = b.cloud.DeleteGlobalBackendService(name); err != nil && !utils.IsHTTPErrorCode(err, http.StatusNotFound) {
return err
}
@ -294,7 +295,7 @@ func (b *Backends) List() ([]interface{}, error) {
// TODO: for consistency with the rest of this sub-package this method
// should return a list of backend ports.
interList := []interface{}{}
be, err := b.cloud.ListBackendServices()
be, err := b.cloud.ListGlobalBackendServices()
if err != nil {
return interList, err
}
@ -361,7 +362,7 @@ func (b *Backends) edgeHop(be *compute.BackendService, igs []*compute.InstanceGr
newBackends := getBackendsForIGs(addIGs, bm)
be.Backends = append(originalBackends, newBackends...)
if err := b.cloud.UpdateBackendService(be); err != nil {
if err := b.cloud.UpdateGlobalBackendService(be); err != nil {
if utils.IsHTTPErrorCode(err, http.StatusBadRequest) {
glog.V(2).Infof("Updating backend service backends with balancing mode %v failed, will try another mode. err:%v", bm, err)
errs = append(errs, err.Error())
@ -427,14 +428,14 @@ func (b *Backends) Shutdown() error {
// Status returns the status of the given backend by name.
func (b *Backends) Status(name string) string {
backend, err := b.cloud.GetBackendService(name)
backend, err := b.cloud.GetGlobalBackendService(name)
if err != nil || len(backend.Backends) == 0 {
return "Unknown"
}
// TODO: Look at more than one backend's status
// TODO: Include port, ip in the status, since it's in the health info.
hs, err := b.cloud.GetHealth(name, backend.Backends[0].Group)
hs, err := b.cloud.GetGlobalBackendServiceHealth(name, backend.Backends[0].Group)
if err != nil || len(hs.HealthStatus) == 0 || hs.HealthStatus[0] == nil {
return "Unknown"
}
@ -453,7 +454,7 @@ func applyLegacyHCToHC(existing *compute.HttpHealthCheck, hc *healthchecks.Healt
hc.UnhealthyThreshold = existing.UnhealthyThreshold
}
func applyProbeSettingsToHC(p *api_v1.Probe, hc *healthchecks.HealthCheck) {
func applyProbeSettingsToHC(p *v1.Probe, hc *healthchecks.HealthCheck) {
healthPath := p.Handler.HTTPGet.Path
// GCE requires a leading "/" for health check urls.
if !strings.HasPrefix(healthPath, "/") {

View file

@ -23,9 +23,9 @@ import (
compute "google.golang.org/api/compute/v1"
"google.golang.org/api/googleapi"
api_v1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/util/intstr"
"k8s.io/apimachinery/pkg/util/sets"
api_v1 "k8s.io/client-go/pkg/api/v1"
"k8s.io/ingress/controllers/gce/healthchecks"
"k8s.io/ingress/controllers/gce/instances"
@ -87,7 +87,7 @@ func TestBackendPoolAdd(t *testing.T) {
beName := namer.BeName(nodePort.Port)
// Check that the new backend has the right port
be, err := f.GetBackendService(beName)
be, err := f.GetGlobalBackendService(beName)
if err != nil {
t.Fatalf("Did not find expected backend %v", beName)
}
@ -171,7 +171,7 @@ func TestBackendPoolUpdate(t *testing.T) {
pool.Add(p)
beName := namer.BeName(p.Port)
be, err := f.GetBackendService(beName)
be, err := f.GetGlobalBackendService(beName)
if err != nil {
t.Fatalf("Unexpected err: %v", err)
}
@ -190,7 +190,7 @@ func TestBackendPoolUpdate(t *testing.T) {
p.Protocol = utils.ProtocolHTTPS
pool.Sync([]ServicePort{p})
be, err = f.GetBackendService(beName)
be, err = f.GetGlobalBackendService(beName)
if err != nil {
t.Fatalf("Unexpected err retrieving backend service after update: %v", err)
}
@ -217,7 +217,7 @@ func TestBackendPoolChaosMonkey(t *testing.T) {
pool.Add(nodePort)
beName := namer.BeName(nodePort.Port)
be, _ := f.GetBackendService(beName)
be, _ := f.GetGlobalBackendService(beName)
// Mess up the link between backend service and instance group.
// This simulates a user doing foolish things through the UI.
@ -225,7 +225,7 @@ func TestBackendPoolChaosMonkey(t *testing.T) {
{Group: "test edge hop"},
}
f.calls = []int{}
f.UpdateBackendService(be)
f.UpdateGlobalBackendService(be)
pool.Add(nodePort)
for _, call := range f.calls {
@ -233,7 +233,7 @@ func TestBackendPoolChaosMonkey(t *testing.T) {
t.Fatalf("Unexpected create for existing backend service")
}
}
gotBackend, err := f.GetBackendService(beName)
gotBackend, err := f.GetGlobalBackendService(beName)
if err != nil {
t.Fatalf("Failed to find a backend with name %v: %v", beName, err)
}
@ -296,12 +296,12 @@ func TestBackendPoolSync(t *testing.T) {
// k8s-be-3001--uid - another cluster tagged with uid
unrelatedBackends := sets.NewString([]string{"foo", "k8s-be-foo", "k8s--bar--foo", "k8s-be-30001--uid"}...)
for _, name := range unrelatedBackends.List() {
f.CreateBackendService(&compute.BackendService{Name: name})
f.CreateGlobalBackendService(&compute.BackendService{Name: name})
}
namer := &utils.Namer{}
// This backend should get deleted again since it is managed by this cluster.
f.CreateBackendService(&compute.BackendService{Name: namer.BeName(deletedPorts[0].Port)})
f.CreateGlobalBackendService(&compute.BackendService{Name: namer.BeName(deletedPorts[0].Port)})
// TODO: Avoid casting.
// Repopulate the pool with a cloud list, which now includes the 82 port
@ -311,7 +311,7 @@ func TestBackendPoolSync(t *testing.T) {
pool.GC(svcNodePorts)
currBackends, _ := f.ListBackendServices()
currBackends, _ := f.ListGlobalBackendServices()
currSet := sets.NewString()
for _, b := range currBackends.Items {
currSet.Insert(b.Name)
@ -355,7 +355,7 @@ func TestBackendPoolDeleteLegacyHealthChecks(t *testing.T) {
}
// Create backend service with expected name and link to legacy health check
f.CreateBackendService(&compute.BackendService{
f.CreateGlobalBackendService(&compute.BackendService{
Name: beName,
HealthChecks: []string{hc.SelfLink},
})
@ -390,7 +390,7 @@ func TestBackendPoolShutdown(t *testing.T) {
// Add a backend-service and verify that it doesn't exist after Shutdown()
pool.Add(ServicePort{Port: 80})
pool.Shutdown()
if _, err := f.GetBackendService(namer.BeName(80)); err == nil {
if _, err := f.GetGlobalBackendService(namer.BeName(80)); err == nil {
t.Fatalf("%v", err)
}
}
@ -404,7 +404,7 @@ func TestBackendInstanceGroupClobbering(t *testing.T) {
// This will add the instance group k8s-ig to the instance pool
pool.Add(ServicePort{Port: 80})
be, err := f.GetBackendService(namer.BeName(80))
be, err := f.GetGlobalBackendService(namer.BeName(80))
if err != nil {
t.Fatalf("%v", err)
}
@ -415,13 +415,13 @@ func TestBackendInstanceGroupClobbering(t *testing.T) {
{Group: "k8s-ig-foo"},
}
be.Backends = append(be.Backends, newGroups...)
if err = f.UpdateBackendService(be); err != nil {
if err = f.UpdateGlobalBackendService(be); err != nil {
t.Fatalf("Failed to update backend service %v", be.Name)
}
// Make sure repeated adds don't clobber the inserted instance group
pool.Add(ServicePort{Port: 80})
be, err = f.GetBackendService(namer.BeName(80))
be, err = f.GetGlobalBackendService(namer.BeName(80))
if err != nil {
t.Fatalf("%v", err)
}
@ -463,7 +463,7 @@ func TestBackendCreateBalancingMode(t *testing.T) {
}
pool.Add(nodePort)
be, err := f.GetBackendService(namer.BeName(nodePort.Port))
be, err := f.GetGlobalBackendService(namer.BeName(nodePort.Port))
if err != nil {
t.Fatalf("%v", err)
}

View file

@ -20,7 +20,7 @@ import (
"fmt"
compute "google.golang.org/api/compute/v1"
api_v1 "k8s.io/client-go/pkg/api/v1"
api_v1 "k8s.io/api/core/v1"
"k8s.io/client-go/tools/cache"
"k8s.io/ingress/controllers/gce/utils"
@ -44,8 +44,8 @@ type FakeBackendServices struct {
errFunc func(op int, be *compute.BackendService) error
}
// GetBackendService fakes getting a backend service from the cloud.
func (f *FakeBackendServices) GetBackendService(name string) (*compute.BackendService, error) {
// GetGlobalBackendService fakes getting a backend service from the cloud.
func (f *FakeBackendServices) GetGlobalBackendService(name string) (*compute.BackendService, error) {
f.calls = append(f.calls, utils.Get)
obj, exists, err := f.backendServices.GetByKey(name)
if !exists {
@ -62,8 +62,8 @@ func (f *FakeBackendServices) GetBackendService(name string) (*compute.BackendSe
return nil, fmt.Errorf("backend service %v not found", name)
}
// CreateBackendService fakes backend service creation.
func (f *FakeBackendServices) CreateBackendService(be *compute.BackendService) error {
// CreateGlobalBackendService fakes backend service creation.
func (f *FakeBackendServices) CreateGlobalBackendService(be *compute.BackendService) error {
if f.errFunc != nil {
if err := f.errFunc(utils.Create, be); err != nil {
return err
@ -74,8 +74,8 @@ func (f *FakeBackendServices) CreateBackendService(be *compute.BackendService) e
return f.backendServices.Update(be)
}
// DeleteBackendService fakes backend service deletion.
func (f *FakeBackendServices) DeleteBackendService(name string) error {
// DeleteGlobalBackendService fakes backend service deletion.
func (f *FakeBackendServices) DeleteGlobalBackendService(name string) error {
f.calls = append(f.calls, utils.Delete)
svc, exists, err := f.backendServices.GetByKey(name)
if !exists {
@ -87,8 +87,8 @@ func (f *FakeBackendServices) DeleteBackendService(name string) error {
return f.backendServices.Delete(svc)
}
// ListBackendServices fakes backend service listing.
func (f *FakeBackendServices) ListBackendServices() (*compute.BackendServiceList, error) {
// ListGlobalBackendServices fakes backend service listing.
func (f *FakeBackendServices) ListGlobalBackendServices() (*compute.BackendServiceList, error) {
var svcs []*compute.BackendService
for _, s := range f.backendServices.List() {
svc := s.(*compute.BackendService)
@ -97,8 +97,8 @@ func (f *FakeBackendServices) ListBackendServices() (*compute.BackendServiceList
return &compute.BackendServiceList{Items: svcs}, nil
}
// UpdateBackendService fakes updating a backend service.
func (f *FakeBackendServices) UpdateBackendService(be *compute.BackendService) error {
// UpdateGlobalBackendService fakes updating a backend service.
func (f *FakeBackendServices) UpdateGlobalBackendService(be *compute.BackendService) error {
if f.errFunc != nil {
if err := f.errFunc(utils.Update, be); err != nil {
return err
@ -108,9 +108,9 @@ func (f *FakeBackendServices) UpdateBackendService(be *compute.BackendService) e
return f.backendServices.Update(be)
}
// GetHealth fakes getting backend service health.
func (f *FakeBackendServices) GetHealth(name, instanceGroupLink string) (*compute.BackendServiceGroupHealth, error) {
be, err := f.GetBackendService(name)
// GetGlobalBackendServiceHealth fakes getting backend service health.
func (f *FakeBackendServices) GetGlobalBackendServiceHealth(name, instanceGroupLink string) (*compute.BackendServiceGroupHealth, error) {
be, err := f.GetGlobalBackendService(name)
if err != nil {
return nil, err
}

View file

@ -18,7 +18,7 @@ package backends
import (
compute "google.golang.org/api/compute/v1"
api_v1 "k8s.io/client-go/pkg/api/v1"
api_v1 "k8s.io/api/core/v1"
)
// ProbeProvider retrieves a probe struct given a nodePort
@ -42,10 +42,10 @@ type BackendPool interface {
// BackendServices is an interface for managing gce backend services.
type BackendServices interface {
GetBackendService(name string) (*compute.BackendService, error)
UpdateBackendService(bg *compute.BackendService) error
CreateBackendService(bg *compute.BackendService) error
DeleteBackendService(name string) error
ListBackendServices() (*compute.BackendServiceList, error)
GetHealth(name, instanceGroupLink string) (*compute.BackendServiceGroupHealth, error)
GetGlobalBackendService(name string) (*compute.BackendService, error)
UpdateGlobalBackendService(bg *compute.BackendService) error
CreateGlobalBackendService(bg *compute.BackendService) error
DeleteGlobalBackendService(name string) error
ListGlobalBackendServices() (*compute.BackendServiceList, error)
GetGlobalBackendServiceHealth(name, instanceGroupLink string) (*compute.BackendServiceGroupHealth, error)
}

View file

@ -224,7 +224,7 @@ func getGCEClient(config io.Reader) *gce.GCECloud {
// user has no need for Ingress in this case. If they grant
// permissions to the node they will have to restart the controller
// manually to re-create the client.
if _, err = cloud.ListBackendServices(); err == nil || utils.IsHTTPErrorCode(err, http.StatusForbidden) {
if _, err = cloud.ListGlobalBackendServices(); err == nil || utils.IsHTTPErrorCode(err, http.StatusForbidden) {
return cloud
}
glog.Warningf("Failed to list backend services, retrying: %v", err)

View file

@ -24,14 +24,14 @@ import (
"github.com/golang/glog"
api_v1 "k8s.io/api/core/v1"
extensions "k8s.io/api/extensions/v1beta1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/fields"
"k8s.io/client-go/kubernetes"
scheme "k8s.io/client-go/kubernetes/scheme"
unversionedcore "k8s.io/client-go/kubernetes/typed/core/v1"
listers "k8s.io/client-go/listers/core/v1"
api_v1 "k8s.io/client-go/pkg/api/v1"
extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1"
"k8s.io/client-go/tools/cache"
"k8s.io/client-go/tools/record"

View file

@ -24,14 +24,14 @@ import (
compute "google.golang.org/api/compute/v1"
api_v1 "k8s.io/api/core/v1"
extensions "k8s.io/api/extensions/v1beta1"
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/intstr"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/apimachinery/pkg/util/uuid"
"k8s.io/client-go/kubernetes/fake"
"k8s.io/client-go/pkg/api"
api_v1 "k8s.io/client-go/pkg/api/v1"
extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1"
"k8s.io/kubernetes/pkg/api"
"k8s.io/ingress/controllers/gce/firewalls"
"k8s.io/ingress/controllers/gce/loadbalancers"
@ -428,7 +428,7 @@ func TestLbChangeStaticIP(t *testing.T) {
}
ing.Annotations = map[string]string{staticIPNameKey: "testip"}
cm.fakeLbs.ReserveGlobalStaticIP("testip", "1.2.3.4")
cm.fakeLbs.ReserveGlobalAddress(&compute.Address{Name: "testip", Address: "1.2.3.4"})
// Second sync reassigns 1.2.3.4 to existing forwarding rule (by recreating it)
lbc.sync(ingStoreKey)

View file

@ -65,7 +65,7 @@ func NewFakeClusterManager(clusterName, firewallName string) *fakeClusterManager
testDefaultBeNodePort,
namer,
)
frPool := firewalls.NewFirewallPool(firewalls.NewFakeFirewallsProvider(namer), namer)
frPool := firewalls.NewFirewallPool(firewalls.NewFakeFirewallsProvider(), namer)
cm := &ClusterManager{
ClusterNamer: namer,
instancePool: nodePool,

View file

@ -21,10 +21,10 @@ import (
"github.com/golang/glog"
api_v1 "k8s.io/api/core/v1"
extensions "k8s.io/api/extensions/v1beta1"
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
api_v1 "k8s.io/client-go/pkg/api/v1"
extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1"
"k8s.io/ingress/controllers/gce/loadbalancers"
)

View file

@ -21,10 +21,10 @@ import (
"testing"
"time"
api_v1 "k8s.io/api/core/v1"
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/intstr"
"k8s.io/apimachinery/pkg/util/sets"
api_v1 "k8s.io/client-go/pkg/api/v1"
"k8s.io/ingress/controllers/gce/backends"
"k8s.io/ingress/controllers/gce/utils"
)
@ -76,20 +76,19 @@ func TestInstancesAddedToZones(t *testing.T) {
lbc.CloudClusterManager.instancePool.Sync([]string{"n1", "n2", "n3"})
gotZonesToNode := cm.fakeIGs.GetInstancesByZone()
i := 0
if cm.fakeIGs.Ports[0] != testPort {
t.Errorf("Expected the same node port on all igs, got ports %+v", cm.fakeIGs.Ports)
}
for z, nodeNames := range zoneToNode {
if ig, err := cm.fakeIGs.GetInstanceGroup(testIG, z); err != nil {
t.Errorf("Failed to find ig %v in zone %v, found %+v: %v", testIG, z, ig, err)
}
if cm.fakeIGs.Ports[i] != testPort {
t.Errorf("Expected the same node port on all igs, got ports %+v", cm.fakeIGs.Ports)
}
expNodes := sets.NewString(nodeNames...)
gotNodes := sets.NewString(gotZonesToNode[z]...)
if !gotNodes.Equal(expNodes) {
t.Errorf("Nodes not added to zones, expected %+v got %+v", expNodes, gotNodes)
}
i++
}
}

View file

@ -26,6 +26,8 @@ import (
"github.com/golang/glog"
compute "google.golang.org/api/compute/v1"
api_v1 "k8s.io/api/core/v1"
extensions "k8s.io/api/extensions/v1beta1"
"k8s.io/apimachinery/pkg/api/meta"
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
@ -34,8 +36,6 @@ import (
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/apimachinery/pkg/util/wait"
listers "k8s.io/client-go/listers/core/v1"
api_v1 "k8s.io/client-go/pkg/api/v1"
extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1"
"k8s.io/client-go/tools/cache"
"k8s.io/client-go/util/workqueue"
@ -595,8 +595,8 @@ func (t *GCETranslator) getHTTPProbe(svc api_v1.Service, targetPort intstr.IntOr
// - has no special host or headers fields, except for possibly an HTTP Host header
func isSimpleHTTPProbe(probe *api_v1.Probe) bool {
return (probe != nil && probe.Handler.HTTPGet != nil && probe.Handler.HTTPGet.Host == "" &&
(len(probe.Handler.HTTPGet.HTTPHeaders) == 0 ||
(len(probe.Handler.HTTPGet.HTTPHeaders) == 1 && probe.Handler.HTTPGet.HTTPHeaders[0].Name == "Host")))
(len(probe.Handler.HTTPGet.HTTPHeaders) == 0 ||
(len(probe.Handler.HTTPGet.HTTPHeaders) == 1 && probe.Handler.HTTPGet.HTTPHeaders[0].Name == "Host")))
}
// GetProbe returns a probe that's used for the given nodeport

View file

@ -26,13 +26,13 @@ import (
"io/ioutil"
"log"
api_v1 "k8s.io/api/core/v1"
registered "k8s.io/apimachinery/pkg/apimachinery/registered"
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/client-go/pkg/api"
api_v1 "k8s.io/client-go/pkg/api/v1"
// This installs the legacy v1 API
"k8s.io/kubernetes/pkg/api"
_ "k8s.io/kubernetes/pkg/api/install"
)

View file

@ -18,86 +18,66 @@ package firewalls
import (
"fmt"
"strconv"
compute "google.golang.org/api/compute/v1"
netset "k8s.io/kubernetes/pkg/util/net/sets"
"k8s.io/ingress/controllers/gce/utils"
)
type fakeFirewallsProvider struct {
fw map[string]*compute.Firewall
namer *utils.Namer
fw map[string]*compute.Firewall
networkUrl string
}
// NewFakeFirewallsProvider creates a fake for firewall rules.
func NewFakeFirewallsProvider(namer *utils.Namer) *fakeFirewallsProvider {
func NewFakeFirewallsProvider() *fakeFirewallsProvider {
return &fakeFirewallsProvider{
fw: make(map[string]*compute.Firewall),
namer: namer,
fw: make(map[string]*compute.Firewall),
}
}
func (f *fakeFirewallsProvider) GetFirewall(prefixedName string) (*compute.Firewall, error) {
rule, exists := f.fw[prefixedName]
func (ff *fakeFirewallsProvider) GetFirewall(name string) (*compute.Firewall, error) {
rule, exists := ff.fw[name]
if exists {
return rule, nil
}
return nil, utils.FakeGoogleAPINotFoundErr()
}
func (f *fakeFirewallsProvider) CreateFirewall(name, msgTag string, srcRange netset.IPNet, ports []int64, hosts []string) error {
prefixedName := f.namer.FrName(name)
strPorts := []string{}
for _, p := range ports {
strPorts = append(strPorts, strconv.FormatInt(p, 10))
}
if _, exists := f.fw[prefixedName]; exists {
return fmt.Errorf("firewall rule %v already exists", prefixedName)
}
f.fw[prefixedName] = &compute.Firewall{
// To accurately mimic the cloudprovider we need to add the k8s-fw
// prefix to the given rule name.
Name: prefixedName,
SourceRanges: srcRange.StringSlice(),
Allowed: []*compute.FirewallAllowed{{Ports: strPorts}},
TargetTags: hosts, // WARNING: This is actually not correct, but good enough for testing this package
func (ff *fakeFirewallsProvider) CreateFirewall(f *compute.Firewall) error {
if _, exists := ff.fw[f.Name]; exists {
return fmt.Errorf("firewall rule %v already exists", f.Name)
}
ff.fw[f.Name] = f
return nil
}
func (f *fakeFirewallsProvider) DeleteFirewall(name string) error {
func (ff *fakeFirewallsProvider) DeleteFirewall(name string) error {
// We need the full name for the same reason as CreateFirewall.
prefixedName := f.namer.FrName(name)
_, exists := f.fw[prefixedName]
_, exists := ff.fw[name]
if !exists {
return utils.FakeGoogleAPINotFoundErr()
}
delete(f.fw, prefixedName)
delete(ff.fw, name)
return nil
}
func (f *fakeFirewallsProvider) UpdateFirewall(name, msgTag string, srcRange netset.IPNet, ports []int64, hosts []string) error {
strPorts := []string{}
for _, p := range ports {
strPorts = append(strPorts, strconv.FormatInt(p, 10))
}
func (ff *fakeFirewallsProvider) UpdateFirewall(f *compute.Firewall) error {
// We need the full name for the same reason as CreateFirewall.
prefixedName := f.namer.FrName(name)
_, exists := f.fw[prefixedName]
_, exists := ff.fw[f.Name]
if !exists {
return fmt.Errorf("update failed for rule %v, srcRange %v ports %v, rule not found", prefixedName, srcRange, ports)
return fmt.Errorf("update failed for rule %v, srcRange %v ports %+v, rule not found", f.Name, f.SourceRanges, f.Allowed)
}
f.fw[prefixedName] = &compute.Firewall{
Name: name,
SourceRanges: srcRange.StringSlice(),
Allowed: []*compute.FirewallAllowed{{Ports: strPorts}},
TargetTags: hosts, // WARNING: This is actually not correct, but good enough for testing this package
}
ff.fw[f.Name] = f
return nil
}
func (ff *fakeFirewallsProvider) NetworkURL() string {
return ff.networkUrl
}
func (ff *fakeFirewallsProvider) GetNodeTags(nodeNames []string) ([]string, error) {
return nodeNames, nil
}

View file

@ -35,18 +35,18 @@ var l7SrcRanges = []string{"130.211.0.0/22", "35.191.0.0/16"}
type FirewallRules struct {
cloud Firewall
namer *utils.Namer
srcRanges netset.IPNet
srcRanges []string
}
// NewFirewallPool creates a new firewall rule manager.
// cloud: the cloud object implementing Firewall.
// namer: cluster namer.
func NewFirewallPool(cloud Firewall, namer *utils.Namer) SingleFirewallPool {
srcNetSet, err := netset.ParseIPNets(l7SrcRanges...)
_, err := netset.ParseIPNets(l7SrcRanges...)
if err != nil {
glog.Fatalf("Could not parse L7 src ranges %v for firewall rule: %v", l7SrcRanges, err)
}
return &FirewallRules{cloud: cloud, namer: namer, srcRanges: srcNetSet}
return &FirewallRules{cloud: cloud, namer: namer, srcRanges: l7SrcRanges}
}
// Sync sync firewall rules with the cloud.
@ -60,9 +60,15 @@ func (fr *FirewallRules) Sync(nodePorts []int64, nodeNames []string) error {
// instead of the whole name.
name := fr.namer.FrName(suffix)
rule, _ := fr.cloud.GetFirewall(name)
firewall, err := fr.createFirewallObject(name, "GCE L7 firewall rule", nodePorts, nodeNames)
if err != nil {
return err
}
if rule == nil {
glog.Infof("Creating global l7 firewall rule %v", name)
return fr.cloud.CreateFirewall(suffix, "GCE L7 firewall rule", fr.srcRanges, nodePorts, nodeNames)
return fr.cloud.CreateFirewall(firewall)
}
requiredPorts := sets.NewString()
@ -85,17 +91,17 @@ func (fr *FirewallRules) Sync(nodePorts []int64, nodeNames []string) error {
glog.V(4).Info("Firewall does not need update of ports or source ranges")
return nil
}
glog.V(3).Infof("Firewall %v already exists, updating nodeports %v", name, nodePorts)
return fr.cloud.UpdateFirewall(suffix, "GCE L7 firewall", fr.srcRanges, nodePorts, nodeNames)
return fr.cloud.UpdateFirewall(firewall)
}
// Shutdown shuts down this firewall rules manager.
func (fr *FirewallRules) Shutdown() error {
glog.Infof("Deleting firewall with suffix %v", fr.namer.FrSuffix())
err := fr.cloud.DeleteFirewall(fr.namer.FrSuffix())
name := fr.namer.FrName(fr.namer.FrSuffix())
glog.Infof("Deleting firewall %v", name)
err := fr.cloud.DeleteFirewall(name)
if err != nil && utils.IsHTTPErrorCode(err, 404) {
glog.Infof("Firewall with suffix %v didn't exist at Shutdown", fr.namer.FrSuffix())
glog.Infof("Firewall with name %v didn't exist at Shutdown", name)
return nil
}
return err
@ -107,3 +113,31 @@ func (fr *FirewallRules) Shutdown() error {
func (fr *FirewallRules) GetFirewall(name string) (*compute.Firewall, error) {
return fr.cloud.GetFirewall(name)
}
func (fr *FirewallRules) createFirewallObject(firewallName, description string, nodePorts []int64, nodeNames []string) (*compute.Firewall, error) {
ports := make([]string, len(nodePorts))
for ix := range nodePorts {
ports[ix] = strconv.Itoa(int(nodePorts[ix]))
}
// If the node tags to be used for this cluster have been predefined in the
// provider config, just use them. Otherwise, invoke computeHostTags method to get the tags.
targetTags, err := fr.cloud.GetNodeTags(nodeNames)
if err != nil {
return nil, err
}
return &compute.Firewall{
Name: firewallName,
Description: description,
SourceRanges: fr.srcRanges,
Network: fr.cloud.NetworkURL(),
Allowed: []*compute.FirewallAllowed{
{
IPProtocol: "tcp",
Ports: ports,
},
},
TargetTags: targetTags,
}, nil
}

View file

@ -22,14 +22,11 @@ import (
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/ingress/controllers/gce/utils"
netset "k8s.io/kubernetes/pkg/util/net/sets"
)
const allCIDR = "0.0.0.0/0"
func TestSyncFirewallPool(t *testing.T) {
namer := utils.NewNamer("ABC", "XYZ")
fwp := NewFakeFirewallsProvider(namer)
fwp := NewFakeFirewallsProvider()
fp := NewFirewallPool(fwp, namer)
ruleName := namer.FrName(namer.FrSuffix())
@ -50,12 +47,16 @@ func TestSyncFirewallPool(t *testing.T) {
}
verifyFirewallRule(fwp, ruleName, nodePorts, nodes, l7SrcRanges, t)
srcRanges, _ := netset.ParseIPNets(allCIDR)
err = fwp.UpdateFirewall(namer.FrSuffix(), "", srcRanges, nodePorts, nodes)
firewall, err := fp.(*FirewallRules).createFirewallObject(namer.FrName(namer.FrSuffix()), "", nodePorts, nodes)
if err != nil {
t.Errorf("unexpected err when creating firewall object, err: %v", err)
}
err = fwp.UpdateFirewall(firewall)
if err != nil {
t.Errorf("failed to update firewall rule, err: %v", err)
}
verifyFirewallRule(fwp, ruleName, nodePorts, nodes, []string{allCIDR}, t)
verifyFirewallRule(fwp, ruleName, nodePorts, nodes, l7SrcRanges, t)
// Run Sync and expect l7 src ranges to be returned
err = fp.Sync(nodePorts, nodes)

View file

@ -18,7 +18,6 @@ package firewalls
import (
compute "google.golang.org/api/compute/v1"
netset "k8s.io/kubernetes/pkg/util/net/sets"
)
// SingleFirewallPool syncs the firewall rule for L7 traffic.
@ -32,8 +31,10 @@ type SingleFirewallPool interface {
// This interface is a little different from the rest because it dovetails into
// the same firewall methods used by the TCPLoadBalancer.
type Firewall interface {
CreateFirewall(name, msgTag string, srcRange netset.IPNet, ports []int64, hosts []string) error
CreateFirewall(f *compute.Firewall) error
GetFirewall(name string) (*compute.Firewall, error)
DeleteFirewall(name string) error
UpdateFirewall(name, msgTag string, srcRange netset.IPNet, ports []int64, hosts []string) error
UpdateFirewall(f *compute.Firewall) error
GetNodeTags(nodeNames []string) ([]string, error)
NetworkURL() string
}

View file

@ -18,6 +18,7 @@ package instances
import (
"fmt"
"strings"
compute "google.golang.org/api/compute/v1"
"k8s.io/apimachinery/pkg/util/sets"
@ -110,7 +111,8 @@ func (f *FakeInstanceGroups) ListInstancesInInstanceGroup(name, zone string, sta
}
// AddInstancesToInstanceGroup fakes adding instances to an instance group.
func (f *FakeInstanceGroups) AddInstancesToInstanceGroup(name, zone string, instanceNames []string) error {
func (f *FakeInstanceGroups) AddInstancesToInstanceGroup(name, zone string, instanceRefs []*compute.InstanceReference) error {
instanceNames := toInstanceNames(instanceRefs)
f.calls = append(f.calls, utils.AddInstances)
f.instances.Insert(instanceNames...)
if _, ok := f.zonesToInstances[zone]; !ok {
@ -126,7 +128,8 @@ func (f *FakeInstanceGroups) GetInstancesByZone() map[string][]string {
}
// RemoveInstancesFromInstanceGroup fakes removing instances from an instance group.
func (f *FakeInstanceGroups) RemoveInstancesFromInstanceGroup(name, zone string, instanceNames []string) error {
func (f *FakeInstanceGroups) RemoveInstancesFromInstanceGroup(name, zone string, instanceRefs []*compute.InstanceReference) error {
instanceNames := toInstanceNames(instanceRefs)
f.calls = append(f.calls, utils.RemoveInstances)
f.instances.Delete(instanceNames...)
l, ok := f.zonesToInstances[zone]
@ -145,10 +148,23 @@ func (f *FakeInstanceGroups) RemoveInstancesFromInstanceGroup(name, zone string,
return nil
}
// AddPortToInstanceGroup fakes adding ports to an Instance Group.
func (f *FakeInstanceGroups) AddPortToInstanceGroup(ig *compute.InstanceGroup, port int64) (*compute.NamedPort, error) {
f.Ports = append(f.Ports, port)
return &compute.NamedPort{Name: f.namer.BeName(port), Port: port}, nil
func (f *FakeInstanceGroups) SetNamedPortsOfInstanceGroup(igName, zone string, namedPorts []*compute.NamedPort) error {
found := false
for _, ig := range f.instanceGroups {
if ig.Name == igName && ig.Zone == zone {
found = true
break
}
}
if !found {
return fmt.Errorf("Failed to find instance group %q in zone %q", igName, zone)
}
f.Ports = f.Ports[:0]
for _, port := range namedPorts {
f.Ports = append(f.Ports, port.Port)
}
return nil
}
// getInstanceList returns an instance list based on the given names.
@ -157,9 +173,7 @@ func getInstanceList(nodeNames sets.String) *compute.InstanceGroupsListInstances
instanceNames := nodeNames.List()
computeInstances := []*compute.InstanceWithNamedPorts{}
for _, name := range instanceNames {
instanceLink := fmt.Sprintf(
"https://www.googleapis.com/compute/v1/projects/%s/zones/%s/instances/%s",
"project", "zone", name)
instanceLink := getInstanceUrl(name)
computeInstances = append(
computeInstances, &compute.InstanceWithNamedPorts{
Instance: instanceLink})
@ -168,3 +182,26 @@ func getInstanceList(nodeNames sets.String) *compute.InstanceGroupsListInstances
Items: computeInstances,
}
}
func (f *FakeInstanceGroups) ToInstanceReferences(zone string, instanceNames []string) (refs []*compute.InstanceReference) {
for _, ins := range instanceNames {
instanceLink := getInstanceUrl(ins)
refs = append(refs, &compute.InstanceReference{Instance: instanceLink})
}
return refs
}
func getInstanceUrl(instanceName string) string {
return fmt.Sprintf("https://www.googleapis.com/compute/v1/projects/%s/zones/%s/instances/%s",
"project", "zone", instanceName)
}
func toInstanceNames(instanceRefs []*compute.InstanceReference) []string {
instanceNames := make([]string, len(instanceRefs))
for ix := range instanceRefs {
url := instanceRefs[ix].Instance
parts := strings.Split(url, "/")
instanceNames[ix] = parts[len(parts)-1]
}
return instanceNames
}

View file

@ -63,13 +63,15 @@ func (i *Instances) Init(zl zoneLister) {
// all of which have the exact same named port.
func (i *Instances) AddInstanceGroup(name string, port int64) ([]*compute.InstanceGroup, *compute.NamedPort, error) {
igs := []*compute.InstanceGroup{}
namedPort := &compute.NamedPort{}
// TODO: move port naming to namer
namedPort := &compute.NamedPort{Name: fmt.Sprintf("port%v", port), Port: port}
zones, err := i.ListZones()
if err != nil {
return igs, namedPort, err
}
defer i.snapshotter.Add(name, struct{}{})
for _, zone := range zones {
ig, _ := i.Get(name, zone)
var err error
@ -82,10 +84,19 @@ func (i *Instances) AddInstanceGroup(name string, port int64) ([]*compute.Instan
} else {
glog.V(3).Infof("Instance group %v already exists in zone %v, adding port %d to it", name, zone, port)
}
defer i.snapshotter.Add(name, struct{}{})
namedPort, err = i.cloud.AddPortToInstanceGroup(ig, port)
if err != nil {
return nil, nil, err
found := false
for _, np := range ig.NamedPorts {
if np.Port == port {
glog.V(3).Infof("Instance group %v already has named port %+v", ig.Name, np)
found = true
break
}
}
if !found {
if err := i.cloud.SetNamedPortsOfInstanceGroup(ig.Name, zone, append(ig.NamedPorts, namedPort)); err != nil {
return nil, nil, err
}
}
igs = append(igs, ig)
}
@ -173,7 +184,7 @@ func (i *Instances) Add(groupName string, names []string) error {
errs := []error{}
for zone, nodeNames := range i.splitNodesByZone(names) {
glog.V(1).Infof("Adding nodes %v to %v in zone %v", nodeNames, groupName, zone)
if err := i.cloud.AddInstancesToInstanceGroup(groupName, zone, nodeNames); err != nil {
if err := i.cloud.AddInstancesToInstanceGroup(groupName, zone, i.cloud.ToInstanceReferences(zone, nodeNames)); err != nil {
errs = append(errs, err)
}
}
@ -187,8 +198,8 @@ func (i *Instances) Add(groupName string, names []string) error {
func (i *Instances) Remove(groupName string, names []string) error {
errs := []error{}
for zone, nodeNames := range i.splitNodesByZone(names) {
glog.V(1).Infof("Adding nodes %v to %v in zone %v", nodeNames, groupName, zone)
if err := i.cloud.RemoveInstancesFromInstanceGroup(groupName, zone, nodeNames); err != nil {
glog.V(1).Infof("Removing nodes %v from %v in zone %v", nodeNames, groupName, zone)
if err := i.cloud.RemoveInstancesFromInstanceGroup(groupName, zone, i.cloud.ToInstanceReferences(zone, nodeNames)); err != nil {
errs = append(errs, err)
}
}

View file

@ -50,7 +50,8 @@ type InstanceGroups interface {
// TODO: Refactor for modulatiry.
ListInstancesInInstanceGroup(name, zone string, state string) (*compute.InstanceGroupsListInstances, error)
AddInstancesToInstanceGroup(name, zone string, instanceNames []string) error
RemoveInstancesFromInstanceGroup(name, zone string, instanceName []string) error
AddPortToInstanceGroup(ig *compute.InstanceGroup, port int64) (*compute.NamedPort, error)
AddInstancesToInstanceGroup(name, zone string, instanceRefs []*compute.InstanceReference) error
RemoveInstancesFromInstanceGroup(name, zone string, instanceRefs []*compute.InstanceReference) error
ToInstanceReferences(zone string, instanceNames []string) (refs []*compute.InstanceReference)
SetNamedPortsOfInstanceGroup(igName, zone string, namedPorts []*compute.NamedPort) error
}

View file

@ -132,10 +132,10 @@ func (f *FakeLoadBalancers) CreateGlobalForwardingRule(proxyLink, ip, name, port
}
// SetProxyForGlobalForwardingRule fakes setting a global forwarding rule.
func (f *FakeLoadBalancers) SetProxyForGlobalForwardingRule(fw *compute.ForwardingRule, proxyLink string) error {
func (f *FakeLoadBalancers) SetProxyForGlobalForwardingRule(forwardingRuleName, proxyLink string) error {
f.calls = append(f.calls, "SetProxyForGlobalForwardingRule")
for i := range f.Fw {
if f.Fw[i].Name == fw.Name {
if f.Fw[i].Name == forwardingRuleName {
f.Fw[i].Target = proxyLink
}
}
@ -397,20 +397,16 @@ func (f *FakeLoadBalancers) CheckURLMap(t *testing.T, l7 *L7, expectedMap map[st
// Static IP fakes
// ReserveGlobalStaticIP fakes out static IP reservation.
func (f *FakeLoadBalancers) ReserveGlobalStaticIP(name, IPAddress string) (*compute.Address, error) {
f.calls = append(f.calls, "ReserveGlobalStaticIP")
ip := &compute.Address{
Name: name,
Address: IPAddress,
}
f.IP = append(f.IP, ip)
return ip, nil
// ReserveGlobalAddress fakes out static IP reservation.
func (f *FakeLoadBalancers) ReserveGlobalAddress(addr *compute.Address) error {
f.calls = append(f.calls, "ReserveGlobalAddress")
f.IP = append(f.IP, addr)
return nil
}
// GetGlobalStaticIP fakes out static IP retrieval.
func (f *FakeLoadBalancers) GetGlobalStaticIP(name string) (*compute.Address, error) {
f.calls = append(f.calls, "GetGlobalStaticIP")
// GetGlobalAddress fakes out static IP retrieval.
func (f *FakeLoadBalancers) GetGlobalAddress(name string) (*compute.Address, error) {
f.calls = append(f.calls, "GetGlobalAddress")
for i := range f.IP {
if f.IP[i].Name == name {
return f.IP[i], nil
@ -419,9 +415,9 @@ func (f *FakeLoadBalancers) GetGlobalStaticIP(name string) (*compute.Address, er
return nil, fmt.Errorf("static IP %v not found", name)
}
// DeleteGlobalStaticIP fakes out static IP deletion.
func (f *FakeLoadBalancers) DeleteGlobalStaticIP(name string) error {
f.calls = append(f.calls, "DeleteGlobalStaticIP")
// DeleteGlobalAddress fakes out static IP deletion.
func (f *FakeLoadBalancers) DeleteGlobalAddress(name string) error {
f.calls = append(f.calls, "DeleteGlobalAddress")
ip := []*compute.Address{}
for i := range f.IP {
if f.IP[i].Name != name {

View file

@ -30,7 +30,7 @@ type LoadBalancers interface {
GetGlobalForwardingRule(name string) (*compute.ForwardingRule, error)
CreateGlobalForwardingRule(proxyLink, ip, name, portRange string) (*compute.ForwardingRule, error)
DeleteGlobalForwardingRule(name string) error
SetProxyForGlobalForwardingRule(fw *compute.ForwardingRule, proxy string) error
SetProxyForGlobalForwardingRule(fw, proxy string) error
// UrlMaps
GetUrlMap(name string) (*compute.UrlMap, error)
@ -57,9 +57,10 @@ type LoadBalancers interface {
DeleteSslCertificate(name string) error
// Static IP
ReserveGlobalStaticIP(name, IPAddress string) (*compute.Address, error)
GetGlobalStaticIP(name string) (*compute.Address, error)
DeleteGlobalStaticIP(name string) error
ReserveGlobalAddress(addr *compute.Address) error
GetGlobalAddress(name string) (*compute.Address, error)
DeleteGlobalAddress(name string) error
}
// LoadBalancerPool is an interface to manage the cloud resources associated

View file

@ -544,7 +544,7 @@ func (l *L7) checkForwardingRule(name, proxyLink, ip, portRange string) (fw *com
} else {
glog.Infof("Forwarding rule %v has the wrong proxy, setting %v overwriting %v",
fw.Name, fw.Target, proxyLink)
if err := l.cloud.SetProxyForGlobalForwardingRule(fw, proxyLink); err != nil {
if err := l.cloud.SetProxyForGlobalForwardingRule(fw.Name, proxyLink); err != nil {
return nil, err
}
}
@ -576,7 +576,7 @@ func (l *L7) getEffectiveIP() (string, bool) {
if l.runtimeInfo.StaticIPName != "" {
// Existing static IPs allocated to forwarding rules will get orphaned
// till the Ingress is torn down.
if ip, err := l.cloud.GetGlobalStaticIP(l.runtimeInfo.StaticIPName); err != nil || ip == nil {
if ip, err := l.cloud.GetGlobalAddress(l.runtimeInfo.StaticIPName); err != nil || ip == nil {
glog.Warningf("The given static IP name %v doesn't translate to an existing global static IP, ignoring it and allocating a new IP: %v",
l.runtimeInfo.StaticIPName, err)
} else {
@ -629,10 +629,10 @@ func (l *L7) checkStaticIP() (err error) {
return nil
}
staticIPName := l.namer.Truncate(fmt.Sprintf("%v-%v", forwardingRulePrefix, l.Name))
ip, _ := l.cloud.GetGlobalStaticIP(staticIPName)
ip, _ := l.cloud.GetGlobalAddress(staticIPName)
if ip == nil {
glog.Infof("Creating static ip %v", staticIPName)
ip, err = l.cloud.ReserveGlobalStaticIP(staticIPName, l.fw.IPAddress)
err = l.cloud.ReserveGlobalAddress(&compute.Address{Name: staticIPName, Address: l.fw.IPAddress})
if err != nil {
if utils.IsHTTPErrorCode(err, http.StatusConflict) ||
utils.IsHTTPErrorCode(err, http.StatusBadRequest) {
@ -642,6 +642,10 @@ func (l *L7) checkStaticIP() (err error) {
}
return err
}
ip, err = l.cloud.GetGlobalAddress(staticIPName)
if err != nil {
return err
}
}
l.ip = ip
return nil
@ -903,7 +907,7 @@ func (l *L7) Cleanup() error {
}
if l.ip != nil {
glog.V(2).Infof("Deleting static IP %v(%v)", l.ip.Name, l.ip.Address)
if err := utils.IgnoreHTTPNotFound(l.cloud.DeleteGlobalStaticIP(l.ip.Name)); err != nil {
if err := utils.IgnoreHTTPNotFound(l.cloud.DeleteGlobalAddress(l.ip.Name)); err != nil {
return err
}
l.ip = nil

View file

@ -289,7 +289,7 @@ func TestCreateBothLoadBalancers(t *testing.T) {
if err != nil || fw.Target != tp.SelfLink {
t.Fatalf("%v", err)
}
ip, err := f.GetGlobalStaticIP(f.fwName(false))
ip, err := f.GetGlobalAddress(f.fwName(false))
if err != nil || ip.Address != fw.IPAddress || ip.Address != fws.IPAddress {
t.Fatalf("%v", err)
}

View file

@ -30,14 +30,13 @@ import (
"github.com/prometheus/client_golang/prometheus/promhttp"
flag "github.com/spf13/pflag"
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/intstr"
"k8s.io/apimachinery/pkg/util/wait"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/pkg/api"
api_v1 "k8s.io/client-go/pkg/api/v1"
"k8s.io/client-go/rest"
"k8s.io/client-go/tools/clientcmd"
clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
@ -122,7 +121,7 @@ var (
`Path used to health-check a backend service. All Services must serve
a 200 page on this path. Currently this is only configurable globally.`)
watchNamespace = flags.String("watch-namespace", api.NamespaceAll,
watchNamespace = flags.String("watch-namespace", v1.NamespaceAll,
`Namespace to watch for Ingress/Services/Endpoints.`)
verbose = flags.Bool("verbose", false,
@ -287,7 +286,7 @@ func newNamer(kubeClient kubernetes.Interface, clusterName string, fwName string
}
namer := utils.NewNamer(name, fw_name)
uidVault := storage.NewConfigMapVault(kubeClient, api.NamespaceSystem, uidConfigMapName)
uidVault := storage.NewConfigMapVault(kubeClient, metav1.NamespaceSystem, uidConfigMapName)
// Start a goroutine to poll the cluster UID config map
// We don't watch because we know exactly which configmap we want and this
@ -359,7 +358,7 @@ func useDefaultOrLookupVault(cfgVault *storage.ConfigMapVault, cm_key, default_n
// Use getFlagOrLookupVault to obtain a stored or overridden value for the firewall name.
// else, use the cluster UID as a backup (this retains backwards compatibility).
func getFirewallName(kubeClient kubernetes.Interface, name, cluster_uid string) (string, error) {
cfgVault := storage.NewConfigMapVault(kubeClient, api.NamespaceSystem, uidConfigMapName)
cfgVault := storage.NewConfigMapVault(kubeClient, metav1.NamespaceSystem, uidConfigMapName)
if fw_name, err := useDefaultOrLookupVault(cfgVault, storage.ProviderDataKey, name); err != nil {
return "", err
} else if fw_name != "" {
@ -377,7 +376,7 @@ func getFirewallName(kubeClient kubernetes.Interface, name, cluster_uid string)
// - remember that "" is the cluster uid
// else, allocate a new uid
func getClusterUID(kubeClient kubernetes.Interface, name string) (string, error) {
cfgVault := storage.NewConfigMapVault(kubeClient, api.NamespaceSystem, uidConfigMapName)
cfgVault := storage.NewConfigMapVault(kubeClient, metav1.NamespaceSystem, uidConfigMapName)
if name, err := useDefaultOrLookupVault(cfgVault, storage.UidDataKey, name); err != nil {
return "", err
} else if name != "" {
@ -385,7 +384,7 @@ func getClusterUID(kubeClient kubernetes.Interface, name string) (string, error)
}
// Check if the cluster has an Ingress with ip
ings, err := kubeClient.Extensions().Ingresses(api.NamespaceAll).List(meta_v1.ListOptions{
ings, err := kubeClient.Extensions().Ingresses(metav1.NamespaceAll).List(metav1.ListOptions{
LabelSelector: labels.Everything().String(),
})
if err != nil {
@ -419,10 +418,10 @@ func getClusterUID(kubeClient kubernetes.Interface, name string) (string, error)
// getNodePort waits for the Service, and returns it's first node port.
func getNodePort(client kubernetes.Interface, ns, name string) (port, nodePort int32, err error) {
var svc *api_v1.Service
var svc *v1.Service
glog.V(3).Infof("Waiting for %v/%v", ns, name)
wait.Poll(1*time.Second, 5*time.Minute, func() (bool, error) {
svc, err = client.Core().Services(ns).Get(name, meta_v1.GetOptions{})
svc, err = client.Core().Services(ns).Get(name, metav1.GetOptions{})
if err != nil {
return false, nil
}

View file

@ -23,10 +23,10 @@ import (
"github.com/golang/glog"
api_v1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
api_v1 "k8s.io/client-go/pkg/api/v1"
"k8s.io/client-go/tools/cache"
)

View file

@ -19,7 +19,7 @@ package storage
import (
"testing"
"k8s.io/client-go/pkg/api"
api "k8s.io/apimachinery/pkg/apis/meta/v1"
)
func TestConfigMapUID(t *testing.T) {

View file

@ -34,7 +34,7 @@ import (
"github.com/spf13/pflag"
proxyproto "github.com/armon/go-proxyproto"
api_v1 "k8s.io/client-go/pkg/api/v1"
api_v1 "k8s.io/api/core/v1"
"k8s.io/ingress/controllers/nginx/pkg/config"
ngx_template "k8s.io/ingress/controllers/nginx/pkg/template"

View file

@ -335,39 +335,39 @@ func NewDefault() Configuration {
HTTP2MaxFieldSize: "4k",
HTTP2MaxHeaderSize: "16k",
HSTS: true,
HSTSIncludeSubdomains: true,
HSTSMaxAge: hstsMaxAge,
HSTSPreload: false,
IgnoreInvalidHeaders: true,
GzipTypes: gzipTypes,
KeepAlive: 75,
KeepAliveRequests: 100,
LargeClientHeaderBuffers: "4 8k",
LogFormatEscapeJSON: false,
LogFormatStream: logFormatStream,
LogFormatUpstream: logFormatUpstream,
MaxWorkerConnections: 16384,
MapHashBucketSize: 64,
ProxyRealIPCIDR: defIPCIDR,
ServerNameHashMaxSize: 1024,
ProxyHeadersHashMaxSize: 512,
HSTSIncludeSubdomains: true,
HSTSMaxAge: hstsMaxAge,
HSTSPreload: false,
IgnoreInvalidHeaders: true,
GzipTypes: gzipTypes,
KeepAlive: 75,
KeepAliveRequests: 100,
LargeClientHeaderBuffers: "4 8k",
LogFormatEscapeJSON: false,
LogFormatStream: logFormatStream,
LogFormatUpstream: logFormatUpstream,
MaxWorkerConnections: 16384,
MapHashBucketSize: 64,
ProxyRealIPCIDR: defIPCIDR,
ServerNameHashMaxSize: 1024,
ProxyHeadersHashMaxSize: 512,
ProxyHeadersHashBucketSize: 64,
ShowServerTokens: true,
SSLBufferSize: sslBufferSize,
SSLCiphers: sslCiphers,
SSLECDHCurve: "secp384r1",
SSLProtocols: sslProtocols,
SSLSessionCache: true,
SSLSessionCacheSize: sslSessionCacheSize,
SSLSessionTickets: true,
SSLSessionTimeout: sslSessionTimeout,
UseGzip: true,
WorkerProcesses: strconv.Itoa(runtime.NumCPU()),
LoadBalanceAlgorithm: defaultLoadBalancerAlgorithm,
VtsStatusZoneSize: "10m",
VariablesHashBucketSize: 64,
VariablesHashMaxSize: 2048,
UseHTTP2: true,
ShowServerTokens: true,
SSLBufferSize: sslBufferSize,
SSLCiphers: sslCiphers,
SSLECDHCurve: "secp384r1",
SSLProtocols: sslProtocols,
SSLSessionCache: true,
SSLSessionCacheSize: sslSessionCacheSize,
SSLSessionTickets: true,
SSLSessionTimeout: sslSessionTimeout,
UseGzip: true,
WorkerProcesses: strconv.Itoa(runtime.NumCPU()),
LoadBalanceAlgorithm: defaultLoadBalancerAlgorithm,
VtsStatusZoneSize: "10m",
VariablesHashBucketSize: 64,
VariablesHashMaxSize: 2048,
UseHTTP2: true,
Backend: defaults.Backend{
ProxyBodySize: bodySize,
ProxyConnectTimeout: 5,

View file

@ -24,8 +24,8 @@ import (
"regexp"
"github.com/pkg/errors"
api "k8s.io/client-go/pkg/api/v1"
extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1"
api "k8s.io/api/core/v1"
extensions "k8s.io/api/extensions/v1beta1"
"k8s.io/ingress/core/pkg/ingress/annotations/parser"
ing_errors "k8s.io/ingress/core/pkg/ingress/errors"

View file

@ -25,10 +25,10 @@ import (
"github.com/pkg/errors"
api "k8s.io/api/core/v1"
extensions "k8s.io/api/extensions/v1beta1"
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/intstr"
api "k8s.io/client-go/pkg/api/v1"
extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1"
)
func buildIngress() *extensions.Ingress {

View file

@ -21,7 +21,7 @@ import (
"regexp"
"strings"
extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1"
extensions "k8s.io/api/extensions/v1beta1"
"k8s.io/ingress/core/pkg/ingress/annotations/parser"
ing_errors "k8s.io/ingress/core/pkg/ingress/errors"

View file

@ -21,9 +21,9 @@ import (
"reflect"
"testing"
api "k8s.io/api/core/v1"
extensions "k8s.io/api/extensions/v1beta1"
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
api "k8s.io/client-go/pkg/api/v1"
extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1"
"k8s.io/apimachinery/pkg/util/intstr"
)

View file

@ -18,7 +18,7 @@ package authtls
import (
"github.com/pkg/errors"
extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1"
extensions "k8s.io/api/extensions/v1beta1"
"k8s.io/ingress/core/pkg/ingress/annotations/parser"
ing_errors "k8s.io/ingress/core/pkg/ingress/errors"

View file

@ -19,10 +19,10 @@ package authtls
import (
"testing"
api "k8s.io/api/core/v1"
extensions "k8s.io/api/extensions/v1beta1"
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/intstr"
api "k8s.io/client-go/pkg/api/v1"
extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1"
)
func buildIngress() *extensions.Ingress {

View file

@ -18,7 +18,7 @@ package class
import (
"github.com/golang/glog"
extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1"
extensions "k8s.io/api/extensions/v1beta1"
"k8s.io/ingress/core/pkg/ingress/annotations/parser"
"k8s.io/ingress/core/pkg/ingress/errors"

View file

@ -19,9 +19,9 @@ package class
import (
"testing"
api "k8s.io/api/core/v1"
extensions "k8s.io/api/extensions/v1beta1"
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
api "k8s.io/client-go/pkg/api/v1"
extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1"
)
func TestIsValidClass(t *testing.T) {

View file

@ -17,7 +17,7 @@ limitations under the License.
package cors
import (
extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1"
extensions "k8s.io/api/extensions/v1beta1"
"k8s.io/ingress/core/pkg/ingress/annotations/parser"
)

View file

@ -19,9 +19,9 @@ package cors
import (
"testing"
api "k8s.io/api/core/v1"
extensions "k8s.io/api/extensions/v1beta1"
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
api "k8s.io/client-go/pkg/api/v1"
extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1"
)
const (

View file

@ -17,7 +17,7 @@ limitations under the License.
package healthcheck
import (
extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1"
extensions "k8s.io/api/extensions/v1beta1"
"k8s.io/ingress/core/pkg/ingress/annotations/parser"
"k8s.io/ingress/core/pkg/ingress/resolver"

View file

@ -19,10 +19,10 @@ package healthcheck
import (
"testing"
api "k8s.io/api/core/v1"
extensions "k8s.io/api/extensions/v1beta1"
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/intstr"
api "k8s.io/client-go/pkg/api/v1"
extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1"
"k8s.io/ingress/core/pkg/ingress/defaults"
)

View file

@ -22,7 +22,7 @@ import (
"github.com/pkg/errors"
extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1"
extensions "k8s.io/api/extensions/v1beta1"
"k8s.io/kubernetes/pkg/util/net/sets"
"k8s.io/ingress/core/pkg/ingress/annotations/parser"

View file

@ -20,10 +20,10 @@ import (
"reflect"
"testing"
api "k8s.io/api/core/v1"
extensions "k8s.io/api/extensions/v1beta1"
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/intstr"
api "k8s.io/client-go/pkg/api/v1"
extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1"
"k8s.io/ingress/core/pkg/ingress/defaults"
"k8s.io/ingress/core/pkg/ingress/errors"

View file

@ -19,7 +19,7 @@ package parser
import (
"strconv"
extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1"
extensions "k8s.io/api/extensions/v1beta1"
"k8s.io/ingress/core/pkg/ingress/errors"
)

View file

@ -19,9 +19,9 @@ package parser
import (
"testing"
api "k8s.io/api/core/v1"
extensions "k8s.io/api/extensions/v1beta1"
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
api "k8s.io/client-go/pkg/api/v1"
extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1"
)
func buildIngress() *extensions.Ingress {

View file

@ -17,7 +17,7 @@ limitations under the License.
package portinredirect
import (
extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1"
extensions "k8s.io/api/extensions/v1beta1"
"k8s.io/ingress/core/pkg/ingress/annotations/parser"
"k8s.io/ingress/core/pkg/ingress/resolver"

View file

@ -19,10 +19,10 @@ package portinredirect
import (
"testing"
api "k8s.io/api/core/v1"
extensions "k8s.io/api/extensions/v1beta1"
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/intstr"
api "k8s.io/client-go/pkg/api/v1"
extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1"
"fmt"

View file

@ -17,7 +17,7 @@ limitations under the License.
package proxy
import (
extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1"
extensions "k8s.io/api/extensions/v1beta1"
"k8s.io/ingress/core/pkg/ingress/annotations/parser"
"k8s.io/ingress/core/pkg/ingress/resolver"

View file

@ -19,10 +19,10 @@ package proxy
import (
"testing"
api "k8s.io/api/core/v1"
extensions "k8s.io/api/extensions/v1beta1"
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/intstr"
api "k8s.io/client-go/pkg/api/v1"
extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1"
"k8s.io/ingress/core/pkg/ingress/defaults"
)

View file

@ -19,7 +19,7 @@ package ratelimit
import (
"fmt"
extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1"
extensions "k8s.io/api/extensions/v1beta1"
"k8s.io/ingress/core/pkg/ingress/annotations/parser"
)

View file

@ -19,9 +19,9 @@ package ratelimit
import (
"testing"
api "k8s.io/api/core/v1"
extensions "k8s.io/api/extensions/v1beta1"
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
api "k8s.io/client-go/pkg/api/v1"
extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1"
"k8s.io/apimachinery/pkg/util/intstr"
)

View file

@ -17,7 +17,7 @@ limitations under the License.
package rewrite
import (
extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1"
extensions "k8s.io/api/extensions/v1beta1"
"k8s.io/ingress/core/pkg/ingress/annotations/parser"
"k8s.io/ingress/core/pkg/ingress/resolver"

View file

@ -19,10 +19,10 @@ package rewrite
import (
"testing"
api "k8s.io/api/core/v1"
extensions "k8s.io/api/extensions/v1beta1"
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/intstr"
api "k8s.io/client-go/pkg/api/v1"
extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1"
"k8s.io/ingress/core/pkg/ingress/defaults"
)

View file

@ -20,7 +20,7 @@ import (
"fmt"
"github.com/pkg/errors"
extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1"
extensions "k8s.io/api/extensions/v1beta1"
"k8s.io/ingress/core/pkg/ingress/annotations/parser"
"k8s.io/ingress/core/pkg/ingress/resolver"

View file

@ -19,9 +19,9 @@ package secureupstream
import (
"testing"
api "k8s.io/api/core/v1"
extensions "k8s.io/api/extensions/v1beta1"
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
api "k8s.io/client-go/pkg/api/v1"
extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1"
"fmt"
"k8s.io/apimachinery/pkg/util/intstr"

View file

@ -17,7 +17,7 @@ limitations under the License.
package serviceupstream
import (
extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1"
extensions "k8s.io/api/extensions/v1beta1"
"k8s.io/ingress/core/pkg/ingress/annotations/parser"
)

View file

@ -21,8 +21,8 @@ import (
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/intstr"
api "k8s.io/client-go/pkg/api/v1"
extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1"
api "k8s.io/api/core/v1"
extensions "k8s.io/api/extensions/v1beta1"
)
func buildIngress() *extensions.Ingress {

View file

@ -21,7 +21,7 @@ import (
"github.com/golang/glog"
extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1"
extensions "k8s.io/api/extensions/v1beta1"
"k8s.io/ingress/core/pkg/ingress/annotations/parser"
)

View file

@ -19,10 +19,10 @@ package sessionaffinity
import (
"testing"
api "k8s.io/api/core/v1"
extensions "k8s.io/api/extensions/v1beta1"
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/intstr"
api "k8s.io/client-go/pkg/api/v1"
extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1"
)
func buildIngress() *extensions.Ingress {

View file

@ -17,7 +17,7 @@ limitations under the License.
package snippet
import (
extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1"
extensions "k8s.io/api/extensions/v1beta1"
"k8s.io/ingress/core/pkg/ingress/annotations/parser"
)

View file

@ -19,9 +19,9 @@ package snippet
import (
"testing"
api "k8s.io/api/core/v1"
extensions "k8s.io/api/extensions/v1beta1"
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
api "k8s.io/client-go/pkg/api/v1"
extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1"
)
func TestParse(t *testing.T) {

View file

@ -17,7 +17,7 @@ limitations under the License.
package sslpassthrough
import (
extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1"
extensions "k8s.io/api/extensions/v1beta1"
"k8s.io/ingress/core/pkg/ingress/annotations/parser"
ing_errors "k8s.io/ingress/core/pkg/ingress/errors"

View file

@ -19,9 +19,9 @@ package sslpassthrough
import (
"testing"
api "k8s.io/api/core/v1"
extensions "k8s.io/api/extensions/v1beta1"
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
api "k8s.io/client-go/pkg/api/v1"
extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1"
"k8s.io/apimachinery/pkg/util/intstr"
)

View file

@ -18,7 +18,7 @@ package controller
import (
"github.com/golang/glog"
extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1"
extensions "k8s.io/api/extensions/v1beta1"
"k8s.io/ingress/core/pkg/ingress/annotations/auth"
"k8s.io/ingress/core/pkg/ingress/annotations/authreq"
"k8s.io/ingress/core/pkg/ingress/annotations/authtls"

View file

@ -19,10 +19,10 @@ package controller
import (
"testing"
api "k8s.io/api/core/v1"
extensions "k8s.io/api/extensions/v1beta1"
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/intstr"
api "k8s.io/client-go/pkg/api/v1"
extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1"
"k8s.io/ingress/core/pkg/ingress/defaults"
"k8s.io/ingress/core/pkg/ingress/resolver"

View file

@ -23,8 +23,8 @@ import (
"github.com/golang/glog"
api "k8s.io/client-go/pkg/api/v1"
extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1"
api "k8s.io/api/core/v1"
extensions "k8s.io/api/extensions/v1beta1"
"k8s.io/client-go/tools/cache"
"k8s.io/ingress/core/pkg/ingress"

View file

@ -23,9 +23,9 @@ import (
"fmt"
api_v1 "k8s.io/api/core/v1"
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
testclient "k8s.io/client-go/kubernetes/fake"
api_v1 "k8s.io/client-go/pkg/api/v1"
cache_client "k8s.io/client-go/tools/cache"
"k8s.io/ingress/core/pkg/ingress"
"k8s.io/ingress/core/pkg/ingress/store"

View file

@ -29,14 +29,14 @@ import (
"github.com/golang/glog"
api "k8s.io/api/core/v1"
extensions "k8s.io/api/extensions/v1beta1"
"k8s.io/apimachinery/pkg/fields"
"k8s.io/apimachinery/pkg/util/intstr"
"k8s.io/apimachinery/pkg/util/runtime"
clientset "k8s.io/client-go/kubernetes"
"k8s.io/client-go/kubernetes/scheme"
unversionedcore "k8s.io/client-go/kubernetes/typed/core/v1"
api "k8s.io/client-go/pkg/api/v1"
extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1"
"k8s.io/client-go/tools/cache"
"k8s.io/client-go/tools/record"
"k8s.io/client-go/util/flowcontrol"

View file

@ -14,9 +14,9 @@ import (
"github.com/prometheus/client_golang/prometheus/promhttp"
"github.com/spf13/pflag"
api "k8s.io/api/core/v1"
"k8s.io/apiserver/pkg/server/healthz"
"k8s.io/client-go/kubernetes"
api "k8s.io/client-go/pkg/api/v1"
"k8s.io/client-go/rest"
"k8s.io/client-go/tools/clientcmd"
clientcmd_api "k8s.io/client-go/tools/clientcmd/api"

View file

@ -17,7 +17,7 @@ limitations under the License.
package resolver
import (
api "k8s.io/client-go/pkg/api/v1"
api "k8s.io/api/core/v1"
"k8s.io/ingress/core/pkg/ingress/defaults"
)

View file

@ -1,122 +0,0 @@
/*
Copyright 2015 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package status
import (
"encoding/json"
"os"
"time"
"github.com/golang/glog"
"k8s.io/apimachinery/pkg/api/errors"
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
client "k8s.io/client-go/kubernetes"
"k8s.io/client-go/kubernetes/scheme"
api "k8s.io/client-go/pkg/api/v1"
"k8s.io/client-go/tools/record"
"k8s.io/ingress/core/pkg/ingress/status/leaderelection"
"k8s.io/ingress/core/pkg/ingress/status/leaderelection/resourcelock"
)
func getCurrentLeader(electionID, namespace string, c client.Interface) (string, *api.Endpoints, error) {
endpoints, err := c.Core().Endpoints(namespace).Get(electionID, meta_v1.GetOptions{})
if err != nil {
return "", nil, err
}
val, found := endpoints.Annotations[resourcelock.LeaderElectionRecordAnnotationKey]
if !found {
return "", endpoints, nil
}
electionRecord := resourcelock.LeaderElectionRecord{}
if err = json.Unmarshal([]byte(val), &electionRecord); err != nil {
return "", nil, err
}
return electionRecord.HolderIdentity, endpoints, err
}
// NewElection creates an election. 'namespace'/'election' should be an existing Kubernetes Service
// 'id' is the id if this leader, should be unique.
func NewElection(electionID,
id,
namespace string,
ttl time.Duration,
callback func(leader string),
c client.Interface) (*leaderelection.LeaderElector, error) {
_, err := c.Core().Endpoints(namespace).Get(electionID, meta_v1.GetOptions{})
if err != nil {
if errors.IsNotFound(err) {
_, err = c.Core().Endpoints(namespace).Create(&api.Endpoints{
ObjectMeta: meta_v1.ObjectMeta{
Name: electionID,
},
})
if err != nil && !errors.IsConflict(err) {
return nil, err
}
} else {
return nil, err
}
}
callbacks := leaderelection.LeaderCallbacks{
OnStartedLeading: func(stop <-chan struct{}) {
callback(id)
},
OnStoppedLeading: func() {
leader, _, err := getCurrentLeader(electionID, namespace, c)
if err != nil {
glog.Errorf("failed to get leader: %v", err)
// empty string means leader is unknown
callback("")
return
}
callback(leader)
},
}
broadcaster := record.NewBroadcaster()
hostname, err := os.Hostname()
if err != nil {
return nil, err
}
recorder := broadcaster.NewRecorder(scheme.Scheme, api.EventSource{
Component: "ingress-leader-elector",
Host: hostname,
})
lock := resourcelock.ConfigMapLock{
ConfigMapMeta: meta_v1.ObjectMeta{Namespace: namespace, Name: electionID},
Client: c,
LockConfig: resourcelock.ResourceLockConfig{
Identity: id,
EventRecorder: recorder,
},
}
config := leaderelection.LeaderElectionConfig{
Lock: &lock,
LeaseDuration: ttl,
RenewDeadline: ttl / 2,
RetryPeriod: ttl / 4,
Callbacks: callbacks,
}
return leaderelection.NewLeaderElector(config)
}

View file

@ -1,132 +0,0 @@
/*
Copyright 2017 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package status
import (
"encoding/json"
"testing"
"time"
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes/fake"
"k8s.io/client-go/pkg/api"
api_v1 "k8s.io/client-go/pkg/api/v1"
"k8s.io/ingress/core/pkg/ingress/status/leaderelection/resourcelock"
)
func TestGetCurrentLeaderLeaderExist(t *testing.T) {
fkER := resourcelock.LeaderElectionRecord{
HolderIdentity: "currentLeader",
LeaseDurationSeconds: 30,
AcquireTime: meta_v1.NewTime(time.Now()),
RenewTime: meta_v1.NewTime(time.Now()),
LeaderTransitions: 3,
}
leaderInfo, _ := json.Marshal(fkER)
fkEndpoints := api_v1.Endpoints{
ObjectMeta: meta_v1.ObjectMeta{
Name: "ingress-controller-test",
Namespace: api.NamespaceSystem,
Annotations: map[string]string{
resourcelock.LeaderElectionRecordAnnotationKey: string(leaderInfo),
},
},
}
fk := fake.NewSimpleClientset(&api_v1.EndpointsList{Items: []api_v1.Endpoints{fkEndpoints}})
identity, endpoints, err := getCurrentLeader("ingress-controller-test", api.NamespaceSystem, fk)
if err != nil {
t.Fatalf("expected identitiy and endpoints but returned error %s", err)
}
if endpoints == nil {
t.Fatalf("returned nil but expected an endpoints")
}
if identity != "currentLeader" {
t.Fatalf("returned %v but expected %v", identity, "currentLeader")
}
}
func TestGetCurrentLeaderLeaderNotExist(t *testing.T) {
fkEndpoints := api_v1.Endpoints{
ObjectMeta: meta_v1.ObjectMeta{
Name: "ingress-controller-test",
Namespace: api.NamespaceSystem,
Annotations: map[string]string{},
},
}
fk := fake.NewSimpleClientset(&api_v1.EndpointsList{Items: []api_v1.Endpoints{fkEndpoints}})
identity, endpoints, err := getCurrentLeader("ingress-controller-test", api.NamespaceSystem, fk)
if err != nil {
t.Fatalf("unexpeted error: %v", err)
}
if endpoints == nil {
t.Fatalf("returned nil but expected an endpoints")
}
if identity != "" {
t.Fatalf("returned %s but expected %s", identity, "")
}
}
func TestGetCurrentLeaderAnnotationError(t *testing.T) {
fkEndpoints := api_v1.Endpoints{
ObjectMeta: meta_v1.ObjectMeta{
Name: "ingress-controller-test",
Namespace: api.NamespaceSystem,
Annotations: map[string]string{
resourcelock.LeaderElectionRecordAnnotationKey: "just-test-error-leader-annotation",
},
},
}
fk := fake.NewSimpleClientset(&api_v1.EndpointsList{Items: []api_v1.Endpoints{fkEndpoints}})
_, _, err := getCurrentLeader("ingress-controller-test", api.NamespaceSystem, fk)
if err == nil {
t.Errorf("expected error")
}
}
func TestNewElection(t *testing.T) {
fk := fake.NewSimpleClientset(&api_v1.EndpointsList{Items: []api_v1.Endpoints{
{
ObjectMeta: meta_v1.ObjectMeta{
Name: "ingress-controller-test",
Namespace: api.NamespaceSystem,
},
},
{
ObjectMeta: meta_v1.ObjectMeta{
Name: "ingress-controller-test-020",
Namespace: api.NamespaceSystem,
},
},
}})
ne, err := NewElection("ingress-controller-test", "startLeader", api.NamespaceSystem, 4*time.Second, func(leader string) {
// do nothing
go t.Logf("execute callback fun, leader is: %s", leader)
}, fk)
if err != nil {
t.Fatalf("unexpected error %v", err)
}
if ne == nil {
t.Fatalf("unexpected nil")
}
}

View file

@ -19,21 +19,25 @@ package status
import (
"fmt"
"net"
"os"
"sort"
"sync"
"time"
"github.com/golang/glog"
v1 "k8s.io/api/core/v1"
extensions "k8s.io/api/extensions/v1beta1"
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/util/wait"
clientset "k8s.io/client-go/kubernetes"
api_v1 "k8s.io/client-go/pkg/api/v1"
extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1"
"k8s.io/client-go/kubernetes/scheme"
"k8s.io/client-go/tools/leaderelection"
"k8s.io/client-go/tools/leaderelection/resourcelock"
"k8s.io/client-go/tools/record"
"k8s.io/ingress/core/pkg/ingress/annotations/class"
"k8s.io/ingress/core/pkg/ingress/status/leaderelection"
"k8s.io/ingress/core/pkg/ingress/store"
"k8s.io/ingress/core/pkg/k8s"
"k8s.io/ingress/core/pkg/strings"
@ -126,7 +130,7 @@ func (s statusSync) Shutdown() {
}
glog.Infof("removing address from ingress status (%v)", addrs)
s.updateStatus([]api_v1.LoadBalancerIngress{})
s.updateStatus([]v1.LoadBalancerIngress{})
}
func (s *statusSync) run() {
@ -198,17 +202,49 @@ func NewStatusSyncer(config Config) Sync {
// we need to use the defined ingress class to allow multiple leaders
// in order to update information about ingress status
id := fmt.Sprintf("%v-%v", config.ElectionID, config.DefaultIngressClass)
electionID := fmt.Sprintf("%v-%v", config.ElectionID, config.DefaultIngressClass)
if config.IngressClass != "" {
id = fmt.Sprintf("%v-%v", config.ElectionID, config.IngressClass)
electionID = fmt.Sprintf("%v-%v", config.ElectionID, config.IngressClass)
}
le, err := NewElection(id,
pod.Name, pod.Namespace, 30*time.Second,
st.callback, config.Client)
callbacks := leaderelection.LeaderCallbacks{
OnStartedLeading: func(stop <-chan struct{}) {
st.callback(pod.Name)
},
OnStoppedLeading: func() {
st.callback("")
},
}
broadcaster := record.NewBroadcaster()
hostname, _ := os.Hostname()
recorder := broadcaster.NewRecorder(scheme.Scheme, v1.EventSource{
Component: "ingress-leader-elector",
Host: hostname,
})
lock := resourcelock.ConfigMapLock{
ConfigMapMeta: meta_v1.ObjectMeta{Namespace: pod.Namespace, Name: electionID},
Client: config.Client.Core(),
LockConfig: resourcelock.ResourceLockConfig{
Identity: electionID,
EventRecorder: recorder,
},
}
le, err := leaderelection.NewLeaderElector(leaderelection.LeaderElectionConfig{
Lock: &lock,
LeaseDuration: 30 * time.Second,
RenewDeadline: 15 * time.Second,
RetryPeriod: 5 * time.Second,
Callbacks: callbacks,
})
if err != nil {
glog.Fatalf("unexpected error starting leader election: %v", err)
}
st.elector = le
return st
}
@ -265,13 +301,13 @@ func (s *statusSync) isRunningMultiplePods() bool {
}
// sliceToStatus converts a slice of IP and/or hostnames to LoadBalancerIngress
func sliceToStatus(endpoints []string) []api_v1.LoadBalancerIngress {
lbi := []api_v1.LoadBalancerIngress{}
func sliceToStatus(endpoints []string) []v1.LoadBalancerIngress {
lbi := []v1.LoadBalancerIngress{}
for _, ep := range endpoints {
if net.ParseIP(ep) == nil {
lbi = append(lbi, api_v1.LoadBalancerIngress{Hostname: ep})
lbi = append(lbi, v1.LoadBalancerIngress{Hostname: ep})
} else {
lbi = append(lbi, api_v1.LoadBalancerIngress{IP: ep})
lbi = append(lbi, v1.LoadBalancerIngress{IP: ep})
}
}
@ -279,7 +315,7 @@ func sliceToStatus(endpoints []string) []api_v1.LoadBalancerIngress {
return lbi
}
func (s *statusSync) updateStatus(newIPs []api_v1.LoadBalancerIngress) {
func (s *statusSync) updateStatus(newIPs []v1.LoadBalancerIngress) {
ings := s.IngressLister.List()
var wg sync.WaitGroup
wg.Add(len(ings))
@ -319,7 +355,7 @@ func (s *statusSync) updateStatus(newIPs []api_v1.LoadBalancerIngress) {
wg.Wait()
}
func ingressSliceEqual(lhs, rhs []api_v1.LoadBalancerIngress) bool {
func ingressSliceEqual(lhs, rhs []v1.LoadBalancerIngress) bool {
if len(lhs) != len(rhs) {
return false
}
@ -336,7 +372,7 @@ func ingressSliceEqual(lhs, rhs []api_v1.LoadBalancerIngress) bool {
}
// loadBalancerIngressByIP sorts LoadBalancerIngress using the field IP
type loadBalancerIngressByIP []api_v1.LoadBalancerIngress
type loadBalancerIngressByIP []v1.LoadBalancerIngress
func (c loadBalancerIngressByIP) Len() int { return len(c) }
func (c loadBalancerIngressByIP) Swap(i, j int) { c[i], c[j] = c[j], c[i] }

View file

@ -23,12 +23,12 @@ import (
"testing"
"time"
api_v1 "k8s.io/api/core/v1"
extensions "k8s.io/api/extensions/v1beta1"
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
testclient "k8s.io/client-go/kubernetes/fake"
"k8s.io/client-go/pkg/api"
api_v1 "k8s.io/client-go/pkg/api/v1"
extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1"
"k8s.io/client-go/tools/cache"
"k8s.io/kubernetes/pkg/api"
"k8s.io/ingress/core/pkg/ingress/annotations/class"
cache_store "k8s.io/ingress/core/pkg/ingress/store"

View file

@ -19,7 +19,7 @@ package store
import (
"fmt"
api "k8s.io/client-go/pkg/api/v1"
api "k8s.io/api/core/v1"
"k8s.io/client-go/tools/cache"
)

View file

@ -21,9 +21,9 @@ import (
"github.com/spf13/pflag"
api "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/util/intstr"
"k8s.io/apiserver/pkg/server/healthz"
api "k8s.io/client-go/pkg/api/v1"
"k8s.io/ingress/core/pkg/ingress/annotations/auth"
"k8s.io/ingress/core/pkg/ingress/annotations/authreq"

View file

@ -21,9 +21,9 @@ import (
"os"
"strings"
api "k8s.io/api/core/v1"
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
clientset "k8s.io/client-go/kubernetes"
api "k8s.io/client-go/pkg/api/v1"
)
// IsValidService checks if exists a service with the specified name

View file

@ -20,9 +20,9 @@ import (
"os"
"testing"
api "k8s.io/api/core/v1"
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
testclient "k8s.io/client-go/kubernetes/fake"
api "k8s.io/client-go/pkg/api/v1"
)
func TestParseNameNS(t *testing.T) {

View file

@ -24,7 +24,7 @@ import (
"github.com/spf13/pflag"
api "k8s.io/client-go/pkg/api/v1"
api "k8s.io/api/core/v1"
nginxconfig "k8s.io/ingress/controllers/nginx/pkg/config"
"k8s.io/ingress/core/pkg/ingress"

View file

@ -1,13 +0,0 @@
include $(GOROOT)/src/Make.inc
TARG=bitbucket.org/ww/goautoneg
GOFILES=autoneg.go
include $(GOROOT)/src/Make.pkg
format:
gofmt -w *.go
docs:
gomake clean
godoc ${TARG} > README.txt

View file

@ -1,67 +0,0 @@
PACKAGE
package goautoneg
import "bitbucket.org/ww/goautoneg"
HTTP Content-Type Autonegotiation.
The functions in this package implement the behaviour specified in
http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
Copyright (c) 2011, Open Knowledge Foundation Ltd.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
Neither the name of the Open Knowledge Foundation Ltd. nor the
names of its contributors may be used to endorse or promote
products derived from this software without specific prior written
permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
FUNCTIONS
func Negotiate(header string, alternatives []string) (content_type string)
Negotiate the most appropriate content_type given the accept header
and a list of alternatives.
func ParseAccept(header string) (accept []Accept)
Parse an Accept Header string returning a sorted list
of clauses
TYPES
type Accept struct {
Type, SubType string
Q float32
Params map[string]string
}
Structure to represent a clause in an HTTP Accept Header
SUBDIRECTORIES
.hg

View file

@ -1,162 +0,0 @@
/*
HTTP Content-Type Autonegotiation.
The functions in this package implement the behaviour specified in
http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
Copyright (c) 2011, Open Knowledge Foundation Ltd.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
Neither the name of the Open Knowledge Foundation Ltd. nor the
names of its contributors may be used to endorse or promote
products derived from this software without specific prior written
permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package goautoneg
import (
"sort"
"strconv"
"strings"
)
// Structure to represent a clause in an HTTP Accept Header
type Accept struct {
Type, SubType string
Q float64
Params map[string]string
}
// For internal use, so that we can use the sort interface
type accept_slice []Accept
func (accept accept_slice) Len() int {
slice := []Accept(accept)
return len(slice)
}
func (accept accept_slice) Less(i, j int) bool {
slice := []Accept(accept)
ai, aj := slice[i], slice[j]
if ai.Q > aj.Q {
return true
}
if ai.Type != "*" && aj.Type == "*" {
return true
}
if ai.SubType != "*" && aj.SubType == "*" {
return true
}
return false
}
func (accept accept_slice) Swap(i, j int) {
slice := []Accept(accept)
slice[i], slice[j] = slice[j], slice[i]
}
// Parse an Accept Header string returning a sorted list
// of clauses
func ParseAccept(header string) (accept []Accept) {
parts := strings.Split(header, ",")
accept = make([]Accept, 0, len(parts))
for _, part := range parts {
part := strings.Trim(part, " ")
a := Accept{}
a.Params = make(map[string]string)
a.Q = 1.0
mrp := strings.Split(part, ";")
media_range := mrp[0]
sp := strings.Split(media_range, "/")
a.Type = strings.Trim(sp[0], " ")
switch {
case len(sp) == 1 && a.Type == "*":
a.SubType = "*"
case len(sp) == 2:
a.SubType = strings.Trim(sp[1], " ")
default:
continue
}
if len(mrp) == 1 {
accept = append(accept, a)
continue
}
for _, param := range mrp[1:] {
sp := strings.SplitN(param, "=", 2)
if len(sp) != 2 {
continue
}
token := strings.Trim(sp[0], " ")
if token == "q" {
a.Q, _ = strconv.ParseFloat(sp[1], 32)
} else {
a.Params[token] = strings.Trim(sp[1], " ")
}
}
accept = append(accept, a)
}
slice := accept_slice(accept)
sort.Sort(slice)
return
}
// Negotiate the most appropriate content_type given the accept header
// and a list of alternatives.
func Negotiate(header string, alternatives []string) (content_type string) {
asp := make([][]string, 0, len(alternatives))
for _, ctype := range alternatives {
asp = append(asp, strings.SplitN(ctype, "/", 2))
}
for _, clause := range ParseAccept(header) {
for i, ctsp := range asp {
if clause.Type == ctsp[0] && clause.SubType == ctsp[1] {
content_type = alternatives[i]
return
}
if clause.Type == ctsp[0] && clause.SubType == "*" {
content_type = alternatives[i]
return
}
if clause.Type == "*" && clause.SubType == "*" {
content_type = alternatives[i]
return
}
}
}
return
}

View file

@ -1,36 +0,0 @@
clone:
path: github.com/go-openapi/analysis
matrix:
GO_VERSION:
- "1.6"
build:
integration:
image: golang:$$GO_VERSION
pull: true
commands:
- go get -u github.com/stretchr/testify/assert
- go get -u gopkg.in/yaml.v2
- go get -u github.com/go-openapi/swag
- go get -u github.com/go-openapi/jsonpointer
- go get -u github.com/go-openapi/spec
- go get -u github.com/go-openapi/loads/fmts
- go test -race ./...
- go test -v -cover -coverprofile=coverage.out -covermode=count ./...
notify:
slack:
channel: bots
webhook_url: $$SLACK_URL
username: drone
publish:
coverage:
server: https://coverage.vmware.run
token: $$GITHUB_TOKEN
# threshold: 70
# must_increase: true
when:
matrix:
GO_VERSION: "1.6"

View file

@ -1,2 +0,0 @@
secrets.yml
coverage.out

View file

@ -1,12 +0,0 @@
approve_by_comment: true
approve_regex: '^(:shipit:|:\+1:|\+1|LGTM|lgtm|Approved)'
reject_regex: ^[Rr]ejected
reset_on_push: false
reviewers:
members:
- casualjim
- frapposelli
- vburenin
- pytlesk4
name: pullapprove
required: 1

View file

@ -1,74 +0,0 @@
# Contributor Covenant Code of Conduct
## Our Pledge
In the interest of fostering an open and welcoming environment, we as
contributors and maintainers pledge to making participation in our project and
our community a harassment-free experience for everyone, regardless of age, body
size, disability, ethnicity, gender identity and expression, level of experience,
nationality, personal appearance, race, religion, or sexual identity and
orientation.
## Our Standards
Examples of behavior that contributes to creating a positive environment
include:
* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism
* Focusing on what is best for the community
* Showing empathy towards other community members
Examples of unacceptable behavior by participants include:
* The use of sexualized language or imagery and unwelcome sexual attention or
advances
* Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or electronic
address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
## Our Responsibilities
Project maintainers are responsible for clarifying the standards of acceptable
behavior and are expected to take appropriate and fair corrective action in
response to any instances of unacceptable behavior.
Project maintainers have the right and responsibility to remove, edit, or
reject comments, commits, code, wiki edits, issues, and other contributions
that are not aligned to this Code of Conduct, or to ban temporarily or
permanently any contributor for other behaviors that they deem inappropriate,
threatening, offensive, or harmful.
## Scope
This Code of Conduct applies both within project spaces and in public spaces
when an individual is representing the project or its community. Examples of
representing a project or community include using an official project e-mail
address, posting via an official social media account, or acting as an appointed
representative at an online or offline event. Representation of a project may be
further defined and clarified by project maintainers.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported by contacting the project team at ivan+abuse@flanders.co.nz. All
complaints will be reviewed and investigated and will result in a response that
is deemed necessary and appropriate to the circumstances. The project team is
obligated to maintain confidentiality with regard to the reporter of an incident.
Further details of specific enforcement policies may be posted separately.
Project maintainers who do not follow or enforce the Code of Conduct in good
faith may face temporary or permanent repercussions as determined by other
members of the project's leadership.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
available at [http://contributor-covenant.org/version/1/4][version]
[homepage]: http://contributor-covenant.org
[version]: http://contributor-covenant.org/version/1/4/

View file

@ -1,6 +0,0 @@
# OpenAPI initiative analysis [![Build Status](https://ci.vmware.run/api/badges/go-openapi/analysis/status.svg)](https://ci.vmware.run/go-openapi/analysis) [![Coverage](https://coverage.vmware.run/badges/go-openapi/analysis/coverage.svg)](https://coverage.vmware.run/go-openapi/analysis) [![Slack Status](https://slackin.goswagger.io/badge.svg)](https://slackin.goswagger.io)
[![license](http://img.shields.io/badge/license-Apache%20v2-orange.svg)](https://raw.githubusercontent.com/go-openapi/analysis/master/LICENSE) [![GoDoc](https://godoc.org/github.com/go-openapi/analysis?status.svg)](http://godoc.org/github.com/go-openapi/analysis)
A foundational library to analyze an OAI specification document for easier reasoning about the content.

View file

@ -1,614 +0,0 @@
// Copyright 2015 go-swagger maintainers
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package analysis
import (
"fmt"
slashpath "path"
"strconv"
"strings"
"github.com/go-openapi/jsonpointer"
"github.com/go-openapi/spec"
"github.com/go-openapi/swag"
)
type referenceAnalysis struct {
schemas map[string]spec.Ref
responses map[string]spec.Ref
parameters map[string]spec.Ref
items map[string]spec.Ref
allRefs map[string]spec.Ref
referenced struct {
schemas map[string]SchemaRef
responses map[string]*spec.Response
parameters map[string]*spec.Parameter
}
}
func (r *referenceAnalysis) addRef(key string, ref spec.Ref) {
r.allRefs["#"+key] = ref
}
func (r *referenceAnalysis) addItemsRef(key string, items *spec.Items) {
r.items["#"+key] = items.Ref
r.addRef(key, items.Ref)
}
func (r *referenceAnalysis) addSchemaRef(key string, ref SchemaRef) {
r.schemas["#"+key] = ref.Schema.Ref
r.addRef(key, ref.Schema.Ref)
}
func (r *referenceAnalysis) addResponseRef(key string, resp *spec.Response) {
r.responses["#"+key] = resp.Ref
r.addRef(key, resp.Ref)
}
func (r *referenceAnalysis) addParamRef(key string, param *spec.Parameter) {
r.parameters["#"+key] = param.Ref
r.addRef(key, param.Ref)
}
// New takes a swagger spec object and returns an analyzed spec document.
// The analyzed document contains a number of indices that make it easier to
// reason about semantics of a swagger specification for use in code generation
// or validation etc.
func New(doc *spec.Swagger) *Spec {
a := &Spec{
spec: doc,
consumes: make(map[string]struct{}, 150),
produces: make(map[string]struct{}, 150),
authSchemes: make(map[string]struct{}, 150),
operations: make(map[string]map[string]*spec.Operation, 150),
allSchemas: make(map[string]SchemaRef, 150),
allOfs: make(map[string]SchemaRef, 150),
references: referenceAnalysis{
schemas: make(map[string]spec.Ref, 150),
responses: make(map[string]spec.Ref, 150),
parameters: make(map[string]spec.Ref, 150),
items: make(map[string]spec.Ref, 150),
allRefs: make(map[string]spec.Ref, 150),
},
}
a.references.referenced.schemas = make(map[string]SchemaRef, 150)
a.references.referenced.responses = make(map[string]*spec.Response, 150)
a.references.referenced.parameters = make(map[string]*spec.Parameter, 150)
a.initialize()
return a
}
// Spec takes a swagger spec object and turns it into a registry
// with a bunch of utility methods to act on the information in the spec
type Spec struct {
spec *spec.Swagger
consumes map[string]struct{}
produces map[string]struct{}
authSchemes map[string]struct{}
operations map[string]map[string]*spec.Operation
references referenceAnalysis
allSchemas map[string]SchemaRef
allOfs map[string]SchemaRef
}
func (s *Spec) initialize() {
for _, c := range s.spec.Consumes {
s.consumes[c] = struct{}{}
}
for _, c := range s.spec.Produces {
s.produces[c] = struct{}{}
}
for _, ss := range s.spec.Security {
for k := range ss {
s.authSchemes[k] = struct{}{}
}
}
for path, pathItem := range s.AllPaths() {
s.analyzeOperations(path, &pathItem)
}
for name, parameter := range s.spec.Parameters {
refPref := slashpath.Join("/parameters", jsonpointer.Escape(name))
if parameter.Items != nil {
s.analyzeItems("items", parameter.Items, refPref)
}
if parameter.In == "body" && parameter.Schema != nil {
s.analyzeSchema("schema", *parameter.Schema, refPref)
}
}
for name, response := range s.spec.Responses {
refPref := slashpath.Join("/responses", jsonpointer.Escape(name))
for _, v := range response.Headers {
if v.Items != nil {
s.analyzeItems("items", v.Items, refPref)
}
}
if response.Schema != nil {
s.analyzeSchema("schema", *response.Schema, refPref)
}
}
for name, schema := range s.spec.Definitions {
s.analyzeSchema(name, schema, "/definitions")
}
// TODO: after analyzing all things and flattening schemas etc
// resolve all the collected references to their final representations
// best put in a separate method because this could get expensive
}
func (s *Spec) analyzeOperations(path string, pi *spec.PathItem) {
// TODO: resolve refs here?
op := pi
s.analyzeOperation("GET", path, op.Get)
s.analyzeOperation("PUT", path, op.Put)
s.analyzeOperation("POST", path, op.Post)
s.analyzeOperation("PATCH", path, op.Patch)
s.analyzeOperation("DELETE", path, op.Delete)
s.analyzeOperation("HEAD", path, op.Head)
s.analyzeOperation("OPTIONS", path, op.Options)
for i, param := range op.Parameters {
refPref := slashpath.Join("/paths", jsonpointer.Escape(path), "parameters", strconv.Itoa(i))
if param.Ref.String() != "" {
s.references.addParamRef(refPref, &param)
}
if param.Items != nil {
s.analyzeItems("items", param.Items, refPref)
}
if param.Schema != nil {
s.analyzeSchema("schema", *param.Schema, refPref)
}
}
}
func (s *Spec) analyzeItems(name string, items *spec.Items, prefix string) {
if items == nil {
return
}
refPref := slashpath.Join(prefix, name)
s.analyzeItems(name, items.Items, refPref)
if items.Ref.String() != "" {
s.references.addItemsRef(refPref, items)
}
}
func (s *Spec) analyzeOperation(method, path string, op *spec.Operation) {
if op == nil {
return
}
for _, c := range op.Consumes {
s.consumes[c] = struct{}{}
}
for _, c := range op.Produces {
s.produces[c] = struct{}{}
}
for _, ss := range op.Security {
for k := range ss {
s.authSchemes[k] = struct{}{}
}
}
if _, ok := s.operations[method]; !ok {
s.operations[method] = make(map[string]*spec.Operation)
}
s.operations[method][path] = op
prefix := slashpath.Join("/paths", jsonpointer.Escape(path), strings.ToLower(method))
for i, param := range op.Parameters {
refPref := slashpath.Join(prefix, "parameters", strconv.Itoa(i))
if param.Ref.String() != "" {
s.references.addParamRef(refPref, &param)
}
s.analyzeItems("items", param.Items, refPref)
if param.In == "body" && param.Schema != nil {
s.analyzeSchema("schema", *param.Schema, refPref)
}
}
if op.Responses != nil {
if op.Responses.Default != nil {
refPref := slashpath.Join(prefix, "responses", "default")
if op.Responses.Default.Ref.String() != "" {
s.references.addResponseRef(refPref, op.Responses.Default)
}
for _, v := range op.Responses.Default.Headers {
s.analyzeItems("items", v.Items, refPref)
}
if op.Responses.Default.Schema != nil {
s.analyzeSchema("schema", *op.Responses.Default.Schema, refPref)
}
}
for k, res := range op.Responses.StatusCodeResponses {
refPref := slashpath.Join(prefix, "responses", strconv.Itoa(k))
if res.Ref.String() != "" {
s.references.addResponseRef(refPref, &res)
}
for _, v := range res.Headers {
s.analyzeItems("items", v.Items, refPref)
}
if res.Schema != nil {
s.analyzeSchema("schema", *res.Schema, refPref)
}
}
}
}
func (s *Spec) analyzeSchema(name string, schema spec.Schema, prefix string) {
refURI := slashpath.Join(prefix, jsonpointer.Escape(name))
schRef := SchemaRef{
Name: name,
Schema: &schema,
Ref: spec.MustCreateRef("#" + refURI),
}
s.allSchemas["#"+refURI] = schRef
if schema.Ref.String() != "" {
s.references.addSchemaRef(refURI, schRef)
}
for k, v := range schema.Definitions {
s.analyzeSchema(k, v, slashpath.Join(refURI, "definitions"))
}
for k, v := range schema.Properties {
s.analyzeSchema(k, v, slashpath.Join(refURI, "properties"))
}
for k, v := range schema.PatternProperties {
s.analyzeSchema(k, v, slashpath.Join(refURI, "patternProperties"))
}
for i, v := range schema.AllOf {
s.analyzeSchema(strconv.Itoa(i), v, slashpath.Join(refURI, "allOf"))
}
if len(schema.AllOf) > 0 {
s.allOfs["#"+refURI] = SchemaRef{Name: name, Schema: &schema, Ref: spec.MustCreateRef("#" + refURI)}
}
for i, v := range schema.AnyOf {
s.analyzeSchema(strconv.Itoa(i), v, slashpath.Join(refURI, "anyOf"))
}
for i, v := range schema.OneOf {
s.analyzeSchema(strconv.Itoa(i), v, slashpath.Join(refURI, "oneOf"))
}
if schema.Not != nil {
s.analyzeSchema("not", *schema.Not, refURI)
}
if schema.AdditionalProperties != nil && schema.AdditionalProperties.Schema != nil {
s.analyzeSchema("additionalProperties", *schema.AdditionalProperties.Schema, refURI)
}
if schema.AdditionalItems != nil && schema.AdditionalItems.Schema != nil {
s.analyzeSchema("additionalItems", *schema.AdditionalItems.Schema, refURI)
}
if schema.Items != nil {
if schema.Items.Schema != nil {
s.analyzeSchema("items", *schema.Items.Schema, refURI)
}
for i, sch := range schema.Items.Schemas {
s.analyzeSchema(strconv.Itoa(i), sch, slashpath.Join(refURI, "items"))
}
}
}
// SecurityRequirement is a representation of a security requirement for an operation
type SecurityRequirement struct {
Name string
Scopes []string
}
// SecurityRequirementsFor gets the security requirements for the operation
func (s *Spec) SecurityRequirementsFor(operation *spec.Operation) []SecurityRequirement {
if s.spec.Security == nil && operation.Security == nil {
return nil
}
schemes := s.spec.Security
if operation.Security != nil {
schemes = operation.Security
}
unique := make(map[string]SecurityRequirement)
for _, scheme := range schemes {
for k, v := range scheme {
if _, ok := unique[k]; !ok {
unique[k] = SecurityRequirement{Name: k, Scopes: v}
}
}
}
var result []SecurityRequirement
for _, v := range unique {
result = append(result, v)
}
return result
}
// SecurityDefinitionsFor gets the matching security definitions for a set of requirements
func (s *Spec) SecurityDefinitionsFor(operation *spec.Operation) map[string]spec.SecurityScheme {
requirements := s.SecurityRequirementsFor(operation)
if len(requirements) == 0 {
return nil
}
result := make(map[string]spec.SecurityScheme)
for _, v := range requirements {
if definition, ok := s.spec.SecurityDefinitions[v.Name]; ok {
if definition != nil {
result[v.Name] = *definition
}
}
}
return result
}
// ConsumesFor gets the mediatypes for the operation
func (s *Spec) ConsumesFor(operation *spec.Operation) []string {
if len(operation.Consumes) == 0 {
cons := make(map[string]struct{}, len(s.spec.Consumes))
for _, k := range s.spec.Consumes {
cons[k] = struct{}{}
}
return s.structMapKeys(cons)
}
cons := make(map[string]struct{}, len(operation.Consumes))
for _, c := range operation.Consumes {
cons[c] = struct{}{}
}
return s.structMapKeys(cons)
}
// ProducesFor gets the mediatypes for the operation
func (s *Spec) ProducesFor(operation *spec.Operation) []string {
if len(operation.Produces) == 0 {
prod := make(map[string]struct{}, len(s.spec.Produces))
for _, k := range s.spec.Produces {
prod[k] = struct{}{}
}
return s.structMapKeys(prod)
}
prod := make(map[string]struct{}, len(operation.Produces))
for _, c := range operation.Produces {
prod[c] = struct{}{}
}
return s.structMapKeys(prod)
}
func mapKeyFromParam(param *spec.Parameter) string {
return fmt.Sprintf("%s#%s", param.In, fieldNameFromParam(param))
}
func fieldNameFromParam(param *spec.Parameter) string {
if nm, ok := param.Extensions.GetString("go-name"); ok {
return nm
}
return swag.ToGoName(param.Name)
}
func (s *Spec) paramsAsMap(parameters []spec.Parameter, res map[string]spec.Parameter) {
for _, param := range parameters {
pr := param
if pr.Ref.String() != "" {
obj, _, err := pr.Ref.GetPointer().Get(s.spec)
if err != nil {
panic(err)
}
pr = obj.(spec.Parameter)
}
res[mapKeyFromParam(&pr)] = pr
}
}
// ParametersFor the specified operation id
func (s *Spec) ParametersFor(operationID string) []spec.Parameter {
gatherParams := func(pi *spec.PathItem, op *spec.Operation) []spec.Parameter {
bag := make(map[string]spec.Parameter)
s.paramsAsMap(pi.Parameters, bag)
s.paramsAsMap(op.Parameters, bag)
var res []spec.Parameter
for _, v := range bag {
res = append(res, v)
}
return res
}
for _, pi := range s.spec.Paths.Paths {
if pi.Get != nil && pi.Get.ID == operationID {
return gatherParams(&pi, pi.Get)
}
if pi.Head != nil && pi.Head.ID == operationID {
return gatherParams(&pi, pi.Head)
}
if pi.Options != nil && pi.Options.ID == operationID {
return gatherParams(&pi, pi.Options)
}
if pi.Post != nil && pi.Post.ID == operationID {
return gatherParams(&pi, pi.Post)
}
if pi.Patch != nil && pi.Patch.ID == operationID {
return gatherParams(&pi, pi.Patch)
}
if pi.Put != nil && pi.Put.ID == operationID {
return gatherParams(&pi, pi.Put)
}
if pi.Delete != nil && pi.Delete.ID == operationID {
return gatherParams(&pi, pi.Delete)
}
}
return nil
}
// ParamsFor the specified method and path. Aggregates them with the defaults etc, so it's all the params that
// apply for the method and path.
func (s *Spec) ParamsFor(method, path string) map[string]spec.Parameter {
res := make(map[string]spec.Parameter)
if pi, ok := s.spec.Paths.Paths[path]; ok {
s.paramsAsMap(pi.Parameters, res)
s.paramsAsMap(s.operations[strings.ToUpper(method)][path].Parameters, res)
}
return res
}
// OperationForName gets the operation for the given id
func (s *Spec) OperationForName(operationID string) (string, string, *spec.Operation, bool) {
for method, pathItem := range s.operations {
for path, op := range pathItem {
if operationID == op.ID {
return method, path, op, true
}
}
}
return "", "", nil, false
}
// OperationFor the given method and path
func (s *Spec) OperationFor(method, path string) (*spec.Operation, bool) {
if mp, ok := s.operations[strings.ToUpper(method)]; ok {
op, fn := mp[path]
return op, fn
}
return nil, false
}
// Operations gathers all the operations specified in the spec document
func (s *Spec) Operations() map[string]map[string]*spec.Operation {
return s.operations
}
func (s *Spec) structMapKeys(mp map[string]struct{}) []string {
if len(mp) == 0 {
return nil
}
result := make([]string, 0, len(mp))
for k := range mp {
result = append(result, k)
}
return result
}
// AllPaths returns all the paths in the swagger spec
func (s *Spec) AllPaths() map[string]spec.PathItem {
if s.spec == nil || s.spec.Paths == nil {
return nil
}
return s.spec.Paths.Paths
}
// OperationIDs gets all the operation ids based on method an dpath
func (s *Spec) OperationIDs() []string {
if len(s.operations) == 0 {
return nil
}
result := make([]string, 0, len(s.operations))
for method, v := range s.operations {
for p, o := range v {
if o.ID != "" {
result = append(result, o.ID)
} else {
result = append(result, fmt.Sprintf("%s %s", strings.ToUpper(method), p))
}
}
}
return result
}
// RequiredConsumes gets all the distinct consumes that are specified in the specification document
func (s *Spec) RequiredConsumes() []string {
return s.structMapKeys(s.consumes)
}
// RequiredProduces gets all the distinct produces that are specified in the specification document
func (s *Spec) RequiredProduces() []string {
return s.structMapKeys(s.produces)
}
// RequiredSecuritySchemes gets all the distinct security schemes that are specified in the swagger spec
func (s *Spec) RequiredSecuritySchemes() []string {
return s.structMapKeys(s.authSchemes)
}
// SchemaRef is a reference to a schema
type SchemaRef struct {
Name string
Ref spec.Ref
Schema *spec.Schema
}
// SchemasWithAllOf returns schema references to all schemas that are defined
// with an allOf key
func (s *Spec) SchemasWithAllOf() (result []SchemaRef) {
for _, v := range s.allOfs {
result = append(result, v)
}
return
}
// AllDefinitions returns schema references for all the definitions that were discovered
func (s *Spec) AllDefinitions() (result []SchemaRef) {
for _, v := range s.allSchemas {
result = append(result, v)
}
return
}
// AllDefinitionReferences returns json refs for all the discovered schemas
func (s *Spec) AllDefinitionReferences() (result []string) {
for _, v := range s.references.schemas {
result = append(result, v.String())
}
return
}
// AllParameterReferences returns json refs for all the discovered parameters
func (s *Spec) AllParameterReferences() (result []string) {
for _, v := range s.references.parameters {
result = append(result, v.String())
}
return
}
// AllResponseReferences returns json refs for all the discovered responses
func (s *Spec) AllResponseReferences() (result []string) {
for _, v := range s.references.responses {
result = append(result, v.String())
}
return
}
// AllItemsReferences returns the references for all the items
func (s *Spec) AllItemsReferences() (result []string) {
for _, v := range s.references.items {
result = append(result, v.String())
}
return
}
// AllReferences returns all the references found in the document
func (s *Spec) AllReferences() (result []string) {
for _, v := range s.references.allRefs {
result = append(result, v.String())
}
return
}
// AllRefs returns all the unique references found in the document
func (s *Spec) AllRefs() (result []spec.Ref) {
set := make(map[string]struct{})
for _, v := range s.references.allRefs {
a := v.String()
if a == "" {
continue
}
if _, ok := set[a]; !ok {
set[a] = struct{}{}
result = append(result, v)
}
}
return
}

View file

@ -1,39 +0,0 @@
clone:
path: github.com/go-openapi/loads
matrix:
GO_VERSION:
- "1.6"
build:
integration:
image: golang:$$GO_VERSION
pull: true
environment:
GOCOVMODE: "count"
commands:
- go get -u github.com/axw/gocov/gocov
- go get -u gopkg.in/matm/v1/gocov-html
- go get -u github.com/cee-dub/go-junit-report
- go get -u github.com/stretchr/testify/assert
- go get -u gopkg.in/yaml.v2
- go get -u github.com/go-openapi/swag
- go get -u github.com/go-openapi/analysis
- go get -u github.com/go-openapi/spec
- ./hack/build-drone.sh
notify:
slack:
channel: bots
webhook_url: $$SLACK_URL
username: drone
publish:
coverage:
server: https://coverage.vmware.run
token: $$GITHUB_TOKEN
# threshold: 70
# must_increase: true
when:
matrix:
GO_VERSION: "1.6"

View file

@ -1,4 +0,0 @@
secrets.yml
coverage.out
profile.cov
profile.out

View file

@ -1,13 +0,0 @@
approve_by_comment: true
approve_regex: '^(:shipit:|:\+1:|\+1|LGTM|lgtm|Approved)'
reject_regex: ^[Rr]ejected
reset_on_push: false
reviewers:
members:
- casualjim
- chancez
- frapposelli
- vburenin
- pytlesk4
name: pullapprove
required: 1

View file

@ -1,74 +0,0 @@
# Contributor Covenant Code of Conduct
## Our Pledge
In the interest of fostering an open and welcoming environment, we as
contributors and maintainers pledge to making participation in our project and
our community a harassment-free experience for everyone, regardless of age, body
size, disability, ethnicity, gender identity and expression, level of experience,
nationality, personal appearance, race, religion, or sexual identity and
orientation.
## Our Standards
Examples of behavior that contributes to creating a positive environment
include:
* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism
* Focusing on what is best for the community
* Showing empathy towards other community members
Examples of unacceptable behavior by participants include:
* The use of sexualized language or imagery and unwelcome sexual attention or
advances
* Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or electronic
address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
## Our Responsibilities
Project maintainers are responsible for clarifying the standards of acceptable
behavior and are expected to take appropriate and fair corrective action in
response to any instances of unacceptable behavior.
Project maintainers have the right and responsibility to remove, edit, or
reject comments, commits, code, wiki edits, issues, and other contributions
that are not aligned to this Code of Conduct, or to ban temporarily or
permanently any contributor for other behaviors that they deem inappropriate,
threatening, offensive, or harmful.
## Scope
This Code of Conduct applies both within project spaces and in public spaces
when an individual is representing the project or its community. Examples of
representing a project or community include using an official project e-mail
address, posting via an official social media account, or acting as an appointed
representative at an online or offline event. Representation of a project may be
further defined and clarified by project maintainers.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported by contacting the project team at ivan+abuse@flanders.co.nz. All
complaints will be reviewed and investigated and will result in a response that
is deemed necessary and appropriate to the circumstances. The project team is
obligated to maintain confidentiality with regard to the reporter of an incident.
Further details of specific enforcement policies may be posted separately.
Project maintainers who do not follow or enforce the Code of Conduct in good
faith may face temporary or permanent repercussions as determined by other
members of the project's leadership.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
available at [http://contributor-covenant.org/version/1/4][version]
[homepage]: http://contributor-covenant.org
[version]: http://contributor-covenant.org/version/1/4/

View file

@ -1,5 +0,0 @@
# Loads OAI specs [![Build Status](https://ci.vmware.run/api/badges/go-openapi/loads/status.svg)](https://ci.vmware.run/go-openapi/loads) [![Coverage](https://coverage.vmware.run/badges/go-openapi/loads/coverage.svg)](https://coverage.vmware.run/go-openapi/loads) [![Slack Status](https://slackin.goswagger.io/badge.svg)](https://slackin.goswagger.io)
[![license](http://img.shields.io/badge/license-Apache%20v2-orange.svg)](https://raw.githubusercontent.com/go-openapi/loads/master/LICENSE) [![GoDoc](https://godoc.org/github.com/go-openapi/loads?status.svg)](http://godoc.org/github.com/go-openapi/loads)
Loading of OAI specification documents from local or remote locations.

View file

@ -1,203 +0,0 @@
// Copyright 2015 go-swagger maintainers
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package loads
import (
"encoding/json"
"fmt"
"net/url"
"github.com/go-openapi/analysis"
"github.com/go-openapi/spec"
"github.com/go-openapi/swag"
)
// JSONDoc loads a json document from either a file or a remote url
func JSONDoc(path string) (json.RawMessage, error) {
data, err := swag.LoadFromFileOrHTTP(path)
if err != nil {
return nil, err
}
return json.RawMessage(data), nil
}
// DocLoader represents a doc loader type
type DocLoader func(string) (json.RawMessage, error)
// DocMatcher represents a predicate to check if a loader matches
type DocMatcher func(string) bool
var loaders = &loader{Match: func(_ string) bool { return true }, Fn: JSONDoc}
// AddLoader for a document
func AddLoader(predicate DocMatcher, load DocLoader) {
prev := loaders
loaders = &loader{
Match: predicate,
Fn: load,
Next: prev,
}
}
type loader struct {
Fn DocLoader
Match DocMatcher
Next *loader
}
// JSONSpec loads a spec from a json document
func JSONSpec(path string) (*Document, error) {
data, err := JSONDoc(path)
if err != nil {
return nil, err
}
// convert to json
return Analyzed(json.RawMessage(data), "")
}
// Document represents a swagger spec document
type Document struct {
// specAnalyzer
Analyzer *analysis.Spec
spec *spec.Swagger
origSpec *spec.Swagger
schema *spec.Schema
raw json.RawMessage
}
// Spec loads a new spec document
func Spec(path string) (*Document, error) {
specURL, err := url.Parse(path)
if err != nil {
return nil, err
}
for l := loaders.Next; l != nil; l = l.Next {
if loaders.Match(specURL.Path) {
b, err2 := loaders.Fn(path)
if err2 != nil {
return nil, err2
}
return Analyzed(b, "")
}
}
b, err := loaders.Fn(path)
if err != nil {
return nil, err
}
return Analyzed(b, "")
}
var swag20Schema = spec.MustLoadSwagger20Schema()
// Analyzed creates a new analyzed spec document
func Analyzed(data json.RawMessage, version string) (*Document, error) {
if version == "" {
version = "2.0"
}
if version != "2.0" {
return nil, fmt.Errorf("spec version %q is not supported", version)
}
swspec := new(spec.Swagger)
if err := json.Unmarshal(data, swspec); err != nil {
return nil, err
}
origsqspec := new(spec.Swagger)
if err := json.Unmarshal(data, origsqspec); err != nil {
return nil, err
}
d := &Document{
Analyzer: analysis.New(swspec),
schema: swag20Schema,
spec: swspec,
raw: data,
origSpec: origsqspec,
}
return d, nil
}
// Expanded expands the ref fields in the spec document and returns a new spec document
func (d *Document) Expanded() (*Document, error) {
swspec := new(spec.Swagger)
if err := json.Unmarshal(d.raw, swspec); err != nil {
return nil, err
}
if err := spec.ExpandSpec(swspec); err != nil {
return nil, err
}
dd := &Document{
Analyzer: analysis.New(swspec),
spec: swspec,
schema: swag20Schema,
raw: d.raw,
origSpec: d.origSpec,
}
return dd, nil
}
// BasePath the base path for this spec
func (d *Document) BasePath() string {
return d.spec.BasePath
}
// Version returns the version of this spec
func (d *Document) Version() string {
return d.spec.Swagger
}
// Schema returns the swagger 2.0 schema
func (d *Document) Schema() *spec.Schema {
return d.schema
}
// Spec returns the swagger spec object model
func (d *Document) Spec() *spec.Swagger {
return d.spec
}
// Host returns the host for the API
func (d *Document) Host() string {
return d.spec.Host
}
// Raw returns the raw swagger spec as json bytes
func (d *Document) Raw() json.RawMessage {
return d.raw
}
func (d *Document) OrigSpec() *spec.Swagger {
return d.origSpec
}
// ResetDefinitions gives a shallow copy with the models reset
func (d *Document) ResetDefinitions() *Document {
defs := make(map[string]spec.Schema, len(d.origSpec.Definitions))
for k, v := range d.origSpec.Definitions {
defs[k] = v
}
d.spec.Definitions = defs
return d
}
// Pristine creates a new pristine document instance based on the input data
func (d *Document) Pristine() *Document {
dd, _ := Analyzed(d.Raw(), d.Version())
return dd
}

136
vendor/github.com/golang/protobuf/ptypes/any.go generated vendored Normal file
View file

@ -0,0 +1,136 @@
// Go support for Protocol Buffers - Google's data interchange format
//
// Copyright 2016 The Go Authors. All rights reserved.
// https://github.com/golang/protobuf
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package ptypes
// This file implements functions to marshal proto.Message to/from
// google.protobuf.Any message.
import (
"fmt"
"reflect"
"strings"
"github.com/golang/protobuf/proto"
"github.com/golang/protobuf/ptypes/any"
)
const googleApis = "type.googleapis.com/"
// AnyMessageName returns the name of the message contained in a google.protobuf.Any message.
//
// Note that regular type assertions should be done using the Is
// function. AnyMessageName is provided for less common use cases like filtering a
// sequence of Any messages based on a set of allowed message type names.
func AnyMessageName(any *any.Any) (string, error) {
slash := strings.LastIndex(any.TypeUrl, "/")
if slash < 0 {
return "", fmt.Errorf("message type url %q is invalid", any.TypeUrl)
}
return any.TypeUrl[slash+1:], nil
}
// MarshalAny takes the protocol buffer and encodes it into google.protobuf.Any.
func MarshalAny(pb proto.Message) (*any.Any, error) {
value, err := proto.Marshal(pb)
if err != nil {
return nil, err
}
return &any.Any{TypeUrl: googleApis + proto.MessageName(pb), Value: value}, nil
}
// DynamicAny is a value that can be passed to UnmarshalAny to automatically
// allocate a proto.Message for the type specified in a google.protobuf.Any
// message. The allocated message is stored in the embedded proto.Message.
//
// Example:
//
// var x ptypes.DynamicAny
// if err := ptypes.UnmarshalAny(a, &x); err != nil { ... }
// fmt.Printf("unmarshaled message: %v", x.Message)
type DynamicAny struct {
proto.Message
}
// Empty returns a new proto.Message of the type specified in a
// google.protobuf.Any message. It returns an error if corresponding message
// type isn't linked in.
func Empty(any *any.Any) (proto.Message, error) {
aname, err := AnyMessageName(any)
if err != nil {
return nil, err
}
t := proto.MessageType(aname)
if t == nil {
return nil, fmt.Errorf("any: message type %q isn't linked in", aname)
}
return reflect.New(t.Elem()).Interface().(proto.Message), nil
}
// UnmarshalAny parses the protocol buffer representation in a google.protobuf.Any
// message and places the decoded result in pb. It returns an error if type of
// contents of Any message does not match type of pb message.
//
// pb can be a proto.Message, or a *DynamicAny.
func UnmarshalAny(any *any.Any, pb proto.Message) error {
if d, ok := pb.(*DynamicAny); ok {
if d.Message == nil {
var err error
d.Message, err = Empty(any)
if err != nil {
return err
}
}
return UnmarshalAny(any, d.Message)
}
aname, err := AnyMessageName(any)
if err != nil {
return err
}
mname := proto.MessageName(pb)
if aname != mname {
return fmt.Errorf("mismatched message type: got %q want %q", aname, mname)
}
return proto.Unmarshal(any.Value, pb)
}
// Is returns true if any value contains a given message type.
func Is(any *any.Any, pb proto.Message) bool {
aname, err := AnyMessageName(any)
if err != nil {
return false
}
return aname == proto.MessageName(pb)
}

155
vendor/github.com/golang/protobuf/ptypes/any/any.pb.go generated vendored Normal file
View file

@ -0,0 +1,155 @@
// Code generated by protoc-gen-go.
// source: github.com/golang/protobuf/ptypes/any/any.proto
// DO NOT EDIT!
/*
Package any is a generated protocol buffer package.
It is generated from these files:
github.com/golang/protobuf/ptypes/any/any.proto
It has these top-level messages:
Any
*/
package any
import proto "github.com/golang/protobuf/proto"
import fmt "fmt"
import math "math"
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
// `Any` contains an arbitrary serialized protocol buffer message along with a
// URL that describes the type of the serialized message.
//
// Protobuf library provides support to pack/unpack Any values in the form
// of utility functions or additional generated methods of the Any type.
//
// Example 1: Pack and unpack a message in C++.
//
// Foo foo = ...;
// Any any;
// any.PackFrom(foo);
// ...
// if (any.UnpackTo(&foo)) {
// ...
// }
//
// Example 2: Pack and unpack a message in Java.
//
// Foo foo = ...;
// Any any = Any.pack(foo);
// ...
// if (any.is(Foo.class)) {
// foo = any.unpack(Foo.class);
// }
//
// Example 3: Pack and unpack a message in Python.
//
// foo = Foo(...)
// any = Any()
// any.Pack(foo)
// ...
// if any.Is(Foo.DESCRIPTOR):
// any.Unpack(foo)
// ...
//
// The pack methods provided by protobuf library will by default use
// 'type.googleapis.com/full.type.name' as the type URL and the unpack
// methods only use the fully qualified type name after the last '/'
// in the type URL, for example "foo.bar.com/x/y.z" will yield type
// name "y.z".
//
//
// JSON
// ====
// The JSON representation of an `Any` value uses the regular
// representation of the deserialized, embedded message, with an
// additional field `@type` which contains the type URL. Example:
//
// package google.profile;
// message Person {
// string first_name = 1;
// string last_name = 2;
// }
//
// {
// "@type": "type.googleapis.com/google.profile.Person",
// "firstName": <string>,
// "lastName": <string>
// }
//
// If the embedded message type is well-known and has a custom JSON
// representation, that representation will be embedded adding a field
// `value` which holds the custom JSON in addition to the `@type`
// field. Example (for message [google.protobuf.Duration][]):
//
// {
// "@type": "type.googleapis.com/google.protobuf.Duration",
// "value": "1.212s"
// }
//
type Any struct {
// A URL/resource name whose content describes the type of the
// serialized protocol buffer message.
//
// For URLs which use the scheme `http`, `https`, or no scheme, the
// following restrictions and interpretations apply:
//
// * If no scheme is provided, `https` is assumed.
// * The last segment of the URL's path must represent the fully
// qualified name of the type (as in `path/google.protobuf.Duration`).
// The name should be in a canonical form (e.g., leading "." is
// not accepted).
// * An HTTP GET on the URL must yield a [google.protobuf.Type][]
// value in binary format, or produce an error.
// * Applications are allowed to cache lookup results based on the
// URL, or have them precompiled into a binary to avoid any
// lookup. Therefore, binary compatibility needs to be preserved
// on changes to types. (Use versioned type names to manage
// breaking changes.)
//
// Schemes other than `http`, `https` (or the empty scheme) might be
// used with implementation specific semantics.
//
TypeUrl string `protobuf:"bytes,1,opt,name=type_url,json=typeUrl" json:"type_url,omitempty"`
// Must be a valid serialized protocol buffer of the above specified type.
Value []byte `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"`
}
func (m *Any) Reset() { *m = Any{} }
func (m *Any) String() string { return proto.CompactTextString(m) }
func (*Any) ProtoMessage() {}
func (*Any) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }
func (*Any) XXX_WellKnownType() string { return "Any" }
func init() {
proto.RegisterType((*Any)(nil), "google.protobuf.Any")
}
func init() { proto.RegisterFile("github.com/golang/protobuf/ptypes/any/any.proto", fileDescriptor0) }
var fileDescriptor0 = []byte{
// 187 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xe2, 0xd2, 0x4f, 0xcf, 0x2c, 0xc9,
0x28, 0x4d, 0xd2, 0x4b, 0xce, 0xcf, 0xd5, 0x4f, 0xcf, 0xcf, 0x49, 0xcc, 0x4b, 0xd7, 0x2f, 0x28,
0xca, 0x2f, 0xc9, 0x4f, 0x2a, 0x4d, 0xd3, 0x2f, 0x28, 0xa9, 0x2c, 0x48, 0x2d, 0xd6, 0x4f, 0xcc,
0xab, 0x04, 0x61, 0x3d, 0xb0, 0xb8, 0x10, 0x7f, 0x7a, 0x7e, 0x7e, 0x7a, 0x4e, 0xaa, 0x1e, 0x4c,
0x95, 0x92, 0x19, 0x17, 0xb3, 0x63, 0x5e, 0xa5, 0x90, 0x24, 0x17, 0x07, 0x48, 0x79, 0x7c, 0x69,
0x51, 0x8e, 0x04, 0xa3, 0x02, 0xa3, 0x06, 0x67, 0x10, 0x3b, 0x88, 0x1f, 0x5a, 0x94, 0x23, 0x24,
0xc2, 0xc5, 0x5a, 0x96, 0x98, 0x53, 0x9a, 0x2a, 0xc1, 0xa4, 0xc0, 0xa8, 0xc1, 0x13, 0x04, 0xe1,
0x38, 0x15, 0x71, 0x09, 0x27, 0xe7, 0xe7, 0xea, 0xa1, 0x19, 0xe7, 0xc4, 0xe1, 0x98, 0x57, 0x19,
0x00, 0xe2, 0x04, 0x30, 0x46, 0xa9, 0x12, 0xe5, 0xb8, 0x05, 0x8c, 0x8c, 0x8b, 0x98, 0x98, 0xdd,
0x03, 0x9c, 0x56, 0x31, 0xc9, 0xb9, 0x43, 0x4c, 0x0b, 0x80, 0xaa, 0xd2, 0x0b, 0x4f, 0xcd, 0xc9,
0xf1, 0xce, 0xcb, 0x2f, 0xcf, 0x0b, 0x01, 0xa9, 0x4e, 0x62, 0x03, 0x6b, 0x37, 0x06, 0x04, 0x00,
0x00, 0xff, 0xff, 0xc6, 0x4d, 0x03, 0x23, 0xf6, 0x00, 0x00, 0x00,
}

140
vendor/github.com/golang/protobuf/ptypes/any/any.proto generated vendored Normal file
View file

@ -0,0 +1,140 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
syntax = "proto3";
package google.protobuf;
option csharp_namespace = "Google.Protobuf.WellKnownTypes";
option go_package = "github.com/golang/protobuf/ptypes/any";
option java_package = "com.google.protobuf";
option java_outer_classname = "AnyProto";
option java_multiple_files = true;
option java_generate_equals_and_hash = true;
option objc_class_prefix = "GPB";
// `Any` contains an arbitrary serialized protocol buffer message along with a
// URL that describes the type of the serialized message.
//
// Protobuf library provides support to pack/unpack Any values in the form
// of utility functions or additional generated methods of the Any type.
//
// Example 1: Pack and unpack a message in C++.
//
// Foo foo = ...;
// Any any;
// any.PackFrom(foo);
// ...
// if (any.UnpackTo(&foo)) {
// ...
// }
//
// Example 2: Pack and unpack a message in Java.
//
// Foo foo = ...;
// Any any = Any.pack(foo);
// ...
// if (any.is(Foo.class)) {
// foo = any.unpack(Foo.class);
// }
//
// Example 3: Pack and unpack a message in Python.
//
// foo = Foo(...)
// any = Any()
// any.Pack(foo)
// ...
// if any.Is(Foo.DESCRIPTOR):
// any.Unpack(foo)
// ...
//
// The pack methods provided by protobuf library will by default use
// 'type.googleapis.com/full.type.name' as the type URL and the unpack
// methods only use the fully qualified type name after the last '/'
// in the type URL, for example "foo.bar.com/x/y.z" will yield type
// name "y.z".
//
//
// JSON
// ====
// The JSON representation of an `Any` value uses the regular
// representation of the deserialized, embedded message, with an
// additional field `@type` which contains the type URL. Example:
//
// package google.profile;
// message Person {
// string first_name = 1;
// string last_name = 2;
// }
//
// {
// "@type": "type.googleapis.com/google.profile.Person",
// "firstName": <string>,
// "lastName": <string>
// }
//
// If the embedded message type is well-known and has a custom JSON
// representation, that representation will be embedded adding a field
// `value` which holds the custom JSON in addition to the `@type`
// field. Example (for message [google.protobuf.Duration][]):
//
// {
// "@type": "type.googleapis.com/google.protobuf.Duration",
// "value": "1.212s"
// }
//
message Any {
// A URL/resource name whose content describes the type of the
// serialized protocol buffer message.
//
// For URLs which use the scheme `http`, `https`, or no scheme, the
// following restrictions and interpretations apply:
//
// * If no scheme is provided, `https` is assumed.
// * The last segment of the URL's path must represent the fully
// qualified name of the type (as in `path/google.protobuf.Duration`).
// The name should be in a canonical form (e.g., leading "." is
// not accepted).
// * An HTTP GET on the URL must yield a [google.protobuf.Type][]
// value in binary format, or produce an error.
// * Applications are allowed to cache lookup results based on the
// URL, or have them precompiled into a binary to avoid any
// lookup. Therefore, binary compatibility needs to be preserved
// on changes to types. (Use versioned type names to manage
// breaking changes.)
//
// Schemes other than `http`, `https` (or the empty scheme) might be
// used with implementation specific semantics.
//
string type_url = 1;
// Must be a valid serialized protocol buffer of the above specified type.
bytes value = 2;
}

35
vendor/github.com/golang/protobuf/ptypes/doc.go generated vendored Normal file
View file

@ -0,0 +1,35 @@
// Go support for Protocol Buffers - Google's data interchange format
//
// Copyright 2016 The Go Authors. All rights reserved.
// https://github.com/golang/protobuf
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/*
Package ptypes contains code for interacting with well-known types.
*/
package ptypes

102
vendor/github.com/golang/protobuf/ptypes/duration.go generated vendored Normal file
View file

@ -0,0 +1,102 @@
// Go support for Protocol Buffers - Google's data interchange format
//
// Copyright 2016 The Go Authors. All rights reserved.
// https://github.com/golang/protobuf
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package ptypes
// This file implements conversions between google.protobuf.Duration
// and time.Duration.
import (
"errors"
"fmt"
"time"
durpb "github.com/golang/protobuf/ptypes/duration"
)
const (
// Range of a durpb.Duration in seconds, as specified in
// google/protobuf/duration.proto. This is about 10,000 years in seconds.
maxSeconds = int64(10000 * 365.25 * 24 * 60 * 60)
minSeconds = -maxSeconds
)
// validateDuration determines whether the durpb.Duration is valid according to the
// definition in google/protobuf/duration.proto. A valid durpb.Duration
// may still be too large to fit into a time.Duration (the range of durpb.Duration
// is about 10,000 years, and the range of time.Duration is about 290).
func validateDuration(d *durpb.Duration) error {
if d == nil {
return errors.New("duration: nil Duration")
}
if d.Seconds < minSeconds || d.Seconds > maxSeconds {
return fmt.Errorf("duration: %v: seconds out of range", d)
}
if d.Nanos <= -1e9 || d.Nanos >= 1e9 {
return fmt.Errorf("duration: %v: nanos out of range", d)
}
// Seconds and Nanos must have the same sign, unless d.Nanos is zero.
if (d.Seconds < 0 && d.Nanos > 0) || (d.Seconds > 0 && d.Nanos < 0) {
return fmt.Errorf("duration: %v: seconds and nanos have different signs", d)
}
return nil
}
// Duration converts a durpb.Duration to a time.Duration. Duration
// returns an error if the durpb.Duration is invalid or is too large to be
// represented in a time.Duration.
func Duration(p *durpb.Duration) (time.Duration, error) {
if err := validateDuration(p); err != nil {
return 0, err
}
d := time.Duration(p.Seconds) * time.Second
if int64(d/time.Second) != p.Seconds {
return 0, fmt.Errorf("duration: %v is out of range for time.Duration", p)
}
if p.Nanos != 0 {
d += time.Duration(p.Nanos)
if (d < 0) != (p.Nanos < 0) {
return 0, fmt.Errorf("duration: %v is out of range for time.Duration", p)
}
}
return d, nil
}
// DurationProto converts a time.Duration to a durpb.Duration.
func DurationProto(d time.Duration) *durpb.Duration {
nanos := d.Nanoseconds()
secs := nanos / 1e9
nanos -= secs * 1e9
return &durpb.Duration{
Seconds: secs,
Nanos: int32(nanos),
}
}

Some files were not shown because too many files have changed in this diff Show more