Remove MustReg
continuous-integration/drone/tag Build is failing Details

main v0.4.2
René Jochum 2 years ago
parent ae68eb3edd
commit 713487dabf
Signed by: jochum
GPG Key ID: F7D906F5E51E8E5E

@ -5,11 +5,12 @@ import (
"fmt"
"jochum.dev/jo-micro/buncomponent"
"jochum.dev/jo-micro/components"
)
func RoleGetId(ctx context.Context, name string) (string, error) {
func RoleGetId(cReg *components.Registry, ctx context.Context, name string) (string, error) {
var result string
err := buncomponent.Must(ctx).Bun().NewSelect().Table("roles").Column("id").Limit(1).Where("name = ?", name).Scan(ctx, &result)
err := buncomponent.MustReg(cReg).Bun().NewSelect().Table("roles").Column("id").Limit(1).Where("name = ?", name).Scan(ctx, &result)
if err != nil || len(result) < 1 {
return "", fmt.Errorf("role '%s' not found", name)
}

@ -8,6 +8,7 @@ import (
"github.com/uptrace/bun"
"jochum.dev/jo-micro/buncomponent"
"jochum.dev/jo-micro/components"
)
type User struct {
@ -26,10 +27,10 @@ type User struct {
DeletedAt bun.NullTime `bun:"deleted_at,soft_delete,nullzero" json:"deleted_at" yaml:"deleted_at"`
}
func UserList(ctx context.Context, limit, offset uint64) ([]User, error) {
func UserList(cReg *components.Registry, ctx context.Context, limit, offset uint64) ([]User, error) {
// Get the data from the db.
var users []User
err := buncomponent.Must(ctx).Bun().NewSelect().
err := buncomponent.MustReg(cReg).Bun().NewSelect().
Model(&users).
ColumnExpr("u.*").
ColumnExpr("array(SELECT r.name FROM users_roles AS ur LEFT JOIN roles AS r ON ur.role_id = r.id WHERE ur.user_id = u.id) AS roles").
@ -42,9 +43,9 @@ func UserList(ctx context.Context, limit, offset uint64) ([]User, error) {
return users, nil
}
func UserDetail(ctx context.Context, id string) (*User, error) {
func UserDetail(cReg *components.Registry, ctx context.Context, id string) (*User, error) {
user := User{}
err := buncomponent.Must(ctx).Bun().NewSelect().
err := buncomponent.MustReg(cReg).Bun().NewSelect().
Model(&user).
ColumnExpr("u.*").
ColumnExpr("array(SELECT r.name FROM users_roles AS ur LEFT JOIN roles AS r ON ur.role_id = r.id WHERE ur.user_id = u.id) AS roles").
@ -59,17 +60,17 @@ func UserDetail(ctx context.Context, id string) (*User, error) {
return &user, nil
}
func UserDelete(ctx context.Context, id string) error {
func UserDelete(cReg *components.Registry, ctx context.Context, id string) error {
user := User{}
_, err := buncomponent.Must(ctx).Bun().NewDelete().Model(&user).Where("id = ?", id).Exec(ctx)
_, err := buncomponent.MustReg(cReg).Bun().NewDelete().Model(&user).Where("id = ?", id).Exec(ctx)
return err
}
func UserUpdateRoles(ctx context.Context, id string, roles []string) (*User, error) {
func UserUpdateRoles(cReg *components.Registry, ctx context.Context, id string, roles []string) (*User, error) {
// Check if all new roles exists
rolesIds := make([]string, len(roles))
for idx, role := range roles {
id, err := RoleGetId(ctx, role)
id, err := RoleGetId(cReg, ctx, role)
if err != nil {
return nil, err
}
@ -77,14 +78,14 @@ func UserUpdateRoles(ctx context.Context, id string, roles []string) (*User, err
}
// Delete all current roles
_, err := buncomponent.Must(ctx).Bun().NewDelete().Table("users_roles").Where("user_id = ?", id).Exec(ctx)
_, err := buncomponent.MustReg(cReg).Bun().NewDelete().Table("users_roles").Where("user_id = ?", id).Exec(ctx)
if err != nil {
return nil, err
}
// Exit out if user wants to delete all roles
if len(roles) < 1 {
return UserDetail(ctx, id)
return UserDetail(cReg, ctx, id)
}
// Reassign roles
@ -93,18 +94,18 @@ func UserUpdateRoles(ctx context.Context, id string, roles []string) (*User, err
"user_id": id,
"role_id": roleId,
}
_, err = buncomponent.Must(ctx).Bun().NewInsert().Model(&values).TableExpr("users_roles").Exec(ctx)
_, err = buncomponent.MustReg(cReg).Bun().NewInsert().Model(&values).TableExpr("users_roles").Exec(ctx)
if err != nil {
return nil, err
}
}
return UserDetail(ctx, id)
return UserDetail(cReg, ctx, id)
}
func UserFindByUsername(ctx context.Context, username string) (*User, error) {
func UserFindByUsername(cReg *components.Registry, ctx context.Context, username string) (*User, error) {
user := User{}
err := buncomponent.Must(ctx).Bun().NewSelect().
err := buncomponent.MustReg(cReg).Bun().NewSelect().
Model(&user).
ColumnExpr("u.*").
ColumnExpr("array(SELECT r.name FROM users_roles AS ur LEFT JOIN roles AS r ON ur.role_id = r.id WHERE ur.user_id = u.id) AS roles").
@ -119,9 +120,9 @@ func UserFindByUsername(ctx context.Context, username string) (*User, error) {
return &user, nil
}
func UserFindById(ctx context.Context, id string) (*User, error) {
func UserFindById(cReg *components.Registry, ctx context.Context, id string) (*User, error) {
user := User{}
err := buncomponent.Must(ctx).Bun().NewSelect().
err := buncomponent.MustReg(cReg).Bun().NewSelect().
Model(&user).
ColumnExpr("u.*").
ColumnExpr("array(SELECT r.name FROM users_roles AS ur LEFT JOIN roles AS r ON ur.role_id = r.id WHERE ur.user_id = u.id) AS roles").
@ -136,22 +137,22 @@ func UserFindById(ctx context.Context, id string) (*User, error) {
return &user, nil
}
func UserCreate(ctx context.Context, username, password, email string, roles []string) (*User, error) {
func UserCreate(cReg *components.Registry, ctx context.Context, username, password, email string, roles []string) (*User, error) {
// Create the user
user := User{}
user.Username = username
user.Password = password
user.Email = email
_, err := buncomponent.Must(ctx).Bun().NewInsert().Model(&user).Exec(ctx, &user)
_, err := buncomponent.MustReg(cReg).Bun().NewInsert().Model(&user).Exec(ctx, &user)
if err != nil {
return nil, err
}
// Create roles
_, err = UserUpdateRoles(ctx, user.ID.String(), roles)
_, err = UserUpdateRoles(cReg, ctx, user.ID.String(), roles)
if err != nil {
if len(user.ID.String()) > 0 {
UserDelete(ctx, user.ID.String())
UserDelete(cReg, ctx, user.ID.String())
}
return nil, err
}

@ -18,6 +18,7 @@ import (
"jochum.dev/jo-micro/auth2/internal/argon2"
"jochum.dev/jo-micro/auth2/internal/proto/authpb"
"jochum.dev/jo-micro/auth2/shared/sjwt"
"jochum.dev/jo-micro/components"
)
type InitConfig struct {
@ -32,6 +33,7 @@ type InitConfig struct {
}
type Handler struct {
cReg *components.Registry
audiences []string
refreshTokenExpiry int64
accessTokenExpiry int64
@ -45,7 +47,8 @@ func NewHandler() *Handler {
return &Handler{}
}
func (h *Handler) Init(c InitConfig) error {
func (h *Handler) Init(cReg *components.Registry, c InitConfig) error {
h.cReg = cReg
h.audiences = c.Audiences
h.accessTokenExpiry = c.AccessTokenExpiry
h.refreshTokenExpiry = c.RefreshTokenExpiry
@ -71,8 +74,8 @@ func (h *Handler) Stop() error {
return nil
}
func (s *Handler) List(ctx context.Context, in *authpb.ListRequest, out *authpb.UserListReply) error {
results, err := db.UserList(ctx, in.Limit, in.Offset)
func (h *Handler) List(ctx context.Context, in *authpb.ListRequest, out *authpb.UserListReply) error {
results, err := db.UserList(h.cReg, ctx, in.Limit, in.Offset)
if err != nil {
return err
}
@ -89,8 +92,8 @@ func (s *Handler) List(ctx context.Context, in *authpb.ListRequest, out *authpb.
return nil
}
func (s *Handler) Detail(ctx context.Context, in *authpb.UserIDRequest, out *authpb.User) error {
result, err := db.UserDetail(ctx, in.UserId)
func (h *Handler) Detail(ctx context.Context, in *authpb.UserIDRequest, out *authpb.User) error {
result, err := db.UserDetail(h.cReg, ctx, in.UserId)
if err != nil {
return err
}
@ -103,8 +106,8 @@ func (s *Handler) Detail(ctx context.Context, in *authpb.UserIDRequest, out *aut
return nil
}
func (s *Handler) Delete(ctx context.Context, in *authpb.UserIDRequest, out *emptypb.Empty) error {
err := db.UserDelete(ctx, in.UserId)
func (h *Handler) Delete(ctx context.Context, in *authpb.UserIDRequest, out *emptypb.Empty) error {
err := db.UserDelete(h.cReg, ctx, in.UserId)
if err != nil {
return err
}
@ -112,8 +115,8 @@ func (s *Handler) Delete(ctx context.Context, in *authpb.UserIDRequest, out *emp
return nil
}
func (s *Handler) UpdateRoles(ctx context.Context, in *authpb.UpdateRolesRequest, out *authpb.User) error {
result, err := db.UserUpdateRoles(ctx, in.UserId, in.Roles)
func (h *Handler) UpdateRoles(ctx context.Context, in *authpb.UpdateRolesRequest, out *authpb.User) error {
result, err := db.UserUpdateRoles(h.cReg, ctx, in.UserId, in.Roles)
if err != nil {
return err
}
@ -126,7 +129,7 @@ func (s *Handler) UpdateRoles(ctx context.Context, in *authpb.UpdateRolesRequest
return nil
}
func (s *Handler) Register(ctx context.Context, in *authpb.RegisterRequest, out *authpb.User) error {
func (h *Handler) Register(ctx context.Context, in *authpb.RegisterRequest, out *authpb.User) error {
if in.Username == auth2.ROLE_SERVICE {
return errors.New(config.Name, "User already exists", http.StatusConflict)
}
@ -136,7 +139,7 @@ func (s *Handler) Register(ctx context.Context, in *authpb.RegisterRequest, out
return err
}
result, err := db.UserCreate(ctx, in.Username, hash, in.Email, []string{auth2.ROLE_USER})
result, err := db.UserCreate(h.cReg, ctx, in.Username, hash, in.Email, []string{auth2.ROLE_USER})
if err != nil {
return errors.New(config.Name, "User already exists", http.StatusConflict)
}
@ -149,14 +152,14 @@ func (s *Handler) Register(ctx context.Context, in *authpb.RegisterRequest, out
return nil
}
func (s *Handler) genTokens(ctx context.Context, user *db.User, out *authpb.Token) error {
func (h *Handler) genTokens(ctx context.Context, user *db.User, out *authpb.Token) error {
// Create the Claims
refreshClaims := sjwt.JWTClaims{
RegisteredClaims: &jwt.RegisteredClaims{
Issuer: config.Name,
Subject: user.Username,
Audience: s.audiences,
ExpiresAt: jwt.NewNumericDate(time.Now().Add(time.Duration(s.accessTokenExpiry) * time.Second)),
Audience: h.audiences,
ExpiresAt: jwt.NewNumericDate(time.Now().Add(time.Duration(h.accessTokenExpiry) * time.Second)),
NotBefore: jwt.NewNumericDate(time.Now()),
IssuedAt: jwt.NewNumericDate(time.Now()),
ID: user.ID.String(),
@ -171,13 +174,13 @@ func (s *Handler) genTokens(ctx context.Context, user *db.User, out *authpb.Toke
refreshToken *jwt.Token
)
switch s.refreshTokenPrivKey.(type) {
switch h.refreshTokenPrivKey.(type) {
case *rsa.PrivateKey:
refreshToken = jwt.NewWithClaims(jwt.SigningMethodRS512, refreshClaims)
case ed25519.PrivateKey:
refreshToken = jwt.NewWithClaims(jwt.SigningMethodEdDSA, refreshClaims)
}
refreshSignedToken, err := refreshToken.SignedString(s.refreshTokenPrivKey)
refreshSignedToken, err := refreshToken.SignedString(h.refreshTokenPrivKey)
if err != nil {
return err
}
@ -187,8 +190,8 @@ func (s *Handler) genTokens(ctx context.Context, user *db.User, out *authpb.Toke
RegisteredClaims: &jwt.RegisteredClaims{
Issuer: config.Name,
Subject: user.Username,
Audience: s.audiences,
ExpiresAt: jwt.NewNumericDate(time.Now().Add(time.Duration(s.accessTokenExpiry) * time.Second)),
Audience: h.audiences,
ExpiresAt: jwt.NewNumericDate(time.Now().Add(time.Duration(h.accessTokenExpiry) * time.Second)),
NotBefore: jwt.NewNumericDate(time.Now()),
IssuedAt: jwt.NewNumericDate(time.Now()),
ID: user.ID.String(),
@ -199,13 +202,13 @@ func (s *Handler) genTokens(ctx context.Context, user *db.User, out *authpb.Toke
return err
}
switch s.accessTokenPrivKey.(type) {
switch h.accessTokenPrivKey.(type) {
case *rsa.PrivateKey:
accessToken = jwt.NewWithClaims(jwt.SigningMethodRS512, accessClaims)
case ed25519.PrivateKey:
accessToken = jwt.NewWithClaims(jwt.SigningMethodEdDSA, accessClaims)
}
accessSignedToken, err := accessToken.SignedString(s.accessTokenPrivKey)
accessSignedToken, err := accessToken.SignedString(h.accessTokenPrivKey)
if err != nil {
return err
}
@ -219,8 +222,8 @@ func (s *Handler) genTokens(ctx context.Context, user *db.User, out *authpb.Toke
return nil
}
func (s *Handler) Login(ctx context.Context, in *authpb.LoginRequest, out *authpb.Token) error {
user, err := db.UserFindByUsername(ctx, in.Username)
func (h *Handler) Login(ctx context.Context, in *authpb.LoginRequest, out *authpb.Token) error {
user, err := db.UserFindByUsername(h.cReg, ctx, in.Username)
if err != nil {
log.Error(err)
return errors.New(config.Name, "Wrong username or password", http.StatusUnauthorized)
@ -234,13 +237,13 @@ func (s *Handler) Login(ctx context.Context, in *authpb.LoginRequest, out *authp
return errors.New(config.Name, "Wrong username or password", http.StatusUnauthorized)
}
return s.genTokens(ctx, user, out)
return h.genTokens(ctx, user, out)
}
func (s *Handler) Refresh(ctx context.Context, in *authpb.RefreshTokenRequest, out *authpb.Token) error {
func (h *Handler) Refresh(ctx context.Context, in *authpb.RefreshTokenRequest, out *authpb.Token) error {
claims := sjwt.JWTClaims{}
_, err := jwt.ParseWithClaims(in.RefreshToken, &claims, func(token *jwt.Token) (interface{}, error) {
return s.refreshTokenPubKey, nil
return h.refreshTokenPubKey, nil
})
if err != nil {
return errors.New(config.Name, fmt.Sprintf("checking the RefreshToken: %s", err), http.StatusBadRequest)
@ -251,12 +254,12 @@ func (s *Handler) Refresh(ctx context.Context, in *authpb.RefreshTokenRequest, o
return fmt.Errorf("claims invalid: %s", err)
}
user, err := db.UserFindById(ctx, claims.ID)
user, err := db.UserFindById(h.cReg, ctx, claims.ID)
if err != nil {
return errors.New(config.Name, fmt.Sprintf("error fetching the user: %s", err), http.StatusUnauthorized)
}
return s.genTokens(ctx, user, out)
return h.genTokens(ctx, user, out)
}
func (s *Handler) Inspect(ctx context.Context, in *emptypb.Empty, out *authpb.JWTClaims) error {

@ -310,7 +310,7 @@ func main() {
return err
}
if err := authHandler.Init(handler.InitConfig{
if err := authHandler.Init(cReg, handler.InitConfig{
Audiences: c.StringSlice("auth2_jwt_audience"),
RefreshTokenExpiry: c.Int64("auth2_jwt_refresh_expiry"),
AccessTokenExpiry: c.Int64("auth2_jwt_access_expiry"),
@ -324,61 +324,6 @@ func main() {
}
authpb.RegisterAuthServiceHandler(service.Server(), authHandler)
// Register with https://jochum.dev/jo-micro/router
// r := router.New()
// c.String("auth2_sqld_router_basepath"),
// router.NewRoute(
// router.Method(router.MethodGet),
// router.Path("/"),
// router.Endpoint(authpb.AuthService.List),
// router.Params("limit", "offset"),
// router.AuthRequired(),
// router.RatelimitUser("1-S", "10-M"),
// ),
// router.NewRoute(
// router.Method(router.MethodPost),
// router.Path("/login"),
// router.Endpoint(authpb.AuthService.Login),
// router.RatelimitClientIP("1-S", "10-M", "30-H", "100-D"),
// ),
// router.NewRoute(
// router.Method(router.MethodPost),
// router.Path("/register"),
// router.Endpoint(authpb.AuthService.Register),
// router.RatelimitClientIP("1-M", "10-H", "50-D"),
// ),
// router.NewRoute(
// router.Method(router.MethodPost),
// router.Path("/refresh"),
// router.Endpoint(authpb.AuthService.Refresh),
// router.RatelimitClientIP("1-M", "10-H", "50-D"),
// ),
// router.NewRoute(
// router.Method(router.MethodDelete),
// router.Path("/:userId"),
// router.Endpoint(authpb.AuthService.Delete),
// router.Params("userId"),
// router.AuthRequired(),
// router.RatelimitUser("1-S", "10-M"),
// ),
// router.NewRoute(
// router.Method(router.MethodGet),
// router.Path("/:userId"),
// router.Endpoint(authpb.AuthService.Detail),
// router.Params("userId"),
// router.AuthRequired(),
// router.RatelimitUser("100-M"),
// ),
// router.NewRoute(
// router.Method(router.MethodPut),
// router.Path("/:userId/roles"),
// router.Endpoint(authpb.AuthService.UpdateRoles),
// router.Params("userId"),
// router.AuthRequired(),
// router.RatelimitUser("1-M"),
// ),
// )
// r.RegisterWithServer(service.Server())
return nil
}),
}

@ -21,10 +21,6 @@ func ClientAuthComponent() *AuthRegistry[ClientPlugin] {
return c
}
func ClientAuthMust(ctx context.Context) *AuthRegistry[ClientPlugin] {
return components.Must(ctx).Must(ClientAuthName).(*AuthRegistry[ClientPlugin])
}
func ClientAuthMustReg(cReg *components.Registry) *AuthRegistry[ClientPlugin] {
return cReg.Must(ClientAuthName).(*AuthRegistry[ClientPlugin])
}
@ -36,10 +32,6 @@ func RouterAuthComponent() *AuthRegistry[RouterPlugin] {
return c
}
func RouterAuthMust(ctx context.Context) *AuthRegistry[RouterPlugin] {
return components.Must(ctx).Must(RouterAuthName).(*AuthRegistry[RouterPlugin])
}
func RouterAuthMustReg(cReg *components.Registry) *AuthRegistry[RouterPlugin] {
return cReg.Must(RouterAuthName).(*AuthRegistry[RouterPlugin])
}

@ -22,10 +22,10 @@ require (
go-micro.dev/v4 v4.8.1
golang.org/x/crypto v0.0.0-20220924013350-4ba4fb4dd9e7
google.golang.org/protobuf v1.28.1
jochum.dev/jo-micro/buncomponent v0.0.2
jochum.dev/jo-micro/components v0.2.0
jochum.dev/jo-micro/logruscomponent v0.0.3
jochum.dev/jo-micro/router v0.4.1
jochum.dev/jo-micro/buncomponent v0.0.3
jochum.dev/jo-micro/components v0.3.0
jochum.dev/jo-micro/logruscomponent v0.0.4
jochum.dev/jo-micro/router v0.4.2
)
require (

@ -1933,16 +1933,22 @@ jochum.dev/jo-micro/buncomponent v0.0.1 h1:UHLODCgkv0x29jt46SPZ8h20WCT2B8ZNG9wW1
jochum.dev/jo-micro/buncomponent v0.0.1/go.mod h1:nQLcdOa3KMOZpm6SLmZK0ef18fX3V9L0BdABdedHiD4=
jochum.dev/jo-micro/buncomponent v0.0.2 h1:+U9KmMYDUAArBVxw9bgyAfs26TuyhbnCJUdm2rymddA=
jochum.dev/jo-micro/buncomponent v0.0.2/go.mod h1:hZpOmq78AKf0nViehhY4k9Y0tvAjQxoks9sQQeTDwu4=
jochum.dev/jo-micro/buncomponent v0.0.3 h1:+cJzIe5nYUG90FptTQr2u1/iw7wPjtw20iiActyYQJM=
jochum.dev/jo-micro/buncomponent v0.0.3/go.mod h1:tw26M9+UixdDamDWsRGTUpXmp/cF7XPjlfQWyggoKAo=
jochum.dev/jo-micro/components v0.0.11 h1:Rtm0J+MiMcyFVrweJ3r1eoxQY5qP59GzC1TPc7O9Ixs=
jochum.dev/jo-micro/components v0.0.11/go.mod h1:XzhOsv4pAOoRdnrgvYlZXwPzzBd9/8h2CzehB/Yf92w=
jochum.dev/jo-micro/components v0.1.0 h1:9QP79NK+lShksiswtqtxsW8kfd0aBtF87HuBZsu8yxE=
jochum.dev/jo-micro/components v0.1.0/go.mod h1:Yvn0Qz1zctUQUI6WIjq7PbfLY87Qvywpw+KxnVZeCvA=
jochum.dev/jo-micro/components v0.2.0 h1:aeV1nOUqpDzZafpKrBd86GdhCJAMYvC2pGeiXl751Ls=
jochum.dev/jo-micro/components v0.2.0/go.mod h1:Yvn0Qz1zctUQUI6WIjq7PbfLY87Qvywpw+KxnVZeCvA=
jochum.dev/jo-micro/components v0.3.0 h1:mo9IzK6UVbQuIit+vp74RFeT/VtS5mVv0ggBZ9q0tiE=
jochum.dev/jo-micro/components v0.3.0/go.mod h1:Yvn0Qz1zctUQUI6WIjq7PbfLY87Qvywpw+KxnVZeCvA=
jochum.dev/jo-micro/logruscomponent v0.0.2 h1:IPyQXOdC0t6Howf4ndykRzVYovrxP5OHM3ZbalRqjYk=
jochum.dev/jo-micro/logruscomponent v0.0.2/go.mod h1:WtSAK/M/zSKuawJhh+Ub+9pknbOKyUScK+qhEbCvFAU=
jochum.dev/jo-micro/logruscomponent v0.0.3 h1:mjgzKKFDQ4uX1slSwajXq7IhrMBuHpkPhcozKWZwPGw=
jochum.dev/jo-micro/logruscomponent v0.0.3/go.mod h1:SPdHhgI+L1xUouhtfuXS28bQn7ojF1YGsgEvhdh4deU=
jochum.dev/jo-micro/logruscomponent v0.0.4 h1:KkJhLIM0mm2tlk+z+gZdpb5vCeuBs6bhG3bncGhCqoQ=
jochum.dev/jo-micro/logruscomponent v0.0.4/go.mod h1:NVy+eN3Xm2SlzdsQGuC/9/+MwU+8BwxFZuaTprmLguU=
jochum.dev/jo-micro/router v0.3.6 h1:MgT8k7/Hrxpk+nfit3wg+X7oduo4DsM/uG6XT7Ca2ys=
jochum.dev/jo-micro/router v0.3.6/go.mod h1:5zHbSgMEUKmF8lodzyg4XXXRxFi8QtOM9Ci55dRXs2I=
jochum.dev/jo-micro/router v0.3.7 h1:4AE6PEp9gRMgGUAFkvJWDuT2Tk0cf/kbg12xBPC94OE=
@ -1953,6 +1959,8 @@ jochum.dev/jo-micro/router v0.4.0 h1:2IA/SzrhXGMv4I3Z0i7//U2bfgOE1cwv+r/Ey4FUSgw
jochum.dev/jo-micro/router v0.4.0/go.mod h1:yPfhNJQ3D1TJ4+IEluT5W5D0ax8mFRZnJ3mcWnyaGvw=
jochum.dev/jo-micro/router v0.4.1 h1:MZC7La+w7isg7JjhgHsjq3htR28p+t0gOZzNyDNFK0k=
jochum.dev/jo-micro/router v0.4.1/go.mod h1:2Izy7ib2LgTpg//YwzlsW7YcaJ5aXoxuLm1Pg3E0Z4c=
jochum.dev/jo-micro/router v0.4.2 h1:/nLP8rq0gM4YzL9x+o9IBofJoz0sOVLgTbwMS0ouINk=
jochum.dev/jo-micro/router v0.4.2/go.mod h1:kIxSXrTrRJ5ahMTF0on9CYCQzeEjrlK4NwHDWIywjSc=
k8s.io/api v0.20.1/go.mod h1:KqwcCVogGxQY3nBlRpwt+wpAMF/KjaCc7RpywacvqUo=
k8s.io/api v0.20.4/go.mod h1:++lNL1AJMkDymriNniQsWRkMDzRaX2Y/POTUi8yvqYQ=
k8s.io/api v0.20.6/go.mod h1:X9e8Qag6JV/bL5G6bU8sdVRltWKmdHsFUGS3eVndqE8=

Loading…
Cancel
Save