(ports []cni.PortMapping)
| 120 | } |
| 121 | |
| 122 | func FormatPorts(ports []cni.PortMapping) string { |
| 123 | if len(ports) == 0 { |
| 124 | return "" |
| 125 | } |
| 126 | |
| 127 | type key struct { |
| 128 | HostIP string |
| 129 | Protocol string |
| 130 | } |
| 131 | grouped := make(map[key][]cni.PortMapping) |
| 132 | |
| 133 | for _, p := range ports { |
| 134 | k := key{HostIP: p.HostIP, Protocol: p.Protocol} |
| 135 | grouped[k] = append(grouped[k], p) |
| 136 | } |
| 137 | |
| 138 | var displayPorts []string |
| 139 | for k, pms := range grouped { |
| 140 | sort.Slice(pms, func(i, j int) bool { |
| 141 | return pms[i].HostPort < pms[j].HostPort |
| 142 | }) |
| 143 | |
| 144 | var i int |
| 145 | var ranges []string |
| 146 | for i = 0; i < len(pms); { |
| 147 | start, end := pms[i], pms[i] |
| 148 | for i+1 < len(pms) && |
| 149 | pms[i+1].HostPort == end.HostPort+1 && |
| 150 | pms[i+1].ContainerPort == end.ContainerPort+1 { |
| 151 | i++ |
| 152 | end = pms[i] |
| 153 | } |
| 154 | |
| 155 | ranges = append( |
| 156 | ranges, |
| 157 | formatRange(start.HostPort, end.HostPort, start.ContainerPort, end.ContainerPort), |
| 158 | ) |
| 159 | i++ |
| 160 | } |
| 161 | displayPorts = append( |
| 162 | displayPorts, |
| 163 | fmt.Sprintf("%s:%s/%s", k.HostIP, strings.Join(ranges, ", "), k.Protocol), |
| 164 | ) |
| 165 | } |
| 166 | |
| 167 | sort.Strings(displayPorts) |
| 168 | |
| 169 | return strings.Join(displayPorts, ", ") |
| 170 | } |
| 171 | |
| 172 | func TimeSinceInHuman(since time.Time) string { |
| 173 | return fmt.Sprintf("%s ago", units.HumanDuration(time.Since(since))) |
searching dependent graphs…