示例#1
0
// Describe returns the description of a project
func (d *ProjectStatusDescriber) Describe(namespace, name string) (string, error) {
	var f formatter = namespacedFormatter{}

	g, forbiddenResources, err := d.MakeGraph(namespace)
	if err != nil {
		return "", err
	}

	allNamespaces := namespace == kapi.NamespaceAll
	var project *projectapi.Project
	if !allNamespaces {
		p, err := d.C.Projects().Get(namespace)
		if err != nil {
			return "", err
		}
		project = p
		f = namespacedFormatter{currentNamespace: namespace}
	}

	coveredNodes := graphview.IntSet{}

	services, coveredByServices := graphview.AllServiceGroups(g, coveredNodes)
	coveredNodes.Insert(coveredByServices.List()...)

	standaloneDCs, coveredByDCs := graphview.AllDeploymentConfigPipelines(g, coveredNodes)
	coveredNodes.Insert(coveredByDCs.List()...)

	standaloneRCs, coveredByRCs := graphview.AllReplicationControllers(g, coveredNodes)
	coveredNodes.Insert(coveredByRCs.List()...)

	standaloneImages, coveredByImages := graphview.AllImagePipelinesFromBuildConfig(g, coveredNodes)
	coveredNodes.Insert(coveredByImages.List()...)

	standalonePods, coveredByPods := graphview.AllPods(g, coveredNodes)
	coveredNodes.Insert(coveredByPods.List()...)

	return tabbedString(func(out *tabwriter.Writer) error {
		indent := "  "
		if allNamespaces {
			fmt.Fprintf(out, describeAllProjectsOnServer(f, d.Server))
		} else {
			fmt.Fprintf(out, describeProjectAndServer(f, project, d.Server))
		}

		for _, service := range services {
			if !service.Service.Found() {
				continue
			}
			local := namespacedFormatter{currentNamespace: service.Service.Namespace}

			var exposes []string
			for _, routeNode := range service.ExposingRoutes {
				exposes = append(exposes, describeRouteInServiceGroup(local, routeNode)...)
			}
			sort.Sort(exposedRoutes(exposes))

			fmt.Fprintln(out)
			printLines(out, "", 0, describeServiceInServiceGroup(f, service, exposes...)...)

			for _, dcPipeline := range service.DeploymentConfigPipelines {
				printLines(out, indent, 1, describeDeploymentInServiceGroup(local, dcPipeline)...)
			}

		rcNode:
			for _, rcNode := range service.FulfillingRCs {
				for _, coveredDC := range service.FulfillingDCs {
					if deployedges.BelongsToDeploymentConfig(coveredDC.DeploymentConfig, rcNode.ReplicationController) {
						continue rcNode
					}
				}
				printLines(out, indent, 1, describeRCInServiceGroup(local, rcNode)...)
			}

		pod:
			for _, podNode := range service.FulfillingPods {
				// skip pods that have been displayed in a roll-up of RCs and DCs (by implicit usage of RCs)
				for _, coveredRC := range service.FulfillingRCs {
					if g.Edge(podNode, coveredRC) != nil {
						continue pod
					}
				}
				printLines(out, indent, 1, describePodInServiceGroup(local, podNode)...)
			}
		}

		for _, standaloneDC := range standaloneDCs {
			fmt.Fprintln(out)
			printLines(out, indent, 0, describeDeploymentInServiceGroup(f, standaloneDC)...)
		}

		for _, standaloneImage := range standaloneImages {
			fmt.Fprintln(out)
			lines := describeStandaloneBuildGroup(f, standaloneImage, namespace)
			lines = append(lines, describeAdditionalBuildDetail(standaloneImage.Build, standaloneImage.LastSuccessfulBuild, standaloneImage.LastUnsuccessfulBuild, standaloneImage.ActiveBuilds, standaloneImage.DestinationResolved, true)...)
			printLines(out, indent, 0, lines...)
		}

		for _, standaloneRC := range standaloneRCs {
			fmt.Fprintln(out)
			printLines(out, indent, 0, describeRCInServiceGroup(f, standaloneRC.RC)...)
		}

		monopods, err := filterBoringPods(standalonePods)
		if err != nil {
			return err
		}
		for _, monopod := range monopods {
			fmt.Fprintln(out)
			printLines(out, indent, 0, describeMonopod(f, monopod.Pod)...)
		}

		allMarkers := osgraph.Markers{}
		allMarkers = append(allMarkers, createForbiddenMarkers(forbiddenResources)...)
		for _, scanner := range getMarkerScanners(d.LogsCommandName, d.SecurityPolicyCommandFormat, d.SetProbeCommandName) {
			allMarkers = append(allMarkers, scanner(g, f)...)
		}

		// TODO: Provide an option to chase these hidden markers.
		allMarkers = allMarkers.FilterByNamespace(namespace)

		fmt.Fprintln(out)

		sort.Stable(osgraph.ByKey(allMarkers))
		sort.Stable(osgraph.ByNodeID(allMarkers))

		errorMarkers := allMarkers.BySeverity(osgraph.ErrorSeverity)
		errorSuggestions := 0
		if len(errorMarkers) > 0 {
			fmt.Fprintln(out, "Errors:")
			for _, marker := range errorMarkers {
				fmt.Fprintln(out, indent+"* "+marker.Message)
				if len(marker.Suggestion) > 0 {
					errorSuggestions++
					if d.Suggest {
						switch s := marker.Suggestion.String(); {
						case strings.Contains(s, "\n"):
							fmt.Fprintln(out)
							for _, line := range strings.Split(s, "\n") {
								fmt.Fprintln(out, indent+"  "+line)
							}
						case len(s) > 0:
							fmt.Fprintln(out, indent+"  try: "+s)
						}
					}
				}
			}
		}

		warningMarkers := allMarkers.BySeverity(osgraph.WarningSeverity)
		if len(warningMarkers) > 0 {
			if d.Suggest {
				fmt.Fprintln(out, "Warnings:")
			}
			for _, marker := range warningMarkers {
				if d.Suggest {
					fmt.Fprintln(out, indent+"* "+marker.Message)
					switch s := marker.Suggestion.String(); {
					case strings.Contains(s, "\n"):
						fmt.Fprintln(out)
						for _, line := range strings.Split(s, "\n") {
							fmt.Fprintln(out, indent+"  "+line)
						}
					case len(s) > 0:
						fmt.Fprintln(out, indent+"  try: "+s)
					}
				}
			}
		}

		// We print errors by default and warnings if -v is used. If we get none,
		// this would be an extra new line.
		if len(errorMarkers) != 0 || (d.Suggest && len(warningMarkers) != 0) {
			fmt.Fprintln(out)
		}

		errors, warnings := "", ""
		if len(errorMarkers) == 1 {
			errors = "1 error"
		} else if len(errorMarkers) > 1 {
			errors = fmt.Sprintf("%d errors", len(errorMarkers))
		}
		if len(warningMarkers) == 1 {
			warnings = "1 warning"
		} else if len(warningMarkers) > 1 {
			warnings = fmt.Sprintf("%d warnings", len(warningMarkers))
		}

		switch {
		case !d.Suggest && len(errorMarkers) > 0 && len(warningMarkers) > 0:
			fmt.Fprintf(out, "%s and %s identified, use 'oc status -v' to see details.\n", errors, warnings)

		case !d.Suggest && len(errorMarkers) > 0 && errorSuggestions > 0:
			fmt.Fprintf(out, "%s identified, use 'oc status -v' to see details.\n", errors)

		case !d.Suggest && len(warningMarkers) > 0:
			fmt.Fprintf(out, "%s identified, use 'oc status -v' to see details.\n", warnings)

		case (len(services) == 0) && (len(standaloneDCs) == 0) && (len(standaloneImages) == 0):
			fmt.Fprintln(out, "You have no services, deployment configs, or build configs.")
			fmt.Fprintln(out, "Run 'oc new-app' to create an application.")

		default:
			fmt.Fprintln(out, "View details with 'oc describe <resource>/<name>' or list everything with 'oc get all'.")
		}

		return nil
	})
}
示例#2
0
// Describe returns the description of a project
func (d *ProjectStatusDescriber) Describe(namespace, name string) (string, error) {
	g, err := d.MakeGraph(namespace)
	if err != nil {
		return "", err
	}

	project, err := d.C.Projects().Get(namespace)
	if err != nil {
		return "", err
	}

	coveredNodes := graphview.IntSet{}

	services, coveredByServices := graphview.AllServiceGroups(g, coveredNodes)
	coveredNodes.Insert(coveredByServices.List()...)

	standaloneDCs, coveredByDCs := graphview.AllDeploymentConfigPipelines(g, coveredNodes)
	coveredNodes.Insert(coveredByDCs.List()...)

	standaloneRCs, coveredByRCs := graphview.AllReplicationControllers(g, coveredNodes)
	coveredNodes.Insert(coveredByRCs.List()...)

	standaloneImages, coveredByImages := graphview.AllImagePipelinesFromBuildConfig(g, coveredNodes)
	coveredNodes.Insert(coveredByImages.List()...)

	return tabbedString(func(out *tabwriter.Writer) error {
		indent := "  "
		fmt.Fprintf(out, "In project %s\n", projectapi.DisplayNameAndNameForProject(project))

		for _, service := range services {
			fmt.Fprintln(out)
			printLines(out, indent, 0, describeServiceInServiceGroup(service)...)

			for _, dcPipeline := range service.DeploymentConfigPipelines {
				printLines(out, indent, 1, describeDeploymentInServiceGroup(dcPipeline)...)
			}

		rcNode:
			for _, rcNode := range service.FulfillingRCs {
				for _, coveredDC := range service.FulfillingDCs {
					if deployedges.BelongsToDeploymentConfig(coveredDC.DeploymentConfig, rcNode.ReplicationController) {
						continue rcNode
					}
				}
				printLines(out, indent, 1, describeRCInServiceGroup(rcNode)...)
			}

		pod:
			for _, podNode := range service.FulfillingPods {
				// skip pods that have been displayed in a roll-up of RCs and DCs (by implicit usage of RCs)
				for _, coveredRC := range service.FulfillingRCs {
					if g.EdgeBetween(podNode, coveredRC) != nil {
						continue pod
					}
				}
				printLines(out, indent, 1, describePodInServiceGroup(podNode)...)
			}
		}

		for _, standaloneDC := range standaloneDCs {
			fmt.Fprintln(out)
			printLines(out, indent, 0, describeDeploymentInServiceGroup(standaloneDC)...)
		}

		for _, standaloneImage := range standaloneImages {
			fmt.Fprintln(out)
			printLines(out, indent, 0, describeStandaloneBuildGroup(standaloneImage, namespace)...)
			printLines(out, indent, 1, describeAdditionalBuildDetail(standaloneImage.Build, standaloneImage.LastSuccessfulBuild, standaloneImage.LastUnsuccessfulBuild, standaloneImage.ActiveBuilds, standaloneImage.DestinationResolved, true)...)
		}

		for _, standaloneRC := range standaloneRCs {
			fmt.Fprintln(out)
			printLines(out, indent, 0, describeRCInServiceGroup(standaloneRC.RC)...)
		}

		if (len(services) == 0) && (len(standaloneDCs) == 0) && (len(standaloneImages) == 0) {
			fmt.Fprintln(out)
			fmt.Fprintln(out, "You have no services, deployment configs, or build configs.")
			fmt.Fprintln(out, "Run 'oc new-app' to create an application.")

		} else {
			fmt.Fprintln(out)

			if hasUnresolvedImageStreamTag(g) {
				fmt.Fprintln(out, "Warning: Some of your builds are pointing to image streams, but the administrator has not configured the integrated Docker registry (oadm registry).")
			}
			if lines, _ := describeBadPodSpecs(out, g); len(lines) > 0 {
				fmt.Fprintln(out, strings.Join(lines, "\n"))
			}

			fmt.Fprintln(out, "To see more, use 'oc describe service <name>' or 'oc describe dc <name>'.")
			fmt.Fprintln(out, "You can use 'oc get all' to see a list of other objects.")
		}

		return nil
	})
}
示例#3
0
// Describe returns the description of a project
func (d *ProjectStatusDescriber) Describe(namespace, name string) (string, error) {
	g, err := d.MakeGraph(namespace)
	if err != nil {
		return "", err
	}

	project, err := d.C.Projects().Get(namespace)
	if err != nil {
		return "", err
	}

	coveredNodes := graphview.IntSet{}

	services, coveredByServices := graphview.AllServiceGroups(g, coveredNodes)
	coveredNodes.Insert(coveredByServices.List()...)

	standaloneDCs, coveredByDCs := graphview.AllDeploymentConfigPipelines(g, coveredNodes)
	coveredNodes.Insert(coveredByDCs.List()...)

	standaloneRCs, coveredByRCs := graphview.AllReplicationControllers(g, coveredNodes)
	coveredNodes.Insert(coveredByRCs.List()...)

	standaloneImages, coveredByImages := graphview.AllImagePipelinesFromBuildConfig(g, coveredNodes)
	coveredNodes.Insert(coveredByImages.List()...)

	return tabbedString(func(out *tabwriter.Writer) error {
		indent := "  "
		fmt.Fprintf(out, "In project %s\n", projectapi.DisplayNameAndNameForProject(project))

		for _, service := range services {
			fmt.Fprintln(out)
			printLines(out, indent, 0, describeServiceInServiceGroup(service)...)

			for _, dcPipeline := range service.DeploymentConfigPipelines {
				printLines(out, indent, 1, describeDeploymentInServiceGroup(dcPipeline)...)
			}

		rcNode:
			for _, rcNode := range service.FulfillingRCs {
				for _, coveredDC := range service.FulfillingDCs {
					if deployedges.BelongsToDeploymentConfig(coveredDC.DeploymentConfig, rcNode.ReplicationController) {
						continue rcNode
					}
				}
				printLines(out, indent, 1, describeRCInServiceGroup(rcNode)...)
			}

		pod:
			for _, podNode := range service.FulfillingPods {
				// skip pods that have been displayed in a roll-up of RCs and DCs (by implicit usage of RCs)
				for _, coveredRC := range service.FulfillingRCs {
					if g.Edge(podNode, coveredRC) != nil {
						continue pod
					}
				}
				printLines(out, indent, 1, describePodInServiceGroup(podNode)...)
			}
		}

		for _, standaloneDC := range standaloneDCs {
			fmt.Fprintln(out)
			printLines(out, indent, 0, describeDeploymentInServiceGroup(standaloneDC)...)
		}

		for _, standaloneImage := range standaloneImages {
			fmt.Fprintln(out)
			printLines(out, indent, 0, describeStandaloneBuildGroup(standaloneImage, namespace)...)
			printLines(out, indent, 1, describeAdditionalBuildDetail(standaloneImage.Build, standaloneImage.LastSuccessfulBuild, standaloneImage.LastUnsuccessfulBuild, standaloneImage.ActiveBuilds, standaloneImage.DestinationResolved, true)...)
		}

		for _, standaloneRC := range standaloneRCs {
			fmt.Fprintln(out)
			printLines(out, indent, 0, describeRCInServiceGroup(standaloneRC.RC)...)
		}

		// always output warnings
		fmt.Fprintln(out)

		allMarkers := osgraph.Markers{}
		for _, scanner := range getMarkerScanners() {
			allMarkers = append(allMarkers, scanner(g)...)
		}
		sort.Stable(osgraph.ByKey(allMarkers))
		sort.Stable(osgraph.ByNodeID(allMarkers))
		if errorMarkers := allMarkers.BySeverity(osgraph.ErrorSeverity); len(errorMarkers) > 0 {
			fmt.Fprintln(out, "Errors:")
			for _, marker := range errorMarkers {
				fmt.Fprintln(out, indent+marker.Message)
			}
		}
		if warningMarkers := allMarkers.BySeverity(osgraph.WarningSeverity); len(warningMarkers) > 0 {
			fmt.Fprintln(out, "Warnings:")
			for _, marker := range warningMarkers {
				fmt.Fprintln(out, indent+marker.Message)
			}
		}

		if (len(services) == 0) && (len(standaloneDCs) == 0) && (len(standaloneImages) == 0) {
			fmt.Fprintln(out, "You have no services, deployment configs, or build configs.")
			fmt.Fprintln(out, "Run 'oc new-app' to create an application.")

		} else {
			fmt.Fprintln(out, "To see more, use 'oc describe service <name>' or 'oc describe dc <name>'.")
			fmt.Fprintln(out, "You can use 'oc get all' to see a list of other objects.")
		}

		return nil
	})
}
示例#4
0
// Describe returns the description of a project
func (d *ProjectStatusDescriber) Describe(namespace, name string) (string, error) {
	g, forbiddenResources, err := d.MakeGraph(namespace)
	if err != nil {
		return "", err
	}

	project, err := d.C.Projects().Get(namespace)
	if err != nil {
		return "", err
	}

	coveredNodes := graphview.IntSet{}

	services, coveredByServices := graphview.AllServiceGroups(g, coveredNodes)
	coveredNodes.Insert(coveredByServices.List()...)

	standaloneDCs, coveredByDCs := graphview.AllDeploymentConfigPipelines(g, coveredNodes)
	coveredNodes.Insert(coveredByDCs.List()...)

	standaloneRCs, coveredByRCs := graphview.AllReplicationControllers(g, coveredNodes)
	coveredNodes.Insert(coveredByRCs.List()...)

	standaloneImages, coveredByImages := graphview.AllImagePipelinesFromBuildConfig(g, coveredNodes)
	coveredNodes.Insert(coveredByImages.List()...)

	return tabbedString(func(out *tabwriter.Writer) error {
		indent := "  "
		fmt.Fprintf(out, describeProjectAndServer(project, d.Server))

		for _, service := range services {
			if !service.Service.Found() {
				continue
			}

			fmt.Fprintln(out)
			printLines(out, indent, 0, describeServiceInServiceGroup(service)...)

			for _, dcPipeline := range service.DeploymentConfigPipelines {
				printLines(out, indent, 1, describeDeploymentInServiceGroup(dcPipeline)...)
			}

		rcNode:
			for _, rcNode := range service.FulfillingRCs {
				for _, coveredDC := range service.FulfillingDCs {
					if deployedges.BelongsToDeploymentConfig(coveredDC.DeploymentConfig, rcNode.ReplicationController) {
						continue rcNode
					}
				}
				printLines(out, indent, 1, describeRCInServiceGroup(rcNode)...)
			}

		pod:
			for _, podNode := range service.FulfillingPods {
				// skip pods that have been displayed in a roll-up of RCs and DCs (by implicit usage of RCs)
				for _, coveredRC := range service.FulfillingRCs {
					if g.Edge(podNode, coveredRC) != nil {
						continue pod
					}
				}
				printLines(out, indent, 1, describePodInServiceGroup(podNode)...)
			}

			for _, routeNode := range service.ExposingRoutes {
				printLines(out, indent, 1, describeRouteInServiceGroup(routeNode)...)
			}
		}

		for _, standaloneDC := range standaloneDCs {
			fmt.Fprintln(out)
			printLines(out, indent, 0, describeDeploymentInServiceGroup(standaloneDC)...)
		}

		for _, standaloneImage := range standaloneImages {
			fmt.Fprintln(out)
			lines := describeStandaloneBuildGroup(standaloneImage, namespace)
			lines = append(lines, describeAdditionalBuildDetail(standaloneImage.Build, standaloneImage.LastSuccessfulBuild, standaloneImage.LastUnsuccessfulBuild, standaloneImage.ActiveBuilds, standaloneImage.DestinationResolved, true)...)
			printLines(out, indent, 0, lines...)
		}

		for _, standaloneRC := range standaloneRCs {
			fmt.Fprintln(out)
			printLines(out, indent, 0, describeRCInServiceGroup(standaloneRC.RC)...)
		}

		allMarkers := osgraph.Markers{}
		allMarkers = append(allMarkers, createForbiddenMarkers(forbiddenResources)...)
		for _, scanner := range getMarkerScanners() {
			allMarkers = append(allMarkers, scanner(g)...)
		}

		fmt.Fprintln(out)

		sort.Stable(osgraph.ByKey(allMarkers))
		sort.Stable(osgraph.ByNodeID(allMarkers))

		errorMarkers := allMarkers.BySeverity(osgraph.ErrorSeverity)
		errorSuggestions := 0
		if len(errorMarkers) > 0 {
			fmt.Fprintln(out, "Errors:")
			for _, marker := range errorMarkers {
				fmt.Fprintln(out, indent+"* "+marker.Message)
				if len(marker.Suggestion) > 0 {
					errorSuggestions++
					if d.Suggest {
						fmt.Fprintln(out, indent+"  "+marker.Suggestion.String())
					}
				}
			}
		}

		warningMarkers := allMarkers.BySeverity(osgraph.WarningSeverity)
		if len(warningMarkers) > 0 {
			if d.Suggest {
				fmt.Fprintln(out, "Warnings:")
			}
			for _, marker := range warningMarkers {
				if d.Suggest {
					fmt.Fprintln(out, indent+"* "+marker.Message)
					if len(marker.Suggestion) > 0 {
						fmt.Fprintln(out, indent+"  "+marker.Suggestion.String())
					}
				}
			}
		}

		// We print errors by default and warnings if -v is used. If we get none,
		// this would be an extra new line.
		if len(errorMarkers) != 0 || (d.Suggest && len(warningMarkers) != 0) {
			fmt.Fprintln(out)
		}

		errors, warnings := "", ""
		if len(errorMarkers) == 1 {
			errors = "1 error"
		} else if len(errorMarkers) > 1 {
			errors = fmt.Sprintf("%d errors", len(errorMarkers))
		}
		if len(warningMarkers) == 1 {
			warnings = "1 warning"
		} else if len(warningMarkers) > 1 {
			warnings = fmt.Sprintf("%d warnings", len(warningMarkers))
		}

		switch {
		case !d.Suggest && len(errorMarkers) > 0 && len(warningMarkers) > 0:
			fmt.Fprintf(out, "%s and %s identified, use 'oc status -v' to see details.\n", errors, warnings)

		case !d.Suggest && len(errorMarkers) > 0 && errorSuggestions > 0:
			fmt.Fprintf(out, "%s identified, use 'oc status -v' to see details.\n", errors)

		case !d.Suggest && len(warningMarkers) > 0:
			fmt.Fprintf(out, "%s identified, use 'oc status -v' to see details.\n", warnings)

		case (len(services) == 0) && (len(standaloneDCs) == 0) && (len(standaloneImages) == 0):
			fmt.Fprintln(out, "You have no services, deployment configs, or build configs.")
			fmt.Fprintln(out, "Run 'oc new-app' to create an application.")

		default:
			fmt.Fprintln(out, "View details with 'oc describe <resource>/<name>' or list everything with 'oc get all'.")
		}

		return nil
	})
}