func ensureSCCExists(ns string, serviceAccountName string) error { binary, err := exec.LookPath("oc") if err != nil { // no openshift so ignore return nil } text, err := getCommandOutputString(binary, []string{"export", "scc", serviceAccountName}, os.Stdin) if err != nil { log.Debug("Failed to get SecurityContextConstraints %s. %s", serviceAccountName, err) } if err != nil || len(text) == 0 { text = ` apiVersion: v1 kind: SecurityContextConstraints groups: - system:cluster-admins - system:nodes metadata: creationTimestamp: null name: ` + serviceAccountName + ` runAsUser: type: RunAsAny seLinuxContext: type: RunAsAny supplementalGroups: type: RunAsAny users: ` } // lets ensure there's a users section if !strings.Contains(text, "\nusers:") { text = text + "\nusers:\n" } line := "system:serviceaccount:" + ns + ":" + serviceAccountName if strings.Contains(text, line) { log.Info("No need to modify SecurityContextConstraints as it already contains line for namespace %s and service account %s", ns, serviceAccountName) return nil } text = text + "\n- " + line + "\n" log.Debug("created SecurityContextConstraints YAML: %s", text) log.Info("Applying changes for SecurityContextConstraints %s for namespace %s and ServiceAccount %s", serviceAccountName, ns, serviceAccountName) reader := bytes.NewReader([]byte(text)) err = runCommand(binary, []string{"apply", "-f", "-"}, reader) if err != nil { log.Err("Failed to update OpenShift SecurityContextConstraints named %s. %s", serviceAccountName, err) } return err }
func osExpandAndVerifyGlobal(c *cli.Context, name string) (string, error) { flag := c.GlobalString(name) value := os.ExpandEnv(flag) if len(value) == 0 { return "", fmt.Errorf("No parameter supplied for: %s", name) } log.Debug("flag %s is %s", name, value) return value, nil }
// ChooseHostAndPrivateKey parses the given Ansible inventory file for the hosts // and chooses a single host inside it, returning the host name and the private key func ChooseHostAndPrivateKey(thisPodName string, hosts string, c *client.Client, ns string, rcName string) (*HostEntry, *api.ReplicationController, map[string]string, error) { retryAttempts := 20 for i := 0; i < retryAttempts; i++ { if i > 0 { // lets sleep before retrying time.Sleep(time.Duration(random(1000, 20000)) * time.Millisecond) } if c == nil { return nil, nil, nil, fmt.Errorf("No Kubernetes Client specified!") } rc, err := c.ReplicationControllers(ns).Get(rcName) if err != nil { return nil, nil, nil, err } if rc == nil { return nil, nil, nil, fmt.Errorf("No ReplicationController found for name %s", rcName) } pods, err := c.Pods(ns).List(api.ListOptions{}) if err != nil { return nil, nil, nil, err } metadata := &rc.ObjectMeta resourceVersion := metadata.ResourceVersion if metadata.Annotations == nil { metadata.Annotations = make(map[string]string) } annotations := metadata.Annotations log.Info("Using ReplicationController with namespace %s name %s and version %s", ns, rcName, resourceVersion) hostsText := annotations[HostInventoryAnnotation] if len(hostsText) == 0 { return nil, nil, nil, fmt.Errorf("Could not find annotation %s on ReplicationController %s", HostInventoryAnnotation, rcName) } hostEntries, err := LoadHostEntriesFromText(hostsText) if err != nil { return nil, nil, nil, err } log.Info("Found %d host entries", len(hostEntries)) // lets pick a random entry if len(hostEntries) > 0 { filteredHostEntries := hostEntries for annKey, podName := range annotations { if strings.HasPrefix(annKey, AnsibleHostPodAnnotationPrefix) { hostName := annKey[len(AnsibleHostPodAnnotationPrefix):] if k8s.PodIsRunning(pods, podName) { if podName != thisPodName { log.Info("Pod %s podName has already claimed host %s", podName, hostName) filteredHostEntries = removeHostEntry(filteredHostEntries, hostName) } } else { // lets remove this annotation as the pod is no longer valid log.Info("Pod %s is no longer running so removing the annotation %s", podName, annKey) delete(metadata.Annotations, annKey) } } } count := len(filteredHostEntries) if count == 0 { log.Info("There are no more hosts available to be supervised by this pod!") return nil, nil, nil, fmt.Errorf("No more hosts available to be supervised!") } log.Info("After filtering out hosts owned by other pods we have %v host entries left", count) pickedEntry := filteredHostEntries[random(0, count)] hostName := pickedEntry.Name if len(pickedEntry.Host) == 0 { return nil, nil, nil, fmt.Errorf("Could not find host name for entry %s", pickedEntry.Name) } if len(pickedEntry.User) == 0 { return nil, nil, nil, fmt.Errorf("Could not find User for entry %s", pickedEntry.Name) } // lets try pick this pod annotations[AnsibleHostPodAnnotationPrefix+hostName] = thisPodName rc, err = c.ReplicationControllers(ns).Update(rc) if err != nil { log.Info("Failed to update the RC, could be concurrent update failure: %s", err) } else { log.Info("Picked host " + pickedEntry.Host) // lets update the Pod with the host name label podClient := c.Pods(ns) pod, err := podClient.Get(thisPodName) if err != nil { return pickedEntry, nil, nil, err } metadata := &pod.ObjectMeta if metadata.Annotations == nil { metadata.Annotations = make(map[string]string) } metadata.Annotations[HostNameAnnotation] = pickedEntry.Name metadata.Annotations[HostAddressAnnotation] = pickedEntry.Host //pod.Status = api.PodStatus{} pod, err = podClient.UpdateStatus(pod) if err != nil { return pickedEntry, nil, nil, err } // lets export required environment variables exportEnvVars := os.Getenv(EnvExportEnvVars) envVars := make(map[string]string) if len(exportEnvVars) > 0 { names := strings.Split(exportEnvVars, " ") for _, name := range names { name = strings.TrimSpace(name) if len(name) > 0 { value := os.Getenv(name) if len(value) > 0 { envVars[name] = value log.Debug("Exporting environment variable %s = %s", name, value) } } } } err = forwardPorts(pod, pickedEntry) return pickedEntry, rc, envVars, err } } } return nil, nil, nil, fmt.Errorf("Could not find any available hosts on the ReplicationController %s and hosts %s", rcName, hosts) }
func osExpand(c *cli.Context, name string) string { flag := c.String(name) value := os.ExpandEnv(flag) log.Debug("flag %s is %s", name, value) return value }