112 lines
3.2 KiB
Go
112 lines
3.2 KiB
Go
//
|
|
// Copyright (c) 2012-2019 Red Hat, Inc.
|
|
// This program and the accompanying materials are made
|
|
// available under the terms of the Eclipse Public License 2.0
|
|
// which is available at https://www.eclipse.org/legal/epl-2.0/
|
|
//
|
|
// SPDX-License-Identifier: EPL-2.0
|
|
//
|
|
// Contributors:
|
|
// Red Hat, Inc. - initial API and implementation
|
|
//
|
|
package che
|
|
|
|
import (
|
|
"bytes"
|
|
"fmt"
|
|
orgv1 "github.com/eclipse/che-operator/pkg/apis/org/v1"
|
|
"github.com/eclipse/che-operator/pkg/deploy"
|
|
"github.com/sirupsen/logrus"
|
|
"io"
|
|
corev1 "k8s.io/api/core/v1"
|
|
"k8s.io/apimachinery/pkg/api/errors"
|
|
"k8s.io/client-go/kubernetes/scheme"
|
|
"k8s.io/client-go/tools/remotecommand"
|
|
"sigs.k8s.io/controller-runtime/pkg/client/config"
|
|
"sigs.k8s.io/controller-runtime/pkg/reconcile"
|
|
)
|
|
|
|
func ExecIntoPod(podName string, provisionCommand string, reason string, ns string) (provisioned bool) {
|
|
|
|
command := []string{"/bin/bash", "-c", provisionCommand}
|
|
logrus.Infof("Running exec to %s in pod %s", reason, podName)
|
|
// print std if operator is run in debug mode (TODO)
|
|
_, stderr, err := k8sclient.RunExec(command, podName, ns)
|
|
if err != nil {
|
|
logrus.Errorf("Error exec'ing into pod: %v: , command: %s", err, command)
|
|
logrus.Errorf(stderr)
|
|
return false
|
|
}
|
|
logrus.Info("Exec successfully completed")
|
|
return true
|
|
}
|
|
|
|
func (cl *k8s) RunExec(command []string, podName, namespace string) (string, string, error) {
|
|
|
|
req := cl.clientset.CoreV1().RESTClient().Post().
|
|
Resource("pods").
|
|
Name(podName).
|
|
Namespace(namespace).
|
|
SubResource("exec")
|
|
|
|
req.VersionedParams(&corev1.PodExecOptions{
|
|
Command: command,
|
|
Stdin: false,
|
|
Stdout: true,
|
|
Stderr: true,
|
|
TTY: false,
|
|
}, scheme.ParameterCodec)
|
|
|
|
cfg, _ := config.GetConfig()
|
|
exec, err := remotecommand.NewSPDYExecutor(cfg, "POST", req.URL())
|
|
if err != nil {
|
|
return "", "", fmt.Errorf("error while creating executor: %v", err)
|
|
}
|
|
|
|
var stdout, stderr bytes.Buffer
|
|
var stdin io.Reader
|
|
err = exec.Stream(remotecommand.StreamOptions{
|
|
Stdin: stdin,
|
|
Stdout: &stdout,
|
|
Stderr: &stderr,
|
|
Tty: false,
|
|
})
|
|
if err != nil {
|
|
return stdout.String(), stderr.String(), err
|
|
}
|
|
|
|
return stdout.String(), stderr.String(), nil
|
|
}
|
|
|
|
func (r *ReconcileChe) CreateKyecloakResources(instance *orgv1.CheCluster, request reconcile.Request, deploymentName string) (err error) {
|
|
cheHost := instance.Spec.Server.CheHost
|
|
keycloakProvisionCommand := deploy.GetKeycloakProvisionCommand(instance, cheHost)
|
|
podToExec, err := k8sclient.GetDeploymentPod(deploymentName, instance.Namespace)
|
|
if err != nil {
|
|
logrus.Errorf("Failed to retrieve pod name. Further exec will fail")
|
|
}
|
|
provisioned := ExecIntoPod(podToExec, keycloakProvisionCommand, "create realm, client and user", instance.Namespace)
|
|
if provisioned {
|
|
instance, err := r.GetCR(request)
|
|
if err != nil {
|
|
if errors.IsNotFound(err) {
|
|
logrus.Errorf("CR %s not found: %s", instance.Name, err)
|
|
return err
|
|
}
|
|
logrus.Errorf("Error when getting %s CR: %s", instance.Name, err)
|
|
return err
|
|
}
|
|
for {
|
|
instance.Status.KeycloakProvisoned = true
|
|
if err := r.UpdateCheCRStatus(instance, "status: provisioned with Keycloak", "true"); err != nil {
|
|
instance, _ = r.GetCR(request)
|
|
} else {
|
|
break
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
return err
|
|
}
|