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
2 changes: 1 addition & 1 deletion cmd/mapt/cmd/aws/services/snc.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import (
maptContext "github.com/redhat-developer/mapt/pkg/manager/context"
openshiftsnc "github.com/redhat-developer/mapt/pkg/provider/aws/action/snc"
sncApi "github.com/redhat-developer/mapt/pkg/target/service/snc"
"github.com/redhat-developer/mapt/pkg/target/service/snc/profile"
"github.com/redhat-developer/mapt/pkg/provider/openshift/profile"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
"github.com/spf13/viper"
Expand Down
33 changes: 33 additions & 0 deletions cmd/mapt/cmd/openshift/openshift.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package openshift

import (
params "github.com/redhat-developer/mapt/cmd/mapt/cmd/params"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
"github.com/spf13/viper"
)

const (
cmd = "openshift"
cmdDesc = "operations on existing OpenShift clusters"
)

func GetCmd() *cobra.Command {
c := &cobra.Command{
Use: cmd,
Short: cmdDesc,
RunE: func(cmd *cobra.Command, args []string) error {
if err := viper.BindPFlags(cmd.Flags()); err != nil {
return err
}
return nil
},
}

flagSet := pflag.NewFlagSet(cmd, pflag.ExitOnError)
params.AddCommonFlags(flagSet)
c.PersistentFlags().AddFlagSet(flagSet)

c.AddCommand(getRHOAICmd())
return c
}
104 changes: 104 additions & 0 deletions cmd/mapt/cmd/openshift/rhoai.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
package openshift

import (
params "github.com/redhat-developer/mapt/cmd/mapt/cmd/params"
maptContext "github.com/redhat-developer/mapt/pkg/manager/context"
rhoaiAction "github.com/redhat-developer/mapt/pkg/provider/openshift/action/rhoai"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
"github.com/spf13/viper"
)

const (
cmdRHOAI = "rhoai"
cmdRHOAIDesc = "deploy Red Hat OpenShift AI on an existing OpenShift cluster"

kubeconfig = "kubeconfig"
kubeconfigDesc = "path to the kubeconfig file for the target OpenShift cluster"

rhoaiProfile = "profile"
rhoaiProfileDesc = "profiles to deploy (ai, virtualization, serverless-serving, serverless-eventing, serverless, servicemesh, nvidia)"
)

func getRHOAICmd() *cobra.Command {
c := &cobra.Command{
Use: cmdRHOAI,
Short: cmdRHOAIDesc,
RunE: func(cmd *cobra.Command, args []string) error {
if err := viper.BindPFlags(cmd.Flags()); err != nil {
return err
}
return nil
},
}
c.AddCommand(createRHOAI(), destroyRHOAI())
return c
}

func createRHOAI() *cobra.Command {
c := &cobra.Command{
Use: params.CreateCmdName,
Short: params.CreateCmdName,
RunE: func(cmd *cobra.Command, args []string) error {
if err := viper.BindPFlags(cmd.Flags()); err != nil {
return err
}
if err := viper.BindPFlags(cmd.InheritedFlags()); err != nil {
return err
}
profiles := viper.GetStringSlice(rhoaiProfile)
if len(profiles) == 0 {
profiles = []string{"ai"}
}
return rhoaiAction.Create(
&maptContext.ContextArgs{
Context: cmd.Context(),
ProjectName: viper.GetString(params.ProjectName),
BackedURL: viper.GetString(params.BackedURL),
Debug: viper.IsSet(params.Debug),
DebugLevel: viper.GetUint(params.DebugLevel),
Tags: viper.GetStringMapString(params.Tags),
},
&rhoaiAction.RHOAIArgs{
KubeconfigPath: viper.GetString(kubeconfig),
Profiles: profiles,
})
},
}
flagSet := pflag.NewFlagSet(params.CreateCmdName, pflag.ExitOnError)
flagSet.StringP(kubeconfig, "", "", kubeconfigDesc)
flagSet.StringSliceP(rhoaiProfile, "", []string{}, rhoaiProfileDesc)
flagSet.StringToStringP(params.Tags, "", nil, params.TagsDesc)
c.PersistentFlags().AddFlagSet(flagSet)
_ = c.MarkFlagRequired(kubeconfig)
return c
}

func destroyRHOAI() *cobra.Command {
c := &cobra.Command{
Use: params.DestroyCmdName,
Short: params.DestroyCmdName,
RunE: func(cmd *cobra.Command, args []string) error {
if err := viper.BindPFlags(cmd.Flags()); err != nil {
return err
}
if err := viper.BindPFlags(cmd.InheritedFlags()); err != nil {
return err
}
return rhoaiAction.Destroy(&maptContext.ContextArgs{
Context: cmd.Context(),
ProjectName: viper.GetString(params.ProjectName),
BackedURL: viper.GetString(params.BackedURL),
Debug: viper.IsSet(params.Debug),
DebugLevel: viper.GetUint(params.DebugLevel),
ForceDestroy: viper.IsSet(params.ForceDestroy),
KeepState: viper.IsSet(params.KeepState),
})
},
}
flagSet := pflag.NewFlagSet(params.DestroyCmdName, pflag.ExitOnError)
flagSet.Bool(params.ForceDestroy, false, params.ForceDestroyDesc)
flagSet.Bool(params.KeepState, false, params.KeepStateDesc)
c.PersistentFlags().AddFlagSet(flagSet)
return c
}
4 changes: 3 additions & 1 deletion cmd/mapt/cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"github.com/redhat-developer/mapt/cmd/mapt/cmd/aws"
"github.com/redhat-developer/mapt/cmd/mapt/cmd/azure"
"github.com/redhat-developer/mapt/cmd/mapt/cmd/ibmcloud"
"github.com/redhat-developer/mapt/cmd/mapt/cmd/openshift"
"github.com/redhat-developer/mapt/cmd/mapt/cmd/params"
"github.com/redhat-developer/mapt/pkg/util/logging"
"github.com/spf13/cobra"
Expand Down Expand Up @@ -63,7 +64,8 @@ func init() {
rootCmd.AddCommand(
aws.GetCmd(),
azure.GetCmd(),
ibmcloud.GetCmd())
ibmcloud.GetCmd(),
openshift.GetCmd())
}

func Execute() {
Expand Down
2 changes: 1 addition & 1 deletion pkg/provider/aws/action/snc/snc.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import (
"github.com/redhat-developer/mapt/pkg/provider/util/command"
"github.com/redhat-developer/mapt/pkg/provider/util/security"
apiSNC "github.com/redhat-developer/mapt/pkg/target/service/snc"
"github.com/redhat-developer/mapt/pkg/target/service/snc/profile"
"github.com/redhat-developer/mapt/pkg/provider/openshift/profile"
"github.com/redhat-developer/mapt/pkg/util"
"github.com/redhat-developer/mapt/pkg/util/logging"
resourcesUtil "github.com/redhat-developer/mapt/pkg/util/resources"
Expand Down
95 changes: 95 additions & 0 deletions pkg/provider/openshift/action/rhoai/rhoai.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
package rhoai

import (
"fmt"
"os"

"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
"github.com/redhat-developer/mapt/pkg/manager"
mc "github.com/redhat-developer/mapt/pkg/manager/context"
"github.com/redhat-developer/mapt/pkg/provider/openshift"
"github.com/redhat-developer/mapt/pkg/provider/openshift/profile"
"github.com/redhat-developer/mapt/pkg/util/logging"
)

const (
StackName = "stackOpenshiftRHOAI"
defaultPrefix = "rhoai"
)

type RHOAIArgs struct {
KubeconfigPath string
Profiles []string
Prefix string
}

type rhoaiRequest struct {
mCtx *mc.Context
prefix string
kubeconfigPath string
profiles []string
}

func Create(mCtxArgs *mc.ContextArgs, args *RHOAIArgs) error {
mCtx, err := mc.Init(mCtxArgs, openshift.Provider())
if err != nil {
return err
}
if err := profile.Validate(args.Profiles); err != nil {
return err
}
prefix := args.Prefix
if prefix == "" {
prefix = defaultPrefix
}
r := &rhoaiRequest{
mCtx: mCtx,
prefix: prefix,
kubeconfigPath: args.KubeconfigPath,
profiles: args.Profiles,
}
return r.deploy()
}

func Destroy(mCtxArgs *mc.ContextArgs) error {
logging.Debug("Run openshift rhoai destroy")
mCtx, err := mc.Init(mCtxArgs, openshift.Provider())
if err != nil {
return err
}
return openshift.DestroyStack(mCtx, StackName)
}

func (r *rhoaiRequest) deploy() error {
cs := manager.Stack{
StackName: r.mCtx.StackNameByProject(StackName),
ProjectName: r.mCtx.ProjectName(),
BackedURL: r.mCtx.BackedURL(),
ProviderCredentials: openshift.NoCredentials,
DeployFunc: r.pulumiProgram,
}
_, err := manager.UpStack(r.mCtx, cs)
if err != nil {
return fmt.Errorf("stack creation failed: %w", err)
}
return nil
}

func (r *rhoaiRequest) pulumiProgram(ctx *pulumi.Context) error {
kcBytes, err := os.ReadFile(r.kubeconfigPath)
if err != nil {
return fmt.Errorf("reading kubeconfig from %s: %w", r.kubeconfigPath, err)
}
kubeconfig := pulumi.String(string(kcBytes)).ToStringOutput()

k8sProvider, err := profile.NewK8sProvider(ctx, "k8s-provider", kubeconfig)
if err != nil {
return err
}

return profile.Deploy(ctx, r.profiles, &profile.DeployArgs{
K8sProvider: k8sProvider,
Kubeconfig: kubeconfig,
Prefix: r.prefix,
})
}
36 changes: 36 additions & 0 deletions pkg/provider/openshift/openshift.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package openshift

import (
"context"

"github.com/redhat-developer/mapt/pkg/manager"
mc "github.com/redhat-developer/mapt/pkg/manager/context"
"github.com/redhat-developer/mapt/pkg/manager/credentials"
)

type OpenShift struct{}

func (o *OpenShift) Init(_ context.Context, _ string) (string, error) {
return "", nil
}

func (o *OpenShift) DefaultHostingPlace() (*string, error) {
return nil, nil
}

func Provider() *OpenShift {
return &OpenShift{}
}

var NoCredentials = credentials.ProviderCredentials{}

func DestroyStack(mCtx *mc.Context, stackName string) error {
return manager.DestroyStack(
mCtx,
manager.Stack{
StackName: mCtx.StackNameByProject(stackName),
ProjectName: mCtx.ProjectName(),
BackedURL: mCtx.BackedURL(),
ProviderCredentials: NoCredentials,
})
}
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ type DeployArgs struct {
func Validate(profiles []string) error {
for _, p := range profiles {
if _, ok := profileRegistry[p]; !ok {
return fmt.Errorf("profile %q is not supported for SNC. Supported profiles: %v",
return fmt.Errorf("profile %q is not supported. Supported profiles: %v",
p, slices.Sorted(maps.Keys(profileRegistry)))
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"time"

"github.com/pulumi/pulumi-kubernetes/sdk/v4/go/kubernetes/apiextensions"
networkingv1 "github.com/pulumi/pulumi-kubernetes/sdk/v4/go/kubernetes/networking/v1"
metav1 "github.com/pulumi/pulumi-kubernetes/sdk/v4/go/kubernetes/meta/v1"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
"k8s.io/apimachinery/pkg/runtime/schema"
Expand Down Expand Up @@ -100,6 +101,36 @@ func deployKnativeCR(ctx *pulumi.Context, args *DeployArgs, operatorReady pulumi
return nil, pulumi.StringOutput{}, err
}

// When ServiceMesh enrolls this namespace, it creates a deny-all
// NetworkPolicy that blocks API server → webhook traffic on multi-node
// clusters. Allow ingress to webhook pods so admission webhooks work.
if _, err := networkingv1.NewNetworkPolicy(ctx, rn(cr.suffix+"-webhook-np"),
&networkingv1.NetworkPolicyArgs{
Metadata: &metav1.ObjectMetaArgs{
Name: pulumi.Sprintf("allow-webhook-%s", cr.suffix),
Namespace: pulumi.String(cr.namespace),
},
Spec: &networkingv1.NetworkPolicySpecArgs{
PodSelector: &metav1.LabelSelectorArgs{
MatchLabels: pulumi.StringMap{"app": pulumi.String("webhook")},
},
Ingress: networkingv1.NetworkPolicyIngressRuleArray{
&networkingv1.NetworkPolicyIngressRuleArgs{
Ports: networkingv1.NetworkPolicyPortArray{
&networkingv1.NetworkPolicyPortArgs{
Port: pulumi.Int(8443),
Protocol: pulumi.String("TCP"),
},
},
},
},
PolicyTypes: pulumi.StringArray{pulumi.String("Ingress")},
},
},
args.k8sOpts(pulumi.DependsOn([]pulumi.Resource{ns}))...); err != nil {
return nil, pulumi.StringOutput{}, err
}

// Create the Knative CR
res, err := apiextensions.NewCustomResource(ctx, rn(cr.suffix),
&apiextensions.CustomResourceArgs{
Expand Down