// Pass ports=nil for all ports. func formatEndpoints(endpoints *api.Endpoints, ports util.StringSet) string { if len(endpoints.Subsets) == 0 { return "<none>" } list := []string{} max := 3 more := false count := 0 for i := range endpoints.Subsets { ss := &endpoints.Subsets[i] for i := range ss.Ports { port := &ss.Ports[i] if ports == nil || ports.Has(port.Name) { for i := range ss.Addresses { if len(list) == max { more = true } addr := &ss.Addresses[i] if !more { list = append(list, fmt.Sprintf("%s:%d", addr.IP, port.Port)) } count++ } } } } ret := strings.Join(list, ",") if more { return fmt.Sprintf("%s + %d more...", ret, count-max) } return ret }
func filterInvalidPods(pods []*api.Pod, source string, recorder record.EventRecorder) (filtered []*api.Pod) { names := util.StringSet{} for i, pod := range pods { var errlist []error if errs := validation.ValidatePod(pod); len(errs) != 0 { errlist = append(errlist, errs...) // If validation fails, don't trust it any further - // even Name could be bad. } else { name := kubecontainer.GetPodFullName(pod) if names.Has(name) { errlist = append(errlist, fielderrors.NewFieldDuplicate("name", pod.Name)) } else { names.Insert(name) } } if len(errlist) > 0 { name := bestPodIdentString(pod) err := utilerrors.NewAggregate(errlist) glog.Warningf("Pod[%d] (%s) from %s failed validation, ignoring: %v", i+1, name, source, err) recorder.Eventf(pod, "FailedValidation", "Error validating pod %s from %s, ignoring: %v", name, source, err) continue } filtered = append(filtered, pod) } return }
// nameMatches checks to see if the resourceName of the action is in a the specified whitelist. An empty whitelist indicates that any name is allowed. // An empty string in the whitelist should only match the action's resourceName if the resourceName itself is empty string. This behavior allows for the // combination of a whitelist for gets in the same rule as a list that won't have a resourceName. I don't recommend writing such a rule, but we do // handle it like you'd expect: white list is respected for gets while not preventing the list you explicitly asked for. func (a DefaultAuthorizationAttributes) nameMatches(allowedResourceNames util.StringSet) bool { if len(allowedResourceNames) == 0 { return true } return allowedResourceNames.Has(a.GetResourceName()) }
func (t *tcShaper) nextClassID() (int, error) { data, err := t.e.Command("tc", "class", "show", "dev", t.iface).CombinedOutput() if err != nil { return -1, err } scanner := bufio.NewScanner(bytes.NewBuffer(data)) classes := util.StringSet{} for scanner.Scan() { line := strings.TrimSpace(scanner.Text()) // skip empty lines if len(line) == 0 { continue } parts := strings.Split(line, " ") // expected tc line: // class htb 1:1 root prio 0 rate 1000Kbit ceil 1000Kbit burst 1600b cburst 1600b if len(parts) != 14 { return -1, fmt.Errorf("unexpected output from tc: %s (%v)", scanner.Text(), parts) } classes.Insert(parts[2]) } // Make sure it doesn't go forever for nextClass := 1; nextClass < 10000; nextClass++ { if !classes.Has(fmt.Sprintf("1:%d", nextClass)) { return nextClass, nil } } // This should really never happen return -1, fmt.Errorf("exhausted class space, please try again") }
// TODO move upstream func intersection(s1 util.StringSet, s2 util.StringSet) util.StringSet { result := util.NewStringSet() for key := range s1 { if s2.Has(key) { result.Insert(key) } } return result }
func findKnownValue(parts []string, valueOptions util.StringSet) int { for i := range parts { if valueOptions.Has(parts[i]) { return i } } return -1 }
// purgeDeletedNamespaces will remove all namespaces enumerated in a reviewRecordStore that are not in the namespace set func purgeDeletedNamespaces(namespaceSet *util.StringSet, userSubjectRecordStore cache.Store, groupSubjectRecordStore cache.Store, reviewRecordStore cache.Store) { reviewRecordItems := reviewRecordStore.List() for i := range reviewRecordItems { reviewRecord := reviewRecordItems[i].(*reviewRecord) if !namespaceSet.Has(reviewRecord.namespace) { deleteNamespaceFromSubjects(userSubjectRecordStore, reviewRecord.users, reviewRecord.namespace) deleteNamespaceFromSubjects(groupSubjectRecordStore, reviewRecord.groups, reviewRecord.namespace) reviewRecordStore.Delete(reviewRecord) } } }
func TestOrphanBuildResolver(t *testing.T) { activeBuildConfig := mockBuildConfig("a", "active-build-config") inactiveBuildConfig := mockBuildConfig("a", "inactive-build-config") buildConfigs := []*buildapi.BuildConfig{activeBuildConfig} builds := []*buildapi.Build{} expectedNames := util.StringSet{} BuildPhaseOptions := []buildapi.BuildPhase{ buildapi.BuildPhaseCancelled, buildapi.BuildPhaseComplete, buildapi.BuildPhaseError, buildapi.BuildPhaseFailed, buildapi.BuildPhaseNew, buildapi.BuildPhasePending, buildapi.BuildPhaseRunning, } BuildPhaseFilter := []buildapi.BuildPhase{ buildapi.BuildPhaseCancelled, buildapi.BuildPhaseComplete, buildapi.BuildPhaseError, buildapi.BuildPhaseFailed, } BuildPhaseFilterSet := util.StringSet{} for _, BuildPhase := range BuildPhaseFilter { BuildPhaseFilterSet.Insert(string(BuildPhase)) } for _, BuildPhaseOption := range BuildPhaseOptions { builds = append(builds, withStatus(mockBuild("a", string(BuildPhaseOption)+"-active", activeBuildConfig), BuildPhaseOption)) builds = append(builds, withStatus(mockBuild("a", string(BuildPhaseOption)+"-inactive", inactiveBuildConfig), BuildPhaseOption)) builds = append(builds, withStatus(mockBuild("a", string(BuildPhaseOption)+"-orphan", nil), BuildPhaseOption)) if BuildPhaseFilterSet.Has(string(BuildPhaseOption)) { expectedNames.Insert(string(BuildPhaseOption) + "-inactive") expectedNames.Insert(string(BuildPhaseOption) + "-orphan") } } dataSet := NewDataSet(buildConfigs, builds) resolver := NewOrphanBuildResolver(dataSet, BuildPhaseFilter) results, err := resolver.Resolve() if err != nil { t.Errorf("Unexpected error %v", err) } foundNames := util.StringSet{} for _, result := range results { foundNames.Insert(result.Name) } if len(foundNames) != len(expectedNames) || !expectedNames.HasAll(foundNames.List()...) { t.Errorf("expected %v, actual %v", expectedNames, foundNames) } }
func doesApplyToUser(ruleUsers, ruleGroups util.StringSet, user user.Info) bool { if ruleUsers.Has(user.GetName()) { return true } for _, currGroup := range user.GetGroups() { if ruleGroups.Has(currGroup) { return true } } return false }
func computeStatus(statusList []*github.CombinedStatus, requiredContexts []string) string { states := util.StringSet{} providers := util.StringSet{} for ix := range statusList { status := statusList[ix] glog.V(8).Infof("Checking commit: %s", *status.SHA) glog.V(8).Infof("Checking commit: %v", status) states.Insert(*status.State) for _, subStatus := range status.Statuses { glog.V(8).Infof("Found status from: %v", subStatus) providers.Insert(*subStatus.Context) } } for _, provider := range requiredContexts { if !providers.Has(provider) { glog.V(8).Infof("Failed to find %s in %v", provider, providers) return "incomplete" } } switch { case states.Has("pending"): return "pending" case states.Has("error"): return "error" case states.Has("failure"): return "failure" default: return "success" } }
// Calls "udevadm trigger --action=change" for newly created "/dev/sd*" drives (exist only in after set). // This is workaround for Issue #7972. Once the underlying issue has been resolved, this may be removed. func udevadmChangeToNewDrives(sdBeforeSet util.StringSet) error { sdAfter, err := filepath.Glob(diskSDPattern) if err != nil { return fmt.Errorf("Error filepath.Glob(\"%s\"): %v\r\n", diskSDPattern, err) } for _, sd := range sdAfter { if !sdBeforeSet.Has(sd) { return udevadmChangeToDrive(sd) } } return nil }
func (r *TestRouter) FilterNamespaces(namespaces util.StringSet) { if len(namespaces) == 0 { r.State = make(map[string]ServiceUnit) } for k := range r.State { // TODO: the id of a service unit should be defined inside this class, not passed in from the outside // remove the leak of the abstraction when we refactor this code ns := strings.SplitN(k, "/", 2)[0] if namespaces.Has(ns) { continue } delete(r.State, k) } }
func getUniqueName(basename string, existingNames *util.StringSet) string { if !existingNames.Has(basename) { return basename } for i := 0; i < 100; i++ { trialName := fmt.Sprintf("%v-%d", basename, i) if !existingNames.Has(trialName) { return trialName } } return string(util.NewUUID()) }
func TestOrphanDeploymentResolver(t *testing.T) { activeDeploymentConfig := mockDeploymentConfig("a", "active-deployment-config") inactiveDeploymentConfig := mockDeploymentConfig("a", "inactive-deployment-config") deploymentConfigs := []*deployapi.DeploymentConfig{activeDeploymentConfig} deployments := []*kapi.ReplicationController{} expectedNames := util.StringSet{} deploymentStatusOptions := []deployapi.DeploymentStatus{ deployapi.DeploymentStatusComplete, deployapi.DeploymentStatusFailed, deployapi.DeploymentStatusNew, deployapi.DeploymentStatusPending, deployapi.DeploymentStatusRunning, } deploymentStatusFilter := []deployapi.DeploymentStatus{ deployapi.DeploymentStatusComplete, deployapi.DeploymentStatusFailed, } deploymentStatusFilterSet := util.StringSet{} for _, deploymentStatus := range deploymentStatusFilter { deploymentStatusFilterSet.Insert(string(deploymentStatus)) } for _, deploymentStatusOption := range deploymentStatusOptions { deployments = append(deployments, withStatus(mockDeployment("a", string(deploymentStatusOption)+"-active", activeDeploymentConfig), deploymentStatusOption)) deployments = append(deployments, withStatus(mockDeployment("a", string(deploymentStatusOption)+"-inactive", inactiveDeploymentConfig), deploymentStatusOption)) deployments = append(deployments, withStatus(mockDeployment("a", string(deploymentStatusOption)+"-orphan", nil), deploymentStatusOption)) if deploymentStatusFilterSet.Has(string(deploymentStatusOption)) { expectedNames.Insert(string(deploymentStatusOption) + "-inactive") expectedNames.Insert(string(deploymentStatusOption) + "-orphan") } } dataSet := NewDataSet(deploymentConfigs, deployments) resolver := NewOrphanDeploymentResolver(dataSet, deploymentStatusFilter) results, err := resolver.Resolve() if err != nil { t.Errorf("Unexpected error %v", err) } foundNames := util.StringSet{} for _, result := range results { foundNames.Insert(result.Name) } if len(foundNames) != len(expectedNames) || !expectedNames.HasAll(foundNames.List()...) { t.Errorf("expected %v, actual %v", expectedNames, foundNames) } }
func (g *conversionGenerator) RepackImports(exclude util.StringSet) { var packages []string for key := range g.imports { packages = append(packages, key) } sort.Strings(packages) g.imports = make(map[string]string) g.shortImports = make(map[string]string) g.targetPackage(g.targetPkg) for _, pkg := range packages { if !exclude.Has(pkg) { g.addImportByPath(pkg) } } }
func (o *NewGroupOptions) AddGroup() error { group := &userapi.Group{} group.Name = o.Group usedNames := util.StringSet{} for _, user := range o.Users { if usedNames.Has(user) { continue } usedNames.Insert(user) group.Users = append(group.Users, user) } _, err := o.GroupClient.Create(group) return err }
func ValidateThirdPartyResource(obj *expapi.ThirdPartyResource) errs.ValidationErrorList { allErrs := errs.ValidationErrorList{} if len(obj.Name) == 0 { allErrs = append(allErrs, errs.NewFieldInvalid("name", obj.Name, "name must be non-empty")) } versions := util.StringSet{} for ix := range obj.Versions { version := &obj.Versions[ix] if len(version.Name) == 0 { allErrs = append(allErrs, errs.NewFieldInvalid("name", version, "name can not be empty")) } if versions.Has(version.Name) { allErrs = append(allErrs, errs.NewFieldDuplicate("version", version)) } versions.Insert(version.Name) } return allErrs }
// HandleAllowedNamespaces limits the scope of valid routes to only those that match // the provided namespace list. func (p *UniqueHost) HandleNamespaces(namespaces util.StringSet) error { p.allowedNamespaces = namespaces changed := false for k, v := range p.hostToRoute { if namespaces.Has(v[0].Namespace) { continue } delete(p.hostToRoute, k) for i := range v { delete(p.routeToHost, routeNameKey(v[i])) } changed = true } if !changed && len(namespaces) > 0 { return nil } return p.plugin.HandleNamespaces(namespaces) }
// TestCreatesAllowedDuringNamespaceDeletion checks to make sure that the resources in the whitelist are allowed func TestCreatesAllowedDuringNamespaceDeletion(t *testing.T) { config := &origin.MasterConfig{ KubeletClientConfig: &kclient.KubeletConfig{}, EtcdHelper: etcdstorage.NewEtcdStorage(nil, nil, ""), } storageMap := config.GetRestStorage() resources := util.StringSet{} for resource := range storageMap { resources.Insert(strings.ToLower(resource)) } for resource := range recommendedCreatableResources { if !resources.Has(resource) { t.Errorf("recommendedCreatableResources has resource %v, but that resource isn't registered.", resource) } } }
// HandleAllowedNamespaces limits the scope of valid routes to only those that match // the provided namespace list. func (p *TemplatePlugin) HandleNamespaces(namespaces util.StringSet) error { p.allowedNamespaces = namespaces changed := false for k, v := range p.hostToRoute { if namespaces.Has(v[0].Namespace) { continue } delete(p.hostToRoute, k) for i := range v { delete(p.routeToHost, routeNameKey(v[i])) } changed = true } if !changed && len(namespaces) > 0 { return nil } p.Router.FilterNamespaces(namespaces) return p.Router.Commit() }
func selectContainer(pod *api.Pod, in io.Reader, out io.Writer) string { fmt.Fprintf(out, "Please select a container:\n") options := libutil.StringSet{} for ix := range pod.Spec.Containers { fmt.Fprintf(out, "[%d] %s\n", ix+1, pod.Spec.Containers[ix].Name) options.Insert(pod.Spec.Containers[ix].Name) } for { var input string fmt.Fprintf(out, "> ") fmt.Fscanln(in, &input) if options.Has(input) { return input } ix, err := strconv.Atoi(input) if err == nil && ix > 0 && ix <= len(pod.Spec.Containers) { return pod.Spec.Containers[ix-1].Name } fmt.Fprintf(out, "Invalid input: %s", input) } }
func NewDefaultRESTMapper(versions []string, interfacesFunc meta.VersionInterfacesFunc, importPathPrefix string, ignoredKinds, rootScoped util.StringSet) *meta.DefaultRESTMapper { mapper := meta.NewDefaultRESTMapper(versions, interfacesFunc) // enumerate all supported versions, get the kinds, and register with the mapper how to address our resources. for _, version := range versions { for kind, oType := range Scheme.KnownTypes(version) { // TODO: Remove import path prefix check. // We check the import path prefix because we currently stuff both "api" and "experimental" objects // into the same group within Scheme since Scheme has no notion of groups yet. if !strings.HasPrefix(oType.PkgPath(), importPathPrefix) || ignoredKinds.Has(kind) { continue } scope := meta.RESTScopeNamespace if rootScoped.Has(kind) { scope = meta.RESTScopeRoot } mapper.Add(scope, kind, version, false) } } return mapper }
func ExpandResources(rawResources kutil.StringSet) kutil.StringSet { ret := kutil.StringSet{} toVisit := rawResources.List() visited := kutil.StringSet{} for i := 0; i < len(toVisit); i++ { currResource := toVisit[i] if visited.Has(currResource) { continue } visited.Insert(currResource) if strings.Index(currResource, ResourceGroupPrefix+":") != 0 { ret.Insert(strings.ToLower(currResource)) continue } if resourceTypes, exists := GroupsToResources[currResource]; exists { toVisit = append(toVisit, resourceTypes...) } } return ret }
// NegotiateVersion queries the server's supported api versions to find // a version that both client and server support. // - If no version is provided, try registered client versions in order of // preference. // - If version is provided, but not default config (explicitly requested via // commandline flag), and is unsupported by the server, print a warning to // stderr and try client's registered versions in order of preference. // - If version is config default, and the server does not support it, // return an error. func NegotiateVersion(client *Client, c *Config, version string, clientRegisteredVersions []string) (string, error) { var err error if client == nil { client, err = New(c) if err != nil { return "", err } } clientVersions := util.StringSet{} for _, v := range clientRegisteredVersions { clientVersions.Insert(v) } apiVersions, err := client.ServerAPIVersions() if err != nil { return "", fmt.Errorf("couldn't read version from server: %v", err) } serverVersions := util.StringSet{} for _, v := range apiVersions.Versions { serverVersions.Insert(v) } // If no version requested, use config version (may also be empty). if len(version) == 0 { version = c.Version } // If version explicitly requested verify that both client and server support it. // If server does not support warn, but try to negotiate a lower version. if len(version) != 0 { if !clientVersions.Has(version) { return "", fmt.Errorf("Client does not support API version '%s'. Client supported API versions: %v", version, clientVersions) } if serverVersions.Has(version) { return version, nil } // If we are using an explicit config version the server does not support, fail. if version == c.Version { return "", fmt.Errorf("Server does not support API version '%s'.", version) } } for _, clientVersion := range clientRegisteredVersions { if serverVersions.Has(clientVersion) { // Version was not explicitly requested in command config (--api-version). // Ok to fall back to a supported version with a warning. if len(version) != 0 { glog.Warningf("Server does not support API version '%s'. Falling back to '%s'.", version, clientVersion) } return clientVersion, nil } } return "", fmt.Errorf("Failed to negotiate an api version. Server supports: %v. Client supports: %v.", serverVersions, clientRegisteredVersions) }
// For each PR in the project that matches: // * pr.Number > minPRNumber // * is mergeable // * has labels "cla: yes", "lgtm" // * combinedStatus = 'success' (e.g. all hooks have finished success in github) // Run the specified function func ForEachCandidatePRDo(client *github.Client, user, project string, fn PRFunction, once bool, config *FilterConfig) error { // Get all PRs prs, err := fetchAllPRs(client, user, project) if err != nil { return err } userSet := util.StringSet{} userSet.Insert(config.UserWhitelist...) for ix := range prs { if prs[ix].User == nil || prs[ix].User.Login == nil { glog.V(2).Infof("Skipping PR %d with no user info %v.", *prs[ix].Number, *prs[ix].User) continue } if *prs[ix].Number < config.MinPRNumber { glog.V(6).Infof("Dropping %d < %d", *prs[ix].Number, config.MinPRNumber) continue } pr, _, err := client.PullRequests.Get(user, project, *prs[ix].Number) if err != nil { glog.Errorf("Error getting pull request: %v", err) continue } glog.V(2).Infof("----==== %d ====----", *pr.Number) // Labels are actually stored in the Issues API, not the Pull Request API issue, _, err := client.Issues.Get(user, project, *pr.Number) if err != nil { glog.Errorf("Failed to get issue for PR: %v", err) continue } glog.V(8).Infof("%v", issue.Labels) if !hasLabels(issue.Labels, []string{"lgtm", "cla: yes"}) { continue } if !hasLabel(issue.Labels, config.WhitelistOverride) && !userSet.Has(*prs[ix].User.Login) { glog.V(4).Infof("Dropping %d since %s isn't in whitelist and %s isn't present", *prs[ix].Number, *prs[ix].User.Login, config.WhitelistOverride) continue } lastModifiedTime, err := lastModifiedTime(client, user, project, pr) if err != nil { glog.Errorf("Failed to get last modified time, skipping PR: %d", *pr.Number) continue } if ok, err := validateLGTMAfterPush(client, user, project, pr, lastModifiedTime); err != nil { glog.Errorf("Error validating LGTM: %v, Skipping: %d", err, *pr.Number) continue } else if !ok { glog.Errorf("PR pushed after LGTM, attempting to remove LGTM and skipping") staleLGTMBody := "LGTM was before last commit, removing LGTM" if _, _, err := client.Issues.CreateComment(user, project, *pr.Number, &github.IssueComment{Body: &staleLGTMBody}); err != nil { glog.Warningf("Failed to create remove label comment: %v", err) } if _, err := client.Issues.RemoveLabelForIssue(user, project, *pr.Number, "lgtm"); err != nil { glog.Warningf("Failed to remove 'lgtm' label for stale lgtm on %d", *pr.Number) } continue } // This is annoying, github appears to only temporarily cache mergeability, if it is nil, wait // for an async refresh and retry. if pr.Mergeable == nil { glog.Infof("Waiting for mergeability on %s %d", *pr.Title, *pr.Number) // TODO: determine what a good empirical setting for this is. time.Sleep(10 * time.Second) pr, _, err = client.PullRequests.Get(user, project, *prs[ix].Number) } if pr.Mergeable == nil { glog.Errorf("No mergeability information for %s %d, Skipping.", *pr.Title, *pr.Number) continue } if !*pr.Mergeable { continue } // Validate the status information for this PR ok, err := ValidateStatus(client, user, project, *pr.Number, config.RequiredStatusContexts, false) if err != nil { glog.Errorf("Error validating PR status: %v", err) continue } if !ok { continue } if err := fn(client, pr, issue); err != nil { glog.Errorf("Failed to run user function: %v", err) continue } if once { break } } return nil }
func (a DefaultAuthorizationAttributes) resourceMatches(allowedResourceTypes util.StringSet) bool { return allowedResourceTypes.Has(authorizationapi.ResourceAll) || allowedResourceTypes.Has(strings.ToLower(a.GetResource())) }
func (a DefaultAuthorizationAttributes) verbMatches(verbs util.StringSet) bool { return verbs.Has(authorizationapi.VerbAll) || verbs.Has(strings.ToLower(a.GetVerb())) }
// ExistingDirectEdge returns true if both head and tail already exist in the graph and the edge kind is // not ReferencedByEdgeKind (the generic reverse edge kind). This will purge the graph of any // edges created by AddReversedEdge. func ExistingDirectEdge(g Interface, head, tail graph.Node, edgeKinds util.StringSet) bool { return !edgeKinds.Has(ReferencedByEdgeKind) && g.Has(head) && g.Has(tail) }
func TestAddDeploymentHash(t *testing.T) { buf := &bytes.Buffer{} codec := testapi.Codec() rc := &api.ReplicationController{ ObjectMeta: api.ObjectMeta{Name: "rc"}, Spec: api.ReplicationControllerSpec{ Selector: map[string]string{ "foo": "bar", }, Template: &api.PodTemplateSpec{ ObjectMeta: api.ObjectMeta{ Labels: map[string]string{ "foo": "bar", }, }, }, }, } podList := &api.PodList{ Items: []api.Pod{ {ObjectMeta: api.ObjectMeta{Name: "foo"}}, {ObjectMeta: api.ObjectMeta{Name: "bar"}}, {ObjectMeta: api.ObjectMeta{Name: "baz"}}, }, } seen := util.StringSet{} updatedRc := false fakeClient := &client.FakeRESTClient{ Codec: codec, Client: client.HTTPClientFunc(func(req *http.Request) (*http.Response, error) { switch p, m := req.URL.Path, req.Method; { case p == testapi.ResourcePath("pods", "default", "") && m == "GET": if req.URL.RawQuery != "labelSelector=foo%3Dbar" { t.Errorf("Unexpected query string: %s", req.URL.RawQuery) } return &http.Response{StatusCode: 200, Body: objBody(codec, podList)}, nil case p == testapi.ResourcePath("pods", "default", "foo") && m == "PUT": seen.Insert("foo") obj := readOrDie(t, req, codec) podList.Items[0] = *(obj.(*api.Pod)) return &http.Response{StatusCode: 200, Body: objBody(codec, &podList.Items[0])}, nil case p == testapi.ResourcePath("pods", "default", "bar") && m == "PUT": seen.Insert("bar") obj := readOrDie(t, req, codec) podList.Items[1] = *(obj.(*api.Pod)) return &http.Response{StatusCode: 200, Body: objBody(codec, &podList.Items[1])}, nil case p == testapi.ResourcePath("pods", "default", "baz") && m == "PUT": seen.Insert("baz") obj := readOrDie(t, req, codec) podList.Items[2] = *(obj.(*api.Pod)) return &http.Response{StatusCode: 200, Body: objBody(codec, &podList.Items[2])}, nil case p == testapi.ResourcePath("replicationcontrollers", "default", "rc") && m == "PUT": updatedRc = true return &http.Response{StatusCode: 200, Body: objBody(codec, rc)}, nil default: t.Fatalf("unexpected request: %#v\n%#v", req.URL, req) return nil, nil } }), } clientConfig := &client.Config{Version: testapi.Version()} client := client.NewOrDie(clientConfig) client.Client = fakeClient.Client if _, err := AddDeploymentKeyToReplicationController(rc, client, "dk", "hash", api.NamespaceDefault, buf); err != nil { t.Errorf("unexpected error: %v", err) } for _, pod := range podList.Items { if !seen.Has(pod.Name) { t.Errorf("Missing update for pod: %s", pod.Name) } } if !updatedRc { t.Errorf("Failed to update replication controller with new labels") } }
// Discover the projects available for the established session and take one to use. It // fails in case of no existing projects, and print out useful information in case of // multiple projects. // Requires o.Username to be set. func (o *LoginOptions) gatherProjectInfo() error { me, err := o.whoAmI() if err != nil { return err } if o.Username != me.Name { return fmt.Errorf("current user, %v, does not match expected user %v", me.Name, o.Username) } oClient, err := client.New(o.Config) if err != nil { return err } projects, err := oClient.Projects().List(labels.Everything(), fields.Everything()) if err != nil { return err } projectsItems := projects.Items switch len(projectsItems) { case 0: fmt.Fprintf(o.Out, `You don't have any projects. You can try to create a new project, by running $ oc new-project <projectname> `) o.Project = o.DefaultNamespace case 1: o.Project = projectsItems[0].Name fmt.Fprintf(o.Out, "Using project %q.\n", o.Project) default: projects := util.StringSet{} for _, project := range projectsItems { projects.Insert(project.Name) } namespace := o.DefaultNamespace if !projects.Has(namespace) { if namespace != kapi.NamespaceDefault && projects.Has(kapi.NamespaceDefault) { namespace = kapi.NamespaceDefault } else { namespace = projects.List()[0] } } if current, err := oClient.Projects().Get(namespace); err == nil { o.Project = current.Name fmt.Fprintf(o.Out, "Using project %q.\n", o.Project) } else if !kerrors.IsNotFound(err) && !clientcmd.IsForbidden(err) { return err } fmt.Fprintf(o.Out, "\nYou have access to the following projects and can switch between them with 'oc project <projectname>':\n\n") for _, p := range projects.List() { if o.Project == p { fmt.Fprintf(o.Out, " * %s (current)\n", p) } else { fmt.Fprintf(o.Out, " * %s\n", p) } } fmt.Fprintln(o.Out) } return nil }