feat: Set current namespace for in-cluster SDK in multi-user mode and add healthz endpoint to API backends (#4638)

* Set current namespace in local KFP context if running from notebook

* Create "~/.config/kfp/" instead of ".config/kfp/"

At first it was assumed the `get_user_namespace` command would be executed from the home directory.

* Create local context file if it doesn't exist during set_user_namespace

* Grab path from LOCAL_KFP_CONTEXT when creating folder

Instead of harcoding the os.mkdirs path to `~/.config/kfp` it now grabs it from the LOCAL_KFP_CONTEXT. Also, removed path creation in `get_user_namespace` as that is now handled in `set_user_namespace`. Also, it now checks if the path exists rather than the local_context_file to remove the situation where it tries to create ~/.config/kfp/ because the context.json doesn't exist when the path does.

* add multi-user setting to healthz api

* Add http prefix to health api url

* move healtz api call to own function and fix multi_user boolean

* Fix HEALTH_PATH declaration

* Move check to Client __init__ and change get_kfp_healthz to avoid breaking in case of old apiserver image

* Add multi_user to frontend healthz

* Expose multi_user in frontend and add integration test

* Fix integration test

* Fix host hardcoding and error handling

* Handle empty API response, check if API up to date

* Fix response return

* remove API check due to empty response

* retry API call if first response empty

* retry getting healthz api if no response

* change health_api to https

The healthz_api has been returning empty responses which might be caused by sending an http request to an https endpoint. Although requests handles redirects, this commit is to test if this solves the issue.

* Add some debug info to healthz exception

* add url to debug and lower retries to 1

* Use api_client to get healthz data

* Debug info for API response

* Follow API redirect history

* Fix indentation

* Add healthz proto

* Try getting healthz api with new python backend

* Add installation of kfp_server_api in tests

* Fix incorrect setup location

* Replace old .get with new http backend .multi_user

* Code clean up

* Small fixes and TimeOutError for retries healthz api

* Remove changes to go dependencies

* Send empty proto request and fix exception client

* Remove unused commit_sha and tag_name
This commit is contained in:
DavidSpek 2020-11-25 00:36:39 +01:00 committed by GitHub
parent 6b8bd4c7ab
commit 0df9473bba
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
36 changed files with 1961 additions and 4 deletions

View File

@ -5,7 +5,10 @@ proto_library(
name = "ml_pipelines_proto",
srcs = ["pipeline_spec.proto"],
visibility = ["//visibility:public"],
deps = ["@com_google_protobuf//:any_proto"],
deps = [
"@com_google_protobuf//:any_proto",
"@com_google_protobuf//:struct_proto",
],
)
go_proto_library(

View File

@ -9,6 +9,7 @@ proto_library(
"error.proto",
"experiment.proto",
"filter.proto",
"healthz.proto",
"job.proto",
"parameter.proto",
"pipeline.proto",

View File

@ -66,7 +66,7 @@ jq -s '
.info.version = "'$VERSION'" |
.info.contact = { "name": "google", "email": "kubeflow-pipelines@google.com", "url": "https://www.google.com" } |
.info.license = { "name": "Apache 2.0", "url": "https://raw.githubusercontent.com/kubeflow/pipelines/master/LICENSE" }
' ${DIR}/swagger/{run,job,pipeline,experiment,pipeline.upload}.swagger.json > "${DIR}/swagger/kfp_api_single_file.swagger.json"
' ${DIR}/swagger/{run,job,pipeline,experiment,pipeline.upload,healthz}.swagger.json > "${DIR}/swagger/kfp_api_single_file.swagger.json"
# Generate Go HTTP client from the swagger files.
${SWAGGER_CMD} generate client \
@ -117,6 +117,14 @@ ${SWAGGER_CMD} generate client \
-m visualization_model \
-t ${DIR}/go_http_client
${SWAGGER_CMD} generate client \
-f ${DIR}/swagger/healthz.swagger.json \
-A healthz \
--principal models.Principal \
-c healthz_client \
-m healthz_model \
-t ${DIR}/go_http_client
# Hack to fix an issue with go-swagger
# See https://github.com/go-swagger/go-swagger/issues/1381 for details.
sed -i -- 's/MaxConcurrency int64 `json:"max_concurrency,omitempty"`/MaxConcurrency int64 `json:"max_concurrency,omitempty,string"`/g' ${DIR}/go_http_client/job_model/api_job.go

View File

@ -9,6 +9,8 @@ go_library(
"experiment.pb.go",
"experiment.pb.gw.go",
"filter.pb.go",
"healthz.pb.go",
"healthz.pb.gw.go",
"job.pb.go",
"job.pb.gw.go",
"parameter.pb.go",

186
backend/api/go_client/healthz.pb.go generated Executable file
View File

@ -0,0 +1,186 @@
// Copyright 2020 Google LLC
//
// 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 protoc-gen-go. DO NOT EDIT.
// source: backend/api/healthz.proto
package go_client // import "github.com/kubeflow/pipelines/backend/api/go_client"
import proto "github.com/golang/protobuf/proto"
import fmt "fmt"
import math "math"
import empty "github.com/golang/protobuf/ptypes/empty"
import _ "github.com/golang/protobuf/ptypes/timestamp"
import _ "github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger/options"
import _ "google.golang.org/genproto/googleapis/api/annotations"
import (
context "golang.org/x/net/context"
grpc "google.golang.org/grpc"
)
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
type GetHealthzResponse struct {
MultiUser bool `protobuf:"varint,3,opt,name=multi_user,json=multiUser,proto3" json:"multi_user,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *GetHealthzResponse) Reset() { *m = GetHealthzResponse{} }
func (m *GetHealthzResponse) String() string { return proto.CompactTextString(m) }
func (*GetHealthzResponse) ProtoMessage() {}
func (*GetHealthzResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_healthz_d6923259aa48c5fd, []int{0}
}
func (m *GetHealthzResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_GetHealthzResponse.Unmarshal(m, b)
}
func (m *GetHealthzResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_GetHealthzResponse.Marshal(b, m, deterministic)
}
func (dst *GetHealthzResponse) XXX_Merge(src proto.Message) {
xxx_messageInfo_GetHealthzResponse.Merge(dst, src)
}
func (m *GetHealthzResponse) XXX_Size() int {
return xxx_messageInfo_GetHealthzResponse.Size(m)
}
func (m *GetHealthzResponse) XXX_DiscardUnknown() {
xxx_messageInfo_GetHealthzResponse.DiscardUnknown(m)
}
var xxx_messageInfo_GetHealthzResponse proto.InternalMessageInfo
func (m *GetHealthzResponse) GetMultiUser() bool {
if m != nil {
return m.MultiUser
}
return false
}
func init() {
proto.RegisterType((*GetHealthzResponse)(nil), "api.GetHealthzResponse")
}
// Reference imports to suppress errors if they are not otherwise used.
var _ context.Context
var _ grpc.ClientConn
// This is a compile-time assertion to ensure that this generated file
// is compatible with the grpc package it is being compiled against.
const _ = grpc.SupportPackageIsVersion4
// HealthzServiceClient is the client API for HealthzService service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
type HealthzServiceClient interface {
GetHealthz(ctx context.Context, in *empty.Empty, opts ...grpc.CallOption) (*GetHealthzResponse, error)
}
type healthzServiceClient struct {
cc *grpc.ClientConn
}
func NewHealthzServiceClient(cc *grpc.ClientConn) HealthzServiceClient {
return &healthzServiceClient{cc}
}
func (c *healthzServiceClient) GetHealthz(ctx context.Context, in *empty.Empty, opts ...grpc.CallOption) (*GetHealthzResponse, error) {
out := new(GetHealthzResponse)
err := c.cc.Invoke(ctx, "/api.HealthzService/GetHealthz", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// HealthzServiceServer is the server API for HealthzService service.
type HealthzServiceServer interface {
GetHealthz(context.Context, *empty.Empty) (*GetHealthzResponse, error)
}
func RegisterHealthzServiceServer(s *grpc.Server, srv HealthzServiceServer) {
s.RegisterService(&_HealthzService_serviceDesc, srv)
}
func _HealthzService_GetHealthz_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(empty.Empty)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(HealthzServiceServer).GetHealthz(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/api.HealthzService/GetHealthz",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(HealthzServiceServer).GetHealthz(ctx, req.(*empty.Empty))
}
return interceptor(ctx, in, info, handler)
}
var _HealthzService_serviceDesc = grpc.ServiceDesc{
ServiceName: "api.HealthzService",
HandlerType: (*HealthzServiceServer)(nil),
Methods: []grpc.MethodDesc{
{
MethodName: "GetHealthz",
Handler: _HealthzService_GetHealthz_Handler,
},
},
Streams: []grpc.StreamDesc{},
Metadata: "backend/api/healthz.proto",
}
func init() { proto.RegisterFile("backend/api/healthz.proto", fileDescriptor_healthz_d6923259aa48c5fd) }
var fileDescriptor_healthz_d6923259aa48c5fd = []byte{
// 377 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x91, 0xcd, 0xae, 0x12, 0x31,
0x14, 0x80, 0x05, 0x12, 0xc4, 0x2a, 0x1a, 0x6b, 0x14, 0x1d, 0x21, 0x10, 0xe2, 0xc2, 0x85, 0xcc,
0x04, 0x79, 0x02, 0x49, 0x8c, 0x6e, 0xdc, 0x40, 0xdc, 0x10, 0x93, 0x49, 0xa7, 0x9c, 0x99, 0x69,
0x98, 0x69, 0x9b, 0xf6, 0x14, 0x22, 0x4b, 0x13, 0x5f, 0x40, 0x1f, 0xed, 0xbe, 0xc2, 0x7d, 0x90,
0x1b, 0x3a, 0x03, 0x77, 0x72, 0xef, 0x5d, 0x35, 0xed, 0xf9, 0xce, 0x4f, 0xbf, 0x43, 0xde, 0x25,
0x8c, 0xef, 0x40, 0x6e, 0x23, 0xa6, 0x45, 0x94, 0x03, 0x2b, 0x30, 0x3f, 0x86, 0xda, 0x28, 0x54,
0xb4, 0xc3, 0xb4, 0x08, 0x86, 0x99, 0x52, 0x59, 0x01, 0x3e, 0xcc, 0xa4, 0x54, 0xc8, 0x50, 0x28,
0x69, 0x2b, 0x24, 0x18, 0xd7, 0x51, 0x7f, 0x4b, 0x5c, 0x1a, 0xa1, 0x28, 0xc1, 0x22, 0x2b, 0x75,
0x0d, 0xbc, 0xbf, 0x0b, 0x40, 0xa9, 0xf1, 0xf7, 0x39, 0xbb, 0xd9, 0x5b, 0x0b, 0x0d, 0x85, 0x90,
0x10, 0x5b, 0x0d, 0xbc, 0x06, 0x3e, 0x34, 0x01, 0x03, 0x56, 0x39, 0xc3, 0x21, 0x36, 0x90, 0x82,
0x01, 0xc9, 0xa1, 0xa6, 0x3e, 0xf9, 0x83, 0xcf, 0x32, 0x90, 0x33, 0x7b, 0x60, 0x59, 0x06, 0x26,
0x52, 0xda, 0x8f, 0xf9, 0xc0, 0xc8, 0x83, 0x66, 0x4d, 0x30, 0x46, 0x99, 0x2a, 0x30, 0x5d, 0x10,
0xfa, 0x0d, 0xf0, 0x7b, 0xa5, 0x60, 0x05, 0x56, 0x2b, 0x69, 0x81, 0x8e, 0x08, 0x29, 0x5d, 0x81,
0x22, 0x76, 0x16, 0xcc, 0xdb, 0xce, 0xa4, 0xf5, 0xb1, 0xb7, 0x7a, 0xe2, 0x5f, 0x7e, 0x5a, 0x30,
0x9f, 0x25, 0x79, 0x5e, 0x67, 0xac, 0xc1, 0xec, 0x05, 0x07, 0xfa, 0x8b, 0x90, 0xdb, 0x32, 0xf4,
0x4d, 0x58, 0x09, 0x08, 0xcf, 0x02, 0xc2, 0xaf, 0x27, 0x01, 0xc1, 0x20, 0x64, 0x5a, 0x84, 0xf7,
0xfb, 0x4d, 0x47, 0x7f, 0xae, 0xae, 0xff, 0xb7, 0x07, 0xf4, 0xf5, 0x69, 0x3e, 0x1b, 0xed, 0xe7,
0x09, 0x20, 0x9b, 0x9f, 0x37, 0xb3, 0xfc, 0xdb, 0xfa, 0xf7, 0xe5, 0xc7, 0x6a, 0x48, 0x1e, 0x6f,
0x21, 0x65, 0xae, 0x40, 0xfa, 0x92, 0xbe, 0x20, 0xfd, 0xe0, 0xa9, 0x2f, 0xb7, 0x46, 0x86, 0xce,
0x6e, 0xc6, 0x64, 0x44, 0xba, 0x4b, 0x60, 0x06, 0x0c, 0x7d, 0xd5, 0x6b, 0x07, 0x7d, 0xe6, 0x30,
0x57, 0x46, 0x1c, 0xbd, 0x87, 0x49, 0x3b, 0x79, 0x46, 0xc8, 0x05, 0x78, 0xb4, 0x59, 0x64, 0x02,
0x73, 0x97, 0x84, 0x5c, 0x95, 0xd1, 0xce, 0x25, 0x90, 0x16, 0xea, 0x70, 0xd9, 0x86, 0x8d, 0x9a,
0xba, 0x32, 0x15, 0xf3, 0x42, 0x80, 0xc4, 0xa4, 0xeb, 0xff, 0xb3, 0xb8, 0x09, 0x00, 0x00, 0xff,
0xff, 0xd1, 0xc1, 0x9c, 0x02, 0x3f, 0x02, 0x00, 0x00,
}

122
backend/api/go_client/healthz.pb.gw.go generated Executable file
View File

@ -0,0 +1,122 @@
// Copyright 2020 Google LLC
//
// 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 protoc-gen-grpc-gateway. DO NOT EDIT.
// source: backend/api/healthz.proto
/*
Package go_client is a reverse proxy.
It translates gRPC into RESTful JSON APIs.
*/
package go_client
import (
"context"
"io"
"net/http"
"github.com/golang/protobuf/proto"
"github.com/golang/protobuf/ptypes/empty"
"github.com/grpc-ecosystem/grpc-gateway/runtime"
"github.com/grpc-ecosystem/grpc-gateway/utilities"
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/grpclog"
"google.golang.org/grpc/status"
)
var _ codes.Code
var _ io.Reader
var _ status.Status
var _ = runtime.String
var _ = utilities.NewDoubleArray
func request_HealthzService_GetHealthz_0(ctx context.Context, marshaler runtime.Marshaler, client HealthzServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq empty.Empty
var metadata runtime.ServerMetadata
msg, err := client.GetHealthz(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return msg, metadata, err
}
// RegisterHealthzServiceHandlerFromEndpoint is same as RegisterHealthzServiceHandler but
// automatically dials to "endpoint" and closes the connection when "ctx" gets done.
func RegisterHealthzServiceHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) {
conn, err := grpc.Dial(endpoint, opts...)
if err != nil {
return err
}
defer func() {
if err != nil {
if cerr := conn.Close(); cerr != nil {
grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr)
}
return
}
go func() {
<-ctx.Done()
if cerr := conn.Close(); cerr != nil {
grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr)
}
}()
}()
return RegisterHealthzServiceHandler(ctx, mux, conn)
}
// RegisterHealthzServiceHandler registers the http handlers for service HealthzService to "mux".
// The handlers forward requests to the grpc endpoint over "conn".
func RegisterHealthzServiceHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error {
return RegisterHealthzServiceHandlerClient(ctx, mux, NewHealthzServiceClient(conn))
}
// RegisterHealthzServiceHandlerClient registers the http handlers for service HealthzService
// to "mux". The handlers forward requests to the grpc endpoint over the given implementation of "HealthzServiceClient".
// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "HealthzServiceClient"
// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in
// "HealthzServiceClient" to call the correct interceptors.
func RegisterHealthzServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux, client HealthzServiceClient) error {
mux.Handle("GET", pattern_HealthzService_GetHealthz_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateContext(ctx, mux, req)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := request_HealthzService_GetHealthz_0(rctx, inboundMarshaler, client, req, pathParams)
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_HealthzService_GetHealthz_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
return nil
}
var (
pattern_HealthzService_GetHealthz_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"apis", "v1beta1", "healthz"}, ""))
)
var (
forward_HealthzService_GetHealthz_0 = runtime.ForwardResponseMessage
)

View File

@ -0,0 +1,14 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = ["healthz_client.go"],
importpath = "github.com/kubeflow/pipelines/backend/api/go_http_client/healthz_client",
visibility = ["//visibility:public"],
deps = [
"//backend/api/go_http_client/healthz_client/healthz_service:go_default_library",
"@com_github_go_openapi_runtime//:go_default_library",
"@com_github_go_openapi_runtime//client:go_default_library",
"@com_github_go_openapi_strfmt//:go_default_library",
],
)

View File

@ -0,0 +1,131 @@
// Copyright 2020 Google LLC
//
// 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 go-swagger; DO NOT EDIT.
package healthz_client
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"github.com/go-openapi/runtime"
httptransport "github.com/go-openapi/runtime/client"
strfmt "github.com/go-openapi/strfmt"
"github.com/kubeflow/pipelines/backend/api/go_http_client/healthz_client/healthz_service"
)
// Default healthz HTTP client.
var Default = NewHTTPClient(nil)
const (
// DefaultHost is the default Host
// found in Meta (info) section of spec file
DefaultHost string = "localhost"
// DefaultBasePath is the default BasePath
// found in Meta (info) section of spec file
DefaultBasePath string = "/"
)
// DefaultSchemes are the default schemes found in Meta (info) section of spec file
var DefaultSchemes = []string{"http", "https"}
// NewHTTPClient creates a new healthz HTTP client.
func NewHTTPClient(formats strfmt.Registry) *Healthz {
return NewHTTPClientWithConfig(formats, nil)
}
// NewHTTPClientWithConfig creates a new healthz HTTP client,
// using a customizable transport config.
func NewHTTPClientWithConfig(formats strfmt.Registry, cfg *TransportConfig) *Healthz {
// ensure nullable parameters have default
if cfg == nil {
cfg = DefaultTransportConfig()
}
// create transport and client
transport := httptransport.New(cfg.Host, cfg.BasePath, cfg.Schemes)
return New(transport, formats)
}
// New creates a new healthz client
func New(transport runtime.ClientTransport, formats strfmt.Registry) *Healthz {
// ensure nullable parameters have default
if formats == nil {
formats = strfmt.Default
}
cli := new(Healthz)
cli.Transport = transport
cli.HealthzService = healthz_service.New(transport, formats)
return cli
}
// DefaultTransportConfig creates a TransportConfig with the
// default settings taken from the meta section of the spec file.
func DefaultTransportConfig() *TransportConfig {
return &TransportConfig{
Host: DefaultHost,
BasePath: DefaultBasePath,
Schemes: DefaultSchemes,
}
}
// TransportConfig contains the transport related info,
// found in the meta section of the spec file.
type TransportConfig struct {
Host string
BasePath string
Schemes []string
}
// WithHost overrides the default host,
// provided by the meta section of the spec file.
func (cfg *TransportConfig) WithHost(host string) *TransportConfig {
cfg.Host = host
return cfg
}
// WithBasePath overrides the default basePath,
// provided by the meta section of the spec file.
func (cfg *TransportConfig) WithBasePath(basePath string) *TransportConfig {
cfg.BasePath = basePath
return cfg
}
// WithSchemes overrides the default schemes,
// provided by the meta section of the spec file.
func (cfg *TransportConfig) WithSchemes(schemes []string) *TransportConfig {
cfg.Schemes = schemes
return cfg
}
// Healthz is a client for healthz
type Healthz struct {
HealthzService *healthz_service.Client
Transport runtime.ClientTransport
}
// SetTransport changes the transport on the client and all its subresources
func (c *Healthz) SetTransport(transport runtime.ClientTransport) {
c.Transport = transport
c.HealthzService.SetTransport(transport)
}

View File

@ -0,0 +1,19 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = [
"get_healthz_parameters.go",
"get_healthz_responses.go",
"healthz_service_client.go",
],
importpath = "github.com/kubeflow/pipelines/backend/api/go_http_client/healthz_client/healthz_service",
visibility = ["//visibility:public"],
deps = [
"//backend/api/go_http_client/healthz_model:go_default_library",
"@com_github_go_openapi_errors//:go_default_library",
"@com_github_go_openapi_runtime//:go_default_library",
"@com_github_go_openapi_runtime//client:go_default_library",
"@com_github_go_openapi_strfmt//:go_default_library",
],
)

View File

@ -0,0 +1,127 @@
// Copyright 2020 Google LLC
//
// 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 go-swagger; DO NOT EDIT.
package healthz_service
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"context"
"net/http"
"time"
"github.com/go-openapi/errors"
"github.com/go-openapi/runtime"
cr "github.com/go-openapi/runtime/client"
strfmt "github.com/go-openapi/strfmt"
)
// NewGetHealthzParams creates a new GetHealthzParams object
// with the default values initialized.
func NewGetHealthzParams() *GetHealthzParams {
return &GetHealthzParams{
timeout: cr.DefaultTimeout,
}
}
// NewGetHealthzParamsWithTimeout creates a new GetHealthzParams object
// with the default values initialized, and the ability to set a timeout on a request
func NewGetHealthzParamsWithTimeout(timeout time.Duration) *GetHealthzParams {
return &GetHealthzParams{
timeout: timeout,
}
}
// NewGetHealthzParamsWithContext creates a new GetHealthzParams object
// with the default values initialized, and the ability to set a context for a request
func NewGetHealthzParamsWithContext(ctx context.Context) *GetHealthzParams {
return &GetHealthzParams{
Context: ctx,
}
}
// NewGetHealthzParamsWithHTTPClient creates a new GetHealthzParams object
// with the default values initialized, and the ability to set a custom HTTPClient for a request
func NewGetHealthzParamsWithHTTPClient(client *http.Client) *GetHealthzParams {
return &GetHealthzParams{
HTTPClient: client,
}
}
/*GetHealthzParams contains all the parameters to send to the API endpoint
for the get healthz operation typically these are written to a http.Request
*/
type GetHealthzParams struct {
timeout time.Duration
Context context.Context
HTTPClient *http.Client
}
// WithTimeout adds the timeout to the get healthz params
func (o *GetHealthzParams) WithTimeout(timeout time.Duration) *GetHealthzParams {
o.SetTimeout(timeout)
return o
}
// SetTimeout adds the timeout to the get healthz params
func (o *GetHealthzParams) SetTimeout(timeout time.Duration) {
o.timeout = timeout
}
// WithContext adds the context to the get healthz params
func (o *GetHealthzParams) WithContext(ctx context.Context) *GetHealthzParams {
o.SetContext(ctx)
return o
}
// SetContext adds the context to the get healthz params
func (o *GetHealthzParams) SetContext(ctx context.Context) {
o.Context = ctx
}
// WithHTTPClient adds the HTTPClient to the get healthz params
func (o *GetHealthzParams) WithHTTPClient(client *http.Client) *GetHealthzParams {
o.SetHTTPClient(client)
return o
}
// SetHTTPClient adds the HTTPClient to the get healthz params
func (o *GetHealthzParams) SetHTTPClient(client *http.Client) {
o.HTTPClient = client
}
// WriteToRequest writes these params to a swagger request
func (o *GetHealthzParams) WriteToRequest(r runtime.ClientRequest, reg strfmt.Registry) error {
if err := r.SetTimeout(o.timeout); err != nil {
return err
}
var res []error
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}

View File

@ -0,0 +1,126 @@
// Copyright 2020 Google LLC
//
// 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 go-swagger; DO NOT EDIT.
package healthz_service
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"fmt"
"io"
"github.com/go-openapi/runtime"
strfmt "github.com/go-openapi/strfmt"
healthz_model "github.com/kubeflow/pipelines/backend/api/go_http_client/healthz_model"
)
// GetHealthzReader is a Reader for the GetHealthz structure.
type GetHealthzReader struct {
formats strfmt.Registry
}
// ReadResponse reads a server response into the received o.
func (o *GetHealthzReader) ReadResponse(response runtime.ClientResponse, consumer runtime.Consumer) (interface{}, error) {
switch response.Code() {
case 200:
result := NewGetHealthzOK()
if err := result.readResponse(response, consumer, o.formats); err != nil {
return nil, err
}
return result, nil
default:
result := NewGetHealthzDefault(response.Code())
if err := result.readResponse(response, consumer, o.formats); err != nil {
return nil, err
}
if response.Code()/100 == 2 {
return result, nil
}
return nil, result
}
}
// NewGetHealthzOK creates a GetHealthzOK with default headers values
func NewGetHealthzOK() *GetHealthzOK {
return &GetHealthzOK{}
}
/*GetHealthzOK handles this case with default header values.
A successful response.
*/
type GetHealthzOK struct {
Payload *healthz_model.APIGetHealthzResponse
}
func (o *GetHealthzOK) Error() string {
return fmt.Sprintf("[GET /apis/v1beta1/healthz][%d] getHealthzOK %+v", 200, o.Payload)
}
func (o *GetHealthzOK) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error {
o.Payload = new(healthz_model.APIGetHealthzResponse)
// response payload
if err := consumer.Consume(response.Body(), o.Payload); err != nil && err != io.EOF {
return err
}
return nil
}
// NewGetHealthzDefault creates a GetHealthzDefault with default headers values
func NewGetHealthzDefault(code int) *GetHealthzDefault {
return &GetHealthzDefault{
_statusCode: code,
}
}
/*GetHealthzDefault handles this case with default header values.
GetHealthzDefault get healthz default
*/
type GetHealthzDefault struct {
_statusCode int
Payload *healthz_model.APIStatus
}
// Code gets the status code for the get healthz default response
func (o *GetHealthzDefault) Code() int {
return o._statusCode
}
func (o *GetHealthzDefault) Error() string {
return fmt.Sprintf("[GET /apis/v1beta1/healthz][%d] GetHealthz default %+v", o._statusCode, o.Payload)
}
func (o *GetHealthzDefault) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error {
o.Payload = new(healthz_model.APIStatus)
// response payload
if err := consumer.Consume(response.Body(), o.Payload); err != nil && err != io.EOF {
return err
}
return nil
}

View File

@ -0,0 +1,73 @@
// Copyright 2020 Google LLC
//
// 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 go-swagger; DO NOT EDIT.
package healthz_service
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"github.com/go-openapi/runtime"
strfmt "github.com/go-openapi/strfmt"
)
// New creates a new healthz service API client.
func New(transport runtime.ClientTransport, formats strfmt.Registry) *Client {
return &Client{transport: transport, formats: formats}
}
/*
Client for healthz service API
*/
type Client struct {
transport runtime.ClientTransport
formats strfmt.Registry
}
/*
GetHealthz gets healthz data
*/
func (a *Client) GetHealthz(params *GetHealthzParams, authInfo runtime.ClientAuthInfoWriter) (*GetHealthzOK, error) {
// TODO: Validate the params before sending
if params == nil {
params = NewGetHealthzParams()
}
result, err := a.transport.Submit(&runtime.ClientOperation{
ID: "GetHealthz",
Method: "GET",
PathPattern: "/apis/v1beta1/healthz",
ProducesMediaTypes: []string{"application/json"},
ConsumesMediaTypes: []string{"application/json"},
Schemes: []string{"http", "https"},
Params: params,
Reader: &GetHealthzReader{formats: a.formats},
AuthInfo: authInfo,
Context: params.Context,
Client: params.HTTPClient,
})
if err != nil {
return nil, err
}
return result.(*GetHealthzOK), nil
}
// SetTransport changes the transport on the client
func (a *Client) SetTransport(transport runtime.ClientTransport) {
a.transport = transport
}

View File

@ -0,0 +1,17 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = [
"api_get_healthz_response.go",
"api_status.go",
"protobuf_any.go",
],
importpath = "github.com/kubeflow/pipelines/backend/api/go_http_client/healthz_model",
visibility = ["//visibility:public"],
deps = [
"@com_github_go_openapi_errors//:go_default_library",
"@com_github_go_openapi_strfmt//:go_default_library",
"@com_github_go_openapi_swag//:go_default_library",
],
)

View File

@ -0,0 +1,57 @@
// Copyright 2020 Google LLC
//
// 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 go-swagger; DO NOT EDIT.
package healthz_model
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
strfmt "github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
)
// APIGetHealthzResponse api get healthz response
// swagger:model apiGetHealthzResponse
type APIGetHealthzResponse struct {
// Returns if KFP in multi-user mode
MultiUser bool `json:"multi_user,omitempty"`
}
// Validate validates this api get healthz response
func (m *APIGetHealthzResponse) Validate(formats strfmt.Registry) error {
return nil
}
// MarshalBinary interface implementation
func (m *APIGetHealthzResponse) MarshalBinary() ([]byte, error) {
if m == nil {
return nil, nil
}
return swag.WriteJSON(m)
}
// UnmarshalBinary interface implementation
func (m *APIGetHealthzResponse) UnmarshalBinary(b []byte) error {
var res APIGetHealthzResponse
if err := swag.ReadJSON(b, &res); err != nil {
return err
}
*m = res
return nil
}

View File

@ -0,0 +1,100 @@
// Copyright 2020 Google LLC
//
// 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 go-swagger; DO NOT EDIT.
package healthz_model
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"strconv"
strfmt "github.com/go-openapi/strfmt"
"github.com/go-openapi/errors"
"github.com/go-openapi/swag"
)
// APIStatus api status
// swagger:model apiStatus
type APIStatus struct {
// code
Code int32 `json:"code,omitempty"`
// details
Details []*ProtobufAny `json:"details"`
// error
Error string `json:"error,omitempty"`
}
// Validate validates this api status
func (m *APIStatus) Validate(formats strfmt.Registry) error {
var res []error
if err := m.validateDetails(formats); err != nil {
res = append(res, err)
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}
func (m *APIStatus) validateDetails(formats strfmt.Registry) error {
if swag.IsZero(m.Details) { // not required
return nil
}
for i := 0; i < len(m.Details); i++ {
if swag.IsZero(m.Details[i]) { // not required
continue
}
if m.Details[i] != nil {
if err := m.Details[i].Validate(formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName("details" + "." + strconv.Itoa(i))
}
return err
}
}
}
return nil
}
// MarshalBinary interface implementation
func (m *APIStatus) MarshalBinary() ([]byte, error) {
if m == nil {
return nil, nil
}
return swag.WriteJSON(m)
}
// UnmarshalBinary interface implementation
func (m *APIStatus) UnmarshalBinary(b []byte) error {
var res APIStatus
if err := swag.ReadJSON(b, &res); err != nil {
return err
}
*m = res
return nil
}

View File

@ -0,0 +1,185 @@
// Copyright 2020 Google LLC
//
// 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 go-swagger; DO NOT EDIT.
package healthz_model
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
strfmt "github.com/go-openapi/strfmt"
"github.com/go-openapi/errors"
"github.com/go-openapi/swag"
)
// ProtobufAny `Any` contains an arbitrary serialized protocol buffer message along with a
// URL that describes the type of the serialized message.
//
// Protobuf library provides support to pack/unpack Any values in the form
// of utility functions or additional generated methods of the Any type.
//
// Example 1: Pack and unpack a message in C++.
//
// Foo foo = ...;
// Any any;
// any.PackFrom(foo);
// ...
// if (any.UnpackTo(&foo)) {
// ...
// }
//
// Example 2: Pack and unpack a message in Java.
//
// Foo foo = ...;
// Any any = Any.pack(foo);
// ...
// if (any.is(Foo.class)) {
// foo = any.unpack(Foo.class);
// }
//
// Example 3: Pack and unpack a message in Python.
//
// foo = Foo(...)
// any = Any()
// any.Pack(foo)
// ...
// if any.Is(Foo.DESCRIPTOR):
// any.Unpack(foo)
// ...
//
// Example 4: Pack and unpack a message in Go
//
// foo := &pb.Foo{...}
// any, err := ptypes.MarshalAny(foo)
// ...
// foo := &pb.Foo{}
// if err := ptypes.UnmarshalAny(any, foo); err != nil {
// ...
// }
//
// The pack methods provided by protobuf library will by default use
// 'type.googleapis.com/full.type.name' as the type URL and the unpack
// methods only use the fully qualified type name after the last '/'
// in the type URL, for example "foo.bar.com/x/y.z" will yield type
// name "y.z".
//
//
// JSON
// ====
// The JSON representation of an `Any` value uses the regular
// representation of the deserialized, embedded message, with an
// additional field `@type` which contains the type URL. Example:
//
// package google.profile;
// message Person {
// string first_name = 1;
// string last_name = 2;
// }
//
// {
// "@type": "type.googleapis.com/google.profile.Person",
// "firstName": <string>,
// "lastName": <string>
// }
//
// If the embedded message type is well-known and has a custom JSON
// representation, that representation will be embedded adding a field
// `value` which holds the custom JSON in addition to the `@type`
// field. Example (for message [google.protobuf.Duration][]):
//
// {
// "@type": "type.googleapis.com/google.protobuf.Duration",
// "value": "1.212s"
// }
// swagger:model protobufAny
type ProtobufAny struct {
// A URL/resource name that uniquely identifies the type of the serialized
// protocol buffer message. The last segment of the URL's path must represent
// the fully qualified name of the type (as in
// `path/google.protobuf.Duration`). The name should be in a canonical form
// (e.g., leading "." is not accepted).
//
// In practice, teams usually precompile into the binary all types that they
// expect it to use in the context of Any. However, for URLs which use the
// scheme `http`, `https`, or no scheme, one can optionally set up a type
// server that maps type URLs to message definitions as follows:
//
// * If no scheme is provided, `https` is assumed.
// * An HTTP GET on the URL must yield a [google.protobuf.Type][]
// value in binary format, or produce an error.
// * Applications are allowed to cache lookup results based on the
// URL, or have them precompiled into a binary to avoid any
// lookup. Therefore, binary compatibility needs to be preserved
// on changes to types. (Use versioned type names to manage
// breaking changes.)
//
// Note: this functionality is not currently available in the official
// protobuf release, and it is not used for type URLs beginning with
// type.googleapis.com.
//
// Schemes other than `http`, `https` (or the empty scheme) might be
// used with implementation specific semantics.
TypeURL string `json:"type_url,omitempty"`
// Must be a valid serialized protocol buffer of the above specified type.
// Format: byte
Value strfmt.Base64 `json:"value,omitempty"`
}
// Validate validates this protobuf any
func (m *ProtobufAny) Validate(formats strfmt.Registry) error {
var res []error
if err := m.validateValue(formats); err != nil {
res = append(res, err)
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}
func (m *ProtobufAny) validateValue(formats strfmt.Registry) error {
if swag.IsZero(m.Value) { // not required
return nil
}
// Format "byte" (base64 string) is already validated when unmarshalled
return nil
}
// MarshalBinary interface implementation
func (m *ProtobufAny) MarshalBinary() ([]byte, error) {
if m == nil {
return nil, nil
}
return swag.WriteJSON(m)
}
// UnmarshalBinary interface implementation
func (m *ProtobufAny) UnmarshalBinary(b []byte) error {
var res ProtobufAny
if err := swag.ReadJSON(b, &res); err != nil {
return err
}
*m = res
return nil
}

74
backend/api/healthz.proto Normal file
View File

@ -0,0 +1,74 @@
// Copyright 2020 Google LLC
//
// 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.
syntax = "proto3";
option go_package = "github.com/kubeflow/pipelines/backend/api/go_client";
package api;
import "google/api/annotations.proto";
import "google/protobuf/timestamp.proto";
import "google/protobuf/empty.proto";
import "backend/api/pipeline_spec.proto";
import "backend/api/resource_reference.proto";
import "protoc-gen-swagger/options/annotations.proto";
import "backend/api/error.proto";
option (grpc.gateway.protoc_gen_swagger.options.openapiv2_swagger) = {
responses: {
key: "default";
value: {
schema: {
json_schema: {
ref: ".api.Status";
}
}
}
}
// Use bearer token for authorizing access to job service.
// Kubernetes client library(https://kubernetes.io/docs/reference/using-api/client-libraries/)
// uses bearer token as default for authorization. The section below
// ensures security definition object is generated in the swagger definition.
// For more details see https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#securityDefinitionsObject
security_definitions: {
security: {
key: "Bearer";
value: {
type: TYPE_API_KEY;
in: IN_HEADER;
name: "authorization";
}
}
}
security: {
security_requirement: {
key: "Bearer";
value: {};
}
}
};
service HealthzService {
// Get healthz data.
rpc GetHealthz(google.protobuf.Empty) returns (GetHealthzResponse) {
option (google.api.http) = {
get: "/apis/v1beta1/healthz"
};
}
}
message GetHealthzResponse {
// Returns if KFP in multi-user mode
bool multi_user = 3;
}

View File

@ -102,6 +102,7 @@ Class | Method | HTTP request | Description
*ExperimentServiceApi* | [**get_experiment**](docs/ExperimentServiceApi.md#get_experiment) | **GET** /apis/v1beta1/experiments/{id} | Finds a specific experiment by ID.
*ExperimentServiceApi* | [**list_experiment**](docs/ExperimentServiceApi.md#list_experiment) | **GET** /apis/v1beta1/experiments | Finds all experiments. Supports pagination, and sorting on certain fields.
*ExperimentServiceApi* | [**unarchive_experiment**](docs/ExperimentServiceApi.md#unarchive_experiment) | **POST** /apis/v1beta1/experiments/{id}:unarchive | Restores an archived experiment. The experiment&#39;s archived runs and jobs will stay archived.
*HealthzServiceApi* | [**get_healthz**](docs/HealthzServiceApi.md#get_healthz) | **GET** /apis/v1beta1/healthz | Get healthz data.
*JobServiceApi* | [**create_job**](docs/JobServiceApi.md#create_job) | **POST** /apis/v1beta1/jobs | Creates a new job.
*JobServiceApi* | [**delete_job**](docs/JobServiceApi.md#delete_job) | **DELETE** /apis/v1beta1/jobs/{id} | Deletes a job.
*JobServiceApi* | [**disable_job**](docs/JobServiceApi.md#disable_job) | **POST** /apis/v1beta1/jobs/{id}/disable | Stops a job and all its associated runs. The job is not deleted.
@ -137,6 +138,7 @@ Class | Method | HTTP request | Description
- [ApiCronSchedule](docs/ApiCronSchedule.md)
- [ApiExperiment](docs/ApiExperiment.md)
- [ApiGetHealthzResponse](docs/ApiGetHealthzResponse.md)
- [ApiGetTemplateResponse](docs/ApiGetTemplateResponse.md)
- [ApiJob](docs/ApiJob.md)
- [ApiListExperimentsResponse](docs/ApiListExperimentsResponse.md)

View File

@ -0,0 +1,10 @@
# ApiGetHealthzResponse
## Properties
Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
**multi_user** | **bool** | | [optional]
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)

View File

@ -0,0 +1,81 @@
# kfp_server_api.HealthzServiceApi
All URIs are relative to *http://localhost*
Method | HTTP request | Description
------------- | ------------- | -------------
[**get_healthz**](HealthzServiceApi.md#get_healthz) | **GET** /apis/v1beta1/healthz | Get healthz data.
# **get_healthz**
> ApiGetHealthzResponse get_healthz()
Get healthz data.
### Example
* Api Key Authentication (Bearer):
```python
from __future__ import print_function
import time
import kfp_server_api
from kfp_server_api.rest import ApiException
from pprint import pprint
# Defining the host is optional and defaults to http://localhost
# See configuration.py for a list of all supported configuration parameters.
configuration = kfp_server_api.Configuration(
host = "http://localhost"
)
# The client must configure the authentication and authorization parameters
# in accordance with the API server security policy.
# Examples for each auth method are provided below, use the example that
# satisfies your auth use case.
# Configure API key authorization: Bearer
configuration = kfp_server_api.Configuration(
host = "http://localhost",
api_key = {
'authorization': 'YOUR_API_KEY'
}
)
# Uncomment below to setup prefix (e.g. Bearer) for API key, if needed
# configuration.api_key_prefix['authorization'] = 'Bearer'
# Enter a context with an instance of the API client
with kfp_server_api.ApiClient(configuration) as api_client:
# Create an instance of the API class
api_instance = kfp_server_api.HealthzServiceApi(api_client)
try:
# Get healthz data.
api_response = api_instance.get_healthz()
pprint(api_response)
except ApiException as e:
print("Exception when calling HealthzServiceApi->get_healthz: %s\n" % e)
```
### Parameters
This endpoint does not need any parameter.
### Return type
[**ApiGetHealthzResponse**](ApiGetHealthzResponse.md)
### Authorization
[Bearer](../README.md#Bearer)
### HTTP request headers
- **Content-Type**: Not defined
- **Accept**: application/json
### HTTP response details
| Status code | Description | Response headers |
|-------------|-------------|------------------|
**200** | A successful response. | - |
**0** | | - |
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)

View File

@ -32,6 +32,7 @@ __version__ = "1.1.0-alpha.1"
# import apis into sdk package
from kfp_server_api.api.experiment_service_api import ExperimentServiceApi
from kfp_server_api.api.healthz_service_api import HealthzServiceApi
from kfp_server_api.api.job_service_api import JobServiceApi
from kfp_server_api.api.pipeline_service_api import PipelineServiceApi
from kfp_server_api.api.pipeline_upload_service_api import PipelineUploadServiceApi
@ -48,6 +49,7 @@ from kfp_server_api.exceptions import ApiException
# import models into sdk package
from kfp_server_api.models.api_cron_schedule import ApiCronSchedule
from kfp_server_api.models.api_experiment import ApiExperiment
from kfp_server_api.models.api_get_healthz_response import ApiGetHealthzResponse
from kfp_server_api.models.api_get_template_response import ApiGetTemplateResponse
from kfp_server_api.models.api_job import ApiJob
from kfp_server_api.models.api_list_experiments_response import ApiListExperimentsResponse

View File

@ -18,6 +18,7 @@ from __future__ import absolute_import
# import apis into api package
from kfp_server_api.api.experiment_service_api import ExperimentServiceApi
from kfp_server_api.api.healthz_service_api import HealthzServiceApi
from kfp_server_api.api.job_service_api import JobServiceApi
from kfp_server_api.api.pipeline_service_api import PipelineServiceApi
from kfp_server_api.api.pipeline_upload_service_api import PipelineUploadServiceApi

View File

@ -0,0 +1,162 @@
# Copyright 2020 Google LLC
#
# 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.
# coding: utf-8
"""
Kubeflow Pipelines API
This file contains REST API specification for Kubeflow Pipelines. The file is autogenerated from the swagger definition.
Contact: kubeflow-pipelines@google.com
Generated by: https://openapi-generator.tech
"""
from __future__ import absolute_import
import re # noqa: F401
# python 2 and python 3 compatibility library
import six
from kfp_server_api.api_client import ApiClient
from kfp_server_api.exceptions import ( # noqa: F401
ApiTypeError,
ApiValueError
)
class HealthzServiceApi(object):
"""NOTE: This class is auto generated by OpenAPI Generator
Ref: https://openapi-generator.tech
Do not edit the class manually.
"""
def __init__(self, api_client=None):
if api_client is None:
api_client = ApiClient()
self.api_client = api_client
def get_healthz(self, **kwargs): # noqa: E501
"""Get healthz data. # noqa: E501
This method makes a synchronous HTTP request by default. To make an
asynchronous HTTP request, please pass async_req=True
>>> thread = api.get_healthz(async_req=True)
>>> result = thread.get()
:param async_req: Whether to execute the request asynchronously.
:type async_req: bool, optional
:param _preload_content: if False, the urllib3.HTTPResponse object will
be returned without reading/decoding response
data. Default is True.
:param _request_timeout: timeout setting for this request. If one
number provided, it will be total request
timeout. It can also be a pair (tuple) of
(connection, read) timeouts.
:return: Returns the result object.
If the method is called asynchronously,
returns the request thread.
:rtype: ApiGetHealthzResponse
"""
kwargs['_return_http_data_only'] = True
return self.get_healthz_with_http_info(**kwargs) # noqa: E501
def get_healthz_with_http_info(self, **kwargs): # noqa: E501
"""Get healthz data. # noqa: E501
This method makes a synchronous HTTP request by default. To make an
asynchronous HTTP request, please pass async_req=True
>>> thread = api.get_healthz_with_http_info(async_req=True)
>>> result = thread.get()
:param async_req: Whether to execute the request asynchronously.
:type async_req: bool, optional
:param _return_http_data_only: response data without head status code
and headers
:type _return_http_data_only: bool, optional
:param _preload_content: if False, the urllib3.HTTPResponse object will
be returned without reading/decoding response
data. Default is True.
:type _preload_content: bool, optional
:param _request_timeout: timeout setting for this request. If one
number provided, it will be total request
timeout. It can also be a pair (tuple) of
(connection, read) timeouts.
:return: Returns the result object.
If the method is called asynchronously,
returns the request thread.
:rtype: tuple(ApiGetHealthzResponse, status_code(int), headers(HTTPHeaderDict))
"""
local_var_params = locals()
all_params = [
]
all_params.extend(
[
'async_req',
'_return_http_data_only',
'_preload_content',
'_request_timeout'
]
)
for key, val in six.iteritems(local_var_params['kwargs']):
if key not in all_params:
raise ApiTypeError(
"Got an unexpected keyword argument '%s'"
" to method get_healthz" % key
)
local_var_params[key] = val
del local_var_params['kwargs']
collection_formats = {}
path_params = {}
query_params = []
header_params = {}
form_params = []
local_var_files = {}
body_params = None
# HTTP header `Accept`
header_params['Accept'] = self.api_client.select_header_accept(
['application/json']) # noqa: E501
# Authentication setting
auth_settings = ['Bearer'] # noqa: E501
return self.api_client.call_api(
'/apis/v1beta1/healthz', 'GET',
path_params,
query_params,
header_params,
body=body_params,
post_params=form_params,
files=local_var_files,
response_type='ApiGetHealthzResponse', # noqa: E501
auth_settings=auth_settings,
async_req=local_var_params.get('async_req'),
_return_http_data_only=local_var_params.get('_return_http_data_only'), # noqa: E501
_preload_content=local_var_params.get('_preload_content', True),
_request_timeout=local_var_params.get('_request_timeout'),
collection_formats=collection_formats)

View File

@ -30,6 +30,7 @@ from __future__ import absolute_import
# import models into model package
from kfp_server_api.models.api_cron_schedule import ApiCronSchedule
from kfp_server_api.models.api_experiment import ApiExperiment
from kfp_server_api.models.api_get_healthz_response import ApiGetHealthzResponse
from kfp_server_api.models.api_get_template_response import ApiGetTemplateResponse
from kfp_server_api.models.api_job import ApiJob
from kfp_server_api.models.api_list_experiments_response import ApiListExperimentsResponse

View File

@ -0,0 +1,134 @@
# Copyright 2020 Google LLC
#
# 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.
# coding: utf-8
"""
Kubeflow Pipelines API
This file contains REST API specification for Kubeflow Pipelines. The file is autogenerated from the swagger definition.
Contact: kubeflow-pipelines@google.com
Generated by: https://openapi-generator.tech
"""
import pprint
import re # noqa: F401
import six
from kfp_server_api.configuration import Configuration
class ApiGetHealthzResponse(object):
"""NOTE: This class is auto generated by OpenAPI Generator.
Ref: https://openapi-generator.tech
Do not edit the class manually.
"""
"""
Attributes:
openapi_types (dict): The key is attribute name
and the value is attribute type.
attribute_map (dict): The key is attribute name
and the value is json key in definition.
"""
openapi_types = {
'multi_user': 'bool'
}
attribute_map = {
'multi_user': 'multi_user'
}
def __init__(self, multi_user=None, local_vars_configuration=None): # noqa: E501
"""ApiGetHealthzResponse - a model defined in OpenAPI""" # noqa: E501
if local_vars_configuration is None:
local_vars_configuration = Configuration()
self.local_vars_configuration = local_vars_configuration
self._multi_user = None
self.discriminator = None
if multi_user is not None:
self.multi_user = multi_user
@property
def multi_user(self):
"""Gets the multi_user of this ApiGetHealthzResponse. # noqa: E501
:return: The multi_user of this ApiGetHealthzResponse. # noqa: E501
:rtype: bool
"""
return self._multi_user
@multi_user.setter
def multi_user(self, multi_user):
"""Sets the multi_user of this ApiGetHealthzResponse.
:param multi_user: The multi_user of this ApiGetHealthzResponse. # noqa: E501
:type multi_user: bool
"""
self._multi_user = multi_user
def to_dict(self):
"""Returns the model properties as a dict"""
result = {}
for attr, _ in six.iteritems(self.openapi_types):
value = getattr(self, attr)
if isinstance(value, list):
result[attr] = list(map(
lambda x: x.to_dict() if hasattr(x, "to_dict") else x,
value
))
elif hasattr(value, "to_dict"):
result[attr] = value.to_dict()
elif isinstance(value, dict):
result[attr] = dict(map(
lambda item: (item[0], item[1].to_dict())
if hasattr(item[1], "to_dict") else item,
value.items()
))
else:
result[attr] = value
return result
def to_str(self):
"""Returns the string representation of the model"""
return pprint.pformat(self.to_dict())
def __repr__(self):
"""For `print` and `pprint`"""
return self.to_str()
def __eq__(self, other):
"""Returns true if both objects are equal"""
if not isinstance(other, ApiGetHealthzResponse):
return False
return self.to_dict() == other.to_dict()
def __ne__(self, other):
"""Returns true if both objects are not equal"""
if not isinstance(other, ApiGetHealthzResponse):
return True
return self.to_dict() != other.to_dict()

View File

@ -0,0 +1,66 @@
# Copyright 2020 Google LLC
#
# 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.
# coding: utf-8
"""
Kubeflow Pipelines API
This file contains REST API specification for Kubeflow Pipelines. The file is autogenerated from the swagger definition.
Contact: kubeflow-pipelines@google.com
Generated by: https://openapi-generator.tech
"""
from __future__ import absolute_import
import unittest
import datetime
import kfp_server_api
from kfp_server_api.models.api_get_healthz_response import ApiGetHealthzResponse # noqa: E501
from kfp_server_api.rest import ApiException
class TestApiGetHealthzResponse(unittest.TestCase):
"""ApiGetHealthzResponse unit test stubs"""
def setUp(self):
pass
def tearDown(self):
pass
def make_instance(self, include_optional):
"""Test ApiGetHealthzResponse
include_option is a boolean, when False only required
params are included, when True both required and
optional params are included """
# model = kfp_server_api.models.api_get_healthz_response.ApiGetHealthzResponse() # noqa: E501
if include_optional :
return ApiGetHealthzResponse(
multi_user = True
)
else :
return ApiGetHealthzResponse(
)
def testApiGetHealthzResponse(self):
"""Test ApiGetHealthzResponse"""
inst_req_only = self.make_instance(include_optional=False)
inst_req_and_optional = self.make_instance(include_optional=True)
if __name__ == '__main__':
unittest.main()

View File

@ -0,0 +1,54 @@
# Copyright 2020 Google LLC
#
# 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.
# coding: utf-8
"""
Kubeflow Pipelines API
This file contains REST API specification for Kubeflow Pipelines. The file is autogenerated from the swagger definition.
Contact: kubeflow-pipelines@google.com
Generated by: https://openapi-generator.tech
"""
from __future__ import absolute_import
import unittest
import kfp_server_api
from kfp_server_api.api.healthz_service_api import HealthzServiceApi # noqa: E501
from kfp_server_api.rest import ApiException
class TestHealthzServiceApi(unittest.TestCase):
"""HealthzServiceApi unit test stubs"""
def setUp(self):
self.api = kfp_server_api.api.healthz_service_api.HealthzServiceApi() # noqa: E501
def tearDown(self):
pass
def test_get_healthz(self):
"""Test case for get_healthz
Get healthz data. # noqa: E501
"""
pass
if __name__ == '__main__':
unittest.main()

99
backend/api/swagger/healthz.swagger.json generated Executable file
View File

@ -0,0 +1,99 @@
{
"swagger": "2.0",
"info": {
"title": "backend/api/healthz.proto",
"version": "version not set"
},
"schemes": [
"http",
"https"
],
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"paths": {
"/apis/v1beta1/healthz": {
"get": {
"summary": "Get healthz data.",
"operationId": "GetHealthz",
"responses": {
"200": {
"description": "A successful response.",
"schema": {
"$ref": "#/definitions/apiGetHealthzResponse"
}
},
"default": {
"description": "",
"schema": {
"$ref": "#/definitions/apiStatus"
}
}
},
"tags": [
"HealthzService"
]
}
}
},
"definitions": {
"apiGetHealthzResponse": {
"type": "object",
"properties": {
"multi_user": {
"type": "boolean",
"format": "boolean",
"title": "Returns if KFP in multi-user mode"
}
}
},
"apiStatus": {
"type": "object",
"properties": {
"error": {
"type": "string"
},
"code": {
"type": "integer",
"format": "int32"
},
"details": {
"type": "array",
"items": {
"$ref": "#/definitions/protobufAny"
}
}
}
},
"protobufAny": {
"type": "object",
"properties": {
"type_url": {
"type": "string",
"description": "A URL/resource name that uniquely identifies the type of the serialized\nprotocol buffer message. The last segment of the URL's path must represent\nthe fully qualified name of the type (as in\n`path/google.protobuf.Duration`). The name should be in a canonical form\n(e.g., leading \".\" is not accepted).\n\nIn practice, teams usually precompile into the binary all types that they\nexpect it to use in the context of Any. However, for URLs which use the\nscheme `http`, `https`, or no scheme, one can optionally set up a type\nserver that maps type URLs to message definitions as follows:\n\n* If no scheme is provided, `https` is assumed.\n* An HTTP GET on the URL must yield a [google.protobuf.Type][]\n value in binary format, or produce an error.\n* Applications are allowed to cache lookup results based on the\n URL, or have them precompiled into a binary to avoid any\n lookup. Therefore, binary compatibility needs to be preserved\n on changes to types. (Use versioned type names to manage\n breaking changes.)\n\nNote: this functionality is not currently available in the official\nprotobuf release, and it is not used for type URLs beginning with\ntype.googleapis.com.\n\nSchemes other than `http`, `https` (or the empty scheme) might be\nused with implementation specific semantics."
},
"value": {
"type": "string",
"format": "byte",
"description": "Must be a valid serialized protocol buffer of the above specified type."
}
},
"description": "`Any` contains an arbitrary serialized protocol buffer message along with a\nURL that describes the type of the serialized message.\n\nProtobuf library provides support to pack/unpack Any values in the form\nof utility functions or additional generated methods of the Any type.\n\nExample 1: Pack and unpack a message in C++.\n\n Foo foo = ...;\n Any any;\n any.PackFrom(foo);\n ...\n if (any.UnpackTo(\u0026foo)) {\n ...\n }\n\nExample 2: Pack and unpack a message in Java.\n\n Foo foo = ...;\n Any any = Any.pack(foo);\n ...\n if (any.is(Foo.class)) {\n foo = any.unpack(Foo.class);\n }\n\n Example 3: Pack and unpack a message in Python.\n\n foo = Foo(...)\n any = Any()\n any.Pack(foo)\n ...\n if any.Is(Foo.DESCRIPTOR):\n any.Unpack(foo)\n ...\n\n Example 4: Pack and unpack a message in Go\n\n foo := \u0026pb.Foo{...}\n any, err := ptypes.MarshalAny(foo)\n ...\n foo := \u0026pb.Foo{}\n if err := ptypes.UnmarshalAny(any, foo); err != nil {\n ...\n }\n\nThe pack methods provided by protobuf library will by default use\n'type.googleapis.com/full.type.name' as the type URL and the unpack\nmethods only use the fully qualified type name after the last '/'\nin the type URL, for example \"foo.bar.com/x/y.z\" will yield type\nname \"y.z\".\n\n\nJSON\n====\nThe JSON representation of an `Any` value uses the regular\nrepresentation of the deserialized, embedded message, with an\nadditional field `@type` which contains the type URL. Example:\n\n package google.profile;\n message Person {\n string first_name = 1;\n string last_name = 2;\n }\n\n {\n \"@type\": \"type.googleapis.com/google.profile.Person\",\n \"firstName\": \u003cstring\u003e,\n \"lastName\": \u003cstring\u003e\n }\n\nIf the embedded message type is well-known and has a custom JSON\nrepresentation, that representation will be embedded adding a field\n`value` which holds the custom JSON in addition to the `@type`\nfield. Example (for message [google.protobuf.Duration][]):\n\n {\n \"@type\": \"type.googleapis.com/google.protobuf.Duration\",\n \"value\": \"1.212s\"\n }"
}
},
"securityDefinitions": {
"Bearer": {
"type": "apiKey",
"name": "authorization",
"in": "header"
}
},
"security": [
{
"Bearer": []
}
]
}

View File

@ -1399,6 +1399,29 @@
"PipelineUploadService"
]
}
},
"/apis/v1beta1/healthz": {
"get": {
"summary": "Get healthz data.",
"operationId": "GetHealthz",
"responses": {
"200": {
"description": "A successful response.",
"schema": {
"$ref": "#/definitions/apiGetHealthzResponse"
}
},
"default": {
"description": "",
"schema": {
"$ref": "#/definitions/apiStatus"
}
}
},
"tags": [
"HealthzService"
]
}
}
},
"definitions": {
@ -2102,6 +2125,16 @@
"description": "The token to list the next page of experiments."
}
}
},
"apiGetHealthzResponse": {
"type": "object",
"properties": {
"multi_user": {
"type": "boolean",
"format": "boolean",
"title": "Returns if KFP in multi-user mode"
}
}
}
},
"securityDefinitions": {

View File

@ -0,0 +1,21 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
go_library(
name = "go_default_library",
srcs = ["log.go"],
importpath = "github.com/kubeflow/pipelines/backend/src/apiserver/archive",
visibility = ["//visibility:public"],
deps = ["//backend/src/common/util:go_default_library"],
)
go_test(
name = "go_default_test",
srcs = ["log_test.go"],
embed = [":go_default_library"],
deps = [
"//backend/src/common/util:go_default_library",
"@com_github_argoproj_argo//pkg/apis/workflow/v1alpha1:go_default_library",
"@com_github_stretchr_testify//assert:go_default_library",
"@io_k8s_apimachinery//pkg/apis/meta/v1:go_default_library",
],
)

View File

@ -25,6 +25,7 @@ import (
"net"
"net/http"
"os"
"strconv"
"strings"
"time"
@ -141,7 +142,7 @@ func startHttpProxy(resourceManager *resource.ResourceManager) {
topMux.HandleFunc("/apis/v1beta1/pipelines/upload", pipelineUploadServer.UploadPipeline)
topMux.HandleFunc("/apis/v1beta1/pipelines/upload_version", pipelineUploadServer.UploadPipelineVersion)
topMux.HandleFunc("/apis/v1beta1/healthz", func(w http.ResponseWriter, r *http.Request) {
io.WriteString(w, `{"commit_sha":"`+common.GetStringConfigWithDefault("COMMIT_SHA", "unknown")+`", "tag_name":"`+common.GetStringConfigWithDefault("TAG_NAME", "unknown")+`"}`)
io.WriteString(w, `{"commit_sha":"`+common.GetStringConfigWithDefault("COMMIT_SHA", "unknown")+`", "tag_name":"`+common.GetStringConfigWithDefault("TAG_NAME", "unknown")+`", "multi_user":`+strconv.FormatBool(common.IsMultiUserMode())+`}`)
})
// log streaming is provided via HTTP.

View File

@ -34,7 +34,6 @@ go_library(
"@io_k8s_apimachinery//pkg/api/errors:go_default_library",
"@io_k8s_apimachinery//pkg/apis/meta/v1:go_default_library",
"@io_k8s_apimachinery//pkg/types:go_default_library",
"@io_k8s_client_go//kubernetes/typed/authorization/v1:go_default_library",
],
)

View File

@ -125,6 +125,7 @@ describe('UIServer apis', () => {
Promise.resolve({
commit_sha: 'commit_sha',
tag_name: '1.0.0',
multi_user: false,
}),
}));
@ -137,6 +138,8 @@ describe('UIServer apis', () => {
{
apiServerCommitHash: 'commit_sha',
apiServerTagName: '1.0.0',
apiServerMultiUser: false,
multi_user: false,
apiServerReady: true,
buildDate,
frontendCommitHash: commitHash,

View File

@ -20,6 +20,8 @@ import { Handler } from 'express';
export interface HealthzStats {
apiServerCommitHash: string;
apiServerTagName: string;
apiServerMultiUser: boolean;
multi_user: boolean;
apiServerReady: boolean;
buildDate: string;
frontendCommitHash: string;
@ -79,6 +81,8 @@ export function getHealthzHandler(options: {
const serverStatus = await response.json();
healthzStats.apiServerCommitHash = serverStatus.commit_sha;
healthzStats.apiServerTagName = serverStatus.tag_name;
healthzStats.apiServerMultiUser = serverStatus.multi_user;
healthzStats.multi_user = serverStatus.multi_user;
} catch (e) {
healthzStats.apiServerReady = false;
}

View File

@ -115,6 +115,11 @@ class Client(object):
IN_CLUSTER_DNS_NAME = 'ml-pipeline.{}.svc.cluster.local:8888'
KUBE_PROXY_PATH = 'api/v1/namespaces/{}/services/ml-pipeline:http/proxy/'
# Auto populated path in pods
# https://kubernetes.io/docs/tasks/access-application-cluster/access-cluster/#accessing-the-api-from-a-pod
# https://kubernetes.io/docs/reference/access-authn-authz/service-accounts-admin/#serviceaccount-admission-controller
NAMESPACE_PATH = '/var/run/secrets/kubernetes.io/serviceaccount/namespace'
LOCAL_KFP_CONTEXT = os.path.expanduser('~/.config/kfp/context.json')
# TODO: Wrap the configurations for different authentication methods.
@ -139,6 +144,14 @@ class Client(object):
self._experiment_api = kfp_server_api.api.experiment_service_api.ExperimentServiceApi(api_client)
self._pipelines_api = kfp_server_api.api.pipeline_service_api.PipelineServiceApi(api_client)
self._upload_api = kfp_server_api.api.PipelineUploadServiceApi(api_client)
self._healthz_api = kfp_server_api.api.healthz_service_api.HealthzServiceApi(api_client)
if not self._context_setting['namespace'] and self.get_kfp_healthz().multi_user is True:
try:
with open(Client.NAMESPACE_PATH, 'r') as f:
current_namespace = f.read()
self.set_user_namespace(current_namespace)
except FileNotFoundError:
logging.info('Failed to automatically set namespace.', exc_info=True)
def _load_config(self, host, client_id, namespace, other_client_id, other_client_secret, existing_token, proxy, ssl_ca_cert, kube_context):
config = kfp_server_api.configuration.Configuration()
@ -277,9 +290,31 @@ class Client(object):
namespace: kubernetes namespace the user has access to.
"""
self._context_setting['namespace'] = namespace
if not os.path.exists(os.path.dirname(Client.LOCAL_KFP_CONTEXT)):
os.makedirs(os.path.dirname(Client.LOCAL_KFP_CONTEXT))
with open(Client.LOCAL_KFP_CONTEXT, 'w') as f:
json.dump(self._context_setting, f)
def get_kfp_healthz(self):
"""Gets healthz info of KFP deployment.
Returns:
response: json formatted response from the healtz endpoint.
"""
count = 0
response = None
max_attempts = 5
while not response:
count += 1
if count > max_attempts:
raise TimeoutError('API call timeout')
try:
response = self._healthz_api.get_healthz()
return response
except:
logging.info('Failed to get healthz info attempt {} of 5.'.format(count))
time.sleep(5)
def get_user_namespace(self):
"""Get user namespace in context config.

View File

@ -11,6 +11,10 @@ RUN wget https://bootstrap.pypa.io/get-pip.py && python3 get-pip.py
COPY ./test/sample-test/requirements.txt /python/src/github.com/kubeflow/pipelines/test/sample-test/requirements.txt
RUN pip3 install -r /python/src/github.com/kubeflow/pipelines/test/sample-test/requirements.txt
# Install KFP server API from commit.
COPY ./backend/api/python_http_client /python_http_client
RUN cd /python_http_client && python3 setup.py install
# Install python client, including DSL compiler.
COPY ./sdk/python /sdk/python
RUN cd /sdk/python && python3 setup.py install