func downloadKubernetes(d downloadProperties) (err error) { os := runtime.GOOS arch := runtime.GOARCH if runtime.GOOS == "windows" { d.kubeBinary += ".exe" } _, err = exec.LookPath(d.kubeBinary) if err != nil { latestVersion, err := getLatestVersionFromGitHub(d.kubeDistroOrg, d.kubeDistroRepo) if err != nil { util.Errorf("Unable to get latest version for %s/%s %v", d.kubeDistroOrg, d.kubeDistroRepo, err) return err } kubeURL := fmt.Sprintf(d.downloadURL+d.kubeDistroRepo+"/releases/"+d.extraPath+"v%s/%s-%s-%s", latestVersion, d.kubeDistroRepo, os, arch) if runtime.GOOS == "windows" { kubeURL += ".exe" } util.Infof("Downloading %s...\n", kubeURL) fullPath := filepath.Join(getFabric8BinLocation(), d.kubeBinary) err = downloadFile(fullPath, kubeURL) if err != nil { util.Errorf("Unable to download file %s/%s %v", fullPath, kubeURL, err) return err } util.Successf("Downloaded %s\n", fullPath) } else { util.Successf("%s is already available on your PATH\n", d.kubeBinary) } return nil }
func openService(ns string, serviceName string, c *k8sclient.Client, printURL bool, retry bool) { if retry { if err := RetryAfter(40, func() error { return CheckService(ns, serviceName, c) }, 10*time.Second); err != nil { util.Errorf("Could not find finalized endpoint being pointed to by %s: %v", serviceName, err) os.Exit(1) } } svcs, err := c.Services(ns).List(kubeApi.ListOptions{}) if err != nil { util.Errorf("No services found %v\n", err) } found := false for _, service := range svcs.Items { if serviceName == service.Name { url := service.ObjectMeta.Annotations[exposeURLAnnotation] if printURL { util.Successf("%s\n", url) } else { util.Successf("\nOpening URL %s\n", url) browser.OpenURL(url) } found = true break } } if !found { util.Errorf("No service %s in namespace %s\n", serviceName, ns) } }
func downloadFunktion() (err error) { os := runtime.GOOS arch := runtime.GOARCH _, err = exec.LookPath(funktion) if err != nil { latestVersion, err := getLatestVersionFromGitHub(fabric8io, funktionOperator) if err != nil { util.Errorf("Unable to get latest version for %s/%s %v", fabric8io, funktionOperator, err) return err } funktionURL := fmt.Sprintf(githubURL+fabric8io+"/"+funktionOperator+"/releases/download/v%s/%s-%s-%s", latestVersion, funktionOperator, os, arch) if runtime.GOOS == "windows" { funktionURL += ".exe" } util.Infof("Downloading %s...\n", funktionURL) fullPath := filepath.Join(getFabric8BinLocation(), funktion) err = downloadFile(fullPath, funktionURL) if err != nil { util.Errorf("Unable to download file %s/%s %v", fullPath, funktionURL, err) return err } util.Successf("Downloaded %s\n", fullPath) } else { util.Successf("%s is already available on your PATH\n", funktion) } return nil }
func downloadKubernetes(isMinishift bool) (err error) { os := runtime.GOOS arch := runtime.GOARCH if isMinishift { kubeDistroOrg = minishiftOwner kubeDistroRepo = minishift kubeDownloadURL = minishiftDownloadURL downloadPath = "download/" kubeBinary = minishift } _, err = exec.LookPath(kubeBinary) if err != nil { latestVersion, err := getLatestVersionFromGitHub(kubeDistroOrg, kubeDistroRepo) if err != nil { util.Errorf("Unable to get latest version for %s/%s %v", kubeDistroOrg, kubeDistroRepo, err) return err } kubeURL := fmt.Sprintf(kubeDownloadURL+kubeDistroRepo+"/releases/"+downloadPath+"v%s/%s-%s-%s", latestVersion, kubeDistroRepo, os, arch) util.Infof("Downloading %s...", kubeURL) err = downloadFile(writeFileLocation+kubeBinary, kubeURL) if err != nil { util.Errorf("Unable to download file %s/%s %v", writeFileLocation+kubeBinary, kubeURL, err) return err } util.Successf("Downloaded %s\n", kubeBinary) } else { util.Successf("%s is already available on your PATH\n", kubeBinary) } return nil }
func createRoutesForDomain(ns string, domain string, c *k8sclient.Client, oc *oclient.Client, fac *cmdutil.Factory) error { rc, err := c.Services(ns).List(labels.Everything()) if err != nil { util.Errorf("Failed to load services in namespace %s with error %v", ns, err) return err } items := rc.Items for _, service := range items { // TODO use the external load balancer as a way to know if we should create a route? name := service.ObjectMeta.Name if name != "kubernetes" { routes := oc.Routes(ns) _, err = routes.Get(name) if err != nil { hostName := name + "." + domain route := rapi.Route{ ObjectMeta: kapi.ObjectMeta{ Name: name, }, Host: hostName, ServiceName: name, } // lets create the route _, err = routes.Create(&route) if err != nil { util.Errorf("Failed to create the route %s with error %v", name, err) return err } } } } return nil }
func deployFabric8SASSecurityContextConstraints(c *k8sclient.Client, f *cmdutil.Factory, ns string) (Result, error) { name := Fabric8SASSCC scc := kapi.SecurityContextConstraints{ ObjectMeta: kapi.ObjectMeta{ Name: name, }, SELinuxContext: kapi.SELinuxContextStrategyOptions{ Type: kapi.SELinuxStrategyRunAsAny, }, RunAsUser: kapi.RunAsUserStrategyOptions{ Type: kapi.RunAsUserStrategyRunAsAny, }, Groups: []string{"system:serviceaccounts"}, Volumes: []kapi.FSType{kapi.FSTypeGitRepo, kapi.FSTypeConfigMap, kapi.FSTypeSecret, kapi.FSTypeEmptyDir}, } _, err := c.SecurityContextConstraints().Get(name) if err == nil { err = c.SecurityContextConstraints().Delete(name) if err != nil { return Failure, err } } _, err = c.SecurityContextConstraints().Create(&scc) if err != nil { util.Errorf("Cannot create SecurityContextConstraints: %v\n", err) util.Errorf("Failed to create SecurityContextConstraints %v in namespace %s: %v\n", scc, ns, err) return Failure, err } util.Infof("SecurityContextConstraints %s is setup correctly\n", name) return Success, err }
func createPV(c *k8sclient.Client, ns string, pvcNames []string, sshCommand string) (Result, error) { for _, pvcName := range pvcNames { hostPath := path.Join("/data", ns, pvcName) nsPvcName := ns + "-" + pvcName pvs := c.PersistentVolumes() rc, err := pvs.List(api.ListOptions{}) if err != nil { util.Errorf("Failed to load PersistentVolumes with error %v\n", err) } items := rc.Items for _, volume := range items { if nsPvcName == volume.ObjectMeta.Name { util.Infof("Already created PersistentVolumes for %s\n", nsPvcName) } } // we no longer need to do chmod on kubernetes as we have init containers now typeOfMaster := util.TypeOfMaster(c) if typeOfMaster != util.Kubernetes || len(sshCommand) > 0 { err = configureHostPathVolume(c, ns, hostPath, sshCommand) if err != nil { util.Errorf("Failed to configure the host path %s with error %v\n", hostPath, err) } } // lets create a new PV util.Infof("PersistentVolume name %s will be created on host path %s\n", nsPvcName, hostPath) pv := api.PersistentVolume{ ObjectMeta: api.ObjectMeta{ Name: nsPvcName, }, Spec: api.PersistentVolumeSpec{ Capacity: api.ResourceList{ api.ResourceName(api.ResourceStorage): resource.MustParse("1Gi"), }, AccessModes: []api.PersistentVolumeAccessMode{api.ReadWriteOnce}, PersistentVolumeSource: api.PersistentVolumeSource{ HostPath: &api.HostPathVolumeSource{Path: hostPath}, }, PersistentVolumeReclaimPolicy: api.PersistentVolumeReclaimRecycle, }, } _, err = pvs.Create(&pv) if err != nil { util.Errorf("Failed to create PersistentVolume %s at %s with error %v\n", nsPvcName, hostPath, err) } } return Success, nil }
func deployFabric8SecurityContextConstraints(c *k8sclient.Client, f *cmdutil.Factory, ns string) (Result, error) { name := Fabric8SCC if ns != "default" { name += "-" + ns } var priority int32 = 10 scc := kapi.SecurityContextConstraints{ ObjectMeta: kapi.ObjectMeta{ Name: name, }, Priority: &priority, AllowPrivilegedContainer: true, AllowHostNetwork: true, AllowHostPorts: true, Volumes: []kapi.FSType{kapi.FSTypeAll}, SELinuxContext: kapi.SELinuxContextStrategyOptions{ Type: kapi.SELinuxStrategyRunAsAny, }, RunAsUser: kapi.RunAsUserStrategyOptions{ Type: kapi.RunAsUserStrategyRunAsAny, }, Users: []string{ "system:serviceaccount:openshift-infra:build-controller", "system:serviceaccount:" + ns + ":default", "system:serviceaccount:" + ns + ":fabric8", "system:serviceaccount:" + ns + ":gerrit", "system:serviceaccount:" + ns + ":jenkins", "system:serviceaccount:" + ns + ":router", "system:serviceaccount:" + ns + ":registry", "system:serviceaccount:" + ns + ":gogs", "system:serviceaccount:" + ns + ":fluentd", }, Groups: []string{bootstrappolicy.ClusterAdminGroup, bootstrappolicy.NodesGroup}, } _, err := c.SecurityContextConstraints().Get(name) if err == nil { err = c.SecurityContextConstraints().Delete(name) if err != nil { return Failure, err } } _, err = c.SecurityContextConstraints().Create(&scc) if err != nil { util.Errorf("Cannot create SecurityContextConstraints: %v\n", err) util.Errorf("Failed to create SecurityContextConstraints %v in namespace %s: %v\n", scc, ns, err) return Failure, err } util.Infof("SecurityContextConstraints %s is setup correctly\n", name) return Success, err }
func createPersistentVolume(cmd *cobra.Command, ns string, c *k8sclient.Client, fac *cmdutil.Factory) (Result, error) { flags := cmd.Flags() hostPath := flags.Lookup(hostPathFlag).Value.String() name := flags.Lookup(nameFlag).Value.String() pvs := c.PersistentVolumes() rc, err := pvs.List(labels.Everything(), fields.Everything()) if err != nil { util.Errorf("Failed to load PersistentVolumes with error %v", err) return Failure, err } items := rc.Items for _, volume := range items { // TODO use the external load balancer as a way to know if we should create a route? vname := volume.ObjectMeta.Name if vname == name { util.Infof("Already created PersistentVolumes for %s\n", name) return Success, nil } } if hostPath == "" { return missingFlag(cmd, hostPathFlag) } if confirmAction(flags) == false { return Failure, nil } // lets create a new PV util.Infof("PersistentVolume name %s will be created on host path %s\n", name, hostPath) pv := api.PersistentVolume{ ObjectMeta: api.ObjectMeta{ Name: name, }, Spec: api.PersistentVolumeSpec{ Capacity: api.ResourceList{ api.ResourceName(api.ResourceStorage): resource.MustParse("100G"), }, AccessModes: []api.PersistentVolumeAccessMode{api.ReadWriteMany}, PersistentVolumeSource: api.PersistentVolumeSource{ HostPath: &api.HostPathVolumeSource{Path: hostPath}, }, }, } _, err = pvs.Create(&pv) if err != nil { util.Errorf("Failed to create PersistentVolume %s at %s with error %v", name, hostPath, err) return Failure, err } return Success, nil }
func install(isMinishift bool) { writeFileLocation := getFabric8BinLocation() err := os.MkdirAll(writeFileLocation, 0700) if err != nil { util.Errorf("Unable to create directory to download files %s %v\n", writeFileLocation, err) } err = downloadDriver() if err != nil { util.Warnf("Unable to download driver %v\n", err) } d := getDownloadProperties(isMinishift) err = downloadKubernetes(d) if err != nil { util.Warnf("Unable to download kubernetes distro %v\n", err) } err = downloadKubectlClient() if err != nil { util.Warnf("Unable to download client %v\n", err) } if d.isMiniShift { err = downloadOpenShiftClient() if err != nil { util.Warnf("Unable to download client %v\n", err) } } }
func downloadClient(isMinishift bool) (err error) { os := runtime.GOOS arch := runtime.GOARCH _, err = exec.LookPath(kubectl) if err != nil { latestVersion, err := getLatestVersionFromGitHub(kubeDistroOrg, kubernetes) if err != nil { return fmt.Errorf("Unable to get latest version for %s/%s %v", kubeDistroOrg, kubernetes, err) } if isMinishift { clientBinary = oc return fmt.Errorf("Openshift client download not yet supported") } clientURL := fmt.Sprintf("https://storage.googleapis.com/kubernetes-release/release/v%s/bin/%s/%s/%s", latestVersion, os, arch, kubectl) util.Infof("Downloading %s...", clientURL) err = downloadFile(writeFileLocation+clientBinary, clientURL) if err != nil { util.Errorf("Unable to download file %s/%s %v", writeFileLocation+clientBinary, clientURL, err) return err } util.Successf("Downloaded %s\n", clientBinary) } else { util.Successf("%s is already available on your PATH\n", clientBinary) } return nil }
func printSummary(typeOfMaster util.MasterType, externalNodeName string, ns string, domain string, c *k8sclient.Client) { util.Info("\n") util.Info("-------------------------\n") util.Info("\n") clientType := getClientTypeName(typeOfMaster) if externalNodeName != "" { util.Info("Deploying ingress controller on node ") util.Successf("%s", externalNodeName) util.Info(" use its external ip when configuring your wildcard DNS.\n") util.Infof("To change node move the label: `%s label node %s %s- && %s label node $YOUR_NEW_NODE %s=true`\n", clientType, externalNodeName, externalIPLabel, clientType, externalIPLabel) util.Info("\n") } util.Info("Default GOGS admin username/password = "******"%s/%s\n", gogsDefaultUsername, gogsDefaultPassword) util.Info("\n") found, _ := checkIfPVCsPending(c, ns) if found { util.Errorf("There are pending PersistentVolumeClaims\n") util.Infof("If using a local cluster run `gofabric8 volumes` to create missing HostPath volumes\n") util.Infof("If using a remote cloud then enable dynamic persistence with a StorageClass. For details see http://fabric8.io/guide/getStarted/persistence.html\n") util.Info("\n") } util.Infof("Downloading images and waiting to open the fabric8 console...\n") util.Info("\n") util.Info("-------------------------\n") }
func addIngressInfraLabel(c *k8sclient.Client, ns string) string { nodeClient := c.Nodes() nodes, err := nodeClient.List(api.ListOptions{}) if err != nil { util.Errorf("\nUnable to find any nodes: %s\n", err) } changed := false hasExistingExposeIPLabel, externalNodeName := hasExistingLabel(nodes, externalIPLabel) if externalNodeName != "" { return externalNodeName } if !hasExistingExposeIPLabel && len(nodes.Items) > 0 { for _, node := range nodes.Items { if !node.Spec.Unschedulable { changed = addLabelIfNotExist(&node.ObjectMeta, externalIPLabel, "true") if changed { _, err = nodeClient.Update(&node) if err != nil { printError("Failed to label node with ", err) } return node.Name } } } } if !changed && !hasExistingExposeIPLabel { util.Warnf("Unable to add label for ingress controller to run on a specific node, please add manually: kubectl label node [your node name] %s=true", externalIPLabel) } return "" }
// lets find the executable on the PATH or in the fabric8 directory func resolveBinaryLocation(executable string) string { path, err := exec.LookPath(executable) if err != nil || fileNotExist(path) { home := os.Getenv("HOME") if home == "" { util.Error("No $HOME environment variable found") } writeFileLocation := getFabric8BinLocation() // lets try in the fabric8 folder path = filepath.Join(writeFileLocation, executable) if fileNotExist(path) { path = executable // lets try in the folder where we found the gofabric8 executable folder, err := osext.ExecutableFolder() if err != nil { util.Errorf("Failed to find executable folder: %v\n", err) } else { path = filepath.Join(folder, executable) if fileNotExist(path) { util.Infof("Could not find executable at %v\n", path) path = executable } } } } util.Infof("using the executable %s\n", path) return path }
func downloadKubectlClient() (err error) { os := runtime.GOOS arch := runtime.GOARCH kubectlBinary := kubectl if runtime.GOOS == "windows" { kubectlBinary += ".exe" } _, err = exec.LookPath(kubectlBinary) if err != nil { latestVersion, err := getLatestVersionFromGitHub(kubernetes, kubernetes) if err != nil { return fmt.Errorf("Unable to get latest version for %s/%s %v", kubernetes, kubernetes, err) } clientURL := fmt.Sprintf("https://storage.googleapis.com/kubernetes-release/release/v%s/bin/%s/%s/%s", latestVersion, os, arch, kubectlBinary) util.Infof("Downloading %s...\n", clientURL) fullPath := filepath.Join(getFabric8BinLocation(), kubectlBinary) err = downloadFile(fullPath, clientURL) if err != nil { util.Errorf("Unable to download file %s/%s %v", fullPath, clientURL, err) return err } util.Successf("Downloaded %s\n", fullPath) } else { util.Successf("%s is already available on your PATH\n", kubectlBinary) } return nil }
func createPV(c *k8sclient.Client, ns string, pvcNames []string, cmd *cobra.Command) (Result, error) { for _, pvcName := range pvcNames { hostPath := "/data/" + pvcName pvs := c.PersistentVolumes() rc, err := pvs.List(api.ListOptions{}) if err != nil { util.Errorf("Failed to load PersistentVolumes with error %v\n", err) } items := rc.Items for _, volume := range items { vname := volume.ObjectMeta.Name if vname == pvcName { util.Infof("Already created PersistentVolumes for %s\n", pvcName) } } err = configureHostPathVolume(c, ns, hostPath, cmd) if err != nil { util.Errorf("Failed to configure the host path %s with error %v\n", hostPath, err) } // lets create a new PV util.Infof("PersistentVolume name %s will be created on host path %s\n", pvcName, hostPath) pv := api.PersistentVolume{ ObjectMeta: api.ObjectMeta{ Name: pvcName, }, Spec: api.PersistentVolumeSpec{ Capacity: api.ResourceList{ api.ResourceName(api.ResourceStorage): resource.MustParse("5Gi"), }, AccessModes: []api.PersistentVolumeAccessMode{api.ReadWriteOnce}, PersistentVolumeSource: api.PersistentVolumeSource{ HostPath: &api.HostPathVolumeSource{Path: hostPath}, }, }, } _, err = pvs.Create(&pv) if err != nil { util.Errorf("Failed to create PersistentVolume %s at %s with error %v\n", pvcName, hostPath, err) } } return Success, nil }
// NewCmdInstall installs the dependencies to run the fabric8 microservices platform func NewCmdInstall(f *cmdutil.Factory) *cobra.Command { cmd := &cobra.Command{ Use: "install", Short: "Installs the dependencies to locally run the fabric8 microservices platform", Long: `Installs the dependencies to locally run the fabric8 microservices platform`, Run: func(cmd *cobra.Command, args []string) { if runtime.GOOS == "windows" { util.Errorf("%s is not yet supported by gofabric8 install", runtime.GOOS) } isMinishift := cmd.Flags().Lookup(minishiftFlag).Value.String() == "true" home := os.Getenv("HOME") if home == "" { util.Error("No $HOME environment variable found") } writeFileLocation = home + binLocation err := os.MkdirAll(writeFileLocation, 0700) if err != nil { util.Errorf("Unable to create directory to download files %s %v\n", writeFileLocation, err) } err = downloadDriver() if err != nil { util.Warnf("Unable to download driver %v\n", err) } err = downloadKubernetes(isMinishift) if err != nil { util.Warnf("Unable to download kubernetes distro %v\n", err) } err = downloadClient(isMinishift) if err != nil { util.Warnf("Unable to download client %v\n", err) } }, } cmd.PersistentFlags().Bool(minishiftFlag, false, "Install minishift rather than minikube") return cmd }
func missingFlag(cmd *cobra.Command, name string) (Result, error) { util.Errorf("No option -%s specified!\n", hostPathFlag) text := cmd.Name() parent := cmd.Parent() if parent != nil { text = parent.Name() + " " + text } util.Infof("Please try something like: %s --%s='some value' ...\n\n", text, hostPathFlag) return Failure, nil }
func createRoutesForDomain(ns string, domain string, c *k8sclient.Client, oc *oclient.Client, fac *cmdutil.Factory) error { rapi.AddToScheme(kapi.Scheme) rapiv1.AddToScheme(kapi.Scheme) rc, err := c.Services(ns).List(kapi.ListOptions{}) if err != nil { util.Errorf("Failed to load services in namespace %s with error %v", ns, err) return err } var labels = make(map[string]string) labels["provider"] = "fabric8" items := rc.Items for _, service := range items { // TODO use the external load balancer as a way to know if we should create a route? name := service.ObjectMeta.Name if name != "kubernetes" { routes := oc.Routes(ns) _, err = routes.Get(name) if err != nil { hostName := name + "." + domain route := rapi.Route{ ObjectMeta: kapi.ObjectMeta{ Labels: labels, Name: name, }, Spec: rapi.RouteSpec{ Host: hostName, To: kapi.ObjectReference{Name: name}, }, } // lets create the route _, err = routes.Create(&route) if err != nil { util.Errorf("Failed to create the route %s with error %v", name, err) return err } } } } return nil }
func isMini(c *k8sclient.Client, ns string) bool { nodes, err := c.Nodes().List(api.ListOptions{}) if err != nil { util.Errorf("\nUnable to find any nodes: %s\n", err) } if len(nodes.Items) == 1 { node := nodes.Items[0] return node.Name == minikubeNodeName || node.Name == minishiftNodeName || node.Name == boot2docker } return false }
// NewCmdDockerEnv sets the current func NewCmdDockerEnv(f *cmdutil.Factory) *cobra.Command { cmd := &cobra.Command{ Use: "docker-env", Short: "Sets up docker env variables; Usage 'eval $(gofabric8 docker-env)'", Long: `Sets up docker env variables; Usage 'eval $(gofabric8 docker-env)'`, Run: func(cmd *cobra.Command, args []string) { c, _ := client.NewClient(f) nodes, err := c.Nodes().List(api.ListOptions{}) if err != nil { util.Errorf("Unable to find any nodes: %s\n", err) } if len(nodes.Items) == 1 { node := nodes.Items[0] var command string var args []string if node.Name == minikubeNodeName { command = "minikube" args = []string{"docker-env"} } else if node.Name == minishiftNodeName { command = "minishift" args = []string{"docker-env"} } else if node.Name == rhelcdk { command = "vagrant" args = []string{"service-manager", "env", "docker"} } if command == "" { util.Fatalf("Unrecognised cluster environment for node %s\n", node.Name) util.Fatalf("docker-env support is currently only for CDK, Minishift and Minikube\n") } e := exec.Command(command, args...) e.Stdout = os.Stdout e.Stderr = os.Stderr err = e.Run() if err != nil { util.Fatalf("Unable to set the docker environment %v", err) } } else { util.Fatalf("docker-env is only available to run on clusters of 1 node") } }, } return cmd }
// CheckService waits for the specified service to be ready by returning an error until the service is up // The check is done by polling the endpoint associated with the service and when the endpoint exists, returning no error->service-online // Credits: https://github.com/kubernetes/minikube/blob/v0.9.0/cmd/minikube/cmd/service.go#L89 func CheckService(ns string, service string, c *k8sclient.Client) error { svc, err := c.Services(ns).Get(service) if err != nil { return err } url := svc.ObjectMeta.Annotations[exposeURLAnnotation] if url == "" { util.Info(".") return errors.New("") } endpoints := c.Endpoints(ns) if endpoints == nil { util.Errorf("No endpoints found in namespace %s\n", ns) } endpoint, err := endpoints.Get(service) if err != nil { util.Errorf("No endpoints found for service %s\n", service) return err } return CheckEndpointReady(endpoint) }
// Ensure that the `restricted` SecurityContextConstraints has the RunAsUser set to RunAsAny // // if `restricted does not exist lets create it // otherwise if needed lets modify the RunAsUser func verifyRestrictedSecurityContextConstraints(c *k8sclient.Client, f *cmdutil.Factory) (Result, error) { name := RestrictedSCC ns, _, e := f.DefaultNamespace() if e != nil { util.Fatal("No default namespace") return Failure, e } rc, err := c.SecurityContextConstraints().Get(name) if err != nil { scc := kapi.SecurityContextConstraints{ ObjectMeta: kapi.ObjectMeta{ Name: RestrictedSCC, }, SELinuxContext: kapi.SELinuxContextStrategyOptions{ Type: kapi.SELinuxStrategyMustRunAs, }, RunAsUser: kapi.RunAsUserStrategyOptions{ Type: kapi.RunAsUserStrategyRunAsAny, }, Groups: []string{bootstrappolicy.AuthenticatedGroup}, } _, err = c.SecurityContextConstraints().Create(&scc) if err != nil { return Failure, err } else { util.Infof("SecurityContextConstraints %s created\n", name) return Success, err } } // lets check that the restricted is configured correctly if kapi.RunAsUserStrategyRunAsAny != rc.RunAsUser.Type { rc.RunAsUser.Type = kapi.RunAsUserStrategyRunAsAny _, err = c.SecurityContextConstraints().Update(rc) if err != nil { util.Errorf("Failed to update SecurityContextConstraints %v in namespace %s: %v\n", rc, ns, err) return Failure, err } util.Infof("SecurityContextConstraints %s is updated to enable fabric8\n", name) } else { util.Infof("SecurityContextConstraints %s is configured correctly\n", name) } return Success, err }
func processTemplate(tmpl *tapi.Template, domain string, apiserver string) { generators := map[string]generator.Generator{ "expression": generator.NewExpressionValueGenerator(rand.New(rand.NewSource(time.Now().UnixNano()))), } p := template.NewProcessor(generators) tmpl.Parameters = append(tmpl.Parameters, tapi.Parameter{ Name: "DOMAIN", Value: domain, }, tapi.Parameter{ Name: "APISERVER", Value: apiserver, }) errorList := p.Process(tmpl) for _, errInfo := range errorList { util.Errorf("Processing template field %s got error %s\n", errInfo.Field, errInfo.Detail) } }
func f8Version(v string, typeOfMaster util.MasterType) string { metadataUrl := consoleMetadataUrl if typeOfMaster == util.Kubernetes { metadataUrl = consoleKubernetesMetadataUrl } resp, err := http.Get(metadataUrl) if err != nil { util.Fatalf("Cannot get fabric8 version to deploy: %v", err) } defer resp.Body.Close() // read xml http response xmlData, err := ioutil.ReadAll(resp.Body) if err != nil { util.Fatalf("Cannot get fabric8 version to deploy: %v", err) } type Metadata struct { Release string `xml:"versioning>release"` Versions []string `xml:"versioning>versions>version"` } var m Metadata err = xml.Unmarshal(xmlData, &m) if err != nil { util.Fatalf("Cannot get fabric8 version to deploy: %v", err) } if v == "latest" { return m.Release } for _, version := range m.Versions { if v == version { return version } } util.Errorf("\nUnknown version: %s\n", v) util.Fatalf("Valid versions: %v\n", append(m.Versions, "latest")) return "" }
func versionForUrl(v string, metadataUrl string) string { resp, err := http.Get(metadataUrl) if err != nil { util.Fatalf("Cannot get fabric8 version to deploy: %v", err) } defer resp.Body.Close() // read xml http response xmlData, err := ioutil.ReadAll(resp.Body) if err != nil { util.Fatalf("Cannot get fabric8 version to deploy: %v", err) } type Metadata struct { Release string `xml:"versioning>release"` Versions []string `xml:"versioning>versions>version"` } var m Metadata err = xml.Unmarshal(xmlData, &m) if err != nil { util.Fatalf("Cannot get fabric8 version to deploy: %v", err) } if v == "latest" { return m.Release } for _, version := range m.Versions { if v == version { return version } } util.Errorf("\nUnknown version %s for %s\n", v, metadataUrl) util.Fatalf("Valid versions: %v\n", append(m.Versions, "latest")) return "" }
func processTemplate(tmpl *tapi.Template, ns string, domain string, apiserver string) { generators := map[string]generator.Generator{ "expression": generator.NewExpressionValueGenerator(rand.New(rand.NewSource(time.Now().UnixNano()))), } p := template.NewProcessor(generators) ip, port, err := net.SplitHostPort(apiserver) if err != nil && !strings.Contains(err.Error(), "missing port in address") { util.Fatalf("%s", err) } namespaceIdx := -1 for i, param := range tmpl.Parameters { if param.Name == "NAMESPACE" { namespaceIdx = i } } if namespaceIdx >= 0 { tmpl.Parameters[namespaceIdx].Value = ns } tmpl.Parameters = append(tmpl.Parameters, tapi.Parameter{ Name: "DOMAIN", Value: ns + "." + domain, }, tapi.Parameter{ Name: "APISERVER", Value: ip, }, tapi.Parameter{ Name: "OAUTH_AUTHORIZE_PORT", Value: port, }) errorList := p.Process(tmpl) for _, errInfo := range errorList { util.Errorf("Processing template field %s got error %s\n", errInfo.Field, errInfo.Detail) } }
func printErr(err error) { if err != nil { util.Errorf("%s\n", err.Error()) } }
func installTemplates(kc *k8sclient.Client, c *oclient.Client, fac *cmdutil.Factory, v string, templateUrl string, dockerRegistry string, arch string, domain string) error { ns, _, err := fac.DefaultNamespace() if err != nil { util.Fatal("No default namespace") return err } templates := c.Templates(ns) util.Infof("Downloading templates for version %v\n", v) uri := fmt.Sprintf(templateUrl, v) resp, err := http.Get(uri) if err != nil { util.Fatalf("Cannot get fabric8 template to deploy: %v", err) } defer resp.Body.Close() tmpFileName := "/tmp/fabric8-template-distros.tar.gz" t, err := os.OpenFile(tmpFileName, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0777) if err != nil { return err } defer t.Close() _, err = io.Copy(t, resp.Body) if err != nil { return err } r, err := zip.OpenReader(tmpFileName) if err != nil { return err } defer r.Close() typeOfMaster := util.TypeOfMaster(kc) for _, f := range r.File { mode := f.FileHeader.Mode() if mode.IsDir() { continue } rc, err := f.Open() if err != nil { return err } defer rc.Close() util.Infof("Loading template %s\n", f.Name) jsonData, err := ioutil.ReadAll(rc) if err != nil { util.Fatalf("Cannot get fabric8 template to deploy: %v", err) } jsonData, err = adaptFabric8ImagesInResourceDescriptor(jsonData, dockerRegistry, arch) if err != nil { util.Fatalf("Cannot append docker registry: %v", err) } jsonData = replaceDomain(jsonData, domain, ns, typeOfMaster) var v1tmpl tapiv1.Template err = json.Unmarshal(jsonData, &v1tmpl) if err != nil { util.Fatalf("Cannot get fabric8 template to deploy: %v", err) } var tmpl tapi.Template err = api.Scheme.Convert(&v1tmpl, &tmpl) if err != nil { util.Fatalf("Cannot get fabric8 template to deploy: %v", err) return err } name := tmpl.ObjectMeta.Name if typeOfMaster == util.Kubernetes { appName := name name = "catalog-" + appName // lets install ConfigMaps for the templates // TODO should the name have a prefix? configmap := api.ConfigMap{ ObjectMeta: api.ObjectMeta{ Name: name, Namespace: ns, Labels: map[string]string{ "name": appName, "provider": "fabric8.io", "kind": "catalog", }, }, Data: map[string]string{ name + ".json": string(jsonData), }, } configmaps := kc.ConfigMaps(ns) _, err = configmaps.Get(name) if err == nil { err = configmaps.Delete(name) if err != nil { util.Errorf("Could not delete configmap %s due to: %v\n", name, err) } } _, err = configmaps.Create(&configmap) if err != nil { util.Fatalf("Failed to create configmap %v", err) return err } } else { // lets install the OpenShift templates _, err = templates.Get(name) if err == nil { err = templates.Delete(name) if err != nil { util.Errorf("Could not delete template %s due to: %v\n", name, err) } } _, err = templates.Create(&tmpl) if err != nil { util.Fatalf("Failed to create template %v", err) return err } } } return nil }
func createIngressForDomain(ns string, domain string, c *k8sclient.Client, fac *cmdutil.Factory) error { rapi.AddToScheme(kapi.Scheme) rapiv1.AddToScheme(kapi.Scheme) ingressClient := c.Extensions().Ingress(ns) ingresses, err := ingressClient.List(kapi.ListOptions{}) if err != nil { util.Errorf("Failed to load ingresses in namespace %s with error %v", ns, err) return err } rc, err := c.Services(ns).List(kapi.ListOptions{}) if err != nil { util.Errorf("Failed to load services in namespace %s with error %v", ns, err) return err } var labels = make(map[string]string) labels["provider"] = "fabric8" items := rc.Items for _, service := range items { name := service.ObjectMeta.Name serviceSpec := service.Spec found := false // TODO we should probably add an annotation to disable ingress creation if name != "jenkinshift" { for _, ingress := range ingresses.Items { if ingress.GetName() == name { found = true break } // TODO look for other ingresses with different names? for _, rule := range ingress.Spec.Rules { http := rule.HTTP if http != nil { for _, path := range http.Paths { ruleService := path.Backend.ServiceName if ruleService == name { found = true break } } } } } if !found { ports := serviceSpec.Ports hostName := name + "." + ns + "." + domain if len(ports) > 0 { rules := []extensions.IngressRule{} for _, port := range ports { rule := extensions.IngressRule{ Host: hostName, IngressRuleValue: extensions.IngressRuleValue{ HTTP: &extensions.HTTPIngressRuleValue{ Paths: []extensions.HTTPIngressPath{ { Backend: extensions.IngressBackend{ ServiceName: name, // we need to use target port until https://github.com/nginxinc/kubernetes-ingress/issues/41 is fixed //ServicePort: intstr.FromInt(port.Port), ServicePort: port.TargetPort, }, }, }, }, }, } rules = append(rules, rule) } ingress := extensions.Ingress{ ObjectMeta: kapi.ObjectMeta{ Labels: labels, Name: name, }, Spec: extensions.IngressSpec{ Rules: rules, }, } // lets create the ingress _, err = ingressClient.Create(&ingress) if err != nil { util.Errorf("Failed to create the ingress %s with error %v", name, err) return err } } } } } return nil }