diff --git a/Makefile b/Makefile index fbd49aa8..8aef1f1d 100644 --- a/Makefile +++ b/Makefile @@ -20,7 +20,7 @@ REPO := $(notdir $(shell pwd)) BIN := installer # Produce CRDs that work back to Kubernetes 1.11 (no version conversion) -CRD_OPTIONS ?= "crd:trivialVersions=true,preserveUnknownFields=false" +CRD_OPTIONS ?= "crd:trivialVersions=true,preserveUnknownFields=false,crdVersions={v1beta1,v1}" # https://github.com/appscodelabs/gengo-builder CODE_GENERATOR_IMAGE ?= appscode/gengo:release-1.18 API_GROUPS ?= installer:v1alpha1 @@ -225,7 +225,7 @@ gen-bindata: .PHONY: gen-values-schema gen-values-schema: - @yq r api/crds/installer.kubepack.com_kubepackoperators.yaml spec.validation.openAPIV3Schema.properties.spec > /tmp/kubepack-operator-values.openapiv3_schema.yaml + @yq r api/crds/installer.kubepack.com_kubepackoperators.v1.yaml spec.versions[0].schema.openAPIV3Schema.properties.spec > /tmp/kubepack-operator-values.openapiv3_schema.yaml @yq d /tmp/kubepack-operator-values.openapiv3_schema.yaml description > charts/kubepack-operator/values.openapiv3_schema.yaml .PHONY: gen-chart-doc diff --git a/api/crds/bindata.go b/api/crds/bindata.go index f436c027..f7c7cf85 100644 --- a/api/crds/bindata.go +++ b/api/crds/bindata.go @@ -1,5 +1,6 @@ // Package crds Code generated by go-bindata. (@generated) DO NOT EDIT. // sources: +// installer.kubepack.com_kubepackoperators.v1.yaml // installer.kubepack.com_kubepackoperators.yaml package crds @@ -77,6 +78,26 @@ func (fi bindataFileInfo) Sys() interface{} { return nil } +var _installerKubepackCom_kubepackoperatorsV1Yaml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x5d\xef\x72\xdc\xb8\x91\xff\xee\xa7\xe8\xf2\x5d\x95\xa5\x8b\x66\xb4\x9b\x5c\x5d\xdd\x69\x53\x49\xe9\x6c\xef\x96\x6a\xfd\x47\x65\x79\x77\x73\xb7\xc9\x6d\x61\xc8\x9e\x19\x44\x24\xc0\x05\x40\xc9\x93\xdb\x7b\xf7\x2b\x34\x40\x0e\x39\x43\x82\x20\x2d\x39\x4e\x42\x7c\xb1\x35\x24\x9b\x0d\xa0\xbb\xd1\xe8\x5f\x37\xc8\x0a\xfe\x3d\x2a\xcd\xa5\xb8\x00\x56\x70\xfc\x60\x50\xd8\xbf\xf4\xf2\xf6\xdf\xf5\x92\xcb\xf3\xbb\x2f\x9f\xdc\x72\x91\x5e\xc0\xf3\x52\x1b\x99\xbf\x43\x2d\x4b\x95\xe0\x0b\x5c\x73\xc1\x0d\x97\xe2\x49\x8e\x86\xa5\xcc\xb0\x8b\x27\x00\x89\x42\x66\x7f\x7c\xcf\x73\xd4\x86\xe5\xc5\x05\x88\x32\xcb\x9e\x00\x64\x6c\x85\x99\xb6\xf7\x00\xb0\xa2\xb8\x80\x3b\x56\x66\xe6\x09\x80\x60\x39\x5e\xc0\x6d\xb9\xc2\x82\x25\xb7\xb2\x40\xc5\x8c\x54\x7a\xc9\x85\x36\x2c\xcb\x50\x2d\xab\x6b\xcb\x44\xe6\x4f\x74\x81\x89\xa5\xb2\x51\xb2\x2c\x2e\xa0\xe7\x2e\x47\xd6\xbf\x2e\x61\x06\x37\x52\xf1\xea\xef\x45\xfd\x36\xff\x27\x2b\x0a\x9d\xc8\x14\xe9\x4f\xd7\xdb\x6f\xfd\x1d\x6f\x3d\x3f\x74\x29\xe3\xda\x7c\xdb\x79\xf9\x15\xd7\x86\x6e\x29\xb2\x52\xb1\xac\xa3\x3f\x74\x55\x73\xb1\x29\x33\xa6\x8e\xaf\x3f\x01\xd0\x89\x2c\xf0\x02\xde\x58\xc6\x0b\x96\x60\xfa\x04\xe0\xce\xcd\x0d\x31\xbe\xf0\x43\x75\xf7\x25\xcb\x8a\x2d\xfb\xd2\x51\x4c\xb6\x98\x33\xd7\x2f\x00\x59\xa0\xb8\xbc\xbe\xfa\xfe\x37\x37\xad\x9f\x01\x0a\x65\x5f\x64\xea\x21\x70\xad\x31\xf9\x8d\x5f\x01\x52\xd4\x89\xe2\x85\x21\xa9\x78\x66\x09\xba\xbb\x20\xb5\xb3\x8e\x1a\xcc\x16\x2b\xd6\x30\xf5\x3c\x80\x5c\x83\xd9\x72\x0d\x0a\x0b\x85\x1a\x85\x21\x49\x68\x11\x06\x7b\x13\x13\x20\x57\x7f\xc6\xc4\x2c\xe1\x06\x95\x25\x03\x7a\x2b\xcb\x2c\x85\x44\x8a\x3b\x54\x06\x14\x26\x72\x23\xf8\x5f\x6a\xda\x1a\x8c\xa4\x97\x66\xcc\xa0\x1f\xe9\x7d\xe3\xc2\xa0\x12\x2c\x83\x3b\x96\x95\x78\x06\x4c\xa4\x90\xb3\x1d\x28\xb4\x6f\x81\x52\x34\xe8\xd1\x2d\x7a\x09\xaf\xa5\x42\xe0\x62\x2d\x2f\x60\x6b\x4c\xa1\x2f\xce\xcf\x37\xdc\x54\x42\x9f\xc8\x3c\x2f\x05\x37\xbb\xf3\x44\x0a\xa3\xf8\xaa\xb4\x53\x78\x9e\xe2\x1d\x66\xe7\x9a\x6f\x16\x4c\x25\x5b\x6e\x30\x31\xa5\xc2\x73\x56\xf0\x05\xb1\x2e\x0c\x69\x4e\x9e\xfe\x93\xf2\x6a\xa2\x9f\xb5\x78\x35\x3b\x3b\xc3\xda\x28\x2e\x36\x8d\x0b\x24\x72\x81\x19\xb0\x32\x07\x5c\x03\xf3\x8f\xba\x5e\xec\x07\xda\xfe\x64\x47\xe7\xdd\xcb\x9b\xf7\x50\xbd\x9a\x26\xe3\x70\xf4\x69\xdc\xf7\x0f\xea\xfd\x14\xd8\x01\xe3\x62\x8d\xca\x4d\xe2\x5a\xc9\x9c\x68\xa2\x48\x0b\xc9\x85\xa1\x3f\x92\x8c\xa3\x38\x1c\x7e\x5d\xae\x72\x6e\xec\xbc\xff\x5c\xa2\x36\x76\xae\x96\xf0\x9c\x09\x21\x0d\xac\x10\xca\x22\x65\x06\xd3\x25\x5c\x09\x78\xce\x72\xcc\x9e\x33\x8d\x8f\x3e\x01\x76\xa4\xf5\xc2\x0e\x6c\xdc\x14\x34\x8d\xd8\xe1\xcd\x6e\xd4\x1a\x17\x2a\x1b\xd4\x33\x5f\x87\xc6\xe1\xa6\xc0\xc4\x4e\x9f\x1d\x41\xaf\x2b\x6b\xa9\xea\xdb\xa0\x65\x63\xf6\xcd\x89\x2a\xac\x79\x86\xad\x2b\xdd\xba\x6c\x1b\x5b\x93\x51\xde\x1d\xfe\x7e\xc0\xdf\xd5\x9a\x7a\xc0\xd7\x1c\xd3\x33\xe2\xaa\x90\xe9\x33\x4d\xbc\xa5\x65\x66\xa5\x29\x91\x42\x1b\xc5\xb8\x30\x87\x22\x14\x7a\xbf\x6d\x42\xa6\x78\xd9\xcb\xc7\x11\x2f\x2f\xe8\x8f\x15\x6a\x7a\xb0\xee\x41\x93\x17\x55\x66\x76\x18\xa4\x95\x4c\xec\xa4\x08\xb6\x03\xcb\xce\x4b\x61\x66\xdd\x1d\xb8\x46\xa5\x30\x7d\x51\x5a\x99\xb8\xa9\x5f\x7c\xb5\x11\xb2\xfe\xf9\xe5\x07\x4c\x4a\x73\x64\x29\x7b\xfb\xf5\xde\xcf\x75\x5a\x66\xa8\xe0\x9e\x67\x99\x7f\x91\xb5\x64\xd5\x05\xcb\xb6\x55\x97\x5e\x92\x6e\x38\xad\xe4\x30\x03\x9a\x19\xae\xd7\x3b\x9a\xb0\x7a\x9c\xf0\x83\x55\x65\x5a\x23\xf6\x93\x0a\xab\x5d\x80\xa4\xd3\x6f\x8e\x59\x7a\x06\xab\xd2\x00\x37\xa4\xfc\xc9\x56\x4a\x8d\xc0\xdc\x44\xd0\x1b\xef\xb8\x24\x83\x0b\x52\x20\x1c\xc9\x67\xb3\xe5\x56\x9b\x69\x01\xc0\x26\x4b\x4b\x1a\x87\x3d\x41\xae\x21\x97\xda\xec\xc7\x3c\x40\xd2\x2b\x8c\x7d\xf5\x3d\x37\x5b\xfa\x63\x63\xdd\x0b\xd4\x06\x74\x99\xdb\xd7\xdd\x23\xdf\x6c\x8d\x3e\x03\xbe\xc4\x25\x89\x08\xb2\x64\x3b\x30\x9c\x8e\x95\x1c\xd1\x68\x60\x59\x56\xb1\xdd\x94\x38\xfc\xb9\xe4\x0a\x73\x6b\x21\xe1\xa4\x32\xa8\x01\xb2\xde\xf4\x9d\x55\x4f\x1e\xc9\x52\xe7\x84\x9d\x05\x28\xa2\x49\x96\xa7\x67\x90\xc8\xbc\x28\x8d\x9d\x15\xdb\xe3\xd5\x0e\xb8\xb1\xb6\xc2\x19\x7c\x25\xcb\x8d\x1b\x17\xcc\x3c\xb3\x72\x1d\x35\xf1\xb4\x44\xb2\x34\xb5\x74\x9e\xba\x41\x7c\x5a\x2d\xb1\xf6\x45\xdc\x0d\x09\x8d\x56\xce\x4c\xb2\xc5\x63\x33\xd0\xa4\x8b\x90\x48\xa5\x50\x17\x52\x10\x4d\x7a\xe6\xe5\xbe\xa7\x5f\xd5\xe4\x4e\xf4\x69\x3d\x9d\x01\x92\x5b\xbe\xd9\x56\xf3\xcc\x14\xd2\xe3\x6d\xc9\xe9\x56\x77\xdb\xb8\xc1\xbc\x57\xdb\xe1\x50\x51\x2f\x05\x60\x5e\x98\xdd\x9e\x72\x53\x12\x0c\xaa\x3c\x62\x04\xc0\x09\x12\xad\x13\xda\xf5\x8f\xe7\x45\xc6\x13\x6e\xbc\x8c\xc2\x17\x70\x42\x42\xca\xcd\x33\x4d\x4a\xb6\x90\xc5\x69\x7f\x27\x6c\xbb\x24\xdf\x79\x98\x31\x10\xb2\x7e\x37\xbd\x24\x48\xd5\xfa\x11\x99\x96\x51\x3c\x0c\x5b\xcf\xea\x3e\xcb\x22\x8a\x04\xc3\xf7\x1d\x8e\xbd\x93\x30\x8d\x19\x26\xc6\xda\x77\x54\xf9\x19\x30\xad\x65\xc2\xad\xcf\x10\x23\x29\xae\xb5\xc5\xcf\x0d\x79\x78\x18\xe2\x3b\x67\xdb\xa1\x40\x0f\x3f\x71\xd4\x55\xbb\x79\xb0\xb6\xa6\xdd\xe5\xa6\xa9\x89\xa0\x09\xd6\x06\x58\x0a\xcf\xb4\xdf\x51\x0d\xf5\x12\x62\x34\xa2\x97\xe9\x5e\x66\x49\x8c\xa2\x28\x42\x63\x7e\xad\xe1\xb5\x0e\x1d\xe3\x42\x7b\xff\xe6\x0c\x18\xdc\xe2\xce\x79\xed\xec\x70\xbb\xd0\xd7\xaa\x6d\x93\x23\xa9\xd0\x2d\x53\xd6\x4a\xdc\xe2\x8e\x48\x79\x47\x3f\x8a\xde\x18\x49\x70\xed\x16\x7b\x9c\x9b\xae\x76\xe4\x18\xd0\xcc\x11\xa7\xc4\x3e\x59\x5d\x3f\x46\xd1\x44\x69\x17\x9d\x71\x24\x77\x3b\xfa\xa9\x1e\xef\x37\xd4\xaa\xa1\x9e\xd8\xdf\x77\xf5\x5e\xc3\x4d\xf4\x33\xed\xa6\xcb\x6a\xd1\x96\x17\x23\xfa\x6b\xac\xcd\xd2\x48\x4a\x54\x6d\xe3\xbe\x67\x19\x4f\x6b\x16\xb5\x5d\x2b\x46\x50\xbc\x12\x67\xf0\x46\x1a\xfb\xcf\xcb\x0f\x5c\x5b\x47\xe2\x85\x44\xfd\x46\x1a\xfa\x73\x09\xdf\x18\x92\xcb\x11\x24\x5f\x0d\x9a\x9d\x46\x87\xc6\x4f\x86\xeb\xf7\xc4\xa9\xb8\x14\xc0\x94\x62\x3b\x3b\x80\xcd\x8d\xa4\x5e\xc2\x55\xc8\x6f\x38\xe2\xdb\xba\x65\x95\x02\x72\x6d\x37\x76\x52\x55\x03\x49\xa1\x01\xa2\x3a\x46\x94\x89\xad\xbc\xd4\xb4\x63\x14\x52\x2c\x68\x4d\xb6\x7c\xb5\xde\x36\x82\x24\xd7\x7e\x4e\x2d\x6f\xcd\x59\x6d\xb2\xe8\x5e\x3c\x82\x6a\xc5\x62\x37\x7b\xf6\xa5\xdf\x98\xb0\xa7\x7c\xd8\x5e\x75\x30\xe4\x5e\xb3\x65\x77\xe4\xf8\x71\xb1\xc9\xc6\x48\xb5\x77\x06\xcf\xe0\x7e\xcb\x93\xad\xdb\x7b\xac\xd0\x45\x49\x0a\x85\x76\x5d\x65\x3a\xde\xd4\x82\x8f\xb0\x6c\x50\x59\x77\x9e\x57\x3c\xba\x48\x4f\xc6\x12\x4c\x21\x25\x77\x37\x7a\x41\xb0\xcd\x6e\x2f\x0d\x6e\x78\x02\x39\xaa\x0d\x42\x61\x57\xd8\x78\xdd\x19\xb1\xa4\xb9\x36\x41\xd9\xaa\x87\xe2\x85\xa4\x72\xff\xe3\x18\x5b\x58\x7b\x18\x79\xe7\x28\x0d\xe8\x09\x5b\x84\x6f\x8f\xeb\x25\x39\x42\x5f\xdb\x3d\xc4\x67\xe1\x03\xd1\x6e\x66\xf6\x81\x66\x1f\x68\xf6\x81\x66\x1f\xa8\xa7\xcd\x3e\xd0\xec\x03\xcd\x3e\x10\xcc\x3e\xd0\xf0\xed\x31\xbd\x8c\x26\xec\xa2\x50\xa3\x02\x62\x3f\xb8\x58\xe1\x61\x04\x8c\x9c\xae\x0a\xe4\x6b\x85\xba\x06\x7b\x66\x9d\x97\x1b\xbf\xae\xbe\xa7\xf0\x1a\x17\x44\x46\x31\xb1\x41\xf8\x72\xf1\xe5\x17\x5f\x0c\x49\xdc\x5a\xaa\x9c\x99\x0b\xab\x01\xbf\xf9\x75\xd4\xe8\x78\x5d\x19\x88\x98\x0f\x49\xc9\xa2\x11\x57\x0c\xde\xe6\x46\x3a\x14\xa1\x8e\x99\xb3\x61\x11\xe8\x8b\xee\x7f\x14\x52\xe4\xed\x67\x0d\x10\xb4\xc0\x87\x26\xa4\xd3\x05\xe8\x36\x9b\x8f\xec\x2b\xbb\x78\x18\xc8\xd1\x00\x33\xad\x90\x31\xcf\xb1\x86\xfb\x9c\x49\x74\x10\x6d\x80\x66\x85\x54\xa5\x20\x85\xc7\x07\xac\x44\x2d\x23\xb9\x0e\x50\xf6\xfd\xf1\x5c\x27\xc8\x34\x5a\xef\x66\x85\x35\xe7\x32\xb7\x9c\x72\x61\x2a\xd3\x6a\xd9\xc6\x6a\x74\x03\xa4\x4f\x70\xb9\x59\x42\x5a\x12\x41\x26\x3c\x02\x7d\xea\xfa\xae\x77\xda\x60\x4e\x88\x97\x54\xf4\x8f\x1d\x04\xa3\x76\x61\x1c\x0e\xef\x50\x98\x92\x65\xd9\x0e\xf0\x8e\x27\xa6\x1e\x47\x02\xca\xb9\x71\xf8\x65\xbf\x26\xc5\xb9\xd7\x87\xda\x3a\x60\xdd\x0f\x9c\x4c\x27\x9c\xcb\xde\x7d\x96\xb1\x14\x87\x94\xdd\xfa\xe6\x74\x23\x49\xd2\xdb\x77\x21\xa4\x05\x62\x17\xa1\xc3\x1d\x55\x99\x65\x76\xf4\x1d\xf0\x72\xcc\x64\x14\xe2\x02\x34\x5e\x15\xf0\xe1\x90\xc6\x96\x14\x3a\x5c\xcf\xe1\x47\x97\x6f\x5e\xd8\x91\x79\x1f\x01\x25\xbc\x97\x85\xcc\xe4\x66\xd7\x9c\x07\xb2\x0d\x04\xe9\x78\xda\x0c\x74\xb9\xf2\x7e\x78\x0c\x3e\xf1\xe6\x60\x62\x67\x6c\xa2\x6a\xf3\xbe\x3c\xdc\xe6\x7d\x79\xa0\xcd\xfb\xf2\x79\x5f\x7e\xc0\xf7\xbc\x2f\x9f\xf7\xe5\xf3\xbe\xbc\xa3\xfd\xbd\xef\xcb\x67\x6c\x62\xf6\x81\xea\x36\xfb\x40\x81\x36\xfb\x40\x91\x1d\x9a\x7d\x20\xdf\x66\x1f\x68\xf6\x81\x66\x1f\x28\x74\xe7\xe7\xe1\x03\x45\x13\x8e\x21\x39\x3c\x58\x8b\xe3\x80\xe5\x40\x74\x3d\xc0\xda\xc0\x0d\x85\x4c\x27\x95\x95\x14\x32\x0d\x54\x95\xb8\x50\x71\x22\x17\x99\x4c\x98\xe9\xd3\x62\x0a\x54\x5b\x42\x1e\x3b\xd1\x2c\x77\x71\xf0\x33\xf8\x8b\x14\x78\x46\xd9\xfa\x56\x69\x29\x66\x2d\xcd\x16\x95\xbd\xfd\x44\x9f\xf6\x64\x57\xcf\x55\x29\xdd\x63\x3c\x57\xa5\xcc\x55\x29\x71\x55\x29\x5b\x16\xf2\x5f\x48\x82\xdd\xf2\x5a\xd5\x48\x1c\x17\xa9\x34\x2c\x8a\x35\x5d\x5f\x0d\x04\xf2\x0f\xab\x57\x3e\x61\x8d\x8a\x15\x57\x2f\x54\x54\x40\xbb\x17\x0f\xd7\xbb\xd4\x03\xc7\x98\x5e\xb7\xfb\x14\x5c\x03\xdc\xfe\x94\x58\x67\x69\x8a\x29\x14\xa8\x16\x4e\x14\x25\xac\xb9\x48\x3b\x7a\x54\x8d\x42\x68\xec\x63\x6b\x46\xda\xac\x8e\x82\x90\x9a\x58\x57\xcb\xc0\x1f\x56\x90\x0c\xae\xae\xf5\x6c\x3e\x76\x05\x09\xed\x29\xab\xa5\x72\x4a\x78\x82\xf6\xa4\x3f\x97\xa8\x76\x20\xef\x50\xed\xf7\x5a\x75\xad\x71\x48\x73\xf7\x8d\xd6\x30\xae\x21\x61\xda\x99\xfa\x18\xa7\x6e\xec\x0e\x7c\x0a\x26\x05\x87\x9d\x3e\x24\xe2\x4a\xa0\xab\x38\x0d\x0d\x48\xb4\xa7\xd8\x19\xd0\xe9\x00\x0d\xc7\x6c\x50\x1d\xa8\x18\x79\xfb\x48\x87\xb8\x73\xf6\xbb\x3a\x31\x6e\xcb\xc5\xe2\x82\x3d\x63\xb6\x86\x14\x16\x1a\x0e\xf8\x8c\x20\x39\x26\x34\x04\x93\xc2\x43\x30\x36\x44\x04\x87\x53\x62\x7b\xe5\x7d\x81\x76\xb4\x68\x14\x49\x68\xc5\x96\x26\x45\x8c\x60\xea\xde\x69\x4a\xe4\x08\x0e\x87\xa1\x9e\x76\x75\x14\x46\x1a\x39\x10\xcd\xa0\x53\x7f\x28\x69\x24\xd1\x56\xe0\xe9\x38\x9c\x34\x52\x2e\x6d\x6b\xc5\x9f\x3e\xc5\x24\x8d\x8d\x28\xc1\xe1\x14\xf9\xc0\x85\x55\xfe\xa3\xf8\xd2\xc8\xce\xef\xa3\x51\xc1\x18\xd3\x04\x15\x38\x8e\xae\xb4\xe2\x4c\x23\x29\x76\xf0\xd7\x13\x6b\x7a\x28\x56\x7d\xbc\xe9\x7d\x38\x43\xab\xab\xf5\x07\x6b\xf6\x21\x98\x91\x24\x27\x05\x6c\x60\x4a\xd0\x06\xa6\xcb\xf5\xf8\xe0\x0d\x8c\x0e\xe0\xc0\xa8\x20\x0e\x8c\x0f\xe4\xc0\xf8\x60\x0e\x4c\xe8\x39\x39\x42\xaf\x1a\x07\x28\x0d\x37\xbb\x8d\xb2\xfa\xcf\xb2\xeb\x09\xab\xe3\x84\x39\x3d\xf6\xdc\x1c\xc3\xce\xeb\xc8\x59\x61\xad\xce\xff\x5a\xe7\x82\x14\xe8\xff\xe2\x57\x77\xc6\x95\xb6\x8e\xbe\x0b\xb4\x36\x69\x54\xf1\x98\xc6\xeb\xa2\xc9\x5a\x8e\xb8\x06\x2b\x4f\x77\x2c\x43\x61\x7c\xb2\xa0\xdf\xb4\x5a\x6e\x0f\xfd\xcf\x78\x6b\x71\xbf\x95\xda\x79\x3e\x6e\x63\xcb\x35\x3c\xbd\xc5\xdd\xd3\xb3\x43\xbb\x14\x4d\xf1\xe9\x95\x78\xea\x30\xb8\x23\x1b\x54\xfb\x70\x52\x64\x3b\x78\x4a\xd7\x9e\xc6\x2b\x7e\x97\x0b\x3c\xce\xb5\x9d\x14\xce\x8c\xbc\x5d\x54\xa7\x61\x8d\x87\x74\xf7\x8f\xd6\x31\xa8\x2a\x28\xb0\xbf\x14\x17\xaf\xad\xbc\xbc\x9b\x63\x4f\x0d\x4e\xaa\x08\x03\xdb\xd8\x59\x30\xa7\x5f\x45\xd1\x6c\xe7\x40\xd2\xa6\x26\x47\x26\x34\x3c\xad\xa2\x8d\xcf\xf4\x9e\xcf\xa7\x0f\x8b\x22\x8f\xd4\xef\x31\xf6\xca\xf8\xf4\xc9\x6f\xe3\xdc\xeb\x83\x38\x87\x8f\xb3\xfa\xf3\xc0\x56\xb8\x0f\xcd\xa6\x70\x52\xed\xf2\x43\xd1\x87\x7d\x93\x8a\x32\x7b\x5b\x04\x84\xe1\x8b\x9a\xca\x7e\xef\x6f\x77\xc1\xf1\x86\xb8\x4a\xc4\x6f\x4b\x44\x15\x1a\xae\xa3\x9d\x7b\x19\x8b\xb3\x1b\xf7\x5b\x54\xad\xfe\x72\xed\xcf\x5b\x23\x3c\x48\x95\x42\xd8\x37\x4b\xe1\x83\xa1\x91\x44\xad\x21\x72\xc7\x85\xf9\x90\x91\xdb\xae\x50\xdf\x69\xcf\xb2\x9f\xaf\xf8\x21\xa8\x82\xbf\x74\x9a\x9b\xcf\xe0\x95\xc2\x2b\x97\xfd\xa5\x8a\x5e\xd2\xe8\x44\x84\x61\xa0\x0a\xda\xf1\xba\xa7\x4b\x78\x49\xaa\xd1\x60\xd0\x5e\xb5\x73\xca\xb2\x4c\xde\xc7\xd9\xa7\x11\x92\x1e\xeb\x5b\x2c\x46\x8c\xd9\x63\x16\x8b\xdc\x3f\x78\xb1\xc8\x41\x48\xee\x6f\xac\x56\x24\x3a\xf4\x39\x17\x8c\xb8\x36\x17\x8c\xf8\xd6\x2e\x18\xa1\xc7\x9c\x95\x0c\x57\x8e\x04\xc1\x82\xaa\xa6\x24\xb6\x72\x04\x7e\xd8\x62\x88\x47\x43\xcb\x83\x9d\xac\xbc\xcc\x0c\x2f\xb2\x3d\xbe\xe2\xd8\xcb\xdc\x06\x77\xed\xc1\xb9\x58\xcd\xb7\x1c\xb2\x64\x7b\xa8\x3e\xf4\x26\x4a\x49\xd0\x64\xc1\x3d\x98\xc5\xb2\xcc\x55\x87\x84\x50\x37\xbf\x27\x76\xc8\x20\x7f\x38\x18\xe4\x85\x3f\x7d\xb4\x0e\x0d\xd1\x8a\x71\x62\x17\xda\xcc\x0a\x87\x5d\xea\x2a\xeb\x17\x46\xbf\x8f\x56\x6f\x17\x7d\xba\xc3\x0a\x6e\xda\xf0\x3b\x14\xfb\x25\xfc\x44\x9f\x86\x9d\x0e\x9f\x27\x16\xe7\xbe\x1c\xbb\x26\x41\xda\x5d\x6e\xcb\x59\xa4\xbb\x10\x24\x5c\xbb\x12\x11\x6e\xc2\x6f\x1b\x6b\xde\xef\x82\x54\x23\x1c\x04\x1a\xa4\xda\x45\x30\x61\x7c\xf0\xc8\x31\x78\x00\xec\x69\x14\x18\xf3\x18\x40\xcc\x68\x10\xe6\x93\x16\x04\x3d\x14\xf0\x32\x02\x74\x89\xdf\x71\x4e\x4f\x96\xed\x07\x51\xe6\x6c\xd9\x89\xc8\x54\x2f\x0c\x12\x55\x15\xb7\x6f\x1f\x05\x81\x7c\xfa\xa4\xd9\x00\xec\xf1\x19\x67\xcf\x92\x24\x4d\x03\x30\x3e\x75\x2a\xec\x03\x81\x16\x0f\x0f\x58\x44\x80\x15\xfe\x6d\x13\x80\xb8\x81\xa4\xd8\xd1\x1d\xef\x07\x29\x6a\xd8\x61\x04\xcd\x00\x40\x31\xe7\x88\xc6\xdc\xf9\x79\xe4\x88\x8e\x86\x13\xa6\x43\x09\x23\xe7\xeb\x51\x20\x84\x47\x80\x0f\x1e\x0d\x3a\x88\x86\x0d\x1c\x1c\x10\x45\x73\x04\x64\x10\x55\x1e\x0f\x7b\x15\x99\xe0\xbc\x8d\x90\xea\xe8\x5b\xe3\x21\x82\xf1\xf0\x40\x94\xd9\x1d\x01\x0d\x54\x61\xff\x41\x9a\x0f\x03\x0b\x44\x5a\xd8\x11\x7a\x1a\x6b\x67\x46\xc0\x00\x8f\x03\x01\x8c\x0c\xff\xc7\x05\x0e\xa0\x33\x78\x10\x0a\xfd\xbb\x7d\xfa\x20\xd1\xf8\xb0\x7f\x73\xaf\x3e\x3c\x08\x43\x21\xff\xc3\xdd\xfa\x20\xc5\xa8\x70\xff\x51\x28\x7f\x90\xec\xc7\x86\xfa\x23\x25\x38\x2e\x92\x1c\x17\xde\x7f\x90\x10\x71\x44\xd1\x83\x30\x7c\x7a\xe1\x43\x53\xe2\x7b\xaa\x1f\x7a\x78\x67\x77\x92\xa7\x50\x94\xc6\xa7\x75\x8f\xa8\x80\xe8\xa1\xf8\x0f\x5c\x17\xd1\x9a\x86\xce\xe2\x88\xd8\xc0\xf7\x98\xe2\x88\x00\x4d\xa9\xe6\xe2\x88\xc1\xe2\x88\xbe\x59\x9b\x2b\x24\xfa\x67\x6a\xae\x90\x98\x2b\x24\x26\x74\x15\xe6\x0a\x89\xc8\x80\xc6\x5c\x21\xe1\xdb\x5c\x21\x31\x57\x48\xc4\x13\x99\x2b\x24\xc2\x3d\x9c\x2b\x24\xe6\x0a\x89\xb9\x42\x62\xb0\xcd\x15\x12\x73\x85\x44\x83\xc1\xb9\x42\x62\xae\x90\x88\x69\x73\x85\xc4\x5c\x21\xb1\xbf\x77\xae\x90\x98\x2b\x24\xe6\x0a\x89\xd6\xeb\xe7\x0a\x89\xce\x36\x57\x48\x7c\x54\x85\x44\x2b\x80\xdf\x5b\x26\x11\x19\x79\x1f\x51\x26\x11\x8c\x91\xbb\xdc\xf8\xa1\x32\x89\x5e\xd6\x03\xb4\x8f\x6a\x3f\x46\xd4\x4a\x84\xa1\x82\x7d\x15\xc5\xa8\x5a\x89\x00\xd1\xce\xef\x6f\x0c\xd7\x4a\x0c\xa0\x0f\xae\x8a\x62\x6c\xad\x44\x80\x68\x3b\xe6\x3d\xaa\x56\x22\x40\xb5\xae\xa2\x98\x6b\x25\xe6\x5a\x89\xb9\x56\x62\xa0\xcd\xb5\x12\x73\xad\xc4\xbe\xcd\xb5\x12\x73\xad\xc4\x5c\x2b\x31\xd7\x4a\xcc\xb5\x12\xe1\x36\xd7\x4a\x0c\xdc\x3e\xd7\x4a\x1c\xb5\xb9\x56\x62\xae\x95\xa8\xda\x5c\x2b\xd1\xdd\xe6\x5a\x89\xb9\x56\x62\xae\x95\xf0\xed\xf3\xa9\x95\x08\x5c\x64\x42\x48\xe3\xb6\x19\xc7\x7d\x89\x5d\xb0\x83\x83\x16\x7a\x79\xc1\x35\xaa\x3b\xec\xd8\x3d\x85\xf7\x9e\xab\x5d\xc1\xb4\xa6\x5d\x0d\xe5\x8d\xff\x80\xab\xad\x94\xb7\x7f\x50\xac\xc7\x48\x38\x26\x56\x52\x66\xd8\xb9\x99\x4e\x58\xe8\xb9\x5e\x71\x40\xc1\x56\x19\xbe\x2e\x4d\x93\x8b\x69\x1c\x38\x52\x47\x5d\x9a\x46\x6c\xa3\x64\x59\x5c\x2b\x2e\x15\x37\xbb\xd7\x5c\xf0\xbc\xec\xc9\x90\x1e\x06\x5c\x86\x60\x96\x2d\xb2\xcc\x6c\x93\x2d\x26\x3d\xcc\x0e\x87\x11\x5c\xdf\x03\xca\x34\xd4\xdf\x41\x25\xb2\x62\xc6\xc5\xe6\x39\x2a\xd3\xc3\xc5\x30\x97\x09\x7b\xae\x02\x10\x5b\x84\xe5\xd8\xa0\xb0\x9e\x17\x7e\x4c\x47\x5d\x5f\x50\x7d\x2c\x2f\x8e\x4a\x70\x55\x1d\xa4\x12\xb6\x82\x8b\xba\xbf\x53\x66\xac\xd4\xf8\x6d\xb9\xc2\xda\x44\x7c\xfd\x73\x2a\xbe\x96\xea\xf2\xb6\x67\x7e\x86\x46\xee\x0e\x95\x75\xa0\x2b\xa5\x78\x1c\x6d\xe8\x1f\x90\x05\x24\xc7\x71\xc1\x45\xb7\x01\xe9\xbd\xef\xc8\x3a\x74\xdc\xd9\xa5\xfa\x1d\xb7\x35\xb4\xb6\xe3\x6a\x53\x5d\x3a\x2e\xf7\xcf\x4d\xc7\xcd\x07\x03\x3f\x66\x7d\x48\xec\x5c\x8e\x5f\x1d\x14\x6e\xb8\x36\x2a\xb8\x14\xf4\x4a\xb5\xc2\x42\x6a\x6e\xe4\xc4\xc7\x0d\xdb\x4c\x78\x2e\x24\x37\x55\x6f\x3a\x2f\x55\xbc\x76\x5c\x34\x6c\xd4\x5a\x9c\x28\x6e\x78\xc2\xb2\xcb\x34\xed\x82\x92\x43\xea\xe5\x84\xf3\x52\xb0\x6c\x67\x78\xd2\x31\x25\xa1\x87\xd7\x65\x96\x59\x37\xf7\xed\x1d\x2a\xc5\xd3\x0e\xdb\x18\x18\x39\x9e\xb3\x0d\x5e\x97\x59\x76\x2d\x33\x9e\x74\xcc\x58\xcc\xb3\x37\x98\x28\xec\x5a\x16\x7a\x37\x3d\x11\xfe\x4e\x97\xa7\x96\xc9\xcd\x2b\xbc\xc3\xec\x98\x64\xd8\xee\x84\x6c\x4e\x2e\x85\x15\x00\x2e\x3a\xc4\x2e\xac\x25\x6c\x83\xa2\x67\x09\x19\x90\xf1\x70\xcc\x7b\xc8\x10\x17\x4a\xe6\x68\xb6\x58\x4e\x5e\x88\xeb\x5d\xd1\x47\x2c\x5d\x31\xfe\x42\x82\xaf\xdd\xe8\x4e\x65\x34\x1b\x08\x8d\x8d\x0d\x88\x45\x6d\x4e\x3e\xee\x5b\x72\x21\x4b\x44\x12\xd3\xf1\xfb\x7e\x46\xfb\x96\x92\x7a\x24\xc7\x58\xa4\xc9\x56\xa1\xf9\xdd\xbd\x4f\xbf\xa9\xe9\xd7\x8e\xcf\x77\xd5\xaa\x01\xe7\x88\x22\xfa\xe7\xbe\x7a\xf7\x5d\xf5\x4c\x2d\x33\x2e\xb3\x06\x41\xf3\x14\x13\xa6\xaa\xe0\x20\xaa\xa9\xf5\xec\x19\xcf\x79\x9f\xbf\x0e\x13\xf4\x87\x89\xdd\xdb\xf5\xc0\x96\x3d\x32\xa9\x6c\x11\x1b\x29\x28\x98\x31\xa8\xc4\x05\xfc\xcf\xc9\x1f\x7f\xf5\xcb\xe2\xf4\xf7\x27\x27\x3f\x7e\xb1\xf8\x8f\x3f\xfd\xea\xe4\x8f\x4b\xfa\xcf\xbf\x9c\xfe\xfe\xf4\x97\xea\x8f\x5f\x9d\x9e\x9e\x9c\xfc\xf8\xed\xeb\x6f\xde\x5f\xbf\xfc\x13\x3f\xfd\xe5\x47\x51\xe6\xb7\xee\xaf\x5f\x4e\x7e\xc4\x97\x7f\x8a\x24\x72\x7a\xfa\xfb\x7f\x0e\x30\xf5\x61\x71\x5b\xae\x50\x09\x34\xa8\x17\x5c\x98\x85\x54\x0b\xd7\x93\x0b\x30\x2a\x10\x0f\x6a\x49\xc2\xb3\x57\x34\x3f\xfe\xc7\x95\x47\x9a\x73\xf6\xc1\xfa\x9c\xc0\x72\x59\xba\x18\xb6\xaf\xf7\x0e\xf0\x53\xcb\x5f\x1d\xa6\x81\xd7\x92\xf2\x86\xd6\xf2\x02\xb6\xc6\x14\xfa\xe2\xfc\x7c\xcf\xf3\x92\xcb\xf3\x54\x26\xfa\x3c\x91\x22\xc1\xc2\xd0\x7f\xd6\x7c\x53\x2a\x0a\x65\x9c\xe7\x4c\xb0\x0d\x2e\xfc\x8b\x17\x35\xf9\x45\x2d\x92\xe7\xcf\xa6\x1b\xd0\xba\x3e\x7e\x16\xcd\xcf\x56\x34\xdf\xf9\x19\x3a\x14\x4e\xb7\x21\x9a\x28\x9c\xaa\xae\x1b\xbf\x5a\x43\xfd\x06\xae\x41\xe6\xdc\x18\x4c\xe9\xc4\x06\xb6\xb7\x7b\x21\x60\x85\x1b\x48\x71\xcd\xca\xcc\x50\x84\xdf\xab\x12\x9d\x51\xe0\x0e\x96\xc0\x0f\x45\xc6\x13\x6e\xb2\xdd\x3e\x20\x7c\xe6\xce\x09\xb9\xe7\x3a\xc4\xb0\x03\x91\x78\x5e\x38\x18\x89\x54\x62\x51\x85\x82\x29\xde\xfb\x59\xab\xd7\xa0\x6b\x96\x94\x76\x23\xf9\x5c\x0a\x83\x1f\x7a\x3c\xd8\x96\x30\xdc\xf8\x27\x40\xd2\x0f\xba\x4e\x9c\xf4\xd0\x80\x2a\x05\xc5\xb4\xa7\x2e\x53\x64\xb3\xae\x15\xbf\xe3\x19\x6e\xf0\xa5\x4e\x98\x4b\xdc\x88\x4c\xc8\x7d\x76\xd9\xf3\x3c\x09\x92\x92\x99\x86\xfb\x2d\xd2\xf9\x30\xa1\xd4\xa2\x42\xc9\x04\xb5\x86\x84\x09\xd8\x30\x2e\xdc\x19\x26\x45\x45\x96\x22\xf3\x82\x8e\xd4\x2e\x98\x42\x61\xaa\x07\x42\x11\x71\x02\x51\xac\x2b\x0f\x29\x57\x98\x58\x59\xac\x79\xaa\x8f\xd3\xf8\x49\xe0\xfd\x4f\xf6\x3d\x1a\xd6\x19\xdb\x0c\x25\xf9\xae\x7c\xaa\x9e\xf0\x19\xe6\x5e\x62\x6a\x76\xa0\x6f\x38\x42\xca\xa4\xc9\x36\x00\xcb\xee\xd9\x8e\x86\xeb\x90\x3a\xd7\x17\xf0\xe5\x29\x4d\x35\xd3\x50\x53\x0f\x25\x4c\xfe\xfa\x14\xb6\x4c\xc3\xf3\xcb\xeb\x9f\x6e\xfe\xeb\xe6\xa7\xcb\x17\xaf\xaf\xde\x0c\x89\x75\x38\x72\x97\xb0\x82\xad\x78\xc6\xc3\x8b\xc1\xd1\xd9\x1d\xcd\xc7\x48\xb9\xd3\xf4\x3c\x55\xb2\x70\xfd\xac\x80\x9d\xba\xaf\xc1\x19\x7d\xd1\xb0\x39\x76\x84\xbc\x0d\xaa\x12\x86\x5a\xaf\xda\x28\x26\x4c\xed\xd6\x05\x88\xee\x87\x59\x95\xc2\xf0\x3c\x90\xdf\x1b\x97\x53\xc6\xd2\x81\xac\x89\x76\x42\x1e\x1d\x3f\xd2\x64\x3d\xf8\x6c\x14\x96\xd9\x76\x79\x2b\xd2\xbb\x7d\x9e\x16\x5c\xbf\xbd\xb9\xfa\x43\xfc\x5b\xc1\xcb\xc8\xc0\x4d\xd1\x08\x6a\x1c\x7e\x6a\xc5\x64\xc4\x48\xbe\xc3\x5c\xde\xcd\x63\xd9\x7f\x4f\xd0\x2b\xac\x6d\x6d\x40\x78\xdb\xc3\x5d\x8a\xa6\x89\x12\x0d\x0a\x90\x53\xc6\xfe\xb5\x33\x8a\xa8\x81\x87\xec\x5f\xe3\xb9\xbd\x19\xa0\x84\x0a\xfb\xb0\x30\xdc\x55\x0d\xb4\xf2\x4c\x94\x94\xa1\x74\x08\x6f\x9f\xb7\x52\x9b\x65\xcb\x6a\xac\x59\xa6\x03\x0a\x1e\x63\x07\xad\xa9\x7f\x6d\x1d\xb0\xc8\x71\xaa\xef\x87\x14\x85\xac\x52\x5a\xed\x9b\x28\x79\x5f\xc9\x04\x9c\x3f\x67\x24\x94\x41\xd7\x68\x4d\xb9\xb1\xd8\x34\x96\x64\x62\x2b\x33\xc8\x75\xd5\xd7\xeb\xfa\x9d\x84\x4e\x07\x68\x96\xba\x3e\x1f\xea\xc0\x0c\xee\x3d\xbc\x35\xa5\x78\xb2\x94\xd2\x64\x0a\x66\xb6\x43\x87\x47\xe4\x4c\xdf\x62\xea\x6e\xf5\x99\x76\xde\xfb\x74\xef\xaa\xd9\x7b\x6f\x47\x61\x8d\xcc\x94\x0a\x69\xfd\x0d\x3b\x86\x2b\xac\xd0\xb6\xa1\x29\x0c\xea\x8d\xed\xcb\x5b\x91\xed\xde\x49\x69\xbe\xe6\x19\xba\x92\x96\xc8\xe9\xfc\xc1\x7b\x33\x2e\x71\xbd\x1e\x34\xbb\xd8\x32\xa2\xbc\xa0\x61\xb2\x02\x0a\xeb\x9a\x78\xc4\xaa\x66\xa7\xef\x01\xc4\x53\x95\xe2\x52\x7f\xa3\x64\x19\x30\x9d\x47\x8b\xf4\x37\x57\x2f\x48\xab\x4a\xa7\x37\x28\x8c\xda\xb9\x1a\x22\x9f\xd3\x50\x77\x74\xd8\x87\x5b\xc2\x77\x56\xa6\x0e\xa4\xc8\x7a\x5c\xa5\xd0\x68\x96\xf0\x9a\xed\x80\x65\x5a\x7a\x67\x2a\xe4\x19\x09\xb8\x96\xe9\x4d\xdb\x67\x5e\xd2\x19\x17\x76\xc9\xe7\x02\x56\xd2\x6c\xe1\xe0\x86\x01\xe1\x3c\xa6\x78\xb6\x4f\x0d\x6b\xa4\xaf\x70\x71\x48\x38\x24\x9c\xec\x16\x35\x14\x0a\x13\x4c\x51\x24\x81\x39\x6c\x44\xcb\xff\xed\x5f\x07\x66\x3a\xbc\x5d\xa6\x99\x7e\x23\x85\x15\xe3\xd8\xf2\x39\x91\xf2\xc4\xa7\xd5\xbb\xec\xf4\x86\x08\x53\x82\xac\xf7\x31\x19\x65\xf2\x0e\x58\xd9\x52\xa3\x72\x79\xbe\xaa\xf4\x75\x72\xdf\x96\x2b\xcc\xd0\xb8\x83\x16\xef\x1c\xe2\xe7\x4e\x87\x23\xc4\x02\x98\xa9\x04\x23\xac\xe9\x28\x74\xa9\xaa\x73\x0a\x0d\xa4\x12\x5d\x22\x8c\x67\xef\xbb\xab\x17\xf0\x05\x9c\x58\xfe\x4e\x29\xb7\x6f\xcd\x78\xc8\x6d\x37\x12\xb4\x61\xea\xb0\xc7\x7c\x5d\x11\xa7\x6e\x90\x7c\x82\x54\x4e\x0d\xcf\x40\x84\x0e\x84\xd4\x65\xb2\xad\x7a\x68\xb7\x3b\xd4\xe3\x15\x42\x81\xca\x4e\x31\x45\x81\xda\x82\x1e\x10\xe7\xd0\x7b\xc2\x82\xde\x27\xce\x01\x8a\xc3\x82\x3e\x42\x9c\xa3\x4d\xd2\x77\xba\x0b\x0b\xad\xda\x91\x45\xfa\xee\x41\x2d\x52\xd3\x05\xb0\x52\xdb\xee\xbd\x13\xcd\x1c\x0d\x4b\x99\x61\xc0\x43\xd3\x51\x8a\xfa\xd1\x7f\x8c\x09\x7e\x38\x7b\xa5\xf1\x15\x17\xe5\x87\xb7\x45\x4f\xc2\x56\xd5\x8e\x64\xe1\xe6\x25\x3d\x48\x53\x4e\xcc\xd3\x80\xbb\x0c\xd3\xb4\xda\x0b\x0e\xc4\xeb\x5d\x73\x4a\xbe\x0f\x48\x75\x3b\x3e\xa4\xca\x2c\x73\xa9\x88\x76\x55\x67\x22\x95\xa1\x92\xd7\x43\x06\xab\xb3\x4f\x1b\x4c\x41\x87\xb0\x8c\x5a\xa4\xfe\xc6\x97\xbd\xb8\xad\x73\xd6\x8d\x30\x37\x5b\x4b\x3a\x08\x91\xb6\x8e\x53\x35\x03\x44\xc0\x67\x7a\xd2\xe2\xe1\xf3\x90\x87\x36\x5b\x23\x64\x28\x3e\xcd\x52\x66\x01\x90\xf7\xa8\x2f\xef\x64\x86\x2e\xc7\xbf\xea\x8c\x25\xf0\x99\xf4\x85\x6e\x8b\xef\x0b\xf9\xf5\xad\xbe\xd0\x7e\xe7\xf3\xe8\x4b\x19\x5c\x89\x8e\xfa\x62\x17\xae\x76\x5f\x68\x05\xf9\x1c\xfa\x12\xb1\xad\xbf\xe7\x22\x95\xf7\x7a\xbc\xd1\xfd\xc1\x3d\x58\x59\x86\xc4\x9a\x1e\xc3\xc5\x46\x37\x0d\x2f\x0b\x06\x4b\x9b\xfb\xd4\x2e\xcb\x5b\x45\xb4\xe9\x08\x00\xda\x17\x1e\xd9\xa8\x00\xf5\xca\xe1\x2a\xb5\xc7\x34\x26\x2c\xa4\x21\x89\x8f\xb2\x8d\x0f\x6e\x01\x37\xb9\x66\xcf\x95\xa5\x65\x38\xcb\x6e\x0a\x4c\x46\x88\xea\x37\xaf\x6f\x2e\xdb\x0f\x5b\xc1\x75\x35\xf2\xb6\x3f\xf6\x3a\xb0\x34\xe7\x54\x8e\x33\x20\xaf\xf7\x2e\x4b\x0f\x4e\x2a\x88\x65\xc3\xcd\xb6\x5c\x2d\x13\x99\x37\xd0\x96\x85\xe6\x1b\x7d\xee\xa5\x6c\x61\xb9\x1f\x2a\x4a\xe0\x22\xa3\xf3\x0b\x2a\x65\xf0\xa7\x64\xef\x19\x4c\xea\x1e\xd0\xd0\x53\x2a\xc5\xd0\x29\x3a\x1e\xbc\x3f\x1e\x80\x37\x2c\x47\x57\x47\xf4\x20\xb6\xe3\x78\x7a\xec\x0b\x3e\x6a\x8a\x88\x43\x5f\x3d\x6c\xbb\xea\xc7\x62\xa0\xc3\x9d\x23\xe5\xbc\xdb\x87\x59\xbc\x2a\x9f\x7d\x64\xff\xc8\x77\xf7\x8f\x59\x7d\xa9\xcc\x48\xa7\x2f\x3f\xd0\xc7\x43\x4f\xbf\xdb\x9f\xb7\xb7\xb4\x7d\xfa\x41\x01\x3c\xf6\xf8\x87\xfc\xfa\x01\x92\x5d\xee\xda\x47\x79\x6b\xdd\x44\x1f\xc0\x63\x83\x51\x5e\x1b\x7c\x9a\xbc\xad\xbf\xe1\xcc\x53\xfa\x8e\xc7\x5f\xb1\x0a\xa5\x38\x12\x92\x63\xea\x6d\xc0\xf6\x58\xac\x60\x2b\xb3\x94\xea\xcd\x16\xce\x7f\xae\x50\x6a\x60\xc6\x28\xbe\x2a\x4d\xa7\x73\x63\xd7\xd4\x44\xe6\xb9\x6c\xe2\x00\x95\x97\xb0\x04\xe7\x72\xb0\xec\xa2\xa5\xad\xbe\xfa\x1a\x6e\xb0\xcb\xc2\x91\x97\xd8\x60\x97\x76\x52\x55\x04\xd1\xd7\x6e\xca\xb5\xdb\x5b\x39\xa3\x7e\x8c\x69\x86\xd7\xd9\x75\x28\x36\xda\x1a\xa8\xa7\x97\x4e\xc7\xac\x71\x2d\x8b\x2a\x1d\x21\x73\x39\xea\x2d\xc7\x2f\xec\x09\x35\x30\x0d\x2e\xdc\xa9\x2f\x4b\xb8\x91\x39\xc2\x9d\xcc\xca\xdc\x41\x01\x3e\x77\xa8\x15\x43\xeb\xfd\x1e\x49\xb2\xa5\x33\xc9\xc8\x85\xba\xb7\x84\xb7\xbc\x70\xc6\x92\x99\x9a\x28\x19\x2f\x7b\xb9\xce\x6c\x2b\x64\x2f\xb4\xf3\x47\x01\x5f\x3a\x2c\x41\xde\x13\x1e\xfb\xcd\xd5\x8b\xda\xc1\xb2\xcf\x7e\x7d\x43\xc3\x06\xbf\x76\x77\x69\x34\x1b\x9e\xc2\x8a\x9b\xfe\xe2\x79\x6b\xfc\x4e\x04\xde\xbb\x28\xb8\x5d\xab\x5c\x61\x9f\x5b\x04\x3c\x9b\xd5\x3b\x6a\x46\xfd\x8b\xfa\x9c\x88\xdf\xb8\xf7\x17\xa8\xbc\x13\x63\x79\x70\x60\xd1\xdb\x77\xcf\xfc\x29\x70\xea\x7e\xa1\xee\x17\x8b\xc5\xc2\xf6\xab\x8a\xeb\xf5\xf9\x7a\x47\x51\x4b\x3a\x0a\x4c\xa6\xdc\x7f\xe1\x65\x3f\xc2\x56\xde\xf7\x2f\x0e\x7c\xd9\x83\x89\x9d\xef\xdf\xb2\xbb\x34\x75\x38\xa6\x32\x14\x4f\xf1\x62\xfc\x9c\x24\xa1\x2f\x7f\x1c\x8e\x74\xbf\xe3\x31\x5f\x66\xa9\x61\x85\x5b\x76\xc7\xa5\x22\x24\xdd\xde\xd0\x6f\xef\xfb\xc6\xa4\x5a\xb1\xfd\xe4\xae\x70\x2d\x95\xfd\xc7\x4a\x14\x7e\x28\xa4\xee\x5d\x9b\xb9\xd0\x3c\xa5\x0d\x80\xc7\x8b\x5c\xe9\x37\x4d\x08\xe1\x29\x56\xd5\xe8\x20\xb1\x96\xd2\x84\xd0\x2d\xab\xb4\x52\x99\x6a\xa8\x60\xc5\x34\xa6\x7b\xd6\x4f\x0e\xa6\xf3\x74\x09\x57\x5e\x02\xb6\xec\xae\xcf\xfd\x12\x12\x70\xbd\xc6\x84\x52\x40\xb0\xd8\x62\x8e\x8a\x65\x6d\xa6\x28\x32\xcc\xf4\x85\x35\xa3\x0a\xcd\x19\xb8\xfc\xa3\x9c\x15\x7d\xaa\x62\x59\x21\xc3\x98\x72\x55\x9d\x77\x52\x57\xaa\x23\x3c\x7d\x4b\x31\xfe\xd7\x5c\x53\x9d\xea\x53\xba\xff\xe9\x25\xa5\x8b\xf4\x1e\x76\x7b\xb5\x26\x49\xde\xbb\x09\xcd\x84\xad\xfa\xe1\xee\x94\x90\xa1\x84\xdb\x01\x88\xe9\x23\xe0\xa5\xa1\xbc\x9e\x71\xd0\x52\x87\x6b\x14\x8a\xc6\x4e\x8c\xc4\x06\xab\x90\x47\x6d\x1e\x3d\xc2\xbb\x3f\x50\xa9\x2f\x4a\xf0\xf1\x06\x64\x18\x3c\x7a\x24\xe0\xe8\x31\x40\xa3\x89\x80\x51\x0d\x0b\x05\x96\x86\x11\x60\xd1\x21\x24\xd4\x1b\x91\x89\x01\x8a\xfa\xa2\xbf\xbd\xf6\x73\xa2\xd8\x0e\xee\x9a\x26\xc7\x3c\x86\x90\xa1\x01\x54\xe8\x23\x10\xa1\x21\x23\x32\x12\x0d\x6a\xed\x0d\x7b\x48\x8e\x98\xc1\xbe\xb9\x0a\xac\x0d\x0f\xbe\x13\xfc\x2b\x1a\x9e\x18\x14\x68\x3c\x02\xc4\xb2\x2c\x22\x87\xf0\x11\xe0\x9f\x89\xd0\xcf\xdf\xe7\xb2\x14\x51\x14\x13\x06\x78\xa6\x81\x3b\xe1\x2f\x37\x46\x06\xdd\x63\xf2\x86\x82\x80\xce\x34\x30\xe7\x53\xf1\x1e\x06\x70\xa6\x81\x37\x9f\x8a\xf7\x30\x60\x33\x0d\xac\xf9\x34\xbc\x0f\x55\x03\x34\xe2\x0a\xe4\x4f\xc7\xd8\xc3\xcb\xfa\x08\x52\x8a\x44\xe8\x43\x20\x7c\xcd\x95\xae\xf3\xe3\xad\x51\xeb\x5f\xd8\xdb\x86\x8a\x8e\x3c\xaf\xe2\x55\x47\x70\xd5\x33\x6b\x11\x78\xce\xd4\xce\xba\xf3\x21\x7b\xd5\x32\xb1\x42\x56\x6c\x56\x7e\x8f\xfb\xde\x22\x95\x79\xec\x86\x06\x39\x98\xa1\x1b\x93\x99\x30\x9c\x97\x10\x4e\x9f\xd5\x3b\x9d\x98\xbe\x2a\xd8\x76\x9d\x86\xbb\x93\x62\x69\x8d\x63\x62\xeb\x72\xdf\xb4\xa2\x45\x80\x95\x65\x3e\xe0\x75\x52\x8c\xe8\x9a\x3e\xe4\xc9\xcd\xd6\x8e\xa8\xdb\xcc\x36\xa8\x9c\xf8\xa8\xce\xd1\xfa\xd5\x17\x3a\xc9\xe9\xc4\xfc\xca\xef\xcd\x58\x29\xfa\x4e\x29\x0c\x8e\x7a\x47\xa7\xeb\x10\x02\x83\x5b\x54\x02\x33\x28\x98\x62\x39\x1a\xf7\x95\xdd\x60\x9a\x5f\x0c\x2a\x26\x06\x20\x88\x16\x4b\x6f\x3c\x84\xc2\x2a\xd2\x14\x35\x08\xe7\x19\x46\x85\xb8\x69\x39\x8d\x66\xe3\xfb\xea\x14\xe9\x07\xe6\x63\xe8\xec\xa6\x05\x8d\x56\xef\xc5\x90\x4f\x10\x19\xc3\xef\x53\x95\x18\xa4\x79\x32\xca\x3c\xd1\xb9\xab\x10\x66\xab\x45\x14\x7c\x6d\x9a\xb3\x38\x57\xf9\x11\x61\xe6\x07\x85\x98\x87\x15\x69\x0c\xb4\xfc\x38\xb0\xf2\x63\x40\xca\xd3\xe0\xe4\xa1\x8f\x43\x4c\x85\x92\x63\xce\x51\x1a\x09\x21\x4f\x83\x8f\xe9\xce\x40\x17\xc7\x42\xc7\x31\xa6\x29\x0e\x32\x7e\x14\xb8\xf8\x11\xa0\xe2\x29\x30\x71\x17\x10\x1c\x78\xc5\x34\x6b\xf2\xe9\xd3\x7b\xa7\x7a\xb8\x81\x8b\x0a\x8b\x8c\x27\xec\x79\x77\x21\xcd\xf4\x23\x65\xfc\x89\x1d\x97\x49\xd2\x4d\x79\xe0\x58\x99\x10\x94\x0b\x23\x2b\xe3\x3f\x76\x77\xe0\x10\xb3\x69\xe7\xd4\xf4\xbb\x4c\x93\x01\x75\xc7\xce\x98\x39\x36\x32\x43\xd5\x37\x9a\x87\x9f\xf5\x39\x58\xb9\xdd\x11\xaf\x0d\x0a\xc7\x32\xda\xeb\xa6\x1e\x59\x98\x42\xa6\xae\x5e\xe7\x7d\x4d\x8f\x36\x89\xc6\x30\xfa\x82\xbc\x35\x0d\xee\x8a\x75\x62\x45\xcf\x21\x95\x8c\x0b\xe3\xf6\x90\xcd\xef\xea\x1b\x45\x5f\xa1\xf9\x6d\x7d\xa0\xf2\x99\x03\x88\x7e\x07\xa5\xae\xbe\x44\x15\x3c\x55\xb5\x3e\xd0\xf8\xb7\xd5\xff\x7e\xd7\xa5\x8f\x43\xeb\xbb\x7b\x6b\x94\xd7\xfe\xd2\x21\x58\xbc\x11\xd3\x47\xdf\x3d\x0f\x6e\x19\xe9\x78\xf6\xdf\x21\xeb\x35\x0f\xee\x50\x5e\xba\xd5\x7d\xfa\xa6\x41\x44\xfb\x4f\xf6\x34\x26\xd6\x9f\x8f\xe1\xb1\xad\x5e\xaa\x4c\x21\xbc\x91\xfe\x8b\x51\x78\x06\xd7\xf4\x05\xfe\xfd\x2f\x64\x18\xdf\x48\xf7\xed\xa8\x5e\xe3\x35\xa8\x7e\x81\xef\x3d\xb4\x86\xeb\xdb\xfd\xd7\x1d\x5c\xff\x9a\x5f\x77\x68\x88\xe8\x60\x1e\xa8\x91\xd5\x77\xdd\xba\xc7\xed\x16\x77\xfb\x53\xfa\xfd\x37\x25\x08\x16\xec\xcf\x53\xac\x85\xa7\x3a\xdd\xde\x1d\x9c\xff\x55\x55\x9e\x96\xaf\xb8\x70\xcc\xb9\x57\x56\x13\x1b\xcc\xdc\xac\xa0\x47\x91\x12\x73\xc4\xd6\xd4\x41\x1e\xfa\xc4\x44\x6b\xa4\xdf\x46\x7e\x50\xc2\xaf\xe5\xe1\x0e\x74\x7e\x38\xa2\xf9\x0d\x88\x97\x3f\x97\x2c\x6b\x3b\x08\xee\xa7\x5e\xba\xfe\xe1\xa3\x53\xcf\xef\x79\x96\x26\x4c\xb9\x23\x34\x9c\x11\x00\x2d\x7d\xbc\xc9\x5a\x9f\x5e\x8a\x09\x13\xb5\xe9\xd9\x4b\x82\xf6\x1b\x47\xa6\x0c\x4f\xca\x8c\x29\xb0\x7a\xba\x91\xaa\xf7\x6b\xd0\xc3\x6b\x4d\x2d\xa6\x37\x98\x48\x91\xc6\xed\xef\xdf\x1f\x3e\xd5\x9c\x19\xe3\x12\x31\xb8\xff\x8a\x51\xa8\xa6\xeb\x40\x51\x4e\xdc\x99\xc9\x95\xcc\xca\x75\x65\x77\x6a\xa5\x8e\x39\x2b\xa4\xf1\x1d\x34\xae\x81\xbb\xcf\xca\x9d\x36\x2c\x79\xad\xb1\x4b\xf8\xcf\x5d\x85\x16\x9f\x01\xef\x77\x24\xfd\x71\xcb\x1a\xcd\x99\x3f\xd7\xb9\x52\x1b\x3f\x45\x7b\x23\xb0\x96\x0a\xef\x50\xc1\x49\x2a\xed\x33\xbd\x24\xe9\x6b\x67\xa7\x4b\xf8\x6f\x54\x92\xc4\x4e\xe0\xc6\x7d\x64\xcb\xab\x59\x9d\x66\xe3\x13\x64\x98\x86\x2f\xe0\x84\x1e\xeb\xe7\x33\xcf\x31\xe5\xcc\x60\xb6\x3b\xad\x0f\xae\x0a\x16\x9a\x3e\x4c\xb0\x2c\x18\x03\xe9\x88\x7f\xb4\xcc\xa6\x73\x4c\x0f\x44\xc1\x2f\xa5\x41\x9b\xd9\xfb\x49\xf3\x16\x0a\x56\x9f\x94\x3e\x64\x32\x2b\xc1\x82\x3f\x5b\xf9\x63\xa0\x70\x43\x3a\xe6\xb4\x67\xa2\x86\x45\xf8\xc1\xc7\x81\x93\x6e\x77\x6b\xb1\x3f\x5a\xfa\xe0\x77\x7f\xa4\xe8\xc1\xaf\x07\xe7\x48\x1e\x5c\xdd\x9f\xb1\x78\x70\xa1\xf3\x3b\x1c\x8b\x96\x63\x7e\x70\xa9\xed\x5b\x3f\x19\xec\xfe\xd1\x8f\xd4\xa9\xb4\x71\x14\x92\x36\x52\xb1\x0d\xfa\x5f\xfe\x3f\x00\x00\xff\xff\x61\x45\x55\x0f\xb2\xf6\x00\x00") + +func installerKubepackCom_kubepackoperatorsV1YamlBytes() ([]byte, error) { + return bindataRead( + _installerKubepackCom_kubepackoperatorsV1Yaml, + "installer.kubepack.com_kubepackoperators.v1.yaml", + ) +} + +func installerKubepackCom_kubepackoperatorsV1Yaml() (*asset, error) { + bytes, err := installerKubepackCom_kubepackoperatorsV1YamlBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "installer.kubepack.com_kubepackoperators.v1.yaml", size: 63154, mode: os.FileMode(420), modTime: time.Unix(1573722179, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + var _installerKubepackCom_kubepackoperatorsYaml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x7d\x6f\x73\xe4\xb6\xd1\xe7\xfb\xfd\x14\x28\x5d\xaa\x56\x4a\x34\x23\x6f\x7c\x95\xba\x28\xa9\xb8\x74\xbb\x6b\x97\xca\xfb\x47\xb5\x5a\xdb\xb9\xdb\x38\x2e\x0c\xd9\x33\x83\x88\x04\x68\x00\x94\x76\xfc\xf8\xf9\xee\x4f\xa1\x01\x72\xf8\x0f\x20\x38\x92\xbc\x76\x42\xbe\xd9\xd5\x90\x6c\x34\x1a\x8d\x46\xf7\xaf\x1b\x20\x2d\xd8\xb7\x20\x15\x13\xfc\x9c\xd0\x82\xc1\x47\x0d\xdc\xfc\xa5\x96\x37\xff\x47\x2d\x99\x38\xbb\x7d\xb6\x02\x4d\x9f\x3d\xb9\x61\x3c\x3d\x27\xcf\x4b\xa5\x45\xfe\x0e\x94\x28\x65\x02\x2f\x60\xcd\x38\xd3\x4c\xf0\x27\x39\x68\x9a\x52\x4d\xcf\x9f\x10\x92\x48\xa0\xe6\xc7\xf7\x2c\x07\xa5\x69\x5e\x9c\x13\x5e\x66\xd9\x13\x42\x32\xba\x82\x4c\x99\x67\x08\xa1\x45\x71\x4e\x6e\x69\x99\xe9\x27\x84\x70\x9a\xc3\x39\xb9\x29\x57\x50\xd0\xe4\x46\x14\x20\xa9\x16\x52\x2d\x19\x57\x9a\x66\x19\xc8\x65\x75\x6f\x99\x88\xfc\x89\x2a\x20\x31\x54\x36\x52\x94\xc5\x39\xf1\x3c\x65\xc9\xba\xe6\x12\xaa\x61\x23\x24\xab\xfe\x5e\xd4\xad\xb9\x3f\x69\x51\xa8\x44\xa4\x80\x7f\xda\xde\x7e\xed\x9e\x78\xeb\xf8\xc1\x5b\x19\x53\xfa\xeb\xc1\xdb\xaf\x98\xd2\xf8\x48\x91\x95\x92\x66\x03\xfd\xc1\xbb\x8a\xf1\x4d\x99\x51\xd9\xbf\xff\x84\x90\x42\x82\x02\x79\x0b\xdf\xf0\x1b\x2e\xee\xf8\x97\x0c\xb2\x54\x9d\x93\x35\xcd\x94\xe1\x4c\x25\xa2\x80\x73\xf2\xc6\xf4\xab\xa0\x09\xa4\x4f\x08\xb9\xa5\x19\x4b\x51\xe0\xb6\x67\xa2\x00\x7e\x71\x75\xf9\xed\xe7\xd7\xc9\x16\x72\x6a\x7f\x34\x94\x4d\x33\xba\x16\x80\x1d\x83\x7a\xf4\xeb\xdf\x08\x49\x41\x25\x92\x15\x48\x91\x3c\x35\xa4\xec\x33\x24\x35\xe3\x0d\x8a\xe8\x2d\x90\x5b\xfb\x1b\xa4\x44\x61\x33\x44\xac\x89\xde\x32\x45\x24\x60\x1f\xb8\x46\x96\x1a\x64\x89\x79\x84\x72\x22\x56\xff\x82\x44\x2f\xc9\xb5\xe9\xa7\x54\x44\x6d\x45\x99\xa5\x24\x11\xfc\x16\xa4\x26\x12\x12\xb1\xe1\xec\xa7\x9a\xb2\x22\x5a\x60\x93\x19\xd5\xe0\x24\x5c\x5d\x8c\x6b\x90\x9c\x66\x46\x08\x25\x9c\x12\xca\x53\x92\xd3\x1d\x91\x60\xda\x20\x25\x6f\x50\xc3\x47\xd4\x92\xbc\x16\x12\x08\xe3\x6b\x71\x4e\xb6\x5a\x17\xea\xfc\xec\x6c\xc3\x74\xa5\xef\x89\xc8\xf3\x92\x33\xbd\x3b\x4b\x04\xd7\x92\xad\x4a\x33\x70\x67\x29\xdc\x42\x76\xa6\xd8\x66\x41\x65\xb2\x65\x1a\x12\x5d\x4a\x38\xa3\x05\x5b\x20\xe3\x5c\xe3\xa4\xc9\xd3\xff\x25\xdd\xe4\x50\x4f\x1b\x9c\xea\x9d\x19\x36\xa5\x25\xe3\x9b\xfa\x67\x54\x32\xaf\xdc\x8d\x8e\x11\xa6\x08\x75\xaf\x59\xfe\xf7\xe2\x35\x3f\x19\xa9\xbc\x7b\x79\xfd\x9e\x54\x8d\xe2\x10\xb4\x65\x8e\xd2\xde\xbf\xa6\xf6\x82\x37\x82\x62\x7c\x0d\xd2\x0e\xdc\x5a\x8a\x1c\x29\x02\x4f\x0b\xc1\xb8\xc6\x3f\x92\x8c\x01\x6f\x0b\x5d\x95\xab\x9c\x69\x33\xd2\x3f\x96\xa0\xb4\x19\x9f\x25\x79\x4e\x39\x17\x9a\xac\x80\x94\x45\x4a\x35\xa4\x4b\x72\xc9\xc9\x73\x9a\x43\xf6\x9c\x2a\x78\x74\xb1\x1b\x09\xab\x85\x11\xe9\xb8\xe0\x9b\xc6\xaa\xba\x86\xa6\x87\xb9\xd0\x32\xb5\x7e\x21\x24\xa7\x1f\x5f\x01\xdf\xe8\xed\x39\xf9\xd3\xe7\x9d\x7b\x05\xd5\x46\x25\xcf\xc9\x3f\x3f\xd0\xc5\x4f\xdf\x1f\x7f\x58\xd0\xc5\x4f\x9f\x2d\xfe\xfc\xfd\xef\x3f\xb8\xff\x9c\x7c\xf1\xbb\xce\x3b\x83\x4c\x56\x3f\xdb\x01\xac\x7f\xae\x4c\xdf\xa0\xd2\x74\x2d\xd2\x75\x01\x89\xd1\x21\x33\x90\x6e\x9a\xae\x85\xac\x1f\x23\xd5\x73\x6e\x6e\xb4\xd8\x5a\xb3\x0c\x22\xe4\x43\xd7\xb8\x06\xec\xba\x32\x6a\xf1\x75\xb9\x46\xbe\xd9\x9a\x41\x7a\x8a\xdc\x14\x22\x7d\xaa\x90\xa7\xb4\xcc\x8c\x2a\x27\x82\x2b\x2d\x29\xe3\x5a\x75\x25\xea\x69\x19\x47\x47\xa4\x70\xe1\xe1\xa0\xc7\xc5\x0b\xfc\x63\x05\x0a\x5f\xab\x39\x6f\x72\x21\xcb\x0c\x14\xca\xc8\x31\xb9\x1c\x20\x1a\x62\xc8\xde\x87\x35\x48\x09\xe9\x8b\xd2\x8c\xe8\x75\x4d\xfe\x72\xc3\x45\xfd\xf3\xcb\x8f\x90\x94\xba\x63\x7a\xbd\xbc\xbf\x77\x23\x98\x96\x19\x48\x72\xc7\xb2\xcc\x35\x63\x8c\x63\x75\xc3\x30\x8c\xd6\xd2\xf4\xaf\x2b\xc6\xfd\xa5\xb7\x54\x13\x45\x35\x53\xeb\x1d\xf6\xb3\x96\x04\x7c\x34\x56\x02\xd7\xff\xfd\x80\x91\xd5\xce\x19\x08\xb3\x18\x9d\x7a\xc9\xae\x4a\x4d\x98\x46\xab\x92\x6c\x85\x50\x40\xa8\x15\x34\xb6\x77\xcb\x04\xda\x6f\x22\x38\x10\x21\x49\x6e\xcc\x01\xae\x19\xe0\xa5\xd8\x60\x67\x89\x12\xd8\x93\x63\x8a\xe4\x42\xe9\xbd\xac\x2b\x35\x37\xe4\xef\x98\xde\x06\x7a\x0f\x64\x63\x3c\x14\x50\x9a\xa8\x32\x37\x4c\xdc\x01\xdb\x6c\xb5\x3a\x25\x6c\x09\x4b\x1c\x7e\xa0\xc9\xb6\xd1\x5c\x0e\xd0\xd3\xcb\xfd\x45\xb3\xcc\x75\xa5\xa5\x4b\xf0\x63\xc9\x24\xe4\xc6\xe8\x92\xe3\xda\x42\x3b\xab\x79\x5a\xdd\xef\x69\x89\xbf\x99\x81\x61\x3a\x25\xa0\x93\xe5\xc9\x29\x49\x44\x5e\x94\xda\xc8\xdc\xf4\x69\xb5\x23\x4c\x9b\xb9\x6d\x57\x09\x29\xca\x4d\x58\x22\x90\x39\x46\xab\x65\x1c\x07\x1b\xd7\x53\x9a\xa6\x86\xca\x91\x15\xd2\x51\xb5\x1a\xab\x32\xf7\x52\x64\x56\x18\x28\xbf\x9c\xea\x64\xeb\x9c\x86\x44\x48\x09\xaa\x10\x1c\x29\xe2\x9d\x97\xfb\xbe\xfc\x25\xa8\x0c\x86\xd8\xb1\x3a\xc1\xc1\x45\x62\x5b\xb6\xd9\x56\x63\x48\x25\xe0\x6f\x6d\x9d\x18\x9a\xbc\xc8\x9e\x86\xdc\x33\x77\x49\x77\xe2\x5d\x70\x02\x79\xa1\x77\x0d\x4d\x6b\x8c\xb1\x06\x99\xd7\x3d\xa4\xe8\xe3\xfa\x2e\x6b\xc7\x95\xe5\x9f\xe5\x45\xc6\x12\xa6\x9d\xe6\x91\xcf\xc8\x31\xaa\x1e\xd3\x4f\x15\x4e\x9b\x85\x28\x4e\x96\xe4\xa2\x72\x9c\x7d\xd7\x38\x53\x5c\xd4\x2d\xbb\x26\x0c\xa3\x4a\x04\x88\xd6\xed\x7b\x9f\x19\xb3\x80\x4d\xe6\x80\x27\xbd\x05\xb4\x7d\xb5\xe5\x6d\xb5\x46\x41\x06\x89\x59\x99\x4c\x67\x4e\x09\x55\x4a\x24\xcc\xb8\x15\xf5\xf8\x07\x49\x92\x8e\xaa\x59\x31\xfb\x3b\x14\xdf\x29\x82\xeb\x7f\x5b\x71\xc7\x9e\xef\x75\xd1\xc4\x10\x66\xa6\xb5\xbb\xda\x34\x18\xa3\x14\x89\x99\xe3\xe6\xfd\xa7\xca\x85\x55\xe1\xde\x91\x71\xbd\xf7\xb2\xeb\x65\xd3\xf9\xa7\xee\x4e\x04\x61\xb7\xf8\x18\x1f\x8f\x32\xae\x9c\xdf\x71\x4a\x28\xb9\x81\x9d\x75\xdf\x4d\x84\x50\xb9\x25\xe6\xe1\x28\xaa\x12\xec\xe2\x62\x6c\xc0\x0d\xec\x90\x90\xf3\xf7\x23\xde\x8f\x1f\x79\x7b\xdd\xc0\xa0\xb3\x31\x74\xf5\x16\x71\x1c\x2b\xe4\x11\x25\x81\x96\x74\x8a\xfc\x88\x0d\x9d\x33\x06\xe8\x77\x47\xbe\xe3\xf1\x30\xfd\x57\x35\x04\x07\xf5\xf3\x5d\x1d\x6c\xd8\x81\x7d\xaa\xec\x00\x99\xb9\xb2\x65\x45\x74\x3f\xb5\x40\xed\xc2\xa9\x52\x45\x6f\xdf\x9a\x68\xb7\x66\x4f\xa1\xe5\xbf\xe4\x7e\xaf\xa4\x7b\xbd\x11\xfa\x92\x9f\x92\x97\x1f\x99\x32\x0b\xfe\x0b\x01\xea\x8d\xd0\xf8\xe7\x92\x7c\xa5\xad\x0e\xbe\x1a\x31\x15\x0d\x16\xa7\x0a\xd6\xf6\xe3\x20\xb1\x5e\x70\x42\xa5\xa4\x3b\x23\x8e\x66\x4c\xa8\x96\xc6\xc1\x1e\x37\x89\xfb\xab\x9e\x60\x4c\x99\x28\x4d\xc8\x4a\x2c\x18\xd9\x23\x4d\xdb\x54\x34\xc5\xbc\x54\x18\xfc\x71\xc1\x17\xb8\x5e\x56\x3c\xb5\xda\xb2\x52\x8f\x67\x53\xb6\xc6\xa7\xcf\x5e\xd5\x6c\x34\x45\x3f\x6b\x5f\x69\xd3\xdc\xab\x56\x23\xf1\x13\x72\xcf\xcc\x96\xde\xa2\x13\xc6\xf8\x26\xab\xdd\xaa\x53\x72\xb7\x65\xc9\x16\xfd\xf6\x68\xa2\x2b\xb0\xf0\x46\x21\xc1\xac\x7b\x54\x19\xd3\x68\x7e\xd9\x80\x34\xee\x30\xab\x84\xc0\xe2\x19\x95\x50\x64\x34\x81\x94\xa4\xe8\x74\x5a\x70\x81\x6a\xd8\xb0\x84\xe4\x20\x37\x60\xe2\xd7\x64\x1b\xab\xfd\xd1\x0b\x8a\xbd\x26\x4f\x96\xea\x95\x58\x5d\xac\x5c\xea\x18\x96\x16\xc6\x32\x45\x3d\x27\x9a\xf0\x5f\x0c\xbb\x9d\x90\x3d\xfc\x70\x4c\xdf\xd0\xe1\x70\x58\xe0\x27\xf6\x35\x30\x2e\x98\x7d\x8d\xd9\xd7\xf0\x5e\xb3\xaf\x51\x5d\xb3\xaf\x31\xfb\x1a\xb3\xaf\x31\xfb\x1a\xbf\x21\x5f\x23\x92\xa8\xc5\x53\x26\xc0\x3a\xdf\x59\x9c\xab\x8b\xe3\xa0\x63\x53\x65\xb2\x5a\x90\xcd\x48\x8f\x8c\x9b\x70\xed\xd6\xb2\xf7\x08\x11\x31\x8e\x44\x24\xe5\x1b\x20\xcf\x16\xcf\x3e\xfb\x2c\xac\x59\x6b\x21\x73\xaa\xcf\x8d\x96\x7f\xfe\xc7\x08\x99\xb8\xd9\xe0\x7d\x72\x5c\x1f\x16\x0d\x44\x2c\xf0\x90\x95\xad\x1f\xad\x1d\x1f\xa1\xb1\xc1\xf6\x21\xcf\xf7\xc8\x4f\x38\x2b\x57\x43\xd4\x2d\xf0\xbb\x97\x4a\xf0\x76\xce\xa1\xce\xd2\x18\x77\x4d\x72\xd0\x84\xea\x16\xb4\xc9\x72\xa8\x13\x48\x36\x0d\x62\xb3\x8e\x5e\x8a\x55\x6e\x24\x25\x82\x3b\xe4\xda\xe8\xce\x32\x92\x63\x7f\xb6\xa3\x99\x14\x21\x09\x50\x05\xc6\x87\x58\x41\xcd\xb5\xc8\x0d\x97\x8c\xeb\xca\x00\x1a\x96\xa1\x92\xaa\x97\xf0\x31\x2c\x37\x4b\x92\x96\x48\x8e\x72\x97\x4e\x3d\xb1\xbd\x56\x3b\xa5\x21\xc7\x1c\x8b\x90\xf8\x8f\xe9\xbe\x96\x3b\xa2\xfd\x88\x2e\xdc\x02\xd7\x25\xcd\xb2\x1d\x81\x5b\x96\xe8\x5a\x7e\x98\xf1\x65\xda\xe6\xc3\x7c\xb3\x25\xc6\x61\xed\xce\xc6\xa0\x9d\xee\xb8\x6f\x56\x15\x97\xde\x48\x45\x1b\x7a\x98\xfe\x09\x4f\x52\xf3\x18\x6a\xce\xdb\x77\x7e\xe4\x9f\xc4\x2d\x24\xdd\x98\xa4\xcc\x32\x23\x6f\x9b\x08\xe8\xb3\x57\x81\xed\xa3\x36\xab\x82\xe2\x6d\x36\xab\xa5\x71\x36\x7f\x64\x33\x19\x17\x6f\x5e\x18\x89\x8c\x75\x99\x90\xf7\xa2\x10\x99\xd8\xec\x9a\xb2\xc7\xd9\x8f\x09\x06\x47\x99\x12\x55\xae\x9c\x67\x3b\xee\xb8\xbd\xe9\x0c\xe5\x8c\x99\xcf\x71\xec\xd0\x35\xc7\xb1\xbd\x6b\x8e\x63\x23\x59\x9c\xe3\x58\xbc\xe6\x38\x76\x8e\x63\x47\xaf\x39\x8e\x1d\x78\x78\xc6\xcc\x67\x5f\x23\x70\xcd\xbe\x46\xef\x9a\x7d\x8d\xd9\xd7\x98\x7d\x8d\xd9\xd7\x08\x5e\xb3\xaf\x31\xf0\xf0\x83\x61\xe6\xe3\xe4\xc6\xc4\xb3\xe8\x03\x6d\x41\x04\xd8\xcb\x52\xf0\x76\x21\xd2\x03\x4a\xea\x0b\x91\x06\x2a\xea\x2d\xa8\x99\x88\x45\x26\x12\xaa\x87\xed\x01\xc2\xa9\x86\x8c\x43\xf2\x15\xcd\x2d\x56\x7b\x4a\x7e\x12\x1c\x6c\xa5\xb3\x99\x66\x88\xac\x0a\xbd\x05\x69\x1e\x3f\x56\x27\x83\x95\xaa\x73\x95\xfe\xe0\x35\x57\xe9\xcf\x55\xfa\xee\x6a\x56\xe9\x6f\xa9\xb2\x7a\x69\x17\x42\x7f\xd1\x7e\xc3\x3a\x18\x03\xf4\x97\x20\xbf\x9f\xa8\x66\xdf\x28\xa1\x53\x16\xdc\x73\xb8\x1f\x78\xdb\xaf\xd4\xa5\x23\x21\xbd\x6a\xf7\x26\x60\xbd\x6d\x0c\x87\x4c\xd3\x34\x85\x94\x14\x20\x17\x56\xf5\x04\x59\x33\x9e\x0e\xf4\xa5\xea\xbf\x97\x6c\x64\x1d\x7d\x9b\xc9\x09\xa9\x8b\x66\x76\xa5\x65\xa0\xbb\x55\xf5\x23\x6b\x61\x3d\x7e\x8f\x59\x55\x8f\x91\x57\xb5\xb8\x4d\x0f\xd9\x31\x6e\xfb\xb1\x04\xb9\x23\xe2\x16\xe4\x3e\x32\xa9\x37\x64\xc6\x04\x21\xb8\xf6\x30\x45\x12\xaa\xac\xa1\x1e\x77\xb5\xa6\x45\xa7\xd3\xf3\x20\xbd\xce\x76\x49\xd8\x28\xbf\xc2\x2c\x50\x10\x91\xde\xdb\x20\xb4\x31\x90\x9c\xa2\x32\xd6\x85\xb7\xa9\xab\xa8\x87\x27\x39\xa7\x83\xa3\xed\x81\x3c\xe2\xc3\x82\x46\x1a\x6f\x04\xf6\x88\xa7\xd9\x81\x47\xee\x09\x7d\x90\x03\xe0\x0f\x32\x0d\x02\x21\x5d\xf1\x1a\x2e\xdd\x3a\xdd\x47\x43\x26\x10\x6d\xe8\xd7\x74\x44\x84\x1c\x16\x8f\x4c\x47\x46\x48\xb7\xfb\xf5\xf0\xc9\x1e\x4c\x32\xa9\xf3\x4d\x48\xc5\x0f\x95\x4c\x22\xd9\x83\x55\xda\x70\x09\xea\x56\x0b\x31\x79\x6c\x61\x4f\x43\x4b\x48\x57\xd4\x0e\x2b\x60\x18\x3a\x77\xb0\x93\x49\x82\x69\xe3\x2c\x5e\xfc\x64\x12\x4d\x1f\x98\xd1\xc6\x50\x26\x93\xec\xe3\x2d\x3d\x1c\xe5\x61\xd8\x74\x2c\xee\x81\x88\x49\x64\xed\x49\x0e\x0f\x09\x46\x90\xe9\x80\x04\x39\x54\x2f\xa7\x02\x13\x64\x22\x38\x41\x26\x00\x14\x64\x2a\x48\x41\xa6\x02\x15\x64\x72\x7f\xd1\x85\x78\xd5\x38\x8d\x65\xec\x32\xe1\x85\x99\xb3\x34\xbb\x9a\xbc\x1a\x4d\x1e\xc1\xbe\xb7\x63\x59\xb5\x8e\x4e\x4e\x0b\x63\x25\xfe\xcb\x2c\xcd\xa8\xf8\xff\x1d\xbb\x8e\x52\x26\x95\x71\x85\x1d\xf8\xd7\xa0\x50\x61\x0e\x8d\xc6\x22\x89\x1a\x6e\x98\x22\x46\x77\x6e\x69\x66\x1c\x10\x5b\xb6\xe5\x42\x35\xc3\x69\xd7\x5f\x8b\x9d\xdf\x77\x5b\x13\x9e\x9b\xc5\xd7\x86\x79\x4c\x91\xa3\x1b\xd8\x1d\x9d\xf6\xec\xc8\xd1\x25\x3f\x8a\xa5\x4a\x5d\xa8\xd2\xb2\x19\xb5\xe7\x23\x78\xb6\x23\x47\x78\xef\x28\x76\x62\x0f\xb9\x8b\x53\x1c\xc1\x03\x40\xb9\xa8\x87\x79\x75\x4a\xce\xd4\x04\xe0\xfe\xc5\x1a\x5f\xa9\x02\xe3\xfd\xad\x18\xb4\xb1\xf2\xa0\xae\xfb\x7e\x10\x39\xae\xb7\x8d\x6f\x8c\xe4\xf5\x89\x3f\x94\x6e\x74\xa9\x55\x89\x86\x2e\x7f\x0e\x94\x2b\x72\x54\xa1\x67\x4f\xd5\x9e\xc7\xa3\x87\xcb\x38\x4e\x9a\xc3\xf1\xb6\x48\xbb\x02\xb6\xaf\x63\xdc\xd5\x4e\x8c\xef\xd0\x42\x77\x7c\xd0\x0a\xf6\xf0\x62\x4a\x8e\xab\x48\xd7\x1f\x7b\xef\x2f\x21\xb1\x8a\xb2\xf5\x3a\xd7\x6c\x51\xd3\xd8\xc7\xbf\x26\x22\x8c\x35\xaf\x55\x59\x73\x5b\x03\x2a\x70\xb3\xc6\xed\xf6\x1a\x15\x33\x83\xef\xb6\x20\x5b\x3d\x65\xca\x1d\xcb\x84\x19\x08\x59\x72\x6e\xda\x15\xdc\xc1\x7a\x51\x24\x8d\x99\xb1\xa7\x0b\x39\x98\xc4\xba\xfd\xd8\x6b\xf4\xfd\xf7\xa3\x14\x59\xea\x48\x2a\x00\x13\x8f\x7c\x72\x35\x93\x82\xbb\x49\x64\x7e\xa9\x90\x38\x94\x0b\xa4\xb1\x92\x65\x75\x1f\x97\xe4\x25\x4e\x82\x26\x73\x4c\xe1\x48\xd2\x2c\x13\x77\x31\xd6\x27\x5a\xab\xe3\x7c\x83\x45\x93\x99\x87\x48\x19\x4c\x2e\xb3\xbf\x7b\xe0\x32\xfb\x0e\xf4\xf4\x1b\xa9\xb2\x8f\x04\xf5\xe6\x52\xfb\xb9\xd4\xbe\x51\x6a\x8f\x2f\x59\xcb\x37\x5e\x73\xef\xd7\x19\xac\xc5\x8f\xad\xb9\x27\xdf\x6d\x01\x67\x54\x00\x60\x33\x43\x94\x97\x99\x66\xc5\x3e\x61\xad\x2c\x6b\x99\x0d\x1f\x6d\xa1\x92\xea\xa0\xb3\xa1\x1d\x01\x34\xd9\x76\xa7\x09\xb6\x83\x09\x6d\x85\x16\xd9\xa5\x59\x68\x96\xb9\xda\x7a\x13\x57\xfa\xc7\x08\x5c\xae\x8a\x3d\x0c\x84\xff\xc2\x1d\x35\x58\x83\x26\x98\x9c\x38\x36\x8b\x65\x66\xd4\xc1\x2c\x59\x95\x55\x0b\xe5\x5c\x7b\xeb\xaf\x45\x65\x6e\xa1\x4a\x90\x6c\xd8\x2d\xf0\xfd\x22\x7c\xac\x4e\x4e\xc6\xca\x9a\x74\xa4\xeb\xd1\x77\x2c\x02\x44\x87\x5c\x8e\xd3\xc8\xe5\x3e\x40\xb6\x76\x04\x22\x96\xf9\xbf\x36\x56\xaf\xbf\x05\x68\xee\x93\x43\xde\x05\x1e\xc5\x53\x2f\xf1\xf5\x00\x06\x88\xb2\xf1\xde\xc4\xe1\xa0\x13\xd2\x08\x07\xa4\x10\x08\xf3\x9b\x13\x7b\x4d\x49\x1f\xfc\x62\xdb\x27\x22\x52\x06\x53\xca\xdc\xc6\xd3\x05\xb1\xf1\xdf\xa1\x25\x8f\xc1\x04\xc0\x5c\xf3\x18\xbc\xe2\xc1\xfe\x7f\xbf\xd2\xc7\x00\xb8\xff\x2b\xad\x81\x3c\x18\xd4\xff\x25\x4b\x1f\x43\x40\xfe\xc4\x6c\x17\x19\x03\xf1\xef\x59\x00\x38\x56\x04\x19\x4d\xd3\x03\xde\x0f\x03\xf2\xd1\x54\x87\x80\xfb\x41\x30\x3e\x9a\xe2\x5c\x41\x38\xfa\xdc\xa7\xae\x20\x9c\x08\xc8\x1f\x0a\xc6\x4f\x1a\x9d\xa9\x20\xbc\x83\xd7\x23\xd8\x88\x04\xe0\xfb\xd0\x7a\x4c\x17\x47\xc1\xf7\x2e\xac\x1e\x07\x3a\x85\x80\xf7\x41\x48\x3d\x82\xec\x30\xe8\x7e\x2f\x77\x2a\x5a\x3b\x23\x1f\x8c\x85\xd0\xa7\xc3\xe7\x11\xb5\x04\x13\xa0\xf3\x0a\x18\x1f\xa1\xf8\x10\xb0\x79\x94\x45\x8c\x9e\x69\x71\x16\x22\x1a\x26\x7f\x0c\x88\x7c\x22\x3c\x1e\x13\x96\x93\xc1\xd0\x3c\x04\x8d\xdb\x48\x78\x84\x64\x3c\x2c\xde\x8c\x86\xc7\xba\x1f\x0b\x89\x37\xe3\xe1\xb1\xcc\x54\x14\x1c\xde\x07\xbb\xe3\xb3\x29\x93\xa0\xf0\x28\x6d\x8d\x41\x5e\x63\xe0\xef\x7b\x83\xaa\xa3\xc5\xeb\x5c\xb3\x43\x0b\xd8\x9b\x7a\xed\xa9\x62\x1f\xe4\x99\xde\x0a\x96\x92\xa2\xd4\xae\x94\x77\x72\x25\xfb\x20\xd5\xff\xa8\xea\xf6\x96\xe8\x83\x25\xee\x61\x48\xfb\xf4\x80\x12\x77\x2f\x45\x37\x2d\x0f\x28\x71\xf7\x93\x74\xa5\xef\x07\x95\xb8\x7b\xa9\x62\xe9\xfb\x61\x25\xee\xa3\x33\xbe\xab\x42\xfe\xb1\xaa\xea\xdc\xbd\x24\xc7\xeb\xdf\x03\x75\xee\x7e\x84\x3c\x58\xff\x1e\xa8\x73\xf7\x8b\x33\xba\xfe\xbd\x57\xe7\x1e\x50\xf9\xb9\xfe\xbd\x73\xcd\xf5\xef\x8d\x6b\xae\x7f\x8f\xec\xec\x5c\xff\x3e\xd7\xbf\x8f\x5d\x73\xfd\xfb\x5c\xff\x3e\xd7\xbf\xcf\xf5\xef\x73\xfd\xfb\x5c\xff\x3e\x70\xcd\xf5\xef\x73\xfd\xfb\x5c\xff\xde\xb8\xe6\xfa\xf7\x91\xae\xcc\xf5\xef\x73\xfd\xfb\x5c\xff\x3e\xd7\xbf\xcf\xf5\xef\x03\x8f\x7c\x92\xfa\xf7\x16\x08\xed\x2d\x82\x0f\xc0\xb1\xfb\xf3\x53\x26\x16\xc1\x7b\x69\xae\x60\xbc\x08\xde\xcb\xb6\x97\xaa\xe7\x8c\x9f\xa8\x4a\x78\x3f\xf4\xda\xac\x90\x9f\x54\x09\x1f\x00\xcd\x07\x4e\xa5\xbf\xe7\xe9\xf3\xa4\x51\x21\x7f\x68\x25\xbc\x5f\x05\xc4\x5c\x09\x3f\x57\xc2\xcf\x95\xf0\x73\x25\xfc\x5c\x09\x6f\xaf\xb9\x12\x7e\xae\x84\x9f\x2b\xe1\xe7\x4a\xf8\xb9\x12\xbe\x77\xcd\x95\xf0\x83\xec\xce\x95\xf0\x73\x25\xfc\x5c\x09\xbf\xbf\xe6\x4a\xf8\xf6\x35\x57\xc2\xcf\x95\xf0\x81\x6b\xae\x84\x7f\x9c\x4a\x78\xef\x2d\xca\xb9\xd0\xd6\xb9\xef\xf2\x1f\xb7\x98\x06\x44\xe4\x6f\xb4\x60\x0a\xe4\x2d\xf4\x22\x95\x50\x6c\xb7\xda\x15\x54\x29\x8c\x20\xb0\x42\xf8\x3b\x58\x6d\x85\xb8\xf9\xbb\xa4\x83\x53\xdf\x36\xbe\x12\x22\x03\xda\x47\x26\x12\xea\x7f\xc7\x33\xdc\xc0\xe9\x2a\x83\xd7\xa5\x6e\xb6\x3e\xbd\x65\x4b\xa6\xd7\x8d\xe9\x84\x36\x52\x94\xc5\x95\x64\x42\x32\xbd\x7b\xcd\x38\xcb\xcb\xc1\x5a\xd8\xb1\x94\x43\x38\xd1\xb0\x05\x9a\xe9\x6d\xb2\x85\x64\x90\xc5\xb1\x60\xdc\xf6\xd6\x3b\x35\xc2\x3d\x1c\x99\x12\x46\x85\x18\xdf\x3c\x07\xa9\x07\x5b\x1f\xe3\x2d\xa1\xcf\xa5\x37\x99\x34\x3a\xf3\x37\xc0\x8d\xb7\x03\x87\x76\xcd\xf2\x0f\xf2\x3e\x3c\x58\x0a\x81\xb5\x6f\x84\x42\xc8\x72\x2d\xea\x1e\x4e\x1d\x97\x52\xc1\xd7\xe5\x0a\xea\x49\xfe\xe5\x8f\x29\xff\x52\xc8\x8b\x9b\xc1\x71\x08\xcb\xe9\x16\xa4\x71\x4e\x2b\x35\x7f\x68\xfd\xf6\x09\x60\x41\x92\x6e\x18\xb9\x18\x36\x00\x9e\xa7\x7a\xf3\xbb\xf7\xdc\xd0\xf4\xed\x3d\xd4\x98\x7d\xbd\x7b\x4d\xf5\xef\xdd\xf4\x8f\x41\xef\xd1\x8e\x88\x63\x6d\x78\x62\xc6\x6b\x9a\x05\x97\xb0\x61\x4a\xcb\x80\xb9\xf6\x68\xaa\x84\x42\x28\xa6\xc5\x01\xaf\x6a\xba\x99\xf8\x8e\x5f\x27\x2a\xfe\x07\x6e\x54\xfc\xf5\x6e\x69\x1a\xbd\x2a\x26\x92\x69\x96\xd0\xec\x22\x4d\xfb\xa9\x4f\xff\x34\xb1\x0a\x77\xc1\x69\xb6\xd3\x2c\xe9\x89\xdd\xff\xe2\xba\xcc\x32\xe3\x48\xbe\xbd\x05\x29\x59\xda\xb3\x64\x5e\x19\xb1\x9c\x6e\xe0\xaa\xcc\xb2\x2b\x91\xb1\xa4\x37\x26\xe3\xef\x5d\x43\x22\xa1\x6f\xb4\x3d\x01\xc4\xa8\x87\xd1\xf7\x87\x32\xb1\x79\x05\xb7\x90\x75\x89\x85\x6c\x85\xdf\x4e\xe4\x82\x9b\xc1\x65\xbc\xa7\x4a\x21\x6d\xa7\x1b\xe0\x83\xa6\x3d\xa8\xaf\x21\x0c\x37\x6c\x2a\x0b\x29\x72\xd0\x5b\x28\x0f\x5a\x0c\xeb\x88\xe2\xc0\xa5\x64\x7c\xa5\x4e\xe0\xb5\x95\xe3\x21\xec\x65\x41\x00\x68\x1a\xec\x13\xe1\xd4\x1f\xfe\xbd\x24\xbf\xf5\x40\x7d\xe8\xfd\xba\x1f\xb5\x61\x03\x5f\x4b\x2d\xd6\x8a\x1c\x34\xa3\x9b\xdf\x91\xfa\xe5\xc2\x00\x9f\xae\xff\xda\xd6\x90\x3a\xc9\x39\xba\x7d\xf8\xb9\xdb\xcf\xf8\xae\x7a\xa3\xd6\x07\x5b\xab\x01\x44\xb1\x14\x12\x2a\x2b\x88\x0b\xe4\x21\xbb\x79\x33\x96\xb3\x61\x9f\x97\x4c\x9e\x0d\x94\xef\xde\xae\x83\xa1\x6b\x54\x21\xd2\x22\x2e\x56\x2e\xa8\xd6\x20\xf9\x39\xf9\xe7\xf1\x3f\xfe\xf0\xf3\xe2\xe4\x8b\xe3\xe3\x0f\x9f\x2d\xfe\xfc\xfd\x1f\x8e\xff\xb1\xc4\xff\xfc\xfe\xe4\x8b\x93\x9f\xab\x3f\xfe\x70\x72\x72\x7c\xfc\xe1\xeb\xd7\x5f\xbd\xbf\x7a\xf9\x3d\x3b\xf9\xf9\x03\x2f\xf3\x1b\xfb\xd7\xcf\xc7\x1f\xe0\xe5\xf7\x91\x44\x4e\x4e\xbe\xf8\x9d\x97\xa5\x8f\x8b\x9b\x72\x05\x92\x83\x06\xb5\x60\x5c\x2f\x84\x5c\xd8\x5e\x9c\x13\x2d\xbd\x28\x48\x6b\xdc\x9f\xbe\xc2\x11\x71\x3f\xae\x5c\x6e\x33\xa7\x1f\x8d\x57\x47\x68\x2e\x4a\x8b\xb9\xba\xfd\xae\x5e\x5e\x6a\x4d\xab\xe1\x09\xf2\x5a\x60\xf5\xc9\x5a\x9c\x93\xad\xd6\x85\x3a\x3f\x3b\xdb\xf3\xbb\x64\xe2\x2c\x15\x89\x3a\x4b\x04\x4f\xa0\xd0\xf8\x9f\x35\xdb\x94\x12\x43\xfa\xb3\x9c\x72\xba\x81\x85\x6b\x76\x51\x93\x5f\xd4\xea\x77\xf6\xf4\x30\x13\x48\xaa\xfd\xc2\xb3\x1a\xfe\x8a\xd4\xf0\x9d\x1b\x93\xae\x22\xda\xf0\xe2\x20\x45\x94\xf5\x9e\xd9\xcb\x35\xa9\xe9\x33\x45\x44\xce\xb4\x86\x14\x77\xa5\xd3\xbd\x3d\xf3\x27\x73\x99\x26\x29\xac\x69\x99\x69\xc4\xaa\xdd\x94\xc1\xdd\xd8\x76\xe3\x3c\x7c\x2c\x32\x96\x30\x9d\xed\xf6\x50\xe7\xa9\x3d\x0f\xe1\x8e\x29\x3f\xb3\x36\xb5\xc1\xf2\xc2\x26\x37\x50\xf5\x17\x15\xc8\x89\x48\xe6\xaf\x76\x1a\x8d\xb8\x4d\x49\x69\x42\xb2\xe7\x82\x6b\xf8\x38\xe8\x4b\xb6\x86\xff\xda\x3d\x4f\x04\xfe\xa0\xea\xd2\x3a\x07\x73\xcb\x92\x23\x4e\x7b\xc8\x92\x83\xf6\xe8\x4a\xb2\x5b\x96\xc1\x06\x5e\xaa\x84\xda\x92\x80\xa8\x12\xcd\xa7\x17\x9e\xb7\x51\x6d\xa4\xc8\x14\xb9\xdb\x02\x7e\xc1\x91\x1a\x4e\x12\x50\xfe\x6c\x73\x42\x39\xd9\x50\xc6\xed\xc7\x08\x8b\x8a\x28\xa2\xcc\x1c\x0b\x08\x0b\x2a\x81\xeb\x8a\x90\xcb\x17\x1b\xb7\xd9\x4b\x33\x65\x12\x12\xa3\x77\x35\x3f\xf5\x21\x01\x3f\x70\xb8\xfb\xc1\xb4\xa2\xc8\x3a\xa3\x1b\x5b\xf4\xb9\x72\xc5\x5b\xfe\x92\x27\x5b\x59\xec\xb4\x63\xcf\x8a\x57\x10\x4c\xe1\x2c\x27\x34\xbb\xa3\x3b\x7f\xe7\xef\x5c\xf5\x63\x83\x36\x53\xe7\xe4\xd9\x09\x0e\x2e\x55\xa4\xa6\x9d\x92\x3f\x9e\xe0\xf1\x06\xcf\x2f\xae\x7e\xb8\xfe\x7f\xd7\x3f\x5c\xbc\x78\x7d\xf9\x26\xac\xa6\x21\xb4\x2a\xa1\x05\x5d\xb1\x8c\x85\xcc\x78\xef\xd4\x81\xe6\x4b\x38\x4d\xd3\xf4\x2c\x95\xa2\xb0\xfd\xa8\x92\x0f\x75\x5f\x02\x49\xd2\x17\x0d\xcb\x61\xfa\xef\x2c\x49\x55\x60\xd2\x6a\x68\x23\x29\xd7\xb5\xcb\xe5\x57\xa4\x5a\x84\xb2\xe4\x9a\xe5\xde\xa2\xd3\x98\x8a\x23\x9a\x06\x33\xef\xed\x22\x2d\x3c\x30\xa1\xc9\x72\xe0\xcd\x88\xac\x5a\xdb\x05\xad\xc8\xee\xf6\x95\x3c\xe4\xea\xed\xf5\xe5\xdf\x3b\xa3\xb1\x2b\xc2\x09\x9e\xc8\x4c\x5d\x4c\x9e\xce\x0c\x79\xb4\x74\xde\x41\x2e\x6e\xff\x93\xe4\x33\xea\x69\xd5\x36\xce\xab\x62\x6d\x01\x96\xbc\x69\x1e\x78\xe3\x7d\x92\x63\xed\xf9\x95\x35\x47\xa0\x42\x45\x9b\x8d\xb7\xf6\x13\x14\x53\xee\xe6\x55\xae\x99\xad\xe1\x6e\x6d\xf4\x93\x42\x8c\x5a\xc5\xad\x50\x7a\xd9\x9a\xcf\x6b\x9a\x29\xef\xe4\x1b\xb7\x4c\xc6\xb8\xbe\x36\x8e\x4d\x94\x74\xea\xa7\x49\x0a\x5c\x54\x65\x88\xa6\x15\xac\xc5\x95\x22\x21\xd6\x4b\xd2\x82\x94\x01\xa7\x63\x8d\x15\x8f\xd0\x34\x5e\x68\xf2\x2a\xc3\xc4\x54\xd5\xc7\xab\xba\xc5\xf0\x21\x33\xa5\xaa\x4f\x98\xe9\x18\xa6\xbd\xdf\xb4\xc6\x02\x3d\x9a\x62\x61\x44\x41\xf5\x56\x05\x4f\x63\xc8\xa9\xba\x81\xd4\x3e\xe8\xd6\x41\xe7\xcf\xd9\x96\x6a\xd6\xde\x9b\xfe\xaf\x81\xea\x52\x02\xae\x73\x21\x67\x6b\x05\x55\x5e\x27\x3c\x68\x81\xb9\x61\xfa\xf0\x96\x67\xbb\x77\x42\xe8\x2f\x59\x06\x76\x2b\x41\xd4\x00\x7e\xe7\x3c\x05\x5b\x4e\x5c\x8b\xca\x2c\x75\x14\xe9\x2e\x50\x38\xa8\x8a\xeb\x9a\xf4\xe8\xca\x62\x06\xec\x9e\x8a\x28\x4b\x7e\xa1\xbe\x92\xa2\xf4\x1a\xbb\xde\x02\xf9\xd5\xe5\x0b\x9c\x37\xa5\x5d\xd5\x81\x6b\xb9\xb3\xfb\x35\x5c\xde\xbb\xee\x60\x60\x9e\x3a\xdf\xe2\x1b\xa3\x3f\x1d\x8d\x31\x7e\x4c\xc9\x15\xe8\x25\x79\x4d\x77\x84\x66\x4a\x54\xce\x4b\x60\xea\x5f\x89\xf4\xba\xed\x7b\x2e\xb1\xf8\xd0\xbe\x46\x56\x42\x6f\x49\xe7\x01\x2c\xf5\xe9\xbf\xe7\x8f\x06\xea\xb2\xa0\x46\x59\x03\xe3\x3d\xb2\x9a\xde\x80\x22\x85\x84\x04\x52\xe0\x89\x77\x74\x1a\xc8\xee\x9f\xfe\x77\x70\x04\x43\x21\x24\x8e\xe0\x1b\xc1\x8d\x5a\xc6\x6d\x3e\xe2\x29\x4b\x5c\x31\xb3\xab\x0c\xde\xab\x24\x56\x55\x3a\xbf\x8c\x62\x6d\xa5\x51\xca\xd0\xfc\x97\xb6\xee\x52\x96\x6e\x97\xd1\xd7\xe5\x0a\x32\xd0\xd6\xe9\xbc\xb5\x39\x25\x7b\x4a\x14\x62\xe9\x84\xea\x6a\xc0\x43\xf3\x15\xb8\x2a\x65\x75\x3e\x99\x26\xa9\x00\x5b\x02\xe1\x58\xfb\xe6\xf2\x05\xf9\x8c\x1c\x1b\xde\x4e\x70\x18\xd7\x94\x65\xa1\xcf\x45\x28\x4d\x65\xb7\xaf\x6c\x5d\x91\xc6\x2e\xa0\xce\x11\x21\xed\x94\x3a\x25\x5c\x10\x55\x06\x6c\x9f\xeb\x9b\xf1\x84\x2b\x07\xbb\x00\x69\x06\x15\x31\x90\x9e\xea\xfa\x54\xd4\xcf\xf3\x74\xd5\xdd\xab\xa8\x9f\xea\x43\xa8\x6e\xa4\x61\xf9\x46\xf5\xb3\x6d\xd5\xd5\xb3\x2b\xdf\x3c\xa0\x5d\x69\x2e\xd5\x46\x47\xdb\xbd\xb6\x8a\x98\x83\xa6\x29\xd5\xd4\xd9\x9b\xea\x01\xbf\xd5\x8d\x1f\xd2\xd0\xd0\x05\xe0\xa4\x91\x21\x0d\x0e\x9d\x7f\x32\xfd\xa2\xd6\x48\xc1\x2b\xc6\xcb\x8f\x6f\x8b\xc1\xf2\x9c\xea\xea\x8d\xfd\xf5\x4b\x7c\x0d\x87\x18\xf5\x10\x85\x6c\xab\x04\xd3\x2a\x7e\x0a\xe2\xcf\xf6\xba\x6c\x0d\xe5\xa9\xc7\x35\xc1\xe9\x4a\x33\x5b\x5e\x66\x56\x60\xca\x53\xe1\xdf\x14\xd8\x65\xae\x3e\xd3\x70\xcf\xd0\x14\xe5\xf8\x2d\xce\xf7\x98\x70\x32\x1b\xca\x5e\x36\xaf\xd6\xa8\x63\xae\xd3\x38\x30\x95\x74\xf1\x75\x57\x99\x87\x66\x7f\x5f\x23\x1a\x8e\x69\xe2\x34\x23\xb6\x30\x4e\x64\xde\x74\x62\xaf\x0f\xef\x44\x06\xb6\x82\xba\xea\x84\x79\xfd\x93\xf7\x01\x1f\x8a\xed\x03\x7a\xd1\xad\x3e\x60\x5c\xf1\xa9\xfb\x50\x06\x56\x8e\x5e\x1f\xcc\x32\xd3\xee\x03\xda\xfc\x4f\xdb\x87\xd1\x10\xf9\x8e\xf1\x54\xdc\xa9\xa9\xa6\xf2\x3b\xfb\x5a\x35\xaf\x13\x63\x36\x34\xe3\x1b\xd5\x34\x97\x34\xcb\xa2\x20\xaa\x21\x7b\x59\x21\xb1\xb8\xb9\x19\x23\xae\x9e\xdd\x41\x0b\xea\x25\xba\x02\x23\x7f\x8b\xbe\xff\x8a\xdd\xef\x18\x9b\xb6\xc9\x15\x7d\x2e\x0d\x1d\xcd\x68\x76\x5d\x40\x12\xad\x94\x5f\xbd\xbe\xbe\x68\xbf\x6a\x54\xd4\xee\x01\x36\x3d\x31\xf7\x09\x4d\x73\x86\x5b\x19\x82\x6a\x79\x67\xeb\xb1\xc8\x71\x95\x06\xd8\x30\xbd\x2d\x57\xcb\x44\xe4\x8d\x8c\xc0\x42\xb1\x8d\x3a\x73\x5a\xb5\x30\x9c\x87\x8b\xc1\x19\xcf\x70\x57\x76\xa5\xf4\xfb\xd3\x6a\x1d\x73\x49\xcd\x3d\x0a\x1c\xd3\xf4\xe1\x1d\x16\x2e\x61\xdc\xef\xfa\x1b\x9a\x83\xdd\xa1\x71\x6f\xcb\xd0\x1f\x12\x43\xfc\x1e\xc3\x82\xbc\xb9\x5d\x93\xa6\x8b\x4d\x19\x04\x7b\xdb\x95\x8f\xf5\x35\xef\xbf\x04\x55\x9e\xf3\xa4\x7e\xa1\x07\xed\x5e\x32\xb3\xa2\x32\x13\x83\x1e\x75\xb0\x5b\x5d\x6f\x7b\xd8\xab\x36\x8f\xb4\x3d\xeb\x11\x65\x1b\xf1\xba\x23\x1d\xa8\x60\x23\x0f\x6c\x6f\xc8\xc3\xdb\x1c\xf2\xd8\xb5\x3c\xbf\xa9\xea\x41\x3c\xe9\xfe\x13\xd4\xf2\x17\x3d\x25\xe8\xd2\x6d\xa7\x02\x07\x16\xc0\xad\xc8\x52\xdc\x8f\xb3\xb0\x7e\x6b\x95\xf7\x24\x54\x6b\xc9\x56\xa5\x1e\x48\x00\x18\xfd\x4b\x44\x9e\x8b\x26\xd6\x5d\xad\xde\x4b\x62\x1d\x01\x9a\x9d\xb7\xe6\x99\xdb\x3f\x4a\xae\x01\x86\xf1\xfd\x06\xab\x18\x99\x54\x28\x9a\xdb\xbf\x26\xd6\x36\x56\xb1\xc6\xb7\x9b\x4b\x0b\xad\x81\x6b\x3f\x2e\xd8\x12\xcf\xd1\x85\x9d\x1b\xc6\x0c\x96\x45\x95\xd0\xce\x6c\xb5\x70\xd7\xfd\xea\x78\x26\x83\xfa\xcf\xb8\x3d\x73\x62\x49\xae\x45\x0e\xe4\x56\x64\x65\x6e\x3b\xef\x6a\x4c\x5a\x38\x93\x16\x24\xd9\xe2\x59\x46\xe8\xbc\xdc\x19\xb2\xbe\x3d\xdf\xc2\x25\xee\x2b\x92\x68\x6c\xcc\x2b\x75\xad\x53\x21\xd2\x73\xf2\x0f\x4e\x9e\x59\x64\x5c\xdc\x61\xb6\xef\xab\xcb\x17\x7e\x97\x67\x65\x5b\xfe\xf2\x1a\xc5\x45\xfe\x68\xdf\x54\xa0\x37\x2c\x25\x2b\x86\x28\xad\x31\x4b\xc7\x1c\xee\x2c\xba\x6b\x56\x0e\xbb\xb1\x69\x78\xdd\x47\xa3\x63\x59\xac\x90\xa5\x9a\x49\xd7\xcc\x09\xf9\xdc\xb6\x53\x80\x74\x2e\x84\x69\xcb\x7f\xce\xf3\xdb\x77\x4f\xdd\x49\x52\xf2\x6e\x21\xef\x16\x8b\xc5\xc2\xf4\xb3\xc2\xbd\x06\xb0\x3b\x3c\x4e\x48\xa4\x6c\xed\x4f\x49\xd6\xd2\x46\xdd\xde\xb3\xa2\xaa\x93\x44\x6c\x2f\x96\x43\x9b\xf0\xc6\xf0\x86\x30\xd6\xe0\x94\xf3\x39\x8e\xfc\x70\x4d\x2f\xe9\xcd\xe3\x81\x97\xdc\xc6\x32\x45\x56\xb0\xa5\xb7\x4c\x48\xcc\xcc\x9a\x07\x70\x8b\x59\x50\x9b\xda\x7d\xae\xd6\x4d\x37\x70\x2b\x58\x0b\x69\xfe\x31\x74\xe0\x63\x21\x14\x8e\xb7\x62\x29\x3a\xd4\xc3\x0b\xc4\xfb\xfd\xc9\x48\x38\x04\x98\x15\x30\x93\x07\x8f\x21\x6a\x4d\x04\xbb\xdb\xcc\x4c\x38\x21\x75\x25\x8e\x61\xfd\xa4\xa6\xe9\xba\x2b\xc7\x9d\xa1\x3a\x59\x92\x4b\x37\xe2\x5b\x7a\x0b\x84\x0b\x02\xeb\x35\x24\x9a\x08\x4e\xa0\xd8\x42\x0e\x92\x0e\x6b\x7e\x8b\x21\x55\x26\x5b\x42\xd5\xb9\x31\x85\xd2\x28\x94\xad\x47\xc9\x69\x61\x4f\x3d\x40\x43\x96\x32\x59\x9d\xa8\x10\xd8\xf4\x4f\x25\x90\xa3\xb7\x88\x68\xbf\x66\x0a\x77\xe4\x1d\x21\x8d\xa3\x0b\x2c\x35\x38\xc2\xd0\xc2\xe8\xe7\x7e\x51\x6e\x94\xe9\x0c\xd2\xac\x5f\x1d\x2a\x27\x08\x97\x52\x06\x53\x24\xf7\x48\x8f\xd4\x8e\xd5\x20\xc3\x93\x53\x23\x5d\xa7\xc4\x0f\x36\x3d\x3c\xd0\x34\xc9\x39\x72\x79\xc8\xfd\x31\x2d\xc3\xb1\xf6\xfd\x0c\xc4\x58\x5a\xe4\x51\x52\x22\x0f\x9f\x0e\x39\x3c\x15\x62\x53\x1e\xde\xf5\x65\x6a\x1a\xa4\x91\xee\xf0\xa0\x19\x31\x29\x10\x1f\x58\xee\xf3\x03\x0e\x53\xd1\x91\x98\xe4\x40\xff\x3d\x9c\xf3\x08\xe6\x3b\xee\x91\xeb\x08\x1b\x89\xfb\xe4\x39\xcc\xf8\x0c\x9b\xdf\xb8\x31\x9b\x94\xe0\x78\x84\xe4\xc6\x27\x31\x2b\xe3\xf9\x8d\xe9\xb9\x8d\x18\xb0\xee\x3e\x89\x8d\x8a\x83\x41\xc2\x53\x93\x1a\xff\x66\x8b\xcc\xe8\xb6\x85\x50\x52\xe3\xe0\x84\x46\x5c\x8d\xdf\xe1\x95\x2a\x81\x24\xc6\xc1\x09\x8c\x47\xe6\x39\x94\xb4\x38\x38\x61\xf1\xc8\x3c\x87\x92\x14\x07\x27\x28\x1e\x95\xe7\x70\xed\x76\x23\x7a\x47\x7f\x77\xdc\xbe\x5d\xd4\xc7\x0e\x62\xb4\xaf\xba\x29\xdb\x35\x93\xaa\xae\x6a\xc6\xe5\xce\x13\xf2\xb6\x4d\x0f\x1e\x52\x5c\xe1\x3f\xbd\xf4\xef\x53\x33\xcf\x59\x4e\xe5\xce\x38\xdb\x7e\x0b\xd4\x32\x98\x5c\x54\x2c\x56\x9e\x8a\xfd\x06\x18\x16\xe2\xef\xc2\x82\x0d\xd4\x6b\x8e\x67\xcd\xc7\x72\xe6\xa1\x62\x4b\xb5\x53\x89\x1e\xde\x43\xd8\xae\xa2\xb7\xcf\x21\x2a\xd5\x38\x0a\xb2\xde\x20\x99\x56\x94\x30\x31\x63\x98\xf6\xfa\x85\x88\xbb\x5c\xe1\xe7\xe5\x98\xde\x1a\x19\xda\x10\xb3\x41\xe3\xd8\x61\x25\xbd\xf5\x67\x38\xdf\x90\xe3\x79\xd6\x95\x57\x9a\xd1\x92\x0f\x9f\x58\x16\x90\xf2\x40\x67\xeb\xc0\x9d\x92\x1b\x90\x1c\x32\x52\x50\x49\x73\xd0\xf6\x5b\x8e\x76\xc1\x1a\x24\x36\x9e\xf7\xe1\x41\xe0\xbd\xc5\xcc\x1b\x97\x30\xa0\x15\x59\x8c\xd4\x7d\x4d\x93\x38\xf8\x17\x97\xc0\x48\x06\xbe\xad\xce\x80\x7d\x40\x0e\xc2\xa7\xc3\x2c\x50\x3e\x9e\x5b\xfe\xd5\x3b\x0a\xd3\x1e\x9e\x06\xe3\x99\xd2\xc7\xcb\x92\x86\x32\xa4\x66\x86\x20\x58\xd9\x34\x4d\x31\xae\x6b\x65\x82\x1e\x3c\x4d\xfa\x80\xe9\x8a\xb1\x69\x12\x9f\x1a\x7d\x8c\xb4\xe8\xc3\xa7\x44\x0f\x4b\x87\x86\x8f\x67\x3f\x2c\x15\x3a\x7e\x8e\xcb\xa4\x14\xe8\x63\xa4\x3f\xa7\xa5\x3e\xc7\x0d\x4e\x4c\xca\xf3\xf0\x74\x27\x11\xfe\xa2\xab\x83\x52\x9d\x75\x70\xed\x25\xfb\x58\x69\xce\xc3\x6c\x45\xd0\xa7\x7c\xc0\xf4\xe6\xe1\xde\xa7\xf7\x96\x84\x22\x63\x09\x7d\x3e\xb4\x59\xe2\xb0\xa3\x31\xdc\x19\x05\x17\x49\x32\x44\x33\x78\x3c\x86\x3f\x59\x49\x26\xed\x1e\xbe\x8f\x97\x6e\x73\x47\xd3\xcf\xda\xf0\x39\x35\x07\x25\x86\x2d\x13\xb1\x63\xa8\x45\x06\x72\x58\x6e\xdd\xcf\x62\x74\x56\x5a\x7b\x98\x63\xe3\xfd\xae\xe6\x79\x9c\xc6\x9e\xad\x28\x44\x6a\x77\x5f\xbc\xaf\x69\x61\x40\xa6\x35\xc5\xaf\x09\x9b\x69\x6e\xef\x18\x97\x72\xf0\xcc\x3f\x63\x22\xb4\x8d\xd6\x9a\xdf\x56\xd6\x12\xbf\xe5\xf0\xd7\xfa\xf8\xd3\x53\x9b\x3e\xf9\x1b\x29\x55\xf5\xbd\x96\xc0\x29\x8a\xf5\x01\xa4\x7f\xad\xfe\xf7\xb7\xfe\xec\x0a\xaf\xc5\xb6\xbd\x08\xcf\xf9\xa5\xcd\xeb\xb0\x06\xda\x0d\xae\x5b\x2e\xe5\xa3\x85\xe5\x35\x7c\x44\xa1\x3d\x6e\x13\x1f\xb4\x9f\x94\x68\x90\x50\x4b\xfb\xb9\x8b\xc6\x40\xba\x73\x01\xc2\xc7\x3c\x53\x09\xe4\x8d\x70\x5f\x57\x81\x53\x72\x85\x5f\x60\xde\xff\x82\xa6\xed\x8d\xb0\xdf\x59\xf1\x18\xa0\x91\x69\xe5\x3d\x55\xbd\x25\xa4\xaf\xf7\x67\xa8\xdb\x7e\xb5\xce\x50\xdf\xab\x62\x15\xb2\xfb\x4c\xa1\xa8\xbe\x6e\x34\x2c\xad\x1b\xd8\xed\x3f\x76\xe9\xce\x6d\xc7\x14\xd9\xe9\xd8\x01\xc6\xd5\xc1\xd7\xf6\xc8\xea\xbf\x54\x9b\x8a\xf2\x15\xe3\x96\x31\xdb\x60\x35\x94\xd8\x66\x75\x98\xad\x77\xdf\x95\x79\x08\x59\x3a\x44\xb0\xe1\x43\xdc\x5b\xd2\x7d\x1b\x79\x64\x7b\xb5\xee\xda\xad\xf0\x1e\xa6\x87\x8e\x66\x6f\x9c\xb3\xfe\xf2\xc7\x92\x66\xed\xa5\xdc\xfd\x64\x1f\xf2\x50\xed\x7d\x0a\xf0\x8e\x65\x69\x42\xa5\x3d\x36\xc0\x4e\x71\xa2\x84\xc3\x6d\xd0\xb2\x24\x94\xd7\xe6\x23\x20\x60\x1c\x79\xe5\x82\x35\x2a\x35\x4b\xca\x8c\x4a\x62\xe6\xe2\x46\xc8\xdd\x41\xb2\xdf\x2b\xe4\x35\x24\x82\xa7\x31\x11\xf4\xfb\xee\x3b\xcd\xd1\xd0\xb6\xa8\x80\xb9\x6f\x7e\xb0\x1c\x02\xde\x43\x63\x3a\x1c\xdb\x8c\x74\xa5\x9d\x62\x5d\xd9\x94\x7a\xd2\x36\xce\x45\x40\xa5\xf5\xd0\xac\xbf\x94\xc8\xec\x07\x96\x4e\x1a\x96\xb9\x9e\x95\x4b\xf2\x7f\x77\x55\x56\xf4\x94\xd8\x22\x0b\xff\x67\x8d\xb0\xc0\xc1\xf1\xe7\x26\x87\xa5\xd8\x98\xe6\x6b\x21\xe1\x16\x24\x39\x4e\x05\xa6\xd7\xf0\x4b\x3f\x27\x3e\xd5\xfb\xff\x20\x05\x2a\x19\x87\x8d\xfd\x04\x8d\x9b\x62\x55\x68\xa7\x5d\x89\x07\x55\xe4\x33\x72\x6c\x3f\x1b\xc4\xf2\x1c\x52\x46\x35\x64\xde\x73\x7a\xab\x23\x77\x02\x1b\x00\xef\x0f\x39\x05\xf0\x85\x01\x6c\xa1\x65\x0c\xad\xb3\xd8\xb1\x84\xf5\x72\xe8\xfd\x4e\xc4\xc0\x57\x00\xec\x1c\x6c\x65\x80\xea\x93\x8d\x2b\x43\x38\x72\x8c\xc6\xbf\x8c\xae\x51\x22\x61\x83\xf3\xc8\xce\x91\x03\x66\xd1\xa8\x5f\xda\x85\x25\x86\x1c\xa3\xc5\xfe\x88\xd8\xd6\xaf\xee\xd0\xc1\xd6\x6f\x9d\xd3\xe8\x5a\xf7\xf6\x27\xb7\xb5\x7e\x1e\x58\x14\x16\x2d\xe7\xb8\x75\xa3\xed\xe3\x3e\x09\x76\xb5\xf3\x93\x3b\x5b\xf1\x9c\xdc\x3e\xa3\x59\xb1\xa5\xcf\xf6\xbf\xa1\x6d\xb1\xf0\x4f\xeb\xb6\x3b\xd5\x33\x6d\x9c\xfa\xa2\xb4\x90\x74\x03\xee\x97\xff\x09\x00\x00\xff\xff\x0f\x6d\x38\x96\xa3\xeb\x00\x00") func installerKubepackCom_kubepackoperatorsYamlBytes() ([]byte, error) { @@ -149,7 +170,8 @@ func AssetNames() []string { // _bindata is a table, holding each asset generator, mapped to its name. var _bindata = map[string]func() (*asset, error){ - "installer.kubepack.com_kubepackoperators.yaml": installerKubepackCom_kubepackoperatorsYaml, + "installer.kubepack.com_kubepackoperators.v1.yaml": installerKubepackCom_kubepackoperatorsV1Yaml, + "installer.kubepack.com_kubepackoperators.yaml": installerKubepackCom_kubepackoperatorsYaml, } // AssetDir returns the file names below a certain @@ -193,7 +215,8 @@ type bintree struct { } var _bintree = &bintree{nil, map[string]*bintree{ - "installer.kubepack.com_kubepackoperators.yaml": {installerKubepackCom_kubepackoperatorsYaml, map[string]*bintree{}}, + "installer.kubepack.com_kubepackoperators.v1.yaml": {installerKubepackCom_kubepackoperatorsV1Yaml, map[string]*bintree{}}, + "installer.kubepack.com_kubepackoperators.yaml": {installerKubepackCom_kubepackoperatorsYaml, map[string]*bintree{}}, }} // RestoreAsset restores an asset under the given directory diff --git a/api/crds/installer.kubepack.com_kubepackoperators.v1.yaml b/api/crds/installer.kubepack.com_kubepackoperators.v1.yaml new file mode 100644 index 00000000..c345d264 --- /dev/null +++ b/api/crds/installer.kubepack.com_kubepackoperators.v1.yaml @@ -0,0 +1,1095 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + creationTimestamp: null + labels: + app: vault + name: kubepackoperators.installer.kubepack.com +spec: + group: installer.kubepack.com + names: + categories: + - kubepack + - appscode + kind: KubepackOperator + listKind: KubepackOperatorList + plural: kubepackoperators + singular: kubepackoperator + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: KubepackOperatorSpec is the schema for Kubepack Operator + values file + properties: + affinity: + description: If specified, the pod's scheduling constraints + properties: + nodeAffinity: + description: Describes node affinity scheduling rules for the + pod. + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods to + nodes that satisfy the affinity expressions specified by + this field, but it may choose a node that violates one or + more of the expressions. The node that is most preferred + is the one with the greatest sum of weights, i.e. for each + node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, + etc.), compute a sum by iterating through the elements of + this field and adding "weight" to the sum if the node matches + the corresponding matchExpressions; the node(s) with the + highest sum are the most preferred. + items: + description: An empty preferred scheduling term matches + all objects with implicit weight 0 (i.e. it's a no-op). + A null preferred scheduling term matches no objects (i.e. + is also a no-op). + properties: + preference: + description: A node selector term, associated with the + corresponding weight. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: A node selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists, DoesNotExist. Gt, and + Lt. + type: string + values: + description: An array of string values. If + the operator is In or NotIn, the values + array must be non-empty. If the operator + is Exists or DoesNotExist, the values array + must be empty. If the operator is Gt or + Lt, the values array must have a single + element, which will be interpreted as an + integer. This array is replaced during a + strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: A node selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists, DoesNotExist. Gt, and + Lt. + type: string + values: + description: An array of string values. If + the operator is In or NotIn, the values + array must be non-empty. If the operator + is Exists or DoesNotExist, the values array + must be empty. If the operator is Gt or + Lt, the values array must have a single + element, which will be interpreted as an + integer. This array is replaced during a + strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + weight: + description: Weight associated with matching the corresponding + nodeSelectorTerm, in the range 1-100. + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the affinity requirements specified by this + field are not met at scheduling time, the pod will not be + scheduled onto the node. If the affinity requirements specified + by this field cease to be met at some point during pod execution + (e.g. due to an update), the system may or may not try to + eventually evict the pod from its node. + properties: + nodeSelectorTerms: + description: Required. A list of node selector terms. + The terms are ORed. + items: + description: A null or empty node selector term matches + no objects. The requirements of them are ANDed. The + TopologySelectorTerm type implements a subset of the + NodeSelectorTerm. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: A node selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists, DoesNotExist. Gt, and + Lt. + type: string + values: + description: An array of string values. If + the operator is In or NotIn, the values + array must be non-empty. If the operator + is Exists or DoesNotExist, the values array + must be empty. If the operator is Gt or + Lt, the values array must have a single + element, which will be interpreted as an + integer. This array is replaced during a + strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: A node selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists, DoesNotExist. Gt, and + Lt. + type: string + values: + description: An array of string values. If + the operator is In or NotIn, the values + array must be non-empty. If the operator + is Exists or DoesNotExist, the values array + must be empty. If the operator is Gt or + Lt, the values array must have a single + element, which will be interpreted as an + integer. This array is replaced during a + strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + type: array + required: + - nodeSelectorTerms + type: object + type: object + podAffinity: + description: Describes pod affinity scheduling rules (e.g. co-locate + this pod in the same node, zone, etc. as some other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods to + nodes that satisfy the affinity expressions specified by + this field, but it may choose a node that violates one or + more of the expressions. The node that is most preferred + is the one with the greatest sum of weights, i.e. for each + node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, + etc.), compute a sum by iterating through the elements of + this field and adding "weight" to the sum if the node has + pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added per-node to find the most preferred node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, associated + with the corresponding weight. + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: A label selector requirement + is a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only "value". + The requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies which namespaces + the labelSelector applies to (matches against); + null or empty list means "this pod's namespace" + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the pods + matching the labelSelector in the specified namespaces, + where co-located is defined as running on a node + whose value of the label with key topologyKey + matches that of any node on which any of the selected + pods is running. Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: weight associated with matching the corresponding + podAffinityTerm, in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the affinity requirements specified by this + field are not met at scheduling time, the pod will not be + scheduled onto the node. If the affinity requirements specified + by this field cease to be met at some point during pod execution + (e.g. due to a pod label update), the system may or may + not try to eventually evict the pod from its node. When + there are multiple elements, the lists of nodes corresponding + to each podAffinityTerm are intersected, i.e. all terms + must be satisfied. + items: + description: Defines a set of pods (namely those matching + the labelSelector relative to the given namespace(s)) + that this pod should be co-located (affinity) or not co-located + (anti-affinity) with, where co-located is defined as running + on a node whose value of the label with key + matches that of any node on which a pod of the set of + pods is running + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. If the + operator is Exists or DoesNotExist, the + values array must be empty. This array is + replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is "In", + and the values array contains only "value". The + requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies which namespaces the + labelSelector applies to (matches against); null or + empty list means "this pod's namespace" + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where + co-located is defined as running on a node whose value + of the label with key topologyKey matches that of + any node on which any of the selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + description: Describes pod anti-affinity scheduling rules (e.g. + avoid putting this pod in the same node, zone, etc. as some + other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods to + nodes that satisfy the anti-affinity expressions specified + by this field, but it may choose a node that violates one + or more of the expressions. The node that is most preferred + is the one with the greatest sum of weights, i.e. for each + node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling anti-affinity expressions, + etc.), compute a sum by iterating through the elements of + this field and adding "weight" to the sum if the node has + pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added per-node to find the most preferred node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, associated + with the corresponding weight. + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: A label selector requirement + is a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only "value". + The requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies which namespaces + the labelSelector applies to (matches against); + null or empty list means "this pod's namespace" + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the pods + matching the labelSelector in the specified namespaces, + where co-located is defined as running on a node + whose value of the label with key topologyKey + matches that of any node on which any of the selected + pods is running. Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: weight associated with matching the corresponding + podAffinityTerm, in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the anti-affinity requirements specified by + this field are not met at scheduling time, the pod will + not be scheduled onto the node. If the anti-affinity requirements + specified by this field cease to be met at some point during + pod execution (e.g. due to a pod label update), the system + may or may not try to eventually evict the pod from its + node. When there are multiple elements, the lists of nodes + corresponding to each podAffinityTerm are intersected, i.e. + all terms must be satisfied. + items: + description: Defines a set of pods (namely those matching + the labelSelector relative to the given namespace(s)) + that this pod should be co-located (affinity) or not co-located + (anti-affinity) with, where co-located is defined as running + on a node whose value of the label with key + matches that of any node on which a pod of the set of + pods is running + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. If the + operator is Exists or DoesNotExist, the + values array must be empty. This array is + replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is "In", + and the values array contains only "value". The + requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies which namespaces the + labelSelector applies to (matches against); null or + empty list means "this pod's namespace" + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where + co-located is defined as running on a node whose value + of the label with key topologyKey matches that of + any node on which any of the selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + annotations: + additionalProperties: + type: string + type: object + apiserver: + properties: + bypassValidatingWebhookXray: + type: boolean + ca: + type: string + enableMutatingWebhook: + type: boolean + enableValidatingWebhook: + type: boolean + groupPriorityMinimum: + format: int32 + type: integer + healthcheck: + properties: + enabled: + type: boolean + type: object + servingCerts: + properties: + caCrt: + type: string + generate: + type: boolean + serverCrt: + type: string + serverKey: + type: string + required: + - generate + type: object + useKubeapiserverFqdnForAks: + type: boolean + versionPriority: + format: int32 + type: integer + required: + - ca + - enableMutatingWebhook + - enableValidatingWebhook + - groupPriorityMinimum + - healthcheck + - servingCerts + - useKubeapiserverFqdnForAks + - versionPriority + type: object + cleaner: + properties: + registry: + type: string + repository: + type: string + tag: + type: string + required: + - registry + - repository + - tag + type: object + criticalAddon: + type: boolean + enableAnalytics: + type: boolean + fullnameOverride: + type: string + imagePullPolicy: + type: string + imagePullSecrets: + items: + type: string + type: array + logLevel: + format: int32 + type: integer + monitoring: + properties: + agent: + type: string + operator: + type: boolean + prometheus: + properties: + namespace: + type: string + type: object + serviceMonitor: + properties: + labels: + additionalProperties: + type: string + type: object + type: object + required: + - agent + - prometheus + - serviceMonitor + type: object + nameOverride: + type: string + nodeSelector: + additionalProperties: + type: string + type: object + operator: + properties: + registry: + type: string + repository: + type: string + resources: + description: Compute Resources required by the sidecar container. + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' + type: object + type: object + securityContext: + description: Security options the pod should run with. + properties: + allowPrivilegeEscalation: + description: 'AllowPrivilegeEscalation controls whether a + process can gain more privileges than its parent process. + This bool directly controls if the no_new_privs flag will + be set on the container process. AllowPrivilegeEscalation + is true always when the container is: 1) run as Privileged + 2) has CAP_SYS_ADMIN' + type: boolean + capabilities: + description: The capabilities to add/drop when running containers. + Defaults to the default set of capabilities granted by the + container runtime. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + drop: + description: Removed capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + type: object + privileged: + description: Run container in privileged mode. Processes in + privileged containers are essentially equivalent to root + on the host. Defaults to false. + type: boolean + procMount: + description: procMount denotes the type of proc mount to use + for the containers. The default is DefaultProcMount which + uses the container runtime defaults for readonly paths and + masked paths. This requires the ProcMountType feature flag + to be enabled. + type: string + readOnlyRootFilesystem: + description: Whether this container has a read-only root filesystem. + Default is false. + type: boolean + runAsGroup: + description: The GID to run the entrypoint of the container + process. Uses runtime default if unset. May also be set + in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext + takes precedence. + format: int64 + type: integer + runAsNonRoot: + description: Indicates that the container must run as a non-root + user. If true, the Kubelet will validate the image at runtime + to ensure that it does not run as UID 0 (root) and fail + to start the container if it does. If unset or false, no + such validation will be performed. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, the + value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: The UID to run the entrypoint of the container + process. Defaults to user specified in image metadata if + unspecified. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, the + value specified in SecurityContext takes precedence. + format: int64 + type: integer + seLinuxOptions: + description: The SELinux context to be applied to the container. + If unspecified, the container runtime will allocate a random + SELinux context for each container. May also be set in + PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext + takes precedence. + properties: + level: + description: Level is SELinux level label that applies + to the container. + type: string + role: + description: Role is a SELinux role label that applies + to the container. + type: string + type: + description: Type is a SELinux type label that applies + to the container. + type: string + user: + description: User is a SELinux user label that applies + to the container. + type: string + type: object + windowsOptions: + description: The Windows specific settings applied to all + containers. If unspecified, the options from the PodSecurityContext + will be used. If set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence. + properties: + gmsaCredentialSpec: + description: GMSACredentialSpec is where the GMSA admission + webhook (https://github.com/kubernetes-sigs/windows-gmsa) + inlines the contents of the GMSA credential spec named + by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name of the + GMSA credential spec to use. + type: string + runAsUserName: + description: The UserName in Windows to run the entrypoint + of the container process. Defaults to the user specified + in image metadata if unspecified. May also be set in + PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext + takes precedence. + type: string + type: object + type: object + tag: + type: string + required: + - registry + - repository + - tag + type: object + podAnnotations: + additionalProperties: + type: string + type: object + podSecurityContext: + description: 'PodSecurityContext holds pod-level security attributes + and common container settings. Optional: Defaults to empty. See + type description for default values of each field.' + properties: + fsGroup: + description: "A special supplemental group that applies to all + containers in a pod. Some volume types allow the Kubelet to + change the ownership of that volume to be owned by the pod: + \n 1. The owning GID will be the FSGroup 2. The setgid bit is + set (new files created in the volume will be owned by FSGroup) + 3. The permission bits are OR'd with rw-rw---- \n If unset, + the Kubelet will not modify the ownership and permissions of + any volume." + format: int64 + type: integer + fsGroupChangePolicy: + description: 'fsGroupChangePolicy defines behavior of changing + ownership and permission of the volume before being exposed + inside Pod. This field will only apply to volume types which + support fsGroup based ownership(and permissions). It will have + no effect on ephemeral volume types such as: secret, configmaps + and emptydir. Valid values are "OnRootMismatch" and "Always". + If not specified defaults to "Always".' + type: string + runAsGroup: + description: The GID to run the entrypoint of the container process. + Uses runtime default if unset. May also be set in SecurityContext. If + set in both SecurityContext and PodSecurityContext, the value + specified in SecurityContext takes precedence for that container. + format: int64 + type: integer + runAsNonRoot: + description: Indicates that the container must run as a non-root + user. If true, the Kubelet will validate the image at runtime + to ensure that it does not run as UID 0 (root) and fail to start + the container if it does. If unset or false, no such validation + will be performed. May also be set in SecurityContext. If set + in both SecurityContext and PodSecurityContext, the value specified + in SecurityContext takes precedence. + type: boolean + runAsUser: + description: The UID to run the entrypoint of the container process. + Defaults to user specified in image metadata if unspecified. + May also be set in SecurityContext. If set in both SecurityContext + and PodSecurityContext, the value specified in SecurityContext + takes precedence for that container. + format: int64 + type: integer + seLinuxOptions: + description: The SELinux context to be applied to all containers. + If unspecified, the container runtime will allocate a random + SELinux context for each container. May also be set in SecurityContext. If + set in both SecurityContext and PodSecurityContext, the value + specified in SecurityContext takes precedence for that container. + properties: + level: + description: Level is SELinux level label that applies to + the container. + type: string + role: + description: Role is a SELinux role label that applies to + the container. + type: string + type: + description: Type is a SELinux type label that applies to + the container. + type: string + user: + description: User is a SELinux user label that applies to + the container. + type: string + type: object + supplementalGroups: + description: A list of groups applied to the first process run + in each container, in addition to the container's primary GID. If + unspecified, no groups will be added to any container. + items: + format: int64 + type: integer + type: array + sysctls: + description: Sysctls hold a list of namespaced sysctls used for + the pod. Pods with unsupported sysctls (by the container runtime) + might fail to launch. + items: + description: Sysctl defines a kernel parameter to be set + properties: + name: + description: Name of a property to set + type: string + value: + description: Value of a property to set + type: string + required: + - name + - value + type: object + type: array + windowsOptions: + description: The Windows specific settings applied to all containers. + If unspecified, the options within a container's SecurityContext + will be used. If set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence. + properties: + gmsaCredentialSpec: + description: GMSACredentialSpec is where the GMSA admission + webhook (https://github.com/kubernetes-sigs/windows-gmsa) + inlines the contents of the GMSA credential spec named by + the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name of the GMSA + credential spec to use. + type: string + runAsUserName: + description: The UserName in Windows to run the entrypoint + of the container process. Defaults to the user specified + in image metadata if unspecified. May also be set in PodSecurityContext. + If set in both SecurityContext and PodSecurityContext, the + value specified in SecurityContext takes precedence. + type: string + type: object + type: object + replicaCount: + format: int32 + type: integer + serviceAccount: + properties: + annotations: + additionalProperties: + type: string + type: object + create: + type: boolean + name: + type: string + required: + - create + type: object + tolerations: + description: If specified, the pod's tolerations. + items: + description: The pod this Toleration is attached to tolerates any + taint that matches the triple using the matching + operator . + properties: + effect: + description: Effect indicates the taint effect to match. Empty + means match all taint effects. When specified, allowed values + are NoSchedule, PreferNoSchedule and NoExecute. + type: string + key: + description: Key is the taint key that the toleration applies + to. Empty means match all taint keys. If the key is empty, + operator must be Exists; this combination means to match all + values and all keys. + type: string + operator: + description: Operator represents a key's relationship to the + value. Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod + can tolerate all taints of a particular category. + type: string + tolerationSeconds: + description: TolerationSeconds represents the period of time + the toleration (which must be of effect NoExecute, otherwise + this field is ignored) tolerates the taint. By default, it + is not set, which means tolerate the taint forever (do not + evict). Zero and negative values will be treated as 0 (evict + immediately) by the system. + format: int64 + type: integer + value: + description: Value is the taint value the toleration matches + to. If the operator is Exists, the value should be empty, + otherwise just a regular string. + type: string + type: object + type: array + required: + - apiserver + - cleaner + - imagePullPolicy + - monitoring + - operator + - replicaCount + - serviceAccount + type: object + type: object + served: true + storage: true diff --git a/api/crds/lib.go b/api/crds/lib.go index dc6a0122..34126347 100644 --- a/api/crds/lib.go +++ b/api/crds/lib.go @@ -19,21 +19,39 @@ package crds import ( "fmt" - apiextensions "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1" "k8s.io/apimachinery/pkg/runtime/schema" + "kmodules.xyz/client-go/apiextensions" "sigs.k8s.io/yaml" ) +func load(filename string, o interface{}) error { + if _, ok := _bindata[filename]; ok { + data, err := Asset(filename) + if err != nil { + return err + } + return yaml.Unmarshal(data, o) + } + return nil +} + func CustomResourceDefinition(gvr schema.GroupVersionResource) (*apiextensions.CustomResourceDefinition, error) { - data, err := Asset(fmt.Sprintf("%s_%s.yaml", gvr.Group, gvr.Resource)) - if err != nil { + var out apiextensions.CustomResourceDefinition + + v1file := fmt.Sprintf("%s_%s.v1.yaml", gvr.Group, gvr.Resource) + if err := load(v1file, &out.V1); err != nil { return nil, err } - var out apiextensions.CustomResourceDefinition - err = yaml.Unmarshal(data, &out) - if err != nil { + + v1beta1file := fmt.Sprintf("%s_%s.yaml", gvr.Group, gvr.Resource) + if err := load(v1beta1file, &out.V1beta1); err != nil { return nil, err } + + if out.V1 == nil && out.V1beta1 == nil { + return nil, fmt.Errorf("missing crd yamls for gvr: %s", gvr) + } + return &out, nil } diff --git a/apis/installer/install/pruning_test.go b/apis/installer/install/pruning_test.go index a317fcd1..fea0a8b4 100644 --- a/apis/installer/install/pruning_test.go +++ b/apis/installer/install/pruning_test.go @@ -28,5 +28,14 @@ import ( func TestPruneTypes(t *testing.T) { Install(clientsetscheme.Scheme) - crdfuzz.SchemaFuzzTestForV1beta1CRD(t, clientsetscheme.Scheme, v1alpha1.KubepackOperator{}.CustomResourceDefinition(), fuzzer.Funcs) + + // CRD v1 + if crd := (v1alpha1.KubepackOperator{}).CustomResourceDefinition(); crd.V1 != nil { + crdfuzz.SchemaFuzzTestForV1CRD(t, clientsetscheme.Scheme, crd.V1, fuzzer.Funcs) + } + + // CRD v1beta1 + if crd := (v1alpha1.KubepackOperator{}).CustomResourceDefinition(); crd.V1beta1 != nil { + crdfuzz.SchemaFuzzTestForV1beta1CRD(t, clientsetscheme.Scheme, crd.V1beta1, fuzzer.Funcs) + } } diff --git a/apis/installer/v1alpha1/kubepack_operator_helpers.go b/apis/installer/v1alpha1/kubepack_operator_helpers.go index 2330b7bb..2353848e 100644 --- a/apis/installer/v1alpha1/kubepack_operator_helpers.go +++ b/apis/installer/v1alpha1/kubepack_operator_helpers.go @@ -19,7 +19,7 @@ package v1alpha1 import ( "kubepack.dev/installer/api/crds" - apiextensions "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1" + "kmodules.xyz/client-go/apiextensions" ) func (_ KubepackOperator) CustomResourceDefinition() *apiextensions.CustomResourceDefinition { diff --git a/go.mod b/go.mod index f7f31eb8..63d81d9c 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,9 @@ module kubepack.dev/installer go 1.12 require ( + cloud.google.com/go v0.49.0 // indirect + github.com/Azure/go-autorest/autorest v0.9.3-0.20191028180845-3492b2aff503 // indirect + github.com/Azure/go-autorest/autorest/adal v0.8.1-0.20191028180845-3492b2aff503 // indirect github.com/NYTimes/gziphandler v1.1.1 // indirect github.com/appscode/go v0.0.0-20200323182826-54e98e09185a github.com/blang/semver v3.5.1+incompatible // indirect @@ -12,6 +15,7 @@ require ( github.com/golang/groupcache v0.0.0-20191027212112-611e8accdfc9 // indirect github.com/google/gofuzz v1.1.0 github.com/googleapis/gnostic v0.3.1 // indirect + github.com/gophercloud/gophercloud v0.6.0 // indirect github.com/grpc-ecosystem/go-grpc-middleware v1.1.0 // indirect github.com/grpc-ecosystem/grpc-gateway v1.12.1 // indirect github.com/hashicorp/golang-lru v0.5.3 // indirect @@ -27,21 +31,19 @@ require ( golang.org/x/time v0.0.0-20191024005414-555d28b269f0 // indirect golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f // indirect google.golang.org/appengine v1.6.5 // indirect - google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9 // indirect gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect k8s.io/api v0.18.3 - k8s.io/apiextensions-apiserver v0.18.3 k8s.io/apimachinery v0.18.3 - k8s.io/client-go v0.18.3 + k8s.io/client-go v12.0.0+incompatible k8s.io/kube-openapi v0.0.0-20200410145947-61e04a5be9a6 - kmodules.xyz/client-go v0.0.0-20200522120609-c6430d66212f + kmodules.xyz/client-go v0.0.0-20200525112657-3b8ebfcb5e19 kmodules.xyz/crd-schema-fuzz v0.0.0-20200521005638-2433a187de95 sigs.k8s.io/yaml v1.2.0 ) replace ( bitbucket.org/ww/goautoneg => gomodules.xyz/goautoneg v0.0.0-20120707110453-a547fc61f48d - git.apache.org/thrift.git => github.com/apache/thrift v0.12.0 + git.apache.org/thrift.git => github.com/apache/thrift v0.13.0 github.com/Azure/azure-sdk-for-go => github.com/Azure/azure-sdk-for-go v35.0.0+incompatible github.com/Azure/go-ansiterm => github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 github.com/Azure/go-autorest => github.com/Azure/go-autorest v13.0.0+incompatible @@ -57,6 +59,7 @@ replace ( github.com/prometheus/client_golang => github.com/prometheus/client_golang v1.0.0 go.etcd.io/etcd => go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738 google.golang.org/grpc => google.golang.org/grpc v1.26.0 + k8s.io/api => github.com/kmodules/api v0.18.4-0.20200524125823-c8bc107809b9 k8s.io/apimachinery => github.com/kmodules/apimachinery v0.19.0-alpha.0.0.20200520235721-10b58e57a423 k8s.io/apiserver => github.com/kmodules/apiserver v0.18.4-0.20200521000930-14c5f6df9625 k8s.io/client-go => k8s.io/client-go v0.18.3 diff --git a/go.sum b/go.sum index 2bb47a93..8da7ba9a 100644 --- a/go.sum +++ b/go.sum @@ -1,14 +1,32 @@ cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= +cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= +cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= +cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= +cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= +cloud.google.com/go v0.49.0 h1:CH+lkubJzcPYB1Ggupcq0+k8Ni2ILdG2lYjDIgavDBQ= +cloud.google.com/go v0.49.0/go.mod h1:hGvAdzcWNbyuxS3nWhD7H2cIJxjRRTRLQVB0bdputVY= +cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= +cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= +cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= +cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= +dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8= +github.com/Azure/go-autorest/autorest v0.9.0 h1:MRvx8gncNaXJqOoLmhNjUAKh33JJF8LyxPhomEtOsjs= github.com/Azure/go-autorest/autorest v0.9.0/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI= +github.com/Azure/go-autorest/autorest/adal v0.5.0 h1:q2gDruN08/guU9vAjuPWff0+QIrpH6ediguzdAzXAUU= github.com/Azure/go-autorest/autorest/adal v0.5.0/go.mod h1:8Z9fGy2MpX0PvDjB1pEgQTmVqjGhiHBW7RJJEciWzS0= +github.com/Azure/go-autorest/autorest/date v0.1.0 h1:YGrhWfrgtFs84+h0o46rJrlmsZtyZRg470CqAXTZaGM= github.com/Azure/go-autorest/autorest/date v0.1.0/go.mod h1:plvfp3oPSKwf2DNjlBjWF/7vwR+cUD/ELuzDCXwHUVA= +github.com/Azure/go-autorest/autorest/mocks v0.2.0 h1:Ww5g4zThfD/6cLb4z6xxgeyDa7QDkizMkJKe0ysZXp0= github.com/Azure/go-autorest/autorest/mocks v0.2.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0= +github.com/Azure/go-autorest/logger v0.1.0 h1:ruG4BSDXONFRrZZJ2GUXDiUyVpayPmb1GnWeHDdaNKY= github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6LSNgds39diKLz7Vrc= +github.com/Azure/go-autorest/tracing v0.5.0 h1:TRn4WjSnkcSy5AEG3pnbtFSwNtwzjr4VYyQflFE619k= github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk= github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= github.com/NYTimes/gziphandler v1.1.1 h1:ZUDjpQae29j0ryrS0u/B8HZfJBtBQHjqw2rQ2cqUQ3I= github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c= @@ -82,6 +100,7 @@ github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLi github.com/evanphx/json-patch v4.5.0+incompatible h1:ouOWdg56aJriqS0huScTkVXPC5IcNrDCXZ6OoTAWu7M= github.com/evanphx/json-patch v4.5.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= +github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo= github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= @@ -89,6 +108,7 @@ github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2H github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/globalsign/mgo v0.0.0-20180905125535-1ca0a4f7cbcb/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q= github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q= +github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= @@ -153,6 +173,7 @@ github.com/golang/groupcache v0.0.0-20191027212112-611e8accdfc9 h1:uHTyIjqVhYRhL github.com/golang/groupcache v0.0.0-20191027212112-611e8accdfc9/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= github.com/golang/protobuf v0.0.0-20161109072736-4bd1920723d7/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -171,15 +192,20 @@ github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g= github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= +github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= github.com/googleapis/gnostic v0.1.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= github.com/googleapis/gnostic v0.3.1 h1:WeAefnSUHlBb0iJKwxFDZdbfGwkd7xRNuV+IpXMJhYk= github.com/googleapis/gnostic v0.3.1/go.mod h1:on+2t9HRStVgn95RSsFWFz+6Q0Snyqv1awfrALZdbtU= github.com/gophercloud/gophercloud v0.1.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8= +github.com/gophercloud/gophercloud v0.6.0 h1:Xb2lcqZtml1XjgYZxbeayEemq7ASbeTp09m36gQFpEU= +github.com/gophercloud/gophercloud v0.6.0/go.mod h1:GICNByuaEBibcjmjvI7QvYJSZEbGkcYwAR7EZK2WMqM= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH/Q= @@ -219,6 +245,8 @@ github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/kmodules/api v0.18.4-0.20200524125823-c8bc107809b9 h1:3WfoOV3g8udvdh1SgCjp93waE4njc5p8Yu6iPdcTPeY= +github.com/kmodules/api v0.18.4-0.20200524125823-c8bc107809b9/go.mod h1:UOaMwERbqJMfeeeHc8XJKawj4P9TgDRnViIqqBeH2QA= github.com/kmodules/apimachinery v0.19.0-alpha.0.0.20200520235721-10b58e57a423 h1:eIx5nBpcokltYCsMIguagM4k2yi04irNqAFVPw4IdjE= github.com/kmodules/apimachinery v0.19.0-alpha.0.0.20200520235721-10b58e57a423/go.mod h1:OaXp26zu/5J7p0f92ASynJa1pZo06YlV9fG7BoWbCko= github.com/kmodules/apiserver v0.18.4-0.20200521000930-14c5f6df9625 h1:VgTz5R1ePhWVoGGBWsFv0+MkLvXwg6XwvaPMlG7QFKo= @@ -252,6 +280,7 @@ github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzp github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= @@ -300,6 +329,7 @@ github.com/prometheus/procfs v0.0.6 h1:0qbH+Yqu/cj1ViVLvEWCP6qMQ4efWUj6bQqOEA0V0 github.com/prometheus/procfs v0.0.6/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= +github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= @@ -353,6 +383,7 @@ go.mongodb.org/mongo-driver v1.0.3/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qL go.mongodb.org/mongo-driver v1.1.1/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= go.mongodb.org/mongo-driver v1.1.2/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= +go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.5.0 h1:OI5t8sDa1Or+q8AeE+yKeB/SDYioSHAgcVljj9JIETY= @@ -367,15 +398,29 @@ golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnf golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190320223903-b7391e95e576/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190422183909-d864b10871cd/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190617133340-57b3e21c3d56/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975 h1:/Tl7pH94bvbAAHBdZJT947M/+gp0+CqQXDtMRC0fseo= golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= +golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= +golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= +golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= +golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190930215403-16217165b5de h1:5hukYrvBGR8/eNkX5mdUezrA6JiaEZDtJb9Ei+1LlBs= golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= +golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= +golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= +golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -387,6 +432,8 @@ golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190320064053-1272bf9dcd53/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -416,10 +463,15 @@ golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20190209173611-3b5209105503/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190321052220-f7bb7a8bee54/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191022100944-742c48ecaeb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -442,26 +494,47 @@ golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGm golang.org/x/tools v0.0.0-20190125232054-d66bd3c5d5a6/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190617190820-da514acc4774/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190920225731-5eefd052ad72/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f h1:kDxGY2VmgABOe55qheT/TFqUMtcTHnomIPS1iv3G4Ms= golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +gomodules.xyz/jsonpatch/v2 v2.1.0 h1:Phva6wqu+xR//Njw6iorylFFgn/z547tw5Ne3HZPQ+k= gomodules.xyz/jsonpatch/v2 v2.1.0/go.mod h1:IhYNNY4jnS53ZnfE4PAmpKtDpTCj1JFXc+3mwe7XcUU= +gomodules.xyz/version v0.1.0 h1:inGItCg/egI0jPMeIE0SQkiDIJaodOMoCrxYqasQLR0= gomodules.xyz/version v0.1.0/go.mod h1:Y8xuV02mL/45psyPKG3NCVOwvAOy6T5Kx0l3rCjKSjU= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= +google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= +google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/appengine v1.6.5 h1:tycE03LOZYQNhDpS27tcQdAzLCVMaj7QT2SXxebnpCM= google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= google.golang.org/genproto v0.0.0-20190927181202-20e1ac93f88c/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9 h1:6XzpBoANz1NqMNfDXzc2QmHmbb1vyMsvRfoP5rM+K1I= google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= @@ -473,6 +546,7 @@ gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= @@ -493,8 +567,8 @@ gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -k8s.io/api v0.18.3 h1:2AJaUQdgUZLoDZHrun21PW2Nx9+ll6cUzvn3IKhSIn0= -k8s.io/api v0.18.3/go.mod h1:UOaMwERbqJMfeeeHc8XJKawj4P9TgDRnViIqqBeH2QA= +honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= k8s.io/apiextensions-apiserver v0.18.3 h1:h6oZO+iAgg0HjxmuNnguNdKNB9+wv3O1EBDdDWJViQ0= k8s.io/apiextensions-apiserver v0.18.3/go.mod h1:TMsNGs7DYpMXd+8MOCX8KzPOCx8fnZMoIGB24m03+JE= k8s.io/cli-runtime v0.18.3/go.mod h1:pqbbi4nqRIQhUWAVzen8uE8DD/zcZLwf+8sQYO4lwLk= @@ -514,10 +588,11 @@ k8s.io/kube-openapi v0.0.0-20200410145947-61e04a5be9a6 h1:Oh3Mzx5pJ+yIumsAD0MOEC k8s.io/kube-openapi v0.0.0-20200410145947-61e04a5be9a6/go.mod h1:GRQhZsXIAJ1xR0C9bd8UpWHZ5plfAS9fzPjJuQ6JL3E= k8s.io/utils v0.0.0-20200324210504-a9aa75ae1b89 h1:d4vVOjXm687F1iLSP2q3lyPPuyvTUt3aVoBpi2DqRsU= k8s.io/utils v0.0.0-20200324210504-a9aa75ae1b89/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= -kmodules.xyz/client-go v0.0.0-20200522120609-c6430d66212f h1:8UjB4zeASqedORHWpGoeDhRT7C564GZuY2rPsMmqvko= -kmodules.xyz/client-go v0.0.0-20200522120609-c6430d66212f/go.mod h1:sY/eoe4ktxZEoHpr5NpAQ5s22VSwTE8psJtKVeVgLRY= +kmodules.xyz/client-go v0.0.0-20200525112657-3b8ebfcb5e19 h1:hgFcY57/qeqdxvBGbjaNSlHXIox4XHmTcYGdJqm+BIw= +kmodules.xyz/client-go v0.0.0-20200525112657-3b8ebfcb5e19/go.mod h1:sY/eoe4ktxZEoHpr5NpAQ5s22VSwTE8psJtKVeVgLRY= kmodules.xyz/crd-schema-fuzz v0.0.0-20200521005638-2433a187de95 h1:v0S/+ftzL6Xrs9XevgchAOJyPKlRQXPiZf87xotj3X4= kmodules.xyz/crd-schema-fuzz v0.0.0-20200521005638-2433a187de95/go.mod h1:jpu8xFsDKd6kAWUAKk8oTu/GQGBWqhrcaDeOJdaCJnk= +rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.7 h1:uuHDyjllyzRyCIvvn0OBjiRB0SgBZGqHNYAmjR7fO50= sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.7/go.mod h1:PHgbrJT7lCHcxMU+mDHEm+nx46H4zuuHZkDP6icnhu0= sigs.k8s.io/kustomize v2.0.3+incompatible/go.mod h1:MkjgH3RdOWrievjo6c9T245dYlB5QeXV4WCbnt/PEpU= diff --git a/vendor/github.com/appscode/go/encoding/json/types/array_or_int.go b/vendor/github.com/appscode/go/encoding/json/types/array_or_int.go new file mode 100644 index 00000000..9494ff1d --- /dev/null +++ b/vendor/github.com/appscode/go/encoding/json/types/array_or_int.go @@ -0,0 +1,55 @@ +package types + +import ( + "bytes" + "encoding/json" + "errors" + "strconv" +) + +/* + GO => Json + [] => `[]` + [1] => `1` +[1, 2] => `[1,2]` +*/ +type ArrayOrInt []int + +func (m *ArrayOrInt) MarshalJSON() ([]byte, error) { + a := *m + n := len(a) + var buf bytes.Buffer + if n == 1 { + buf.WriteString(strconv.Itoa(a[0])) + } else { + buf.WriteString(`[`) + + for i := 0; i < n; i++ { + if i > 0 { + buf.WriteString(`,`) + } + buf.WriteString(strconv.Itoa(a[i])) + } + + buf.WriteString(`]`) + } + return buf.Bytes(), nil +} + +func (m *ArrayOrInt) UnmarshalJSON(data []byte) error { + if m == nil { + return errors.New("jsontypes.ArrayOrInt: UnmarshalJSON on nil pointer") + } + var err error + if data[0] == '[' { + var a []int + err = json.Unmarshal(data, &a) + if err == nil { + *m = a + } + } else { + v, _ := strconv.Atoi(string(data)) + *m = append((*m)[0:0], v) + } + return err +} diff --git a/vendor/github.com/appscode/go/encoding/json/types/array_or_string.go b/vendor/github.com/appscode/go/encoding/json/types/array_or_string.go new file mode 100644 index 00000000..10015f14 --- /dev/null +++ b/vendor/github.com/appscode/go/encoding/json/types/array_or_string.go @@ -0,0 +1,57 @@ +package types + +import ( + "bytes" + "encoding/json" + "errors" +) + +/* + GO => Json + [] => `[]` + ["a"] => `"a"` +["a", "b"] => `["a","b"]` +*/ +type ArrayOrString []string + +func (m *ArrayOrString) MarshalJSON() ([]byte, error) { + a := *m + n := len(a) + var buf bytes.Buffer + if n == 1 { + buf.WriteString(`"`) + buf.WriteString(a[0]) + buf.WriteString(`"`) + } else { + buf.WriteString(`[`) + + for i := 0; i < n; i++ { + if i > 0 { + buf.WriteString(`,`) + } + buf.WriteString(`"`) + buf.WriteString(a[i]) + buf.WriteString(`"`) + } + + buf.WriteString(`]`) + } + return buf.Bytes(), nil +} + +func (m *ArrayOrString) UnmarshalJSON(data []byte) error { + if m == nil { + return errors.New("jsontypes.ArrayOrString: UnmarshalJSON on nil pointer") + } + var err error + if data[0] == '[' { + var a []string + err = json.Unmarshal(data, &a) + if err == nil { + *m = a + } + } else { + *m = append((*m)[0:0], string(data[1:len(data)-1])) + } + return err +} diff --git a/vendor/github.com/appscode/go/encoding/json/types/bool_yo.go b/vendor/github.com/appscode/go/encoding/json/types/bool_yo.go new file mode 100644 index 00000000..ea839543 --- /dev/null +++ b/vendor/github.com/appscode/go/encoding/json/types/bool_yo.go @@ -0,0 +1,33 @@ +package types + +import ( + "errors" + "strconv" +) + +type BoolYo bool + +func (m *BoolYo) MarshalJSON() ([]byte, error) { + a := *m + if a { + return []byte(`"true"`), nil + } + return []byte(`"false"`), nil +} + +func (m *BoolYo) UnmarshalJSON(data []byte) error { + if m == nil { + return errors.New("jsontypes.BoolYo: UnmarshalJSON on nil pointer") + } + + n := len(data) + var in string + if data[0] == '"' && data[n-1] == '"' { + in = string(data[1 : n-1]) + } else { + in = string(data) + } + v, err := strconv.ParseBool(in) + *m = BoolYo(v) + return err +} diff --git a/vendor/github.com/appscode/go/encoding/json/types/doc.go b/vendor/github.com/appscode/go/encoding/json/types/doc.go new file mode 100644 index 00000000..d3ca266e --- /dev/null +++ b/vendor/github.com/appscode/go/encoding/json/types/doc.go @@ -0,0 +1,2 @@ +// Package types provides a collection of Golang types with JSON marshaling support +package types diff --git a/vendor/github.com/appscode/go/encoding/json/types/int_hash.go b/vendor/github.com/appscode/go/encoding/json/types/int_hash.go new file mode 100644 index 00000000..7ad701cb --- /dev/null +++ b/vendor/github.com/appscode/go/encoding/json/types/int_hash.go @@ -0,0 +1,193 @@ +package types + +import ( + "bytes" + "encoding/json" + "errors" + "fmt" + "reflect" + "strconv" + "strings" + + "github.com/appscode/go/types" +) + +/* +IntHash represents as int64 Generation and string Hash. It is json serialized into $. +*/ +// +k8s:openapi-gen=true +type IntHash struct { + generation int64 + hash string +} + +func ParseIntHash(v interface{}) (*IntHash, error) { + switch m := v.(type) { + case nil: + return &IntHash{}, nil + case int: + return &IntHash{generation: int64(m)}, nil + case int64: + return &IntHash{generation: m}, nil + case *int64: + return &IntHash{generation: types.Int64(m)}, nil + case IntHash: + return &m, nil + case *IntHash: + return m, nil + case string: + return parseStringIntoIntHash(m) + case *string: + return parseStringIntoIntHash(types.String(m)) + default: + return nil, fmt.Errorf("failed to parse type %s into IntHash", reflect.TypeOf(v).String()) + } +} + +func parseStringIntoIntHash(s string) (*IntHash, error) { + if s == "" { + return &IntHash{}, nil + } + + idx := strings.IndexRune(s, '$') + switch { + case idx <= 0: + return nil, errors.New("missing generation") + case idx == len(s)-1: + return nil, errors.New("missing hash") + default: + i, err := strconv.ParseInt(s[:idx], 10, 64) + if err != nil { + return nil, err + } + h := s[idx+1:] + return &IntHash{generation: i, hash: h}, nil + } +} + +func NewIntHash(i int64, h string) *IntHash { return &IntHash{generation: i, hash: h} } + +func IntHashForGeneration(i int64) *IntHash { return &IntHash{generation: i} } + +func IntHashForHash(h string) *IntHash { return &IntHash{hash: h} } + +func (m IntHash) Generation() int64 { + return m.generation +} + +func (m IntHash) Hash() string { + return m.hash +} + +// IsZero returns true if the value is nil or time is zero. +func (m *IntHash) IsZero() bool { + if m == nil { + return true + } + return m.generation == 0 && m.hash == "" +} + +func (m *IntHash) Equal(u *IntHash) bool { + if m == nil { + return u == nil + } + if u == nil { // t != nil + return false + } + if m == u { + return true + } + if m.generation == u.generation { + return m.hash == u.hash + } + return false +} + +func (m *IntHash) MatchGeneration(u *IntHash) bool { + if m == nil { + return u == nil + } + if u == nil { // t != nil + return false + } + if m == u { + return true + } + return m.generation == u.generation +} + +func (m *IntHash) DeepCopyInto(out *IntHash) { + *out = *m +} + +func (m *IntHash) DeepCopy() *IntHash { + if m == nil { + return nil + } + out := new(IntHash) + m.DeepCopyInto(out) + return out +} + +func (m IntHash) String() string { + return fmt.Sprintf(`%d$%s`, m.generation, m.hash) +} + +func (m *IntHash) MarshalJSON() ([]byte, error) { + if m == nil { + return nil, nil + } + if m.hash == "" { + return json.Marshal(m.generation) + } + return json.Marshal(m.String()) +} + +func (m *IntHash) UnmarshalJSON(data []byte) error { + if m == nil { + return errors.New("jsontypes.IntHash: UnmarshalJSON on nil pointer") + } + + if data[0] == '"' { + var s string + err := json.Unmarshal(data, &s) + if err != nil { + return err + } + ih, err := ParseIntHash(s) + if err != nil { + return err + } + *m = *ih + return nil + } else if bytes.Equal(data, []byte("null")) { + return nil + } + + var i int64 + err := json.Unmarshal(data, &i) + if err != nil { + return err + } + m.generation = i + return nil +} + +// OpenAPISchemaType is used by the kube-openapi generator when constructing +// the OpenAPI spec of this type. +// +// See: https://github.com/kubernetes/kube-openapi/tree/master/pkg/generators +func (_ IntHash) OpenAPISchemaType() []string { return []string{"string"} } + +// OpenAPISchemaFormat is used by the kube-openapi generator when constructing +// the OpenAPI spec of this type. +func (_ IntHash) OpenAPISchemaFormat() string { return "" } + +// MarshalQueryParameter converts to a URL query parameter value +func (m IntHash) MarshalQueryParameter() (string, error) { + if m.IsZero() { + // Encode unset/nil objects as an empty string + return "", nil + } + return m.String(), nil +} diff --git a/vendor/github.com/appscode/go/encoding/json/types/str_to_bool.go b/vendor/github.com/appscode/go/encoding/json/types/str_to_bool.go new file mode 100644 index 00000000..b8fcc716 --- /dev/null +++ b/vendor/github.com/appscode/go/encoding/json/types/str_to_bool.go @@ -0,0 +1,44 @@ +package types + +import ( + "errors" +) + +/* +StrToBool turns strings into bool when marshaled to Json. Empty strings are converted to false. Non-empty string, eg, +`"false"` will become True bool value. If already a json bool, then no change is made. + +This can be used to turn a string to bool if you have existing Json data. +*/ +type StrToBool bool + +func (m *StrToBool) MarshalJSON() ([]byte, error) { + a := *m + if a { + return []byte("true"), nil + } + return []byte("false"), nil +} + +func (m *StrToBool) UnmarshalJSON(data []byte) error { + if m == nil { + return errors.New("jsontypes.StrToBool: UnmarshalJSON on nil pointer") + } + var err error + if data[0] == '"' { + // non empty string == true + *m = (len(data) - 2) > 0 + } else { + switch string(data) { + case "true": + *m = true + err = nil + case "false": + *m = false + err = nil + default: + err = errors.New("jsontypes.StrToBool: UnmarshalJSON failed for " + string(data)) + } + } + return err +} diff --git a/vendor/github.com/appscode/go/encoding/json/types/str_yo.go b/vendor/github.com/appscode/go/encoding/json/types/str_yo.go new file mode 100644 index 00000000..1dd083f1 --- /dev/null +++ b/vendor/github.com/appscode/go/encoding/json/types/str_yo.go @@ -0,0 +1,43 @@ +package types + +import ( + "bytes" + "encoding/json" + "errors" + "unicode/utf8" +) + +/* +StrYo turns non-strings into into a string by adding quotes around it into bool, +when marshaled to Json. If input is already string, no change is done. +*/ +type StrYo string + +func (m *StrYo) UnmarshalJSON(data []byte) error { + if m == nil { + return errors.New("jsontypes.StrYo: UnmarshalJSON on nil pointer") + } + + if data[0] == '"' { + var s string + err := json.Unmarshal(data, &s) + if err != nil { + return err + } + *m = StrYo(s) + return nil + } else if data[0] == '{' { + return errors.New("jsontypes.StrYo: Expected string, found object") + } else if data[0] == '[' { + return errors.New("jsontypes.StrYo: Expected string, found array") + } else if bytes.Equal(data, []byte("null")) { + *m = "" + return nil + } + d := string(data) + if utf8.ValidString(d) { + *m = StrYo(d) + return nil + } + return errors.New("jsontypes.StrYo: Found invalid utf8 byte array") +} diff --git a/vendor/github.com/appscode/go/encoding/json/types/urlamp.go b/vendor/github.com/appscode/go/encoding/json/types/urlamp.go new file mode 100644 index 00000000..49cf04d8 --- /dev/null +++ b/vendor/github.com/appscode/go/encoding/json/types/urlamp.go @@ -0,0 +1,105 @@ +package types + +import ( + "bytes" + "errors" + "fmt" + "net/url" + "reflect" + "sort" + "strconv" + "strings" +) + +type URLMap struct { + Scheme string + Hosts map[string]string + Port int +} + +func NewURLMap(scheme string, port int) *URLMap { + return &URLMap{ + Scheme: scheme, + Hosts: map[string]string{}, + Port: port, + } +} + +func (um *URLMap) Insert(name, host string) { + um.Hosts[name] = host +} + +func (um *URLMap) Delete(hosts ...string) { + for _, host := range hosts { + delete(um.Hosts, host) + } +} + +func (um *URLMap) Has(host string) bool { + _, contained := um.Hosts[host] + return contained +} + +func (um URLMap) Equal(s2 URLMap) bool { + return um.Scheme == s2.Scheme && + um.Port == s2.Port && + reflect.DeepEqual(um.Hosts, s2.Hosts) +} + +func (um *URLMap) MarshalJSON() ([]byte, error) { + var b bytes.Buffer + b.WriteRune('"') + if um != nil { + names := make([]string, 0, len(um.Hosts)) + for name := range um.Hosts { + names = append(names, name) + } + sort.Strings(names) + + for i, name := range names { + if i > 0 { + b.WriteRune(',') + } + b.WriteString(name) + b.WriteRune('=') + b.WriteString(um.Scheme) + b.WriteString("://") + b.WriteString(um.Hosts[name]) + b.WriteString(":") + b.WriteString(strconv.Itoa(um.Port)) + } + } + b.WriteRune('"') + return []byte(b.String()), nil +} + +func (um *URLMap) UnmarshalJSON(data []byte) error { + if um == nil { + return errors.New("jsontypes.URLMap: UnmarshalJSON on nil pointer") + } + + n := len(data) + if n < 2 { + return fmt.Errorf("jsontypes.URLMap: UnmarshalJSON on invalid data %s", string(data)) + } + if n == 2 && string(data) == `""` { + return nil + } + um.Hosts = map[string]string{} + + entries := strings.Split(string(data[1:n-1]), ",") + for _, entry := range entries { + parts := strings.Split(entry, "=") + if u, err := url.Parse(parts[1]); err == nil { + um.Scheme = u.Scheme + um.Hosts[parts[0]] = u.Hostname() + um.Port, err = strconv.Atoi(u.Port()) + if err != nil { + return err + } + } else { + return err + } + } + return nil +} diff --git a/vendor/github.com/appscode/go/encoding/json/types/urlset.go b/vendor/github.com/appscode/go/encoding/json/types/urlset.go new file mode 100644 index 00000000..eacaa896 --- /dev/null +++ b/vendor/github.com/appscode/go/encoding/json/types/urlset.go @@ -0,0 +1,97 @@ +package types + +import ( + "errors" + "fmt" + "net/url" + "sort" + "strconv" + "strings" + + "bytes" + + "github.com/appscode/go/sets" +) + +type URLSet struct { + Scheme string + Hosts sets.String + Port int +} + +func NewURLSet(scheme string, port int) *URLSet { + return &URLSet{ + Scheme: scheme, + Hosts: sets.NewString(), + Port: port, + } +} + +func (us *URLSet) Insert(hosts ...string) { + us.Hosts.Insert(hosts...) +} + +func (us *URLSet) Delete(hosts ...string) { + us.Hosts.Delete(hosts...) +} + +func (us *URLSet) Has(host string) bool { + return us.Hosts.Has(host) +} + +func (s1 URLSet) Equal(s2 URLSet) bool { + return s1.Scheme == s2.Scheme && + s1.Port == s2.Port && + s1.Hosts.Equal(s2.Hosts) +} + +func (us *URLSet) MarshalJSON() ([]byte, error) { + var b bytes.Buffer + b.WriteRune('"') + if us != nil { + urls := us.Hosts.List() + sort.Strings(urls) + for i, h := range urls { + if i > 0 { + b.WriteRune(',') + } + b.WriteString(us.Scheme) + b.WriteString("://") + b.WriteString(h) + b.WriteString(":") + b.WriteString(strconv.Itoa(us.Port)) + } + } + b.WriteRune('"') + return []byte(b.String()), nil +} + +func (us *URLSet) UnmarshalJSON(data []byte) error { + if us == nil { + return errors.New("jsontypes.URLSet: UnmarshalJSON on nil pointer") + } + + n := len(data) + if n < 2 { + return fmt.Errorf("jsontypes.URLSet: UnmarshalJSON on invalid data %s", string(data)) + } + if n == 2 && string(data) == `""` { + return nil + } + us.Hosts = sets.NewString() + + urls := strings.Split(string(data[1:n-1]), ",") + for _, rawurl := range urls { + if u, err := url.Parse(rawurl); err == nil { + us.Scheme = u.Scheme + us.Hosts.Insert(u.Hostname()) + us.Port, err = strconv.Atoi(u.Port()) + if err != nil { + return err + } + } else { + return err + } + } + return nil +} diff --git a/vendor/github.com/appscode/go/sets/BUILD b/vendor/github.com/appscode/go/sets/BUILD new file mode 100644 index 00000000..5a6175ad --- /dev/null +++ b/vendor/github.com/appscode/go/sets/BUILD @@ -0,0 +1,72 @@ +package(default_visibility = ["//visibility:public"]) + +load("@io_kubernetes_build//defs:go.bzl", "go_genrule") +load( + "@io_bazel_rules_go//go:def.bzl", + "go_library", + "go_test", +) + +go_library( + name = "go_default_library", + srcs = [ + "byte.go", + "doc.go", + "empty.go", + "int.go", + "int64.go", + "string.go", + ], + importpath = "k8s.io/apimachinery/pkg/util/sets", +) + +go_genrule( + name = "set-gen", + srcs = [ + "//hack/boilerplate:boilerplate.go.txt", + ], + outs = [ + "byte.go", + "doc.go", + "empty.go", + "int.go", + "int64.go", + "string.go", + ], + cmd = """ +$(location //vendor/k8s.io/code-generator/cmd/set-gen) \ + --input-dirs ./vendor/k8s.io/apimachinery/pkg/util/sets/types \ + --output-base $$(dirname $$(dirname $(location :byte.go))) \ + --go-header-file $(location //hack/boilerplate:boilerplate.go.txt) \ + --output-package sets + """, + go_deps = [ + "//vendor/k8s.io/apimachinery/pkg/util/sets/types:go_default_library", + ], + tools = [ + "//vendor/k8s.io/code-generator/cmd/set-gen", + ], +) + +go_test( + name = "go_default_test", + srcs = ["set_test.go"], + importpath = "k8s.io/apimachinery/pkg/util/sets", + library = ":go_default_library", +) + +filegroup( + name = "package-srcs", + srcs = glob(["**"]), + tags = ["automanaged"], + visibility = ["//visibility:private"], +) + +filegroup( + name = "all-srcs", + srcs = [ + ":package-srcs", + "//staging/src/k8s.io/apimachinery/pkg/util/sets/types:all-srcs", + ], + tags = ["automanaged"], +) diff --git a/vendor/github.com/appscode/go/sets/README.md b/vendor/github.com/appscode/go/sets/README.md new file mode 100644 index 00000000..288edde4 --- /dev/null +++ b/vendor/github.com/appscode/go/sets/README.md @@ -0,0 +1 @@ +Forked from https://github.com/kubernetes/apimachinery/blob/20bbfef868144faf29af69ddb2f01646ead5c1a1/pkg/util/sets/byte.go#L19 diff --git a/vendor/github.com/appscode/go/sets/byte.go b/vendor/github.com/appscode/go/sets/byte.go new file mode 100644 index 00000000..a460e4b1 --- /dev/null +++ b/vendor/github.com/appscode/go/sets/byte.go @@ -0,0 +1,203 @@ +/* +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. +*/ + +// This file was autogenerated by set-gen. Do not edit it manually! + +package sets + +import ( + "reflect" + "sort" +) + +// sets.Byte is a set of bytes, implemented via map[byte]struct{} for minimal memory consumption. +type Byte map[byte]Empty + +// New creates a Byte from a list of values. +func NewByte(items ...byte) Byte { + ss := Byte{} + ss.Insert(items...) + return ss +} + +// ByteKeySet creates a Byte from a keys of a map[byte](? extends interface{}). +// If the value passed in is not actually a map, this will panic. +func ByteKeySet(theMap interface{}) Byte { + v := reflect.ValueOf(theMap) + ret := Byte{} + + for _, keyValue := range v.MapKeys() { + ret.Insert(keyValue.Interface().(byte)) + } + return ret +} + +// Insert adds items to the set. +func (s Byte) Insert(items ...byte) { + for _, item := range items { + s[item] = Empty{} + } +} + +// Delete removes all items from the set. +func (s Byte) Delete(items ...byte) { + for _, item := range items { + delete(s, item) + } +} + +// Has returns true if and only if item is contained in the set. +func (s Byte) Has(item byte) bool { + _, contained := s[item] + return contained +} + +// HasAll returns true if and only if all items are contained in the set. +func (s Byte) HasAll(items ...byte) bool { + for _, item := range items { + if !s.Has(item) { + return false + } + } + return true +} + +// HasAny returns true if any items are contained in the set. +func (s Byte) HasAny(items ...byte) bool { + for _, item := range items { + if s.Has(item) { + return true + } + } + return false +} + +// Difference returns a set of objects that are not in s2 +// For example: +// s1 = {a1, a2, a3} +// s2 = {a1, a2, a4, a5} +// s1.Difference(s2) = {a3} +// s2.Difference(s1) = {a4, a5} +func (s Byte) Difference(s2 Byte) Byte { + result := NewByte() + for key := range s { + if !s2.Has(key) { + result.Insert(key) + } + } + return result +} + +// Union returns a new set which includes items in either s1 or s2. +// For example: +// s1 = {a1, a2} +// s2 = {a3, a4} +// s1.Union(s2) = {a1, a2, a3, a4} +// s2.Union(s1) = {a1, a2, a3, a4} +func (s1 Byte) Union(s2 Byte) Byte { + result := NewByte() + for key := range s1 { + result.Insert(key) + } + for key := range s2 { + result.Insert(key) + } + return result +} + +// Intersection returns a new set which includes the item in BOTH s1 and s2 +// For example: +// s1 = {a1, a2} +// s2 = {a2, a3} +// s1.Intersection(s2) = {a2} +func (s1 Byte) Intersection(s2 Byte) Byte { + var walk, other Byte + result := NewByte() + if s1.Len() < s2.Len() { + walk = s1 + other = s2 + } else { + walk = s2 + other = s1 + } + for key := range walk { + if other.Has(key) { + result.Insert(key) + } + } + return result +} + +// IsSuperset returns true if and only if s1 is a superset of s2. +func (s1 Byte) IsSuperset(s2 Byte) bool { + for item := range s2 { + if !s1.Has(item) { + return false + } + } + return true +} + +// Equal returns true if and only if s1 is equal (as a set) to s2. +// Two sets are equal if their membership is identical. +// (In practice, this means same elements, order doesn't matter) +func (s1 Byte) Equal(s2 Byte) bool { + return len(s1) == len(s2) && s1.IsSuperset(s2) +} + +type sortableSliceOfByte []byte + +func (s sortableSliceOfByte) Len() int { return len(s) } +func (s sortableSliceOfByte) Less(i, j int) bool { return lessByte(s[i], s[j]) } +func (s sortableSliceOfByte) Swap(i, j int) { s[i], s[j] = s[j], s[i] } + +// List returns the contents as a sorted byte slice. +func (s Byte) List() []byte { + res := make(sortableSliceOfByte, 0, len(s)) + for key := range s { + res = append(res, key) + } + sort.Sort(res) + return []byte(res) +} + +// UnsortedList returns the slice with contents in random order. +func (s Byte) UnsortedList() []byte { + res := make([]byte, 0, len(s)) + for key := range s { + res = append(res, key) + } + return res +} + +// Returns a single element from the set. +func (s Byte) PopAny() (byte, bool) { + for key := range s { + s.Delete(key) + return key, true + } + var zeroValue byte + return zeroValue, false +} + +// Len returns the size of the set. +func (s Byte) Len() int { + return len(s) +} + +func lessByte(lhs, rhs byte) bool { + return lhs < rhs +} diff --git a/vendor/github.com/appscode/go/sets/doc.go b/vendor/github.com/appscode/go/sets/doc.go new file mode 100644 index 00000000..28a6a7d5 --- /dev/null +++ b/vendor/github.com/appscode/go/sets/doc.go @@ -0,0 +1,20 @@ +/* +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. +*/ + +// This file was autogenerated by set-gen. Do not edit it manually! + +// Package sets has auto-generated set types. +package sets diff --git a/vendor/github.com/appscode/go/sets/empty.go b/vendor/github.com/appscode/go/sets/empty.go new file mode 100644 index 00000000..cd22b953 --- /dev/null +++ b/vendor/github.com/appscode/go/sets/empty.go @@ -0,0 +1,23 @@ +/* +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. +*/ + +// This file was autogenerated by set-gen. Do not edit it manually! + +package sets + +// Empty is public since it is used by some internal API objects for conversions between external +// string arrays and internal sets, and conversion logic requires public types today. +type Empty struct{} diff --git a/vendor/github.com/appscode/go/sets/int.go b/vendor/github.com/appscode/go/sets/int.go new file mode 100644 index 00000000..0614e9fb --- /dev/null +++ b/vendor/github.com/appscode/go/sets/int.go @@ -0,0 +1,203 @@ +/* +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. +*/ + +// This file was autogenerated by set-gen. Do not edit it manually! + +package sets + +import ( + "reflect" + "sort" +) + +// sets.Int is a set of ints, implemented via map[int]struct{} for minimal memory consumption. +type Int map[int]Empty + +// New creates a Int from a list of values. +func NewInt(items ...int) Int { + ss := Int{} + ss.Insert(items...) + return ss +} + +// IntKeySet creates a Int from a keys of a map[int](? extends interface{}). +// If the value passed in is not actually a map, this will panic. +func IntKeySet(theMap interface{}) Int { + v := reflect.ValueOf(theMap) + ret := Int{} + + for _, keyValue := range v.MapKeys() { + ret.Insert(keyValue.Interface().(int)) + } + return ret +} + +// Insert adds items to the set. +func (s Int) Insert(items ...int) { + for _, item := range items { + s[item] = Empty{} + } +} + +// Delete removes all items from the set. +func (s Int) Delete(items ...int) { + for _, item := range items { + delete(s, item) + } +} + +// Has returns true if and only if item is contained in the set. +func (s Int) Has(item int) bool { + _, contained := s[item] + return contained +} + +// HasAll returns true if and only if all items are contained in the set. +func (s Int) HasAll(items ...int) bool { + for _, item := range items { + if !s.Has(item) { + return false + } + } + return true +} + +// HasAny returns true if any items are contained in the set. +func (s Int) HasAny(items ...int) bool { + for _, item := range items { + if s.Has(item) { + return true + } + } + return false +} + +// Difference returns a set of objects that are not in s2 +// For example: +// s1 = {a1, a2, a3} +// s2 = {a1, a2, a4, a5} +// s1.Difference(s2) = {a3} +// s2.Difference(s1) = {a4, a5} +func (s Int) Difference(s2 Int) Int { + result := NewInt() + for key := range s { + if !s2.Has(key) { + result.Insert(key) + } + } + return result +} + +// Union returns a new set which includes items in either s1 or s2. +// For example: +// s1 = {a1, a2} +// s2 = {a3, a4} +// s1.Union(s2) = {a1, a2, a3, a4} +// s2.Union(s1) = {a1, a2, a3, a4} +func (s1 Int) Union(s2 Int) Int { + result := NewInt() + for key := range s1 { + result.Insert(key) + } + for key := range s2 { + result.Insert(key) + } + return result +} + +// Intersection returns a new set which includes the item in BOTH s1 and s2 +// For example: +// s1 = {a1, a2} +// s2 = {a2, a3} +// s1.Intersection(s2) = {a2} +func (s1 Int) Intersection(s2 Int) Int { + var walk, other Int + result := NewInt() + if s1.Len() < s2.Len() { + walk = s1 + other = s2 + } else { + walk = s2 + other = s1 + } + for key := range walk { + if other.Has(key) { + result.Insert(key) + } + } + return result +} + +// IsSuperset returns true if and only if s1 is a superset of s2. +func (s1 Int) IsSuperset(s2 Int) bool { + for item := range s2 { + if !s1.Has(item) { + return false + } + } + return true +} + +// Equal returns true if and only if s1 is equal (as a set) to s2. +// Two sets are equal if their membership is identical. +// (In practice, this means same elements, order doesn't matter) +func (s1 Int) Equal(s2 Int) bool { + return len(s1) == len(s2) && s1.IsSuperset(s2) +} + +type sortableSliceOfInt []int + +func (s sortableSliceOfInt) Len() int { return len(s) } +func (s sortableSliceOfInt) Less(i, j int) bool { return lessInt(s[i], s[j]) } +func (s sortableSliceOfInt) Swap(i, j int) { s[i], s[j] = s[j], s[i] } + +// List returns the contents as a sorted int slice. +func (s Int) List() []int { + res := make(sortableSliceOfInt, 0, len(s)) + for key := range s { + res = append(res, key) + } + sort.Sort(res) + return []int(res) +} + +// UnsortedList returns the slice with contents in random order. +func (s Int) UnsortedList() []int { + res := make([]int, 0, len(s)) + for key := range s { + res = append(res, key) + } + return res +} + +// Returns a single element from the set. +func (s Int) PopAny() (int, bool) { + for key := range s { + s.Delete(key) + return key, true + } + var zeroValue int + return zeroValue, false +} + +// Len returns the size of the set. +func (s Int) Len() int { + return len(s) +} + +func lessInt(lhs, rhs int) bool { + return lhs < rhs +} diff --git a/vendor/github.com/appscode/go/sets/int64.go b/vendor/github.com/appscode/go/sets/int64.go new file mode 100644 index 00000000..82e1ba78 --- /dev/null +++ b/vendor/github.com/appscode/go/sets/int64.go @@ -0,0 +1,203 @@ +/* +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. +*/ + +// This file was autogenerated by set-gen. Do not edit it manually! + +package sets + +import ( + "reflect" + "sort" +) + +// sets.Int64 is a set of int64s, implemented via map[int64]struct{} for minimal memory consumption. +type Int64 map[int64]Empty + +// New creates a Int64 from a list of values. +func NewInt64(items ...int64) Int64 { + ss := Int64{} + ss.Insert(items...) + return ss +} + +// Int64KeySet creates a Int64 from a keys of a map[int64](? extends interface{}). +// If the value passed in is not actually a map, this will panic. +func Int64KeySet(theMap interface{}) Int64 { + v := reflect.ValueOf(theMap) + ret := Int64{} + + for _, keyValue := range v.MapKeys() { + ret.Insert(keyValue.Interface().(int64)) + } + return ret +} + +// Insert adds items to the set. +func (s Int64) Insert(items ...int64) { + for _, item := range items { + s[item] = Empty{} + } +} + +// Delete removes all items from the set. +func (s Int64) Delete(items ...int64) { + for _, item := range items { + delete(s, item) + } +} + +// Has returns true if and only if item is contained in the set. +func (s Int64) Has(item int64) bool { + _, contained := s[item] + return contained +} + +// HasAll returns true if and only if all items are contained in the set. +func (s Int64) HasAll(items ...int64) bool { + for _, item := range items { + if !s.Has(item) { + return false + } + } + return true +} + +// HasAny returns true if any items are contained in the set. +func (s Int64) HasAny(items ...int64) bool { + for _, item := range items { + if s.Has(item) { + return true + } + } + return false +} + +// Difference returns a set of objects that are not in s2 +// For example: +// s1 = {a1, a2, a3} +// s2 = {a1, a2, a4, a5} +// s1.Difference(s2) = {a3} +// s2.Difference(s1) = {a4, a5} +func (s Int64) Difference(s2 Int64) Int64 { + result := NewInt64() + for key := range s { + if !s2.Has(key) { + result.Insert(key) + } + } + return result +} + +// Union returns a new set which includes items in either s1 or s2. +// For example: +// s1 = {a1, a2} +// s2 = {a3, a4} +// s1.Union(s2) = {a1, a2, a3, a4} +// s2.Union(s1) = {a1, a2, a3, a4} +func (s1 Int64) Union(s2 Int64) Int64 { + result := NewInt64() + for key := range s1 { + result.Insert(key) + } + for key := range s2 { + result.Insert(key) + } + return result +} + +// Intersection returns a new set which includes the item in BOTH s1 and s2 +// For example: +// s1 = {a1, a2} +// s2 = {a2, a3} +// s1.Intersection(s2) = {a2} +func (s1 Int64) Intersection(s2 Int64) Int64 { + var walk, other Int64 + result := NewInt64() + if s1.Len() < s2.Len() { + walk = s1 + other = s2 + } else { + walk = s2 + other = s1 + } + for key := range walk { + if other.Has(key) { + result.Insert(key) + } + } + return result +} + +// IsSuperset returns true if and only if s1 is a superset of s2. +func (s1 Int64) IsSuperset(s2 Int64) bool { + for item := range s2 { + if !s1.Has(item) { + return false + } + } + return true +} + +// Equal returns true if and only if s1 is equal (as a set) to s2. +// Two sets are equal if their membership is identical. +// (In practice, this means same elements, order doesn't matter) +func (s1 Int64) Equal(s2 Int64) bool { + return len(s1) == len(s2) && s1.IsSuperset(s2) +} + +type sortableSliceOfInt64 []int64 + +func (s sortableSliceOfInt64) Len() int { return len(s) } +func (s sortableSliceOfInt64) Less(i, j int) bool { return lessInt64(s[i], s[j]) } +func (s sortableSliceOfInt64) Swap(i, j int) { s[i], s[j] = s[j], s[i] } + +// List returns the contents as a sorted int64 slice. +func (s Int64) List() []int64 { + res := make(sortableSliceOfInt64, 0, len(s)) + for key := range s { + res = append(res, key) + } + sort.Sort(res) + return []int64(res) +} + +// UnsortedList returns the slice with contents in random order. +func (s Int64) UnsortedList() []int64 { + res := make([]int64, 0, len(s)) + for key := range s { + res = append(res, key) + } + return res +} + +// Returns a single element from the set. +func (s Int64) PopAny() (int64, bool) { + for key := range s { + s.Delete(key) + return key, true + } + var zeroValue int64 + return zeroValue, false +} + +// Len returns the size of the set. +func (s Int64) Len() int { + return len(s) +} + +func lessInt64(lhs, rhs int64) bool { + return lhs < rhs +} diff --git a/vendor/github.com/appscode/go/sets/string.go b/vendor/github.com/appscode/go/sets/string.go new file mode 100644 index 00000000..baef7a6a --- /dev/null +++ b/vendor/github.com/appscode/go/sets/string.go @@ -0,0 +1,203 @@ +/* +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. +*/ + +// This file was autogenerated by set-gen. Do not edit it manually! + +package sets + +import ( + "reflect" + "sort" +) + +// sets.String is a set of strings, implemented via map[string]struct{} for minimal memory consumption. +type String map[string]Empty + +// New creates a String from a list of values. +func NewString(items ...string) String { + ss := String{} + ss.Insert(items...) + return ss +} + +// StringKeySet creates a String from a keys of a map[string](? extends interface{}). +// If the value passed in is not actually a map, this will panic. +func StringKeySet(theMap interface{}) String { + v := reflect.ValueOf(theMap) + ret := String{} + + for _, keyValue := range v.MapKeys() { + ret.Insert(keyValue.Interface().(string)) + } + return ret +} + +// Insert adds items to the set. +func (s String) Insert(items ...string) { + for _, item := range items { + s[item] = Empty{} + } +} + +// Delete removes all items from the set. +func (s String) Delete(items ...string) { + for _, item := range items { + delete(s, item) + } +} + +// Has returns true if and only if item is contained in the set. +func (s String) Has(item string) bool { + _, contained := s[item] + return contained +} + +// HasAll returns true if and only if all items are contained in the set. +func (s String) HasAll(items ...string) bool { + for _, item := range items { + if !s.Has(item) { + return false + } + } + return true +} + +// HasAny returns true if any items are contained in the set. +func (s String) HasAny(items ...string) bool { + for _, item := range items { + if s.Has(item) { + return true + } + } + return false +} + +// Difference returns a set of objects that are not in s2 +// For example: +// s1 = {a1, a2, a3} +// s2 = {a1, a2, a4, a5} +// s1.Difference(s2) = {a3} +// s2.Difference(s1) = {a4, a5} +func (s String) Difference(s2 String) String { + result := NewString() + for key := range s { + if !s2.Has(key) { + result.Insert(key) + } + } + return result +} + +// Union returns a new set which includes items in either s1 or s2. +// For example: +// s1 = {a1, a2} +// s2 = {a3, a4} +// s1.Union(s2) = {a1, a2, a3, a4} +// s2.Union(s1) = {a1, a2, a3, a4} +func (s1 String) Union(s2 String) String { + result := NewString() + for key := range s1 { + result.Insert(key) + } + for key := range s2 { + result.Insert(key) + } + return result +} + +// Intersection returns a new set which includes the item in BOTH s1 and s2 +// For example: +// s1 = {a1, a2} +// s2 = {a2, a3} +// s1.Intersection(s2) = {a2} +func (s1 String) Intersection(s2 String) String { + var walk, other String + result := NewString() + if s1.Len() < s2.Len() { + walk = s1 + other = s2 + } else { + walk = s2 + other = s1 + } + for key := range walk { + if other.Has(key) { + result.Insert(key) + } + } + return result +} + +// IsSuperset returns true if and only if s1 is a superset of s2. +func (s1 String) IsSuperset(s2 String) bool { + for item := range s2 { + if !s1.Has(item) { + return false + } + } + return true +} + +// Equal returns true if and only if s1 is equal (as a set) to s2. +// Two sets are equal if their membership is identical. +// (In practice, this means same elements, order doesn't matter) +func (s1 String) Equal(s2 String) bool { + return len(s1) == len(s2) && s1.IsSuperset(s2) +} + +type sortableSliceOfString []string + +func (s sortableSliceOfString) Len() int { return len(s) } +func (s sortableSliceOfString) Less(i, j int) bool { return lessString(s[i], s[j]) } +func (s sortableSliceOfString) Swap(i, j int) { s[i], s[j] = s[j], s[i] } + +// List returns the contents as a sorted string slice. +func (s String) List() []string { + res := make(sortableSliceOfString, 0, len(s)) + for key := range s { + res = append(res, key) + } + sort.Sort(res) + return []string(res) +} + +// UnsortedList returns the slice with contents in random order. +func (s String) UnsortedList() []string { + res := make([]string, 0, len(s)) + for key := range s { + res = append(res, key) + } + return res +} + +// Returns a single element from the set. +func (s String) PopAny() (string, bool) { + for key := range s { + s.Delete(key) + return key, true + } + var zeroValue string + return zeroValue, false +} + +// Len returns the size of the set. +func (s String) Len() int { + return len(s) +} + +func lessString(lhs, rhs string) bool { + return lhs < rhs +} diff --git a/vendor/github.com/appscode/go/types/convert_types.go b/vendor/github.com/appscode/go/types/convert_types.go new file mode 100644 index 00000000..b60ac230 --- /dev/null +++ b/vendor/github.com/appscode/go/types/convert_types.go @@ -0,0 +1,501 @@ +package types + +import "time" + +// StringP returns a pointer to the string value passed in. +func StringP(v string) *string { + return &v +} + +// String returns the value of the string pointer passed in or +// "" if the pointer is nil. +func String(v *string) string { + if v != nil { + return *v + } + return "" +} + +// StringPSlice converts a slice of string values into a slice of +// string pointers +func StringPSlice(src []string) []*string { + dst := make([]*string, len(src)) + for i := 0; i < len(src); i++ { + dst[i] = &(src[i]) + } + return dst +} + +// StringSlice converts a slice of string pointers into a slice of +// string values +func StringSlice(src []*string) []string { + dst := make([]string, len(src)) + for i := 0; i < len(src); i++ { + if src[i] != nil { + dst[i] = *(src[i]) + } + } + return dst +} + +// StringPMap converts a string map of string values into a string +// map of string pointers +func StringPMap(src map[string]string) map[string]*string { + dst := make(map[string]*string) + for k, val := range src { + v := val + dst[k] = &v + } + return dst +} + +// StringMap converts a string map of string pointers into a string +// map of string values +func StringMap(src map[string]*string) map[string]string { + dst := make(map[string]string) + for k, val := range src { + if val != nil { + dst[k] = *val + } + } + return dst +} + +var trueP = BoolP(true) + +// FalseP returns a pointer to `true` boolean value. +func TrueP() *bool { + return trueP +} + +var falseP = BoolP(false) + +// FalseP returns a pointer to `false` boolean value. +func FalseP() *bool { + return falseP +} + +// BoolP returns a pointer to the bool value passed in. +func BoolP(v bool) *bool { + return &v +} + +// Bool returns the value of the bool pointer passed in or +// false if the pointer is nil. +func Bool(v *bool) bool { + if v != nil { + return *v + } + return false +} + +// BoolPSlice converts a slice of bool values into a slice of +// bool pointers +func BoolPSlice(src []bool) []*bool { + dst := make([]*bool, len(src)) + for i := 0; i < len(src); i++ { + dst[i] = &(src[i]) + } + return dst +} + +// BoolSlice converts a slice of bool pointers into a slice of +// bool values +func BoolSlice(src []*bool) []bool { + dst := make([]bool, len(src)) + for i := 0; i < len(src); i++ { + if src[i] != nil { + dst[i] = *(src[i]) + } + } + return dst +} + +// BoolPMap converts a string map of bool values into a string +// map of bool pointers +func BoolPMap(src map[string]bool) map[string]*bool { + dst := make(map[string]*bool) + for k, val := range src { + v := val + dst[k] = &v + } + return dst +} + +// BoolMap converts a string map of bool pointers into a string +// map of bool values +func BoolMap(src map[string]*bool) map[string]bool { + dst := make(map[string]bool) + for k, val := range src { + if val != nil { + dst[k] = *val + } + } + return dst +} + +// IntP returns a pointer to the int value passed in. +func IntP(v int) *int { + return &v +} + +// Int returns the value of the int pointer passed in or +// 0 if the pointer is nil. +func Int(v *int) int { + if v != nil { + return *v + } + return 0 +} + +// IntPSlice converts a slice of int values into a slice of +// int pointers +func IntPSlice(src []int) []*int { + dst := make([]*int, len(src)) + for i := 0; i < len(src); i++ { + dst[i] = &(src[i]) + } + return dst +} + +// IntSlice converts a slice of int pointers into a slice of +// int values +func IntSlice(src []*int) []int { + dst := make([]int, len(src)) + for i := 0; i < len(src); i++ { + if src[i] != nil { + dst[i] = *(src[i]) + } + } + return dst +} + +// IntPMap converts a string map of int values into a string +// map of int pointers +func IntPMap(src map[string]int) map[string]*int { + dst := make(map[string]*int) + for k, val := range src { + v := val + dst[k] = &v + } + return dst +} + +// IntMap converts a string map of int pointers into a string +// map of int values +func IntMap(src map[string]*int) map[string]int { + dst := make(map[string]int) + for k, val := range src { + if val != nil { + dst[k] = *val + } + } + return dst +} + +// UIntP returns a pointer to the uint value passed in. +func UIntP(v uint) *uint { + return &v +} + +// UInt returns the value of the uint pointer passed in or +// 0 if the pointer is nil. +func UInt(v *uint) uint { + if v != nil { + return *v + } + return 0 +} + +// UIntPSlice converts a slice of uint values into a slice of +// uint pointers +func UIntPSlice(src []uint) []*uint { + dst := make([]*uint, len(src)) + for i := 0; i < len(src); i++ { + dst[i] = &(src[i]) + } + return dst +} + +// UIntSlice converts a slice of uint pointers into a slice of +// uint values +func UIntSlice(src []*uint) []uint { + dst := make([]uint, len(src)) + for i := 0; i < len(src); i++ { + if src[i] != nil { + dst[i] = *(src[i]) + } + } + return dst +} + +// UIntPMap converts a string map of uint values into a string +// map of uint pointers +func UIntPMap(src map[string]uint) map[string]*uint { + dst := make(map[string]*uint) + for k, val := range src { + v := val + dst[k] = &v + } + return dst +} + +// UIntMap converts a string map of uint pointers into a string +// map of uint values +func UIntMap(src map[string]*uint) map[string]uint { + dst := make(map[string]uint) + for k, val := range src { + if val != nil { + dst[k] = *val + } + } + return dst +} + +// Int32P returns a pointer to the int32 value passed in. +func Int32P(v int32) *int32 { + return &v +} + +// Int32 returns the value of the int32 pointer passed in or +// 0 if the pointer is nil. +func Int32(v *int32) int32 { + if v != nil { + return *v + } + return 0 +} + +// Int32PSlice converts a slice of int32 values into a slice of +// int32 pointers +func Int32PSlice(src []int32) []*int32 { + dst := make([]*int32, len(src)) + for i := 0; i < len(src); i++ { + dst[i] = &(src[i]) + } + return dst +} + +// Int32Slice converts a slice of int32 pointers into a slice of +// int32 values +func Int32Slice(src []*int32) []int32 { + dst := make([]int32, len(src)) + for i := 0; i < len(src); i++ { + if src[i] != nil { + dst[i] = *(src[i]) + } + } + return dst +} + +// Int32PMap converts a string map of int32 values into a string +// map of int32 pointers +func Int32PMap(src map[string]int32) map[string]*int32 { + dst := make(map[string]*int32) + for k, val := range src { + v := val + dst[k] = &v + } + return dst +} + +// Int32Map converts a string map of int32 pointers into a string +// map of int32 values +func Int32Map(src map[string]*int32) map[string]int32 { + dst := make(map[string]int32) + for k, val := range src { + if val != nil { + dst[k] = *val + } + } + return dst +} + +// Int64P returns a pointer to the int64 value passed in. +func Int64P(v int64) *int64 { + return &v +} + +// Int64 returns the value of the int64 pointer passed in or +// 0 if the pointer is nil. +func Int64(v *int64) int64 { + if v != nil { + return *v + } + return 0 +} + +// Int64PSlice converts a slice of int64 values into a slice of +// int64 pointers +func Int64PSlice(src []int64) []*int64 { + dst := make([]*int64, len(src)) + for i := 0; i < len(src); i++ { + dst[i] = &(src[i]) + } + return dst +} + +// Int64Slice converts a slice of int64 pointers into a slice of +// int64 values +func Int64Slice(src []*int64) []int64 { + dst := make([]int64, len(src)) + for i := 0; i < len(src); i++ { + if src[i] != nil { + dst[i] = *(src[i]) + } + } + return dst +} + +// Int64PMap converts a string map of int64 values into a string +// map of int64 pointers +func Int64PMap(src map[string]int64) map[string]*int64 { + dst := make(map[string]*int64) + for k, val := range src { + v := val + dst[k] = &v + } + return dst +} + +// Int64Map converts a string map of int64 pointers into a string +// map of int64 values +func Int64Map(src map[string]*int64) map[string]int64 { + dst := make(map[string]int64) + for k, val := range src { + if val != nil { + dst[k] = *val + } + } + return dst +} + +// Float64P returns a pointer to the float64 value passed in. +func Float64P(v float64) *float64 { + return &v +} + +// Float64 returns the value of the float64 pointer passed in or +// 0 if the pointer is nil. +func Float64(v *float64) float64 { + if v != nil { + return *v + } + return 0 +} + +// Float64PSlice converts a slice of float64 values into a slice of +// float64 pointers +func Float64PSlice(src []float64) []*float64 { + dst := make([]*float64, len(src)) + for i := 0; i < len(src); i++ { + dst[i] = &(src[i]) + } + return dst +} + +// Float64Slice converts a slice of float64 pointers into a slice of +// float64 values +func Float64Slice(src []*float64) []float64 { + dst := make([]float64, len(src)) + for i := 0; i < len(src); i++ { + if src[i] != nil { + dst[i] = *(src[i]) + } + } + return dst +} + +// Float64PMap converts a string map of float64 values into a string +// map of float64 pointers +func Float64PMap(src map[string]float64) map[string]*float64 { + dst := make(map[string]*float64) + for k, val := range src { + v := val + dst[k] = &v + } + return dst +} + +// Float64Map converts a string map of float64 pointers into a string +// map of float64 values +func Float64Map(src map[string]*float64) map[string]float64 { + dst := make(map[string]float64) + for k, val := range src { + if val != nil { + dst[k] = *val + } + } + return dst +} + +// TimeP returns a pointer to the time.Time value passed in. +func TimeP(v time.Time) *time.Time { + return &v +} + +// Time returns the value of the time.Time pointer passed in or +// time.Time{} if the pointer is nil. +func Time(v *time.Time) time.Time { + if v != nil { + return *v + } + return time.Time{} +} + +// TimeUnixMilli returns a Unix timestamp in milliseconds from "January 1, 1970 UTC". +// The result is undefined if the Unix time cannot be represented by an int64. +// Which includes calling TimeUnixMilli on a zero Time is undefined. +// +// This utility is useful for service API's such as CloudWatch Logs which require +// their unix time values to be in milliseconds. +// +// See Go stdlib https://golang.org/pkg/time/#Time.UnixNano for more information. +func TimeUnixMilli(t time.Time) int64 { + return t.UnixNano() / int64(time.Millisecond/time.Nanosecond) +} + +// TimePSlice converts a slice of time.Time values into a slice of +// time.Time pointers +func TimePSlice(src []time.Time) []*time.Time { + dst := make([]*time.Time, len(src)) + for i := 0; i < len(src); i++ { + dst[i] = &(src[i]) + } + return dst +} + +// TimeSlice converts a slice of time.Time pointers into a slice of +// time.Time values +func TimeSlice(src []*time.Time) []time.Time { + dst := make([]time.Time, len(src)) + for i := 0; i < len(src); i++ { + if src[i] != nil { + dst[i] = *(src[i]) + } + } + return dst +} + +// TimePMap converts a string map of time.Time values into a string +// map of time.Time pointers +func TimePMap(src map[string]time.Time) map[string]*time.Time { + dst := make(map[string]*time.Time) + for k, val := range src { + v := val + dst[k] = &v + } + return dst +} + +// TimeMap converts a string map of time.Time pointers into a string +// map of time.Time values +func TimeMap(src map[string]*time.Time) map[string]time.Time { + dst := make(map[string]time.Time) + for k, val := range src { + if val != nil { + dst[k] = *val + } + } + return dst +} diff --git a/vendor/github.com/appscode/go/types/doc.go b/vendor/github.com/appscode/go/types/doc.go new file mode 100644 index 00000000..031caf59 --- /dev/null +++ b/vendor/github.com/appscode/go/types/doc.go @@ -0,0 +1,7 @@ +/* +GOlang value <--> pointer + +##Acknowledgements +This repo was started as a fork of https://github.com/aws/aws-sdk-go/blob/master/aws/convert_types.go +*/ +package types diff --git a/vendor/github.com/fatih/structs/.gitignore b/vendor/github.com/fatih/structs/.gitignore new file mode 100644 index 00000000..83656241 --- /dev/null +++ b/vendor/github.com/fatih/structs/.gitignore @@ -0,0 +1,23 @@ +# Compiled Object files, Static and Dynamic libs (Shared Objects) +*.o +*.a +*.so + +# Folders +_obj +_test + +# Architecture specific extensions/prefixes +*.[568vq] +[568vq].out + +*.cgo1.go +*.cgo2.c +_cgo_defun.c +_cgo_gotypes.go +_cgo_export.* + +_testmain.go + +*.exe +*.test diff --git a/vendor/github.com/fatih/structs/.travis.yml b/vendor/github.com/fatih/structs/.travis.yml new file mode 100644 index 00000000..a08df798 --- /dev/null +++ b/vendor/github.com/fatih/structs/.travis.yml @@ -0,0 +1,13 @@ +language: go +go: + - 1.7.x + - 1.8.x + - 1.9.x + - tip +sudo: false +before_install: +- go get github.com/axw/gocov/gocov +- go get github.com/mattn/goveralls +- if ! go get github.com/golang/tools/cmd/cover; then go get golang.org/x/tools/cmd/cover; fi +script: +- $HOME/gopath/bin/goveralls -service=travis-ci diff --git a/vendor/github.com/fatih/structs/LICENSE b/vendor/github.com/fatih/structs/LICENSE new file mode 100644 index 00000000..34504e4b --- /dev/null +++ b/vendor/github.com/fatih/structs/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2014 Fatih Arslan + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/vendor/github.com/fatih/structs/README.md b/vendor/github.com/fatih/structs/README.md new file mode 100644 index 00000000..a75eabf3 --- /dev/null +++ b/vendor/github.com/fatih/structs/README.md @@ -0,0 +1,163 @@ +# Structs [![GoDoc](http://img.shields.io/badge/go-documentation-blue.svg?style=flat-square)](http://godoc.org/github.com/fatih/structs) [![Build Status](http://img.shields.io/travis/fatih/structs.svg?style=flat-square)](https://travis-ci.org/fatih/structs) [![Coverage Status](http://img.shields.io/coveralls/fatih/structs.svg?style=flat-square)](https://coveralls.io/r/fatih/structs) + +Structs contains various utilities to work with Go (Golang) structs. It was +initially used by me to convert a struct into a `map[string]interface{}`. With +time I've added other utilities for structs. It's basically a high level +package based on primitives from the reflect package. Feel free to add new +functions or improve the existing code. + +## Install + +```bash +go get github.com/fatih/structs +``` + +## Usage and Examples + +Just like the standard lib `strings`, `bytes` and co packages, `structs` has +many global functions to manipulate or organize your struct data. Lets define +and declare a struct: + +```go +type Server struct { + Name string `json:"name,omitempty"` + ID int + Enabled bool + users []string // not exported + http.Server // embedded +} + +server := &Server{ + Name: "gopher", + ID: 123456, + Enabled: true, +} +``` + +```go +// Convert a struct to a map[string]interface{} +// => {"Name":"gopher", "ID":123456, "Enabled":true} +m := structs.Map(server) + +// Convert the values of a struct to a []interface{} +// => ["gopher", 123456, true] +v := structs.Values(server) + +// Convert the names of a struct to a []string +// (see "Names methods" for more info about fields) +n := structs.Names(server) + +// Convert the values of a struct to a []*Field +// (see "Field methods" for more info about fields) +f := structs.Fields(server) + +// Return the struct name => "Server" +n := structs.Name(server) + +// Check if any field of a struct is initialized or not. +h := structs.HasZero(server) + +// Check if all fields of a struct is initialized or not. +z := structs.IsZero(server) + +// Check if server is a struct or a pointer to struct +i := structs.IsStruct(server) +``` + +### Struct methods + +The structs functions can be also used as independent methods by creating a new +`*structs.Struct`. This is handy if you want to have more control over the +structs (such as retrieving a single Field). + +```go +// Create a new struct type: +s := structs.New(server) + +m := s.Map() // Get a map[string]interface{} +v := s.Values() // Get a []interface{} +f := s.Fields() // Get a []*Field +n := s.Names() // Get a []string +f := s.Field(name) // Get a *Field based on the given field name +f, ok := s.FieldOk(name) // Get a *Field based on the given field name +n := s.Name() // Get the struct name +h := s.HasZero() // Check if any field is uninitialized +z := s.IsZero() // Check if all fields are uninitialized +``` + +### Field methods + +We can easily examine a single Field for more detail. Below you can see how we +get and interact with various field methods: + + +```go +s := structs.New(server) + +// Get the Field struct for the "Name" field +name := s.Field("Name") + +// Get the underlying value, value => "gopher" +value := name.Value().(string) + +// Set the field's value +name.Set("another gopher") + +// Get the field's kind, kind => "string" +name.Kind() + +// Check if the field is exported or not +if name.IsExported() { + fmt.Println("Name field is exported") +} + +// Check if the value is a zero value, such as "" for string, 0 for int +if !name.IsZero() { + fmt.Println("Name is initialized") +} + +// Check if the field is an anonymous (embedded) field +if !name.IsEmbedded() { + fmt.Println("Name is not an embedded field") +} + +// Get the Field's tag value for tag name "json", tag value => "name,omitempty" +tagValue := name.Tag("json") +``` + +Nested structs are supported too: + +```go +addrField := s.Field("Server").Field("Addr") + +// Get the value for addr +a := addrField.Value().(string) + +// Or get all fields +httpServer := s.Field("Server").Fields() +``` + +We can also get a slice of Fields from the Struct type to iterate over all +fields. This is handy if you wish to examine all fields: + +```go +s := structs.New(server) + +for _, f := range s.Fields() { + fmt.Printf("field name: %+v\n", f.Name()) + + if f.IsExported() { + fmt.Printf("value : %+v\n", f.Value()) + fmt.Printf("is zero : %+v\n", f.IsZero()) + } +} +``` + +## Credits + + * [Fatih Arslan](https://github.com/fatih) + * [Cihangir Savas](https://github.com/cihangir) + +## License + +The MIT License (MIT) - see LICENSE.md for more details diff --git a/vendor/github.com/fatih/structs/field.go b/vendor/github.com/fatih/structs/field.go new file mode 100644 index 00000000..e6978323 --- /dev/null +++ b/vendor/github.com/fatih/structs/field.go @@ -0,0 +1,141 @@ +package structs + +import ( + "errors" + "fmt" + "reflect" +) + +var ( + errNotExported = errors.New("field is not exported") + errNotSettable = errors.New("field is not settable") +) + +// Field represents a single struct field that encapsulates high level +// functions around the field. +type Field struct { + value reflect.Value + field reflect.StructField + defaultTag string +} + +// Tag returns the value associated with key in the tag string. If there is no +// such key in the tag, Tag returns the empty string. +func (f *Field) Tag(key string) string { + return f.field.Tag.Get(key) +} + +// Value returns the underlying value of the field. It panics if the field +// is not exported. +func (f *Field) Value() interface{} { + return f.value.Interface() +} + +// IsEmbedded returns true if the given field is an anonymous field (embedded) +func (f *Field) IsEmbedded() bool { + return f.field.Anonymous +} + +// IsExported returns true if the given field is exported. +func (f *Field) IsExported() bool { + return f.field.PkgPath == "" +} + +// IsZero returns true if the given field is not initialized (has a zero value). +// It panics if the field is not exported. +func (f *Field) IsZero() bool { + zero := reflect.Zero(f.value.Type()).Interface() + current := f.Value() + + return reflect.DeepEqual(current, zero) +} + +// Name returns the name of the given field +func (f *Field) Name() string { + return f.field.Name +} + +// Kind returns the fields kind, such as "string", "map", "bool", etc .. +func (f *Field) Kind() reflect.Kind { + return f.value.Kind() +} + +// Set sets the field to given value v. It returns an error if the field is not +// settable (not addressable or not exported) or if the given value's type +// doesn't match the fields type. +func (f *Field) Set(val interface{}) error { + // we can't set unexported fields, so be sure this field is exported + if !f.IsExported() { + return errNotExported + } + + // do we get here? not sure... + if !f.value.CanSet() { + return errNotSettable + } + + given := reflect.ValueOf(val) + + if f.value.Kind() != given.Kind() { + return fmt.Errorf("wrong kind. got: %s want: %s", given.Kind(), f.value.Kind()) + } + + f.value.Set(given) + return nil +} + +// Zero sets the field to its zero value. It returns an error if the field is not +// settable (not addressable or not exported). +func (f *Field) Zero() error { + zero := reflect.Zero(f.value.Type()).Interface() + return f.Set(zero) +} + +// Fields returns a slice of Fields. This is particular handy to get the fields +// of a nested struct . A struct tag with the content of "-" ignores the +// checking of that particular field. Example: +// +// // Field is ignored by this package. +// Field *http.Request `structs:"-"` +// +// It panics if field is not exported or if field's kind is not struct +func (f *Field) Fields() []*Field { + return getFields(f.value, f.defaultTag) +} + +// Field returns the field from a nested struct. It panics if the nested struct +// is not exported or if the field was not found. +func (f *Field) Field(name string) *Field { + field, ok := f.FieldOk(name) + if !ok { + panic("field not found") + } + + return field +} + +// FieldOk returns the field from a nested struct. The boolean returns whether +// the field was found (true) or not (false). +func (f *Field) FieldOk(name string) (*Field, bool) { + value := &f.value + // value must be settable so we need to make sure it holds the address of the + // variable and not a copy, so we can pass the pointer to strctVal instead of a + // copy (which is not assigned to any variable, hence not settable). + // see "https://blog.golang.org/laws-of-reflection#TOC_8." + if f.value.Kind() != reflect.Ptr { + a := f.value.Addr() + value = &a + } + v := strctVal(value.Interface()) + t := v.Type() + + field, ok := t.FieldByName(name) + if !ok { + return nil, false + } + + return &Field{ + field: field, + value: v.FieldByName(name), + }, true +} diff --git a/vendor/github.com/fatih/structs/structs.go b/vendor/github.com/fatih/structs/structs.go new file mode 100644 index 00000000..3a877065 --- /dev/null +++ b/vendor/github.com/fatih/structs/structs.go @@ -0,0 +1,584 @@ +// Package structs contains various utilities functions to work with structs. +package structs + +import ( + "fmt" + + "reflect" +) + +var ( + // DefaultTagName is the default tag name for struct fields which provides + // a more granular to tweak certain structs. Lookup the necessary functions + // for more info. + DefaultTagName = "structs" // struct's field default tag name +) + +// Struct encapsulates a struct type to provide several high level functions +// around the struct. +type Struct struct { + raw interface{} + value reflect.Value + TagName string +} + +// New returns a new *Struct with the struct s. It panics if the s's kind is +// not struct. +func New(s interface{}) *Struct { + return &Struct{ + raw: s, + value: strctVal(s), + TagName: DefaultTagName, + } +} + +// Map converts the given struct to a map[string]interface{}, where the keys +// of the map are the field names and the values of the map the associated +// values of the fields. The default key string is the struct field name but +// can be changed in the struct field's tag value. The "structs" key in the +// struct's field tag value is the key name. Example: +// +// // Field appears in map as key "myName". +// Name string `structs:"myName"` +// +// A tag value with the content of "-" ignores that particular field. Example: +// +// // Field is ignored by this package. +// Field bool `structs:"-"` +// +// A tag value with the content of "string" uses the stringer to get the value. Example: +// +// // The value will be output of Animal's String() func. +// // Map will panic if Animal does not implement String(). +// Field *Animal `structs:"field,string"` +// +// A tag value with the option of "flatten" used in a struct field is to flatten its fields +// in the output map. Example: +// +// // The FieldStruct's fields will be flattened into the output map. +// FieldStruct time.Time `structs:",flatten"` +// +// A tag value with the option of "omitnested" stops iterating further if the type +// is a struct. Example: +// +// // Field is not processed further by this package. +// Field time.Time `structs:"myName,omitnested"` +// Field *http.Request `structs:",omitnested"` +// +// A tag value with the option of "omitempty" ignores that particular field if +// the field value is empty. Example: +// +// // Field appears in map as key "myName", but the field is +// // skipped if empty. +// Field string `structs:"myName,omitempty"` +// +// // Field appears in map as key "Field" (the default), but +// // the field is skipped if empty. +// Field string `structs:",omitempty"` +// +// Note that only exported fields of a struct can be accessed, non exported +// fields will be neglected. +func (s *Struct) Map() map[string]interface{} { + out := make(map[string]interface{}) + s.FillMap(out) + return out +} + +// FillMap is the same as Map. Instead of returning the output, it fills the +// given map. +func (s *Struct) FillMap(out map[string]interface{}) { + if out == nil { + return + } + + fields := s.structFields() + + for _, field := range fields { + name := field.Name + val := s.value.FieldByName(name) + isSubStruct := false + var finalVal interface{} + + tagName, tagOpts := parseTag(field.Tag.Get(s.TagName)) + if tagName != "" { + name = tagName + } + + // if the value is a zero value and the field is marked as omitempty do + // not include + if tagOpts.Has("omitempty") { + zero := reflect.Zero(val.Type()).Interface() + current := val.Interface() + + if reflect.DeepEqual(current, zero) { + continue + } + } + + if !tagOpts.Has("omitnested") { + finalVal = s.nested(val) + + v := reflect.ValueOf(val.Interface()) + if v.Kind() == reflect.Ptr { + v = v.Elem() + } + + switch v.Kind() { + case reflect.Map, reflect.Struct: + isSubStruct = true + } + } else { + finalVal = val.Interface() + } + + if tagOpts.Has("string") { + s, ok := val.Interface().(fmt.Stringer) + if ok { + out[name] = s.String() + } + continue + } + + if isSubStruct && (tagOpts.Has("flatten")) { + for k := range finalVal.(map[string]interface{}) { + out[k] = finalVal.(map[string]interface{})[k] + } + } else { + out[name] = finalVal + } + } +} + +// Values converts the given s struct's field values to a []interface{}. A +// struct tag with the content of "-" ignores the that particular field. +// Example: +// +// // Field is ignored by this package. +// Field int `structs:"-"` +// +// A value with the option of "omitnested" stops iterating further if the type +// is a struct. Example: +// +// // Fields is not processed further by this package. +// Field time.Time `structs:",omitnested"` +// Field *http.Request `structs:",omitnested"` +// +// A tag value with the option of "omitempty" ignores that particular field and +// is not added to the values if the field value is empty. Example: +// +// // Field is skipped if empty +// Field string `structs:",omitempty"` +// +// Note that only exported fields of a struct can be accessed, non exported +// fields will be neglected. +func (s *Struct) Values() []interface{} { + fields := s.structFields() + + var t []interface{} + + for _, field := range fields { + val := s.value.FieldByName(field.Name) + + _, tagOpts := parseTag(field.Tag.Get(s.TagName)) + + // if the value is a zero value and the field is marked as omitempty do + // not include + if tagOpts.Has("omitempty") { + zero := reflect.Zero(val.Type()).Interface() + current := val.Interface() + + if reflect.DeepEqual(current, zero) { + continue + } + } + + if tagOpts.Has("string") { + s, ok := val.Interface().(fmt.Stringer) + if ok { + t = append(t, s.String()) + } + continue + } + + if IsStruct(val.Interface()) && !tagOpts.Has("omitnested") { + // look out for embedded structs, and convert them to a + // []interface{} to be added to the final values slice + t = append(t, Values(val.Interface())...) + } else { + t = append(t, val.Interface()) + } + } + + return t +} + +// Fields returns a slice of Fields. A struct tag with the content of "-" +// ignores the checking of that particular field. Example: +// +// // Field is ignored by this package. +// Field bool `structs:"-"` +// +// It panics if s's kind is not struct. +func (s *Struct) Fields() []*Field { + return getFields(s.value, s.TagName) +} + +// Names returns a slice of field names. A struct tag with the content of "-" +// ignores the checking of that particular field. Example: +// +// // Field is ignored by this package. +// Field bool `structs:"-"` +// +// It panics if s's kind is not struct. +func (s *Struct) Names() []string { + fields := getFields(s.value, s.TagName) + + names := make([]string, len(fields)) + + for i, field := range fields { + names[i] = field.Name() + } + + return names +} + +func getFields(v reflect.Value, tagName string) []*Field { + if v.Kind() == reflect.Ptr { + v = v.Elem() + } + + t := v.Type() + + var fields []*Field + + for i := 0; i < t.NumField(); i++ { + field := t.Field(i) + + if tag := field.Tag.Get(tagName); tag == "-" { + continue + } + + f := &Field{ + field: field, + value: v.FieldByName(field.Name), + } + + fields = append(fields, f) + + } + + return fields +} + +// Field returns a new Field struct that provides several high level functions +// around a single struct field entity. It panics if the field is not found. +func (s *Struct) Field(name string) *Field { + f, ok := s.FieldOk(name) + if !ok { + panic("field not found") + } + + return f +} + +// FieldOk returns a new Field struct that provides several high level functions +// around a single struct field entity. The boolean returns true if the field +// was found. +func (s *Struct) FieldOk(name string) (*Field, bool) { + t := s.value.Type() + + field, ok := t.FieldByName(name) + if !ok { + return nil, false + } + + return &Field{ + field: field, + value: s.value.FieldByName(name), + defaultTag: s.TagName, + }, true +} + +// IsZero returns true if all fields in a struct is a zero value (not +// initialized) A struct tag with the content of "-" ignores the checking of +// that particular field. Example: +// +// // Field is ignored by this package. +// Field bool `structs:"-"` +// +// A value with the option of "omitnested" stops iterating further if the type +// is a struct. Example: +// +// // Field is not processed further by this package. +// Field time.Time `structs:"myName,omitnested"` +// Field *http.Request `structs:",omitnested"` +// +// Note that only exported fields of a struct can be accessed, non exported +// fields will be neglected. It panics if s's kind is not struct. +func (s *Struct) IsZero() bool { + fields := s.structFields() + + for _, field := range fields { + val := s.value.FieldByName(field.Name) + + _, tagOpts := parseTag(field.Tag.Get(s.TagName)) + + if IsStruct(val.Interface()) && !tagOpts.Has("omitnested") { + ok := IsZero(val.Interface()) + if !ok { + return false + } + + continue + } + + // zero value of the given field, such as "" for string, 0 for int + zero := reflect.Zero(val.Type()).Interface() + + // current value of the given field + current := val.Interface() + + if !reflect.DeepEqual(current, zero) { + return false + } + } + + return true +} + +// HasZero returns true if a field in a struct is not initialized (zero value). +// A struct tag with the content of "-" ignores the checking of that particular +// field. Example: +// +// // Field is ignored by this package. +// Field bool `structs:"-"` +// +// A value with the option of "omitnested" stops iterating further if the type +// is a struct. Example: +// +// // Field is not processed further by this package. +// Field time.Time `structs:"myName,omitnested"` +// Field *http.Request `structs:",omitnested"` +// +// Note that only exported fields of a struct can be accessed, non exported +// fields will be neglected. It panics if s's kind is not struct. +func (s *Struct) HasZero() bool { + fields := s.structFields() + + for _, field := range fields { + val := s.value.FieldByName(field.Name) + + _, tagOpts := parseTag(field.Tag.Get(s.TagName)) + + if IsStruct(val.Interface()) && !tagOpts.Has("omitnested") { + ok := HasZero(val.Interface()) + if ok { + return true + } + + continue + } + + // zero value of the given field, such as "" for string, 0 for int + zero := reflect.Zero(val.Type()).Interface() + + // current value of the given field + current := val.Interface() + + if reflect.DeepEqual(current, zero) { + return true + } + } + + return false +} + +// Name returns the structs's type name within its package. For more info refer +// to Name() function. +func (s *Struct) Name() string { + return s.value.Type().Name() +} + +// structFields returns the exported struct fields for a given s struct. This +// is a convenient helper method to avoid duplicate code in some of the +// functions. +func (s *Struct) structFields() []reflect.StructField { + t := s.value.Type() + + var f []reflect.StructField + + for i := 0; i < t.NumField(); i++ { + field := t.Field(i) + // we can't access the value of unexported fields + if field.PkgPath != "" { + continue + } + + // don't check if it's omitted + if tag := field.Tag.Get(s.TagName); tag == "-" { + continue + } + + f = append(f, field) + } + + return f +} + +func strctVal(s interface{}) reflect.Value { + v := reflect.ValueOf(s) + + // if pointer get the underlying element≤ + for v.Kind() == reflect.Ptr { + v = v.Elem() + } + + if v.Kind() != reflect.Struct { + panic("not struct") + } + + return v +} + +// Map converts the given struct to a map[string]interface{}. For more info +// refer to Struct types Map() method. It panics if s's kind is not struct. +func Map(s interface{}) map[string]interface{} { + return New(s).Map() +} + +// FillMap is the same as Map. Instead of returning the output, it fills the +// given map. +func FillMap(s interface{}, out map[string]interface{}) { + New(s).FillMap(out) +} + +// Values converts the given struct to a []interface{}. For more info refer to +// Struct types Values() method. It panics if s's kind is not struct. +func Values(s interface{}) []interface{} { + return New(s).Values() +} + +// Fields returns a slice of *Field. For more info refer to Struct types +// Fields() method. It panics if s's kind is not struct. +func Fields(s interface{}) []*Field { + return New(s).Fields() +} + +// Names returns a slice of field names. For more info refer to Struct types +// Names() method. It panics if s's kind is not struct. +func Names(s interface{}) []string { + return New(s).Names() +} + +// IsZero returns true if all fields is equal to a zero value. For more info +// refer to Struct types IsZero() method. It panics if s's kind is not struct. +func IsZero(s interface{}) bool { + return New(s).IsZero() +} + +// HasZero returns true if any field is equal to a zero value. For more info +// refer to Struct types HasZero() method. It panics if s's kind is not struct. +func HasZero(s interface{}) bool { + return New(s).HasZero() +} + +// IsStruct returns true if the given variable is a struct or a pointer to +// struct. +func IsStruct(s interface{}) bool { + v := reflect.ValueOf(s) + if v.Kind() == reflect.Ptr { + v = v.Elem() + } + + // uninitialized zero value of a struct + if v.Kind() == reflect.Invalid { + return false + } + + return v.Kind() == reflect.Struct +} + +// Name returns the structs's type name within its package. It returns an +// empty string for unnamed types. It panics if s's kind is not struct. +func Name(s interface{}) string { + return New(s).Name() +} + +// nested retrieves recursively all types for the given value and returns the +// nested value. +func (s *Struct) nested(val reflect.Value) interface{} { + var finalVal interface{} + + v := reflect.ValueOf(val.Interface()) + if v.Kind() == reflect.Ptr { + v = v.Elem() + } + + switch v.Kind() { + case reflect.Struct: + n := New(val.Interface()) + n.TagName = s.TagName + m := n.Map() + + // do not add the converted value if there are no exported fields, ie: + // time.Time + if len(m) == 0 { + finalVal = val.Interface() + } else { + finalVal = m + } + case reflect.Map: + // get the element type of the map + mapElem := val.Type() + switch val.Type().Kind() { + case reflect.Ptr, reflect.Array, reflect.Map, + reflect.Slice, reflect.Chan: + mapElem = val.Type().Elem() + if mapElem.Kind() == reflect.Ptr { + mapElem = mapElem.Elem() + } + } + + // only iterate over struct types, ie: map[string]StructType, + // map[string][]StructType, + if mapElem.Kind() == reflect.Struct || + (mapElem.Kind() == reflect.Slice && + mapElem.Elem().Kind() == reflect.Struct) { + m := make(map[string]interface{}, val.Len()) + for _, k := range val.MapKeys() { + m[k.String()] = s.nested(val.MapIndex(k)) + } + finalVal = m + break + } + + // TODO(arslan): should this be optional? + finalVal = val.Interface() + case reflect.Slice, reflect.Array: + if val.Type().Kind() == reflect.Interface { + finalVal = val.Interface() + break + } + + // TODO(arslan): should this be optional? + // do not iterate of non struct types, just pass the value. Ie: []int, + // []string, co... We only iterate further if it's a struct. + // i.e []foo or []*foo + if val.Type().Elem().Kind() != reflect.Struct && + !(val.Type().Elem().Kind() == reflect.Ptr && + val.Type().Elem().Elem().Kind() == reflect.Struct) { + finalVal = val.Interface() + break + } + + slices := make([]interface{}, val.Len()) + for x := 0; x < val.Len(); x++ { + slices[x] = s.nested(val.Index(x)) + } + finalVal = slices + default: + finalVal = val.Interface() + } + + return finalVal +} diff --git a/vendor/github.com/fatih/structs/tags.go b/vendor/github.com/fatih/structs/tags.go new file mode 100644 index 00000000..136a31eb --- /dev/null +++ b/vendor/github.com/fatih/structs/tags.go @@ -0,0 +1,32 @@ +package structs + +import "strings" + +// tagOptions contains a slice of tag options +type tagOptions []string + +// Has returns true if the given option is available in tagOptions +func (t tagOptions) Has(opt string) bool { + for _, tagOpt := range t { + if tagOpt == opt { + return true + } + } + + return false +} + +// parseTag splits a struct field's tag into its name and a list of options +// which comes after a name. A tag is in the form of: "name,option1,option2". +// The name can be neglectected. +func parseTag(tag string) (string, tagOptions) { + // tag is one of followings: + // "" + // "name" + // "name,opt" + // "name,opt,opt2" + // ",opt" + + res := strings.Split(tag, ",") + return res[0], res[1:] +} diff --git a/vendor/github.com/mitchellh/mapstructure/.travis.yml b/vendor/github.com/mitchellh/mapstructure/.travis.yml new file mode 100644 index 00000000..1689c7d7 --- /dev/null +++ b/vendor/github.com/mitchellh/mapstructure/.travis.yml @@ -0,0 +1,8 @@ +language: go + +go: + - "1.11.x" + - tip + +script: + - go test diff --git a/vendor/github.com/mitchellh/mapstructure/CHANGELOG.md b/vendor/github.com/mitchellh/mapstructure/CHANGELOG.md new file mode 100644 index 00000000..3b3cb723 --- /dev/null +++ b/vendor/github.com/mitchellh/mapstructure/CHANGELOG.md @@ -0,0 +1,21 @@ +## 1.1.2 + +* Fix error when decode hook decodes interface implementation into interface + type. [GH-140] + +## 1.1.1 + +* Fix panic that can happen in `decodePtr` + +## 1.1.0 + +* Added `StringToIPHookFunc` to convert `string` to `net.IP` and `net.IPNet` [GH-133] +* Support struct to struct decoding [GH-137] +* If source map value is nil, then destination map value is nil (instead of empty) +* If source slice value is nil, then destination slice value is nil (instead of empty) +* If source pointer is nil, then destination pointer is set to nil (instead of + allocated zero value of type) + +## 1.0.0 + +* Initial tagged stable release. diff --git a/vendor/github.com/mitchellh/mapstructure/LICENSE b/vendor/github.com/mitchellh/mapstructure/LICENSE new file mode 100644 index 00000000..f9c841a5 --- /dev/null +++ b/vendor/github.com/mitchellh/mapstructure/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2013 Mitchell Hashimoto + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/github.com/mitchellh/mapstructure/README.md b/vendor/github.com/mitchellh/mapstructure/README.md new file mode 100644 index 00000000..0018dc7d --- /dev/null +++ b/vendor/github.com/mitchellh/mapstructure/README.md @@ -0,0 +1,46 @@ +# mapstructure [![Godoc](https://godoc.org/github.com/mitchellh/mapstructure?status.svg)](https://godoc.org/github.com/mitchellh/mapstructure) + +mapstructure is a Go library for decoding generic map values to structures +and vice versa, while providing helpful error handling. + +This library is most useful when decoding values from some data stream (JSON, +Gob, etc.) where you don't _quite_ know the structure of the underlying data +until you read a part of it. You can therefore read a `map[string]interface{}` +and use this library to decode it into the proper underlying native Go +structure. + +## Installation + +Standard `go get`: + +``` +$ go get github.com/mitchellh/mapstructure +``` + +## Usage & Example + +For usage and examples see the [Godoc](http://godoc.org/github.com/mitchellh/mapstructure). + +The `Decode` function has examples associated with it there. + +## But Why?! + +Go offers fantastic standard libraries for decoding formats such as JSON. +The standard method is to have a struct pre-created, and populate that struct +from the bytes of the encoded format. This is great, but the problem is if +you have configuration or an encoding that changes slightly depending on +specific fields. For example, consider this JSON: + +```json +{ + "type": "person", + "name": "Mitchell" +} +``` + +Perhaps we can't populate a specific structure without first reading +the "type" field from the JSON. We could always do two passes over the +decoding of the JSON (reading the "type" first, and the rest later). +However, it is much simpler to just decode this into a `map[string]interface{}` +structure, read the "type" key, then use something like this library +to decode it into the proper structure. diff --git a/vendor/github.com/mitchellh/mapstructure/decode_hooks.go b/vendor/github.com/mitchellh/mapstructure/decode_hooks.go new file mode 100644 index 00000000..1f0abc65 --- /dev/null +++ b/vendor/github.com/mitchellh/mapstructure/decode_hooks.go @@ -0,0 +1,217 @@ +package mapstructure + +import ( + "errors" + "fmt" + "net" + "reflect" + "strconv" + "strings" + "time" +) + +// typedDecodeHook takes a raw DecodeHookFunc (an interface{}) and turns +// it into the proper DecodeHookFunc type, such as DecodeHookFuncType. +func typedDecodeHook(h DecodeHookFunc) DecodeHookFunc { + // Create variables here so we can reference them with the reflect pkg + var f1 DecodeHookFuncType + var f2 DecodeHookFuncKind + + // Fill in the variables into this interface and the rest is done + // automatically using the reflect package. + potential := []interface{}{f1, f2} + + v := reflect.ValueOf(h) + vt := v.Type() + for _, raw := range potential { + pt := reflect.ValueOf(raw).Type() + if vt.ConvertibleTo(pt) { + return v.Convert(pt).Interface() + } + } + + return nil +} + +// DecodeHookExec executes the given decode hook. This should be used +// since it'll naturally degrade to the older backwards compatible DecodeHookFunc +// that took reflect.Kind instead of reflect.Type. +func DecodeHookExec( + raw DecodeHookFunc, + from reflect.Type, to reflect.Type, + data interface{}) (interface{}, error) { + switch f := typedDecodeHook(raw).(type) { + case DecodeHookFuncType: + return f(from, to, data) + case DecodeHookFuncKind: + return f(from.Kind(), to.Kind(), data) + default: + return nil, errors.New("invalid decode hook signature") + } +} + +// ComposeDecodeHookFunc creates a single DecodeHookFunc that +// automatically composes multiple DecodeHookFuncs. +// +// The composed funcs are called in order, with the result of the +// previous transformation. +func ComposeDecodeHookFunc(fs ...DecodeHookFunc) DecodeHookFunc { + return func( + f reflect.Type, + t reflect.Type, + data interface{}) (interface{}, error) { + var err error + for _, f1 := range fs { + data, err = DecodeHookExec(f1, f, t, data) + if err != nil { + return nil, err + } + + // Modify the from kind to be correct with the new data + f = nil + if val := reflect.ValueOf(data); val.IsValid() { + f = val.Type() + } + } + + return data, nil + } +} + +// StringToSliceHookFunc returns a DecodeHookFunc that converts +// string to []string by splitting on the given sep. +func StringToSliceHookFunc(sep string) DecodeHookFunc { + return func( + f reflect.Kind, + t reflect.Kind, + data interface{}) (interface{}, error) { + if f != reflect.String || t != reflect.Slice { + return data, nil + } + + raw := data.(string) + if raw == "" { + return []string{}, nil + } + + return strings.Split(raw, sep), nil + } +} + +// StringToTimeDurationHookFunc returns a DecodeHookFunc that converts +// strings to time.Duration. +func StringToTimeDurationHookFunc() DecodeHookFunc { + return func( + f reflect.Type, + t reflect.Type, + data interface{}) (interface{}, error) { + if f.Kind() != reflect.String { + return data, nil + } + if t != reflect.TypeOf(time.Duration(5)) { + return data, nil + } + + // Convert it by parsing + return time.ParseDuration(data.(string)) + } +} + +// StringToIPHookFunc returns a DecodeHookFunc that converts +// strings to net.IP +func StringToIPHookFunc() DecodeHookFunc { + return func( + f reflect.Type, + t reflect.Type, + data interface{}) (interface{}, error) { + if f.Kind() != reflect.String { + return data, nil + } + if t != reflect.TypeOf(net.IP{}) { + return data, nil + } + + // Convert it by parsing + ip := net.ParseIP(data.(string)) + if ip == nil { + return net.IP{}, fmt.Errorf("failed parsing ip %v", data) + } + + return ip, nil + } +} + +// StringToIPNetHookFunc returns a DecodeHookFunc that converts +// strings to net.IPNet +func StringToIPNetHookFunc() DecodeHookFunc { + return func( + f reflect.Type, + t reflect.Type, + data interface{}) (interface{}, error) { + if f.Kind() != reflect.String { + return data, nil + } + if t != reflect.TypeOf(net.IPNet{}) { + return data, nil + } + + // Convert it by parsing + _, net, err := net.ParseCIDR(data.(string)) + return net, err + } +} + +// StringToTimeHookFunc returns a DecodeHookFunc that converts +// strings to time.Time. +func StringToTimeHookFunc(layout string) DecodeHookFunc { + return func( + f reflect.Type, + t reflect.Type, + data interface{}) (interface{}, error) { + if f.Kind() != reflect.String { + return data, nil + } + if t != reflect.TypeOf(time.Time{}) { + return data, nil + } + + // Convert it by parsing + return time.Parse(layout, data.(string)) + } +} + +// WeaklyTypedHook is a DecodeHookFunc which adds support for weak typing to +// the decoder. +// +// Note that this is significantly different from the WeaklyTypedInput option +// of the DecoderConfig. +func WeaklyTypedHook( + f reflect.Kind, + t reflect.Kind, + data interface{}) (interface{}, error) { + dataVal := reflect.ValueOf(data) + switch t { + case reflect.String: + switch f { + case reflect.Bool: + if dataVal.Bool() { + return "1", nil + } + return "0", nil + case reflect.Float32: + return strconv.FormatFloat(dataVal.Float(), 'f', -1, 64), nil + case reflect.Int: + return strconv.FormatInt(dataVal.Int(), 10), nil + case reflect.Slice: + dataType := dataVal.Type() + elemKind := dataType.Elem().Kind() + if elemKind == reflect.Uint8 { + return string(dataVal.Interface().([]uint8)), nil + } + case reflect.Uint: + return strconv.FormatUint(dataVal.Uint(), 10), nil + } + } + + return data, nil +} diff --git a/vendor/github.com/mitchellh/mapstructure/error.go b/vendor/github.com/mitchellh/mapstructure/error.go new file mode 100644 index 00000000..47a99e5a --- /dev/null +++ b/vendor/github.com/mitchellh/mapstructure/error.go @@ -0,0 +1,50 @@ +package mapstructure + +import ( + "errors" + "fmt" + "sort" + "strings" +) + +// Error implements the error interface and can represents multiple +// errors that occur in the course of a single decode. +type Error struct { + Errors []string +} + +func (e *Error) Error() string { + points := make([]string, len(e.Errors)) + for i, err := range e.Errors { + points[i] = fmt.Sprintf("* %s", err) + } + + sort.Strings(points) + return fmt.Sprintf( + "%d error(s) decoding:\n\n%s", + len(e.Errors), strings.Join(points, "\n")) +} + +// WrappedErrors implements the errwrap.Wrapper interface to make this +// return value more useful with the errwrap and go-multierror libraries. +func (e *Error) WrappedErrors() []error { + if e == nil { + return nil + } + + result := make([]error, len(e.Errors)) + for i, e := range e.Errors { + result[i] = errors.New(e) + } + + return result +} + +func appendErrors(errors []string, err error) []string { + switch e := err.(type) { + case *Error: + return append(errors, e.Errors...) + default: + return append(errors, e.Error()) + } +} diff --git a/vendor/github.com/mitchellh/mapstructure/go.mod b/vendor/github.com/mitchellh/mapstructure/go.mod new file mode 100644 index 00000000..d2a71256 --- /dev/null +++ b/vendor/github.com/mitchellh/mapstructure/go.mod @@ -0,0 +1 @@ +module github.com/mitchellh/mapstructure diff --git a/vendor/github.com/mitchellh/mapstructure/mapstructure.go b/vendor/github.com/mitchellh/mapstructure/mapstructure.go new file mode 100644 index 00000000..256ee63f --- /dev/null +++ b/vendor/github.com/mitchellh/mapstructure/mapstructure.go @@ -0,0 +1,1149 @@ +// Package mapstructure exposes functionality to convert an arbitrary +// map[string]interface{} into a native Go structure. +// +// The Go structure can be arbitrarily complex, containing slices, +// other structs, etc. and the decoder will properly decode nested +// maps and so on into the proper structures in the native Go struct. +// See the examples to see what the decoder is capable of. +package mapstructure + +import ( + "encoding/json" + "errors" + "fmt" + "reflect" + "sort" + "strconv" + "strings" +) + +// DecodeHookFunc is the callback function that can be used for +// data transformations. See "DecodeHook" in the DecoderConfig +// struct. +// +// The type should be DecodeHookFuncType or DecodeHookFuncKind. +// Either is accepted. Types are a superset of Kinds (Types can return +// Kinds) and are generally a richer thing to use, but Kinds are simpler +// if you only need those. +// +// The reason DecodeHookFunc is multi-typed is for backwards compatibility: +// we started with Kinds and then realized Types were the better solution, +// but have a promise to not break backwards compat so we now support +// both. +type DecodeHookFunc interface{} + +// DecodeHookFuncType is a DecodeHookFunc which has complete information about +// the source and target types. +type DecodeHookFuncType func(reflect.Type, reflect.Type, interface{}) (interface{}, error) + +// DecodeHookFuncKind is a DecodeHookFunc which knows only the Kinds of the +// source and target types. +type DecodeHookFuncKind func(reflect.Kind, reflect.Kind, interface{}) (interface{}, error) + +// DecoderConfig is the configuration that is used to create a new decoder +// and allows customization of various aspects of decoding. +type DecoderConfig struct { + // DecodeHook, if set, will be called before any decoding and any + // type conversion (if WeaklyTypedInput is on). This lets you modify + // the values before they're set down onto the resulting struct. + // + // If an error is returned, the entire decode will fail with that + // error. + DecodeHook DecodeHookFunc + + // If ErrorUnused is true, then it is an error for there to exist + // keys in the original map that were unused in the decoding process + // (extra keys). + ErrorUnused bool + + // ZeroFields, if set to true, will zero fields before writing them. + // For example, a map will be emptied before decoded values are put in + // it. If this is false, a map will be merged. + ZeroFields bool + + // If WeaklyTypedInput is true, the decoder will make the following + // "weak" conversions: + // + // - bools to string (true = "1", false = "0") + // - numbers to string (base 10) + // - bools to int/uint (true = 1, false = 0) + // - strings to int/uint (base implied by prefix) + // - int to bool (true if value != 0) + // - string to bool (accepts: 1, t, T, TRUE, true, True, 0, f, F, + // FALSE, false, False. Anything else is an error) + // - empty array = empty map and vice versa + // - negative numbers to overflowed uint values (base 10) + // - slice of maps to a merged map + // - single values are converted to slices if required. Each + // element is weakly decoded. For example: "4" can become []int{4} + // if the target type is an int slice. + // + WeaklyTypedInput bool + + // Metadata is the struct that will contain extra metadata about + // the decoding. If this is nil, then no metadata will be tracked. + Metadata *Metadata + + // Result is a pointer to the struct that will contain the decoded + // value. + Result interface{} + + // The tag name that mapstructure reads for field names. This + // defaults to "mapstructure" + TagName string +} + +// A Decoder takes a raw interface value and turns it into structured +// data, keeping track of rich error information along the way in case +// anything goes wrong. Unlike the basic top-level Decode method, you can +// more finely control how the Decoder behaves using the DecoderConfig +// structure. The top-level Decode method is just a convenience that sets +// up the most basic Decoder. +type Decoder struct { + config *DecoderConfig +} + +// Metadata contains information about decoding a structure that +// is tedious or difficult to get otherwise. +type Metadata struct { + // Keys are the keys of the structure which were successfully decoded + Keys []string + + // Unused is a slice of keys that were found in the raw value but + // weren't decoded since there was no matching field in the result interface + Unused []string +} + +// Decode takes an input structure and uses reflection to translate it to +// the output structure. output must be a pointer to a map or struct. +func Decode(input interface{}, output interface{}) error { + config := &DecoderConfig{ + Metadata: nil, + Result: output, + } + + decoder, err := NewDecoder(config) + if err != nil { + return err + } + + return decoder.Decode(input) +} + +// WeakDecode is the same as Decode but is shorthand to enable +// WeaklyTypedInput. See DecoderConfig for more info. +func WeakDecode(input, output interface{}) error { + config := &DecoderConfig{ + Metadata: nil, + Result: output, + WeaklyTypedInput: true, + } + + decoder, err := NewDecoder(config) + if err != nil { + return err + } + + return decoder.Decode(input) +} + +// DecodeMetadata is the same as Decode, but is shorthand to +// enable metadata collection. See DecoderConfig for more info. +func DecodeMetadata(input interface{}, output interface{}, metadata *Metadata) error { + config := &DecoderConfig{ + Metadata: metadata, + Result: output, + } + + decoder, err := NewDecoder(config) + if err != nil { + return err + } + + return decoder.Decode(input) +} + +// WeakDecodeMetadata is the same as Decode, but is shorthand to +// enable both WeaklyTypedInput and metadata collection. See +// DecoderConfig for more info. +func WeakDecodeMetadata(input interface{}, output interface{}, metadata *Metadata) error { + config := &DecoderConfig{ + Metadata: metadata, + Result: output, + WeaklyTypedInput: true, + } + + decoder, err := NewDecoder(config) + if err != nil { + return err + } + + return decoder.Decode(input) +} + +// NewDecoder returns a new decoder for the given configuration. Once +// a decoder has been returned, the same configuration must not be used +// again. +func NewDecoder(config *DecoderConfig) (*Decoder, error) { + val := reflect.ValueOf(config.Result) + if val.Kind() != reflect.Ptr { + return nil, errors.New("result must be a pointer") + } + + val = val.Elem() + if !val.CanAddr() { + return nil, errors.New("result must be addressable (a pointer)") + } + + if config.Metadata != nil { + if config.Metadata.Keys == nil { + config.Metadata.Keys = make([]string, 0) + } + + if config.Metadata.Unused == nil { + config.Metadata.Unused = make([]string, 0) + } + } + + if config.TagName == "" { + config.TagName = "mapstructure" + } + + result := &Decoder{ + config: config, + } + + return result, nil +} + +// Decode decodes the given raw interface to the target pointer specified +// by the configuration. +func (d *Decoder) Decode(input interface{}) error { + return d.decode("", input, reflect.ValueOf(d.config.Result).Elem()) +} + +// Decodes an unknown data type into a specific reflection value. +func (d *Decoder) decode(name string, input interface{}, outVal reflect.Value) error { + var inputVal reflect.Value + if input != nil { + inputVal = reflect.ValueOf(input) + + // We need to check here if input is a typed nil. Typed nils won't + // match the "input == nil" below so we check that here. + if inputVal.Kind() == reflect.Ptr && inputVal.IsNil() { + input = nil + } + } + + if input == nil { + // If the data is nil, then we don't set anything, unless ZeroFields is set + // to true. + if d.config.ZeroFields { + outVal.Set(reflect.Zero(outVal.Type())) + + if d.config.Metadata != nil && name != "" { + d.config.Metadata.Keys = append(d.config.Metadata.Keys, name) + } + } + return nil + } + + if !inputVal.IsValid() { + // If the input value is invalid, then we just set the value + // to be the zero value. + outVal.Set(reflect.Zero(outVal.Type())) + if d.config.Metadata != nil && name != "" { + d.config.Metadata.Keys = append(d.config.Metadata.Keys, name) + } + return nil + } + + if d.config.DecodeHook != nil { + // We have a DecodeHook, so let's pre-process the input. + var err error + input, err = DecodeHookExec( + d.config.DecodeHook, + inputVal.Type(), outVal.Type(), input) + if err != nil { + return fmt.Errorf("error decoding '%s': %s", name, err) + } + } + + var err error + outputKind := getKind(outVal) + switch outputKind { + case reflect.Bool: + err = d.decodeBool(name, input, outVal) + case reflect.Interface: + err = d.decodeBasic(name, input, outVal) + case reflect.String: + err = d.decodeString(name, input, outVal) + case reflect.Int: + err = d.decodeInt(name, input, outVal) + case reflect.Uint: + err = d.decodeUint(name, input, outVal) + case reflect.Float32: + err = d.decodeFloat(name, input, outVal) + case reflect.Struct: + err = d.decodeStruct(name, input, outVal) + case reflect.Map: + err = d.decodeMap(name, input, outVal) + case reflect.Ptr: + err = d.decodePtr(name, input, outVal) + case reflect.Slice: + err = d.decodeSlice(name, input, outVal) + case reflect.Array: + err = d.decodeArray(name, input, outVal) + case reflect.Func: + err = d.decodeFunc(name, input, outVal) + default: + // If we reached this point then we weren't able to decode it + return fmt.Errorf("%s: unsupported type: %s", name, outputKind) + } + + // If we reached here, then we successfully decoded SOMETHING, so + // mark the key as used if we're tracking metainput. + if d.config.Metadata != nil && name != "" { + d.config.Metadata.Keys = append(d.config.Metadata.Keys, name) + } + + return err +} + +// This decodes a basic type (bool, int, string, etc.) and sets the +// value to "data" of that type. +func (d *Decoder) decodeBasic(name string, data interface{}, val reflect.Value) error { + if val.IsValid() && val.Elem().IsValid() { + return d.decode(name, data, val.Elem()) + } + + dataVal := reflect.ValueOf(data) + + // If the input data is a pointer, and the assigned type is the dereference + // of that exact pointer, then indirect it so that we can assign it. + // Example: *string to string + if dataVal.Kind() == reflect.Ptr && dataVal.Type().Elem() == val.Type() { + dataVal = reflect.Indirect(dataVal) + } + + if !dataVal.IsValid() { + dataVal = reflect.Zero(val.Type()) + } + + dataValType := dataVal.Type() + if !dataValType.AssignableTo(val.Type()) { + return fmt.Errorf( + "'%s' expected type '%s', got '%s'", + name, val.Type(), dataValType) + } + + val.Set(dataVal) + return nil +} + +func (d *Decoder) decodeString(name string, data interface{}, val reflect.Value) error { + dataVal := reflect.Indirect(reflect.ValueOf(data)) + dataKind := getKind(dataVal) + + converted := true + switch { + case dataKind == reflect.String: + val.SetString(dataVal.String()) + case dataKind == reflect.Bool && d.config.WeaklyTypedInput: + if dataVal.Bool() { + val.SetString("1") + } else { + val.SetString("0") + } + case dataKind == reflect.Int && d.config.WeaklyTypedInput: + val.SetString(strconv.FormatInt(dataVal.Int(), 10)) + case dataKind == reflect.Uint && d.config.WeaklyTypedInput: + val.SetString(strconv.FormatUint(dataVal.Uint(), 10)) + case dataKind == reflect.Float32 && d.config.WeaklyTypedInput: + val.SetString(strconv.FormatFloat(dataVal.Float(), 'f', -1, 64)) + case dataKind == reflect.Slice && d.config.WeaklyTypedInput, + dataKind == reflect.Array && d.config.WeaklyTypedInput: + dataType := dataVal.Type() + elemKind := dataType.Elem().Kind() + switch elemKind { + case reflect.Uint8: + var uints []uint8 + if dataKind == reflect.Array { + uints = make([]uint8, dataVal.Len(), dataVal.Len()) + for i := range uints { + uints[i] = dataVal.Index(i).Interface().(uint8) + } + } else { + uints = dataVal.Interface().([]uint8) + } + val.SetString(string(uints)) + default: + converted = false + } + default: + converted = false + } + + if !converted { + return fmt.Errorf( + "'%s' expected type '%s', got unconvertible type '%s'", + name, val.Type(), dataVal.Type()) + } + + return nil +} + +func (d *Decoder) decodeInt(name string, data interface{}, val reflect.Value) error { + dataVal := reflect.Indirect(reflect.ValueOf(data)) + dataKind := getKind(dataVal) + dataType := dataVal.Type() + + switch { + case dataKind == reflect.Int: + val.SetInt(dataVal.Int()) + case dataKind == reflect.Uint: + val.SetInt(int64(dataVal.Uint())) + case dataKind == reflect.Float32: + val.SetInt(int64(dataVal.Float())) + case dataKind == reflect.Bool && d.config.WeaklyTypedInput: + if dataVal.Bool() { + val.SetInt(1) + } else { + val.SetInt(0) + } + case dataKind == reflect.String && d.config.WeaklyTypedInput: + i, err := strconv.ParseInt(dataVal.String(), 0, val.Type().Bits()) + if err == nil { + val.SetInt(i) + } else { + return fmt.Errorf("cannot parse '%s' as int: %s", name, err) + } + case dataType.PkgPath() == "encoding/json" && dataType.Name() == "Number": + jn := data.(json.Number) + i, err := jn.Int64() + if err != nil { + return fmt.Errorf( + "error decoding json.Number into %s: %s", name, err) + } + val.SetInt(i) + default: + return fmt.Errorf( + "'%s' expected type '%s', got unconvertible type '%s'", + name, val.Type(), dataVal.Type()) + } + + return nil +} + +func (d *Decoder) decodeUint(name string, data interface{}, val reflect.Value) error { + dataVal := reflect.Indirect(reflect.ValueOf(data)) + dataKind := getKind(dataVal) + + switch { + case dataKind == reflect.Int: + i := dataVal.Int() + if i < 0 && !d.config.WeaklyTypedInput { + return fmt.Errorf("cannot parse '%s', %d overflows uint", + name, i) + } + val.SetUint(uint64(i)) + case dataKind == reflect.Uint: + val.SetUint(dataVal.Uint()) + case dataKind == reflect.Float32: + f := dataVal.Float() + if f < 0 && !d.config.WeaklyTypedInput { + return fmt.Errorf("cannot parse '%s', %f overflows uint", + name, f) + } + val.SetUint(uint64(f)) + case dataKind == reflect.Bool && d.config.WeaklyTypedInput: + if dataVal.Bool() { + val.SetUint(1) + } else { + val.SetUint(0) + } + case dataKind == reflect.String && d.config.WeaklyTypedInput: + i, err := strconv.ParseUint(dataVal.String(), 0, val.Type().Bits()) + if err == nil { + val.SetUint(i) + } else { + return fmt.Errorf("cannot parse '%s' as uint: %s", name, err) + } + default: + return fmt.Errorf( + "'%s' expected type '%s', got unconvertible type '%s'", + name, val.Type(), dataVal.Type()) + } + + return nil +} + +func (d *Decoder) decodeBool(name string, data interface{}, val reflect.Value) error { + dataVal := reflect.Indirect(reflect.ValueOf(data)) + dataKind := getKind(dataVal) + + switch { + case dataKind == reflect.Bool: + val.SetBool(dataVal.Bool()) + case dataKind == reflect.Int && d.config.WeaklyTypedInput: + val.SetBool(dataVal.Int() != 0) + case dataKind == reflect.Uint && d.config.WeaklyTypedInput: + val.SetBool(dataVal.Uint() != 0) + case dataKind == reflect.Float32 && d.config.WeaklyTypedInput: + val.SetBool(dataVal.Float() != 0) + case dataKind == reflect.String && d.config.WeaklyTypedInput: + b, err := strconv.ParseBool(dataVal.String()) + if err == nil { + val.SetBool(b) + } else if dataVal.String() == "" { + val.SetBool(false) + } else { + return fmt.Errorf("cannot parse '%s' as bool: %s", name, err) + } + default: + return fmt.Errorf( + "'%s' expected type '%s', got unconvertible type '%s'", + name, val.Type(), dataVal.Type()) + } + + return nil +} + +func (d *Decoder) decodeFloat(name string, data interface{}, val reflect.Value) error { + dataVal := reflect.Indirect(reflect.ValueOf(data)) + dataKind := getKind(dataVal) + dataType := dataVal.Type() + + switch { + case dataKind == reflect.Int: + val.SetFloat(float64(dataVal.Int())) + case dataKind == reflect.Uint: + val.SetFloat(float64(dataVal.Uint())) + case dataKind == reflect.Float32: + val.SetFloat(dataVal.Float()) + case dataKind == reflect.Bool && d.config.WeaklyTypedInput: + if dataVal.Bool() { + val.SetFloat(1) + } else { + val.SetFloat(0) + } + case dataKind == reflect.String && d.config.WeaklyTypedInput: + f, err := strconv.ParseFloat(dataVal.String(), val.Type().Bits()) + if err == nil { + val.SetFloat(f) + } else { + return fmt.Errorf("cannot parse '%s' as float: %s", name, err) + } + case dataType.PkgPath() == "encoding/json" && dataType.Name() == "Number": + jn := data.(json.Number) + i, err := jn.Float64() + if err != nil { + return fmt.Errorf( + "error decoding json.Number into %s: %s", name, err) + } + val.SetFloat(i) + default: + return fmt.Errorf( + "'%s' expected type '%s', got unconvertible type '%s'", + name, val.Type(), dataVal.Type()) + } + + return nil +} + +func (d *Decoder) decodeMap(name string, data interface{}, val reflect.Value) error { + valType := val.Type() + valKeyType := valType.Key() + valElemType := valType.Elem() + + // By default we overwrite keys in the current map + valMap := val + + // If the map is nil or we're purposely zeroing fields, make a new map + if valMap.IsNil() || d.config.ZeroFields { + // Make a new map to hold our result + mapType := reflect.MapOf(valKeyType, valElemType) + valMap = reflect.MakeMap(mapType) + } + + // Check input type and based on the input type jump to the proper func + dataVal := reflect.Indirect(reflect.ValueOf(data)) + switch dataVal.Kind() { + case reflect.Map: + return d.decodeMapFromMap(name, dataVal, val, valMap) + + case reflect.Struct: + return d.decodeMapFromStruct(name, dataVal, val, valMap) + + case reflect.Array, reflect.Slice: + if d.config.WeaklyTypedInput { + return d.decodeMapFromSlice(name, dataVal, val, valMap) + } + + fallthrough + + default: + return fmt.Errorf("'%s' expected a map, got '%s'", name, dataVal.Kind()) + } +} + +func (d *Decoder) decodeMapFromSlice(name string, dataVal reflect.Value, val reflect.Value, valMap reflect.Value) error { + // Special case for BC reasons (covered by tests) + if dataVal.Len() == 0 { + val.Set(valMap) + return nil + } + + for i := 0; i < dataVal.Len(); i++ { + err := d.decode( + fmt.Sprintf("%s[%d]", name, i), + dataVal.Index(i).Interface(), val) + if err != nil { + return err + } + } + + return nil +} + +func (d *Decoder) decodeMapFromMap(name string, dataVal reflect.Value, val reflect.Value, valMap reflect.Value) error { + valType := val.Type() + valKeyType := valType.Key() + valElemType := valType.Elem() + + // Accumulate errors + errors := make([]string, 0) + + // If the input data is empty, then we just match what the input data is. + if dataVal.Len() == 0 { + if dataVal.IsNil() { + if !val.IsNil() { + val.Set(dataVal) + } + } else { + // Set to empty allocated value + val.Set(valMap) + } + + return nil + } + + for _, k := range dataVal.MapKeys() { + fieldName := fmt.Sprintf("%s[%s]", name, k) + + // First decode the key into the proper type + currentKey := reflect.Indirect(reflect.New(valKeyType)) + if err := d.decode(fieldName, k.Interface(), currentKey); err != nil { + errors = appendErrors(errors, err) + continue + } + + // Next decode the data into the proper type + v := dataVal.MapIndex(k).Interface() + currentVal := reflect.Indirect(reflect.New(valElemType)) + if err := d.decode(fieldName, v, currentVal); err != nil { + errors = appendErrors(errors, err) + continue + } + + valMap.SetMapIndex(currentKey, currentVal) + } + + // Set the built up map to the value + val.Set(valMap) + + // If we had errors, return those + if len(errors) > 0 { + return &Error{errors} + } + + return nil +} + +func (d *Decoder) decodeMapFromStruct(name string, dataVal reflect.Value, val reflect.Value, valMap reflect.Value) error { + typ := dataVal.Type() + for i := 0; i < typ.NumField(); i++ { + // Get the StructField first since this is a cheap operation. If the + // field is unexported, then ignore it. + f := typ.Field(i) + if f.PkgPath != "" { + continue + } + + // Next get the actual value of this field and verify it is assignable + // to the map value. + v := dataVal.Field(i) + if !v.Type().AssignableTo(valMap.Type().Elem()) { + return fmt.Errorf("cannot assign type '%s' to map value field of type '%s'", v.Type(), valMap.Type().Elem()) + } + + tagValue := f.Tag.Get(d.config.TagName) + tagParts := strings.Split(tagValue, ",") + + // Determine the name of the key in the map + keyName := f.Name + if tagParts[0] != "" { + if tagParts[0] == "-" { + continue + } + keyName = tagParts[0] + } + + // If "squash" is specified in the tag, we squash the field down. + squash := false + for _, tag := range tagParts[1:] { + if tag == "squash" { + squash = true + break + } + } + if squash && v.Kind() != reflect.Struct { + return fmt.Errorf("cannot squash non-struct type '%s'", v.Type()) + } + + switch v.Kind() { + // this is an embedded struct, so handle it differently + case reflect.Struct: + x := reflect.New(v.Type()) + x.Elem().Set(v) + + vType := valMap.Type() + vKeyType := vType.Key() + vElemType := vType.Elem() + mType := reflect.MapOf(vKeyType, vElemType) + vMap := reflect.MakeMap(mType) + + err := d.decode(keyName, x.Interface(), vMap) + if err != nil { + return err + } + + if squash { + for _, k := range vMap.MapKeys() { + valMap.SetMapIndex(k, vMap.MapIndex(k)) + } + } else { + valMap.SetMapIndex(reflect.ValueOf(keyName), vMap) + } + + default: + valMap.SetMapIndex(reflect.ValueOf(keyName), v) + } + } + + if val.CanAddr() { + val.Set(valMap) + } + + return nil +} + +func (d *Decoder) decodePtr(name string, data interface{}, val reflect.Value) error { + // If the input data is nil, then we want to just set the output + // pointer to be nil as well. + isNil := data == nil + if !isNil { + switch v := reflect.Indirect(reflect.ValueOf(data)); v.Kind() { + case reflect.Chan, + reflect.Func, + reflect.Interface, + reflect.Map, + reflect.Ptr, + reflect.Slice: + isNil = v.IsNil() + } + } + if isNil { + if !val.IsNil() && val.CanSet() { + nilValue := reflect.New(val.Type()).Elem() + val.Set(nilValue) + } + + return nil + } + + // Create an element of the concrete (non pointer) type and decode + // into that. Then set the value of the pointer to this type. + valType := val.Type() + valElemType := valType.Elem() + if val.CanSet() { + realVal := val + if realVal.IsNil() || d.config.ZeroFields { + realVal = reflect.New(valElemType) + } + + if err := d.decode(name, data, reflect.Indirect(realVal)); err != nil { + return err + } + + val.Set(realVal) + } else { + if err := d.decode(name, data, reflect.Indirect(val)); err != nil { + return err + } + } + return nil +} + +func (d *Decoder) decodeFunc(name string, data interface{}, val reflect.Value) error { + // Create an element of the concrete (non pointer) type and decode + // into that. Then set the value of the pointer to this type. + dataVal := reflect.Indirect(reflect.ValueOf(data)) + if val.Type() != dataVal.Type() { + return fmt.Errorf( + "'%s' expected type '%s', got unconvertible type '%s'", + name, val.Type(), dataVal.Type()) + } + val.Set(dataVal) + return nil +} + +func (d *Decoder) decodeSlice(name string, data interface{}, val reflect.Value) error { + dataVal := reflect.Indirect(reflect.ValueOf(data)) + dataValKind := dataVal.Kind() + valType := val.Type() + valElemType := valType.Elem() + sliceType := reflect.SliceOf(valElemType) + + valSlice := val + if valSlice.IsNil() || d.config.ZeroFields { + if d.config.WeaklyTypedInput { + switch { + // Slice and array we use the normal logic + case dataValKind == reflect.Slice, dataValKind == reflect.Array: + break + + // Empty maps turn into empty slices + case dataValKind == reflect.Map: + if dataVal.Len() == 0 { + val.Set(reflect.MakeSlice(sliceType, 0, 0)) + return nil + } + // Create slice of maps of other sizes + return d.decodeSlice(name, []interface{}{data}, val) + + case dataValKind == reflect.String && valElemType.Kind() == reflect.Uint8: + return d.decodeSlice(name, []byte(dataVal.String()), val) + + // All other types we try to convert to the slice type + // and "lift" it into it. i.e. a string becomes a string slice. + default: + // Just re-try this function with data as a slice. + return d.decodeSlice(name, []interface{}{data}, val) + } + } + + // Check input type + if dataValKind != reflect.Array && dataValKind != reflect.Slice { + return fmt.Errorf( + "'%s': source data must be an array or slice, got %s", name, dataValKind) + + } + + // If the input value is empty, then don't allocate since non-nil != nil + if dataVal.Len() == 0 { + return nil + } + + // Make a new slice to hold our result, same size as the original data. + valSlice = reflect.MakeSlice(sliceType, dataVal.Len(), dataVal.Len()) + } + + // Accumulate any errors + errors := make([]string, 0) + + for i := 0; i < dataVal.Len(); i++ { + currentData := dataVal.Index(i).Interface() + for valSlice.Len() <= i { + valSlice = reflect.Append(valSlice, reflect.Zero(valElemType)) + } + currentField := valSlice.Index(i) + + fieldName := fmt.Sprintf("%s[%d]", name, i) + if err := d.decode(fieldName, currentData, currentField); err != nil { + errors = appendErrors(errors, err) + } + } + + // Finally, set the value to the slice we built up + val.Set(valSlice) + + // If there were errors, we return those + if len(errors) > 0 { + return &Error{errors} + } + + return nil +} + +func (d *Decoder) decodeArray(name string, data interface{}, val reflect.Value) error { + dataVal := reflect.Indirect(reflect.ValueOf(data)) + dataValKind := dataVal.Kind() + valType := val.Type() + valElemType := valType.Elem() + arrayType := reflect.ArrayOf(valType.Len(), valElemType) + + valArray := val + + if valArray.Interface() == reflect.Zero(valArray.Type()).Interface() || d.config.ZeroFields { + // Check input type + if dataValKind != reflect.Array && dataValKind != reflect.Slice { + if d.config.WeaklyTypedInput { + switch { + // Empty maps turn into empty arrays + case dataValKind == reflect.Map: + if dataVal.Len() == 0 { + val.Set(reflect.Zero(arrayType)) + return nil + } + + // All other types we try to convert to the array type + // and "lift" it into it. i.e. a string becomes a string array. + default: + // Just re-try this function with data as a slice. + return d.decodeArray(name, []interface{}{data}, val) + } + } + + return fmt.Errorf( + "'%s': source data must be an array or slice, got %s", name, dataValKind) + + } + if dataVal.Len() > arrayType.Len() { + return fmt.Errorf( + "'%s': expected source data to have length less or equal to %d, got %d", name, arrayType.Len(), dataVal.Len()) + + } + + // Make a new array to hold our result, same size as the original data. + valArray = reflect.New(arrayType).Elem() + } + + // Accumulate any errors + errors := make([]string, 0) + + for i := 0; i < dataVal.Len(); i++ { + currentData := dataVal.Index(i).Interface() + currentField := valArray.Index(i) + + fieldName := fmt.Sprintf("%s[%d]", name, i) + if err := d.decode(fieldName, currentData, currentField); err != nil { + errors = appendErrors(errors, err) + } + } + + // Finally, set the value to the array we built up + val.Set(valArray) + + // If there were errors, we return those + if len(errors) > 0 { + return &Error{errors} + } + + return nil +} + +func (d *Decoder) decodeStruct(name string, data interface{}, val reflect.Value) error { + dataVal := reflect.Indirect(reflect.ValueOf(data)) + + // If the type of the value to write to and the data match directly, + // then we just set it directly instead of recursing into the structure. + if dataVal.Type() == val.Type() { + val.Set(dataVal) + return nil + } + + dataValKind := dataVal.Kind() + switch dataValKind { + case reflect.Map: + return d.decodeStructFromMap(name, dataVal, val) + + case reflect.Struct: + // Not the most efficient way to do this but we can optimize later if + // we want to. To convert from struct to struct we go to map first + // as an intermediary. + m := make(map[string]interface{}) + mval := reflect.Indirect(reflect.ValueOf(&m)) + if err := d.decodeMapFromStruct(name, dataVal, mval, mval); err != nil { + return err + } + + result := d.decodeStructFromMap(name, mval, val) + return result + + default: + return fmt.Errorf("'%s' expected a map, got '%s'", name, dataVal.Kind()) + } +} + +func (d *Decoder) decodeStructFromMap(name string, dataVal, val reflect.Value) error { + dataValType := dataVal.Type() + if kind := dataValType.Key().Kind(); kind != reflect.String && kind != reflect.Interface { + return fmt.Errorf( + "'%s' needs a map with string keys, has '%s' keys", + name, dataValType.Key().Kind()) + } + + dataValKeys := make(map[reflect.Value]struct{}) + dataValKeysUnused := make(map[interface{}]struct{}) + for _, dataValKey := range dataVal.MapKeys() { + dataValKeys[dataValKey] = struct{}{} + dataValKeysUnused[dataValKey.Interface()] = struct{}{} + } + + errors := make([]string, 0) + + // This slice will keep track of all the structs we'll be decoding. + // There can be more than one struct if there are embedded structs + // that are squashed. + structs := make([]reflect.Value, 1, 5) + structs[0] = val + + // Compile the list of all the fields that we're going to be decoding + // from all the structs. + type field struct { + field reflect.StructField + val reflect.Value + } + fields := []field{} + for len(structs) > 0 { + structVal := structs[0] + structs = structs[1:] + + structType := structVal.Type() + + for i := 0; i < structType.NumField(); i++ { + fieldType := structType.Field(i) + fieldKind := fieldType.Type.Kind() + + // If "squash" is specified in the tag, we squash the field down. + squash := false + tagParts := strings.Split(fieldType.Tag.Get(d.config.TagName), ",") + for _, tag := range tagParts[1:] { + if tag == "squash" { + squash = true + break + } + } + + if squash { + if fieldKind != reflect.Struct { + errors = appendErrors(errors, + fmt.Errorf("%s: unsupported type for squash: %s", fieldType.Name, fieldKind)) + } else { + structs = append(structs, structVal.FieldByName(fieldType.Name)) + } + continue + } + + // Normal struct field, store it away + fields = append(fields, field{fieldType, structVal.Field(i)}) + } + } + + // for fieldType, field := range fields { + for _, f := range fields { + field, fieldValue := f.field, f.val + fieldName := field.Name + + tagValue := field.Tag.Get(d.config.TagName) + tagValue = strings.SplitN(tagValue, ",", 2)[0] + if tagValue != "" { + fieldName = tagValue + } + + rawMapKey := reflect.ValueOf(fieldName) + rawMapVal := dataVal.MapIndex(rawMapKey) + if !rawMapVal.IsValid() { + // Do a slower search by iterating over each key and + // doing case-insensitive search. + for dataValKey := range dataValKeys { + mK, ok := dataValKey.Interface().(string) + if !ok { + // Not a string key + continue + } + + if strings.EqualFold(mK, fieldName) { + rawMapKey = dataValKey + rawMapVal = dataVal.MapIndex(dataValKey) + break + } + } + + if !rawMapVal.IsValid() { + // There was no matching key in the map for the value in + // the struct. Just ignore. + continue + } + } + + // Delete the key we're using from the unused map so we stop tracking + delete(dataValKeysUnused, rawMapKey.Interface()) + + if !fieldValue.IsValid() { + // This should never happen + panic("field is not valid") + } + + // If we can't set the field, then it is unexported or something, + // and we just continue onwards. + if !fieldValue.CanSet() { + continue + } + + // If the name is empty string, then we're at the root, and we + // don't dot-join the fields. + if name != "" { + fieldName = fmt.Sprintf("%s.%s", name, fieldName) + } + + if err := d.decode(fieldName, rawMapVal.Interface(), fieldValue); err != nil { + errors = appendErrors(errors, err) + } + } + + if d.config.ErrorUnused && len(dataValKeysUnused) > 0 { + keys := make([]string, 0, len(dataValKeysUnused)) + for rawKey := range dataValKeysUnused { + keys = append(keys, rawKey.(string)) + } + sort.Strings(keys) + + err := fmt.Errorf("'%s' has invalid keys: %s", name, strings.Join(keys, ", ")) + errors = appendErrors(errors, err) + } + + if len(errors) > 0 { + return &Error{errors} + } + + // Add the unused keys to the list of unused keys if we're tracking metadata + if d.config.Metadata != nil { + for rawKey := range dataValKeysUnused { + key := rawKey.(string) + if name != "" { + key = fmt.Sprintf("%s.%s", name, key) + } + + d.config.Metadata.Unused = append(d.config.Metadata.Unused, key) + } + } + + return nil +} + +func getKind(val reflect.Value) reflect.Kind { + kind := val.Kind() + + switch { + case kind >= reflect.Int && kind <= reflect.Int64: + return reflect.Int + case kind >= reflect.Uint && kind <= reflect.Uint64: + return reflect.Uint + case kind >= reflect.Float32 && kind <= reflect.Float64: + return reflect.Float32 + default: + return kind + } +} diff --git a/vendor/gomodules.xyz/jsonpatch/v2/LICENSE b/vendor/gomodules.xyz/jsonpatch/v2/LICENSE new file mode 100644 index 00000000..8f71f43f --- /dev/null +++ b/vendor/gomodules.xyz/jsonpatch/v2/LICENSE @@ -0,0 +1,202 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright {yyyy} {name of copyright owner} + + 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. + diff --git a/vendor/gomodules.xyz/jsonpatch/v2/go.mod b/vendor/gomodules.xyz/jsonpatch/v2/go.mod new file mode 100644 index 00000000..b5eaf830 --- /dev/null +++ b/vendor/gomodules.xyz/jsonpatch/v2/go.mod @@ -0,0 +1,9 @@ +module gomodules.xyz/jsonpatch/v2 + +go 1.12 + +require ( + github.com/evanphx/json-patch v4.5.0+incompatible + github.com/pkg/errors v0.8.1 // indirect + github.com/stretchr/testify v1.3.0 +) diff --git a/vendor/gomodules.xyz/jsonpatch/v2/go.sum b/vendor/gomodules.xyz/jsonpatch/v2/go.sum new file mode 100644 index 00000000..d8f9ffe1 --- /dev/null +++ b/vendor/gomodules.xyz/jsonpatch/v2/go.sum @@ -0,0 +1,11 @@ +github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/evanphx/json-patch v4.5.0+incompatible h1:ouOWdg56aJriqS0huScTkVXPC5IcNrDCXZ6OoTAWu7M= +github.com/evanphx/json-patch v4.5.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= diff --git a/vendor/gomodules.xyz/jsonpatch/v2/jsonpatch.go b/vendor/gomodules.xyz/jsonpatch/v2/jsonpatch.go new file mode 100644 index 00000000..b8ae4456 --- /dev/null +++ b/vendor/gomodules.xyz/jsonpatch/v2/jsonpatch.go @@ -0,0 +1,336 @@ +package jsonpatch + +import ( + "bytes" + "encoding/json" + "fmt" + "reflect" + "strings" +) + +var errBadJSONDoc = fmt.Errorf("invalid JSON Document") + +type JsonPatchOperation = Operation + +type Operation struct { + Operation string `json:"op"` + Path string `json:"path"` + Value interface{} `json:"value,omitempty"` +} + +func (j *Operation) Json() string { + b, _ := json.Marshal(j) + return string(b) +} + +func (j *Operation) MarshalJSON() ([]byte, error) { + var b bytes.Buffer + b.WriteString("{") + b.WriteString(fmt.Sprintf(`"op":"%s"`, j.Operation)) + b.WriteString(fmt.Sprintf(`,"path":"%s"`, j.Path)) + // Consider omitting Value for non-nullable operations. + if j.Value != nil || j.Operation == "replace" || j.Operation == "add" { + v, err := json.Marshal(j.Value) + if err != nil { + return nil, err + } + b.WriteString(`,"value":`) + b.Write(v) + } + b.WriteString("}") + return b.Bytes(), nil +} + +type ByPath []Operation + +func (a ByPath) Len() int { return len(a) } +func (a ByPath) Swap(i, j int) { a[i], a[j] = a[j], a[i] } +func (a ByPath) Less(i, j int) bool { return a[i].Path < a[j].Path } + +func NewOperation(op, path string, value interface{}) Operation { + return Operation{Operation: op, Path: path, Value: value} +} + +// CreatePatch creates a patch as specified in http://jsonpatch.com/ +// +// 'a' is original, 'b' is the modified document. Both are to be given as json encoded content. +// The function will return an array of JsonPatchOperations +// +// An error will be returned if any of the two documents are invalid. +func CreatePatch(a, b []byte) ([]Operation, error) { + var aI interface{} + var bI interface{} + err := json.Unmarshal(a, &aI) + if err != nil { + return nil, errBadJSONDoc + } + err = json.Unmarshal(b, &bI) + if err != nil { + return nil, errBadJSONDoc + } + return handleValues(aI, bI, "", []Operation{}) +} + +// Returns true if the values matches (must be json types) +// The types of the values must match, otherwise it will always return false +// If two map[string]interface{} are given, all elements must match. +func matchesValue(av, bv interface{}) bool { + if reflect.TypeOf(av) != reflect.TypeOf(bv) { + return false + } + switch at := av.(type) { + case string: + bt, ok := bv.(string) + if ok && bt == at { + return true + } + case float64: + bt, ok := bv.(float64) + if ok && bt == at { + return true + } + case bool: + bt, ok := bv.(bool) + if ok && bt == at { + return true + } + case map[string]interface{}: + bt, ok := bv.(map[string]interface{}) + if !ok { + return false + } + for key := range at { + if !matchesValue(at[key], bt[key]) { + return false + } + } + for key := range bt { + if !matchesValue(at[key], bt[key]) { + return false + } + } + return true + case []interface{}: + bt, ok := bv.([]interface{}) + if !ok { + return false + } + if len(bt) != len(at) { + return false + } + for key := range at { + if !matchesValue(at[key], bt[key]) { + return false + } + } + for key := range bt { + if !matchesValue(at[key], bt[key]) { + return false + } + } + return true + } + return false +} + +// From http://tools.ietf.org/html/rfc6901#section-4 : +// +// Evaluation of each reference token begins by decoding any escaped +// character sequence. This is performed by first transforming any +// occurrence of the sequence '~1' to '/', and then transforming any +// occurrence of the sequence '~0' to '~'. +// TODO decode support: +// var rfc6901Decoder = strings.NewReplacer("~1", "/", "~0", "~") + +var rfc6901Encoder = strings.NewReplacer("~", "~0", "/", "~1") + +func makePath(path string, newPart interface{}) string { + key := rfc6901Encoder.Replace(fmt.Sprintf("%v", newPart)) + if path == "" { + return "/" + key + } + if strings.HasSuffix(path, "/") { + return path + key + } + return path + "/" + key +} + +// diff returns the (recursive) difference between a and b as an array of JsonPatchOperations. +func diff(a, b map[string]interface{}, path string, patch []Operation) ([]Operation, error) { + for key, bv := range b { + p := makePath(path, key) + av, ok := a[key] + // value was added + if !ok { + patch = append(patch, NewOperation("add", p, bv)) + continue + } + // Types are the same, compare values + var err error + patch, err = handleValues(av, bv, p, patch) + if err != nil { + return nil, err + } + } + // Now add all deleted values as nil + for key := range a { + _, found := b[key] + if !found { + p := makePath(path, key) + + patch = append(patch, NewOperation("remove", p, nil)) + } + } + return patch, nil +} + +func handleValues(av, bv interface{}, p string, patch []Operation) ([]Operation, error) { + { + at := reflect.TypeOf(av) + bt := reflect.TypeOf(bv) + if at == nil && bt == nil { + // do nothing + return patch, nil + } else if at == nil && bt != nil { + return append(patch, NewOperation("add", p, bv)), nil + } else if at != bt { + // If types have changed, replace completely (preserves null in destination) + return append(patch, NewOperation("replace", p, bv)), nil + } + } + + var err error + switch at := av.(type) { + case map[string]interface{}: + bt := bv.(map[string]interface{}) + patch, err = diff(at, bt, p, patch) + if err != nil { + return nil, err + } + case string, float64, bool: + if !matchesValue(av, bv) { + patch = append(patch, NewOperation("replace", p, bv)) + } + case []interface{}: + bt := bv.([]interface{}) + if isSimpleArray(at) && isSimpleArray(bt) { + patch = append(patch, compareEditDistance(at, bt, p)...) + } else { + n := min(len(at), len(bt)) + for i := len(at) - 1; i >= n; i-- { + patch = append(patch, NewOperation("remove", makePath(p, i), nil)) + } + for i := n; i < len(bt); i++ { + patch = append(patch, NewOperation("add", makePath(p, i), bt[i])) + } + for i := 0; i < n; i++ { + var err error + patch, err = handleValues(at[i], bt[i], makePath(p, i), patch) + if err != nil { + return nil, err + } + } + } + default: + panic(fmt.Sprintf("Unknown type:%T ", av)) + } + return patch, nil +} + +func isBasicType(a interface{}) bool { + switch a.(type) { + case string, float64, bool: + default: + return false + } + return true +} + +func isSimpleArray(a []interface{}) bool { + for i := range a { + switch a[i].(type) { + case string, float64, bool: + default: + val := reflect.ValueOf(a[i]) + if val.Kind() == reflect.Map { + for _, k := range val.MapKeys() { + av := val.MapIndex(k) + if av.Kind() == reflect.Ptr || av.Kind() == reflect.Interface { + if av.IsNil() { + continue + } + av = av.Elem() + } + if av.Kind() != reflect.String && av.Kind() != reflect.Float64 && av.Kind() != reflect.Bool { + return false + } + } + return true + } + return false + } + } + return true +} + +// https://en.wikipedia.org/wiki/Wagner%E2%80%93Fischer_algorithm +// Adapted from https://github.com/texttheater/golang-levenshtein +func compareEditDistance(s, t []interface{}, p string) []Operation { + m := len(s) + n := len(t) + + d := make([][]int, m+1) + for i := 0; i <= m; i++ { + d[i] = make([]int, n+1) + d[i][0] = i + } + for j := 0; j <= n; j++ { + d[0][j] = j + } + + for j := 1; j <= n; j++ { + for i := 1; i <= m; i++ { + if reflect.DeepEqual(s[i-1], t[j-1]) { + d[i][j] = d[i-1][j-1] // no op required + } else { + del := d[i-1][j] + 1 + add := d[i][j-1] + 1 + rep := d[i-1][j-1] + 1 + d[i][j] = min(rep, min(add, del)) + } + } + } + + return backtrace(s, t, p, m, n, d) +} + +func min(x int, y int) int { + if y < x { + return y + } + return x +} + +func backtrace(s, t []interface{}, p string, i int, j int, matrix [][]int) []Operation { + if i > 0 && matrix[i-1][j]+1 == matrix[i][j] { + op := NewOperation("remove", makePath(p, i-1), nil) + return append([]Operation{op}, backtrace(s, t, p, i-1, j, matrix)...) + } + if j > 0 && matrix[i][j-1]+1 == matrix[i][j] { + op := NewOperation("add", makePath(p, i), t[j-1]) + return append([]Operation{op}, backtrace(s, t, p, i, j-1, matrix)...) + } + if i > 0 && j > 0 && matrix[i-1][j-1]+1 == matrix[i][j] { + if isBasicType(s[0]) { + op := NewOperation("replace", makePath(p, i-1), t[j-1]) + return append([]Operation{op}, backtrace(s, t, p, i-1, j-1, matrix)...) + } + + p2, _ := handleValues(s[i-1], t[j-1], makePath(p, i-1), []Operation{}) + return append(p2, backtrace(s, t, p, i-1, j-1, matrix)...) + } + if i > 0 && j > 0 && matrix[i-1][j-1] == matrix[i][j] { + return backtrace(s, t, p, i-1, j-1, matrix) + } + return []Operation{} +} diff --git a/vendor/gomodules.xyz/version/.travis.yml b/vendor/gomodules.xyz/version/.travis.yml new file mode 100644 index 00000000..b3833cb5 --- /dev/null +++ b/vendor/gomodules.xyz/version/.travis.yml @@ -0,0 +1,12 @@ +language: go + +go: + - 1.9 + - "1.10" + - 1.11 + - 1.12 + +go_import_path: gomodules.xyz/version + +script: + - go test \ No newline at end of file diff --git a/vendor/gomodules.xyz/version/LICENSE b/vendor/gomodules.xyz/version/LICENSE new file mode 100644 index 00000000..c33dcc7c --- /dev/null +++ b/vendor/gomodules.xyz/version/LICENSE @@ -0,0 +1,354 @@ +Mozilla Public License, version 2.0 + +1. Definitions + +1.1. “Contributor” + + means each individual or legal entity that creates, contributes to the + creation of, or owns Covered Software. + +1.2. “Contributor Version” + + means the combination of the Contributions of others (if any) used by a + Contributor and that particular Contributor’s Contribution. + +1.3. “Contribution” + + means Covered Software of a particular Contributor. + +1.4. “Covered Software” + + means Source Code Form to which the initial Contributor has attached the + notice in Exhibit A, the Executable Form of such Source Code Form, and + Modifications of such Source Code Form, in each case including portions + thereof. + +1.5. “Incompatible With Secondary Licenses” + means + + a. that the initial Contributor has attached the notice described in + Exhibit B to the Covered Software; or + + b. that the Covered Software was made available under the terms of version + 1.1 or earlier of the License, but not also under the terms of a + Secondary License. + +1.6. “Executable Form” + + means any form of the work other than Source Code Form. + +1.7. “Larger Work” + + means a work that combines Covered Software with other material, in a separate + file or files, that is not Covered Software. + +1.8. “License” + + means this document. + +1.9. “Licensable” + + means having the right to grant, to the maximum extent possible, whether at the + time of the initial grant or subsequently, any and all of the rights conveyed by + this License. + +1.10. “Modifications” + + means any of the following: + + a. any file in Source Code Form that results from an addition to, deletion + from, or modification of the contents of Covered Software; or + + b. any new file in Source Code Form that contains any Covered Software. + +1.11. “Patent Claims” of a Contributor + + means any patent claim(s), including without limitation, method, process, + and apparatus claims, in any patent Licensable by such Contributor that + would be infringed, but for the grant of the License, by the making, + using, selling, offering for sale, having made, import, or transfer of + either its Contributions or its Contributor Version. + +1.12. “Secondary License” + + means either the GNU General Public License, Version 2.0, the GNU Lesser + General Public License, Version 2.1, the GNU Affero General Public + License, Version 3.0, or any later versions of those licenses. + +1.13. “Source Code Form” + + means the form of the work preferred for making modifications. + +1.14. “You” (or “Your”) + + means an individual or a legal entity exercising rights under this + License. For legal entities, “You” includes any entity that controls, is + controlled by, or is under common control with You. For purposes of this + definition, “control” means (a) the power, direct or indirect, to cause + the direction or management of such entity, whether by contract or + otherwise, or (b) ownership of more than fifty percent (50%) of the + outstanding shares or beneficial ownership of such entity. + + +2. License Grants and Conditions + +2.1. Grants + + Each Contributor hereby grants You a world-wide, royalty-free, + non-exclusive license: + + a. under intellectual property rights (other than patent or trademark) + Licensable by such Contributor to use, reproduce, make available, + modify, display, perform, distribute, and otherwise exploit its + Contributions, either on an unmodified basis, with Modifications, or as + part of a Larger Work; and + + b. under Patent Claims of such Contributor to make, use, sell, offer for + sale, have made, import, and otherwise transfer either its Contributions + or its Contributor Version. + +2.2. Effective Date + + The licenses granted in Section 2.1 with respect to any Contribution become + effective for each Contribution on the date the Contributor first distributes + such Contribution. + +2.3. Limitations on Grant Scope + + The licenses granted in this Section 2 are the only rights granted under this + License. No additional rights or licenses will be implied from the distribution + or licensing of Covered Software under this License. Notwithstanding Section + 2.1(b) above, no patent license is granted by a Contributor: + + a. for any code that a Contributor has removed from Covered Software; or + + b. for infringements caused by: (i) Your and any other third party’s + modifications of Covered Software, or (ii) the combination of its + Contributions with other software (except as part of its Contributor + Version); or + + c. under Patent Claims infringed by Covered Software in the absence of its + Contributions. + + This License does not grant any rights in the trademarks, service marks, or + logos of any Contributor (except as may be necessary to comply with the + notice requirements in Section 3.4). + +2.4. Subsequent Licenses + + No Contributor makes additional grants as a result of Your choice to + distribute the Covered Software under a subsequent version of this License + (see Section 10.2) or under the terms of a Secondary License (if permitted + under the terms of Section 3.3). + +2.5. Representation + + Each Contributor represents that the Contributor believes its Contributions + are its original creation(s) or it has sufficient rights to grant the + rights to its Contributions conveyed by this License. + +2.6. Fair Use + + This License is not intended to limit any rights You have under applicable + copyright doctrines of fair use, fair dealing, or other equivalents. + +2.7. Conditions + + Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in + Section 2.1. + + +3. Responsibilities + +3.1. Distribution of Source Form + + All distribution of Covered Software in Source Code Form, including any + Modifications that You create or to which You contribute, must be under the + terms of this License. You must inform recipients that the Source Code Form + of the Covered Software is governed by the terms of this License, and how + they can obtain a copy of this License. You may not attempt to alter or + restrict the recipients’ rights in the Source Code Form. + +3.2. Distribution of Executable Form + + If You distribute Covered Software in Executable Form then: + + a. such Covered Software must also be made available in Source Code Form, + as described in Section 3.1, and You must inform recipients of the + Executable Form how they can obtain a copy of such Source Code Form by + reasonable means in a timely manner, at a charge no more than the cost + of distribution to the recipient; and + + b. You may distribute such Executable Form under the terms of this License, + or sublicense it under different terms, provided that the license for + the Executable Form does not attempt to limit or alter the recipients’ + rights in the Source Code Form under this License. + +3.3. Distribution of a Larger Work + + You may create and distribute a Larger Work under terms of Your choice, + provided that You also comply with the requirements of this License for the + Covered Software. If the Larger Work is a combination of Covered Software + with a work governed by one or more Secondary Licenses, and the Covered + Software is not Incompatible With Secondary Licenses, this License permits + You to additionally distribute such Covered Software under the terms of + such Secondary License(s), so that the recipient of the Larger Work may, at + their option, further distribute the Covered Software under the terms of + either this License or such Secondary License(s). + +3.4. Notices + + You may not remove or alter the substance of any license notices (including + copyright notices, patent notices, disclaimers of warranty, or limitations + of liability) contained within the Source Code Form of the Covered + Software, except that You may alter any license notices to the extent + required to remedy known factual inaccuracies. + +3.5. Application of Additional Terms + + You may choose to offer, and to charge a fee for, warranty, support, + indemnity or liability obligations to one or more recipients of Covered + Software. However, You may do so only on Your own behalf, and not on behalf + of any Contributor. You must make it absolutely clear that any such + warranty, support, indemnity, or liability obligation is offered by You + alone, and You hereby agree to indemnify every Contributor for any + liability incurred by such Contributor as a result of warranty, support, + indemnity or liability terms You offer. You may include additional + disclaimers of warranty and limitations of liability specific to any + jurisdiction. + +4. Inability to Comply Due to Statute or Regulation + + If it is impossible for You to comply with any of the terms of this License + with respect to some or all of the Covered Software due to statute, judicial + order, or regulation then You must: (a) comply with the terms of this License + to the maximum extent possible; and (b) describe the limitations and the code + they affect. Such description must be placed in a text file included with all + distributions of the Covered Software under this License. Except to the + extent prohibited by statute or regulation, such description must be + sufficiently detailed for a recipient of ordinary skill to be able to + understand it. + +5. Termination + +5.1. The rights granted under this License will terminate automatically if You + fail to comply with any of its terms. However, if You become compliant, + then the rights granted under this License from a particular Contributor + are reinstated (a) provisionally, unless and until such Contributor + explicitly and finally terminates Your grants, and (b) on an ongoing basis, + if such Contributor fails to notify You of the non-compliance by some + reasonable means prior to 60 days after You have come back into compliance. + Moreover, Your grants from a particular Contributor are reinstated on an + ongoing basis if such Contributor notifies You of the non-compliance by + some reasonable means, this is the first time You have received notice of + non-compliance with this License from such Contributor, and You become + compliant prior to 30 days after Your receipt of the notice. + +5.2. If You initiate litigation against any entity by asserting a patent + infringement claim (excluding declaratory judgment actions, counter-claims, + and cross-claims) alleging that a Contributor Version directly or + indirectly infringes any patent, then the rights granted to You by any and + all Contributors for the Covered Software under Section 2.1 of this License + shall terminate. + +5.3. In the event of termination under Sections 5.1 or 5.2 above, all end user + license agreements (excluding distributors and resellers) which have been + validly granted by You or Your distributors under this License prior to + termination shall survive termination. + +6. Disclaimer of Warranty + + Covered Software is provided under this License on an “as is” basis, without + warranty of any kind, either expressed, implied, or statutory, including, + without limitation, warranties that the Covered Software is free of defects, + merchantable, fit for a particular purpose or non-infringing. The entire + risk as to the quality and performance of the Covered Software is with You. + Should any Covered Software prove defective in any respect, You (not any + Contributor) assume the cost of any necessary servicing, repair, or + correction. This disclaimer of warranty constitutes an essential part of this + License. No use of any Covered Software is authorized under this License + except under this disclaimer. + +7. Limitation of Liability + + Under no circumstances and under no legal theory, whether tort (including + negligence), contract, or otherwise, shall any Contributor, or anyone who + distributes Covered Software as permitted above, be liable to You for any + direct, indirect, special, incidental, or consequential damages of any + character including, without limitation, damages for lost profits, loss of + goodwill, work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses, even if such party shall have been + informed of the possibility of such damages. This limitation of liability + shall not apply to liability for death or personal injury resulting from such + party’s negligence to the extent applicable law prohibits such limitation. + Some jurisdictions do not allow the exclusion or limitation of incidental or + consequential damages, so this exclusion and limitation may not apply to You. + +8. Litigation + + Any litigation relating to this License may be brought only in the courts of + a jurisdiction where the defendant maintains its principal place of business + and such litigation shall be governed by laws of that jurisdiction, without + reference to its conflict-of-law provisions. Nothing in this Section shall + prevent a party’s ability to bring cross-claims or counter-claims. + +9. Miscellaneous + + This License represents the complete agreement concerning the subject matter + hereof. If any provision of this License is held to be unenforceable, such + provision shall be reformed only to the extent necessary to make it + enforceable. Any law or regulation which provides that the language of a + contract shall be construed against the drafter shall not be used to construe + this License against a Contributor. + + +10. Versions of the License + +10.1. New Versions + + Mozilla Foundation is the license steward. Except as provided in Section + 10.3, no one other than the license steward has the right to modify or + publish new versions of this License. Each version will be given a + distinguishing version number. + +10.2. Effect of New Versions + + You may distribute the Covered Software under the terms of the version of + the License under which You originally received the Covered Software, or + under the terms of any subsequent version published by the license + steward. + +10.3. Modified Versions + + If you create software not governed by this License, and you want to + create a new license for such software, you may create and use a modified + version of this License if you rename the license and remove any + references to the name of the license steward (except to note that such + modified license differs from this License). + +10.4. Distributing Source Code Form that is Incompatible With Secondary Licenses + If You choose to distribute Source Code Form that is Incompatible With + Secondary Licenses under the terms of this version of the License, the + notice described in Exhibit B of this License must be attached. + +Exhibit A - Source Code Form License Notice + + This Source Code Form is subject to the + terms of the Mozilla Public License, v. + 2.0. If a copy of the MPL was not + distributed with this file, You can + obtain one at + http://mozilla.org/MPL/2.0/. + +If it is not possible or desirable to put the notice in a particular file, then +You may include the notice in a location (such as a LICENSE file in a relevant +directory) where a recipient would be likely to look for such a notice. + +You may add additional accurate notices of copyright ownership. + +Exhibit B - “Incompatible With Secondary Licenses” Notice + + This Source Code Form is “Incompatible + With Secondary Licenses”, as defined by + the Mozilla Public License, v. 2.0. + diff --git a/vendor/gomodules.xyz/version/README.md b/vendor/gomodules.xyz/version/README.md new file mode 100644 index 00000000..6f3a15ce --- /dev/null +++ b/vendor/gomodules.xyz/version/README.md @@ -0,0 +1,65 @@ +# Versioning Library for Go +[![Build Status](https://travis-ci.org/hashicorp/go-version.svg?branch=master)](https://travis-ci.org/hashicorp/go-version) + +go-version is a library for parsing versions and version constraints, +and verifying versions against a set of constraints. go-version +can sort a collection of versions properly, handles prerelease/beta +versions, can increment versions, etc. + +Versions used with go-version must follow [SemVer](http://semver.org/). + +## Installation and Usage + +Package documentation can be found on +[GoDoc](http://godoc.org/github.com/hashicorp/go-version). + +Installation can be done with a normal `go get`: + +``` +$ go get github.com/hashicorp/go-version +``` + +#### Version Parsing and Comparison + +```go +v1, err := version.NewVersion("1.2") +v2, err := version.NewVersion("1.5+metadata") + +// Comparison example. There is also GreaterThan, Equal, and just +// a simple Compare that returns an int allowing easy >=, <=, etc. +if v1.LessThan(v2) { + fmt.Printf("%s is less than %s", v1, v2) +} +``` + +#### Version Constraints + +```go +v1, err := version.NewVersion("1.2") + +// Constraints example. +constraints, err := version.NewConstraint(">= 1.0, < 1.4") +if constraints.Check(v1) { + fmt.Printf("%s satisfies constraints %s", v1, constraints) +} +``` + +#### Version Sorting + +```go +versionsRaw := []string{"1.1", "0.7.1", "1.4-beta", "1.4", "2"} +versions := make([]*version.Version, len(versionsRaw)) +for i, raw := range versionsRaw { + v, _ := version.NewVersion(raw) + versions[i] = v +} + +// After this, the versions are properly sorted +sort.Sort(version.Collection(versions)) +``` + +## Issues and Contributing + +If you find an issue with this library, please report an issue. If you'd +like, we welcome any contributions. Fork this library and submit a pull +request. diff --git a/vendor/gomodules.xyz/version/constraint.go b/vendor/gomodules.xyz/version/constraint.go new file mode 100644 index 00000000..d0557596 --- /dev/null +++ b/vendor/gomodules.xyz/version/constraint.go @@ -0,0 +1,204 @@ +package version + +import ( + "fmt" + "reflect" + "regexp" + "strings" +) + +// Constraint represents a single constraint for a version, such as +// ">= 1.0". +type Constraint struct { + f constraintFunc + check *Version + original string +} + +// Constraints is a slice of constraints. We make a custom type so that +// we can add methods to it. +type Constraints []*Constraint + +type constraintFunc func(v, c *Version) bool + +var constraintOperators map[string]constraintFunc + +var constraintRegexp *regexp.Regexp + +func init() { + constraintOperators = map[string]constraintFunc{ + "": constraintEqual, + "=": constraintEqual, + "!=": constraintNotEqual, + ">": constraintGreaterThan, + "<": constraintLessThan, + ">=": constraintGreaterThanEqual, + "<=": constraintLessThanEqual, + "~>": constraintPessimistic, + } + + ops := make([]string, 0, len(constraintOperators)) + for k := range constraintOperators { + ops = append(ops, regexp.QuoteMeta(k)) + } + + constraintRegexp = regexp.MustCompile(fmt.Sprintf( + `^\s*(%s)\s*(%s)\s*$`, + strings.Join(ops, "|"), + VersionRegexpRaw)) +} + +// NewConstraint will parse one or more constraints from the given +// constraint string. The string must be a comma-separated list of +// constraints. +func NewConstraint(v string) (Constraints, error) { + vs := strings.Split(v, ",") + result := make([]*Constraint, len(vs)) + for i, single := range vs { + c, err := parseSingle(single) + if err != nil { + return nil, err + } + + result[i] = c + } + + return Constraints(result), nil +} + +// Check tests if a version satisfies all the constraints. +func (cs Constraints) Check(v *Version) bool { + for _, c := range cs { + if !c.Check(v) { + return false + } + } + + return true +} + +// Returns the string format of the constraints +func (cs Constraints) String() string { + csStr := make([]string, len(cs)) + for i, c := range cs { + csStr[i] = c.String() + } + + return strings.Join(csStr, ",") +} + +// Check tests if a constraint is validated by the given version. +func (c *Constraint) Check(v *Version) bool { + return c.f(v, c.check) +} + +func (c *Constraint) String() string { + return c.original +} + +func parseSingle(v string) (*Constraint, error) { + matches := constraintRegexp.FindStringSubmatch(v) + if matches == nil { + return nil, fmt.Errorf("Malformed constraint: %s", v) + } + + check, err := NewVersion(matches[2]) + if err != nil { + return nil, err + } + + return &Constraint{ + f: constraintOperators[matches[1]], + check: check, + original: v, + }, nil +} + +func prereleaseCheck(v, c *Version) bool { + switch vPre, cPre := v.Prerelease() != "", c.Prerelease() != ""; { + case cPre && vPre: + // A constraint with a pre-release can only match a pre-release version + // with the same base segments. + return reflect.DeepEqual(c.Segments64(), v.Segments64()) + + case !cPre && vPre: + // A constraint without a pre-release can only match a version without a + // pre-release. + return false + + case cPre && !vPre: + // OK, except with the pessimistic operator + case !cPre && !vPre: + // OK + } + return true +} + +//------------------------------------------------------------------- +// Constraint functions +//------------------------------------------------------------------- + +func constraintEqual(v, c *Version) bool { + return v.Equal(c) +} + +func constraintNotEqual(v, c *Version) bool { + return !v.Equal(c) +} + +func constraintGreaterThan(v, c *Version) bool { + return prereleaseCheck(v, c) && v.Compare(c) == 1 +} + +func constraintLessThan(v, c *Version) bool { + return prereleaseCheck(v, c) && v.Compare(c) == -1 +} + +func constraintGreaterThanEqual(v, c *Version) bool { + return prereleaseCheck(v, c) && v.Compare(c) >= 0 +} + +func constraintLessThanEqual(v, c *Version) bool { + return prereleaseCheck(v, c) && v.Compare(c) <= 0 +} + +func constraintPessimistic(v, c *Version) bool { + // Using a pessimistic constraint with a pre-release, restricts versions to pre-releases + if !prereleaseCheck(v, c) || (c.Prerelease() != "" && v.Prerelease() == "") { + return false + } + + // If the version being checked is naturally less than the constraint, then there + // is no way for the version to be valid against the constraint + if v.LessThan(c) { + return false + } + // We'll use this more than once, so grab the length now so it's a little cleaner + // to write the later checks + cs := len(c.segments) + + // If the version being checked has less specificity than the constraint, then there + // is no way for the version to be valid against the constraint + if cs > len(v.segments) { + return false + } + + // Check the segments in the constraint against those in the version. If the version + // being checked, at any point, does not have the same values in each index of the + // constraints segments, then it cannot be valid against the constraint. + for i := 0; i < c.si-1; i++ { + if v.segments[i] != c.segments[i] { + return false + } + } + + // Check the last part of the segment in the constraint. If the version segment at + // this index is less than the constraints segment at this index, then it cannot + // be valid against the constraint + if c.segments[cs-1] > v.segments[cs-1] { + return false + } + + // If nothing has rejected the version by now, it's valid + return true +} diff --git a/vendor/gomodules.xyz/version/go.mod b/vendor/gomodules.xyz/version/go.mod new file mode 100644 index 00000000..59b8cf03 --- /dev/null +++ b/vendor/gomodules.xyz/version/go.mod @@ -0,0 +1,3 @@ +module gomodules.xyz/version + +go 1.12 diff --git a/vendor/gomodules.xyz/version/mutator.go b/vendor/gomodules.xyz/version/mutator.go new file mode 100644 index 00000000..c3777949 --- /dev/null +++ b/vendor/gomodules.xyz/version/mutator.go @@ -0,0 +1,65 @@ +package version + +type Mutator struct { + *Version +} + +func (m *Mutator) ResetMetadata() *Mutator { + m.metadata = "" + return m +} + +func (m *Mutator) SetMetadata(md string) *Mutator { + m.metadata = md + return m +} + +func (m *Mutator) ResetPrerelease() *Mutator { + m.pre = "" + return m +} + +func (m *Mutator) SetPrerelease(id string) *Mutator { + m.pre = id + return m +} + +func (m *Mutator) ResetPatch() *Mutator { + m.pre = "" + m.segments[2] = 0 + return m +} + +func (m *Mutator) NextPatch() *Mutator { + if m.pre != "" { + m.pre = "" + } else { + m.segments[2]++ + } + return m +} + +func (m *Mutator) NextMinor() *Mutator { + if m.pre != "" { + m.pre = "" + } else { + m.segments[1]++ + m.segments[2] = 0 + } + return m +} + +func (m *Mutator) NextMajor() *Mutator { + if m.pre != "" { + m.pre = "" + } else { + m.segments[0]++ + m.segments[1] = 0 + m.segments[2] = 0 + } + return m +} + +func (m *Mutator) Done() *Version { + return m.Version +} diff --git a/vendor/gomodules.xyz/version/serialization.go b/vendor/gomodules.xyz/version/serialization.go new file mode 100644 index 00000000..23ec14f2 --- /dev/null +++ b/vendor/gomodules.xyz/version/serialization.go @@ -0,0 +1,56 @@ +package version + +import ( + "bytes" + "encoding/json" +) + +// UnmarshalJSON implements the json.Unmarshaller interface. +func (v *Version) UnmarshalJSON(value []byte) error { + var str string + err := json.Unmarshal(value, &str) + if err != nil { + return err + } + vj, err := NewVersion(str) + if err != nil { + return err + } + *v = *vj + return nil +} + +// MarshalJSON implements the json.Marshaller interface. +func (v Version) MarshalJSON() ([]byte, error) { + var buf bytes.Buffer + e := json.NewEncoder(&buf) + e.SetEscapeHTML(false) + err := e.Encode(v.String()) + // https://stackoverflow.com/a/36320146/244009 + return bytes.TrimSpace(buf.Bytes()), err +} + +// UnmarshalJSON implements the json.Unmarshaller interface. +func (c *Constraints) UnmarshalJSON(value []byte) error { + var str string + + err := json.Unmarshal(value, &str) + if err != nil { + return err + } + cj, err := NewConstraint(str) + if err != nil { + return err + } + *c = cj + return nil +} + +// MarshalJSON implements the json.Marshaller interface. +func (c Constraints) MarshalJSON() ([]byte, error) { + var buf bytes.Buffer + e := json.NewEncoder(&buf) + e.SetEscapeHTML(false) + err := e.Encode(c.String()) + return bytes.TrimSpace(buf.Bytes()), err +} diff --git a/vendor/gomodules.xyz/version/version.go b/vendor/gomodules.xyz/version/version.go new file mode 100644 index 00000000..fe568756 --- /dev/null +++ b/vendor/gomodules.xyz/version/version.go @@ -0,0 +1,418 @@ +package version + +import ( + "bytes" + "fmt" + "reflect" + "regexp" + "strconv" + "strings" +) + +// The compiled regular expression used to test the validity of a version. +var ( + versionRegexp *regexp.Regexp + semverRegexp *regexp.Regexp +) + +// The raw regular expression string used for testing the validity +// of a version. +const ( + VersionRegexpRaw string = `v?([0-9]+(\.[0-9]+)*?)` + + `(-([0-9]+[0-9A-Za-z\-~]*(\.[0-9A-Za-z\-~]+)*)|(-?([A-Za-z\-~]+[0-9A-Za-z\-~]*(\.[0-9A-Za-z\-~]+)*)))?` + + `(\+([0-9A-Za-z\-~]+(\.[0-9A-Za-z\-~]+)*))?` + + `?` + + // SemverRegexpRaw requires a separator between version and prerelease + SemverRegexpRaw string = `v?([0-9]+(\.[0-9]+)*?)` + + `(-([0-9]+[0-9A-Za-z\-~]*(\.[0-9A-Za-z\-~]+)*)|(-([A-Za-z\-~]+[0-9A-Za-z\-~]*(\.[0-9A-Za-z\-~]+)*)))?` + + `(\+([0-9A-Za-z\-~]+(\.[0-9A-Za-z\-~]+)*))?` + + `?` +) + +// Version represents a single version. +type Version struct { + metadata string + pre string + segments []int64 + si int + original string +} + +func init() { + versionRegexp = regexp.MustCompile("^" + VersionRegexpRaw + "$") + semverRegexp = regexp.MustCompile("^" + SemverRegexpRaw + "$") +} + +// NewVersion parses the given version and returns a new +// Version. +func NewVersion(v string) (*Version, error) { + return newVersion(v, versionRegexp) +} + +// NewSemver parses the given version and returns a new +// Version that adheres strictly to SemVer specs +// https://semver.org/ +func NewSemver(v string) (*Version, error) { + return newVersion(v, semverRegexp) +} + +func newVersion(v string, pattern *regexp.Regexp) (*Version, error) { + matches := pattern.FindStringSubmatch(v) + if matches == nil { + return nil, fmt.Errorf("Malformed version: %s", v) + } + segmentsStr := strings.Split(matches[1], ".") + segments := make([]int64, len(segmentsStr)) + si := 0 + for i, str := range segmentsStr { + val, err := strconv.ParseInt(str, 10, 64) + if err != nil { + return nil, fmt.Errorf( + "Error parsing version: %s", err) + } + + segments[i] = int64(val) + si++ + } + + // Even though we could support more than three segments, if we + // got less than three, pad it with 0s. This is to cover the basic + // default usecase of semver, which is MAJOR.MINOR.PATCH at the minimum + for i := len(segments); i < 3; i++ { + segments = append(segments, 0) + } + + pre := matches[7] + if pre == "" { + pre = matches[4] + } + + return &Version{ + metadata: matches[10], + pre: pre, + segments: segments, + si: si, + original: v, + }, nil +} + +// Must is a helper that wraps a call to a function returning (*Version, error) +// and panics if error is non-nil. +func Must(v *Version, err error) *Version { + if err != nil { + panic(err) + } + + return v +} + +// Compare compares this version to another version. This +// returns -1, 0, or 1 if this version is smaller, equal, +// or larger than the other version, respectively. +// +// If you want boolean results, use the LessThan, Equal, +// GreaterThan, GreaterThanOrEqual or LessThanOrEqual methods. +func (v *Version) Compare(other *Version) int { + // A quick, efficient equality check + if v.String() == other.String() { + return 0 + } + + segmentsSelf := v.Segments64() + segmentsOther := other.Segments64() + + // If the segments are the same, we must compare on prerelease info + if reflect.DeepEqual(segmentsSelf, segmentsOther) { + preSelf := v.Prerelease() + preOther := other.Prerelease() + if preSelf == "" && preOther == "" { + return 0 + } + if preSelf == "" { + return 1 + } + if preOther == "" { + return -1 + } + + return comparePrereleases(preSelf, preOther) + } + + // Get the highest specificity (hS), or if they're equal, just use segmentSelf length + lenSelf := len(segmentsSelf) + lenOther := len(segmentsOther) + hS := lenSelf + if lenSelf < lenOther { + hS = lenOther + } + // Compare the segments + // Because a constraint could have more/less specificity than the version it's + // checking, we need to account for a lopsided or jagged comparison + for i := 0; i < hS; i++ { + if i > lenSelf-1 { + // This means Self had the lower specificity + // Check to see if the remaining segments in Other are all zeros + if !allZero(segmentsOther[i:]) { + // if not, it means that Other has to be greater than Self + return -1 + } + break + } else if i > lenOther-1 { + // this means Other had the lower specificity + // Check to see if the remaining segments in Self are all zeros - + if !allZero(segmentsSelf[i:]) { + //if not, it means that Self has to be greater than Other + return 1 + } + break + } + lhs := segmentsSelf[i] + rhs := segmentsOther[i] + if lhs == rhs { + continue + } else if lhs < rhs { + return -1 + } + // Otherwis, rhs was > lhs, they're not equal + return 1 + } + + // if we got this far, they're equal + return 0 +} + +func allZero(segs []int64) bool { + for _, s := range segs { + if s != 0 { + return false + } + } + return true +} + +func comparePart(preSelf string, preOther string) int { + if preSelf == preOther { + return 0 + } + + var selfInt int64 + selfNumeric := true + selfInt, err := strconv.ParseInt(preSelf, 10, 64) + if err != nil { + selfNumeric = false + } + + var otherInt int64 + otherNumeric := true + otherInt, err = strconv.ParseInt(preOther, 10, 64) + if err != nil { + otherNumeric = false + } + + // if a part is empty, we use the other to decide + if preSelf == "" { + if otherNumeric { + return -1 + } + return 1 + } + + if preOther == "" { + if selfNumeric { + return 1 + } + return -1 + } + + if selfNumeric && !otherNumeric { + return -1 + } else if !selfNumeric && otherNumeric { + return 1 + } else if !selfNumeric && !otherNumeric && preSelf > preOther { + return 1 + } else if selfInt > otherInt { + return 1 + } + + return -1 +} + +func comparePrereleases(v string, other string) int { + // the same pre release! + if v == other { + return 0 + } + + // split both pre releases for analyse their parts + selfPreReleaseMeta := strings.Split(v, ".") + otherPreReleaseMeta := strings.Split(other, ".") + + selfPreReleaseLen := len(selfPreReleaseMeta) + otherPreReleaseLen := len(otherPreReleaseMeta) + + biggestLen := otherPreReleaseLen + if selfPreReleaseLen > otherPreReleaseLen { + biggestLen = selfPreReleaseLen + } + + // loop for parts to find the first difference + for i := 0; i < biggestLen; i = i + 1 { + partSelfPre := "" + if i < selfPreReleaseLen { + partSelfPre = selfPreReleaseMeta[i] + } + + partOtherPre := "" + if i < otherPreReleaseLen { + partOtherPre = otherPreReleaseMeta[i] + } + + compare := comparePart(partSelfPre, partOtherPre) + // if parts are equals, continue the loop + if compare != 0 { + return compare + } + } + + return 0 +} + +// Equal tests if two versions are equal. +func (v *Version) Equal(o *Version) bool { + return v.Compare(o) == 0 +} + +// GreaterThan tests if this version is greater than another version. +func (v *Version) GreaterThan(o *Version) bool { + return v.Compare(o) > 0 +} + +// GreaterThanOrEqual tests if this version is greater than or equal to another version. +func (v *Version) GreaterThanOrEqual(o *Version) bool { + return v.Compare(o) >= 0 +} + +// LessThan tests if this version is less than another version. +func (v *Version) LessThan(o *Version) bool { + return v.Compare(o) < 0 +} + +// LessThanOrEqual tests if this version is less than or equal to another version. +func (v *Version) LessThanOrEqual(o *Version) bool { + return v.Compare(o) <= 0 +} + +// Metadata returns any metadata that was part of the version +// string. +// +// Metadata is anything that comes after the "+" in the version. +// For example, with "1.2.3+beta", the metadata is "beta". +func (v *Version) Metadata() string { + return v.metadata +} + +// Prerelease returns any prerelease data that is part of the version, +// or blank if there is no prerelease data. +// +// Prerelease information is anything that comes after the "-" in the +// version (but before any metadata). For example, with "1.2.3-beta", +// the prerelease information is "beta". +func (v *Version) Prerelease() string { + return v.pre +} + +// Segments returns the numeric segments of the version as a slice of ints. +// +// This excludes any metadata or pre-release information. For example, +// for a version "1.2.3-beta", segments will return a slice of +// 1, 2, 3. +func (v *Version) Segments() []int { + segmentSlice := make([]int, len(v.segments)) + for i, v := range v.segments { + segmentSlice[i] = int(v) + } + return segmentSlice +} + +// Segments64 returns the numeric segments of the version as a slice of int64s. +// +// This excludes any metadata or pre-release information. For example, +// for a version "1.2.3-beta", segments will return a slice of +// 1, 2, 3. +func (v *Version) Segments64() []int64 { + result := make([]int64, len(v.segments)) + copy(result, v.segments) + return result +} + +// String returns the full version string included pre-release +// and metadata information. +// +// This value is rebuilt according to the parsed segments and other +// information. Therefore, ambiguities in the version string such as +// prefixed zeroes (1.04.0 => 1.4.0), `v` prefix (v1.0.0 => 1.0.0), and +// missing parts (1.0 => 1.0.0) will be made into a canonicalized form +// as shown in the parenthesized examples. +func (v *Version) String() string { + var buf bytes.Buffer + fmtParts := make([]string, len(v.segments)) + for i, s := range v.segments { + // We can ignore err here since we've pre-parsed the values in segments + str := strconv.FormatInt(s, 10) + fmtParts[i] = str + } + fmt.Fprintf(&buf, strings.Join(fmtParts, ".")) + if v.pre != "" { + fmt.Fprintf(&buf, "-%s", v.pre) + } + if v.metadata != "" { + fmt.Fprintf(&buf, "+%s", v.metadata) + } + + return buf.String() +} + +// Original returns the original parsed version as-is, including any +// potential whitespace, `v` prefix, etc. +func (v *Version) Original() string { + return v.original +} + +func (v *Version) Clone() *Version { + return &Version{ + metadata: v.metadata, + pre: v.pre, + segments: append([]int64(nil), v.segments...), + si: v.si, + original: v.original, + } +} + +func (v *Version) ToMutator() *Mutator { + return &Mutator{Version: v} +} + +// Major returns major version number of this Version object +func (v *Version) Major() int64 { + if len(v.segments) >= 1 { + return v.segments[0] + } + return 0 +} + +// Minor returns minor version number of this Version object +func (v *Version) Minor() int64 { + if len(v.segments) >= 2 { + return v.segments[1] + } + return 0 +} + +// Patch returns patch version number of this Version object +func (v *Version) Patch() int64 { + if len(v.segments) >= 3 { + return v.segments[2] + } + return 0 +} diff --git a/vendor/gomodules.xyz/version/version_collection.go b/vendor/gomodules.xyz/version/version_collection.go new file mode 100644 index 00000000..cc888d43 --- /dev/null +++ b/vendor/gomodules.xyz/version/version_collection.go @@ -0,0 +1,17 @@ +package version + +// Collection is a type that implements the sort.Interface interface +// so that versions can be sorted. +type Collection []*Version + +func (v Collection) Len() int { + return len(v) +} + +func (v Collection) Less(i, j int) bool { + return v[i].LessThan(v[j]) +} + +func (v Collection) Swap(i, j int) { + v[i], v[j] = v[j], v[i] +} diff --git a/vendor/k8s.io/api/core/v1/types.go b/vendor/k8s.io/api/core/v1/types.go index b61a86ab..3b780a3e 100644 --- a/vendor/k8s.io/api/core/v1/types.go +++ b/vendor/k8s.io/api/core/v1/types.go @@ -1758,6 +1758,7 @@ type ContainerPort struct { // Protocol for port. Must be UDP, TCP, or SCTP. // Defaults to "TCP". // +optional + // +kubebuilder:default=TCP Protocol Protocol `json:"protocol,omitempty" protobuf:"bytes,4,opt,name=protocol,casttype=Protocol"` // What host IP to bind the external port to. // +optional diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/clientset.go b/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/clientset.go new file mode 100644 index 00000000..74aca8f5 --- /dev/null +++ b/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/clientset.go @@ -0,0 +1,111 @@ +/* +Copyright 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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package clientset + +import ( + "fmt" + + apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1" + apiextensionsv1beta1 "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1beta1" + discovery "k8s.io/client-go/discovery" + rest "k8s.io/client-go/rest" + flowcontrol "k8s.io/client-go/util/flowcontrol" +) + +type Interface interface { + Discovery() discovery.DiscoveryInterface + ApiextensionsV1beta1() apiextensionsv1beta1.ApiextensionsV1beta1Interface + ApiextensionsV1() apiextensionsv1.ApiextensionsV1Interface +} + +// Clientset contains the clients for groups. Each group has exactly one +// version included in a Clientset. +type Clientset struct { + *discovery.DiscoveryClient + apiextensionsV1beta1 *apiextensionsv1beta1.ApiextensionsV1beta1Client + apiextensionsV1 *apiextensionsv1.ApiextensionsV1Client +} + +// ApiextensionsV1beta1 retrieves the ApiextensionsV1beta1Client +func (c *Clientset) ApiextensionsV1beta1() apiextensionsv1beta1.ApiextensionsV1beta1Interface { + return c.apiextensionsV1beta1 +} + +// ApiextensionsV1 retrieves the ApiextensionsV1Client +func (c *Clientset) ApiextensionsV1() apiextensionsv1.ApiextensionsV1Interface { + return c.apiextensionsV1 +} + +// Discovery retrieves the DiscoveryClient +func (c *Clientset) Discovery() discovery.DiscoveryInterface { + if c == nil { + return nil + } + return c.DiscoveryClient +} + +// NewForConfig creates a new Clientset for the given config. +// If config's RateLimiter is not set and QPS and Burst are acceptable, +// NewForConfig will generate a rate-limiter in configShallowCopy. +func NewForConfig(c *rest.Config) (*Clientset, error) { + configShallowCopy := *c + if configShallowCopy.RateLimiter == nil && configShallowCopy.QPS > 0 { + if configShallowCopy.Burst <= 0 { + return nil, fmt.Errorf("burst is required to be greater than 0 when RateLimiter is not set and QPS is set to greater than 0") + } + configShallowCopy.RateLimiter = flowcontrol.NewTokenBucketRateLimiter(configShallowCopy.QPS, configShallowCopy.Burst) + } + var cs Clientset + var err error + cs.apiextensionsV1beta1, err = apiextensionsv1beta1.NewForConfig(&configShallowCopy) + if err != nil { + return nil, err + } + cs.apiextensionsV1, err = apiextensionsv1.NewForConfig(&configShallowCopy) + if err != nil { + return nil, err + } + + cs.DiscoveryClient, err = discovery.NewDiscoveryClientForConfig(&configShallowCopy) + if err != nil { + return nil, err + } + return &cs, nil +} + +// NewForConfigOrDie creates a new Clientset for the given config and +// panics if there is an error in the config. +func NewForConfigOrDie(c *rest.Config) *Clientset { + var cs Clientset + cs.apiextensionsV1beta1 = apiextensionsv1beta1.NewForConfigOrDie(c) + cs.apiextensionsV1 = apiextensionsv1.NewForConfigOrDie(c) + + cs.DiscoveryClient = discovery.NewDiscoveryClientForConfigOrDie(c) + return &cs +} + +// New creates a new Clientset for the given RESTClient. +func New(c rest.Interface) *Clientset { + var cs Clientset + cs.apiextensionsV1beta1 = apiextensionsv1beta1.New(c) + cs.apiextensionsV1 = apiextensionsv1.New(c) + + cs.DiscoveryClient = discovery.NewDiscoveryClient(c) + return &cs +} diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/doc.go b/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/doc.go new file mode 100644 index 00000000..ee865e56 --- /dev/null +++ b/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/doc.go @@ -0,0 +1,20 @@ +/* +Copyright 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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +// This package has the automatically generated clientset. +package clientset diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/scheme/doc.go b/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/scheme/doc.go new file mode 100644 index 00000000..7dc37561 --- /dev/null +++ b/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/scheme/doc.go @@ -0,0 +1,20 @@ +/* +Copyright 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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +// This package contains the scheme of the automatically generated clientset. +package scheme diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/scheme/register.go b/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/scheme/register.go new file mode 100644 index 00000000..144c2066 --- /dev/null +++ b/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/scheme/register.go @@ -0,0 +1,58 @@ +/* +Copyright 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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package scheme + +import ( + apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" + apiextensionsv1beta1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" + serializer "k8s.io/apimachinery/pkg/runtime/serializer" + utilruntime "k8s.io/apimachinery/pkg/util/runtime" +) + +var Scheme = runtime.NewScheme() +var Codecs = serializer.NewCodecFactory(Scheme) +var ParameterCodec = runtime.NewParameterCodec(Scheme) +var localSchemeBuilder = runtime.SchemeBuilder{ + apiextensionsv1beta1.AddToScheme, + apiextensionsv1.AddToScheme, +} + +// AddToScheme adds all types of this clientset into the given scheme. This allows composition +// of clientsets, like in: +// +// import ( +// "k8s.io/client-go/kubernetes" +// clientsetscheme "k8s.io/client-go/kubernetes/scheme" +// aggregatorclientsetscheme "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/scheme" +// ) +// +// kclientset, _ := kubernetes.NewForConfig(c) +// _ = aggregatorclientsetscheme.AddToScheme(clientsetscheme.Scheme) +// +// After this, RawExtensions in Kubernetes types will serialize kube-aggregator types +// correctly. +var AddToScheme = localSchemeBuilder.AddToScheme + +func init() { + v1.AddToGroupVersion(Scheme, schema.GroupVersion{Version: "v1"}) + utilruntime.Must(AddToScheme(Scheme)) +} diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1/apiextensions_client.go b/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1/apiextensions_client.go new file mode 100644 index 00000000..8823cb6a --- /dev/null +++ b/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1/apiextensions_client.go @@ -0,0 +1,89 @@ +/* +Copyright 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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v1 + +import ( + v1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" + "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/scheme" + rest "k8s.io/client-go/rest" +) + +type ApiextensionsV1Interface interface { + RESTClient() rest.Interface + CustomResourceDefinitionsGetter +} + +// ApiextensionsV1Client is used to interact with features provided by the apiextensions.k8s.io group. +type ApiextensionsV1Client struct { + restClient rest.Interface +} + +func (c *ApiextensionsV1Client) CustomResourceDefinitions() CustomResourceDefinitionInterface { + return newCustomResourceDefinitions(c) +} + +// NewForConfig creates a new ApiextensionsV1Client for the given config. +func NewForConfig(c *rest.Config) (*ApiextensionsV1Client, error) { + config := *c + if err := setConfigDefaults(&config); err != nil { + return nil, err + } + client, err := rest.RESTClientFor(&config) + if err != nil { + return nil, err + } + return &ApiextensionsV1Client{client}, nil +} + +// NewForConfigOrDie creates a new ApiextensionsV1Client for the given config and +// panics if there is an error in the config. +func NewForConfigOrDie(c *rest.Config) *ApiextensionsV1Client { + client, err := NewForConfig(c) + if err != nil { + panic(err) + } + return client +} + +// New creates a new ApiextensionsV1Client for the given RESTClient. +func New(c rest.Interface) *ApiextensionsV1Client { + return &ApiextensionsV1Client{c} +} + +func setConfigDefaults(config *rest.Config) error { + gv := v1.SchemeGroupVersion + config.GroupVersion = &gv + config.APIPath = "/apis" + config.NegotiatedSerializer = scheme.Codecs.WithoutConversion() + + if config.UserAgent == "" { + config.UserAgent = rest.DefaultKubernetesUserAgent() + } + + return nil +} + +// RESTClient returns a RESTClient that is used to communicate +// with API server by this client implementation. +func (c *ApiextensionsV1Client) RESTClient() rest.Interface { + if c == nil { + return nil + } + return c.restClient +} diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1/customresourcedefinition.go b/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1/customresourcedefinition.go new file mode 100644 index 00000000..5569b12d --- /dev/null +++ b/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1/customresourcedefinition.go @@ -0,0 +1,184 @@ +/* +Copyright 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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v1 + +import ( + "context" + "time" + + v1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" + scheme "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/scheme" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + rest "k8s.io/client-go/rest" +) + +// CustomResourceDefinitionsGetter has a method to return a CustomResourceDefinitionInterface. +// A group's client should implement this interface. +type CustomResourceDefinitionsGetter interface { + CustomResourceDefinitions() CustomResourceDefinitionInterface +} + +// CustomResourceDefinitionInterface has methods to work with CustomResourceDefinition resources. +type CustomResourceDefinitionInterface interface { + Create(ctx context.Context, customResourceDefinition *v1.CustomResourceDefinition, opts metav1.CreateOptions) (*v1.CustomResourceDefinition, error) + Update(ctx context.Context, customResourceDefinition *v1.CustomResourceDefinition, opts metav1.UpdateOptions) (*v1.CustomResourceDefinition, error) + UpdateStatus(ctx context.Context, customResourceDefinition *v1.CustomResourceDefinition, opts metav1.UpdateOptions) (*v1.CustomResourceDefinition, error) + Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error + DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error + Get(ctx context.Context, name string, opts metav1.GetOptions) (*v1.CustomResourceDefinition, error) + List(ctx context.Context, opts metav1.ListOptions) (*v1.CustomResourceDefinitionList, error) + Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.CustomResourceDefinition, err error) + CustomResourceDefinitionExpansion +} + +// customResourceDefinitions implements CustomResourceDefinitionInterface +type customResourceDefinitions struct { + client rest.Interface +} + +// newCustomResourceDefinitions returns a CustomResourceDefinitions +func newCustomResourceDefinitions(c *ApiextensionsV1Client) *customResourceDefinitions { + return &customResourceDefinitions{ + client: c.RESTClient(), + } +} + +// Get takes name of the customResourceDefinition, and returns the corresponding customResourceDefinition object, and an error if there is any. +func (c *customResourceDefinitions) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.CustomResourceDefinition, err error) { + result = &v1.CustomResourceDefinition{} + err = c.client.Get(). + Resource("customresourcedefinitions"). + Name(name). + VersionedParams(&options, scheme.ParameterCodec). + Do(ctx). + Into(result) + return +} + +// List takes label and field selectors, and returns the list of CustomResourceDefinitions that match those selectors. +func (c *customResourceDefinitions) List(ctx context.Context, opts metav1.ListOptions) (result *v1.CustomResourceDefinitionList, err error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + result = &v1.CustomResourceDefinitionList{} + err = c.client.Get(). + Resource("customresourcedefinitions"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Do(ctx). + Into(result) + return +} + +// Watch returns a watch.Interface that watches the requested customResourceDefinitions. +func (c *customResourceDefinitions) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + opts.Watch = true + return c.client.Get(). + Resource("customresourcedefinitions"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Watch(ctx) +} + +// Create takes the representation of a customResourceDefinition and creates it. Returns the server's representation of the customResourceDefinition, and an error, if there is any. +func (c *customResourceDefinitions) Create(ctx context.Context, customResourceDefinition *v1.CustomResourceDefinition, opts metav1.CreateOptions) (result *v1.CustomResourceDefinition, err error) { + result = &v1.CustomResourceDefinition{} + err = c.client.Post(). + Resource("customresourcedefinitions"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(customResourceDefinition). + Do(ctx). + Into(result) + return +} + +// Update takes the representation of a customResourceDefinition and updates it. Returns the server's representation of the customResourceDefinition, and an error, if there is any. +func (c *customResourceDefinitions) Update(ctx context.Context, customResourceDefinition *v1.CustomResourceDefinition, opts metav1.UpdateOptions) (result *v1.CustomResourceDefinition, err error) { + result = &v1.CustomResourceDefinition{} + err = c.client.Put(). + Resource("customresourcedefinitions"). + Name(customResourceDefinition.Name). + VersionedParams(&opts, scheme.ParameterCodec). + Body(customResourceDefinition). + Do(ctx). + Into(result) + return +} + +// UpdateStatus was generated because the type contains a Status member. +// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). +func (c *customResourceDefinitions) UpdateStatus(ctx context.Context, customResourceDefinition *v1.CustomResourceDefinition, opts metav1.UpdateOptions) (result *v1.CustomResourceDefinition, err error) { + result = &v1.CustomResourceDefinition{} + err = c.client.Put(). + Resource("customresourcedefinitions"). + Name(customResourceDefinition.Name). + SubResource("status"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(customResourceDefinition). + Do(ctx). + Into(result) + return +} + +// Delete takes name of the customResourceDefinition and deletes it. Returns an error if one occurs. +func (c *customResourceDefinitions) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { + return c.client.Delete(). + Resource("customresourcedefinitions"). + Name(name). + Body(&opts). + Do(ctx). + Error() +} + +// DeleteCollection deletes a collection of objects. +func (c *customResourceDefinitions) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { + var timeout time.Duration + if listOpts.TimeoutSeconds != nil { + timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second + } + return c.client.Delete(). + Resource("customresourcedefinitions"). + VersionedParams(&listOpts, scheme.ParameterCodec). + Timeout(timeout). + Body(&opts). + Do(ctx). + Error() +} + +// Patch applies the patch and returns the patched customResourceDefinition. +func (c *customResourceDefinitions) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.CustomResourceDefinition, err error) { + result = &v1.CustomResourceDefinition{} + err = c.client.Patch(pt). + Resource("customresourcedefinitions"). + Name(name). + SubResource(subresources...). + VersionedParams(&opts, scheme.ParameterCodec). + Body(data). + Do(ctx). + Into(result) + return +} diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1/doc.go b/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1/doc.go new file mode 100644 index 00000000..3af5d054 --- /dev/null +++ b/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1/doc.go @@ -0,0 +1,20 @@ +/* +Copyright 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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +// This package has the automatically generated typed clients. +package v1 diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1/generated_expansion.go b/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1/generated_expansion.go new file mode 100644 index 00000000..e594636a --- /dev/null +++ b/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1/generated_expansion.go @@ -0,0 +1,21 @@ +/* +Copyright 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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v1 + +type CustomResourceDefinitionExpansion interface{} diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1beta1/apiextensions_client.go b/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1beta1/apiextensions_client.go new file mode 100644 index 00000000..ff1ec4f2 --- /dev/null +++ b/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1beta1/apiextensions_client.go @@ -0,0 +1,89 @@ +/* +Copyright 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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v1beta1 + +import ( + v1beta1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1" + "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/scheme" + rest "k8s.io/client-go/rest" +) + +type ApiextensionsV1beta1Interface interface { + RESTClient() rest.Interface + CustomResourceDefinitionsGetter +} + +// ApiextensionsV1beta1Client is used to interact with features provided by the apiextensions.k8s.io group. +type ApiextensionsV1beta1Client struct { + restClient rest.Interface +} + +func (c *ApiextensionsV1beta1Client) CustomResourceDefinitions() CustomResourceDefinitionInterface { + return newCustomResourceDefinitions(c) +} + +// NewForConfig creates a new ApiextensionsV1beta1Client for the given config. +func NewForConfig(c *rest.Config) (*ApiextensionsV1beta1Client, error) { + config := *c + if err := setConfigDefaults(&config); err != nil { + return nil, err + } + client, err := rest.RESTClientFor(&config) + if err != nil { + return nil, err + } + return &ApiextensionsV1beta1Client{client}, nil +} + +// NewForConfigOrDie creates a new ApiextensionsV1beta1Client for the given config and +// panics if there is an error in the config. +func NewForConfigOrDie(c *rest.Config) *ApiextensionsV1beta1Client { + client, err := NewForConfig(c) + if err != nil { + panic(err) + } + return client +} + +// New creates a new ApiextensionsV1beta1Client for the given RESTClient. +func New(c rest.Interface) *ApiextensionsV1beta1Client { + return &ApiextensionsV1beta1Client{c} +} + +func setConfigDefaults(config *rest.Config) error { + gv := v1beta1.SchemeGroupVersion + config.GroupVersion = &gv + config.APIPath = "/apis" + config.NegotiatedSerializer = scheme.Codecs.WithoutConversion() + + if config.UserAgent == "" { + config.UserAgent = rest.DefaultKubernetesUserAgent() + } + + return nil +} + +// RESTClient returns a RESTClient that is used to communicate +// with API server by this client implementation. +func (c *ApiextensionsV1beta1Client) RESTClient() rest.Interface { + if c == nil { + return nil + } + return c.restClient +} diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1beta1/customresourcedefinition.go b/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1beta1/customresourcedefinition.go new file mode 100644 index 00000000..2d16ca70 --- /dev/null +++ b/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1beta1/customresourcedefinition.go @@ -0,0 +1,184 @@ +/* +Copyright 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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v1beta1 + +import ( + "context" + "time" + + v1beta1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1" + scheme "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/scheme" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + rest "k8s.io/client-go/rest" +) + +// CustomResourceDefinitionsGetter has a method to return a CustomResourceDefinitionInterface. +// A group's client should implement this interface. +type CustomResourceDefinitionsGetter interface { + CustomResourceDefinitions() CustomResourceDefinitionInterface +} + +// CustomResourceDefinitionInterface has methods to work with CustomResourceDefinition resources. +type CustomResourceDefinitionInterface interface { + Create(ctx context.Context, customResourceDefinition *v1beta1.CustomResourceDefinition, opts v1.CreateOptions) (*v1beta1.CustomResourceDefinition, error) + Update(ctx context.Context, customResourceDefinition *v1beta1.CustomResourceDefinition, opts v1.UpdateOptions) (*v1beta1.CustomResourceDefinition, error) + UpdateStatus(ctx context.Context, customResourceDefinition *v1beta1.CustomResourceDefinition, opts v1.UpdateOptions) (*v1beta1.CustomResourceDefinition, error) + Delete(ctx context.Context, name string, opts v1.DeleteOptions) error + DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error + Get(ctx context.Context, name string, opts v1.GetOptions) (*v1beta1.CustomResourceDefinition, error) + List(ctx context.Context, opts v1.ListOptions) (*v1beta1.CustomResourceDefinitionList, error) + Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1beta1.CustomResourceDefinition, err error) + CustomResourceDefinitionExpansion +} + +// customResourceDefinitions implements CustomResourceDefinitionInterface +type customResourceDefinitions struct { + client rest.Interface +} + +// newCustomResourceDefinitions returns a CustomResourceDefinitions +func newCustomResourceDefinitions(c *ApiextensionsV1beta1Client) *customResourceDefinitions { + return &customResourceDefinitions{ + client: c.RESTClient(), + } +} + +// Get takes name of the customResourceDefinition, and returns the corresponding customResourceDefinition object, and an error if there is any. +func (c *customResourceDefinitions) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1beta1.CustomResourceDefinition, err error) { + result = &v1beta1.CustomResourceDefinition{} + err = c.client.Get(). + Resource("customresourcedefinitions"). + Name(name). + VersionedParams(&options, scheme.ParameterCodec). + Do(ctx). + Into(result) + return +} + +// List takes label and field selectors, and returns the list of CustomResourceDefinitions that match those selectors. +func (c *customResourceDefinitions) List(ctx context.Context, opts v1.ListOptions) (result *v1beta1.CustomResourceDefinitionList, err error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + result = &v1beta1.CustomResourceDefinitionList{} + err = c.client.Get(). + Resource("customresourcedefinitions"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Do(ctx). + Into(result) + return +} + +// Watch returns a watch.Interface that watches the requested customResourceDefinitions. +func (c *customResourceDefinitions) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + opts.Watch = true + return c.client.Get(). + Resource("customresourcedefinitions"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Watch(ctx) +} + +// Create takes the representation of a customResourceDefinition and creates it. Returns the server's representation of the customResourceDefinition, and an error, if there is any. +func (c *customResourceDefinitions) Create(ctx context.Context, customResourceDefinition *v1beta1.CustomResourceDefinition, opts v1.CreateOptions) (result *v1beta1.CustomResourceDefinition, err error) { + result = &v1beta1.CustomResourceDefinition{} + err = c.client.Post(). + Resource("customresourcedefinitions"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(customResourceDefinition). + Do(ctx). + Into(result) + return +} + +// Update takes the representation of a customResourceDefinition and updates it. Returns the server's representation of the customResourceDefinition, and an error, if there is any. +func (c *customResourceDefinitions) Update(ctx context.Context, customResourceDefinition *v1beta1.CustomResourceDefinition, opts v1.UpdateOptions) (result *v1beta1.CustomResourceDefinition, err error) { + result = &v1beta1.CustomResourceDefinition{} + err = c.client.Put(). + Resource("customresourcedefinitions"). + Name(customResourceDefinition.Name). + VersionedParams(&opts, scheme.ParameterCodec). + Body(customResourceDefinition). + Do(ctx). + Into(result) + return +} + +// UpdateStatus was generated because the type contains a Status member. +// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). +func (c *customResourceDefinitions) UpdateStatus(ctx context.Context, customResourceDefinition *v1beta1.CustomResourceDefinition, opts v1.UpdateOptions) (result *v1beta1.CustomResourceDefinition, err error) { + result = &v1beta1.CustomResourceDefinition{} + err = c.client.Put(). + Resource("customresourcedefinitions"). + Name(customResourceDefinition.Name). + SubResource("status"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(customResourceDefinition). + Do(ctx). + Into(result) + return +} + +// Delete takes name of the customResourceDefinition and deletes it. Returns an error if one occurs. +func (c *customResourceDefinitions) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { + return c.client.Delete(). + Resource("customresourcedefinitions"). + Name(name). + Body(&opts). + Do(ctx). + Error() +} + +// DeleteCollection deletes a collection of objects. +func (c *customResourceDefinitions) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { + var timeout time.Duration + if listOpts.TimeoutSeconds != nil { + timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second + } + return c.client.Delete(). + Resource("customresourcedefinitions"). + VersionedParams(&listOpts, scheme.ParameterCodec). + Timeout(timeout). + Body(&opts). + Do(ctx). + Error() +} + +// Patch applies the patch and returns the patched customResourceDefinition. +func (c *customResourceDefinitions) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1beta1.CustomResourceDefinition, err error) { + result = &v1beta1.CustomResourceDefinition{} + err = c.client.Patch(pt). + Resource("customresourcedefinitions"). + Name(name). + SubResource(subresources...). + VersionedParams(&opts, scheme.ParameterCodec). + Body(data). + Do(ctx). + Into(result) + return +} diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1beta1/doc.go b/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1beta1/doc.go new file mode 100644 index 00000000..77110195 --- /dev/null +++ b/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1beta1/doc.go @@ -0,0 +1,20 @@ +/* +Copyright 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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +// This package has the automatically generated typed clients. +package v1beta1 diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1beta1/generated_expansion.go b/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1beta1/generated_expansion.go new file mode 100644 index 00000000..2a989d4b --- /dev/null +++ b/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1beta1/generated_expansion.go @@ -0,0 +1,21 @@ +/* +Copyright 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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v1beta1 + +type CustomResourceDefinitionExpansion interface{} diff --git a/vendor/kmodules.xyz/client-go/.gitignore b/vendor/kmodules.xyz/client-go/.gitignore new file mode 100644 index 00000000..9aab7195 --- /dev/null +++ b/vendor/kmodules.xyz/client-go/.gitignore @@ -0,0 +1,35 @@ +# Compiled Object files, Static and Dynamic libs (Shared Objects) +*.o +*.a +*.so + +# Folders +_obj +_test + +# Architecture specific extensions/prefixes +*.[568vq] +[568vq].out + +*.cgo1.go +*.cgo2.c +_cgo_defun.c +_cgo_gotypes.go +_cgo_export.* + +_testmain.go + +*.exe +*.test +*.prof +.idea/ +dist/ +**/junit.xml +**/.env +.vscode/ +coverage.txt + +/bin +/.go + +apiserver.local.config/** diff --git a/vendor/kmodules.xyz/client-go/CONTRIBUTING.md b/vendor/kmodules.xyz/client-go/CONTRIBUTING.md new file mode 100644 index 00000000..3c4dc6dd --- /dev/null +++ b/vendor/kmodules.xyz/client-go/CONTRIBUTING.md @@ -0,0 +1,37 @@ +# How to Contribute + +AppsCode projects are [Apache 2.0 licensed](LICENSE) and accept contributions via +GitHub pull requests. This document outlines some of the conventions on +development workflow, commit message formatting, contact points and other +resources to make it easier to get your contribution accepted. + +## Certificate of Origin + +By contributing to this project you agree to the Developer Certificate of +Origin (DCO). This document was created by the Linux Kernel community and is a +simple statement that you, as a contributor, have the legal right to make the +contribution. See the [DCO](DCO) file for details. + +## Developer Guide +If you find something undocumented or incorrect along the way, +please feel free to send a Pull Request. + +## Getting Help +If you have a question about Kutil or having problem using it, you can contact us on our public Slack channel. Follow [this link](https://slack.appscode.com) to get invitation to our Slack channel. + +## Bugs/Feature request +If you have found a bug with Kutil or want to request for new features, please [file an issue](https://github.com/kmodules/client-go/issues/new). + +## Contribution Flow +If you fix a bug or developed a new feature, feel free to submit a PR. In either case, please file a [Github issue]((https://github.com/kmodules/client-go/issues/new)) first, so that we can have a discussion on it. This is a rough outline of what a contributor's workflow looks like: + +- Create a topic branch from where you want to base your work (usually master). +- Make commits of logical units. +- Push your changes to a topic branch in your fork of the repository. +- Make sure the tests pass, and add any new tests as appropriate. +- Submit a pull request to the original repository. + +Thanks for your contributions! + +## Spread the word +If you have written blog post or tutorial on Kutil, please share it with us on [Twitter](https://twitter.com/AppsCodeHQ) or [Slack](https://slack.appscode.com). diff --git a/vendor/kmodules.xyz/client-go/DCO b/vendor/kmodules.xyz/client-go/DCO new file mode 100644 index 00000000..716561d5 --- /dev/null +++ b/vendor/kmodules.xyz/client-go/DCO @@ -0,0 +1,36 @@ +Developer Certificate of Origin +Version 1.1 + +Copyright (C) 2004, 2006 The Linux Foundation and its contributors. +660 York Street, Suite 102, +San Francisco, CA 94110 USA + +Everyone is permitted to copy and distribute verbatim copies of this +license document, but changing it is not allowed. + + +Developer's Certificate of Origin 1.1 + +By making a contribution to this project, I certify that: + +(a) The contribution was created in whole or in part by me and I + have the right to submit it under the open source license + indicated in the file; or + +(b) The contribution is based upon previous work that, to the best + of my knowledge, is covered under an appropriate open source + license and I have the right under that license to submit that + work with modifications, whether created in whole or in part + by me, under the same open source license (unless I am + permitted to submit under a different license), as indicated + in the file; or + +(c) The contribution was provided directly to me by some other + person who certified (a), (b) or (c) and I have not modified + it. + +(d) I understand and agree that this project and the contribution + are public and that a record of the contribution (including all + personal information I submit with it, including my sign-off) is + maintained indefinitely and may be redistributed consistent with + this project or the open source license(s) involved. diff --git a/vendor/kmodules.xyz/client-go/Makefile b/vendor/kmodules.xyz/client-go/Makefile new file mode 100644 index 00000000..4de17bf3 --- /dev/null +++ b/vendor/kmodules.xyz/client-go/Makefile @@ -0,0 +1,302 @@ +# Copyright 2019 AppsCode Inc. +# Copyright 2016 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. + +SHELL=/bin/bash -o pipefail + +GO_PKG := kmodules.xyz +REPO := $(notdir $(shell pwd)) +BIN := client-go + +# https://github.com/appscodelabs/gengo-builder +CODE_GENERATOR_IMAGE ?= appscode/gengo:release-1.18 + +# This version-strategy uses git tags to set the version string +git_branch := $(shell git rev-parse --abbrev-ref HEAD) +git_tag := $(shell git describe --exact-match --abbrev=0 2>/dev/null || echo "") +commit_hash := $(shell git rev-parse --verify HEAD) +commit_timestamp := $(shell date --date="@$$(git show -s --format=%ct)" --utc +%FT%T) + +VERSION := $(shell git describe --tags --always --dirty) +version_strategy := commit_hash +ifdef git_tag + VERSION := $(git_tag) + version_strategy := tag +else + ifeq (,$(findstring $(git_branch),master HEAD)) + ifneq (,$(patsubst release-%,,$(git_branch))) + VERSION := $(git_branch) + version_strategy := branch + endif + endif +endif + +### +### These variables should not need tweaking. +### + +SRC_DIRS := *.go admissionregistration api apiextensions apiregistration apps batch bin certificates core discovery dynamic extensions logs meta openapi policy rbac storage tools + +DOCKER_PLATFORMS := linux/amd64 linux/arm linux/arm64 +BIN_PLATFORMS := $(DOCKER_PLATFORMS) + +# Used internally. Users should pass GOOS and/or GOARCH. +OS := $(if $(GOOS),$(GOOS),$(shell go env GOOS)) +ARCH := $(if $(GOARCH),$(GOARCH),$(shell go env GOARCH)) + +BASEIMAGE_PROD ?= gcr.io/distroless/static +BASEIMAGE_DBG ?= debian:stretch + +GO_VERSION ?= 1.14 +BUILD_IMAGE ?= appscode/golang-dev:$(GO_VERSION) + +OUTBIN = bin/$(OS)_$(ARCH)/$(BIN) +ifeq ($(OS),windows) + OUTBIN = bin/$(OS)_$(ARCH)/$(BIN).exe +endif + +# Directories that we need created to build/test. +BUILD_DIRS := bin/$(OS)_$(ARCH) \ + .go/bin/$(OS)_$(ARCH) \ + .go/cache \ + hack/config \ + $(HOME)/.credentials \ + $(HOME)/.kube \ + $(HOME)/.minikube + +DOCKER_REPO_ROOT := /go/src/$(GO_PKG)/$(REPO) + +# If you want to build all binaries, see the 'all-build' rule. +# If you want to build all containers, see the 'all-container' rule. +# If you want to build AND push all containers, see the 'all-push' rule. +all: fmt build + +# For the following OS/ARCH expansions, we transform OS/ARCH into OS_ARCH +# because make pattern rules don't match with embedded '/' characters. + +build-%: + @$(MAKE) build \ + --no-print-directory \ + GOOS=$(firstword $(subst _, ,$*)) \ + GOARCH=$(lastword $(subst _, ,$*)) + +all-build: $(addprefix build-, $(subst /,_, $(BIN_PLATFORMS))) + +version: + @echo version=$(VERSION) + @echo version_strategy=$(version_strategy) + @echo git_tag=$(git_tag) + @echo git_branch=$(git_branch) + @echo commit_hash=$(commit_hash) + @echo commit_timestamp=$(commit_timestamp) + +# Generate a typed clientset +.PHONY: clientset +clientset: + @docker run --rm \ + -u $$(id -u):$$(id -g) \ + -v /tmp:/.cache \ + -v $$(pwd):$(DOCKER_REPO_ROOT) \ + -w $(DOCKER_REPO_ROOT) \ + --env HTTP_PROXY=$(HTTP_PROXY) \ + --env HTTPS_PROXY=$(HTTPS_PROXY) \ + $(CODE_GENERATOR_IMAGE) \ + deepcopy-gen \ + --go-header-file "./hack/license/go.txt" \ + --input-dirs "$(GO_PKG)/$(REPO)/api/v1" \ + --output-file-base zz_generated.deepcopy + +# Generate openapi schema +.PHONY: openapi +openapi: + @echo "Generating openapi schema" + @docker run --rm \ + -u $$(id -u):$$(id -g) \ + -v /tmp:/.cache \ + -v $$(pwd):$(DOCKER_REPO_ROOT) \ + -w $(DOCKER_REPO_ROOT) \ + --env HTTP_PROXY=$(HTTP_PROXY) \ + --env HTTPS_PROXY=$(HTTPS_PROXY) \ + $(CODE_GENERATOR_IMAGE) \ + openapi-gen \ + --v 1 --logtostderr \ + --go-header-file "./hack/license/go.txt" \ + --input-dirs "$(GO_PKG)/$(REPO)/api/v1" \ + --output-package "$(GO_PKG)/$(REPO)/api/v1" \ + --report-filename /tmp/violation_exceptions.list + +.PHONY: gen-crd-protos +gen-crd-protos: + @docker run --rm \ + -u $$(id -u):$$(id -g) \ + -v /tmp:/.cache \ + -v $$(pwd):$(DOCKER_REPO_ROOT) \ + -w $(DOCKER_REPO_ROOT) \ + --env HTTP_PROXY=$(HTTP_PROXY) \ + --env HTTPS_PROXY=$(HTTPS_PROXY) \ + $(CODE_GENERATOR_IMAGE) \ + go-to-protobuf \ + --go-header-file "./hack/license/go.txt" \ + --proto-import=$(DOCKER_REPO_ROOT)/vendor \ + --proto-import=$(DOCKER_REPO_ROOT)/third_party/protobuf \ + --apimachinery-packages=-k8s.io/apimachinery/pkg/api/resource,-k8s.io/apimachinery/pkg/apis/meta/v1,-k8s.io/apimachinery/pkg/apis/meta/v1beta1,-k8s.io/apimachinery/pkg/runtime,-k8s.io/apimachinery/pkg/runtime/schema,-k8s.io/apimachinery/pkg/util/intstr \ + --packages=-k8s.io/api/core/v1,kmodules.xyz/client-go/api/v1 + +.PHONY: gen +gen: clientset openapi gen-crd-protos + +fmt: $(BUILD_DIRS) + @docker run \ + -i \ + --rm \ + -u $$(id -u):$$(id -g) \ + -v $$(pwd):/src \ + -w /src \ + -v $$(pwd)/.go/bin/$(OS)_$(ARCH):/go/bin \ + -v $$(pwd)/.go/bin/$(OS)_$(ARCH):/go/bin/$(OS)_$(ARCH) \ + -v $$(pwd)/.go/cache:/.cache \ + --env HTTP_PROXY=$(HTTP_PROXY) \ + --env HTTPS_PROXY=$(HTTPS_PROXY) \ + $(BUILD_IMAGE) \ + /bin/bash -c " \ + REPO_PKG=$(GO_PKG)/$(REPO) \ + ./hack/fmt.sh $(SRC_DIRS) \ + " + +build: $(OUTBIN) + +.PHONY: .go/$(OUTBIN) +$(OUTBIN): $(BUILD_DIRS) + @echo "making $(OUTBIN)" + @docker run \ + -i \ + --rm \ + -u $$(id -u):$$(id -g) \ + -v $$(pwd):/src \ + -w /src \ + -v $$(pwd)/.go/bin/$(OS)_$(ARCH):/go/bin \ + -v $$(pwd)/.go/bin/$(OS)_$(ARCH):/go/bin/$(OS)_$(ARCH) \ + -v $$(pwd)/.go/cache:/.cache \ + --env HTTP_PROXY=$(HTTP_PROXY) \ + --env HTTPS_PROXY=$(HTTPS_PROXY) \ + $(BUILD_IMAGE) \ + /bin/bash -c " \ + ARCH=$(ARCH) \ + OS=$(OS) \ + VERSION=$(VERSION) \ + version_strategy=$(version_strategy) \ + git_branch=$(git_branch) \ + git_tag=$(git_tag) \ + commit_hash=$(commit_hash) \ + commit_timestamp=$(commit_timestamp) \ + ./hack/build.sh \ + " + @echo + +test: $(BUILD_DIRS) + @docker run \ + -i \ + --rm \ + -u $$(id -u):$$(id -g) \ + -v $$(pwd):/src \ + -w /src \ + -v $$(pwd)/.go/bin/$(OS)_$(ARCH):/go/bin \ + -v $$(pwd)/.go/bin/$(OS)_$(ARCH):/go/bin/$(OS)_$(ARCH) \ + -v $$(pwd)/.go/cache:/.cache \ + --env HTTP_PROXY=$(HTTP_PROXY) \ + --env HTTPS_PROXY=$(HTTPS_PROXY) \ + $(BUILD_IMAGE) \ + /bin/bash -c " \ + ARCH=$(ARCH) \ + OS=$(OS) \ + VERSION=$(VERSION) \ + ./hack/test.sh $(SRC_DIRS) \ + " + +ADDTL_LINTERS := goconst,gofmt,goimports,unparam + +.PHONY: lint +lint: $(BUILD_DIRS) + @echo "running linter" + @docker run \ + -i \ + --rm \ + -u $$(id -u):$$(id -g) \ + -v $$(pwd):/src \ + -w /src \ + -v $$(pwd)/.go/bin/$(OS)_$(ARCH):/go/bin \ + -v $$(pwd)/.go/bin/$(OS)_$(ARCH):/go/bin/$(OS)_$(ARCH) \ + -v $$(pwd)/.go/cache:/.cache \ + --env HTTP_PROXY=$(HTTP_PROXY) \ + --env HTTPS_PROXY=$(HTTPS_PROXY) \ + --env GO111MODULE=on \ + --env GOFLAGS="-mod=vendor" \ + $(BUILD_IMAGE) \ + golangci-lint run --enable $(ADDTL_LINTERS) --timeout=10m --skip-files="generated.*\.go$\" --skip-dirs-use-default + +$(BUILD_DIRS): + @mkdir -p $@ + +.PHONY: dev +dev: gen fmt push + +.PHONY: verify +verify: verify-modules verify-gen + +.PHONY: verify-modules +verify-modules: + go mod tidy + go mod vendor + @if !(git diff --exit-code HEAD); then \ + echo "go module files are out of date"; exit 1; \ + fi + +.PHONY: verify-gen +verify-gen: gen fmt + @if !(git diff --exit-code HEAD); then \ + echo "file formatting is out of date, run make gen fmt"; exit 1; \ + fi + +.PHONY: add-license +add-license: + @echo "Adding license header" + @docker run --rm \ + -u $$(id -u):$$(id -g) \ + -v /tmp:/.cache \ + -v $$(pwd):$(DOCKER_REPO_ROOT) \ + -w $(DOCKER_REPO_ROOT) \ + --env HTTP_PROXY=$(HTTP_PROXY) \ + --env HTTPS_PROXY=$(HTTPS_PROXY) \ + $(BUILD_IMAGE) \ + ltag -t "./hack/license" --excludes "vendor contrib" -v + +.PHONY: check-license +check-license: + @echo "Checking files for license header" + @docker run --rm \ + -u $$(id -u):$$(id -g) \ + -v /tmp:/.cache \ + -v $$(pwd):$(DOCKER_REPO_ROOT) \ + -w $(DOCKER_REPO_ROOT) \ + --env HTTP_PROXY=$(HTTP_PROXY) \ + --env HTTPS_PROXY=$(HTTPS_PROXY) \ + $(BUILD_IMAGE) \ + ltag -t "./hack/license" --excludes "vendor contrib" --check -v + +.PHONY: ci +ci: verify lint build test #cover + +.PHONY: clean +clean: + rm -rf .go bin diff --git a/vendor/kmodules.xyz/client-go/README.md b/vendor/kmodules.xyz/client-go/README.md new file mode 100644 index 00000000..a18fc91e --- /dev/null +++ b/vendor/kmodules.xyz/client-go/README.md @@ -0,0 +1,12 @@ +[![Go Report Card](https://goreportcard.com/badge/kmodules.xyz/client-go)](https://goreportcard.com/report/kmodules.xyz/client-go) +[![GoDoc](https://godoc.org/kmodules.xyz/client-go?status.svg "GoDoc")](https://godoc.org/kmodules.xyz/client-go) +[![Build Status](https://github.com/kmodules/client-go/workflows/CI/badge.svg)](https://github.com/kmodules/client-go/actions?workflow=CI) +[![codecov](https://codecov.io/gh/kmodules/client-go/branch/master/graph/badge.svg)](https://codecov.io/gh/kmodules/client-go) +[![Slack](https://slack.appscode.com/badge.svg)](https://slack.appscode.com) +[![Twitter](https://img.shields.io/twitter/follow/appscodehq.svg?style=social&logo=twitter&label=Follow)](https://twitter.com/intent/follow?screen_name=AppsCodeHQ) + +# client-go +Kubernetes client-go utilities. This package is a collection of helper methods for `k8s.io/client-go`. [AppsCode](https://appscode.com) develops and maintains this library and uses across their various projects. `kmodules.xyz/client-go` is not a replacement for `k8s.io/client-go`. + +## Related Libraries +- [Kubernetes webhook runtime](https://github.com/kmodules/webhook-runtime) diff --git a/vendor/kmodules.xyz/client-go/apiextensions/kubernetes.go b/vendor/kmodules.xyz/client-go/apiextensions/kubernetes.go new file mode 100644 index 00000000..166e475f --- /dev/null +++ b/vendor/kmodules.xyz/client-go/apiextensions/kubernetes.go @@ -0,0 +1,194 @@ +/* +Copyright The Kmodules 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 apiextensions + +import ( + "context" + "fmt" + "net/http" + "time" + + v1 "kmodules.xyz/client-go/apiextensions/v1" + "kmodules.xyz/client-go/apiextensions/v1beta1" + discovery_util "kmodules.xyz/client-go/discovery" + meta_util "kmodules.xyz/client-go/meta" + + "github.com/pkg/errors" + crdv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" + crdv1beta1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1" + crd_cs "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset" + kerr "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/util/wait" + "k8s.io/client-go/rest" +) + +func RegisterCRDs(client crd_cs.Interface, crds []*CustomResourceDefinition) error { + major, minor, _, _, _, err := discovery_util.GetVersionInfo(client.Discovery()) + if err != nil { + return err + } + k116OrLater := major > 1 || (major == 1 && minor >= 16) + + for _, crd := range crds { + // Use crd v1 for k8s >= 1.16, if available + // ref: https://github.com/kubernetes/kubernetes/issues/91395 + if k116OrLater && crd.V1 != nil { + _, _, err := v1.CreateOrUpdateCustomResourceDefinition( + context.TODO(), + client, + crd.V1.Name, + func(in *crdv1.CustomResourceDefinition) *crdv1.CustomResourceDefinition { + in.Labels = meta_util.MergeKeys(in.Labels, crd.V1.Labels) + in.Annotations = meta_util.MergeKeys(in.Annotations, crd.V1.Annotations) + + in.Spec = crd.V1.Spec + return in + }, + metav1.UpdateOptions{}, + ) + if err != nil { + return err + } + } else { + if crd.V1beta1 == nil { + return fmt.Errorf("missing crd v1beta1 definition") + } + + if major == 1 && minor <= 11 { + // CRD schema must only have "properties", "required" or "description" at the root if the status subresource is enabled + // xref: https://github.com/stashed/stash/issues/1007#issuecomment-570888875 + crd.V1beta1.Spec.Validation.OpenAPIV3Schema.Type = "" + } + removeDefaults(crd.V1beta1.Spec.Validation.OpenAPIV3Schema) + + _, _, err := v1beta1.CreateOrUpdateCustomResourceDefinition( + context.TODO(), + client, + crd.V1beta1.Name, + func(in *crdv1beta1.CustomResourceDefinition) *crdv1beta1.CustomResourceDefinition { + in.Labels = meta_util.MergeKeys(in.Labels, crd.V1beta1.Labels) + in.Annotations = meta_util.MergeKeys(in.Annotations, crd.V1beta1.Annotations) + + in.Spec = crd.V1beta1.Spec + return in + }, + metav1.UpdateOptions{}, + ) + if err != nil { + return err + } + } + } + return WaitForCRDReady(client.ApiextensionsV1beta1().RESTClient(), crds) +} + +func removeDefaults(schema *crdv1beta1.JSONSchemaProps) { + if schema == nil { + return + } + + schema.Default = nil + + if schema.Items != nil { + removeDefaults(schema.Items.Schema) + + for idx := range schema.Items.JSONSchemas { + removeDefaults(&schema.Items.JSONSchemas[idx]) + } + } + + for idx := range schema.AllOf { + removeDefaults(&schema.AllOf[idx]) + } + for idx := range schema.OneOf { + removeDefaults(&schema.OneOf[idx]) + } + for idx := range schema.AnyOf { + removeDefaults(&schema.AnyOf[idx]) + } + if schema.Not != nil { + removeDefaults(schema.Not) + } + for key, prop := range schema.Properties { + removeDefaults(&prop) + schema.Properties[key] = prop + } + if schema.AdditionalProperties != nil { + removeDefaults(schema.AdditionalProperties.Schema) + } + for key, prop := range schema.PatternProperties { + removeDefaults(&prop) + schema.PatternProperties[key] = prop + } + for key, prop := range schema.Dependencies { + removeDefaults(prop.Schema) + schema.Dependencies[key] = prop + } + if schema.AdditionalItems != nil { + removeDefaults(schema.AdditionalItems.Schema) + } + for key, prop := range schema.Definitions { + removeDefaults(&prop) + schema.Definitions[key] = prop + } +} + +func WaitForCRDReady(restClient rest.Interface, crds []*CustomResourceDefinition) error { + err := wait.Poll(3*time.Second, 5*time.Minute, func() (bool, error) { + for _, crd := range crds { + var gvr schema.GroupVersionResource + if crd.V1 != nil { + gvr = schema.GroupVersionResource{ + Group: crd.V1.Spec.Group, + Version: crd.V1.Spec.Versions[0].Name, + Resource: crd.V1.Spec.Names.Plural, + } + } else if crd.V1beta1 != nil { + gvr = schema.GroupVersionResource{ + Group: crd.V1beta1.Spec.Group, + Version: crd.V1beta1.Spec.Versions[0].Name, + Resource: crd.V1beta1.Spec.Names.Plural, + } + } + + res := restClient.Get().AbsPath("apis", gvr.Group, gvr.Version, gvr.Resource).Do(context.TODO()) + err := res.Error() + if err != nil { + // RESTClient returns *apierrors.StatusError for any status codes < 200 or > 206 + // and http.Client.Do errors are returned directly. + if se, ok := err.(*kerr.StatusError); ok { + if se.Status().Code == http.StatusNotFound { + return false, nil + } + } + return false, err + } + + var statusCode int + res.StatusCode(&statusCode) + if statusCode != http.StatusOK { + return false, errors.Errorf("invalid status code: %d", statusCode) + } + } + + return true, nil + }) + + return errors.Wrap(err, "timed out waiting for CRD") +} diff --git a/vendor/kmodules.xyz/client-go/apiextensions/types.go b/vendor/kmodules.xyz/client-go/apiextensions/types.go new file mode 100644 index 00000000..944f55e4 --- /dev/null +++ b/vendor/kmodules.xyz/client-go/apiextensions/types.go @@ -0,0 +1,11 @@ +package apiextensions + +import ( + crdv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" + crdv1beta1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1" +) + +type CustomResourceDefinition struct { + V1beta1 *crdv1beta1.CustomResourceDefinition + V1 *crdv1.CustomResourceDefinition +} diff --git a/vendor/kmodules.xyz/client-go/apiextensions/v1/crd.go b/vendor/kmodules.xyz/client-go/apiextensions/v1/crd.go new file mode 100644 index 00000000..0695e92f --- /dev/null +++ b/vendor/kmodules.xyz/client-go/apiextensions/v1/crd.go @@ -0,0 +1,90 @@ +/* +Copyright The Kmodules 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 v1 + +import ( + "context" + + "github.com/golang/glog" + "github.com/pkg/errors" + api "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" + cs "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset" + kerr "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/wait" + kutil "kmodules.xyz/client-go" +) + +func CreateOrUpdateCustomResourceDefinition( + ctx context.Context, + c cs.Interface, + name string, + transform func(in *api.CustomResourceDefinition) *api.CustomResourceDefinition, + opts metav1.UpdateOptions, +) (*api.CustomResourceDefinition, kutil.VerbType, error) { + _, err := c.ApiextensionsV1().CustomResourceDefinitions().Get(ctx, name, metav1.GetOptions{}) + if kerr.IsNotFound(err) { + glog.V(3).Infof("Creating CustomResourceDefinition %s.", name) + out, err := c.ApiextensionsV1().CustomResourceDefinitions().Create(ctx, transform(&api.CustomResourceDefinition{ + TypeMeta: metav1.TypeMeta{ + APIVersion: api.SchemeGroupVersion.String(), + Kind: "CustomResourceDefinition", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: name, + }, + }), metav1.CreateOptions{ + DryRun: opts.DryRun, + FieldManager: opts.FieldManager, + }) + return out, kutil.VerbCreated, err + } else if err != nil { + return nil, kutil.VerbUnchanged, err + } + cur, err := TryUpdateCustomResourceDefinition(ctx, c, name, transform, opts) + if err != nil { + return nil, kutil.VerbUnchanged, err + } + return cur, kutil.VerbUpdated, nil +} + +func TryUpdateCustomResourceDefinition( + ctx context.Context, + c cs.Interface, + name string, + transform func(*api.CustomResourceDefinition) *api.CustomResourceDefinition, + opts metav1.UpdateOptions, +) (result *api.CustomResourceDefinition, err error) { + attempt := 0 + err = wait.PollImmediate(kutil.RetryInterval, kutil.RetryTimeout, func() (bool, error) { + attempt++ + cur, e2 := c.ApiextensionsV1().CustomResourceDefinitions().Get(ctx, name, metav1.GetOptions{}) + if kerr.IsNotFound(e2) { + return false, e2 + } else if e2 == nil { + result, e2 = c.ApiextensionsV1().CustomResourceDefinitions().Update(ctx, transform(cur.DeepCopy()), opts) + return e2 == nil, nil + } + glog.Errorf("Attempt %d failed to update CustomResourceDefinition %s due to %v.", attempt, cur.Name, e2) + return false, nil + }) + + if err != nil { + err = errors.Errorf("failed to update CustomResourceDefinition %s after %d attempts due to %v", name, attempt, err) + } + return +} diff --git a/vendor/kmodules.xyz/client-go/apiextensions/v1beta1/crd.go b/vendor/kmodules.xyz/client-go/apiextensions/v1beta1/crd.go new file mode 100644 index 00000000..7f5f1347 --- /dev/null +++ b/vendor/kmodules.xyz/client-go/apiextensions/v1beta1/crd.go @@ -0,0 +1,90 @@ +/* +Copyright The Kmodules 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 v1beta1 + +import ( + "context" + + "github.com/golang/glog" + "github.com/pkg/errors" + api "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1" + cs "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset" + kerr "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/wait" + kutil "kmodules.xyz/client-go" +) + +func CreateOrUpdateCustomResourceDefinition( + ctx context.Context, + c cs.Interface, + name string, + transform func(in *api.CustomResourceDefinition) *api.CustomResourceDefinition, + opts metav1.UpdateOptions, +) (*api.CustomResourceDefinition, kutil.VerbType, error) { + _, err := c.ApiextensionsV1beta1().CustomResourceDefinitions().Get(ctx, name, metav1.GetOptions{}) + if kerr.IsNotFound(err) { + glog.V(3).Infof("Creating CustomResourceDefinition %s.", name) + out, err := c.ApiextensionsV1beta1().CustomResourceDefinitions().Create(ctx, transform(&api.CustomResourceDefinition{ + TypeMeta: metav1.TypeMeta{ + APIVersion: api.SchemeGroupVersion.String(), + Kind: "CustomResourceDefinition", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: name, + }, + }), metav1.CreateOptions{ + DryRun: opts.DryRun, + FieldManager: opts.FieldManager, + }) + return out, kutil.VerbCreated, err + } else if err != nil { + return nil, kutil.VerbUnchanged, err + } + cur, err := TryUpdateCustomResourceDefinition(ctx, c, name, transform, opts) + if err != nil { + return nil, kutil.VerbUnchanged, err + } + return cur, kutil.VerbUpdated, nil +} + +func TryUpdateCustomResourceDefinition( + ctx context.Context, + c cs.Interface, + name string, + transform func(*api.CustomResourceDefinition) *api.CustomResourceDefinition, + opts metav1.UpdateOptions, +) (result *api.CustomResourceDefinition, err error) { + attempt := 0 + err = wait.PollImmediate(kutil.RetryInterval, kutil.RetryTimeout, func() (bool, error) { + attempt++ + cur, e2 := c.ApiextensionsV1beta1().CustomResourceDefinitions().Get(ctx, name, metav1.GetOptions{}) + if kerr.IsNotFound(e2) { + return false, e2 + } else if e2 == nil { + result, e2 = c.ApiextensionsV1beta1().CustomResourceDefinitions().Update(ctx, transform(cur.DeepCopy()), opts) + return e2 == nil, nil + } + glog.Errorf("Attempt %d failed to update CustomResourceDefinition %s due to %v.", attempt, cur.Name, e2) + return false, nil + }) + + if err != nil { + err = errors.Errorf("failed to update CustomResourceDefinition %s after %d attempts due to %v", name, attempt, err) + } + return +} diff --git a/vendor/kmodules.xyz/client-go/discovery/README.md b/vendor/kmodules.xyz/client-go/discovery/README.md new file mode 100644 index 00000000..2b49db48 --- /dev/null +++ b/vendor/kmodules.xyz/client-go/discovery/README.md @@ -0,0 +1 @@ +- Adapted from https://github.com/kubernetes/apimachinery/blob/bfe7139b14565386b4470736ca765bf21616b60e/pkg/api/meta/restmapper.go#L72 diff --git a/vendor/kmodules.xyz/client-go/discovery/lib.go b/vendor/kmodules.xyz/client-go/discovery/lib.go new file mode 100644 index 00000000..d31b2522 --- /dev/null +++ b/vendor/kmodules.xyz/client-go/discovery/lib.go @@ -0,0 +1,219 @@ +/* +Copyright The Kmodules 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 discovery + +import ( + "context" + "fmt" + + "github.com/golang/glog" + "github.com/pkg/errors" + "gomodules.xyz/version" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/client-go/discovery" + "k8s.io/client-go/kubernetes" +) + +func GetVersion(client discovery.DiscoveryInterface) (string, error) { + info, err := client.ServerVersion() + if err != nil { + return "", err + } + gv, err := version.NewVersion(info.GitVersion) + if err != nil { + return "", err + } + return gv.ToMutator().ResetMetadata().ResetPrerelease().String(), nil +} + +func GetVersionInfo(client discovery.DiscoveryInterface) (int64, int64, int64, string, string, error) { + info, err := client.ServerVersion() + if err != nil { + return -1, -1, -1, "", "", err + } + gv, err := version.NewVersion(info.GitVersion) + if err != nil { + return -1, -1, -1, "", "", err + } + v := gv.ToMutator().ResetMetadata().ResetPrerelease() + return v.Major(), v.Minor(), v.Patch(), v.Prerelease(), v.Metadata(), nil +} + +func GetBaseVersion(client discovery.DiscoveryInterface) (string, error) { + info, err := client.ServerVersion() + if err != nil { + return "", err + } + gv, err := version.NewVersion(info.GitVersion) + if err != nil { + return "", err + } + return gv.ToMutator().ResetMetadata().ResetPrerelease().ResetPatch().String(), nil +} + +func CheckAPIVersion(client discovery.DiscoveryInterface, constraint string) (bool, error) { + info, err := client.ServerVersion() + if err != nil { + return false, err + } + cond, err := version.NewConstraint(constraint) + if err != nil { + return false, err + } + v, err := version.NewVersion(info.GitVersion) + if err != nil { + return false, err + } + return cond.Check(v.ToMutator().ResetPrerelease().ResetMetadata().Done()), nil +} + +func IsPreferredAPIResource(client discovery.DiscoveryInterface, groupVersion, kind string) bool { + return ExistsGroupVersionKind(client, groupVersion, kind) +} + +func ExistsGroupVersionKind(client discovery.DiscoveryInterface, groupVersion, kind string) bool { + if resourceList, err := client.ServerPreferredResources(); discovery.IsGroupDiscoveryFailedError(err) || err == nil { + for _, resources := range resourceList { + if resources.GroupVersion != groupVersion { + continue + } + for _, resource := range resources.APIResources { + if resource.Kind == kind { + return true + } + } + } + } + return false +} + +func ExistsGroupKind(client discovery.DiscoveryInterface, group, kind string) bool { + if resourceList, err := client.ServerPreferredResources(); discovery.IsGroupDiscoveryFailedError(err) || err == nil { + for _, resources := range resourceList { + gv, err := schema.ParseGroupVersion(resources.GroupVersion) + if err != nil { + return false + } + if gv.Group != group { + continue + } + for _, resource := range resources.APIResources { + if resource.Kind == kind { + return true + } + } + } + } + return false +} + +type KnownBug struct { + URL string + Fix string +} + +func (e *KnownBug) Error() string { + return "Bug: " + e.URL + ". To fix, " + e.Fix +} + +var err62649_K1_9 = &KnownBug{URL: "https://github.com/kubernetes/kubernetes/pull/62649", Fix: "upgrade to Kubernetes 1.9.8 or later."} +var err62649_K1_10 = &KnownBug{URL: "https://github.com/kubernetes/kubernetes/pull/62649", Fix: "upgrade to Kubernetes 1.10.2 or later."} +var err83778_K1_16 = &KnownBug{URL: "https://github.com/kubernetes/kubernetes/pull/83787", Fix: "upgrade to Kubernetes 1.16.2 or later."} + +var ( + DefaultConstraint = ">= 1.11.0" + DefaultBlackListedVersions = map[string]error{ + "1.16.0": err83778_K1_16, + "1.16.1": err83778_K1_16, + } + DefaultBlackListedMultiMasterVersions = map[string]error{ + "1.9.0": err62649_K1_9, + "1.9.1": err62649_K1_9, + "1.9.2": err62649_K1_9, + "1.9.3": err62649_K1_9, + "1.9.4": err62649_K1_9, + "1.9.5": err62649_K1_9, + "1.9.6": err62649_K1_9, + "1.9.7": err62649_K1_9, + "1.10.0": err62649_K1_10, + "1.10.1": err62649_K1_10, + } +) + +func IsDefaultSupportedVersion(kc kubernetes.Interface) error { + return IsSupportedVersion( + kc, + DefaultConstraint, + DefaultBlackListedVersions, + DefaultBlackListedMultiMasterVersions) +} + +func IsSupportedVersion(kc kubernetes.Interface, constraint string, blackListedVersions map[string]error, blackListedMultiMasterVersions map[string]error) error { + info, err := kc.Discovery().ServerVersion() + if err != nil { + return err + } + glog.Infof("Kubernetes version: %#v\n", info) + + gv, err := version.NewVersion(info.GitVersion) + if err != nil { + return err + } + v := gv.ToMutator().ResetMetadata().ResetPrerelease().Done() + + nodes, err := kc.CoreV1().Nodes().List(context.TODO(), metav1.ListOptions{ + LabelSelector: "node-role.kubernetes.io/master", + }) + if err != nil { + return err + } + multiMaster := len(nodes.Items) > 1 + + return checkVersion(v, multiMaster, constraint, blackListedVersions, blackListedMultiMasterVersions) +} + +func checkVersion(v *version.Version, multiMaster bool, constraint string, blackListedVersions map[string]error, blackListedMultiMasterVersions map[string]error) error { + vs := v.String() + + if constraint != "" { + c, err := version.NewConstraint(constraint) + if err != nil { + return err + } + if !c.Check(v) { + return fmt.Errorf("kubernetes version %s fails constraint %s", vs, constraint) + } + } + + if e, ok := blackListedVersions[v.Original()]; ok { + return errors.Wrapf(e, "kubernetes version %s is blacklisted", v.Original()) + } + if e, ok := blackListedVersions[vs]; ok { + return errors.Wrapf(e, "kubernetes version %s is blacklisted", vs) + } + + if multiMaster { + if e, ok := blackListedMultiMasterVersions[v.Original()]; ok { + return errors.Wrapf(e, "kubernetes version %s is blacklisted for multi-master cluster", v.Original()) + } + if e, ok := blackListedMultiMasterVersions[vs]; ok { + return errors.Wrapf(e, "kubernetes version %s is blacklisted for multi-master cluster", vs) + } + } + return nil +} diff --git a/vendor/kmodules.xyz/client-go/discovery/restmapper.go b/vendor/kmodules.xyz/client-go/discovery/restmapper.go new file mode 100644 index 00000000..81ef941b --- /dev/null +++ b/vendor/kmodules.xyz/client-go/discovery/restmapper.go @@ -0,0 +1,596 @@ +/* +Copyright The Kmodules 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 discovery + +import ( + "fmt" + "reflect" + "sort" + "strings" + + "github.com/golang/glog" + "github.com/pkg/errors" + "k8s.io/apimachinery/pkg/api/meta" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/conversion" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/client-go/discovery" +) + +func DetectResource(restmapper *DefaultRESTMapper, obj interface{}) (schema.GroupVersionResource, error) { + gvk, err := guessGVK(obj) + if err != nil { + return schema.GroupVersionResource{}, err + } + resources, err := restmapper.ResourcesForKind(gvk) + if err != nil { + return schema.GroupVersionResource{}, err + } + result := make([]schema.GroupVersionResource, 0, len(resources)) + for _, resource := range resources { + if strings.ContainsRune(resource.Resource, '/') { + continue + } + result = append(result, resource) + } + if len(result) == 1 { + return result[0], nil + } + return schema.GroupVersionResource{}, &AmbiguousResourceError{PartialResource: gvk, MatchingResources: resources} +} + +func APIResourceForGVK(client discovery.DiscoveryInterface, input schema.GroupVersionKind) (metav1.APIResource, error) { + resourceList, err := client.ServerResourcesForGroupVersion(input.GroupVersion().String()) + if discovery.IsGroupDiscoveryFailedError(err) { + glog.Errorf("Skipping failed API Groups: %v", err) + } else if err != nil { + return metav1.APIResource{}, err + } + var resources []metav1.APIResource + for _, resource := range resourceList.APIResources { + if resource.Kind == input.Kind { // match kind + resource.Group = input.Group + resource.Version = input.Version + resources = append(resources, resource) + } + } + resources = FilterAPISubResources(resources) // ignore sub-resources + if len(resources) == 1 { + return resources[0], nil + } + + var matches []schema.GroupVersionResource + for _, resource := range resources { + matches = append(matches, schema.GroupVersionResource{ + Group: resource.Group, + Version: resource.Version, + Resource: resource.Name, + }) + } + return metav1.APIResource{}, &AmbiguousResourceError{PartialResource: input, MatchingResources: matches} +} + +func ResourceForGVK(client discovery.DiscoveryInterface, input schema.GroupVersionKind) (schema.GroupVersionResource, error) { + resourceList, err := client.ServerResourcesForGroupVersion(input.GroupVersion().String()) + if discovery.IsGroupDiscoveryFailedError(err) { + glog.Errorf("Skipping failed API Groups: %v", err) + } else if err != nil { + return schema.GroupVersionResource{}, err + } + var resources []schema.GroupVersionResource + for _, resource := range resourceList.APIResources { + if resource.Kind == input.Kind { // match kind + resources = append(resources, input.GroupVersion().WithResource(resource.Name)) + } + } + resources = FilterSubResources(resources) // ignore sub-resources + if len(resources) == 1 { + return resources[0], nil + } + return schema.GroupVersionResource{}, &AmbiguousResourceError{PartialResource: input, MatchingResources: resources} +} + +func FilterAPISubResources(resources []metav1.APIResource) []metav1.APIResource { + var filtered []metav1.APIResource + for _, res := range resources { + if !strings.ContainsRune(res.Name, '/') { + filtered = append(filtered, res) + } + } + return filtered +} + +func FilterSubResources(resources []schema.GroupVersionResource) []schema.GroupVersionResource { + var filtered []schema.GroupVersionResource + for _, res := range resources { + if !strings.ContainsRune(res.Resource, '/') { + filtered = append(filtered, res) + } + } + return filtered +} + +func LoadRestMapper(client discovery.DiscoveryInterface) (*DefaultRESTMapper, error) { + restMapper := NewDefaultRESTMapper([]schema.GroupVersion{}) + + _, resourceLists, err := client.ServerGroupsAndResources() + if discovery.IsGroupDiscoveryFailedError(err) { + glog.Errorf("Skipping failed API Groups: %v", err) + } else if err != nil { + return nil, err + } + for _, resourceList := range resourceLists { + for _, resource := range resourceList.APIResources { + gv, _ := schema.ParseGroupVersion(resourceList.GroupVersion) + plural := gv.WithResource(resource.Name) + singular := gv.WithResource(resource.SingularName) + gvk := gv.WithKind(resource.Kind) + restMapper.AddSpecific(gvk, plural, singular) + } + } + return restMapper, nil +} + +func guessGVK(obj interface{}) (schema.GroupVersionKind, error) { + if m, err := meta.TypeAccessor(obj); err == nil { + return schema.FromAPIVersionAndKind(m.GetAPIVersion(), m.GetKind()), nil + } + + val, err := conversion.EnforcePtr(obj) + if err != nil { + return schema.GroupVersionKind{}, err + } + + pp := pkgPath(val) + parts := strings.Split(pp, "/") + if len(parts) < 2 { + return schema.GroupVersionKind{}, errors.Errorf("failed to guess GroupVersion from package path %s", pp) + } + group := parts[len(parts)-2] + if strings.HasPrefix(pp, "k8s.io/api") && group == "core" { + group = "" + } + version := parts[len(parts)-1] + + return schema.GroupVersionKind{Group: group, Version: version, Kind: val.Type().Name()}, nil +} + +func pkgPath(val reflect.Value) string { + p := val.Type().PkgPath() + idx := strings.LastIndex(p, "/vendor/") + if idx > -1 { + p = p[idx+len("/vendor/"):] + } + return p +} + +// ref: https://github.com/kubernetes/apimachinery/blob/bfe7139b14565386b4470736ca765bf21616b60e/pkg/api/meta/restmapper.go#L72 +type DefaultRESTMapper struct { + defaultGroupVersions []schema.GroupVersion + + resourceToKind map[schema.GroupVersionResource]schema.GroupVersionKind + kindToPluralResource map[schema.GroupVersionKind]schema.GroupVersionResource + singularToPlural map[schema.GroupVersionResource]schema.GroupVersionResource + pluralToSingular map[schema.GroupVersionResource]schema.GroupVersionResource +} + +func NewDefaultRESTMapper(defaultGroupVersions []schema.GroupVersion) *DefaultRESTMapper { + resourceToKind := make(map[schema.GroupVersionResource]schema.GroupVersionKind) + kindToPluralResource := make(map[schema.GroupVersionKind]schema.GroupVersionResource) + singularToPlural := make(map[schema.GroupVersionResource]schema.GroupVersionResource) + pluralToSingular := make(map[schema.GroupVersionResource]schema.GroupVersionResource) + // TODO: verify name mappings work correctly when versions differ + + return &DefaultRESTMapper{ + resourceToKind: resourceToKind, + kindToPluralResource: kindToPluralResource, + defaultGroupVersions: defaultGroupVersions, + singularToPlural: singularToPlural, + pluralToSingular: pluralToSingular, + } +} + +func (m *DefaultRESTMapper) AddSpecific(kind schema.GroupVersionKind, plural, singular schema.GroupVersionResource) { + m.singularToPlural[singular] = plural + m.pluralToSingular[plural] = singular + + m.resourceToKind[singular] = kind + m.resourceToKind[plural] = kind + + m.kindToPluralResource[kind] = plural +} + +func (m *DefaultRESTMapper) ResourcesForKind(input schema.GroupVersionKind) ([]schema.GroupVersionResource, error) { + gvk := coerceKindForMatching(input) + + hasResource := len(gvk.Kind) > 0 + hasGroup := len(gvk.Group) > 0 + hasVersion := len(gvk.Version) > 0 + + if !hasResource { + return nil, errors.Errorf("a resource must be present, got: %v", gvk) + } + + var ret []schema.GroupVersionResource + switch { + case hasGroup: + // given a group, prefer an exact match. If you don't find one, resort to a prefix match on group + foundExactMatch := false + requestedGroupKind := gvk.GroupKind() + for plural := range m.pluralToSingular { + kind, ok := m.resourceToKind[plural] + if !ok { + continue + } + if kind.GroupKind() == requestedGroupKind && (!hasVersion || kind.Version == gvk.Version) { + foundExactMatch = true + ret = append(ret, plural) + } + } + + // if you didn't find an exact match, match on group prefixing. This allows storageclass.storage to match + // storageclass.storage.k8s.io + if !foundExactMatch { + for plural := range m.pluralToSingular { + if !strings.HasPrefix(plural.Group, requestedGroupKind.Group) { + continue + } + kind, ok := m.resourceToKind[plural] + if !ok { + continue + } + if kind.Kind == requestedGroupKind.Kind && (!hasVersion || kind.Version == gvk.Version) { + ret = append(ret, plural) + } + } + } + + case hasVersion: + for plural := range m.pluralToSingular { + kind, ok := m.resourceToKind[plural] + if !ok { + continue + } + if kind.Version == gvk.Version && kind.Kind == gvk.Kind { + ret = append(ret, plural) + } + } + + default: + for plural := range m.pluralToSingular { + kind, ok := m.resourceToKind[plural] + if !ok { + continue + } + if kind.Kind == gvk.Kind { + ret = append(ret, plural) + } + } + } + + if len(ret) == 0 { + return nil, errors.Errorf("no matches for %v", gvk) + } + + sort.Sort(resourceByPreferredGroupVersion{ret, m.defaultGroupVersions}) + return ret, nil +} + +func (m *DefaultRESTMapper) ResourceForKind(input schema.GroupVersionKind) (schema.GroupVersionResource, error) { + resources, err := m.ResourcesForKind(input) + if err != nil { + return schema.GroupVersionResource{}, err + } + if len(resources) == 1 { + return resources[0], nil + } + + return schema.GroupVersionResource{}, &AmbiguousResourceError{PartialResource: input, MatchingResources: resources} +} + +// coerceKindForMatching makes the resource lower case and converts internal versions to unspecified (legacy behavior) +func coerceKindForMatching(gvk schema.GroupVersionKind) schema.GroupVersionKind { + if gvk.Version == runtime.APIVersionInternal { + gvk.Version = "" + } + return gvk +} + +// coerceResourceForMatching makes the resource lower case and converts internal versions to unspecified (legacy behavior) +func coerceResourceForMatching(resource schema.GroupVersionResource) schema.GroupVersionResource { + resource.Resource = strings.ToLower(resource.Resource) + if resource.Version == runtime.APIVersionInternal { + resource.Version = "" + } + + return resource +} + +func (m *DefaultRESTMapper) ResourcesFor(input schema.GroupVersionResource) ([]schema.GroupVersionResource, error) { + resource := coerceResourceForMatching(input) + + hasResource := len(resource.Resource) > 0 + hasGroup := len(resource.Group) > 0 + hasVersion := len(resource.Version) > 0 + + if !hasResource { + return nil, errors.Errorf("a resource must be present, got: %v", resource) + } + + var ret []schema.GroupVersionResource + switch { + case hasGroup && hasVersion: + // fully qualified. Find the exact match + for plural, singular := range m.pluralToSingular { + if singular == resource { + ret = append(ret, plural) + break + } + if plural == resource { + ret = append(ret, plural) + break + } + } + + case hasGroup: + // given a group, prefer an exact match. If you don't find one, resort to a prefix match on group + foundExactMatch := false + requestedGroupResource := resource.GroupResource() + for plural, singular := range m.pluralToSingular { + if singular.GroupResource() == requestedGroupResource { + foundExactMatch = true + ret = append(ret, plural) + } + if plural.GroupResource() == requestedGroupResource { + foundExactMatch = true + ret = append(ret, plural) + } + } + + // if you didn't find an exact match, match on group prefixing. This allows storageclass.storage to match + // storageclass.storage.k8s.io + if !foundExactMatch { + for plural, singular := range m.pluralToSingular { + if !strings.HasPrefix(plural.Group, requestedGroupResource.Group) { + continue + } + if singular.Resource == requestedGroupResource.Resource { + ret = append(ret, plural) + } + if plural.Resource == requestedGroupResource.Resource { + ret = append(ret, plural) + } + } + + } + + case hasVersion: + for plural, singular := range m.pluralToSingular { + if singular.Version == resource.Version && singular.Resource == resource.Resource { + ret = append(ret, plural) + } + if plural.Version == resource.Version && plural.Resource == resource.Resource { + ret = append(ret, plural) + } + } + + default: + for plural, singular := range m.pluralToSingular { + if singular.Resource == resource.Resource { + ret = append(ret, plural) + } + if plural.Resource == resource.Resource { + ret = append(ret, plural) + } + } + } + + if len(ret) == 0 { + return nil, errors.Errorf("no matches for %v", resource) + } + + sort.Sort(resourceByPreferredGroupVersion{ret, m.defaultGroupVersions}) + return ret, nil +} + +func (m *DefaultRESTMapper) ResourceFor(resource schema.GroupVersionResource) (schema.GroupVersionResource, error) { + resources, err := m.ResourcesFor(resource) + if err != nil { + return schema.GroupVersionResource{}, err + } + if len(resources) == 1 { + return resources[0], nil + } + + return schema.GroupVersionResource{}, &meta.AmbiguousResourceError{PartialResource: resource, MatchingResources: resources} +} + +func (m *DefaultRESTMapper) KindsFor(input schema.GroupVersionResource) ([]schema.GroupVersionKind, error) { + resource := coerceResourceForMatching(input) + + hasResource := len(resource.Resource) > 0 + hasGroup := len(resource.Group) > 0 + hasVersion := len(resource.Version) > 0 + + if !hasResource { + return nil, errors.Errorf("a resource must be present, got: %v", resource) + } + + var ret []schema.GroupVersionKind + switch { + // fully qualified. Find the exact match + case hasGroup && hasVersion: + kind, exists := m.resourceToKind[resource] + if exists { + ret = append(ret, kind) + } + + case hasGroup: + foundExactMatch := false + requestedGroupResource := resource.GroupResource() + for currResource, currKind := range m.resourceToKind { + if currResource.GroupResource() == requestedGroupResource { + foundExactMatch = true + ret = append(ret, currKind) + } + } + + // if you didn't find an exact match, match on group prefixing. This allows storageclass.storage to match + // storageclass.storage.k8s.io + if !foundExactMatch { + for currResource, currKind := range m.resourceToKind { + if !strings.HasPrefix(currResource.Group, requestedGroupResource.Group) { + continue + } + if currResource.Resource == requestedGroupResource.Resource { + ret = append(ret, currKind) + } + } + + } + + case hasVersion: + for currResource, currKind := range m.resourceToKind { + if currResource.Version == resource.Version && currResource.Resource == resource.Resource { + ret = append(ret, currKind) + } + } + + default: + for currResource, currKind := range m.resourceToKind { + if currResource.Resource == resource.Resource { + ret = append(ret, currKind) + } + } + } + + if len(ret) == 0 { + return nil, errors.Errorf("no matches for %v", input) + } + + sort.Sort(kindByPreferredGroupVersion{ret, m.defaultGroupVersions}) + return ret, nil +} + +func (m *DefaultRESTMapper) KindFor(resource schema.GroupVersionResource) (schema.GroupVersionKind, error) { + kinds, err := m.KindsFor(resource) + if err != nil { + return schema.GroupVersionKind{}, err + } + if len(kinds) == 1 { + return kinds[0], nil + } + + return schema.GroupVersionKind{}, &meta.AmbiguousResourceError{PartialResource: resource, MatchingKinds: kinds} +} + +type kindByPreferredGroupVersion struct { + list []schema.GroupVersionKind + sortOrder []schema.GroupVersion +} + +func (o kindByPreferredGroupVersion) Len() int { return len(o.list) } +func (o kindByPreferredGroupVersion) Swap(i, j int) { o.list[i], o.list[j] = o.list[j], o.list[i] } +func (o kindByPreferredGroupVersion) Less(i, j int) bool { + lhs := o.list[i] + rhs := o.list[j] + if lhs == rhs { + return false + } + + if lhs.GroupVersion() == rhs.GroupVersion() { + return lhs.Kind < rhs.Kind + } + + // otherwise, the difference is in the GroupVersion, so we need to sort with respect to the preferred order + lhsIndex := -1 + rhsIndex := -1 + + for i := range o.sortOrder { + if o.sortOrder[i] == lhs.GroupVersion() { + lhsIndex = i + } + if o.sortOrder[i] == rhs.GroupVersion() { + rhsIndex = i + } + } + + if rhsIndex == -1 { + return true + } + + return lhsIndex < rhsIndex +} + +type resourceByPreferredGroupVersion struct { + list []schema.GroupVersionResource + sortOrder []schema.GroupVersion +} + +func (o resourceByPreferredGroupVersion) Len() int { return len(o.list) } +func (o resourceByPreferredGroupVersion) Swap(i, j int) { o.list[i], o.list[j] = o.list[j], o.list[i] } +func (o resourceByPreferredGroupVersion) Less(i, j int) bool { + lhs := o.list[i] + rhs := o.list[j] + if lhs == rhs { + return false + } + + if lhs.GroupVersion() == rhs.GroupVersion() { + return lhs.Resource < rhs.Resource + } + + // otherwise, the difference is in the GroupVersion, so we need to sort with respect to the preferred order + lhsIndex := -1 + rhsIndex := -1 + + for i := range o.sortOrder { + if o.sortOrder[i] == lhs.GroupVersion() { + lhsIndex = i + } + if o.sortOrder[i] == rhs.GroupVersion() { + rhsIndex = i + } + } + + if rhsIndex == -1 { + return true + } + + return lhsIndex < rhsIndex +} + +// AmbiguousResourceError is returned if the RESTMapper finds multiple matches for a resource +type AmbiguousResourceError struct { + PartialResource schema.GroupVersionKind + + MatchingResources []schema.GroupVersionResource + MatchingKinds []schema.GroupVersionKind +} + +func (e *AmbiguousResourceError) Error() string { + switch { + case len(e.MatchingKinds) > 0 && len(e.MatchingResources) > 0: + return fmt.Sprintf("%v matches multiple resources %v and kinds %v", e.PartialResource, e.MatchingResources, e.MatchingKinds) + case len(e.MatchingKinds) > 0: + return fmt.Sprintf("%v matches multiple kinds %v", e.PartialResource, e.MatchingKinds) + case len(e.MatchingResources) > 0: + return fmt.Sprintf("%v matches multiple resources %v", e.PartialResource, e.MatchingResources) + } + return fmt.Sprintf("%v matches multiple resources or kinds", e.PartialResource) +} diff --git a/vendor/kmodules.xyz/client-go/doc.go b/vendor/kmodules.xyz/client-go/doc.go new file mode 100644 index 00000000..3b100927 --- /dev/null +++ b/vendor/kmodules.xyz/client-go/doc.go @@ -0,0 +1,17 @@ +/* +Copyright The Kmodules 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 kutil // import "kmodules.xyz/client-go" diff --git a/vendor/kmodules.xyz/client-go/go.mod b/vendor/kmodules.xyz/client-go/go.mod new file mode 100644 index 00000000..f1688fa9 --- /dev/null +++ b/vendor/kmodules.xyz/client-go/go.mod @@ -0,0 +1,39 @@ +module kmodules.xyz/client-go + +go 1.12 + +require ( + github.com/appscode/go v0.0.0-20200323182826-54e98e09185a + github.com/davecgh/go-spew v1.1.1 + github.com/evanphx/json-patch v4.5.0+incompatible + github.com/fatih/structs v1.1.0 + github.com/fsnotify/fsnotify v1.4.7 + github.com/go-openapi/spec v0.19.3 + github.com/gogo/protobuf v1.3.1 + github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b + github.com/google/go-cmp v0.3.0 + github.com/imdario/mergo v0.3.5 + github.com/jpillora/go-ogle-analytics v0.0.0-20161213085824-14b04e0594ef + github.com/json-iterator/go v1.1.8 + github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88 // indirect + github.com/mitchellh/mapstructure v1.1.2 + github.com/pkg/errors v0.8.1 + github.com/spf13/cobra v0.0.5 + github.com/spf13/pflag v1.0.5 + github.com/stretchr/testify v1.4.0 + github.com/yudai/gojsondiff v1.0.0 + github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82 // indirect + github.com/yudai/pp v2.0.1+incompatible // indirect + gomodules.xyz/jsonpatch/v2 v2.1.0 + gomodules.xyz/version v0.1.0 + k8s.io/api v0.18.3 + k8s.io/apiextensions-apiserver v0.18.3 + k8s.io/apimachinery v0.18.3 + k8s.io/apiserver v0.18.3 + k8s.io/cli-runtime v0.18.3 + k8s.io/client-go v0.18.3 + k8s.io/klog v1.0.0 + k8s.io/kube-aggregator v0.18.3 + k8s.io/kube-openapi v0.0.0-20200410145947-61e04a5be9a6 + sigs.k8s.io/yaml v1.2.0 +) diff --git a/vendor/kmodules.xyz/client-go/go.sum b/vendor/kmodules.xyz/client-go/go.sum new file mode 100644 index 00000000..3b8930b7 --- /dev/null +++ b/vendor/kmodules.xyz/client-go/go.sum @@ -0,0 +1,527 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.38.0 h1:ROfEUZz+Gh5pa62DJWXSaonyu3StP6EA6lPEXPI6mCo= +cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= +github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8= +github.com/Azure/go-autorest/autorest v0.9.0 h1:MRvx8gncNaXJqOoLmhNjUAKh33JJF8LyxPhomEtOsjs= +github.com/Azure/go-autorest/autorest v0.9.0/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI= +github.com/Azure/go-autorest/autorest/adal v0.5.0 h1:q2gDruN08/guU9vAjuPWff0+QIrpH6ediguzdAzXAUU= +github.com/Azure/go-autorest/autorest/adal v0.5.0/go.mod h1:8Z9fGy2MpX0PvDjB1pEgQTmVqjGhiHBW7RJJEciWzS0= +github.com/Azure/go-autorest/autorest/date v0.1.0 h1:YGrhWfrgtFs84+h0o46rJrlmsZtyZRg470CqAXTZaGM= +github.com/Azure/go-autorest/autorest/date v0.1.0/go.mod h1:plvfp3oPSKwf2DNjlBjWF/7vwR+cUD/ELuzDCXwHUVA= +github.com/Azure/go-autorest/autorest/mocks v0.1.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0= +github.com/Azure/go-autorest/autorest/mocks v0.2.0 h1:Ww5g4zThfD/6cLb4z6xxgeyDa7QDkizMkJKe0ysZXp0= +github.com/Azure/go-autorest/autorest/mocks v0.2.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0= +github.com/Azure/go-autorest/logger v0.1.0 h1:ruG4BSDXONFRrZZJ2GUXDiUyVpayPmb1GnWeHDdaNKY= +github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6LSNgds39diKLz7Vrc= +github.com/Azure/go-autorest/tracing v0.5.0 h1:TRn4WjSnkcSy5AEG3pnbtFSwNtwzjr4VYyQflFE619k= +github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk= +github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46 h1:lsxEuwrXEAokXB9qhlbKWPpo3KMLZQ5WB5WLQRW1uq0= +github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= +github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= +github.com/PuerkitoBio/purell v1.1.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= +github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI= +github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= +github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= +github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M= +github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= +github.com/agnivade/levenshtein v1.0.1/go.mod h1:CURSv5d9Uaml+FovSIICkLbAUZ9S4RqaHDIsdSBg7lM= +github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= +github.com/appscode/go v0.0.0-20200323182826-54e98e09185a h1:cZ80NKoLRaW1PVCWXAJE+YFkBAmLZ8BnrJmH0ClY1Gs= +github.com/appscode/go v0.0.0-20200323182826-54e98e09185a/go.mod h1:lIcm8Z6VPuvcw/a3EeOWcG6R3I13iHMLYbtVP7TKufY= +github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= +github.com/asaskevich/govalidator v0.0.0-20180720115003-f9ffefc3facf/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= +github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= +github.com/beevik/ntp v0.2.0/go.mod h1:hIHWr+l3+/clUnF44zdK+CWW7fO8dR5cIylAQ76NRpg= +github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= +github.com/beorn7/perks v1.0.0 h1:HWo1m869IqiPhD389kmkxeTalrjNbbJTC8LXupb+sl0= +github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= +github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= +github.com/blang/semver v3.5.0+incompatible h1:CGxCgetQ64DKk7rdZ++Vfnb1+ogGNnB17OJKJXD2Cfs= +github.com/blang/semver v3.5.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= +github.com/cenkalti/backoff v2.1.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa h1:OaNxuTZr7kxeODyLWsRMC+OD03aFUH+mW6r2d+MWa5Y= +github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= +github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0/go.mod h1:4Zcjuz89kmFXt9morQgcfYZAYZ5n8WHjt81YYWIwtTM= +github.com/codeskyblue/go-sh v0.0.0-20190412065543-76bd3d59ff27/go.mod h1:VQx0hjo2oUeQkQUET7wRwradO6f+fN5jzXgB/zROxxE= +github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= +github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= +github.com/coreos/go-oidc v2.1.0+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc= +github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-semver v0.3.0 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmfM= +github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e h1:Wf6HqHfScWJN9/ZjdUKyjop4mf3Qdd+1TvvltAvM3m8= +github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= +github.com/coreos/pkg v0.0.0-20180108230652-97fdf19511ea h1:n2Ltr3SrfQlf/9nOna1DoGKxLx3qTSI8Ttl6Xrqp6mw= +github.com/coreos/pkg v0.0.0-20180108230652-97fdf19511ea/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= +github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= +github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM= +github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= +github.com/docker/docker v0.7.3-0.20190327010347-be7ac8be2ae0/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/go-units v0.3.3/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= +github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= +github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96 h1:cenwrSVm+Z7QLSV/BsnenAOcDXdX4cMv4wP0B/5QbPg= +github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM= +github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo= +github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153 h1:yUdfgN0XgIJw7foRItutHYUIhlcKzcSf5vDpdhQAKTc= +github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= +github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= +github.com/emicklei/go-restful v2.9.5+incompatible h1:spTtZBk5DYEvbxMVutUuTyh1Ao2r4iyvLdACqsl/Ljk= +github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/evanphx/json-patch v4.2.0+incompatible h1:fUDGZCv/7iAN7u0puUVhvKCcsR6vRfwrJatElLBEf0I= +github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/evanphx/json-patch v4.5.0+incompatible h1:ouOWdg56aJriqS0huScTkVXPC5IcNrDCXZ6OoTAWu7M= +github.com/evanphx/json-patch v4.5.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= +github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo= +github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= +github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= +github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/globalsign/mgo v0.0.0-20180905125535-1ca0a4f7cbcb/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q= +github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q= +github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= +github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= +github.com/go-openapi/analysis v0.0.0-20180825180245-b006789cd277/go.mod h1:k70tL6pCuVxPJOHXQ+wIac1FUrvNkHolPie/cLEU6hI= +github.com/go-openapi/analysis v0.17.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik= +github.com/go-openapi/analysis v0.18.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik= +github.com/go-openapi/analysis v0.19.2/go.mod h1:3P1osvZa9jKjb8ed2TPng3f0i/UY9snX6gxi44djMjk= +github.com/go-openapi/analysis v0.19.5/go.mod h1:hkEAkxagaIvIP7VTn8ygJNkd4kAYON2rCu0v0ObL0AU= +github.com/go-openapi/errors v0.17.0/go.mod h1:LcZQpmvG4wyF5j4IhA73wkLFQg+QJXOQHVjmcZxhka0= +github.com/go-openapi/errors v0.18.0/go.mod h1:LcZQpmvG4wyF5j4IhA73wkLFQg+QJXOQHVjmcZxhka0= +github.com/go-openapi/errors v0.19.2/go.mod h1:qX0BLWsyaKfvhluLejVpVNwNRdXZhEbTA4kxxpKBC94= +github.com/go-openapi/jsonpointer v0.0.0-20160704185906-46af16f9f7b1/go.mod h1:+35s3my2LFTysnkMfxsJBAMHj/DoqoB9knIWoYG/Vk0= +github.com/go-openapi/jsonpointer v0.17.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M= +github.com/go-openapi/jsonpointer v0.18.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M= +github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg= +github.com/go-openapi/jsonpointer v0.19.3 h1:gihV7YNZK1iK6Tgwwsxo2rJbD1GTbdm72325Bq8FI3w= +github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= +github.com/go-openapi/jsonreference v0.0.0-20160704190145-13c6e3589ad9/go.mod h1:W3Z9FmVs9qj+KR4zFKmDPGiLdk1D9Rlm7cyMvf57TTg= +github.com/go-openapi/jsonreference v0.17.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I= +github.com/go-openapi/jsonreference v0.18.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I= +github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc= +github.com/go-openapi/jsonreference v0.19.3 h1:5cxNfTy0UVC3X8JL5ymxzyoUZmo8iZb+jeTWn7tUa8o= +github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8= +github.com/go-openapi/loads v0.17.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU= +github.com/go-openapi/loads v0.18.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU= +github.com/go-openapi/loads v0.19.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU= +github.com/go-openapi/loads v0.19.2/go.mod h1:QAskZPMX5V0C2gvfkGZzJlINuP7Hx/4+ix5jWFxsNPs= +github.com/go-openapi/loads v0.19.4/go.mod h1:zZVHonKd8DXyxyw4yfnVjPzBjIQcLt0CCsn0N0ZrQsk= +github.com/go-openapi/runtime v0.0.0-20180920151709-4f900dc2ade9/go.mod h1:6v9a6LTXWQCdL8k1AO3cvqx5OtZY/Y9wKTgaoP6YRfA= +github.com/go-openapi/runtime v0.19.0/go.mod h1:OwNfisksmmaZse4+gpV3Ne9AyMOlP1lt4sK4FXt0O64= +github.com/go-openapi/runtime v0.19.4/go.mod h1:X277bwSUBxVlCYR3r7xgZZGKVvBd/29gLDlFGtJ8NL4= +github.com/go-openapi/spec v0.0.0-20160808142527-6aced65f8501/go.mod h1:J8+jY1nAiCcj+friV/PDoE1/3eeccG9LYBs0tYvLOWc= +github.com/go-openapi/spec v0.17.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI= +github.com/go-openapi/spec v0.18.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI= +github.com/go-openapi/spec v0.19.2/go.mod h1:sCxk3jxKgioEJikev4fgkNmwS+3kuYdJtcsZsD5zxMY= +github.com/go-openapi/spec v0.19.3 h1:0XRyw8kguri6Yw4SxhsQA/atC88yqrk0+G4YhI2wabc= +github.com/go-openapi/spec v0.19.3/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo= +github.com/go-openapi/strfmt v0.17.0/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pLP5l494TcyU= +github.com/go-openapi/strfmt v0.18.0/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pLP5l494TcyU= +github.com/go-openapi/strfmt v0.19.0/go.mod h1:+uW+93UVvGGq2qGaZxdDeJqSAqBqBdl+ZPMF/cC8nDY= +github.com/go-openapi/strfmt v0.19.3/go.mod h1:0yX7dbo8mKIvc3XSKp7MNfxw4JytCfCD6+bY1AVL9LU= +github.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87/go.mod h1:DXUve3Dpr1UfpPtxFw+EFuQ41HhCWZfha5jSVRG7C7I= +github.com/go-openapi/swag v0.17.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg= +github.com/go-openapi/swag v0.18.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg= +github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= +github.com/go-openapi/swag v0.19.5 h1:lTz6Ys4CmqqCQmZPBlbQENR1/GucA2bzYTE12Pw4tFY= +github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= +github.com/go-openapi/validate v0.18.0/go.mod h1:Uh4HdOzKt19xGIGm1qHf/ofbX1YQ4Y+MYsct2VUrAJ4= +github.com/go-openapi/validate v0.19.2/go.mod h1:1tRCw7m3jtI8eNWEEliiAqUIcBztB2KDnRCRMUi7GTA= +github.com/go-openapi/validate v0.19.5/go.mod h1:8DJv2CVJQ6kGNpFW6eV9N3JviE1C85nY1c2z52x1Gk4= +github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= +github.com/gogo/protobuf v1.3.1 h1:DqDEcV5aeaTmdFBePNpYsp3FlcVH/2ISVVM9Qf8PSls= +github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903 h1:LbsanbbD6LieFkXbj9YNNBupiGHJgFeLpO0j0Fza1h8= +github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/protobuf v0.0.0-20161109072736-4bd1920723d7/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/btree v1.0.0 h1:0udJVsspx3VBr5FwtLhQQtuAsVc79tTq0ocGIPAU6qo= +github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g= +github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= +github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY= +github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= +github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= +github.com/googleapis/gnostic v0.1.0 h1:rVsPeBmXbYv4If/cumu1AzZPwV58q433hvONV1UEZoI= +github.com/googleapis/gnostic v0.1.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= +github.com/gophercloud/gophercloud v0.1.0 h1:P/nh25+rzXouhytV2pUHBb65fnds26Ghl8/391+sT5o= +github.com/gophercloud/gophercloud v0.1.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH/Q= +github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7 h1:pdN6V1QBWetyv/0+wjACpqVH+eVULgEjkurDLq3goeM= +github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= +github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4 h1:z53tR0945TRRQO/fLEVPI6SMv7ZflF0TEaTAoU7tOzg= +github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= +github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92BcuyuQ/YW4NSIpoGtfXNho= +github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= +github.com/grpc-ecosystem/grpc-gateway v1.9.5 h1:UImYN5qQ8tuGpGE16ZmjvcTtTw24zw1QAp/SlnNrZhI= +github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= +github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/howeyc/gopass v0.0.0-20170109162249-bf9dde6d0d2c/go.mod h1:lADxMC39cJJqL93Duh1xhAs4I2Zs8mKS89XWXFGp9cs= +github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/imdario/mergo v0.3.5 h1:JboBksRwiiAJWvIYJVo46AfV+IAIKZpfrSzVKj42R4Q= +github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= +github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/jonboulle/clockwork v0.1.0 h1:VKV+ZcuP6l3yW9doeqz6ziZGgcynBVQO+obU0+0hcPo= +github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= +github.com/jpillora/go-ogle-analytics v0.0.0-20161213085824-14b04e0594ef h1:jLpa0vamfyIGeIJ/CfUJEWoKriw4ODeOgF1XxDvgMZ4= +github.com/jpillora/go-ogle-analytics v0.0.0-20161213085824-14b04e0594ef/go.mod h1:PlwhC7q1VSK73InDzdDatVetQrTsQHIbOvcJAZzitY0= +github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.8 h1:QiWkFLKq0T7mpzwOTu6BzNDbfTE8OLrYhVKYMLF46Ok= +github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= +github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= +github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88 h1:uC1QfSlInpQF+M0ao65imhwqKnz3Q2z/d8PWZRMQvDM= +github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q1U84EfirKl04SVQ/s7nPm1ZPhiXd34z40TNz36k= +github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= +github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= +github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA= +github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de h1:9TO3cAIGXtEhnIaL+V+BEER86oLrvS+kWobKpbJuye0= +github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de/go.mod h1:zAbeS9B/r2mtpb6U+EI2rYA5OAXxsYw6wTamcNW+zcE= +github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.7.0 h1:aizVhC/NAAcKWb+5QsU1iNOZb4Yws5UO2I+aIprQITM= +github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs= +github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= +github.com/mattn/go-colorable v0.1.2 h1:/bC9yWikZXAL9uJdulbSfyVNIR3n3trXl+v8+1sx8mU= +github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= +github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mattn/go-isatty v0.0.8 h1:HLtExJ+uU2HOZ+wI0Tt5DtUDrx8yhUqDcp7fYERX4CE= +github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= +github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= +github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE= +github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI= +github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/moul/http2curl v1.0.0/go.mod h1:8UbvGypXm98wA/IqH45anm5Y2Z6ep6O31QGOAZ3H0fQ= +github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= +github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= +github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= +github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.11.0 h1:JAKSXpt1YjtLA7YpPiqO9ss6sNXEsPfSGdwN0UHqzrw= +github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= +github.com/onsi/gomega v1.7.0 h1:XPnZz8VVBHjVsy1vzJmRwIcSwiUO+JFfrv/xGiigmME= +github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= +github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= +github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI= +github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= +github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pquerna/cachecontrol v0.0.0-20171018203845-0dec1b30a021/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA= +github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v1.0.0 h1:vrDKnkGzuGvhNAL56c7DBz29ZL+KxnoR0x7enabFceM= +github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= +github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M= +github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/common v0.4.1 h1:K0MGApIoQvMw27RTdJkPbr3JZ7DNbtxQNyi5STVM6Kw= +github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.2 h1:6LJUbpNm42llc4HRCuvApCSWB/WfhuNo9K98Q9sNGfs= +github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= +github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= +github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ= +github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= +github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4= +github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= +github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= +github.com/soheilhy/cmux v0.1.4 h1:0HKaf1o97UwFjHH9o5XsHUOF+tqmdA7KEzXLpiyaw0E= +github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= +github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= +github.com/spf13/afero v1.2.2 h1:5jhuqJyZCZf2JRofRvN/nIFgIWNzPa3/Vz8mYylgbWc= +github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= +github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= +github.com/spf13/cobra v0.0.5 h1:f0B+LkLX6DtmRH1isoNA9VTtNUK9K8xYd28JNNfOv/s= +github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= +github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= +github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= +github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= +github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8 h1:ndzgwNDnKIqyCvHTXaCqh9KlOWKvBry6nuXMJmonVsE= +github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= +github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= +github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= +github.com/vektah/gqlparser v1.1.2/go.mod h1:1ycwN7Ij5njmMkPPAOaRFY4rET2Enx7IkVv3vaXspKw= +github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 h1:eY9dn8+vbi4tKz5Qo6v2eYzo7kUS51QINcR5jNpbZS8= +github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= +github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= +github.com/yudai/gojsondiff v1.0.0 h1:27cbfqXLVEJ1o8I6v3y9lg8Ydm53EKqHXAOMxEGlCOA= +github.com/yudai/gojsondiff v1.0.0/go.mod h1:AY32+k2cwILAkW1fbgxQ5mUmMiZFgLIV+FBNExI05xg= +github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82 h1:BHyfKlQyqbsFN5p3IfnEUduWvb9is428/nNb5L3U01M= +github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM= +github.com/yudai/pp v2.0.1+incompatible h1:Q4//iY4pNF6yPLZIigmvcl7k/bPgrcTPIFIcmawg5bI= +github.com/yudai/pp v2.0.1+incompatible/go.mod h1:PuxR/8QJ7cyCkFp/aUDS+JY727OFEZkTdatxwunjIkc= +go.etcd.io/bbolt v1.3.3 h1:MUGmc65QhB3pIlaQ5bB4LwqSj6GIonVJXpZiaKNyaKk= +go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= +go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738 h1:VcrIfasaLFkyjk6KNlXQSzO+B0fZcnECiDrKJsfxka0= +go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= +go.mongodb.org/mongo-driver v1.0.3/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= +go.mongodb.org/mongo-driver v1.1.1/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= +go.mongodb.org/mongo-driver v1.1.2/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= +go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= +go.uber.org/atomic v1.3.2 h1:2Oa65PReHzfn29GpvgsYwloV9AVFHPDk8tYxt2c2tr4= +go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/multierr v1.1.0 h1:HoEmRHQPVSqub6w2z2d2EOVs2fjyFRGyofhKuyDq0QI= +go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= +go.uber.org/zap v1.10.0 h1:ORx85nbTijNz8ljznvCMR1ZBIPKFn3jQrag10X2AsuM= +go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190320223903-b7391e95e576/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190422183909-d864b10871cd/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190617133340-57b3e21c3d56/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975 h1:/Tl7pH94bvbAAHBdZJT947M/+gp0+CqQXDtMRC0fseo= +golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181005035420-146acd28ed58/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190320064053-1272bf9dcd53/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191004110552-13f9640d40b9 h1:rjwSpXsdiK0dV8/Naq3kAw9ymfAeJIyd0upUIElB+lI= +golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 h1:SVwTIAaPC2U/AvvLNZ2a7OVsmBpC8L5BlwK1whH3hm0= +golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e h1:vcxGaoTs7kV8m5Np9uUNQin4BrLOthgV7252N8V+FwY= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20170830134202-bb24a47a89ea/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190209173611-3b5209105503/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190321052220-f7bb7a8bee54/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191022100944-742c48ecaeb7 h1:HmbHVPwrPEKPGLAcHSrMe6+hqSUlvZU0rab6x5EXfGU= +golang.org/x/sys v0.0.0-20191022100944-742c48ecaeb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 h1:SvFZT6jyqRaOeXpc5h/JSfZenJ2O330aBsf7JfSUXmQ= +golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181011042414-1f849cf54d09/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190125232054-d66bd3c5d5a6/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190617190820-da514acc4774/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190920225731-5eefd052ad72/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +gomodules.xyz/jsonpatch/v2 v2.1.0 h1:Phva6wqu+xR//Njw6iorylFFgn/z547tw5Ne3HZPQ+k= +gomodules.xyz/jsonpatch/v2 v2.1.0/go.mod h1:IhYNNY4jnS53ZnfE4PAmpKtDpTCj1JFXc+3mwe7XcUU= +gomodules.xyz/version v0.1.0 h1:inGItCg/egI0jPMeIE0SQkiDIJaodOMoCrxYqasQLR0= +gomodules.xyz/version v0.1.0/go.mod h1:Y8xuV02mL/45psyPKG3NCVOwvAOy6T5Kx0l3rCjKSjU= +google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.5.0 h1:KxkO13IPW4Lslp2bz+KHP2E3gtFlrIGNThxkZQ3g+4c= +google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55 h1:gSJIx1SDwno+2ElGhA4+qG2zF97qiUzTM+rQ0klBOcE= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.26.0 h1:2dTRdpdFEEhJYQD8EMLB61nnrzSCTbG38PhqdhvOltg= +google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= +gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= +gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= +gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8= +gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= +gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= +gopkg.in/square/go-jose.v2 v2.2.2/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +k8s.io/api v0.18.3 h1:2AJaUQdgUZLoDZHrun21PW2Nx9+ll6cUzvn3IKhSIn0= +k8s.io/api v0.18.3/go.mod h1:UOaMwERbqJMfeeeHc8XJKawj4P9TgDRnViIqqBeH2QA= +k8s.io/apiextensions-apiserver v0.18.3 h1:h6oZO+iAgg0HjxmuNnguNdKNB9+wv3O1EBDdDWJViQ0= +k8s.io/apiextensions-apiserver v0.18.3/go.mod h1:TMsNGs7DYpMXd+8MOCX8KzPOCx8fnZMoIGB24m03+JE= +k8s.io/apimachinery v0.18.3 h1:pOGcbVAhxADgUYnjS08EFXs9QMl8qaH5U4fr5LGUrSk= +k8s.io/apimachinery v0.18.3/go.mod h1:OaXp26zu/5J7p0f92ASynJa1pZo06YlV9fG7BoWbCko= +k8s.io/apiserver v0.18.3 h1:BVjccwKP/kEqY+ResOyWs0EKs7f4XL0d0E5GkU3uiqI= +k8s.io/apiserver v0.18.3/go.mod h1:tHQRmthRPLUtwqsOnJJMoI8SW3lnoReZeE861lH8vUw= +k8s.io/cli-runtime v0.18.3 h1:8IBtaTYmXiXipKdx2FAKotvnQMjcF0kSLvX4szY340c= +k8s.io/cli-runtime v0.18.3/go.mod h1:pqbbi4nqRIQhUWAVzen8uE8DD/zcZLwf+8sQYO4lwLk= +k8s.io/client-go v0.18.3 h1:QaJzz92tsN67oorwzmoB0a9r9ZVHuD5ryjbCKP0U22k= +k8s.io/client-go v0.18.3/go.mod h1:4a/dpQEvzAhT1BbuWW09qvIaGw6Gbu1gZYiQZIi1DMw= +k8s.io/code-generator v0.18.3/go.mod h1:TgNEVx9hCyPGpdtCWA34olQYLkh3ok9ar7XfSsr8b6c= +k8s.io/component-base v0.18.3 h1:QXq+P4lgi4LCIREya1RDr5gTcBaVFhxEcALir3QCSDA= +k8s.io/component-base v0.18.3/go.mod h1:bp5GzGR0aGkYEfTj+eTY0AN/vXTgkJdQXjNTTVUaa3k= +k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= +k8s.io/gengo v0.0.0-20200114144118-36b2048a9120/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= +k8s.io/klog v0.0.0-20181102134211-b9b56d5dfc92/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= +k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= +k8s.io/klog v1.0.0 h1:Pt+yjF5aB1xDSVbau4VsWe+dQNzA0qv1LlXdC2dF6Q8= +k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I= +k8s.io/kube-aggregator v0.18.3 h1:zAKL1YuI6KULjvsXFQl0W3pQQt73bGXU20+GzYDtdhc= +k8s.io/kube-aggregator v0.18.3/go.mod h1:fux0WabUOggW2yAACL4jQGVd6kv7mSgBnJ3GgCXCris= +k8s.io/kube-openapi v0.0.0-20200410145947-61e04a5be9a6 h1:Oh3Mzx5pJ+yIumsAD0MOECPVeXsVot0UkiaCGVyfGQY= +k8s.io/kube-openapi v0.0.0-20200410145947-61e04a5be9a6/go.mod h1:GRQhZsXIAJ1xR0C9bd8UpWHZ5plfAS9fzPjJuQ6JL3E= +k8s.io/utils v0.0.0-20200324210504-a9aa75ae1b89 h1:d4vVOjXm687F1iLSP2q3lyPPuyvTUt3aVoBpi2DqRsU= +k8s.io/utils v0.0.0-20200324210504-a9aa75ae1b89/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= +sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.7 h1:uuHDyjllyzRyCIvvn0OBjiRB0SgBZGqHNYAmjR7fO50= +sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.7/go.mod h1:PHgbrJT7lCHcxMU+mDHEm+nx46H4zuuHZkDP6icnhu0= +sigs.k8s.io/kustomize v2.0.3+incompatible h1:JUufWFNlI44MdtnjUqVnvh29rR37PQFzPbLXqhyOyX0= +sigs.k8s.io/kustomize v2.0.3+incompatible/go.mod h1:MkjgH3RdOWrievjo6c9T245dYlB5QeXV4WCbnt/PEpU= +sigs.k8s.io/structured-merge-diff/v3 v3.0.0-20200116222232-67a7b8c61874/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw= +sigs.k8s.io/structured-merge-diff/v3 v3.0.0 h1:dOmIZBMfhcHS09XZkMyUgkq5trg3/jRyJYFZUiaOp8E= +sigs.k8s.io/structured-merge-diff/v3 v3.0.0/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw= +sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= +sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q= +sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= diff --git a/vendor/kmodules.xyz/client-go/meta/annotations.go b/vendor/kmodules.xyz/client-go/meta/annotations.go new file mode 100644 index 00000000..1224c6fc --- /dev/null +++ b/vendor/kmodules.xyz/client-go/meta/annotations.go @@ -0,0 +1,189 @@ +/* +Copyright The Kmodules 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 meta + +import ( + "strconv" + "time" + + kutil "kmodules.xyz/client-go" +) + +type ParserFunc func(map[string]string, string) (interface{}, error) + +var _ ParserFunc = GetBool +var _ ParserFunc = GetInt +var _ ParserFunc = GetString +var _ ParserFunc = GetList +var _ ParserFunc = GetMap +var _ ParserFunc = GetFloat +var _ ParserFunc = GetDuration + +func GetBool(m map[string]string, key string) (interface{}, error) { + if m == nil { + return false, kutil.ErrNotFound + } + v, ok := m[key] + if !ok { + return false, kutil.ErrNotFound + } + return strconv.ParseBool(v) +} + +func GetBoolValue(m map[string]string, key string) (bool, error) { + v, err := GetBool(m, key) + return v.(bool), err +} + +func GetInt(m map[string]string, key string) (interface{}, error) { + if m == nil { + return 0, kutil.ErrNotFound + } + v, ok := m[key] + if !ok { + return 0, kutil.ErrNotFound + } + return strconv.Atoi(v) +} + +func GetIntValue(m map[string]string, key string) (int, error) { + v, err := GetInt(m, key) + return v.(int), err +} + +func GetString(m map[string]string, key string) (interface{}, error) { + if m == nil { + return "", kutil.ErrNotFound + } + v, ok := m[key] + if !ok { + return "", kutil.ErrNotFound + } + return v, nil +} + +func GetStringValue(m map[string]string, key string) (string, error) { + v, err := GetString(m, key) + return v.(string), err +} + +func HasKey(m map[string]string, key string) bool { + if m == nil { + return false + } + _, ok := m[key] + return ok +} + +func RemoveKey(m map[string]string, key string) map[string]string { + if m == nil { + return nil + } + delete(m, key) + return m +} + +func GetList(m map[string]string, key string) (interface{}, error) { + if m == nil { + return []string{}, kutil.ErrNotFound + } + s, ok := m[key] + if !ok { + return []string{}, kutil.ErrNotFound + } + v := make([]string, 0) + err := json.Unmarshal([]byte(s), &v) + return v, err +} + +func GetListValue(m map[string]string, key string) ([]string, error) { + v, err := GetList(m, key) + return v.([]string), err +} + +func GetMap(m map[string]string, key string) (interface{}, error) { + if m == nil { + return map[string]string{}, kutil.ErrNotFound + } + s, ok := m[key] + if !ok { + return map[string]string{}, kutil.ErrNotFound + } + v := make(map[string]string) + err := json.Unmarshal([]byte(s), &v) + return v, err +} + +func GetMapValue(m map[string]string, key string) (map[string]string, error) { + v, err := GetMap(m, key) + return v.(map[string]string), err +} + +func GetFloat(m map[string]string, key string) (interface{}, error) { + if m == nil { + return 0.0, kutil.ErrNotFound + } + f, ok := m[key] + if !ok { + return 0.0, kutil.ErrNotFound + } + + return strconv.ParseFloat(f, 64) +} + +func GetFloatValue(m map[string]string, key string) (float64, error) { + v, err := GetFloat(m, key) + return v.(float64), err +} + +func GetDuration(m map[string]string, key string) (interface{}, error) { + if m == nil { + return time.Duration(0), kutil.ErrNotFound + } + d, ok := m[key] + if !ok { + return time.Duration(0), kutil.ErrNotFound + } + + return time.ParseDuration(d) +} + +func GetDurationValue(m map[string]string, key string) (time.Duration, error) { + v, err := GetDuration(m, key) + return v.(time.Duration), err +} + +type GetFunc func(map[string]string) (interface{}, error) + +func ParseFor(key string, fn ParserFunc) GetFunc { + return func(m map[string]string) (interface{}, error) { + return fn(m, key) + } +} + +func GetStringValueForKeys(m map[string]string, key string, alts ...string) (string, error) { + if m == nil { + return "", kutil.ErrNotFound + } + keys := append([]string{key}, alts...) + for _, k := range keys { + if v, ok := m[k]; ok { + return v, nil + } + } + return "", kutil.ErrNotFound +} diff --git a/vendor/kmodules.xyz/client-go/meta/arguments.go b/vendor/kmodules.xyz/client-go/meta/arguments.go new file mode 100644 index 00000000..ba624a80 --- /dev/null +++ b/vendor/kmodules.xyz/client-go/meta/arguments.go @@ -0,0 +1,147 @@ +/* +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. +*/ + +// ref: https://github.com/kubernetes/kubernetes/blob/master/cmd/kubeadm/app/util/arguments.go + +package meta + +import ( + "fmt" + "strings" + + "github.com/golang/glog" +) + +func UpsertArgumentList(baseArgs []string, overrideArgs []string, protectedFlags ...string) []string { + out := make([]string, 0, len(baseArgs)+len(overrideArgs)) + + baseMap := make(map[string]int, len(baseArgs)) + for i, arg := range baseArgs { + out = append(out, arg) // copy to out + + if !strings.HasPrefix(arg, "--") { + continue + } + idx := strings.IndexRune(arg, '=') + if idx < 0 { + continue + } + baseMap[arg[:idx]] = i + } + + protectedSet := make(map[string]string, len(protectedFlags)) + for _, flag := range protectedFlags { + protectedSet[flag] = "" + } + + var idx int + for _, arg := range overrideArgs { + if !strings.HasPrefix(arg, "--") { + goto Append + } + idx = strings.IndexRune(arg, '=') + if idx < 0 { + goto Append + } + + if _, found := protectedSet[arg[:idx]]; found { + continue + } + + if idx, found := baseMap[arg[:idx]]; found { + out[idx] = arg // overwrite + continue + } + + Append: + out = append(out, arg) // append to out + } + return out +} + +// BuildArgumentListFromMap takes two string-string maps, one with the base arguments and one with optional override arguments +func BuildArgumentListFromMap(baseArguments map[string]string, overrideArguments map[string]string) []string { + var command []string + for k, v := range overrideArguments { + // values of "" are allowed as well + command = append(command, fmt.Sprintf("--%s=%s", k, v)) + } + for k, v := range baseArguments { + if _, overrideExists := overrideArguments[k]; !overrideExists { + command = append(command, fmt.Sprintf("--%s=%s", k, v)) + } + } + return command +} + +// ParseArgumentListToMap parses a CLI argument list in the form "--foo=bar" to a string-string map +func ParseArgumentListToMap(arguments []string) map[string]string { + resultingMap := map[string]string{} + for i, arg := range arguments { + key, val, err := parseArgument(arg) + + // Ignore if the first argument doesn't satisfy the criteria, it's most often the binary name + // Warn in all other cases, but don't error out. This can happen only if the user has edited the argument list by hand, so they might know what they are doing + if err != nil { + if i != 0 { + glog.Warningf("WARNING: The component argument %q could not be parsed correctly. The argument must be of the form %q. Skipping...", arg, "--") + } + continue + } + + resultingMap[key] = val + } + return resultingMap +} + +// ReplaceArgument gets a command list; converts it to a map for easier modification, runs the provided function that +// returns a new modified map, and then converts the map back to a command string slice +func ReplaceArgument(command []string, argMutateFunc func(map[string]string) map[string]string) []string { + argMap := ParseArgumentListToMap(command) + + // Save the first command (the executable) if we're sure it's not an argument (i.e. no --) + var newCommand []string + if len(command) > 0 && !strings.HasPrefix(command[0], "--") { + newCommand = append(newCommand, command[0]) + } + newArgMap := argMutateFunc(argMap) + newCommand = append(newCommand, BuildArgumentListFromMap(newArgMap, map[string]string{})...) + return newCommand +} + +// parseArgument parses the argument "--foo=bar" to "foo" and "bar" +func parseArgument(arg string) (string, string, error) { + if !strings.HasPrefix(arg, "--") { + return "", "", fmt.Errorf("the argument should start with '--'") + } + if !strings.Contains(arg, "=") { + return "", "", fmt.Errorf("the argument should have a '=' between the flag and the value") + } + // Remove the starting -- + arg = strings.TrimPrefix(arg, "--") + // Split the string on =. Return only two substrings, since we want only key/value, but the value can include '=' as well + keyvalSlice := strings.SplitN(arg, "=", 2) + + // Make sure both a key and value is present + if len(keyvalSlice) != 2 { + return "", "", fmt.Errorf("the argument must have both a key and a value") + } + if len(keyvalSlice[0]) == 0 { + return "", "", fmt.Errorf("the argument must have a key") + } + + return keyvalSlice[0], keyvalSlice[1], nil +} diff --git a/vendor/kmodules.xyz/client-go/meta/cloud.go b/vendor/kmodules.xyz/client-go/meta/cloud.go new file mode 100644 index 00000000..1ea2ab2e --- /dev/null +++ b/vendor/kmodules.xyz/client-go/meta/cloud.go @@ -0,0 +1,123 @@ +/* +Copyright The Kmodules 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 meta + +import ( + "crypto/x509" + "errors" + "io/ioutil" + "net/http" + "strings" + "time" + + "sigs.k8s.io/yaml" +) + +// ref: https://cloud.google.com/compute/docs/storing-retrieving-metadata +func TestGKE() (string, error) { + // ref: https://github.com/kubernetes/kubernetes/blob/a0f94123616c275f94e7a5b680d60d6f34e92f37/pkg/credentialprovider/gcp/metadata.go#L115 + data, err := ioutil.ReadFile("/sys/class/dmi/id/product_name") + if err != nil { + return "", err + } + name := strings.TrimSpace(string(data)) + if name != "Google" && name != "Google Compute Engine" { + return "", errors.New("not GKE") + } + + client := &http.Client{Timeout: time.Millisecond * 100} + req, err := http.NewRequest(http.MethodGet, "http://metadata.google.internal/computeMetadata/v1/instance/attributes/kube-env", nil) + if err != nil { + return "", err + } + req.Header.Set("Metadata-Flavor", "Google") + resp, err := client.Do(req) + if err != nil { + return "", err + } + defer resp.Body.Close() + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return "", err + } + content := make(map[string]interface{}) + err = yaml.Unmarshal(body, &content) + if err != nil { + return "", err + } + v, ok := content["KUBERNETES_MASTER_NAME"] + if !ok { + return "", errors.New("missing KUBERNETES_MASTER_NAME") + } + return v.(string), nil +} + +const aksDomain = ".azmk8s.io" + +func TestAKS(cert *x509.Certificate) (string, error) { + for _, host := range cert.DNSNames { + if strings.HasSuffix(host, aksDomain) && isAKS() == nil { + return host, nil + } + } + return "", errors.New("not AKS") +} + +// ref: https://cloud.google.com/compute/docs/storing-retrieving-metadata +func isAKS() error { + data, err := ioutil.ReadFile("/sys/class/dmi/id/sys_vendor") + if err != nil { + return err + } + sysVendor := strings.TrimSpace(string(data)) + + data, err = ioutil.ReadFile("/sys/class/dmi/id/product_name") + if err != nil { + return err + } + productName := strings.TrimSpace(string(data)) + + if sysVendor != "Microsoft Corporation" && productName != "Virtual Machine" { + return errors.New("not AKS") + } + return nil +} + +const eksDomain = ".eks.amazonaws.com" + +func TestEKS(cert *x509.Certificate) (string, error) { + for _, host := range cert.DNSNames { + if strings.HasSuffix(host, eksDomain) && isEKS() == nil { + return host, nil + } + } + return "", errors.New("not EKS") +} + +// ref: https://cloud.google.com/compute/docs/storing-retrieving-metadata +func isEKS() error { + data, err := ioutil.ReadFile("/sys/class/dmi/id/sys_vendor") + if err != nil { + return err + } + sysVendor := strings.TrimSpace(string(data)) + + if sysVendor != "Amazon EC2" { + return errors.New("not EKS") + } + return nil +} diff --git a/vendor/kmodules.xyz/client-go/meta/cmp.go b/vendor/kmodules.xyz/client-go/meta/cmp.go new file mode 100644 index 00000000..e4a3d6ce --- /dev/null +++ b/vendor/kmodules.xyz/client-go/meta/cmp.go @@ -0,0 +1,109 @@ +/* +Copyright The Kmodules 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 meta + +import ( + "github.com/google/go-cmp/cmp" + jsoniter "github.com/json-iterator/go" + jsondiff "github.com/yudai/gojsondiff" + "github.com/yudai/gojsondiff/formatter" + "k8s.io/apimachinery/pkg/api/resource" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +var ( + cmpOptions = []cmp.Option{ + cmp.Comparer(func(x, y resource.Quantity) bool { + return x.Cmp(y) == 0 + }), + cmp.Comparer(func(x, y *metav1.Time) bool { + if x == nil && y == nil { + return true + } + if x != nil && y != nil { + return x.Time.Equal(y.Time) + } + return false + }), + } +) + +func Diff(x, y interface{}) string { + return cmp.Diff(x, y, cmpOptions...) +} + +func Equal(x, y interface{}) bool { + return cmp.Equal(x, y, cmpOptions...) +} + +const LastAppliedConfigAnnotation = "kubectl.kubernetes.io/last-applied-configuration" + +// EqualAnnotation checks equality of annotations skipping `kubectl.kubernetes.io/last-applied-configuration` key +func EqualAnnotation(x, y map[string]string) bool { + xLen := len(x) + if _, found := x[LastAppliedConfigAnnotation]; found { + xLen-- + } + yLen := len(y) + if _, found := y[LastAppliedConfigAnnotation]; found { + yLen-- + } + if xLen != yLen { + return false + } + + for k, v := range x { + if k == LastAppliedConfigAnnotation { + continue + } + if y[k] != v { + return false + } + } + return true +} + +func JsonDiff(old, new interface{}) (string, error) { + var json = jsoniter.ConfigFastest + oldBytes, err := json.Marshal(old) + if err != nil { + return "", err + } + + newBytes, err := json.Marshal(new) + if err != nil { + return "", err + } + + // Then, compare them + differ := jsondiff.New() + d, err := differ.Compare(oldBytes, newBytes) + if err != nil { + return "", err + } + + var aJson map[string]interface{} + if err := json.Unmarshal(oldBytes, &aJson); err != nil { + return "", err + } + + format := formatter.NewAsciiFormatter(aJson, formatter.AsciiFormatterConfig{ + ShowArrayIndex: true, + Coloring: false, + }) + return format.Format(d) +} diff --git a/vendor/kmodules.xyz/client-go/meta/encoding.go b/vendor/kmodules.xyz/client-go/meta/encoding.go new file mode 100644 index 00000000..ce3d4be2 --- /dev/null +++ b/vendor/kmodules.xyz/client-go/meta/encoding.go @@ -0,0 +1,183 @@ +/* +Copyright The Kmodules 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 meta + +import ( + "reflect" + + "github.com/mitchellh/mapstructure" + "k8s.io/apimachinery/pkg/api/resource" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/runtime/serializer/versioning" + "k8s.io/client-go/kubernetes/scheme" +) + +type codec struct { + runtime.Codec +} + +type Codec struct { + // Embed a private pointer that cannot be instantiated outside of this package. + *codec +} + +var JSONSerializer = func() *Codec { + mediaType := "application/json" + info, ok := runtime.SerializerInfoForMediaType(scheme.Codecs.SupportedMediaTypes(), mediaType) + if !ok { + panic("unsupported media type " + mediaType) + } + return &Codec{&codec{info.Serializer}} +}() + +var JSONPrettySerializer = func() *Codec { + mediaType := "application/json" + info, ok := runtime.SerializerInfoForMediaType(scheme.Codecs.SupportedMediaTypes(), mediaType) + if !ok { + panic("unsupported media type " + mediaType) + } + return &Codec{&codec{info.PrettySerializer}} +}() + +var YAMLSerializer = func() *Codec { + mediaType := "application/yaml" + info, ok := runtime.SerializerInfoForMediaType(scheme.Codecs.SupportedMediaTypes(), mediaType) + if !ok { + panic("unsupported media type " + mediaType) + } + return &Codec{&codec{info.Serializer}} +}() + +// MarshalToYAML marshals an object into yaml. +func MarshalToYAML(obj runtime.Object, gv schema.GroupVersion) ([]byte, error) { + encoder := versioning.NewCodec( + YAMLSerializer, + nil, + runtime.UnsafeObjectConvertor(scheme.Scheme), + scheme.Scheme, + scheme.Scheme, + nil, + gv, + nil, + scheme.Scheme.Name(), + ) + return runtime.Encode(encoder, obj) +} + +// UnmarshalFromYAML unmarshals an object into yaml. +func UnmarshalFromYAML(data []byte, gv schema.GroupVersion) (runtime.Object, error) { + decoder := versioning.NewCodec( + nil, + YAMLSerializer, + runtime.UnsafeObjectConvertor(scheme.Scheme), + scheme.Scheme, + scheme.Scheme, + nil, + nil, + gv, + scheme.Scheme.Name(), + ) + return runtime.Decode(decoder, data) +} + +// MarshalToJson marshals an object into json. +func MarshalToJson(obj runtime.Object, gv schema.GroupVersion) ([]byte, error) { + encoder := versioning.NewCodec( + JSONSerializer, + nil, + runtime.UnsafeObjectConvertor(scheme.Scheme), + scheme.Scheme, + scheme.Scheme, + nil, + gv, + nil, + scheme.Scheme.Name(), + ) + return runtime.Encode(encoder, obj) +} + +// MarshalToPrettyJson marshals an object into pretty json. +func MarshalToPrettyJson(obj runtime.Object, gv schema.GroupVersion) ([]byte, error) { + encoder := versioning.NewCodec( + JSONPrettySerializer, + nil, + runtime.UnsafeObjectConvertor(scheme.Scheme), + scheme.Scheme, + scheme.Scheme, + nil, + gv, + nil, + scheme.Scheme.Name(), + ) + return runtime.Encode(encoder, obj) +} + +// UnmarshalFromJSON unmarshals an object into json. +func UnmarshalFromJSON(data []byte, gv schema.GroupVersion) (runtime.Object, error) { + decoder := versioning.NewCodec( + nil, + JSONSerializer, + runtime.UnsafeObjectConvertor(scheme.Scheme), + scheme.Scheme, + scheme.Scheme, + nil, + nil, + gv, + scheme.Scheme.Name(), + ) + return runtime.Decode(decoder, data) +} + +// Decode takes an input structure and uses reflection to translate it to +// the output structure. output must be a pointer to a map or struct. +// +// WARNING: `json` tags are not respected when struct converted to map[string]interface{} +// WARNING: Embedded structs are not decoded properly: https://github.com/mitchellh/mapstructure/pull/80 +// +func Decode(input interface{}, output interface{}) error { + config := &mapstructure.DecoderConfig{ + DecodeHook: StringToQuantityHookFunc(), + Metadata: nil, + Result: output, + } + + decoder, err := mapstructure.NewDecoder(config) + if err != nil { + return err + } + + return decoder.Decode(input) +} + +// StringToQuantityHookFunc returns a DecodeHookFunc that converts string to resource.Quantity +func StringToQuantityHookFunc() mapstructure.DecodeHookFunc { + return func( + f reflect.Type, + t reflect.Type, + data interface{}) (interface{}, error) { + if f.Kind() != reflect.String { + return data, nil + } + if t != reflect.TypeOf(resource.Quantity{}) { + return data, nil + } + + // Convert it by parsing + return resource.ParseQuantity(data.(string)) + } +} diff --git a/vendor/kmodules.xyz/client-go/meta/hash.go b/vendor/kmodules.xyz/client-go/meta/hash.go new file mode 100644 index 00000000..6880b503 --- /dev/null +++ b/vendor/kmodules.xyz/client-go/meta/hash.go @@ -0,0 +1,155 @@ +/* +Copyright The Kmodules 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 meta + +import ( + "fmt" + "hash" + "hash/fnv" + "reflect" + "strconv" + + "github.com/appscode/go/encoding/json/types" + "github.com/davecgh/go-spew/spew" + "github.com/fatih/structs" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" +) + +// ObjectHash includes all top label fields (like data, spec) except TypeMeta, ObjectMeta and Status +// also includes Generation, Annotation and Labels form ObjectMeta +func ObjectHash(in metav1.Object) string { + obj := make(map[string]interface{}) + + obj["generation"] = in.GetGeneration() + if len(in.GetLabels()) > 0 { + obj["labels"] = in.GetLabels() + } + + if len(in.GetAnnotations()) > 0 { + data := make(map[string]string, len(in.GetAnnotations())) + for k, v := range in.GetAnnotations() { + if k != LastAppliedConfigAnnotation { + data[k] = v + } + } + obj["annotations"] = data + } + + st := structs.New(in) + for _, field := range st.Fields() { + fieldName := field.Name() + if fieldName != "ObjectMeta" && fieldName != "TypeMeta" && fieldName != "Status" { + obj[fieldName] = field.Value() + } + } + + h := fnv.New64a() + DeepHashObject(h, obj) + return strconv.FormatUint(h.Sum64(), 10) +} + +func GenerationHash(in metav1.Object) string { + obj := make(map[string]interface{}, 3) + obj["generation"] = in.GetGeneration() + if len(in.GetLabels()) > 0 { + obj["labels"] = in.GetLabels() + } + if len(in.GetAnnotations()) > 0 { + data := make(map[string]string, len(in.GetAnnotations())) + for k, v := range in.GetAnnotations() { + if k != LastAppliedConfigAnnotation { + data[k] = v + } + } + obj["annotations"] = data + } + h := fnv.New64a() + DeepHashObject(h, obj) + return strconv.FormatUint(h.Sum64(), 10) +} + +// DeepHashObject writes specified object to hash using the spew library +// which follows pointers and prints actual values of the nested objects +// ensuring the hash does not change when a pointer changes. +func DeepHashObject(hasher hash.Hash, objectToWrite interface{}) { + hasher.Reset() + printer := spew.ConfigState{ + Indent: " ", + SortKeys: true, + DisableMethods: true, + SpewKeys: true, + } + printer.Fprintf(hasher, "%#v", objectToWrite) +} + +func MustAlreadyReconciled(o interface{}) bool { + reconciled, err := AlreadyReconciled(o) + if err != nil { + panic("failed to extract status.observedGeneration field due to err:" + err.Error()) + } + return reconciled +} + +func AlreadyReconciled(o interface{}) (bool, error) { + var generation, observedGeneration *types.IntHash + var err error + + switch obj := o.(type) { + case *unstructured.Unstructured: + generation, observedGeneration, err = extractGenerationFromUnstructured(obj) + case metav1.Object: + generation, observedGeneration, err = extractGenerationFromObject(obj) + default: + err = fmt.Errorf("unknown object type %s", reflect.TypeOf(o).String()) + } + if err != nil { + return false, err + } + return observedGeneration.MatchGeneration(generation), nil +} + +func extractGenerationFromUnstructured(obj *unstructured.Unstructured) (*types.IntHash, *types.IntHash, error) { + generation := types.IntHashForGeneration(obj.GetGeneration()) + + val, found, err := unstructured.NestedFieldNoCopy(obj.Object, "status", "observedGeneration") + if err != nil { + return nil, nil, err + } else if !found { + return nil, nil, fmt.Errorf("status.observedGeneration is missing") + } + observedGeneration, err := types.ParseIntHash(val) + + return generation, observedGeneration, err +} + +func extractGenerationFromObject(obj metav1.Object) (*types.IntHash, *types.IntHash, error) { + generation := types.IntHashForGeneration(obj.GetGeneration()) + + st := structs.New(obj) + fieldStatus, found := st.FieldOk("Status") + if !found { + return nil, nil, fmt.Errorf("status is missing") + } + fieldObsGen, found := fieldStatus.FieldOk("ObservedGeneration") + if !found { + return nil, nil, fmt.Errorf("status.observedGeneration is missing") + } + observedGeneration, err := types.ParseIntHash(fieldObsGen.Value()) + + return generation, observedGeneration, err +} diff --git a/vendor/kmodules.xyz/client-go/meta/incluster.go b/vendor/kmodules.xyz/client-go/meta/incluster.go new file mode 100644 index 00000000..f7c5bda1 --- /dev/null +++ b/vendor/kmodules.xyz/client-go/meta/incluster.go @@ -0,0 +1,90 @@ +/* +Copyright The Kmodules 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 meta + +import ( + "crypto/tls" + "crypto/x509" + "fmt" + "io/ioutil" + "net" + "net/http" + "os" + "strings" + "time" + + core "k8s.io/api/core/v1" + "k8s.io/client-go/rest" +) + +func Namespace() string { + if ns := os.Getenv("KUBE_NAMESPACE"); ns != "" { + return ns + } + if data, err := ioutil.ReadFile("/var/run/secrets/kubernetes.io/serviceaccount/namespace"); err == nil { + if ns := strings.TrimSpace(string(data)); len(ns) > 0 { + return ns + } + } + return core.NamespaceDefault +} + +// PossiblyInCluster returns true if loading an inside-kubernetes-cluster is possible. +func PossiblyInCluster() bool { + fi, err := os.Stat("/var/run/secrets/kubernetes.io/serviceaccount/token") + return os.Getenv("KUBERNETES_SERVICE_HOST") != "" && + os.Getenv("KUBERNETES_SERVICE_PORT") != "" && + err == nil && !fi.IsDir() +} + +func APIServerCertificate(cfg *rest.Config) (*x509.Certificate, error) { + err := rest.LoadTLSFiles(cfg) + if err != nil { + return nil, err + } + + // create ca cert pool + caCertPool := x509.NewCertPool() + ok := caCertPool.AppendCertsFromPEM(cfg.CAData) + if !ok { + return nil, fmt.Errorf("can't append caCert to caCertPool") + } + + tr := &http.Transport{ + Proxy: http.ProxyFromEnvironment, + DialContext: (&net.Dialer{ + Timeout: 30 * time.Second, + KeepAlive: 30 * time.Second, + DualStack: true, + }).DialContext, + MaxIdleConns: 100, + IdleConnTimeout: 90 * time.Second, + TLSHandshakeTimeout: 10 * time.Second, + ExpectContinueTimeout: 1 * time.Second, + TLSClientConfig: &tls.Config{RootCAs: caCertPool}, + } + client := &http.Client{Transport: tr} + + resp, err := client.Get(cfg.Host) + if err != nil { + return nil, err + } + for i := range resp.TLS.VerifiedChains { + return resp.TLS.VerifiedChains[i][0], nil + } + return nil, fmt.Errorf("no cert found") +} diff --git a/vendor/kmodules.xyz/client-go/meta/lib.go b/vendor/kmodules.xyz/client-go/meta/lib.go new file mode 100644 index 00000000..fc289903 --- /dev/null +++ b/vendor/kmodules.xyz/client-go/meta/lib.go @@ -0,0 +1,173 @@ +/* +Copyright The Kmodules 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 meta + +import ( + "fmt" + "reflect" + "strings" + + "github.com/spf13/pflag" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/sets" + "k8s.io/apimachinery/pkg/util/validation" +) + +// https://kubernetes.io/docs/concepts/overview/working-with-objects/common-labels/#labels +// ref: https://github.com/kubernetes-sigs/application/blob/4ead7f1b87048b7717b3e474a21fdc07e6bce636/pkg/controller/application/application_controller.go#L28 +const ( + NameLabelKey = "app.kubernetes.io/name" + VersionLabelKey = "app.kubernetes.io/version" + InstanceLabelKey = "app.kubernetes.io/instance" + PartOfLabelKey = "app.kubernetes.io/part-of" + ComponentLabelKey = "app.kubernetes.io/component" + ManagedByLabelKey = "app.kubernetes.io/managed-by" + + MaxCronJobNameLength = 52 //xref: https://github.com/kubernetes/kubernetes/pull/52733 +) + +var labelKeyBlacklist = []string{ + NameLabelKey, + VersionLabelKey, + InstanceLabelKey, + // PartOfLabelKey, // propagate part-of key + // ComponentLabelKey, // propagate part-of key + ManagedByLabelKey, +} + +// AddLabelBlacklistFlag is for explicitly initializing the flags +func AddLabelBlacklistFlag(fs *pflag.FlagSet) { + if fs == nil { + fs = pflag.CommandLine + } + fs.StringSliceVar(&labelKeyBlacklist, "label-key-blacklist", labelKeyBlacklist, "list of keys that are not propagated from a CRD object to its offshoots") +} + +func DeleteInBackground() metav1.DeleteOptions { + policy := metav1.DeletePropagationBackground + return metav1.DeleteOptions{PropagationPolicy: &policy} +} + +func DeleteInForeground() metav1.DeleteOptions { + policy := metav1.DeletePropagationForeground + return metav1.DeleteOptions{PropagationPolicy: &policy} +} + +func GetKind(v interface{}) string { + return reflect.Indirect(reflect.ValueOf(v)).Type().Name() +} + +func FilterKeys(domainKey string, out, in map[string]string) map[string]string { + if in == nil { + return out + } + if out == nil { + out = make(map[string]string, len(in)) + } + + blacklist := sets.NewString(labelKeyBlacklist...) + + n := len(domainKey) + var idx int + for k, v := range in { + if blacklist.Has(k) { + continue + } + + idx = strings.IndexRune(k, '/') + switch { + case idx < n: + out[k] = v + case idx == n && k[:idx] != domainKey: + out[k] = v + case idx > n && k[idx-n-1:idx] != "."+domainKey: + out[k] = v + } + } + return out +} + +func MergeKeys(out, in map[string]string) map[string]string { + if in == nil { + return out + } + if out == nil { + out = make(map[string]string, len(in)) + } + + for k, v := range in { + out[k] = v + } + return out +} + +func ValidNameWithPrefix(prefix, name string, customLength ...int) string { + maxLength := validation.DNS1123LabelMaxLength + if len(customLength) != 0 { + maxLength = customLength[0] + } + out := fmt.Sprintf("%s-%s", prefix, name) + return strings.Trim(out[:min(maxLength, len(out))], "-") +} + +func ValidNameWithSuffix(name, suffix string, customLength ...int) string { + maxLength := validation.DNS1123LabelMaxLength + if len(customLength) != 0 { + maxLength = customLength[0] + } + out := fmt.Sprintf("%s-%s", name, suffix) + return strings.Trim(out[max(0, len(out)-maxLength):], "-") +} + +func ValidNameWithPefixNSuffix(prefix, name, suffix string, customLength ...int) string { + maxLength := validation.DNS1123LabelMaxLength + if len(customLength) != 0 { + maxLength = customLength[0] + } + out := fmt.Sprintf("%s-%s-%s", prefix, name, suffix) + n := len(out) + if n <= maxLength { + return strings.Trim(out, "-") + } + return strings.Trim(out[:(maxLength+1)/2]+out[(n-maxLength/2):], "-") +} + +func ValidCronJobNameWithPrefix(prefix, name string) string { + return ValidNameWithPrefix(prefix, name, MaxCronJobNameLength) +} + +func ValidCronJobNameWithSuffix(name, suffix string) string { + return ValidNameWithSuffix(name, suffix, MaxCronJobNameLength) +} + +func ValidCronJobNameWithPefixNSuffix(prefix, name, suffix string) string { + return ValidNameWithPefixNSuffix(prefix, name, suffix, MaxCronJobNameLength) +} + +func min(x, y int) int { + if x < y { + return x + } + return y +} + +func max(x, y int) int { + if x > y { + return x + } + return y +} diff --git a/vendor/kmodules.xyz/client-go/meta/patch.go b/vendor/kmodules.xyz/client-go/meta/patch.go new file mode 100644 index 00000000..ec6139ca --- /dev/null +++ b/vendor/kmodules.xyz/client-go/meta/patch.go @@ -0,0 +1,155 @@ +/* +Copyright The Kmodules 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 meta + +import ( + "fmt" + "strings" + + jsonpatch "github.com/evanphx/json-patch" + jsoniter "github.com/json-iterator/go" + jp "gomodules.xyz/jsonpatch/v2" + "k8s.io/apimachinery/pkg/util/mergepatch" + "k8s.io/apimachinery/pkg/util/strategicpatch" +) + +var json = jsoniter.ConfigFastest + +func toJson(v interface{}) ([]byte, error) { + if u, ok := v.([]byte); ok { + return u, nil + } + return json.Marshal(v) +} + +func CreateStrategicPatch(cur interface{}, mod interface{}, fns ...mergepatch.PreconditionFunc) ([]byte, error) { + curJson, err := toJson(cur) + if err != nil { + return nil, err + } + + modJson, err := toJson(mod) + if err != nil { + return nil, err + } + + return strategicpatch.CreateTwoWayMergePatch(curJson, modJson, mod, fns...) +} + +func CreateJSONMergePatch(cur interface{}, mod interface{}, fns ...mergepatch.PreconditionFunc) ([]byte, error) { + curJson, err := toJson(cur) + if err != nil { + return nil, err + } + + modJson, err := toJson(mod) + if err != nil { + return nil, err + } + + patch, err := jsonpatch.CreateMergePatch(curJson, modJson) + if err != nil { + return nil, err + } + if err := meetPreconditions(patch, fns...); err != nil { + return nil, err + } + + return patch, nil +} + +func CreateJSONPatch(cur interface{}, mod interface{}) ([]byte, error) { + curJson, err := toJson(cur) + if err != nil { + return nil, err + } + + modJson, err := toJson(mod) + if err != nil { + return nil, err + } + + ops, err := jp.CreatePatch(curJson, modJson) + if err != nil { + return nil, err + } + return json.Marshal(ops) +} + +// Apply the preconditions to the patch, and return an error if any of them fail. +// ref: https://github.com/kubernetes/apimachinery/blob/master/pkg/util/jsonmergepatch/patch.go#L74 +func meetPreconditions(patch []byte, fns ...mergepatch.PreconditionFunc) error { + var patchMap map[string]interface{} + if err := json.Unmarshal(patch, &patchMap); err != nil { + return fmt.Errorf("failed to unmarshal patch for precondition check: %s", patch) + } + + for _, fn := range fns { + if !fn(patchMap) { + return mergepatch.NewErrPreconditionFailed(patchMap) + } + } + return nil +} + +// RequireChainKeyUnchanged creates a precondition function that fails +// if the [field].key is present in the patch (indicating its value +// has changed). Here, [field] can be recursive field i.e. 'spec.someField.someKey' + +// Use 'mergepatch' package to set 'RequireKeyUnchanged' and 'RequireMetadataKeyUnchanged'. +// But, for recursive key checking, use the following 'RequireChainKeyUnchanged' method. +// ref: https://github.com/kubernetes/apimachinery/blob/master/pkg/util/mergepatch/util.go#L30 + +func RequireChainKeyUnchanged(key string) mergepatch.PreconditionFunc { + return func(patch interface{}) bool { + patchMap, ok := patch.(map[string]interface{}) + if !ok { + fmt.Println("Invalid data") + return true + } + return checkChainKeyUnchanged(key, patchMap) + } +} + +func checkChainKeyUnchanged(key string, mapData map[string]interface{}) bool { + keys := strings.Split(key, ".") + + newKey := strings.Join(keys[1:], ".") + if keys[0] == "*" { + if len(keys) == 1 { + return true + } + for _, val := range mapData { + if !checkChainKeyUnchanged(newKey, val.(map[string]interface{})) { + return false + } + } + } else { + values, ok := mapData[keys[0]] + if !ok || len(keys) == 1 { + return !ok + } + if x, ok := values.([]interface{}); ok { + // x is of type []Interface + for _, val := range x { + return checkChainKeyUnchanged(newKey, val.(map[string]interface{})) + } + } + return checkChainKeyUnchanged(newKey, values.(map[string]interface{})) + } + return true +} diff --git a/vendor/kmodules.xyz/client-go/util.go b/vendor/kmodules.xyz/client-go/util.go new file mode 100644 index 00000000..14641396 --- /dev/null +++ b/vendor/kmodules.xyz/client-go/util.go @@ -0,0 +1,64 @@ +/* +Copyright The Kmodules 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 kutil + +import ( + "errors" + "regexp" + "time" + + kerr "k8s.io/apimachinery/pkg/api/errors" +) + +const ( + RetryInterval = 50 * time.Millisecond + RetryTimeout = 2 * time.Second + ReadinessTimeout = 10 * time.Minute + GCTimeout = 5 * time.Minute +) + +type VerbType string + +const ( + VerbUnchanged VerbType = "" + VerbCreated VerbType = "created" + VerbPatched VerbType = "patched" + VerbUpdated VerbType = "updated" + VerbDeleted VerbType = "deleted" + + ObjectNameField = "metadata.name" +) + +var ( + ErrNotFound = errors.New("not found") + ErrUnknown = errors.New("unknown") +) + +func IsRequestRetryable(err error) bool { + return kerr.IsServiceUnavailable(err) || + kerr.IsTimeout(err) || + kerr.IsServerTimeout(err) || + kerr.IsTooManyRequests(err) +} + +var reMutator = regexp.MustCompile(`^Internal error occurred: admission webhook "[^"]+" denied the request.*$`) +var reValidator = regexp.MustCompile(`^admission webhook "[^"]+" denied the request.*$`) + +func AdmissionWebhookDeniedRequest(err error) bool { + return (kerr.IsInternalError(err) && reMutator.MatchString(err.Error())) || + (kerr.IsForbidden(err) && reValidator.MatchString(err.Error())) +} diff --git a/vendor/modules.txt b/vendor/modules.txt index cd9d2004..25634ec0 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -5,7 +5,10 @@ github.com/PuerkitoBio/purell # github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 github.com/PuerkitoBio/urlesc # github.com/appscode/go v0.0.0-20200323182826-54e98e09185a +github.com/appscode/go/encoding/json/types github.com/appscode/go/runtime +github.com/appscode/go/sets +github.com/appscode/go/types # github.com/beorn7/perks v1.0.0 github.com/beorn7/perks/quantile # github.com/blang/semver v3.5.1+incompatible @@ -22,6 +25,8 @@ github.com/emicklei/go-restful github.com/emicklei/go-restful/log # github.com/evanphx/json-patch v4.5.0+incompatible github.com/evanphx/json-patch +# github.com/fatih/structs v1.1.0 +github.com/fatih/structs # github.com/go-openapi/jsonpointer v0.19.3 github.com/go-openapi/jsonpointer # github.com/go-openapi/jsonreference v0.19.3 @@ -76,6 +81,8 @@ github.com/mailru/easyjson/jlexer github.com/mailru/easyjson/jwriter # github.com/matttproud/golang_protobuf_extensions v1.0.1 github.com/matttproud/golang_protobuf_extensions/pbutil +# github.com/mitchellh/mapstructure v1.1.2 +github.com/mitchellh/mapstructure # github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd github.com/modern-go/concurrent # github.com/modern-go/reflect2 v1.0.1 @@ -182,6 +189,10 @@ golang.org/x/time/rate golang.org/x/tools/go/ast/astutil golang.org/x/tools/go/gcexportdata golang.org/x/tools/go/internal/gcimporter +# gomodules.xyz/jsonpatch/v2 v2.1.0 +gomodules.xyz/jsonpatch/v2 +# gomodules.xyz/version v0.1.0 +gomodules.xyz/version # google.golang.org/appengine v1.6.5 google.golang.org/appengine/internal google.golang.org/appengine/internal/base @@ -237,7 +248,7 @@ gopkg.in/inf.v0 gopkg.in/natefinch/lumberjack.v2 # gopkg.in/yaml.v2 v2.2.8 gopkg.in/yaml.v2 -# k8s.io/api v0.18.3 +# k8s.io/api v0.18.3 => github.com/kmodules/api v0.18.4-0.20200524125823-c8bc107809b9 k8s.io/api/admission/v1 k8s.io/api/admission/v1beta1 k8s.io/api/admissionregistration/v1 @@ -287,6 +298,10 @@ k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1 k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1 k8s.io/apiextensions-apiserver/pkg/apiserver/schema k8s.io/apiextensions-apiserver/pkg/apiserver/schema/pruning +k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset +k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/scheme +k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1 +k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1beta1 # k8s.io/apimachinery v0.18.3 => github.com/kmodules/apimachinery v0.19.0-alpha.0.0.20200520235721-10b58e57a423 k8s.io/apimachinery/pkg/api/apitesting k8s.io/apimachinery/pkg/api/apitesting/fuzzer @@ -464,7 +479,7 @@ k8s.io/apiserver/plugin/pkg/audit/truncate k8s.io/apiserver/plugin/pkg/audit/webhook k8s.io/apiserver/plugin/pkg/authenticator/token/webhook k8s.io/apiserver/plugin/pkg/authorizer/webhook -# k8s.io/client-go v0.18.3 => k8s.io/client-go v0.18.3 +# k8s.io/client-go v12.0.0+incompatible => k8s.io/client-go v0.18.3 k8s.io/client-go/discovery k8s.io/client-go/informers k8s.io/client-go/informers/admissionregistration @@ -650,7 +665,13 @@ k8s.io/utils/net k8s.io/utils/path k8s.io/utils/pointer k8s.io/utils/trace -# kmodules.xyz/client-go v0.0.0-20200522120609-c6430d66212f +# kmodules.xyz/client-go v0.0.0-20200525112657-3b8ebfcb5e19 +kmodules.xyz/client-go +kmodules.xyz/client-go/apiextensions +kmodules.xyz/client-go/apiextensions/v1 +kmodules.xyz/client-go/apiextensions/v1beta1 +kmodules.xyz/client-go/discovery +kmodules.xyz/client-go/meta kmodules.xyz/client-go/openapi # kmodules.xyz/crd-schema-fuzz v0.0.0-20200521005638-2433a187de95 kmodules.xyz/crd-schema-fuzz