forked from linki/chaoskube
-
Notifications
You must be signed in to change notification settings - Fork 0
/
util.go
141 lines (117 loc) · 3.68 KB
/
util.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
package util
import (
"fmt"
"strings"
"time"
"k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
const (
// a short time format; like time.Kitchen but with 24-hour notation.
Kitchen24 = "15:04"
// a time format that just cares about the day and month.
YearDay = "Jan_2"
)
// TimePeriod represents a time period with a single beginning and end.
type TimePeriod struct {
From time.Time
To time.Time
}
// NewTimePeriod returns a normalized TimePeriod given a start and end time.
func NewTimePeriod(from, to time.Time) TimePeriod {
return TimePeriod{From: TimeOfDay(from), To: TimeOfDay(to)}
}
// Includes returns true iff the given pointInTime's time of day is included in time period tp.
func (tp TimePeriod) Includes(pointInTime time.Time) bool {
isAfter := TimeOfDay(pointInTime).After(tp.From)
isBefore := TimeOfDay(pointInTime).Before(tp.To)
if tp.From.Before(tp.To) {
return isAfter && isBefore
}
if tp.From.After(tp.To) {
return isAfter || isBefore
}
return TimeOfDay(pointInTime).Equal(tp.From)
}
// String returns tp as a pretty string.
func (tp TimePeriod) String() string {
return fmt.Sprintf("%s-%s", tp.From.Format(Kitchen24), tp.To.Format(Kitchen24))
}
// ParseWeekdays takes a comma-separated list of abbreviated weekdays (e.g. sat,sun) and turns them
// into a slice of time.Weekday. It ignores any whitespace and any invalid weekdays.
func ParseWeekdays(weekdays string) []time.Weekday {
var days = map[string]time.Weekday{
"sun": time.Sunday,
"mon": time.Monday,
"tue": time.Tuesday,
"wed": time.Wednesday,
"thu": time.Thursday,
"fri": time.Friday,
"sat": time.Saturday,
}
parsedWeekdays := []time.Weekday{}
for _, wd := range strings.Split(weekdays, ",") {
if day, ok := days[strings.TrimSpace(strings.ToLower(wd))]; ok {
parsedWeekdays = append(parsedWeekdays, day)
}
}
return parsedWeekdays
}
// ParseTimePeriods takes a comma-separated list of time periods in Kitchen24 format and turns them
// into a slice of TimePeriods. It ignores any whitespace.
func ParseTimePeriods(timePeriods string) ([]TimePeriod, error) {
parsedTimePeriods := []TimePeriod{}
for _, tp := range strings.Split(timePeriods, ",") {
if strings.TrimSpace(tp) == "" {
continue
}
parts := strings.Split(tp, "-")
if len(parts) != 2 {
return nil, fmt.Errorf("Invalid time range '%v': must contain exactly one '-'", tp)
}
begin, err := time.Parse(Kitchen24, strings.TrimSpace(parts[0]))
if err != nil {
return nil, err
}
end, err := time.Parse(Kitchen24, strings.TrimSpace(parts[1]))
if err != nil {
return nil, err
}
parsedTimePeriods = append(parsedTimePeriods, NewTimePeriod(begin, end))
}
return parsedTimePeriods, nil
}
func ParseDays(days string) ([]time.Time, error) {
parsedDays := []time.Time{}
for _, day := range strings.Split(days, ",") {
if strings.TrimSpace(day) == "" {
continue
}
parsedDay, err := time.Parse(YearDay, strings.TrimSpace(day))
if err != nil {
return nil, err
}
parsedDays = append(parsedDays, parsedDay)
}
return parsedDays, nil
}
// TimeOfDay normalizes the given point in time by returning a time object that represents the same
// time of day of the given time but on the very first day (day 0).
func TimeOfDay(pointInTime time.Time) time.Time {
return time.Date(0, 0, 0, pointInTime.Hour(), pointInTime.Minute(), pointInTime.Second(), pointInTime.Nanosecond(), time.UTC)
}
// NewPod returns a new pod instance for testing purposes.
func NewPod(namespace, name string) v1.Pod {
return v1.Pod{
ObjectMeta: metav1.ObjectMeta{
Namespace: namespace,
Name: name,
Labels: map[string]string{
"app": name,
},
Annotations: map[string]string{
"chaos": name,
},
},
}
}