Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions clients/rancher/auth/auth.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package auth

import (
"github.com/rancher/shepherd/clients/rancher/auth/openldap"
management "github.com/rancher/shepherd/clients/rancher/generated/management/v3"
"github.com/rancher/shepherd/pkg/session"
)

type Client struct {
OLDAP *openldap.OLDAPClient
}

// NewAuth constructs the Auth Provider Struct
func NewClient(mgmt *management.Client, session *session.Session) (*Client, error) {
oLDAP, err := openldap.NewOLDAP(mgmt, session)
if err != nil {
return nil, err
}

return &Client{
OLDAP: oLDAP,
}, nil
}
13 changes: 13 additions & 0 deletions clients/rancher/auth/authprovider.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package auth

type Provider string

const (
LocalAuth Provider = "local"
OpenLDAPAuth Provider = "openLdap"
)

// String stringer for the AuthProvider
func (a Provider) String() string {
return string(a)
}
34 changes: 34 additions & 0 deletions clients/rancher/auth/openldap/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package openldap

const (
ConfigurationFileKey = "openLDAP"
)

type Config struct {
Hostname string `json:"hostname" yaml:"hostname"`
IP string `json:"IP" yaml:"IP"`
ServiceAccount *ServiceAccount `json:"serviceAccount" yaml:"serviceAccount"`
Group *Group `json:"group" yaml:"group"`
Users *Users `json:"users" yaml:"users"`
AccessMode string `json:"accessMode" yaml:"accessMode" default:"unrestricted"`
}

type ServiceAccount struct {
DistinguishedName string `json:"distinguishedName" yaml:"distinguishedName"`
Password string `json:"password" yaml:"password"`
}

type Group struct {
ObjectClass string `json:"objectClass" yaml:"objectClass"`
MemberMappingAttribute string `json:"memberMappingAttribute" yaml:"memberMappingAttribute"`
}

type Users struct {
Admin *User `json:"admin" yaml:"admin"`
SearchBase string `json:"searchBase" yaml:"searchBase"`
}

type User struct {
Password string `json:"password,omitempty" yaml:"password,omitempty"`
Username string `json:"username,omitempty" yaml:"username,omitempty"`
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,44 +3,46 @@ package openldap
import (
"fmt"

management "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3"
"github.com/rancher/shepherd/clients/rancher"
apisv3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3"

management "github.com/rancher/shepherd/clients/rancher/generated/management/v3"
"github.com/rancher/shepherd/pkg/config"
"github.com/rancher/shepherd/pkg/session"
)

type OLDAPOperations interface {
Enable() error
Disable() error
Update(existing, updates *management.AuthConfig) (*management.AuthConfig, error)
}

const (
resourceType = "openldap"
schemaType = "openLdapConfigs"
)

type OLDAP struct {
Config *Config

type OLDAPClient struct {
client *management.Client
session *session.Session
client *rancher.Client

Config *Config
}

// NewOLDAP constructs OLDAP struct after it reads Open LDAP from the configuration file
func NewOLDAP(client *rancher.Client, ts *session.Session) (*OLDAP, error) {
func NewOLDAP(client *management.Client, session *session.Session) (*OLDAPClient, error) {
ldapConfig := new(Config)
config.LoadConfig(ConfigurationFileKey, ldapConfig)

return &OLDAP{
Config: ldapConfig,
session: ts,
return &OLDAPClient{
client: client,
session: session,
Config: ldapConfig,
}, nil
}

// Enable is a method of OLDAP, makes a request to the action with the given
// configuration values
func (o *OLDAP) Enable() error {
func (o *OLDAPClient) Enable() error {
var jsonResp map[string]interface{}

url := o.newActionURL("testAndApply")
Expand All @@ -49,7 +51,7 @@ func (o *OLDAP) Enable() error {
return err
}

err = o.client.Management.Ops.DoModify("POST", url, enableActionInput, &jsonResp)
err = o.client.Ops.DoModify("POST", url, enableActionInput, &jsonResp)
if err != nil {
return err
}
Expand All @@ -61,28 +63,35 @@ func (o *OLDAP) Enable() error {
return nil
}

// Update is a method of OLDAP, makes an update with the given configuration values
func (o *OLDAPClient) Update(
existing, updates *management.AuthConfig,
) (*management.AuthConfig, error) {
return o.client.AuthConfig.Update(existing, updates)
}

// Disable is a method of OLDAP, makes a request to disable Open LDAP
func (o *OLDAP) Disable() error {
func (o *OLDAPClient) Disable() error {
var jsonResp map[string]any

url := o.newActionURL("disable")
disableActionInput := o.newDisableInput()

return o.client.Management.Ops.DoModify("POST", url, &disableActionInput, &jsonResp)
return o.client.Ops.DoModify("POST", url, &disableActionInput, &jsonResp)
}

func (o *OLDAP) newActionURL(action string) string {
protocol := "https"

if *o.client.RancherConfig.Insecure {
protocol = "http"
}

return fmt.Sprintf("%v://%v/v3/%v/%v?action=%v", protocol, o.client.RancherConfig.Host, schemaType, resourceType, action)
func (o *OLDAPClient) newActionURL(action string) string {
return fmt.Sprintf(
"%v/%v/%v?action=%v",
o.client.Opts.URL,
schemaType,
resourceType,
action,
)
}

func (o *OLDAP) newEnableInputFromConfig() (*management.LdapTestAndApplyInput, error) {
var resource management.LdapTestAndApplyInput
func (o *OLDAPClient) newEnableInputFromConfig() (*apisv3.LdapTestAndApplyInput, error) {
var resource apisv3.LdapTestAndApplyInput

var server string
if o.Config.Hostname == "" && o.Config.IP == "" {
Expand Down Expand Up @@ -116,6 +125,6 @@ func (o *OLDAP) newEnableInputFromConfig() (*management.LdapTestAndApplyInput, e
return &resource, nil
}

func (o *OLDAP) newDisableInput() []byte {
func (o *OLDAPClient) newDisableInput() []byte {
return []byte(`{"action": "disable"}`)
}
43 changes: 32 additions & 11 deletions clients/rancher/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,26 +11,27 @@ import (

"github.com/pkg/errors"
"github.com/rancher/norman/httperror"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/watch"
"k8s.io/client-go/dynamic"
"k8s.io/client-go/rest"
"k8s.io/client-go/tools/clientcmd"

frameworkDynamic "github.com/rancher/shepherd/clients/dynamic"
"github.com/rancher/shepherd/clients/ec2"
kubeProvisioning "github.com/rancher/shepherd/clients/provisioning"
"github.com/rancher/shepherd/clients/rancher/auth"
"github.com/rancher/shepherd/clients/rancher/catalog"
management "github.com/rancher/shepherd/clients/rancher/generated/management/v3"
v1 "github.com/rancher/shepherd/clients/rancher/v1"

kubeProvisioning "github.com/rancher/shepherd/clients/provisioning"
"github.com/rancher/shepherd/clients/ranchercli"
kubeRKE "github.com/rancher/shepherd/clients/rke"
"github.com/rancher/shepherd/pkg/clientbase"
"github.com/rancher/shepherd/pkg/config"
"github.com/rancher/shepherd/pkg/environmentflag"
"github.com/rancher/shepherd/pkg/session"
"github.com/rancher/shepherd/pkg/wrangler"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/watch"
"k8s.io/client-go/dynamic"
"k8s.io/client-go/rest"
"k8s.io/client-go/tools/clientcmd"
)

// Client is the main rancher Client object that gives an end user access to the Provisioning and Management
Expand All @@ -49,6 +50,7 @@ type Client struct {
// CLI is the client used to interact with the Rancher CLI
CLI *ranchercli.Client
// Session is the session object used by the client to track all the resources being created by the client.
Auth *auth.Client // Session is the session object used by the client to track all the resources being created by the client.
Session *session.Session
// Flags is the environment flags used by the client to test selectively against a rancher instance.
Flags *environmentflag.EnvironmentFlags
Expand Down Expand Up @@ -137,6 +139,13 @@ func newClient(c *Client, bearerToken string, config *Config, session *session.S

c.WranglerContext = wranglerContext

auth, err := auth.NewClient(c.Management, session)
if err != nil {
return nil, err
}

c.Auth = auth

splitBearerKey := strings.Split(bearerToken, ":")
token, err := c.Management.Token.ByID(splitBearerKey[0])
if err != nil {
Expand Down Expand Up @@ -220,7 +229,18 @@ func (c *Client) doAction(endpoint, action string, body []byte, output interface
// AsUser accepts a user object, and then creates a token for said `user`. Then it instantiates and returns a Client using the token created.
// This function uses the login action, and user must have a correct username and password combination.
func (c *Client) AsUser(user *management.User) (*Client, error) {
returnedToken, err := c.login(user)
returnedToken, err := c.login(user, auth.LocalAuth)
if err != nil {
return nil, err
}

return NewClient(returnedToken.Token, c.Session)
}

// AsAuthUser accepts a user object, and then creates a token for said `user`. Then it instantiates and returns a Client using the token created.
// This function uses the login action, and user must have a correct username and password combination.
func (c *Client) AsAuthUser(user *management.User, authProvider auth.Provider) (*Client, error) {
returnedToken, err := c.login(user, authProvider)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -346,7 +366,7 @@ func (c *Client) GetManagementWatchInterface(schemaType string, opts metav1.List
}

// login uses the local authentication provider to authenticate a user and return the subsequent token.
func (c *Client) login(user *management.User) (*management.Token, error) {
func (c *Client) login(user *management.User, provider auth.Provider) (*management.Token, error) {
token := &management.Token{}
bodyContent, err := json.Marshal(struct {
Username string `json:"username"`
Expand All @@ -358,7 +378,8 @@ func (c *Client) login(user *management.User) (*management.Token, error) {
if err != nil {
return nil, err
}
err = c.doAction("/v3-public/localProviders/local", "login", bodyContent, token)
endpoint := fmt.Sprintf("/v3-public/%vProviders/%v", provider.String(), strings.ToLower(provider.String()))
err = c.doAction(endpoint, "login", bodyContent, token)
if err != nil {
return nil, err
}
Expand Down
23 changes: 0 additions & 23 deletions extensions/auth/auth.go

This file was deleted.

35 changes: 0 additions & 35 deletions extensions/auth/openldap/config.go

This file was deleted.

24 changes: 18 additions & 6 deletions extensions/users/users.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,22 @@ func UserConfig() (user *management.User) {
return
}

// RefreshGroupMembership is helper function that sends a POST request to user action refresh auth provider access
func RefreshGroupMembership(client *rancher.Client) error {
endpoint := fmt.Sprintf("https://%v/v3/%v?action=%v", client.RancherConfig.Host, "users", "refreshauthprovideraccess")

var jsonResp map[string]any

bodyContent := []byte(`{}`)

err := client.Management.Ops.DoModify("POST", endpoint, &bodyContent, &jsonResp)
if err != nil {
return err
}

return nil
}

// CreateUserWithRole is helper function that creates a user with a role or multiple roles
func CreateUserWithRole(rancherClient *rancher.Client, user *management.User, roles ...string) (*management.User, error) {
createdUser, err := rancherClient.Management.User.Create(user)
Expand Down Expand Up @@ -76,9 +92,7 @@ func CreateUserWithRole(rancherClient *rancher.Client, user *management.User, ro
// AddProjectMember is a helper function that adds a project role to `user`. It uses the watch.WatchWait to ensure BackingNamespaceCreated is true.
// If a list of ResourceAttributes is given, then the function blocks until all
// attributes are allowed by SelfSubjectAccessReviews OR the function times out.
func AddProjectMember(rancherClient *rancher.Client, project *management.Project,
user *management.User, projectRole string, attrs []*authzv1.ResourceAttributes,
) error {
func AddProjectMember(rancherClient *rancher.Client, project *management.Project, user *management.User, projectRole string, attrs []*authzv1.ResourceAttributes) error {
role := &management.ProjectRoleTemplateBinding{
ProjectID: project.ID,
UserPrincipalID: user.PrincipalIDs[0],
Expand Down Expand Up @@ -189,9 +203,7 @@ func RemoveProjectMember(rancherClient *rancher.Client, user *management.User) e
// AddClusterRoleToUser is a helper function that adds a cluster role to `user`.
// If a list of ResourceAttributes is given, then the function blocks until all
// attributes are allowed by SelfSubjectAccessReviews OR the function times out.
func AddClusterRoleToUser(rancherClient *rancher.Client, cluster *management.Cluster,
user *management.User, clusterRole string, attrs []*authzv1.ResourceAttributes,
) error {
func AddClusterRoleToUser(rancherClient *rancher.Client, cluster *management.Cluster, user *management.User, clusterRole string, attrs []*authzv1.ResourceAttributes) error {
role := &management.ClusterRoleTemplateBinding{
ClusterID: cluster.Resource.ID,
UserPrincipalID: user.PrincipalIDs[0],
Expand Down
Loading