提交 93ad572e 编写于 作者: H hongming

refine tenant api

Signed-off-by: Nhongming <talonwan@yunify.com>
上级 744bd053
......@@ -142,6 +142,15 @@
packages = ["."]
revision = "aabc10ec26b754e797f9028f4589c5b7bd90dc20"
[[projects]]
branch = "master"
name = "github.com/docker/spdystream"
packages = [
".",
"spdy",
]
revision = "6480d4af844c189cf5dd913db24ddd339d3a4f85"
[[projects]]
name = "github.com/dustin/go-humanize"
packages = ["."]
......@@ -740,7 +749,7 @@
"api/prometheus/v1",
"prometheus",
"prometheus/internal",
"prometheus/promhttp"
"prometheus/promhttp",
]
revision = "505eaef017263e299324067d40ca2c48f6a2cf50"
version = "v0.9.2"
......@@ -756,7 +765,7 @@
packages = [
"expfmt",
"internal/bitbucket.org/ww/goautoneg",
"model"
"model",
]
revision = "cfeb6f9992ffa54aaa4f2170ade4067ee478b250"
version = "v0.2.0"
......@@ -769,7 +778,7 @@
"internal/util",
"iostats",
"nfs",
"xfs"
"xfs",
]
revision = "e56f2e22fc761e82a34aca553f6725e2aff4fe6c"
......@@ -778,7 +787,7 @@
packages = [
"modfile",
"module",
"semver"
"semver",
]
revision = "1cf9852c553c5b7da2d5a4a091129a7822fed0c9"
version = "v1.2.2"
......@@ -793,7 +802,7 @@
name = "github.com/spf13/afero"
packages = [
".",
"mem"
"mem",
]
revision = "f4711e4db9e9a1d3887343acb72b2bbfc2f686f5"
version = "v1.2.1"
......@@ -820,7 +829,7 @@
name = "github.com/stretchr/testify"
packages = [
"assert",
"mock"
"mock",
]
revision = "ffdc059bfe9ce6a4e144ba849dbedead332c6053"
version = "v1.3.0"
......@@ -843,7 +852,7 @@
"lego",
"log",
"platform/wait",
"registration"
"registration",
]
revision = "2952cdaebd4da7cd560e195343bdd3cb78a67643"
version = "v2.3.0"
......@@ -868,7 +877,7 @@
"internal/bufferpool",
"internal/color",
"internal/exit",
"zapcore"
"zapcore",
]
revision = "ff33455a0e382e8a81d14dd7c922020b6b5e7982"
version = "v1.9.1"
......@@ -883,7 +892,7 @@
"hkdf",
"ocsp",
"pbkdf2",
"ssh/terminal"
"ssh/terminal",
]
revision = "a1f597ede03a7bef967a422b5b3a5bd08805a01e"
......@@ -906,7 +915,7 @@
"internal/socks",
"ipv4",
"ipv6",
"proxy"
"proxy",
]
revision = "9f648a60d9775ef5c977e7669d1673a7a67bef33"
......@@ -918,7 +927,7 @@
"google",
"internal",
"jws",
"jwt"
"jwt",
]
revision = "e64efc72b421e893cbf63f17ba2221e7d6d0b0f3"
......@@ -928,8 +937,9 @@
packages = [
"cpu",
"unix",
"windows"
"windows",
]
revision = "fead79001313d15903fb4605b4a1b781532cd93e"
[[projects]]
......@@ -961,7 +971,7 @@
"unicode/cldr",
"unicode/norm",
"unicode/rangetable",
"width"
"width",
]
revision = "f21a4dfb5e38f5895301dc265a8def02365cc3d0"
version = "v0.3.0"
......@@ -976,7 +986,6 @@
branch = "master"
name = "golang.org/x/tools"
packages = [
"container/intsets",
"go/ast/astutil",
"go/gcexportdata",
"go/internal/cgo",
......@@ -988,7 +997,7 @@
"internal/fastwalk",
"internal/gopathwalk",
"internal/module",
"internal/semver"
"internal/semver",
]
revision = "8b67d361bba210f5fbb3c1a0fc121e0847b10b57"
......@@ -1005,7 +1014,7 @@
"internal/modules",
"internal/remote_api",
"internal/urlfetch",
"urlfetch"
"urlfetch",
]
revision = "e9657d882bb81064595ca3b56cbe2546bbabf7b1"
version = "v1.4.0"
......@@ -1023,6 +1032,12 @@
source = "https://github.com/fsnotify/fsnotify.git"
version = "v1.4.7"
[[projects]]
name = "gopkg.in/igm/sockjs-go.v2"
packages = ["sockjs"]
revision = "d276e9ffe5cc5c271b81198cc77a2adf6c4482d2"
version = "v2.0.0"
[[projects]]
name = "gopkg.in/inf.v0"
packages = ["."]
......@@ -1041,7 +1056,7 @@
".",
"cipher",
"json",
"jwt"
"jwt",
]
revision = "628223f44a71f715d2881ea69afc795a1e9c01be"
version = "v2.3.0"
......@@ -1093,7 +1108,7 @@
"settings/v1alpha1",
"storage/v1",
"storage/v1alpha1",
"storage/v1beta1"
"storage/v1beta1",
]
revision = "05914d821849570fba9eacfb29466f2d8d3cd229"
version = "kubernetes-1.13.1"
......@@ -1106,7 +1121,7 @@
"pkg/client/clientset/clientset",
"pkg/client/clientset/clientset/scheme",
"pkg/client/clientset/clientset/typed/apiextensions/v1beta1",
"pkg/features"
"pkg/features",
]
revision = "0fe22c71c47604641d9aa352c785b7912c200562"
version = "kubernetes-1.13.1"
......@@ -1144,12 +1159,15 @@
"pkg/util/diff",
"pkg/util/errors",
"pkg/util/framer",
"pkg/util/httpstream",
"pkg/util/httpstream/spdy",
"pkg/util/intstr",
"pkg/util/json",
"pkg/util/mergepatch",
"pkg/util/naming",
"pkg/util/net",
"pkg/util/rand",
"pkg/util/remotecommand",
"pkg/util/runtime",
"pkg/util/sets",
"pkg/util/strategicpatch",
......@@ -1161,7 +1179,8 @@
"pkg/version",
"pkg/watch",
"third_party/forked/golang/json",
"third_party/forked/golang/reflect"
"third_party/forked/golang/netutil",
"third_party/forked/golang/reflect",
]
revision = "2b1284ed4c93a43499e781493253e2ac5959c4fd"
version = "kubernetes-1.13.1"
......@@ -1176,7 +1195,7 @@
"pkg/authorization/authorizer",
"pkg/endpoints/request",
"pkg/features",
"pkg/util/feature"
"pkg/util/feature",
]
revision = "3ccfe8365421eb08e334b195786a2973460741d8"
version = "kubernetes-1.13.1"
......@@ -1318,17 +1337,20 @@
"tools/pager",
"tools/record",
"tools/reference",
"tools/remotecommand",
"tools/watch",
"transport",
"transport/spdy",
"util/buffer",
"util/cert",
"util/connrotation",
"util/exec",
"util/flowcontrol",
"util/homedir",
"util/integer",
"util/jsonpath",
"util/retry",
"util/workqueue"
"util/workqueue",
]
revision = "8d9ed539ba3134352c586810e749e58df4e94e4f"
version = "kubernetes-1.13.1"
......@@ -1344,8 +1366,9 @@
"cmd/client-gen/generators/util",
"cmd/client-gen/path",
"cmd/client-gen/types",
"pkg/util"
"pkg/util",
]
pruneopts = "T"
revision = "c2090bec4d9b1fb25de3812f868accc2bc9ecbae"
version = "kubernetes-1.13.1"
......@@ -1360,7 +1383,7 @@
"generator",
"namer",
"parser",
"types"
"types",
]
revision = "b90029ef6cd877cb3f422d75b3a07707e3aac6b7"
......@@ -1407,7 +1430,7 @@
"pkg/util/net/sets",
"pkg/util/parsers",
"pkg/util/slice",
"pkg/util/taints"
"pkg/util/taints",
]
revision = "c27b913fddd1a6c480c229191a087698aa92f0b1"
version = "v1.13.4"
......@@ -1433,6 +1456,7 @@
"pkg/client/apiutil",
"pkg/client/config",
"pkg/controller",
"pkg/controller/controllerutil",
"pkg/envtest",
"pkg/envtest/printer",
"pkg/event",
......@@ -1461,7 +1485,7 @@
"pkg/webhook/internal/cert/writer",
"pkg/webhook/internal/cert/writer/atomic",
"pkg/webhook/internal/metrics",
"pkg/webhook/types"
"pkg/webhook/types",
]
revision = "12d98582e72927b6cd0123e2b4e819f9341ce62c"
version = "v0.1.10"
......@@ -1478,7 +1502,7 @@
"pkg/rbac",
"pkg/util",
"pkg/webhook",
"pkg/webhook/internal"
"pkg/webhook/internal",
]
revision = "fbf141159251d035089e7acdd5a343f8cec91b94"
version = "v0.1.9"
......@@ -1488,7 +1512,7 @@
packages = [
"integration",
"integration/addr",
"integration/internal"
"integration/internal",
]
revision = "d348cb12705b516376e0c323bacca72b00a78425"
version = "v0.1.1"
......@@ -1502,6 +1526,111 @@
[solve-meta]
analyzer-name = "dep"
analyzer-version = 1
inputs-digest = "662b6da91343ff0a611e4487b8eef803b103b676f5b2a5db7ed8351846218fc5"
input-imports = [
"github.com/dgrijalva/jwt-go",
"github.com/docker/docker/api/types",
"github.com/docker/docker/client",
"github.com/emicklei/go-restful",
"github.com/emicklei/go-restful-openapi",
"github.com/go-ldap/ldap",
"github.com/go-openapi/spec",
"github.com/go-redis/redis",
"github.com/go-sql-driver/mysql",
"github.com/golang/glog",
"github.com/google/uuid",
"github.com/jinzhu/gorm",
"github.com/json-iterator/go",
"github.com/kiali/kiali/config",
"github.com/kiali/kiali/handlers",
"github.com/knative/pkg/apis/istio/v1alpha3",
"github.com/knative/pkg/client/clientset/versioned",
"github.com/knative/pkg/client/informers/externalversions",
"github.com/knative/pkg/client/informers/externalversions/istio/v1alpha3",
"github.com/knative/pkg/client/listers/istio/v1alpha3",
"github.com/kubernetes-sigs/application/pkg/apis/app/v1beta1",
"github.com/kubesphere/s2ioperator/pkg/apis/devops/v1alpha1",
"github.com/kubesphere/s2ioperator/pkg/client/clientset/versioned",
"github.com/kubesphere/s2ioperator/pkg/client/informers/externalversions",
"github.com/mholt/caddy",
"github.com/mholt/caddy/caddy/caddymain",
"github.com/mholt/caddy/caddyhttp/httpserver",
"github.com/onsi/ginkgo",
"github.com/onsi/gomega",
"github.com/spf13/cobra",
"github.com/spf13/pflag",
"golang.org/x/net/context",
"gopkg.in/igm/sockjs-go.v2/sockjs",
"gopkg.in/yaml.v2",
"k8s.io/api/apps/v1",
"k8s.io/api/apps/v1beta2",
"k8s.io/api/batch/v1",
"k8s.io/api/batch/v1beta1",
"k8s.io/api/core/v1",
"k8s.io/api/extensions/v1beta1",
"k8s.io/api/policy/v1beta1",
"k8s.io/api/rbac/v1",
"k8s.io/api/storage/v1",
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions",
"k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset",
"k8s.io/apimachinery/pkg/api/errors",
"k8s.io/apimachinery/pkg/api/resource",
"k8s.io/apimachinery/pkg/apis/meta/v1",
"k8s.io/apimachinery/pkg/fields",
"k8s.io/apimachinery/pkg/labels",
"k8s.io/apimachinery/pkg/runtime",
"k8s.io/apimachinery/pkg/runtime/schema",
"k8s.io/apimachinery/pkg/runtime/serializer",
"k8s.io/apimachinery/pkg/types",
"k8s.io/apimachinery/pkg/util/json",
"k8s.io/apimachinery/pkg/util/runtime",
"k8s.io/apimachinery/pkg/util/sets",
"k8s.io/apimachinery/pkg/util/wait",
"k8s.io/apimachinery/pkg/watch",
"k8s.io/apiserver/pkg/authentication/user",
"k8s.io/apiserver/pkg/authorization/authorizer",
"k8s.io/apiserver/pkg/endpoints/request",
"k8s.io/client-go/discovery",
"k8s.io/client-go/discovery/fake",
"k8s.io/client-go/informers",
"k8s.io/client-go/informers/apps/v1",
"k8s.io/client-go/informers/core/v1",
"k8s.io/client-go/kubernetes",
"k8s.io/client-go/kubernetes/scheme",
"k8s.io/client-go/kubernetes/typed/core/v1",
"k8s.io/client-go/listers/apps/v1",
"k8s.io/client-go/listers/core/v1",
"k8s.io/client-go/plugin/pkg/client/auth/gcp",
"k8s.io/client-go/rest",
"k8s.io/client-go/testing",
"k8s.io/client-go/tools/cache",
"k8s.io/client-go/tools/clientcmd",
"k8s.io/client-go/tools/record",
"k8s.io/client-go/tools/remotecommand",
"k8s.io/client-go/util/flowcontrol",
"k8s.io/client-go/util/workqueue",
"k8s.io/code-generator/cmd/client-gen",
"k8s.io/gengo/examples/deepcopy-gen/generators",
"k8s.io/gengo/examples/defaulter-gen/generators",
"k8s.io/klog",
"k8s.io/kubernetes/pkg/apis/core",
"k8s.io/kubernetes/pkg/controller",
"k8s.io/kubernetes/pkg/util/metrics",
"k8s.io/kubernetes/pkg/util/slice",
"sigs.k8s.io/application/pkg/controller/application",
"sigs.k8s.io/controller-runtime/pkg/client",
"sigs.k8s.io/controller-runtime/pkg/client/config",
"sigs.k8s.io/controller-runtime/pkg/controller",
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil",
"sigs.k8s.io/controller-runtime/pkg/envtest",
"sigs.k8s.io/controller-runtime/pkg/handler",
"sigs.k8s.io/controller-runtime/pkg/manager",
"sigs.k8s.io/controller-runtime/pkg/reconcile",
"sigs.k8s.io/controller-runtime/pkg/runtime/log",
"sigs.k8s.io/controller-runtime/pkg/runtime/scheme",
"sigs.k8s.io/controller-runtime/pkg/runtime/signals",
"sigs.k8s.io/controller-runtime/pkg/source",
"sigs.k8s.io/controller-tools/cmd/controller-gen",
"sigs.k8s.io/testing_frameworks/integration",
]
solver-name = "gps-cdcl"
solver-version = 1
......@@ -116,3 +116,7 @@ required = [
[[constraint]]
branch = "master"
name = "github.com/knative/pkg"
[[constraint]]
name = "gopkg.in/igm/sockjs-go.v2"
version = "2.0.0"
......@@ -64,7 +64,7 @@ deploy: manifests
# Generate DeepCopy to implement runtime.Object
deepcopy:
./vendor/k8s.io/code-generator/generate-groups.sh deepcopy,lister,informer,client kubesphere.io/kubesphere/pkg/client kubesphere.io/kubesphere/pkg/apis "servicemesh:v1alpha2"
./vendor/k8s.io/code-generator/generate-groups.sh all kubesphere.io/kubesphere/pkg/client kubesphere.io/kubesphere/pkg/apis "servicemesh:v1alpha2 tenant:v1alpha1"
# Generate code
generate:
......@@ -79,7 +79,7 @@ docker-build: all
# Run tests
test: generate fmt vet
export KUBEBUILDER_CONTROLPLANE_START_TIMEOUT=1m; go test ./pkg/... ./cmd/... -coverprofile cover.out
go test ./pkg/... ./cmd/... -coverprofile cover.out
.PHONY: clean
clean:
......
/*
Copyright 2019 The KubeSphere 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 app
import (
......@@ -6,7 +23,6 @@ import (
"k8s.io/client-go/rest"
"kubesphere.io/kubesphere/pkg/controller/destinationrule"
"kubesphere.io/kubesphere/pkg/controller/virtualservice"
"kubesphere.io/kubesphere/pkg/simple/controller/namespace"
"sigs.k8s.io/controller-runtime/pkg/manager"
"time"
......@@ -60,11 +76,6 @@ func AddControllers(mgr manager.Manager, cfg *rest.Config, stopCh <-chan struct{
kubeClient,
istioclient)
nsController := namespace.NewNamespaceController(kubeClient,
informerFactory.Core().V1().Namespaces(),
informerFactory.Rbac().V1().Roles(),
)
servicemeshinformer.Start(stopCh)
istioInformer.Start(stopCh)
informerFactory.Start(stopCh)
......@@ -72,7 +83,6 @@ func AddControllers(mgr manager.Manager, cfg *rest.Config, stopCh <-chan struct{
controllers := map[string]manager.Runnable{
"virtualservice-controller": vsController,
"destinationrule-controller": drController,
"namespace-controller": nsController,
}
for name, ctrl := range controllers {
......
......@@ -27,6 +27,8 @@ import (
_ "kubesphere.io/kubesphere/pkg/apis/operations/install"
_ "kubesphere.io/kubesphere/pkg/apis/resources/install"
_ "kubesphere.io/kubesphere/pkg/apis/servicemesh/metrics/install"
_ "kubesphere.io/kubesphere/pkg/apis/tenant/install"
_ "kubesphere.io/kubesphere/pkg/apis/terminal/install"
)
func main() {
......
......@@ -29,6 +29,4 @@ func (s *ServerRunOptions) AddFlags(fs *pflag.FlagSet) {
s.GenericServerRunOptions.AddFlags(fs)
fs.StringVar(&s.IstioPilotServiceURL, "istio-pilot-service-url", "http://istio-pilot.istio-system.svc:8080/version", "istio pilot discovery service url")
fs.StringVar(&s.OpenPitrixServer, "openpitrix-server", "http://openpitrix-api-gateway.openpitrix-system.svc", "openpitrix server")
fs.StringVar(&s.OpenPitrixProxyToken, "openpitrix-proxy-token", "", "openpitrix proxy token")
}
......@@ -29,8 +29,10 @@ import (
"kubesphere.io/kubesphere/pkg/apiserver/runtime"
"kubesphere.io/kubesphere/pkg/filter"
"kubesphere.io/kubesphere/pkg/informers"
"kubesphere.io/kubesphere/pkg/models"
logging "kubesphere.io/kubesphere/pkg/models/log"
"kubesphere.io/kubesphere/pkg/signals"
"kubesphere.io/kubesphere/pkg/simple/client/mysql"
"log"
"net/http"
)
......@@ -70,28 +72,43 @@ func Run(s *options.ServerRunOptions) error {
container := runtime.Container
container.Filter(filter.Logging)
log.Printf("Server listening on %d.", s.GenericServerRunOptions.InsecurePort)
for _, webservice := range container.RegisteredWebServices() {
for _, route := range webservice.Routes() {
log.Printf(route.Path)
log.Println(route.Method, route.Path)
}
}
initializeESClientConfig()
initializeKialiConfig(s)
err = initializeDatabase()
if err != nil {
return err
}
if s.GenericServerRunOptions.InsecurePort != 0 {
log.Printf("Server listening on %d.", s.GenericServerRunOptions.InsecurePort)
err = http.ListenAndServe(fmt.Sprintf("%s:%d", s.GenericServerRunOptions.BindAddress, s.GenericServerRunOptions.InsecurePort), container)
}
if s.GenericServerRunOptions.SecurePort != 0 && len(s.GenericServerRunOptions.TlsCertFile) > 0 && len(s.GenericServerRunOptions.TlsPrivateKey) > 0 {
log.Printf("Server listening on %d.", s.GenericServerRunOptions.SecurePort)
err = http.ListenAndServeTLS(fmt.Sprintf("%s:%d", s.GenericServerRunOptions.BindAddress, s.GenericServerRunOptions.SecurePort), s.GenericServerRunOptions.TlsCertFile, s.GenericServerRunOptions.TlsPrivateKey, container)
}
return err
}
func initializeDatabase() error {
db := mysql.Client()
if !db.HasTable(&models.WorkspaceDPBinding{}) {
if err := db.CreateTable(&models.WorkspaceDPBinding{}).Error; err != nil {
return err
}
}
return nil
}
func initializeKialiConfig(s *options.ServerRunOptions) {
// Initialize kiali config
config := kconfig.NewConfig()
......@@ -114,7 +131,7 @@ func initializeKialiConfig(s *options.ServerRunOptions) {
func initializeESClientConfig() {
// List all outputs
outputs,err := logging.GetFluentbitOutputFromConfigMap()
outputs, err := logging.GetFluentbitOutputFromConfigMap()
if err != nil {
glog.Errorln(err)
return
......@@ -153,9 +170,11 @@ func waitForResourceSync() {
informerFactory.Apps().V1().StatefulSets().Lister()
informerFactory.Apps().V1().Deployments().Lister()
informerFactory.Apps().V1().DaemonSets().Lister()
informerFactory.Apps().V1().ReplicaSets().Lister()
informerFactory.Batch().V1().Jobs().Lister()
informerFactory.Batch().V1beta1().CronJobs().Lister()
informerFactory.Extensions().V1beta1().Ingresses().Lister()
informerFactory.Start(stopChan)
informerFactory.WaitForCacheSync(stopChan)
......@@ -167,5 +186,12 @@ func waitForResourceSync() {
s2iInformerFactory.Start(stopChan)
s2iInformerFactory.WaitForCacheSync(stopChan)
ksInformerFactory := informers.KsSharedInformerFactory()
ksInformerFactory.Tenant().V1alpha1().Workspaces().Lister()
ksInformerFactory.Start(stopChan)
ksInformerFactory.WaitForCacheSync(stopChan)
log.Println("resources sync success")
}
/*
Copyright 2019 The KubeSphere 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 options
import (
......@@ -10,6 +27,7 @@ type ServerRunOptions struct {
AdminEmail string
AdminPassword string
TokenExpireTime string
JWTSecret string
}
func NewServerRunOptions() *ServerRunOptions {
......@@ -22,6 +40,7 @@ func NewServerRunOptions() *ServerRunOptions {
func (s *ServerRunOptions) AddFlags(fs *pflag.FlagSet) {
fs.StringVar(&s.AdminEmail, "admin-email", "admin@kubesphere.io", "default administrator's email")
fs.StringVar(&s.AdminPassword, "admin-password", "passw0rd", "default administrator's password")
fs.StringVar(&s.TokenExpireTime, "token-expire-time", "24h", "token expire time")
fs.StringVar(&s.TokenExpireTime, "token-expire-time", "2h", "token expire time,valid time units are \"ns\",\"us\",\"ms\",\"s\",\"m\",\"h\"")
fs.StringVar(&s.JWTSecret, "jwt-secret", "", "jwt secret")
s.GenericServerRunOptions.AddFlags(fs)
}
......@@ -29,6 +29,7 @@ import (
"kubesphere.io/kubesphere/pkg/informers"
"kubesphere.io/kubesphere/pkg/models/iam"
"kubesphere.io/kubesphere/pkg/signals"
"kubesphere.io/kubesphere/pkg/utils/jwtutil"
"log"
"net/http"
"time"
......@@ -54,14 +55,12 @@ cluster's shared state through which all other components interact.`,
}
func Run(s *options.ServerRunOptions) error {
pflag.VisitAll(func(flag *pflag.Flag) {
log.Printf("FLAG: --%s=%q", flag.Name, flag.Value)
})
var err error
expireTime, err := time.ParseDuration(s.TokenExpireTime)
if err != nil {
......@@ -69,6 +68,7 @@ func Run(s *options.ServerRunOptions) error {
}
err = iam.Init(s.AdminEmail, s.AdminPassword, expireTime)
jwtutil.Setup(s.JWTSecret)
if err != nil {
return err
......@@ -79,11 +79,19 @@ func Run(s *options.ServerRunOptions) error {
container := runtime.Container
container.Filter(filter.Logging)
for _, webservice := range container.RegisteredWebServices() {
for _, route := range webservice.Routes() {
log.Println(route.Method, route.Path)
}
}
if s.GenericServerRunOptions.InsecurePort != 0 {
log.Printf("Server listening on %d.", s.GenericServerRunOptions.InsecurePort)
err = http.ListenAndServe(fmt.Sprintf("%s:%d", s.GenericServerRunOptions.BindAddress, s.GenericServerRunOptions.InsecurePort), container)
}
if s.GenericServerRunOptions.SecurePort != 0 && len(s.GenericServerRunOptions.TlsCertFile) > 0 && len(s.GenericServerRunOptions.TlsPrivateKey) > 0 {
log.Printf("Server listening on %d.", s.GenericServerRunOptions.SecurePort)
err = http.ListenAndServeTLS(fmt.Sprintf("%s:%d", s.GenericServerRunOptions.BindAddress, s.GenericServerRunOptions.SecurePort), s.GenericServerRunOptions.TlsCertFile, s.GenericServerRunOptions.TlsPrivateKey, container)
}
......@@ -103,5 +111,11 @@ func waitForResourceSync() {
informerFactory.Start(stopChan)
informerFactory.WaitForCacheSync(stopChan)
ksInformerFactory := informers.KsSharedInformerFactory()
ksInformerFactory.Tenant().V1alpha1().Workspaces().Lister()
ksInformerFactory.Start(stopChan)
ksInformerFactory.WaitForCacheSync(stopChan)
log.Println("resources sync success")
}
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
creationTimestamp: null
labels:
controller-tools.k8s.io: "1.0"
name: workspaces.tenant.kubesphere.io
spec:
group: tenant.kubesphere.io
names:
kind: Workspace
plural: workspaces
scope: Cluster
validation:
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/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/api-conventions.md#types-kinds'
type: string
metadata:
type: object
spec:
properties:
manager:
type: string
quotas:
type: object
type: object
status:
properties:
quotas:
description: 'INSERT ADDITIONAL STATUS FIELD - define observed state
of cluster Important: Run "make" to regenerate code after modifying
this file'
type: object
type: object
version: v1alpha1
status:
acceptedNames:
kind: ""
plural: ""
conditions: []
storedVersions: []
......@@ -4,84 +4,100 @@ metadata:
creationTimestamp: null
name: manager-role
rules:
- apiGroups:
- networking.istio.io
resources:
- virtualservices
verbs:
- get
- list
- watch
- create
- update
- patch
- delete
- apiGroups:
- networking.istio.io
resources:
- virtualservices/status
verbs:
- get
- list
- watch
- create
- update
- patch
- delete
- apiGroups:
- servicemesh.kubesphere.io
resources:
- strategies
verbs:
- get
- list
- watch
- create
- update
- patch
- delete
- apiGroups:
- servicemesh.kubesphere.io
resources:
- strategies/status
verbs:
- get
- update
- patch
- apiGroups:
- admissionregistration.k8s.io
resources:
- mutatingwebhookconfigurations
- validatingwebhookconfigurations
verbs:
- get
- list
- watch
- create
- update
- patch
- delete
- apiGroups:
- ""
resources:
- secrets
verbs:
- get
- list
- watch
- create
- update
- patch
- delete
- apiGroups:
- ""
resources:
- services
verbs:
- get
- list
- watch
- create
- update
- patch
- delete
- apiGroups:
- ""
resources:
- namespaces
verbs:
- get
- list
- watch
- create
- update
- patch
- delete
- apiGroups:
- ""
resources:
- namespaces/status
verbs:
- get
- update
- patch
- apiGroups:
- ""
resources:
- namespaces
verbs:
- get
- list
- watch
- create
- update
- patch
- delete
- apiGroups:
- ""
resources:
- namespaces/status
verbs:
- get
- update
- patch
- apiGroups:
- tenant.kubesphere.io
resources:
- workspaces
verbs:
- get
- list
- watch
- create
- update
- patch
- delete
- apiGroups:
- tenant.kubesphere.io
resources:
- workspaces/status
verbs:
- get
- update
- patch
- apiGroups:
- admissionregistration.k8s.io
resources:
- mutatingwebhookconfigurations
- validatingwebhookconfigurations
verbs:
- get
- list
- watch
- create
- update
- patch
- delete
- apiGroups:
- ""
resources:
- secrets
verbs:
- get
- list
- watch
- create
- update
- patch
- delete
- apiGroups:
- ""
resources:
- services
verbs:
- get
- list
- watch
- create
- update
- patch
- delete
apiVersion: tenant.kubesphere.io/v1alpha1
kind: Workspace
metadata:
labels:
controller-tools.k8s.io: "1.0"
name: workspace-sample
spec:
manager: admin
......@@ -2,6 +2,6 @@
docker build -f build/ks-apigateway/Dockerfile -t kubespheredev/ks-apigateway:latest .
docker build -f build/ks-apiserver/Dockerfile -t kubespheredev/ks-apiserver:latest .
docker build -f build/ks-iam/Dockerfile -t kubespheredev/ks-iam:latest .
docker build -f build/ks-iam/Dockerfile -t kubespheredev/ks-account:latest .
docker build -f build/controller-manager/Dockerfile -t kubespheredev/ks-controller-manager:latest .
......@@ -5,5 +5,5 @@
echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" --password-stdin
docker push kubespheredev/ks-apigateway:latest
docker push kubespheredev/ks-apiserver:latest
docker push kubespheredev/ks-iam:latest
docker push kubespheredev/ks-account:latest
docker push kubespheredev/ks-controller-manager:latest
......@@ -23,6 +23,7 @@ import (
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/apiserver/pkg/authentication/user"
"k8s.io/apiserver/pkg/endpoints/request"
"log"
"net/http"
"strconv"
"strings"
......@@ -50,7 +51,7 @@ type User struct {
}
var requestInfoFactory = request.RequestInfoFactory{
APIPrefixes: sets.NewString("api", "apis"),
APIPrefixes: sets.NewString("api", "apis", "kapis", "kapi"),
GrouplessAPIPrefixes: sets.NewString("api")}
func (h Auth) ServeHTTP(resp http.ResponseWriter, req *http.Request) (int, error) {
......@@ -71,6 +72,7 @@ func (h Auth) ServeHTTP(resp http.ResponseWriter, req *http.Request) (int, error
token, err := h.Validate(uToken)
if err != nil {
log.Println(uToken)
return h.HandleUnauthorized(resp, err), nil
}
......@@ -166,6 +168,7 @@ func (h Auth) Validate(uToken string) (*jwt.Token, error) {
func (h Auth) HandleUnauthorized(w http.ResponseWriter, err error) int {
message := fmt.Sprintf("Unauthorized,%v", err)
w.Header().Add("WWW-Authenticate", message)
log.Println(message)
return http.StatusUnauthorized
}
......
......@@ -33,7 +33,7 @@ import (
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/kubernetes/pkg/util/slice"
"kubesphere.io/kubesphere/pkg/informers"
sliceutils "kubesphere.io/kubesphere/pkg/utils"
"kubesphere.io/kubesphere/pkg/utils/sliceutil"
)
type Authentication struct {
......@@ -87,6 +87,10 @@ func handleForbidden(w http.ResponseWriter, err error) int {
func permissionValidate(attrs authorizer.Attributes) (bool, error) {
if attrs.GetResource() == "users" && attrs.GetUser().GetName() == attrs.GetName() {
return true, nil
}
permitted, err := clusterRoleValidate(attrs)
if err != nil {
......@@ -164,7 +168,7 @@ func clusterRoleValidate(attrs authorizer.Attributes) (bool, error) {
for _, subject := range clusterRoleBinding.Subjects {
if (subject.Kind == v1.UserKind && subject.Name == attrs.GetUser().GetName()) ||
(subject.Kind == v1.GroupKind && sliceutils.HasString(attrs.GetUser().GetGroups(), subject.Name)) {
(subject.Kind == v1.GroupKind && sliceutil.HasString(attrs.GetUser().GetGroups(), subject.Name)) {
clusterRole, err := clusterRoleLister.Get(clusterRoleBinding.RoleRef.Name)
......@@ -198,11 +202,11 @@ func ruleMatchesResources(rule v1.PolicyRule, apiGroup string, resource string,
return false
}
if !sliceutils.HasString(rule.APIGroups, apiGroup) && !sliceutils.HasString(rule.APIGroups, v1.ResourceAll) {
if !sliceutil.HasString(rule.APIGroups, apiGroup) && !sliceutil.HasString(rule.APIGroups, v1.ResourceAll) {
return false
}
if len(rule.ResourceNames) > 0 && !sliceutils.HasString(rule.ResourceNames, resourceName) {
if len(rule.ResourceNames) > 0 && !sliceutil.HasString(rule.ResourceNames, resourceName) {
return false
}
......@@ -234,7 +238,7 @@ func ruleMatchesResources(rule v1.PolicyRule, apiGroup string, resource string,
func ruleMatchesRequest(rule v1.PolicyRule, apiGroup string, nonResourceURL string, resource string, subresource string, resourceName string, verb string) bool {
if !sliceutils.HasString(rule.Verbs, verb) && !sliceutils.HasString(rule.Verbs, v1.VerbAll) {
if !sliceutil.HasString(rule.Verbs, verb) && !sliceutil.HasString(rule.Verbs, v1.VerbAll) {
return false
}
......
......@@ -25,7 +25,6 @@ import (
"github.com/mholt/caddy/caddyhttp/httpserver"
"kubesphere.io/kubesphere/pkg/informers"
"kubesphere.io/kubesphere/pkg/signals"
)
func init() {
......@@ -43,13 +42,8 @@ func Setup(c *caddy.Controller) error {
if err != nil {
return err
}
if err != nil {
return err
}
stopChan := make(chan struct{}, 0)
c.OnStartup(func() error {
stopChan := signals.SetupSignalHandler()
informerFactory := informers.SharedInformerFactory()
informerFactory.Rbac().V1().Roles().Lister()
informerFactory.Rbac().V1().RoleBindings().Lister()
......@@ -61,6 +55,11 @@ func Setup(c *caddy.Controller) error {
return nil
})
c.OnShutdown(func() error {
close(stopChan)
return nil
})
httpserver.GetConfig(c).AddMiddleware(func(next httpserver.Handler) httpserver.Handler {
return &Authentication{Next: next, Rule: rule}
})
......
package apis
import (
"kubesphere.io/kubesphere/pkg/apis/tenant/v1alpha1"
)
func init() {
// Register the types with the Scheme so the components can map objects to GroupVersionKinds and back
AddToSchemes = append(AddToSchemes, v1alpha1.SchemeBuilder.AddToScheme)
}
......@@ -20,7 +20,6 @@ package v1alpha2
import (
"github.com/emicklei/go-restful"
"github.com/emicklei/go-restful-openapi"
"k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/runtime/schema"
"kubesphere.io/kubesphere/pkg/apiserver/iam"
"kubesphere.io/kubesphere/pkg/apiserver/runtime"
......@@ -46,6 +45,7 @@ func addWebService(c *restful.Container) error {
Doc("Token review").
Reads(iam.TokenReview{}).
Writes(iam.TokenReview{}).
Doc("k8s token review").
Metadata(restfulspec.KeyOpenAPITags, tags))
ws.Route(ws.POST("/login").
To(iam.LoginHandler).
......@@ -53,10 +53,10 @@ func addWebService(c *restful.Container) error {
Reads(iam.LoginRequest{}).
Writes(models.Token{}).
Metadata(restfulspec.KeyOpenAPITags, tags))
ws.Route(ws.GET("/users/{name}").
To(iam.UserDetail).
ws.Route(ws.GET("/users/{username}").
To(iam.DescribeUser).
Doc("User detail").
Param(ws.PathParameter("username", "username")).
Writes(models.User{}).
Metadata(restfulspec.KeyOpenAPITags, tags))
ws.Route(ws.POST("/users").
......@@ -67,11 +67,13 @@ func addWebService(c *restful.Container) error {
Metadata(restfulspec.KeyOpenAPITags, tags))
ws.Route(ws.DELETE("/users/{name}").
To(iam.DeleteUser).
Param(ws.PathParameter("name", "username")).
Doc("Delete user").
Writes(errors.Error{}).
Metadata(restfulspec.KeyOpenAPITags, tags))
ws.Route(ws.PUT("/users/{name}").
To(iam.UpdateUser).
Param(ws.PathParameter("name", "username")).
Reads(models.User{}).
Writes(errors.Error{}).
Doc("Update user").
......@@ -79,26 +81,29 @@ func addWebService(c *restful.Container) error {
ws.Route(ws.GET("/users/{name}/log").
To(iam.UserLoginLog).
Param(ws.PathParameter("name", "username")).
Doc("User login log").
Writes([]map[string]string{}).
Metadata(restfulspec.KeyOpenAPITags, tags))
ws.Route(ws.GET("/users").
To(iam.UserList).
To(iam.ListUsers).
Doc("User list").
Writes(models.PageableResponse{}).
Metadata(restfulspec.KeyOpenAPITags, tags))
ws.Route(ws.GET("/groups").
To(iam.RootGroupList).
To(iam.ListGroups).
Writes([]models.Group{}).
Doc("User group list").
Metadata(restfulspec.KeyOpenAPITags, tags))
ws.Route(ws.GET("/groups/{path}").
To(iam.GroupDetail).
To(iam.DescribeGroup).
Param(ws.PathParameter("path", "group path")).
Doc("User group detail").
Metadata(restfulspec.KeyOpenAPITags, tags))
ws.Route(ws.GET("/groups/{path}/users").
To(iam.GroupUsers).
To(iam.ListGroupUsers).
Param(ws.PathParameter("path", "group path")).
Doc("Group user list").
Metadata(restfulspec.KeyOpenAPITags, tags))
ws.Route(ws.POST("/groups").
......@@ -108,139 +113,108 @@ func addWebService(c *restful.Container) error {
Metadata(restfulspec.KeyOpenAPITags, tags))
ws.Route(ws.DELETE("/groups/{path}").
To(iam.DeleteGroup).
Param(ws.PathParameter("path", "group path")).
Doc("Delete user group").
Metadata(restfulspec.KeyOpenAPITags, tags))
ws.Route(ws.PUT("/groups/{path}").
To(iam.UpdateGroup).
Param(ws.PathParameter("path", "group path")).
Doc("Update user group").
Metadata(restfulspec.KeyOpenAPITags, tags))
ws.Route(ws.GET("/users/{username}/roles").
To(iam.UserRoles).
To(iam.ListUserRoles).
Param(ws.PathParameter("username", "username")).
Doc("Get user role list").
Metadata(restfulspec.KeyOpenAPITags, tags))
ws.Route(ws.GET("/namespaces/{namespace}/roles").
To(iam.ListRoles).
Param(ws.PathParameter("namespace", "namespace")).
Doc("Get role list").
Metadata(restfulspec.KeyOpenAPITags, tags))
ws.Route(ws.GET("/clusterroles").
To(iam.ListClusterRoles).
Doc("Get cluster role list").
Metadata(restfulspec.KeyOpenAPITags, tags))
ws.Route(ws.GET("/namespaces/{namespace}/roles/{role}/users").
To(iam.RoleUsers).
To(iam.ListRoleUsers).
Param(ws.PathParameter("namespace", "namespace")).
Param(ws.PathParameter("role", "role name")).
Doc("Get user list by role").
Metadata(restfulspec.KeyOpenAPITags, tags))
ws.Route(ws.GET("/namespaces/{namespace}/roles/{role}/rules").
To(iam.RoleRules).
Doc("Get role detail").
Metadata(restfulspec.KeyOpenAPITags, tags))
ws.Route(ws.GET("/namespaces/{namespace}/users").
To(iam.NamespaceUsers).
To(iam.ListNamespaceUsers).
Param(ws.PathParameter("namespace", "namespace")).
Doc("Get user list by namespace").
Metadata(restfulspec.KeyOpenAPITags, tags))
ws.Route(ws.GET("/clusterroles/{clusterrole}/users").
To(iam.ClusterRoleUsers).
To(iam.ListClusterRoleUsers).
Param(ws.PathParameter("clusterrole", "cluster role name")).
Doc("Get user list by cluster role").
Metadata(restfulspec.KeyOpenAPITags, tags))
ws.Route(ws.GET("/clusterroles/{clusterrole}/rules").
To(iam.ClusterRoleRules).
To(iam.ListClusterRoleRules).
Param(ws.PathParameter("clusterrole", "cluster role name")).
Doc("Get cluster role detail").
Metadata(restfulspec.KeyOpenAPITags, tags))
ws.Route(ws.GET("/rulesmapping/clusterroles").
To(iam.ClusterRulesMappingHandler).
To(iam.ClusterRulesMapping).
Doc("Get cluster role policy rules mapping").
Metadata(restfulspec.KeyOpenAPITags, tags))
ws.Route(ws.GET("/rulesmapping/roles").
To(iam.RulesMappingHandler).
To(iam.RulesMapping).
Doc("Get role policy rules mapping").
Metadata(restfulspec.KeyOpenAPITags, tags))
ws.Route(ws.GET("/workspaces/{workspace}/rules").
To(iam.WorkspaceRulesHandler).
Doc("Get workspace level policy rules").
ws.Route(ws.GET("/workspaces/{workspace}/roles").
To(iam.ListWorkspaceRoles).
Param(ws.PathParameter("workspace", "workspace name")).
Doc("List workspace role").
Metadata(restfulspec.KeyOpenAPITags, tags))
ws.Route(ws.GET("/workspaces/{workspace}/roles/{role}").
To(iam.DescribeWorkspaceRole).
Param(ws.PathParameter("workspace", "workspace name")).
Param(ws.PathParameter("role", "workspace role name")).
Doc("Describe workspace role").
Metadata(restfulspec.KeyOpenAPITags, tags))
ws.Route(ws.GET("/workspaces/{workspace}/roles/{role}/rules").
To(iam.ListWorkspaceRoleRules).
Param(ws.PathParameter("workspace", "workspace name")).
Param(ws.PathParameter("role", "workspace role name")).
Doc("Get workspace role policy rules").
Metadata(restfulspec.KeyOpenAPITags, tags))
ws.Route(ws.GET("/workspaces/{workspace}/members").
To(iam.WorkspaceMemberList).
To(iam.ListWorkspaceUsers).
Param(ws.PathParameter("workspace", "workspace name")).
Doc("Get workspace member list").
Metadata(restfulspec.KeyOpenAPITags, tags))
ws.Route(ws.GET("/namespaces/{namespace}/rules").
To(iam.NamespacesRulesHandler).
Doc("Get namespace level policy rules").
ws.Route(ws.POST("/workspaces/{workspace}/members").
To(iam.InviteUser).
Param(ws.PathParameter("workspace", "workspace name")).
Doc("Add user to workspace").
Metadata(restfulspec.KeyOpenAPITags, tags))
ws.Route(ws.GET("/devops/{devops}/rules").
To(iam.DevopsRulesHandler).
Doc("Get devops project level policy rules").
ws.Route(ws.POST("/workspaces/{workspace}/members").
To(iam.RemoveUser).
Param(ws.PathParameter("workspace", "workspace name")).
Doc("Remove user from workspace").
Metadata(restfulspec.KeyOpenAPITags, tags))
tags = []string{"Workspace"}
ws.Route(ws.GET("/workspaces").
To(iam.UserWorkspaceListHandler).
Doc("Get workspace list").
Metadata(restfulspec.KeyOpenAPITags, tags).
Writes([]models.Workspace{}))
ws.Route(ws.POST("/workspaces").
To(iam.WorkspaceCreateHandler).
Doc("Create workspace").
Metadata(restfulspec.KeyOpenAPITags, tags).
Writes(models.Workspace{}))
ws.Route(ws.DELETE("/workspaces/{name}").
To(iam.DeleteWorkspaceHandler).
Doc("Delete workspace").
Metadata(restfulspec.KeyOpenAPITags, tags).
Writes(errors.Error{}))
ws.Route(ws.GET("/workspaces/{name}").
To(iam.WorkspaceDetailHandler).
Doc("Get workspace detail").
Metadata(restfulspec.KeyOpenAPITags, tags).
Writes(models.Workspace{}))
ws.Route(ws.PUT("/workspaces/{name}").
To(iam.WorkspaceEditHandler).
Doc("Update workspace").
Metadata(restfulspec.KeyOpenAPITags, tags).
Writes(models.Workspace{}))
ws.Route(ws.GET("/workspaces/{name}/members/{member}").
To(iam.WorkspaceMemberDetail).
Doc("Get workspace member detail").
ws.Route(ws.GET("/workspaces/{workspace}/members/{username}").
To(iam.DescribeWorkspaceUser).
Param(ws.PathParameter("workspace", "workspace name")).
Param(ws.PathParameter("username", "username")).
Doc("Describe user in workspace").
Metadata(restfulspec.KeyOpenAPITags, tags))
ws.Route(ws.GET("/workspaces/{name}/roles").
To(iam.WorkspaceRoles).
Doc("Get workspace roles").
Metadata(restfulspec.KeyOpenAPITags, tags))
ws.Route(ws.POST("/workspaces/{name}/members").
To(iam.WorkspaceMemberInvite).
Doc("Add user to workspace").
ws.Route(ws.GET("/namespaces/{namespace}/roles/{role}/rules").
To(iam.ListRoleRules).
Param(ws.PathParameter("namespace", "namespace")).
Param(ws.PathParameter("role", "role name")).
Doc("Get namespace role policy rules").
Metadata(restfulspec.KeyOpenAPITags, tags))
ws.Route(ws.DELETE("/workspaces/{name}/members").
To(iam.WorkspaceMemberRemove).
Doc("Delete user from workspace").
ws.Route(ws.GET("/devops/{devops}/roles/{role}/rules").
To(iam.ListDevopsRoleRules).
Param(ws.PathParameter("devops", "devops project id")).
Param(ws.PathParameter("role", "devops role name")).
Doc("Get devops role policy rules").
Metadata(restfulspec.KeyOpenAPITags, tags))
tags = []string{"unstable"}
ws.Route(ws.GET("/workspaces/{workspace}/namespaces").
To(iam.UserNamespaceListHandler).
Doc("Get namespace list").
Metadata(restfulspec.KeyOpenAPITags, tags).
Writes(models.PageableResponse{}))
ws.Route(ws.POST("/workspaces/{name}/namespaces").
To(iam.NamespaceCreateHandler).
Doc("Create namespace").
Metadata(restfulspec.KeyOpenAPITags, tags).
Writes(v1.Namespace{}))
ws.Route(ws.DELETE("/workspaces/{name}/namespaces/{namespace}").To(iam.NamespaceDeleteHandler).Metadata(restfulspec.KeyOpenAPITags, tags))
ws.Route(ws.GET("/workspaces/{name}/namespaces/{namespace}").To(iam.NamespaceCheckHandler).Metadata(restfulspec.KeyOpenAPITags, tags))
ws.Route(ws.GET("/namespaces/{namespace}").To(iam.NamespaceCheckHandler))
// TODO move to /apis/resources.kubesphere.io/workspaces/{workspace}/members/{username}
ws.Route(ws.GET("/workspaces/{workspace}/members/{username}/namespaces").To(iam.NamespacesListHandler).Metadata(restfulspec.KeyOpenAPITags, tags))
ws.Route(ws.GET("/workspaces/{name}/members/{username}/devops").To(iam.DevOpsProjectHandler).Metadata(restfulspec.KeyOpenAPITags, tags))
// TODO /workspaces/{name}/roles/{role}
ws.Route(ws.GET("/workspaces/{name}/roles/{role}").To(iam.WorkspaceRoles).Metadata(restfulspec.KeyOpenAPITags, tags))
// TODO move to /apis/resources.kubesphere.io/devops
ws.Route(ws.GET("/workspaces/{name}/devops").To(iam.DevOpsProjectHandler).Metadata(restfulspec.KeyOpenAPITags, tags))
ws.Route(ws.POST("/workspaces/{name}/devops").To(iam.DevOpsProjectCreateHandler).Metadata(restfulspec.KeyOpenAPITags, tags))
ws.Route(ws.DELETE("/workspaces/{name}/devops/{id}").To(iam.DevOpsProjectDeleteHandler).Metadata(restfulspec.KeyOpenAPITags, tags))
// TODO merge into /groups
ws.Route(ws.GET("/groups/count").To(iam.CountHandler).Metadata(restfulspec.KeyOpenAPITags, tags))
ws.Route(ws.GET("/users/{name}/namespaces").To(iam.NamespacesListHandler).Metadata(restfulspec.KeyOpenAPITags, tags))
c.Add(ws)
return nil
}
......@@ -214,4 +214,4 @@ func addWebService(c *restful.Container) error {
c.Add(ws)
return nil
}
\ No newline at end of file
}
......@@ -52,7 +52,7 @@ func addWebService(c *restful.Container) error {
tags := []string{"Namespace resources"}
webservice.Route(webservice.GET("/namespaces/{namespace}/{resources}").
To(resources.NamespaceResourceHandler).
To(resources.ListResources).
Metadata(restfulspec.KeyOpenAPITags, tags).
Doc("Namespace level resource query").
Param(webservice.PathParameter("namespace", "which namespace")).
......@@ -69,7 +69,7 @@ func addWebService(c *restful.Container) error {
tags = []string{"Cluster resources"}
webservice.Route(webservice.GET("/{resources}").
To(resources.ClusterResourceHandler).
To(resources.ListResources).
Writes(models.PageableResponse{}).
Metadata(restfulspec.KeyOpenAPITags, tags).
Doc("Cluster level resource query").
......@@ -196,26 +196,19 @@ func addWebService(c *restful.Container) error {
webservice.Route(webservice.GET("/routers").
To(routers.GetAllRouters).
Doc("Get all routers").
Doc("List all routers").
Metadata(restfulspec.KeyOpenAPITags, tags).
Writes(corev1.Service{}))
webservice.Route(webservice.GET("/users/{username}/routers").
To(routers.GetAllRoutersOfUser).
Doc("Get routers for user").
Metadata(restfulspec.KeyOpenAPITags, tags).
Param(webservice.PathParameter("username", "")).
Writes(corev1.Service{}))
webservice.Route(webservice.GET("/namespaces/{namespace}/router").
To(routers.GetRouter).
Doc("Get router of a specified project").
Doc("List router of a specified project").
Metadata(restfulspec.KeyOpenAPITags, tags).
Param(webservice.PathParameter("namespace", "name of the project")))
webservice.Route(webservice.DELETE("/namespaces/{namespace}/router").
To(routers.DeleteRouter).
Doc("Get router of a specified project").
Doc("List router of a specified project").
Metadata(restfulspec.KeyOpenAPITags, tags).
Param(webservice.PathParameter("namespace", "name of the project")))
......
/*
Copyright 2019 The KubeSphere 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 tenant contains tenant API versions
package tenant
......@@ -15,30 +15,19 @@
limitations under the License.
*/
package resources
package install
import (
"github.com/emicklei/go-restful"
"net/http"
"kubesphere.io/kubesphere/pkg/errors"
"kubesphere.io/kubesphere/pkg/models/resources"
"kubesphere.io/kubesphere/pkg/params"
urlruntime "k8s.io/apimachinery/pkg/util/runtime"
tenantv1alpha2 "kubesphere.io/kubesphere/pkg/apis/tenant/v1alpha2"
"kubesphere.io/kubesphere/pkg/apiserver/runtime"
)
func ClusterResourceHandler(req *restful.Request, resp *restful.Response) {
resourceName := req.PathParameter("resources")
conditions, err := params.ParseConditions(req)
orderBy := req.QueryParameter(params.OrderByParam)
limit, offset := params.ParsePaging(req)
reverse := params.ParseReverse(req)
result, err := resources.ListClusterResource(resourceName, conditions, orderBy, reverse, limit, offset)
if err != nil {
resp.WriteHeaderAndEntity(http.StatusInternalServerError, errors.Wrap(err))
return
}
func init() {
Install(runtime.Container)
}
resp.WriteAsJson(result)
func Install(container *restful.Container) {
urlruntime.Must(tenantv1alpha2.AddToContainer(container))
}
/*
Copyright 2019 The KubeSphere 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 v1alpha1 contains API Schema definitions for the tenant v1alpha1 API group
// +k8s:openapi-gen=true
// +k8s:deepcopy-gen=package,register
// +k8s:conversion-gen=kubesphere.io/kubesphere/pkg/apis/tenant
// +k8s:defaulter-gen=TypeMeta
// +groupName=tenant.kubesphere.io
package v1alpha1
/*
Copyright 2019 The KubeSphere 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.
*/
// NOTE: Boilerplate only. Ignore this file.
// Package v1alpha1 contains API Schema definitions for the tenant v1alpha1 API group
// +k8s:openapi-gen=true
// +k8s:deepcopy-gen=package,register
// +k8s:conversion-gen=kubesphere.io/kubesphere/pkg/apis/tenant
// +k8s:defaulter-gen=TypeMeta
// +groupName=tenant.kubesphere.io
package v1alpha1
import (
"k8s.io/apimachinery/pkg/runtime/schema"
"sigs.k8s.io/controller-runtime/pkg/runtime/scheme"
)
var (
// SchemeGroupVersion is group version used to register these objects
SchemeGroupVersion = schema.GroupVersion{Group: "tenant.kubesphere.io", Version: "v1alpha1"}
// SchemeBuilder is used to add go types to the GroupVersionKind scheme
SchemeBuilder = &scheme.Builder{GroupVersion: SchemeGroupVersion}
// AddToScheme is required by pkg/client/...
AddToScheme = SchemeBuilder.AddToScheme
)
// Resource is required by pkg/client/listers/...
func Resource(resource string) schema.GroupResource {
return SchemeGroupVersion.WithResource(resource).GroupResource()
}
/*
Copyright 2019 The KubeSphere 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 v1alpha1
import (
"log"
"os"
"path/filepath"
"testing"
"k8s.io/client-go/kubernetes/scheme"
"k8s.io/client-go/rest"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/envtest"
)
var cfg *rest.Config
var c client.Client
func TestMain(m *testing.M) {
t := &envtest.Environment{
CRDDirectoryPaths: []string{filepath.Join("..", "..", "..", "..", "config", "crds")},
}
err := SchemeBuilder.AddToScheme(scheme.Scheme)
if err != nil {
log.Fatal(err)
}
if cfg, err = t.Start(); err != nil {
log.Fatal(err)
}
if c, err = client.New(cfg, client.Options{Scheme: scheme.Scheme}); err != nil {
log.Fatal(err)
}
code := m.Run()
t.Stop()
os.Exit(code)
}
/*
Copyright 2019 The KubeSphere 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 v1alpha1
import (
"k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN!
// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized.
// WorkspaceSpec defines the desired state of Workspace
type WorkspaceSpec struct {
Manager string `json:"manager,omitempty"`
Quotas v1.ResourceQuotaSpec `json:"quotas,omitempty"`
}
// WorkspaceStatus defines the observed state of Workspace
type WorkspaceStatus struct {
// INSERT ADDITIONAL STATUS FIELD - define observed state of cluster
// Important: Run "make" to regenerate code after modifying this file
Quotas v1.ResourceQuotaStatus `json:"quotas,omitempty"`
}
// +genclient
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// +genclient:nonNamespaced
// Workspace is the Schema for the workspaces API
// +k8s:openapi-gen=true
type Workspace struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
Spec WorkspaceSpec `json:"spec,omitempty"`
Status WorkspaceStatus `json:"status,omitempty"`
}
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// +genclient:nonNamespaced
// WorkspaceList contains a list of Workspace
type WorkspaceList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []Workspace `json:"items"`
}
func init() {
SchemeBuilder.Register(&Workspace{}, &WorkspaceList{})
}
/*
Copyright 2019 The KubeSphere 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 v1alpha1
import (
"testing"
"github.com/onsi/gomega"
"golang.org/x/net/context"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
)
func TestStorageWorkspace(t *testing.T) {
key := types.NamespacedName{
Name: "foo",
}
created := &Workspace{
ObjectMeta: metav1.ObjectMeta{
Name: "foo",
}}
g := gomega.NewGomegaWithT(t)
// Test Create
fetched := &Workspace{}
g.Expect(c.Create(context.TODO(), created)).NotTo(gomega.HaveOccurred())
g.Expect(c.Get(context.TODO(), key, fetched)).NotTo(gomega.HaveOccurred())
g.Expect(fetched).To(gomega.Equal(created))
// Test Updating the Labels
updated := fetched.DeepCopy()
updated.Labels = map[string]string{"hello": "world"}
g.Expect(c.Update(context.TODO(), updated)).NotTo(gomega.HaveOccurred())
g.Expect(c.Get(context.TODO(), key, fetched)).NotTo(gomega.HaveOccurred())
g.Expect(fetched).To(gomega.Equal(updated))
// Test Delete
g.Expect(c.Delete(context.TODO(), fetched)).NotTo(gomega.HaveOccurred())
g.Expect(c.Get(context.TODO(), key, fetched)).To(gomega.HaveOccurred())
}
// +build !ignore_autogenerated
/*
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 deepcopy-gen. DO NOT EDIT.
package v1alpha1
import (
"k8s.io/apimachinery/pkg/runtime"
)
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Workspace) DeepCopyInto(out *Workspace) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
in.Spec.DeepCopyInto(&out.Spec)
in.Status.DeepCopyInto(&out.Status)
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Workspace.
func (in *Workspace) DeepCopy() *Workspace {
if in == nil {
return nil
}
out := new(Workspace)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *Workspace) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
return nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *WorkspaceList) DeepCopyInto(out *WorkspaceList) {
*out = *in
out.TypeMeta = in.TypeMeta
out.ListMeta = in.ListMeta
if in.Items != nil {
in, out := &in.Items, &out.Items
*out = make([]Workspace, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WorkspaceList.
func (in *WorkspaceList) DeepCopy() *WorkspaceList {
if in == nil {
return nil
}
out := new(WorkspaceList)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *WorkspaceList) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
return nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *WorkspaceSpec) DeepCopyInto(out *WorkspaceSpec) {
*out = *in
in.Quotas.DeepCopyInto(&out.Quotas)
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WorkspaceSpec.
func (in *WorkspaceSpec) DeepCopy() *WorkspaceSpec {
if in == nil {
return nil
}
out := new(WorkspaceSpec)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *WorkspaceStatus) DeepCopyInto(out *WorkspaceStatus) {
*out = *in
in.Quotas.DeepCopyInto(&out.Quotas)
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WorkspaceStatus.
func (in *WorkspaceStatus) DeepCopy() *WorkspaceStatus {
if in == nil {
return nil
}
out := new(WorkspaceStatus)
in.DeepCopyInto(out)
return out
}
/*
Copyright 2019 The KubeSphere 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 v1alpha2
import (
"github.com/emicklei/go-restful"
"github.com/emicklei/go-restful-openapi"
"k8s.io/apimachinery/pkg/runtime/schema"
"kubesphere.io/kubesphere/pkg/apiserver/runtime"
"kubesphere.io/kubesphere/pkg/apiserver/tenant"
)
const GroupName = "tenant.kubesphere.io"
var GroupVersion = schema.GroupVersion{Group: GroupName, Version: "v1alpha2"}
var (
WebServiceBuilder = runtime.NewContainerBuilder(addWebService)
AddToContainer = WebServiceBuilder.AddToContainer
)
func addWebService(c *restful.Container) error {
tags := []string{"Tenant"}
ws := runtime.NewWebService(GroupVersion)
ws.Route(ws.GET("/workspaces").
To(tenant.ListWorkspaces).
Doc("List workspace by user").
Metadata(restfulspec.KeyOpenAPITags, tags))
ws.Route(ws.GET("/workspaces/{workspace}/rules").
To(tenant.ListWorkspaceRules).
Param(ws.PathParameter("workspace", "workspace name")).
Doc("List the rules for the current user").
Metadata(restfulspec.KeyOpenAPITags, tags))
ws.Route(ws.GET("/namespaces/{namespace}/rules").
To(tenant.ListNamespaceRules).
Param(ws.PathParameter("namespace", "namespace")).
Doc("List the rules for the current user").
Metadata(restfulspec.KeyOpenAPITags, tags))
ws.Route(ws.GET("/devops/{devops}/rules").
To(tenant.ListDevopsRules).
Param(ws.PathParameter("devops", "devops project id")).
Doc("List the rules for the current user").
Metadata(restfulspec.KeyOpenAPITags, tags))
ws.Route(ws.GET("/workspaces/{workspace}/namespaces").
To(tenant.ListNamespaces).
Param(ws.PathParameter("workspace", "workspace name")).
Doc("List the namespaces for the current user").
Metadata(restfulspec.KeyOpenAPITags, tags))
ws.Route(ws.GET("/workspaces/{workspace}/members/{username}/namespaces").
To(tenant.ListNamespaces).
Param(ws.PathParameter("workspace", "workspace name")).
Param(ws.PathParameter("username", "workspace member's username")).
Doc("List the namespaces for the workspace member").
Metadata(restfulspec.KeyOpenAPITags, tags))
ws.Route(ws.POST("/workspaces/{workspace}/namespaces").
To(tenant.CreateNamespace).
Param(ws.PathParameter("workspace", "workspace name")).
Doc("Create namespace").
Metadata(restfulspec.KeyOpenAPITags, tags))
ws.Route(ws.DELETE("/workspaces/{workspace}/namespaces/{namespace}").
To(tenant.DeleteNamespace).
Param(ws.PathParameter("workspace", "workspace name")).
Param(ws.PathParameter("namespace", "namespace")).
Doc("Delete namespace").
Metadata(restfulspec.KeyOpenAPITags, tags))
ws.Route(ws.GET("/workspaces/{workspace}/devops").
To(tenant.ListDevopsProjects).
Param(ws.PathParameter("workspace", "workspace name")).
Doc("List devops projects for the current user").
Metadata(restfulspec.KeyOpenAPITags, tags))
ws.Route(ws.GET("/workspaces/{workspace}/members/{username}/devops").
To(tenant.ListDevopsProjects).
Param(ws.PathParameter("workspace", "workspace name")).
Param(ws.PathParameter("username", "workspace member's username")).
Doc("List the devops projects for the workspace member").
Metadata(restfulspec.KeyOpenAPITags, tags))
ws.Route(ws.POST("/workspaces/{workspace}/devops").
To(tenant.CreateDevopsProject).
Param(ws.PathParameter("workspace", "workspace name")).
Doc("Create devops project").
Metadata(restfulspec.KeyOpenAPITags, tags))
ws.Route(ws.DELETE("/workspaces/{workspace}/devops").
To(tenant.DeleteDevopsProject).
Param(ws.PathParameter("workspace", "workspace name")).
Doc("Delete devops project").
Metadata(restfulspec.KeyOpenAPITags, tags))
c.Add(ws)
return nil
}
/*
Copyright 2019 The KubeSphere 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 install
import (
"github.com/emicklei/go-restful"
urlruntime "k8s.io/apimachinery/pkg/util/runtime"
terminalv1alpha2 "kubesphere.io/kubesphere/pkg/apis/terminal/v1alpha2"
"kubesphere.io/kubesphere/pkg/apiserver/runtime"
)
func init() {
Install(runtime.Container)
}
func Install(c *restful.Container) {
urlruntime.Must(terminalv1alpha2.AddToContainer(c))
}
/*
Copyright 2019 The KubeSphere 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 v1alpha2
import (
"github.com/emicklei/go-restful"
"github.com/emicklei/go-restful-openapi"
"k8s.io/apimachinery/pkg/runtime/schema"
"kubesphere.io/kubesphere/pkg/apiserver/runtime"
"kubesphere.io/kubesphere/pkg/apiserver/terminal"
"kubesphere.io/kubesphere/pkg/models"
)
const GroupName = "terminal.kubesphere.io"
var GroupVersion = schema.GroupVersion{Group: GroupName, Version: "v1alpha2"}
var (
WebServiceBuilder = runtime.NewContainerBuilder(addWebService)
AddToContainer = WebServiceBuilder.AddToContainer
)
func addWebService(c *restful.Container) error {
webservice := runtime.NewWebService(GroupVersion)
tags := []string{"Terminal"}
webservice.Route(webservice.GET("/namespace/{namespace}/pods/{pods}").
To(terminal.CreateTerminalSession).
Doc("create terminal session").
Metadata(restfulspec.KeyOpenAPITags, tags).
Writes(models.PodInfo{}))
path := runtime.ApiRootPath + "/" + GroupVersion.String() + "/sockjs"
c.Handle(path, terminal.NewTerminalHandler(path))
c.Add(webservice)
return nil
}
......@@ -20,56 +20,82 @@ package iam
import (
"github.com/emicklei/go-restful"
"k8s.io/api/rbac/v1"
k8serr "k8s.io/apimachinery/pkg/api/errors"
"kubesphere.io/kubesphere/pkg/params"
"net/http"
"sort"
"kubesphere.io/kubesphere/pkg/constants"
"kubesphere.io/kubesphere/pkg/errors"
"kubesphere.io/kubesphere/pkg/models/iam"
"kubesphere.io/kubesphere/pkg/models/iam/policy"
)
type roleList struct {
ClusterRoles []*v1.ClusterRole `json:"clusterRoles" protobuf:"bytes,2,rep,name=clusterRoles"`
ClusterRoles []*v1.ClusterRole `json:"clusterRole" protobuf:"bytes,2,rep,name=clusterRoles"`
Roles []*v1.Role `json:"roles" protobuf:"bytes,2,rep,name=roles"`
}
func RoleRules(req *restful.Request, resp *restful.Response) {
namespace := req.PathParameter("namespace")
func ListRoleUsers(req *restful.Request, resp *restful.Response) {
roleName := req.PathParameter("role")
namespace := req.PathParameter("namespace")
role, err := iam.GetRole(namespace, roleName)
users, err := iam.RoleUsers(namespace, roleName)
if err != nil {
resp.WriteError(http.StatusInternalServerError, err)
resp.WriteHeaderAndEntity(http.StatusInternalServerError, errors.Wrap(err))
return
}
rules, err := iam.GetRoleSimpleRules([]*v1.Role{role}, namespace)
resp.WriteAsJson(users)
}
func ListClusterRoles(req *restful.Request, resp *restful.Response) {
conditions, err := params.ParseConditions(req.QueryParameter(params.ConditionsParam))
orderBy := req.QueryParameter(params.OrderByParam)
limit, offset := params.ParsePaging(req.QueryParameter(params.PagingParam))
reverse := params.ParseReverse(req)
if err != nil {
resp.WriteError(http.StatusInternalServerError, err)
resp.WriteHeaderAndEntity(http.StatusBadRequest, errors.Wrap(err))
return
}
resp.WriteAsJson(rules[namespace])
result, err := iam.ListClusterRoles(conditions, orderBy, reverse, limit, offset)
if err != nil {
resp.WriteHeaderAndEntity(http.StatusInternalServerError, errors.Wrap(err))
return
}
resp.WriteAsJson(result)
}
func RoleUsers(req *restful.Request, resp *restful.Response) {
roleName := req.PathParameter("role")
func ListRoles(req *restful.Request, resp *restful.Response) {
namespace := req.PathParameter("namespace")
conditions, err := params.ParseConditions(req.QueryParameter(params.ConditionsParam))
orderBy := req.QueryParameter(params.OrderByParam)
limit, offset := params.ParsePaging(req.QueryParameter(params.PagingParam))
reverse := params.ParseReverse(req)
users, err := iam.RoleUsers(namespace, roleName)
if err != nil {
resp.WriteHeaderAndEntity(http.StatusBadRequest, errors.Wrap(err))
return
}
result, err := iam.ListRoles(namespace, conditions, orderBy, reverse, limit, offset)
if err != nil {
resp.WriteHeaderAndEntity(http.StatusInternalServerError, errors.Wrap(err))
return
}
resp.WriteAsJson(users)
resp.WriteAsJson(result)
}
func NamespaceUsers(req *restful.Request, resp *restful.Response) {
// List users by namespace
func ListNamespaceUsers(req *restful.Request, resp *restful.Response) {
namespace := req.PathParameter("namespace")
......@@ -80,25 +106,26 @@ func NamespaceUsers(req *restful.Request, resp *restful.Response) {
return
}
// sort by time by default
sort.Slice(users, func(i, j int) bool {
return users[i].Username < users[j].Username
return users[i].RoleBindTime.After(*users[j].RoleBindTime)
})
resp.WriteAsJson(users)
}
func UserRoles(req *restful.Request, resp *restful.Response) {
func ListUserRoles(req *restful.Request, resp *restful.Response) {
username := req.PathParameter("username")
roles, err := iam.GetRoles(username, "")
roles, err := iam.GetUserRoles("", username)
if err != nil {
resp.WriteHeaderAndEntity(http.StatusInternalServerError, errors.Wrap(err))
return
}
clusterRoles, err := iam.GetClusterRoles(username)
_, clusterRoles, err := iam.GetUserClusterRoles(username)
if err != nil {
resp.WriteHeaderAndEntity(http.StatusInternalServerError, errors.Wrap(err))
......@@ -112,79 +139,62 @@ func UserRoles(req *restful.Request, resp *restful.Response) {
resp.WriteAsJson(roleList)
}
func NamespaceRulesHandler(req *restful.Request, resp *restful.Response) {
namespace := req.PathParameter("namespace")
username := req.HeaderParameter(constants.UserNameHeader)
clusterRoles, err := iam.GetClusterRoles(username)
if err != nil {
resp.WriteError(http.StatusInternalServerError, err)
return
}
roles, err := iam.GetRoles(username, namespace)
if err != nil {
resp.WriteError(http.StatusInternalServerError, err)
return
}
for _, clusterRole := range clusterRoles {
role := new(v1.Role)
role.Name = clusterRole.Name
role.Labels = clusterRole.Labels
role.Namespace = namespace
role.Annotations = clusterRole.Annotations
role.Kind = "Role"
role.Rules = clusterRole.Rules
roles = append(roles, role)
}
rules, err := iam.GetRoleSimpleRules(roles, namespace)
if err != nil {
resp.WriteError(http.StatusInternalServerError, err)
return
}
resp.WriteAsJson(rules[namespace])
}
func RulesMappingHandler(req *restful.Request, resp *restful.Response) {
func RulesMapping(req *restful.Request, resp *restful.Response) {
rules := policy.RoleRuleMapping
resp.WriteAsJson(rules)
}
func ClusterRulesMappingHandler(req *restful.Request, resp *restful.Response) {
func ClusterRulesMapping(req *restful.Request, resp *restful.Response) {
rules := policy.ClusterRoleRuleMapping
resp.WriteAsJson(rules)
}
func ClusterRoleRules(req *restful.Request, resp *restful.Response) {
func ListClusterRoleRules(req *restful.Request, resp *restful.Response) {
clusterRoleName := req.PathParameter("clusterrole")
clusterRole, err := iam.GetClusterRole(clusterRoleName)
rules, err := iam.GetClusterRoleSimpleRules(clusterRoleName)
if err != nil {
resp.WriteError(http.StatusInternalServerError, err)
return
}
rules, err := iam.GetClusterRoleSimpleRules([]*v1.ClusterRole{clusterRole})
resp.WriteAsJson(rules)
}
func ListClusterRoleUsers(req *restful.Request, resp *restful.Response) {
clusterRoleName := req.PathParameter("clusterrole")
conditions, err := params.ParseConditions(req.QueryParameter(params.ConditionsParam))
orderBy := req.QueryParameter(params.OrderByParam)
limit, offset := params.ParsePaging(req.QueryParameter(params.PagingParam))
reverse := params.ParseReverse(req)
if err != nil {
resp.WriteHeaderAndEntity(http.StatusBadRequest, errors.Wrap(err))
return
}
result, err := iam.ListClusterRoleUsers(clusterRoleName, conditions, orderBy, reverse, limit, offset)
if err != nil {
resp.WriteError(http.StatusInternalServerError, err)
if k8serr.IsNotFound(err) {
resp.WriteError(http.StatusNotFound, err)
} else {
resp.WriteError(http.StatusInternalServerError, err)
}
return
}
resp.WriteAsJson(rules)
resp.WriteAsJson(result)
}
func ClusterRoleUsers(req *restful.Request, resp *restful.Response) {
clusterRoleName := req.PathParameter("clusterrole")
func ListRoleRules(req *restful.Request, resp *restful.Response) {
namespaceName := req.PathParameter("namespace")
roleName := req.PathParameter("role")
users, err := iam.ClusterRoleUsers(clusterRoleName)
rules, err := iam.GetRoleSimpleRules(namespaceName, roleName)
if err != nil {
resp.WriteError(http.StatusInternalServerError, err)
resp.WriteHeaderAndEntity(http.StatusInternalServerError, errors.Wrap(err))
return
}
resp.WriteAsJson(users)
resp.WriteAsJson(rules)
}
......@@ -18,17 +18,14 @@
package iam
import (
"fmt"
"github.com/dgrijalva/jwt-go"
"github.com/emicklei/go-restful"
"kubesphere.io/kubesphere/pkg/models"
"kubesphere.io/kubesphere/pkg/simple/client/ldap"
"kubesphere.io/kubesphere/pkg/utils/iputil"
"kubesphere.io/kubesphere/pkg/utils/jwtutil"
"net/http"
"kubesphere.io/kubesphere/pkg/errors"
"kubesphere.io/kubesphere/pkg/models/iam"
"kubesphere.io/kubesphere/pkg/utils"
jwtutils "kubesphere.io/kubesphere/pkg/utils/jwt"
)
type Spec struct {
......@@ -63,11 +60,11 @@ func LoginHandler(req *restful.Request, resp *restful.Response) {
err := req.ReadEntity(&loginRequest)
if err != nil || loginRequest.Username == "" || loginRequest.Password == "" {
resp.WriteHeaderAndEntity(http.StatusUnauthorized, errors.Wrap(fmt.Errorf("incorrect username or password")))
resp.WriteHeaderAndEntity(http.StatusUnauthorized, errors.New("incorrect username or password"))
return
}
ip := utils.RemoteIp(req.Request)
ip := iputil.RemoteIp(req.Request)
token, err := iam.Login(loginRequest.Username, loginRequest.Password, ip)
......@@ -76,7 +73,7 @@ func LoginHandler(req *restful.Request, resp *restful.Response) {
return
}
resp.WriteAsJson(models.Token{Token: token})
resp.WriteAsJson(token)
}
// k8s token review
......@@ -91,13 +88,13 @@ func TokenReviewHandler(req *restful.Request, resp *restful.Response) {
}
if tokenReview.Spec == nil {
resp.WriteHeaderAndEntity(http.StatusBadRequest, errors.Wrap(fmt.Errorf("token must not be null")))
resp.WriteHeaderAndEntity(http.StatusBadRequest, errors.New("token must not be null"))
return
}
uToken := tokenReview.Spec.Token
token, err := jwtutils.ValidateToken(uToken)
token, err := jwtutil.ValidateToken(uToken)
if err != nil {
failed := TokenReview{APIVersion: APIVersion,
......@@ -112,24 +109,29 @@ func TokenReviewHandler(req *restful.Request, resp *restful.Response) {
claims := token.Claims.(jwt.MapClaims)
username := claims["username"].(string)
username, ok := claims["username"].(string)
conn, err := ldap.Client()
if !ok {
resp.WriteHeaderAndEntity(http.StatusBadRequest, errors.New("username not found"))
return
}
user, err := iam.GetUserInfo(username)
if err != nil {
resp.WriteHeaderAndEntity(http.StatusInternalServerError, errors.Wrap(err))
return
}
defer conn.Close()
user, err := iam.UserDetail(username, conn)
groups, err := iam.GetUserGroups(username)
if err != nil {
resp.WriteHeaderAndEntity(http.StatusInternalServerError, errors.Wrap(err))
return
}
user.Groups = groups
success := TokenReview{APIVersion: APIVersion,
Kind: KindTokenReview,
Status: &Status{
......
......@@ -19,7 +19,6 @@ package iam
import (
"fmt"
ldapclient "kubesphere.io/kubesphere/pkg/simple/client/ldap"
"net/http"
"regexp"
"strings"
......@@ -33,8 +32,6 @@ import (
)
func CreateGroup(req *restful.Request, resp *restful.Response) {
//var json map[string]interface{}
var group models.Group
err := req.ReadEntity(&group)
......@@ -45,19 +42,18 @@ func CreateGroup(req *restful.Request, resp *restful.Response) {
}
if !regexp.MustCompile("[a-z0-9]([-a-z0-9]*[a-z0-9])?").MatchString(group.Name) {
resp.WriteHeaderAndEntity(http.StatusBadRequest, fmt.Errorf("incalid group name %s", group))
return
}
if group.Creator == "" {
resp.WriteHeaderAndEntity(http.StatusBadRequest, fmt.Errorf("creator should not be null"))
resp.WriteHeaderAndEntity(http.StatusBadRequest, errors.New(fmt.Sprintf("incalid group name %s", group)))
return
}
created, err := iam.CreateGroup(group)
created, err := iam.CreateGroup(&group)
if err != nil {
resp.WriteHeaderAndEntity(http.StatusInternalServerError, errors.Wrap(err))
if ldap.IsErrorWithCode(err, ldap.LDAPResultEntryAlreadyExists) {
resp.WriteHeaderAndEntity(http.StatusConflict, errors.Wrap(err))
} else {
resp.WriteHeaderAndEntity(http.StatusInternalServerError, errors.Wrap(err))
}
return
}
......@@ -75,6 +71,10 @@ func DeleteGroup(req *restful.Request, resp *restful.Response) {
err := iam.DeleteGroup(path)
if err != nil {
if ldap.IsErrorWithCode(err, ldap.LDAPResultNoSuchObject) {
resp.WriteHeaderAndEntity(http.StatusNotFound, errors.Wrap(err))
return
}
resp.WriteHeaderAndEntity(http.StatusInternalServerError, errors.Wrap(err))
return
}
......@@ -106,23 +106,18 @@ func UpdateGroup(req *restful.Request, resp *restful.Response) {
}
func GroupDetail(req *restful.Request, resp *restful.Response) {
func DescribeGroup(req *restful.Request, resp *restful.Response) {
path := req.PathParameter("path")
conn, err := ldapclient.Client()
if err != nil {
resp.WriteHeaderAndEntity(http.StatusInternalServerError, errors.Wrap(err))
return
}
defer conn.Close()
group, err := iam.GroupDetail(path, conn)
group, err := iam.DescribeGroup(path)
if err != nil {
resp.WriteHeaderAndEntity(http.StatusInternalServerError, errors.Wrap(err))
if ldap.IsErrorWithCode(err, ldap.LDAPResultNoSuchObject) {
resp.WriteHeaderAndEntity(http.StatusNotFound, errors.Wrap(err))
} else {
resp.WriteHeaderAndEntity(http.StatusInternalServerError, errors.Wrap(err))
}
return
}
......@@ -130,20 +125,11 @@ func GroupDetail(req *restful.Request, resp *restful.Response) {
}
func GroupUsers(req *restful.Request, resp *restful.Response) {
func ListGroupUsers(req *restful.Request, resp *restful.Response) {
path := req.PathParameter("path")
conn, err := ldapclient.Client()
if err != nil {
resp.WriteHeaderAndEntity(http.StatusInternalServerError, errors.Wrap(err))
return
}
defer conn.Close()
group, err := iam.GroupDetail(path, conn)
group, err := iam.DescribeGroup(path)
if err != nil {
resp.WriteHeaderAndEntity(http.StatusInternalServerError, errors.Wrap(err))
......@@ -156,10 +142,10 @@ func GroupUsers(req *restful.Request, resp *restful.Response) {
for i := 0; i < len(group.Members); i++ {
name := group.Members[i]
user, err := iam.UserDetail(name, conn)
user, err := iam.DescribeUser(name)
if err != nil {
if ldap.IsErrorWithCode(err, 32) {
if ldap.IsErrorWithCode(err, ldap.LDAPResultNoSuchObject) {
group.Members = append(group.Members[:i], group.Members[i+1:]...)
i--
modify = true
......@@ -170,25 +156,6 @@ func GroupUsers(req *restful.Request, resp *restful.Response) {
}
}
clusterRoles, err := iam.GetClusterRoles(name)
if err != nil {
resp.WriteHeaderAndEntity(http.StatusInternalServerError, errors.Wrap(err))
return
}
for i := 0; i < len(clusterRoles); i++ {
if clusterRoles[i].Annotations["rbac.authorization.k8s.io/clusterrole"] == "true" {
user.ClusterRole = clusterRoles[i].Name
break
}
}
if group.Path == group.Name {
workspaceRole := iam.GetWorkspaceRole(clusterRoles, group.Name)
user.WorkspaceRole = workspaceRole
}
users = append(users, user)
}
......@@ -200,18 +167,7 @@ func GroupUsers(req *restful.Request, resp *restful.Response) {
}
func CountHandler(req *restful.Request, resp *restful.Response) {
count, err := iam.CountChild("")
if err != nil {
resp.WriteHeaderAndEntity(http.StatusInternalServerError, errors.Wrap(err))
return
}
resp.WriteAsJson(map[string]int{"total_count": count})
}
func RootGroupList(req *restful.Request, resp *restful.Response) {
func ListGroups(req *restful.Request, resp *restful.Response) {
array := req.QueryParameter("path")
......@@ -229,18 +185,9 @@ func RootGroupList(req *restful.Request, resp *restful.Response) {
groups := make([]*models.Group, 0)
conn, err := ldapclient.Client()
if err != nil {
resp.WriteHeaderAndEntity(http.StatusInternalServerError, errors.Wrap(err))
return
}
defer conn.Close()
for _, v := range paths {
path := strings.TrimSpace(v)
group, err := iam.GroupDetail(path, conn)
group, err := iam.DescribeGroup(path)
if err != nil {
resp.WriteHeaderAndEntity(http.StatusInternalServerError, errors.Wrap(err))
return
......
......@@ -19,9 +19,9 @@ package iam
import (
"fmt"
"kubesphere.io/kubesphere/pkg/params"
"net/http"
"regexp"
"strconv"
"strings"
"github.com/emicklei/go-restful"
......@@ -31,7 +31,6 @@ import (
"kubesphere.io/kubesphere/pkg/errors"
"kubesphere.io/kubesphere/pkg/models"
"kubesphere.io/kubesphere/pkg/models/iam"
ldapclient "kubesphere.io/kubesphere/pkg/simple/client/ldap"
)
const (
......@@ -63,7 +62,7 @@ func CreateUser(req *restful.Request, resp *restful.Response) {
return
}
err = iam.CreateUser(user)
created, err := iam.CreateUser(&user)
if err != nil {
if ldap.IsErrorWithCode(err, ldap.LDAPResultEntryAlreadyExists) {
......@@ -74,7 +73,7 @@ func CreateUser(req *restful.Request, resp *restful.Response) {
return
}
resp.WriteAsJson(errors.None)
resp.WriteAsJson(created)
}
func DeleteUser(req *restful.Request, resp *restful.Response) {
......@@ -100,7 +99,7 @@ func DeleteUser(req *restful.Request, resp *restful.Response) {
func UpdateUser(req *restful.Request, resp *restful.Response) {
usernameInPath := req.PathParameter("name")
username := req.HeaderParameter(constants.UserNameHeader)
usernameInHeader := req.HeaderParameter(constants.UserNameHeader)
var user models.User
err := req.ReadEntity(&user)
......@@ -125,22 +124,23 @@ func UpdateUser(req *restful.Request, resp *restful.Response) {
return
}
if username == user.Username && user.Password != "" {
_, err = iam.Login(username, user.CurrentPassword, "")
// change password by self
if usernameInHeader == user.Username && user.Password != "" {
_, err = iam.Login(usernameInHeader, user.CurrentPassword, "")
if err != nil {
resp.WriteHeaderAndEntity(http.StatusBadRequest, errors.Wrap(fmt.Errorf("incorrect current password")))
return
}
}
err = iam.UpdateUser(user)
result, err := iam.UpdateUser(&user)
if err != nil {
resp.WriteHeaderAndEntity(http.StatusInternalServerError, errors.Wrap(err))
return
}
resp.WriteAsJson(errors.None)
resp.WriteAsJson(result)
}
func UserLoginLog(req *restful.Request, resp *restful.Response) {
......@@ -167,20 +167,11 @@ func UserLoginLog(req *restful.Request, resp *restful.Response) {
resp.WriteAsJson(result)
}
func CurrentUserDetail(req *restful.Request, resp *restful.Response) {
username := req.HeaderParameter(constants.UserNameHeader)
conn, err := ldapclient.Client()
if err != nil {
resp.WriteHeaderAndEntity(http.StatusInternalServerError, errors.Wrap(err))
return
}
func DescribeUser(req *restful.Request, resp *restful.Response) {
defer conn.Close()
username := req.PathParameter("username")
user, err := iam.UserDetail(username, conn)
user, err := iam.DescribeUser(username)
if err != nil {
if ldap.IsErrorWithCode(err, ldap.LDAPResultNoSuchObject) {
......@@ -191,186 +182,81 @@ func CurrentUserDetail(req *restful.Request, resp *restful.Response) {
return
}
clusterRoles, err := iam.GetClusterRoles(username)
clusterRole, err := iam.GetUserClusterRole(username)
if err != nil {
resp.WriteHeaderAndEntity(http.StatusInternalServerError, errors.Wrap(err))
return
}
clusterRules, err := iam.GetClusterRoleSimpleRules(clusterRoles)
if err != nil {
resp.WriteHeaderAndEntity(http.StatusInternalServerError, errors.Wrap(err))
return
}
for i := 0; i < len(clusterRoles); i++ {
if clusterRoles[i].Annotations["rbac.authorization.k8s.io/clusterrole"] == "true" {
user.ClusterRole = clusterRoles[i].Name
break
}
}
user.ClusterRules = clusterRules
resp.WriteAsJson(user)
}
func NamespacesListHandler(req *restful.Request, resp *restful.Response) {
username := req.PathParameter("name")
user.ClusterRole = clusterRole.Name
namespaces, err := iam.GetNamespaces(username)
clusterRules, err := iam.GetUserClusterSimpleRules(username)
if err != nil {
resp.WriteHeaderAndEntity(http.StatusInternalServerError, errors.Wrap(err))
return
}
resp.WriteAsJson(namespaces)
}
func UserDetail(req *restful.Request, resp *restful.Response) {
username := req.PathParameter("name")
usernameFromHeader := req.HeaderParameter(constants.UserNameHeader)
if username == usernameFromHeader {
CurrentUserDetail(req, resp)
return
}
conn, err := ldapclient.Client()
if err != nil {
resp.WriteHeaderAndEntity(http.StatusInternalServerError, errors.Wrap(err))
return
result := struct {
*models.User
ClusterRules []models.SimpleRule `json:"cluster_rules"`
}{
User: user,
ClusterRules: clusterRules,
}
defer conn.Close()
user, err := iam.UserDetail(username, conn)
if err != nil {
resp.WriteHeaderAndEntity(http.StatusInternalServerError, errors.Wrap(err))
return
}
resp.WriteAsJson(result)
}
clusterRoles, err := iam.GetClusterRoles(username)
func Precheck(req *restful.Request, resp *restful.Response) {
if err != nil {
resp.WriteHeaderAndEntity(http.StatusInternalServerError, errors.Wrap(err))
return
}
check := req.QueryParameter("check")
clusterRules, err := iam.GetClusterRoleSimpleRules(clusterRoles)
exist, err := iam.UserCreateCheck(check)
if err != nil {
resp.WriteHeaderAndEntity(http.StatusInternalServerError, errors.Wrap(err))
return
}
workspaceRoles := iam.GetWorkspaceRoles(clusterRoles)
for i := 0; i < len(clusterRoles); i++ {
if clusterRoles[i].Annotations["rbac.authorization.k8s.io/clusterrole"] == "true" {
user.ClusterRole = clusterRoles[i].Name
break
}
}
user.ClusterRules = clusterRules
user.WorkspaceRoles = workspaceRoles
resp.WriteAsJson(user)
resp.WriteAsJson(map[string]bool{"exist": exist})
}
func UserList(req *restful.Request, resp *restful.Response) {
limit, err := strconv.Atoi(req.QueryParameter("limit"))
if err != nil {
limit = 65535
}
offset, err := strconv.Atoi(req.QueryParameter("offset"))
if err != nil {
offset = 0
}
func ListUsers(req *restful.Request, resp *restful.Response) {
if check := req.QueryParameter("check"); check != "" {
exist, err := iam.UserCreateCheck(check)
if err != nil {
resp.WriteHeaderAndEntity(http.StatusInternalServerError, errors.Wrap(err))
return
}
resp.WriteAsJson(map[string]bool{"exist": exist})
Precheck(req, resp)
return
}
conn, err := ldapclient.Client()
limit, offset := params.ParsePaging(req.QueryParameter(params.PagingParam))
conditions, err := params.ParseConditions(req.QueryParameter(params.ConditionsParam))
orderBy := req.QueryParameter(params.OrderByParam)
reverse := params.ParseReverse(req)
names := params.ParseArray(req.QueryParameter(params.NameParam))
if err != nil {
resp.WriteHeaderAndEntity(http.StatusInternalServerError, errors.Wrap(err))
resp.WriteHeaderAndEntity(http.StatusBadRequest, errors.Wrap(err))
return
}
if len(names) > 0 {
users, err := iam.ListUsersByName(names)
defer conn.Close()
if query := req.QueryParameter("name"); query != "" {
names := strings.Split(query, ",")
users := make([]*models.User, 0)
for _, name := range names {
user, err := iam.UserDetail(name, conn)
if err != nil {
if ldap.IsErrorWithCode(err, 32) {
continue
} else {
resp.WriteHeaderAndEntity(http.StatusInternalServerError, errors.Wrap(err))
return
}
}
users = append(users, user)
if err != nil {
resp.WriteHeaderAndEntity(http.StatusBadRequest, errors.Wrap(err))
return
}
resp.WriteAsJson(users)
return
}
var total int
var users []models.User
if query := req.QueryParameter("search"); query != "" {
total, users, err = iam.Search(query, limit, offset)
} else if query := req.QueryParameter("keyword"); query != "" {
total, users, err = iam.Search(query, limit, offset)
} else {
total, users, err = iam.UserList(limit, offset)
}
users, err := iam.ListUsers(conditions, orderBy, reverse, limit, offset)
if err != nil {
resp.WriteHeaderAndEntity(http.StatusInternalServerError, errors.Wrap(err))
return
}
for i := 0; i < len(users); i++ {
clusterRoles, err := iam.GetClusterRoles(users[i].Username)
if err != nil {
resp.WriteHeaderAndEntity(http.StatusInternalServerError, errors.Wrap(err))
return
}
for j := 0; j < len(clusterRoles); j++ {
if clusterRoles[j].Annotations["rbac.authorization.k8s.io/clusterrole"] == "true" {
users[i].ClusterRole = clusterRoles[j].Name
break
}
}
}
items := make([]interface{}, 0)
for _, u := range users {
items = append(items, u)
}
resp.WriteAsJson(models.PageableResponse{Items: items, TotalCount: total})
resp.WriteAsJson(users)
}
......@@ -16,39 +16,3 @@
*/
package iam
import "sync"
type Counter struct {
value int
m *sync.Mutex
}
func NewCounter(value int) Counter {
c := Counter{}
c.m = &sync.Mutex{}
c.Set(value)
return c
}
func (c *Counter) Set(value int) {
c.m.Lock()
c.value = value
c.m.Unlock()
}
func (c *Counter) Add(value int) {
c.m.Lock()
c.value += value
c.m.Unlock()
}
func (c *Counter) Sub(value int) {
c.m.Lock()
c.value -= value
c.m.Unlock()
}
func (c *Counter) Get() int {
return c.value
}
此差异已折叠。
......@@ -21,15 +21,17 @@ import (
"github.com/emicklei/go-restful"
"kubesphere.io/kubesphere/pkg/errors"
"kubesphere.io/kubesphere/pkg/models/applications"
//"kubesphere.io/kubesphere/pkg/models/applications"
"kubesphere.io/kubesphere/pkg/params"
"net/http"
)
func ApplicationHandler(req *restful.Request, resp *restful.Response) {
limit, offset := params.ParsePaging(req)
limit, offset := params.ParsePaging(req.QueryParameter(params.PagingParam))
clusterId := req.QueryParameter("cluster_id")
runtimeId := req.QueryParameter("runtime_id")
conditions, err := params.ParseConditions(req)
conditions, err := params.ParseConditions(req.QueryParameter(params.ConditionsParam))
if err != nil {
if err != nil {
resp.WriteHeaderAndEntity(http.StatusBadRequest, errors.Wrap(err))
......
......@@ -19,22 +19,39 @@ package resources
import (
"github.com/emicklei/go-restful"
"kubesphere.io/kubesphere/pkg/models"
"kubesphere.io/kubesphere/pkg/models/resources"
"net/http"
"kubesphere.io/kubesphere/pkg/errors"
"kubesphere.io/kubesphere/pkg/models/resources"
"kubesphere.io/kubesphere/pkg/params"
)
func NamespaceResourceHandler(req *restful.Request, resp *restful.Response) {
func ListResources(req *restful.Request, resp *restful.Response) {
namespace := req.PathParameter("namespace")
resourceName := req.PathParameter("resources")
conditions, err := params.ParseConditions(req)
conditions, err := params.ParseConditions(req.QueryParameter(params.ConditionsParam))
orderBy := req.QueryParameter(params.OrderByParam)
limit, offset := params.ParsePaging(req)
limit, offset := params.ParsePaging(req.QueryParameter(params.PagingParam))
reverse := params.ParseReverse(req)
names := params.ParseArray(req.QueryParameter(params.NameParam))
result, err := resources.ListNamespaceResource(namespace, resourceName, conditions, orderBy, reverse, limit, offset)
if orderBy == "" {
orderBy = resources.CreateTime
reverse = true
}
if err != nil {
resp.WriteHeaderAndEntity(http.StatusBadRequest, errors.Wrap(err))
return
}
var result *models.PageableResponse
if len(names) > 0 {
result, err = resources.ListResourcesByName(namespace, resourceName, names)
} else {
result, err = resources.ListResources(namespace, resourceName, conditions, orderBy, reverse, limit, offset)
}
if err != nil {
resp.WriteHeaderAndEntity(http.StatusInternalServerError, errors.Wrap(err))
......
......@@ -50,21 +50,6 @@ func GetAllRouters(request *restful.Request, response *restful.Response) {
response.WriteAsJson(routers)
}
// Get all namespace ingress controller services for user
func GetAllRoutersOfUser(request *restful.Request, response *restful.Response) {
username := request.PathParameter("username")
routers, err := routers.GetAllRoutersOfUser(username)
if err != nil {
response.WriteHeaderAndEntity(http.StatusInternalServerError, errors.Wrap(err))
return
}
response.WriteAsJson(routers)
}
// Get ingress controller service for specified namespace
func GetRouter(request *restful.Request, response *restful.Response) {
......
/*
Copyright 2019 The KubeSphere 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 tenant
import (
"github.com/emicklei/go-restful"
"k8s.io/api/core/v1"
k8serr "k8s.io/apimachinery/pkg/api/errors"
"kubesphere.io/kubesphere/pkg/apis/tenant/v1alpha1"
"kubesphere.io/kubesphere/pkg/constants"
"kubesphere.io/kubesphere/pkg/errors"
"kubesphere.io/kubesphere/pkg/models"
"kubesphere.io/kubesphere/pkg/models/iam"
"kubesphere.io/kubesphere/pkg/models/tenant"
"kubesphere.io/kubesphere/pkg/models/workspaces"
"kubesphere.io/kubesphere/pkg/params"
"log"
"net/http"
)
func ListWorkspaceRules(req *restful.Request, resp *restful.Response) {
workspace := req.PathParameter("workspace")
username := req.HeaderParameter(constants.UserNameHeader)
rules, err := iam.GetUserWorkspaceSimpleRules(workspace, username)
if err != nil {
resp.WriteHeaderAndEntity(http.StatusInternalServerError, errors.Wrap(err))
return
}
resp.WriteAsJson(rules)
}
func ListWorkspaces(req *restful.Request, resp *restful.Response) {
username := req.HeaderParameter(constants.UserNameHeader)
conditions, err := params.ParseConditions(req.QueryParameter(params.ConditionsParam))
orderBy := req.QueryParameter(params.OrderByParam)
limit, offset := params.ParsePaging(req.QueryParameter(params.PagingParam))
reverse := params.ParseReverse(req)
if err != nil {
resp.WriteHeaderAndEntity(http.StatusBadRequest, errors.Wrap(err))
return
}
result, err := tenant.ListWorkspaces(username, conditions, orderBy, reverse, limit, offset)
if err != nil {
resp.WriteHeaderAndEntity(http.StatusInternalServerError, errors.Wrap(err))
return
}
resp.WriteAsJson(result)
}
func ListNamespaces(req *restful.Request, resp *restful.Response) {
workspace := req.PathParameter("workspace")
username := req.PathParameter("username")
// /workspaces/{workspace}/members/{username}/namespaces
if username == "" {
// /workspaces/{workspace}/namespaces
username = req.HeaderParameter(constants.UserNameHeader)
}
conditions, err := params.ParseConditions(req.QueryParameter(params.ConditionsParam))
orderBy := req.QueryParameter(params.OrderByParam)
limit, offset := params.ParsePaging(req.QueryParameter(params.PagingParam))
reverse := params.ParseReverse(req)
if err != nil {
resp.WriteHeaderAndEntity(http.StatusBadRequest, errors.Wrap(err))
return
}
conditions.Match["kubesphere.io/workspace"] = workspace
result, err := tenant.ListNamespaces(username, conditions, orderBy, reverse, limit, offset)
if err != nil {
resp.WriteHeaderAndEntity(http.StatusInternalServerError, errors.Wrap(err))
return
}
resp.WriteAsJson(result)
}
func CreateNamespace(req *restful.Request, resp *restful.Response) {
workspaceName := req.PathParameter("workspace")
username := req.HeaderParameter(constants.UserNameHeader)
var namespace v1.Namespace
err := req.ReadEntity(&namespace)
if err != nil {
resp.WriteHeaderAndEntity(http.StatusBadRequest, errors.Wrap(err))
return
}
workspace, err := tenant.GetWorkspace(workspaceName)
err = checkResourceQuotas(workspace)
if err != nil {
resp.WriteHeaderAndEntity(http.StatusForbidden, errors.Wrap(err))
return
}
if err != nil {
if k8serr.IsNotFound(err) {
resp.WriteHeaderAndEntity(http.StatusForbidden, errors.Wrap(err))
} else {
resp.WriteHeaderAndEntity(http.StatusInternalServerError, errors.Wrap(err))
}
return
}
created, err := tenant.CreateNamespace(workspaceName, &namespace, username)
if err != nil {
if k8serr.IsAlreadyExists(err) {
resp.WriteHeaderAndEntity(http.StatusConflict, err)
} else {
resp.WriteHeaderAndEntity(http.StatusInternalServerError, err)
}
return
}
resp.WriteAsJson(created)
}
func DeleteNamespace(req *restful.Request, resp *restful.Response) {
workspaceName := req.PathParameter("workspace")
namespaceName := req.PathParameter("namespace")
err := workspaces.DeleteNamespace(workspaceName, namespaceName)
if err != nil {
resp.WriteHeaderAndEntity(http.StatusBadRequest, errors.Wrap(err))
return
}
resp.WriteAsJson(errors.None)
}
func checkResourceQuotas(wokrspace *v1alpha1.Workspace) error {
return nil
}
func ListDevopsProjects(req *restful.Request, resp *restful.Response) {
workspace := req.PathParameter("workspace")
username := req.PathParameter(constants.UserNameHeader)
if username == "" {
username = req.HeaderParameter(constants.UserNameHeader)
}
orderBy := req.QueryParameter(params.OrderByParam)
reverse := params.ParseReverse(req)
limit, offset := params.ParsePaging(req.QueryParameter(params.PagingParam))
conditions, err := params.ParseConditions(req.QueryParameter(params.ConditionsParam))
if err != nil {
resp.WriteHeaderAndEntity(http.StatusBadRequest, errors.Wrap(err))
return
}
result, err := tenant.ListDevopsProjects(workspace, username, conditions, orderBy, reverse, limit, offset)
if err != nil {
resp.WriteHeaderAndEntity(http.StatusInternalServerError, errors.Wrap(err))
return
}
resp.WriteAsJson(result)
}
func DeleteDevopsProject(req *restful.Request, resp *restful.Response) {
devops := req.PathParameter("id")
workspace := req.PathParameter("workspace")
force := req.QueryParameter("force")
username := req.HeaderParameter(constants.UserNameHeader)
err := workspaces.UnBindDevopsProject(workspace, devops)
if err != nil && force != "true" {
resp.WriteHeaderAndEntity(http.StatusInternalServerError, errors.Wrap(err))
return
}
err = workspaces.DeleteDevopsProject(username, devops)
if err != nil {
resp.WriteHeaderAndEntity(http.StatusInternalServerError, errors.Wrap(err))
return
}
resp.WriteAsJson(errors.None)
}
func CreateDevopsProject(req *restful.Request, resp *restful.Response) {
workspace := req.PathParameter("workspace")
username := req.HeaderParameter(constants.UserNameHeader)
var devops models.DevopsProject
err := req.ReadEntity(&devops)
if err != nil {
resp.WriteHeaderAndEntity(http.StatusBadRequest, errors.Wrap(err))
return
}
log.Println("create workspace", username, workspace, devops)
project, err := workspaces.CreateDevopsProject(username, workspace, devops)
if err != nil {
resp.WriteHeaderAndEntity(http.StatusInternalServerError, errors.Wrap(err))
return
}
resp.WriteAsJson(project)
}
func ListNamespaceRules(req *restful.Request, resp *restful.Response) {
namespace := req.PathParameter("namespace")
username := req.HeaderParameter(constants.UserNameHeader)
rules, err := iam.GetUserNamespaceSimpleRules(namespace, username)
if err != nil {
resp.WriteError(http.StatusInternalServerError, err)
return
}
resp.WriteAsJson(rules)
}
func ListDevopsRules(req *restful.Request, resp *restful.Response) {
devops := req.PathParameter("devops")
username := req.HeaderParameter(constants.UserNameHeader)
rules, err := iam.GetUserDevopsSimpleRules(username, devops)
if err != nil {
resp.WriteError(http.StatusInternalServerError, err)
return
}
resp.WriteAsJson(rules)
}
/*
Copyright 2019 The KubeSphere 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 terminal
import (
"github.com/emicklei/go-restful"
"gopkg.in/igm/sockjs-go.v2/sockjs"
"kubesphere.io/kubesphere/pkg/errors"
"kubesphere.io/kubesphere/pkg/models/terminal"
"net/http"
)
// TerminalResponse is sent by handleExecShell. The Id is a random session id that binds the original REST request and the SockJS connection.
// Any clientapi in possession of this Id can hijack the terminal session.
type TerminalResponse struct {
Id string `json:"id"`
}
// CreateAttachHandler is called from main for /api/sockjs
func NewTerminalHandler(path string) http.Handler {
return sockjs.NewHandler(path, sockjs.DefaultOptions, terminal.HandleTerminalSession)
}
// Handles execute shell API call
func CreateTerminalSession(request *restful.Request, resp *restful.Response) {
namespace := request.PathParameter("namespace")
podName := request.PathParameter("pod")
containerName := request.QueryParameter("container")
shell := request.QueryParameter("shell")
sessionId, err := terminal.NewSession(shell, namespace, podName, containerName)
if err != nil {
resp.WriteHeaderAndEntity(http.StatusInternalServerError, errors.Wrap(err))
return
}
TerminalResponse := &TerminalResponse{Id: sessionId}
resp.WriteAsJson(TerminalResponse)
}
......@@ -19,10 +19,11 @@ limitations under the License.
package versioned
import (
discovery "k8s.io/client-go/discovery"
rest "k8s.io/client-go/rest"
flowcontrol "k8s.io/client-go/util/flowcontrol"
"k8s.io/client-go/discovery"
"k8s.io/client-go/rest"
"k8s.io/client-go/util/flowcontrol"
servicemeshv1alpha2 "kubesphere.io/kubesphere/pkg/client/clientset/versioned/typed/servicemesh/v1alpha2"
tenantv1alpha1 "kubesphere.io/kubesphere/pkg/client/clientset/versioned/typed/tenant/v1alpha1"
)
type Interface interface {
......@@ -30,6 +31,9 @@ type Interface interface {
ServicemeshV1alpha2() servicemeshv1alpha2.ServicemeshV1alpha2Interface
// Deprecated: please explicitly pick a version if possible.
Servicemesh() servicemeshv1alpha2.ServicemeshV1alpha2Interface
TenantV1alpha1() tenantv1alpha1.TenantV1alpha1Interface
// Deprecated: please explicitly pick a version if possible.
Tenant() tenantv1alpha1.TenantV1alpha1Interface
}
// Clientset contains the clients for groups. Each group has exactly one
......@@ -37,6 +41,7 @@ type Interface interface {
type Clientset struct {
*discovery.DiscoveryClient
servicemeshV1alpha2 *servicemeshv1alpha2.ServicemeshV1alpha2Client
tenantV1alpha1 *tenantv1alpha1.TenantV1alpha1Client
}
// ServicemeshV1alpha2 retrieves the ServicemeshV1alpha2Client
......@@ -50,6 +55,17 @@ func (c *Clientset) Servicemesh() servicemeshv1alpha2.ServicemeshV1alpha2Interfa
return c.servicemeshV1alpha2
}
// TenantV1alpha1 retrieves the TenantV1alpha1Client
func (c *Clientset) TenantV1alpha1() tenantv1alpha1.TenantV1alpha1Interface {
return c.tenantV1alpha1
}
// Deprecated: Tenant retrieves the default version of TenantClient.
// Please explicitly pick a version.
func (c *Clientset) Tenant() tenantv1alpha1.TenantV1alpha1Interface {
return c.tenantV1alpha1
}
// Discovery retrieves the DiscoveryClient
func (c *Clientset) Discovery() discovery.DiscoveryInterface {
if c == nil {
......@@ -70,6 +86,10 @@ func NewForConfig(c *rest.Config) (*Clientset, error) {
if err != nil {
return nil, err
}
cs.tenantV1alpha1, err = tenantv1alpha1.NewForConfig(&configShallowCopy)
if err != nil {
return nil, err
}
cs.DiscoveryClient, err = discovery.NewDiscoveryClientForConfig(&configShallowCopy)
if err != nil {
......@@ -83,6 +103,7 @@ func NewForConfig(c *rest.Config) (*Clientset, error) {
func NewForConfigOrDie(c *rest.Config) *Clientset {
var cs Clientset
cs.servicemeshV1alpha2 = servicemeshv1alpha2.NewForConfigOrDie(c)
cs.tenantV1alpha1 = tenantv1alpha1.NewForConfigOrDie(c)
cs.DiscoveryClient = discovery.NewDiscoveryClientForConfigOrDie(c)
return &cs
......@@ -92,6 +113,7 @@ func NewForConfigOrDie(c *rest.Config) *Clientset {
func New(c rest.Interface) *Clientset {
var cs Clientset
cs.servicemeshV1alpha2 = servicemeshv1alpha2.New(c)
cs.tenantV1alpha1 = tenantv1alpha1.New(c)
cs.DiscoveryClient = discovery.NewDiscoveryClient(c)
return &cs
......
......@@ -27,6 +27,8 @@ import (
clientset "kubesphere.io/kubesphere/pkg/client/clientset/versioned"
servicemeshv1alpha2 "kubesphere.io/kubesphere/pkg/client/clientset/versioned/typed/servicemesh/v1alpha2"
fakeservicemeshv1alpha2 "kubesphere.io/kubesphere/pkg/client/clientset/versioned/typed/servicemesh/v1alpha2/fake"
tenantv1alpha1 "kubesphere.io/kubesphere/pkg/client/clientset/versioned/typed/tenant/v1alpha1"
faketenantv1alpha1 "kubesphere.io/kubesphere/pkg/client/clientset/versioned/typed/tenant/v1alpha1/fake"
)
// NewSimpleClientset returns a clientset that will respond with the provided objects.
......@@ -80,3 +82,13 @@ func (c *Clientset) ServicemeshV1alpha2() servicemeshv1alpha2.ServicemeshV1alpha
func (c *Clientset) Servicemesh() servicemeshv1alpha2.ServicemeshV1alpha2Interface {
return &fakeservicemeshv1alpha2.FakeServicemeshV1alpha2{Fake: &c.Fake}
}
// TenantV1alpha1 retrieves the TenantV1alpha1Client
func (c *Clientset) TenantV1alpha1() tenantv1alpha1.TenantV1alpha1Interface {
return &faketenantv1alpha1.FakeTenantV1alpha1{Fake: &c.Fake}
}
// Tenant retrieves the TenantV1alpha1Client
func (c *Clientset) Tenant() tenantv1alpha1.TenantV1alpha1Interface {
return &faketenantv1alpha1.FakeTenantV1alpha1{Fake: &c.Fake}
}
......@@ -19,12 +19,13 @@ limitations under the License.
package fake
import (
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"
"k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/runtime/serializer"
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
servicemeshv1alpha2 "kubesphere.io/kubesphere/pkg/apis/servicemesh/v1alpha2"
tenantv1alpha1 "kubesphere.io/kubesphere/pkg/apis/tenant/v1alpha1"
)
var scheme = runtime.NewScheme()
......@@ -32,6 +33,7 @@ var codecs = serializer.NewCodecFactory(scheme)
var parameterCodec = runtime.NewParameterCodec(scheme)
var localSchemeBuilder = runtime.SchemeBuilder{
servicemeshv1alpha2.AddToScheme,
tenantv1alpha1.AddToScheme,
}
// AddToScheme adds all types of this clientset into the given scheme. This allows composition
......
......@@ -19,12 +19,13 @@ limitations under the License.
package scheme
import (
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"
"k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/runtime/serializer"
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
servicemeshv1alpha2 "kubesphere.io/kubesphere/pkg/apis/servicemesh/v1alpha2"
tenantv1alpha1 "kubesphere.io/kubesphere/pkg/apis/tenant/v1alpha1"
)
var Scheme = runtime.NewScheme()
......@@ -32,6 +33,7 @@ var Codecs = serializer.NewCodecFactory(Scheme)
var ParameterCodec = runtime.NewParameterCodec(Scheme)
var localSchemeBuilder = runtime.SchemeBuilder{
servicemeshv1alpha2.AddToScheme,
tenantv1alpha1.AddToScheme,
}
// AddToScheme adds all types of this clientset into the given scheme. This allows composition
......
/*
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 v1alpha1
/*
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 fake has the automatically generated clients.
package fake
/*
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 fake
import (
"k8s.io/client-go/rest"
"k8s.io/client-go/testing"
"kubesphere.io/kubesphere/pkg/client/clientset/versioned/typed/tenant/v1alpha1"
)
type FakeTenantV1alpha1 struct {
*testing.Fake
}
func (c *FakeTenantV1alpha1) Workspaces() v1alpha1.WorkspaceInterface {
return &FakeWorkspaces{c}
}
// RESTClient returns a RESTClient that is used to communicate
// with API server by this client implementation.
func (c *FakeTenantV1alpha1) RESTClient() rest.Interface {
var ret *rest.RESTClient
return ret
}
/*
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 fake
import (
"k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/watch"
"k8s.io/client-go/testing"
"kubesphere.io/kubesphere/pkg/apis/tenant/v1alpha1"
)
// FakeWorkspaces implements WorkspaceInterface
type FakeWorkspaces struct {
Fake *FakeTenantV1alpha1
}
var workspacesResource = schema.GroupVersionResource{Group: "tenant.kubesphere.io", Version: "v1alpha1", Resource: "workspaces"}
var workspacesKind = schema.GroupVersionKind{Group: "tenant.kubesphere.io", Version: "v1alpha1", Kind: "Workspace"}
// Get takes name of the workspace, and returns the corresponding workspace object, and an error if there is any.
func (c *FakeWorkspaces) Get(name string, options v1.GetOptions) (result *v1alpha1.Workspace, err error) {
obj, err := c.Fake.
Invokes(testing.NewRootGetAction(workspacesResource, name), &v1alpha1.Workspace{})
if obj == nil {
return nil, err
}
return obj.(*v1alpha1.Workspace), err
}
// List takes label and field selectors, and returns the list of Workspaces that match those selectors.
func (c *FakeWorkspaces) List(opts v1.ListOptions) (result *v1alpha1.WorkspaceList, err error) {
obj, err := c.Fake.
Invokes(testing.NewRootListAction(workspacesResource, workspacesKind, opts), &v1alpha1.WorkspaceList{})
if obj == nil {
return nil, err
}
label, _, _ := testing.ExtractFromListOptions(opts)
if label == nil {
label = labels.Everything()
}
list := &v1alpha1.WorkspaceList{ListMeta: obj.(*v1alpha1.WorkspaceList).ListMeta}
for _, item := range obj.(*v1alpha1.WorkspaceList).Items {
if label.Matches(labels.Set(item.Labels)) {
list.Items = append(list.Items, item)
}
}
return list, err
}
// Watch returns a watch.Interface that watches the requested workspaces.
func (c *FakeWorkspaces) Watch(opts v1.ListOptions) (watch.Interface, error) {
return c.Fake.
InvokesWatch(testing.NewRootWatchAction(workspacesResource, opts))
}
// Create takes the representation of a workspace and creates it. Returns the server's representation of the workspace, and an error, if there is any.
func (c *FakeWorkspaces) Create(workspace *v1alpha1.Workspace) (result *v1alpha1.Workspace, err error) {
obj, err := c.Fake.
Invokes(testing.NewRootCreateAction(workspacesResource, workspace), &v1alpha1.Workspace{})
if obj == nil {
return nil, err
}
return obj.(*v1alpha1.Workspace), err
}
// Update takes the representation of a workspace and updates it. Returns the server's representation of the workspace, and an error, if there is any.
func (c *FakeWorkspaces) Update(workspace *v1alpha1.Workspace) (result *v1alpha1.Workspace, err error) {
obj, err := c.Fake.
Invokes(testing.NewRootUpdateAction(workspacesResource, workspace), &v1alpha1.Workspace{})
if obj == nil {
return nil, err
}
return obj.(*v1alpha1.Workspace), err
}
// UpdateStatus was generated because the type contains a Status member.
// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus().
func (c *FakeWorkspaces) UpdateStatus(workspace *v1alpha1.Workspace) (*v1alpha1.Workspace, error) {
obj, err := c.Fake.
Invokes(testing.NewRootUpdateSubresourceAction(workspacesResource, "status", workspace), &v1alpha1.Workspace{})
if obj == nil {
return nil, err
}
return obj.(*v1alpha1.Workspace), err
}
// Delete takes name of the workspace and deletes it. Returns an error if one occurs.
func (c *FakeWorkspaces) Delete(name string, options *v1.DeleteOptions) error {
_, err := c.Fake.
Invokes(testing.NewRootDeleteAction(workspacesResource, name), &v1alpha1.Workspace{})
return err
}
// DeleteCollection deletes a collection of objects.
func (c *FakeWorkspaces) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error {
action := testing.NewRootDeleteCollectionAction(workspacesResource, listOptions)
_, err := c.Fake.Invokes(action, &v1alpha1.WorkspaceList{})
return err
}
// Patch applies the patch and returns the patched workspace.
func (c *FakeWorkspaces) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha1.Workspace, err error) {
obj, err := c.Fake.
Invokes(testing.NewRootPatchSubresourceAction(workspacesResource, name, pt, data, subresources...), &v1alpha1.Workspace{})
if obj == nil {
return nil, err
}
return obj.(*v1alpha1.Workspace), err
}
/*
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 v1alpha1
type WorkspaceExpansion interface{}
/*
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 v1alpha1
import (
"k8s.io/apimachinery/pkg/runtime/serializer"
"k8s.io/client-go/rest"
"kubesphere.io/kubesphere/pkg/apis/tenant/v1alpha1"
"kubesphere.io/kubesphere/pkg/client/clientset/versioned/scheme"
)
type TenantV1alpha1Interface interface {
RESTClient() rest.Interface
WorkspacesGetter
}
// TenantV1alpha1Client is used to interact with features provided by the tenant.kubesphere.io group.
type TenantV1alpha1Client struct {
restClient rest.Interface
}
func (c *TenantV1alpha1Client) Workspaces() WorkspaceInterface {
return newWorkspaces(c)
}
// NewForConfig creates a new TenantV1alpha1Client for the given config.
func NewForConfig(c *rest.Config) (*TenantV1alpha1Client, error) {
config := *c
if err := setConfigDefaults(&config); err != nil {
return nil, err
}
client, err := rest.RESTClientFor(&config)
if err != nil {
return nil, err
}
return &TenantV1alpha1Client{client}, nil
}
// NewForConfigOrDie creates a new TenantV1alpha1Client for the given config and
// panics if there is an error in the config.
func NewForConfigOrDie(c *rest.Config) *TenantV1alpha1Client {
client, err := NewForConfig(c)
if err != nil {
panic(err)
}
return client
}
// New creates a new TenantV1alpha1Client for the given RESTClient.
func New(c rest.Interface) *TenantV1alpha1Client {
return &TenantV1alpha1Client{c}
}
func setConfigDefaults(config *rest.Config) error {
gv := v1alpha1.SchemeGroupVersion
config.GroupVersion = &gv
config.APIPath = "/apis"
config.NegotiatedSerializer = serializer.DirectCodecFactory{CodecFactory: scheme.Codecs}
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 *TenantV1alpha1Client) RESTClient() rest.Interface {
if c == nil {
return nil
}
return c.restClient
}
/*
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 v1alpha1
import (
"time"
"k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/watch"
"k8s.io/client-go/rest"
"kubesphere.io/kubesphere/pkg/apis/tenant/v1alpha1"
"kubesphere.io/kubesphere/pkg/client/clientset/versioned/scheme"
)
// WorkspacesGetter has a method to return a WorkspaceInterface.
// A group's client should implement this interface.
type WorkspacesGetter interface {
Workspaces() WorkspaceInterface
}
// WorkspaceInterface has methods to work with Workspace resources.
type WorkspaceInterface interface {
Create(*v1alpha1.Workspace) (*v1alpha1.Workspace, error)
Update(*v1alpha1.Workspace) (*v1alpha1.Workspace, error)
UpdateStatus(*v1alpha1.Workspace) (*v1alpha1.Workspace, error)
Delete(name string, options *v1.DeleteOptions) error
DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error
Get(name string, options v1.GetOptions) (*v1alpha1.Workspace, error)
List(opts v1.ListOptions) (*v1alpha1.WorkspaceList, error)
Watch(opts v1.ListOptions) (watch.Interface, error)
Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha1.Workspace, err error)
WorkspaceExpansion
}
// workspaces implements WorkspaceInterface
type workspaces struct {
client rest.Interface
}
// newWorkspaces returns a Workspaces
func newWorkspaces(c *TenantV1alpha1Client) *workspaces {
return &workspaces{
client: c.RESTClient(),
}
}
// Get takes name of the workspace, and returns the corresponding workspace object, and an error if there is any.
func (c *workspaces) Get(name string, options v1.GetOptions) (result *v1alpha1.Workspace, err error) {
result = &v1alpha1.Workspace{}
err = c.client.Get().
Resource("workspaces").
Name(name).
VersionedParams(&options, scheme.ParameterCodec).
Do().
Into(result)
return
}
// List takes label and field selectors, and returns the list of Workspaces that match those selectors.
func (c *workspaces) List(opts v1.ListOptions) (result *v1alpha1.WorkspaceList, err error) {
var timeout time.Duration
if opts.TimeoutSeconds != nil {
timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
}
result = &v1alpha1.WorkspaceList{}
err = c.client.Get().
Resource("workspaces").
VersionedParams(&opts, scheme.ParameterCodec).
Timeout(timeout).
Do().
Into(result)
return
}
// Watch returns a watch.Interface that watches the requested workspaces.
func (c *workspaces) Watch(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("workspaces").
VersionedParams(&opts, scheme.ParameterCodec).
Timeout(timeout).
Watch()
}
// Create takes the representation of a workspace and creates it. Returns the server's representation of the workspace, and an error, if there is any.
func (c *workspaces) Create(workspace *v1alpha1.Workspace) (result *v1alpha1.Workspace, err error) {
result = &v1alpha1.Workspace{}
err = c.client.Post().
Resource("workspaces").
Body(workspace).
Do().
Into(result)
return
}
// Update takes the representation of a workspace and updates it. Returns the server's representation of the workspace, and an error, if there is any.
func (c *workspaces) Update(workspace *v1alpha1.Workspace) (result *v1alpha1.Workspace, err error) {
result = &v1alpha1.Workspace{}
err = c.client.Put().
Resource("workspaces").
Name(workspace.Name).
Body(workspace).
Do().
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 *workspaces) UpdateStatus(workspace *v1alpha1.Workspace) (result *v1alpha1.Workspace, err error) {
result = &v1alpha1.Workspace{}
err = c.client.Put().
Resource("workspaces").
Name(workspace.Name).
SubResource("status").
Body(workspace).
Do().
Into(result)
return
}
// Delete takes name of the workspace and deletes it. Returns an error if one occurs.
func (c *workspaces) Delete(name string, options *v1.DeleteOptions) error {
return c.client.Delete().
Resource("workspaces").
Name(name).
Body(options).
Do().
Error()
}
// DeleteCollection deletes a collection of objects.
func (c *workspaces) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error {
var timeout time.Duration
if listOptions.TimeoutSeconds != nil {
timeout = time.Duration(*listOptions.TimeoutSeconds) * time.Second
}
return c.client.Delete().
Resource("workspaces").
VersionedParams(&listOptions, scheme.ParameterCodec).
Timeout(timeout).
Body(options).
Do().
Error()
}
// Patch applies the patch and returns the patched workspace.
func (c *workspaces) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha1.Workspace, err error) {
result = &v1alpha1.Workspace{}
err = c.client.Patch(pt).
Resource("workspaces").
SubResource(subresources...).
Name(name).
Body(data).
Do().
Into(result)
return
}
......@@ -19,17 +19,18 @@ limitations under the License.
package externalversions
import (
reflect "reflect"
sync "sync"
time "time"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
runtime "k8s.io/apimachinery/pkg/runtime"
schema "k8s.io/apimachinery/pkg/runtime/schema"
cache "k8s.io/client-go/tools/cache"
versioned "kubesphere.io/kubesphere/pkg/client/clientset/versioned"
internalinterfaces "kubesphere.io/kubesphere/pkg/client/informers/externalversions/internalinterfaces"
servicemesh "kubesphere.io/kubesphere/pkg/client/informers/externalversions/servicemesh"
"reflect"
"sync"
"time"
"k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/client-go/tools/cache"
"kubesphere.io/kubesphere/pkg/client/clientset/versioned"
"kubesphere.io/kubesphere/pkg/client/informers/externalversions/internalinterfaces"
"kubesphere.io/kubesphere/pkg/client/informers/externalversions/servicemesh"
"kubesphere.io/kubesphere/pkg/client/informers/externalversions/tenant"
)
// SharedInformerOption defines the functional option type for SharedInformerFactory.
......@@ -173,8 +174,13 @@ type SharedInformerFactory interface {
WaitForCacheSync(stopCh <-chan struct{}) map[reflect.Type]bool
Servicemesh() servicemesh.Interface
Tenant() tenant.Interface
}
func (f *sharedInformerFactory) Servicemesh() servicemesh.Interface {
return servicemesh.New(f, f.namespace, f.tweakListOptions)
}
func (f *sharedInformerFactory) Tenant() tenant.Interface {
return tenant.New(f, f.namespace, f.tweakListOptions)
}
......@@ -21,9 +21,10 @@ package externalversions
import (
"fmt"
schema "k8s.io/apimachinery/pkg/runtime/schema"
cache "k8s.io/client-go/tools/cache"
v1alpha2 "kubesphere.io/kubesphere/pkg/apis/servicemesh/v1alpha2"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/client-go/tools/cache"
"kubesphere.io/kubesphere/pkg/apis/servicemesh/v1alpha2"
"kubesphere.io/kubesphere/pkg/apis/tenant/v1alpha1"
)
// GenericInformer is type of SharedIndexInformer which will locate and delegate to other
......@@ -58,6 +59,10 @@ func (f *sharedInformerFactory) ForResource(resource schema.GroupVersionResource
case v1alpha2.SchemeGroupVersion.WithResource("strategies"):
return &genericInformer{resource: resource.GroupResource(), informer: f.Servicemesh().V1alpha2().Strategies().Informer()}, nil
// Group=tenant.kubesphere.io, Version=v1alpha1
case v1alpha1.SchemeGroupVersion.WithResource("workspaces"):
return &genericInformer{resource: resource.GroupResource(), informer: f.Tenant().V1alpha1().Workspaces().Informer()}, nil
}
return nil, fmt.Errorf("no informer found for %v", resource)
......
/*
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 informer-gen. DO NOT EDIT.
package tenant
import (
"kubesphere.io/kubesphere/pkg/client/informers/externalversions/internalinterfaces"
"kubesphere.io/kubesphere/pkg/client/informers/externalversions/tenant/v1alpha1"
)
// Interface provides access to each of this group's versions.
type Interface interface {
// V1alpha1 provides access to shared informers for resources in V1alpha1.
V1alpha1() v1alpha1.Interface
}
type group struct {
factory internalinterfaces.SharedInformerFactory
namespace string
tweakListOptions internalinterfaces.TweakListOptionsFunc
}
// New returns a new Interface.
func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface {
return &group{factory: f, namespace: namespace, tweakListOptions: tweakListOptions}
}
// V1alpha1 returns a new v1alpha1.Interface.
func (g *group) V1alpha1() v1alpha1.Interface {
return v1alpha1.New(g.factory, g.namespace, g.tweakListOptions)
}
/*
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 informer-gen. DO NOT EDIT.
package v1alpha1
import (
"kubesphere.io/kubesphere/pkg/client/informers/externalversions/internalinterfaces"
)
// Interface provides access to all the informers in this group version.
type Interface interface {
// Workspaces returns a WorkspaceInformer.
Workspaces() WorkspaceInformer
}
type version struct {
factory internalinterfaces.SharedInformerFactory
namespace string
tweakListOptions internalinterfaces.TweakListOptionsFunc
}
// New returns a new Interface.
func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface {
return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions}
}
// Workspaces returns a WorkspaceInformer.
func (v *version) Workspaces() WorkspaceInformer {
return &workspaceInformer{factory: v.factory, tweakListOptions: v.tweakListOptions}
}
/*
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 informer-gen. DO NOT EDIT.
package v1alpha1
import (
"time"
"k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/watch"
"k8s.io/client-go/tools/cache"
tenantv1alpha1 "kubesphere.io/kubesphere/pkg/apis/tenant/v1alpha1"
"kubesphere.io/kubesphere/pkg/client/clientset/versioned"
"kubesphere.io/kubesphere/pkg/client/informers/externalversions/internalinterfaces"
"kubesphere.io/kubesphere/pkg/client/listers/tenant/v1alpha1"
)
// WorkspaceInformer provides access to a shared informer and lister for
// Workspaces.
type WorkspaceInformer interface {
Informer() cache.SharedIndexInformer
Lister() v1alpha1.WorkspaceLister
}
type workspaceInformer struct {
factory internalinterfaces.SharedInformerFactory
tweakListOptions internalinterfaces.TweakListOptionsFunc
}
// NewWorkspaceInformer constructs a new informer for Workspace type.
// Always prefer using an informer factory to get a shared informer instead of getting an independent
// one. This reduces memory footprint and number of connections to the server.
func NewWorkspaceInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer {
return NewFilteredWorkspaceInformer(client, resyncPeriod, indexers, nil)
}
// NewFilteredWorkspaceInformer constructs a new informer for Workspace type.
// Always prefer using an informer factory to get a shared informer instead of getting an independent
// one. This reduces memory footprint and number of connections to the server.
func NewFilteredWorkspaceInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer {
return cache.NewSharedIndexInformer(
&cache.ListWatch{
ListFunc: func(options v1.ListOptions) (runtime.Object, error) {
if tweakListOptions != nil {
tweakListOptions(&options)
}
return client.TenantV1alpha1().Workspaces().List(options)
},
WatchFunc: func(options v1.ListOptions) (watch.Interface, error) {
if tweakListOptions != nil {
tweakListOptions(&options)
}
return client.TenantV1alpha1().Workspaces().Watch(options)
},
},
&tenantv1alpha1.Workspace{},
resyncPeriod,
indexers,
)
}
func (f *workspaceInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer {
return NewFilteredWorkspaceInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions)
}
func (f *workspaceInformer) Informer() cache.SharedIndexInformer {
return f.factory.InformerFor(&tenantv1alpha1.Workspace{}, f.defaultInformer)
}
func (f *workspaceInformer) Lister() v1alpha1.WorkspaceLister {
return v1alpha1.NewWorkspaceLister(f.Informer().GetIndexer())
}
/*
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 lister-gen. DO NOT EDIT.
package v1alpha1
// WorkspaceListerExpansion allows custom methods to be added to
// WorkspaceLister.
type WorkspaceListerExpansion interface{}
/*
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 lister-gen. DO NOT EDIT.
package v1alpha1
import (
"k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/client-go/tools/cache"
"kubesphere.io/kubesphere/pkg/apis/tenant/v1alpha1"
)
// WorkspaceLister helps list Workspaces.
type WorkspaceLister interface {
// List lists all Workspaces in the indexer.
List(selector labels.Selector) (ret []*v1alpha1.Workspace, err error)
// Get retrieves the Workspace from the index for a given name.
Get(name string) (*v1alpha1.Workspace, error)
WorkspaceListerExpansion
}
// workspaceLister implements the WorkspaceLister interface.
type workspaceLister struct {
indexer cache.Indexer
}
// NewWorkspaceLister returns a new WorkspaceLister.
func NewWorkspaceLister(indexer cache.Indexer) WorkspaceLister {
return &workspaceLister{indexer: indexer}
}
// List lists all Workspaces in the indexer.
func (s *workspaceLister) List(selector labels.Selector) (ret []*v1alpha1.Workspace, err error) {
err = cache.ListAll(s.indexer, selector, func(m interface{}) {
ret = append(ret, m.(*v1alpha1.Workspace))
})
return ret, err
}
// Get retrieves the Workspace from the index for a given name.
func (s *workspaceLister) Get(name string) (*v1alpha1.Workspace, error) {
obj, exists, err := s.indexer.GetByKey(name)
if err != nil {
return nil, err
}
if !exists {
return nil, errors.NewNotFound(v1alpha1.Resource("workspace"), name)
}
return obj.(*v1alpha1.Workspace), nil
}
......@@ -31,13 +31,16 @@ const (
IngressControllerFolder = DataHome + "/ingress-controller"
IngressControllerPrefix = "kubesphere-router-"
WorkspaceLabelKey = "kubesphere.io/workspace"
WorkspaceAdmin = "workspace-admin"
ClusterAdmin = "cluster-admin"
WorkspaceRegular = "workspace-regular"
WorkspaceViewer = "workspace-viewer"
DevopsOwner = "owner"
DevopsReporter = "reporter"
WorkspaceLabelKey = "kubesphere.io/workspace"
DisplayNameLabelKey = "displayName"
CreatorLabelKey = "creator"
OpenPitrixRuntimeAnnotationKey = "openpitrix_runtime"
WorkspaceAdmin = "workspace-admin"
ClusterAdmin = "cluster-admin"
WorkspaceRegular = "workspace-regular"
WorkspaceViewer = "workspace-viewer"
DevopsOwner = "owner"
DevopsReporter = "reporter"
UserNameHeader = "X-Token-Username"
)
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册