* Add Virtual Kubelet provider for VIC Initial virtual kubelet provider for VMware VIC. This provider currently handles creating and starting of a pod VM via the VIC portlayer and persona server. Image store handling via the VIC persona server. This provider currently requires the feature/wolfpack branch of VIC. * Added pod stop and delete. Also added node capacity. Added the ability to stop and delete pod VMs via VIC. Also retrieve node capacity information from the VCH. * Cleanup and readme file Some file clean up and added a Readme.md markdown file for the VIC provider. * Cleaned up errors, added function comments, moved operation code 1. Cleaned up error handling. Set standard for creating errors. 2. Added method prototype comments for all interface functions. 3. Moved PodCreator, PodStarter, PodStopper, and PodDeleter to a new folder. * Add mocking code and unit tests for podcache, podcreator, and podstarter Used the unit test framework used in VIC to handle assertions in the provider's unit test. Mocking code generated using OSS project mockery, which is compatible with the testify assertion framework. * Vendored packages for the VIC provider Requires feature/wolfpack branch of VIC and a few specific commit sha of projects used within VIC. * Implementation of POD Stopper and Deleter unit tests (#4) * Updated files for initial PR
265 lines
7.6 KiB
Go
265 lines
7.6 KiB
Go
package govalidator
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"html"
|
|
"math"
|
|
"path"
|
|
"regexp"
|
|
"strings"
|
|
"unicode"
|
|
"unicode/utf8"
|
|
)
|
|
|
|
// Contains check if the string contains the substring.
|
|
func Contains(str, substring string) bool {
|
|
return strings.Contains(str, substring)
|
|
}
|
|
|
|
// Matches check if string matches the pattern (pattern is regular expression)
|
|
// In case of error return false
|
|
func Matches(str, pattern string) bool {
|
|
match, _ := regexp.MatchString(pattern, str)
|
|
return match
|
|
}
|
|
|
|
// LeftTrim trim characters from the left-side of the input.
|
|
// If second argument is empty, it's will be remove leading spaces.
|
|
func LeftTrim(str, chars string) string {
|
|
if chars == "" {
|
|
return strings.TrimLeftFunc(str, unicode.IsSpace)
|
|
}
|
|
r, _ := regexp.Compile("^[" + chars + "]+")
|
|
return r.ReplaceAllString(str, "")
|
|
}
|
|
|
|
// RightTrim trim characters from the right-side of the input.
|
|
// If second argument is empty, it's will be remove spaces.
|
|
func RightTrim(str, chars string) string {
|
|
if chars == "" {
|
|
return strings.TrimRightFunc(str, unicode.IsSpace)
|
|
}
|
|
r, _ := regexp.Compile("[" + chars + "]+$")
|
|
return r.ReplaceAllString(str, "")
|
|
}
|
|
|
|
// Trim trim characters from both sides of the input.
|
|
// If second argument is empty, it's will be remove spaces.
|
|
func Trim(str, chars string) string {
|
|
return LeftTrim(RightTrim(str, chars), chars)
|
|
}
|
|
|
|
// WhiteList remove characters that do not appear in the whitelist.
|
|
func WhiteList(str, chars string) string {
|
|
pattern := "[^" + chars + "]+"
|
|
r, _ := regexp.Compile(pattern)
|
|
return r.ReplaceAllString(str, "")
|
|
}
|
|
|
|
// BlackList remove characters that appear in the blacklist.
|
|
func BlackList(str, chars string) string {
|
|
pattern := "[" + chars + "]+"
|
|
r, _ := regexp.Compile(pattern)
|
|
return r.ReplaceAllString(str, "")
|
|
}
|
|
|
|
// StripLow remove characters with a numerical value < 32 and 127, mostly control characters.
|
|
// If keep_new_lines is true, newline characters are preserved (\n and \r, hex 0xA and 0xD).
|
|
func StripLow(str string, keepNewLines bool) string {
|
|
chars := ""
|
|
if keepNewLines {
|
|
chars = "\x00-\x09\x0B\x0C\x0E-\x1F\x7F"
|
|
} else {
|
|
chars = "\x00-\x1F\x7F"
|
|
}
|
|
return BlackList(str, chars)
|
|
}
|
|
|
|
// ReplacePattern replace regular expression pattern in string
|
|
func ReplacePattern(str, pattern, replace string) string {
|
|
r, _ := regexp.Compile(pattern)
|
|
return r.ReplaceAllString(str, replace)
|
|
}
|
|
|
|
// Escape replace <, >, & and " with HTML entities.
|
|
var Escape = html.EscapeString
|
|
|
|
func addSegment(inrune, segment []rune) []rune {
|
|
if len(segment) == 0 {
|
|
return inrune
|
|
}
|
|
if len(inrune) != 0 {
|
|
inrune = append(inrune, '_')
|
|
}
|
|
inrune = append(inrune, segment...)
|
|
return inrune
|
|
}
|
|
|
|
// UnderscoreToCamelCase converts from underscore separated form to camel case form.
|
|
// Ex.: my_func => MyFunc
|
|
func UnderscoreToCamelCase(s string) string {
|
|
return strings.Replace(strings.Title(strings.Replace(strings.ToLower(s), "_", " ", -1)), " ", "", -1)
|
|
}
|
|
|
|
// CamelCaseToUnderscore converts from camel case form to underscore separated form.
|
|
// Ex.: MyFunc => my_func
|
|
func CamelCaseToUnderscore(str string) string {
|
|
var output []rune
|
|
var segment []rune
|
|
for _, r := range str {
|
|
|
|
// not treat number as separate segment
|
|
if !unicode.IsLower(r) && string(r) != "_" && !unicode.IsNumber(r) {
|
|
output = addSegment(output, segment)
|
|
segment = nil
|
|
}
|
|
segment = append(segment, unicode.ToLower(r))
|
|
}
|
|
output = addSegment(output, segment)
|
|
return string(output)
|
|
}
|
|
|
|
// Reverse return reversed string
|
|
func Reverse(s string) string {
|
|
r := []rune(s)
|
|
for i, j := 0, len(r)-1; i < j; i, j = i+1, j-1 {
|
|
r[i], r[j] = r[j], r[i]
|
|
}
|
|
return string(r)
|
|
}
|
|
|
|
// GetLines split string by "\n" and return array of lines
|
|
func GetLines(s string) []string {
|
|
return strings.Split(s, "\n")
|
|
}
|
|
|
|
// GetLine return specified line of multiline string
|
|
func GetLine(s string, index int) (string, error) {
|
|
lines := GetLines(s)
|
|
if index < 0 || index >= len(lines) {
|
|
return "", errors.New("line index out of bounds")
|
|
}
|
|
return lines[index], nil
|
|
}
|
|
|
|
// RemoveTags remove all tags from HTML string
|
|
func RemoveTags(s string) string {
|
|
return ReplacePattern(s, "<[^>]*>", "")
|
|
}
|
|
|
|
// SafeFileName return safe string that can be used in file names
|
|
func SafeFileName(str string) string {
|
|
name := strings.ToLower(str)
|
|
name = path.Clean(path.Base(name))
|
|
name = strings.Trim(name, " ")
|
|
separators, err := regexp.Compile(`[ &_=+:]`)
|
|
if err == nil {
|
|
name = separators.ReplaceAllString(name, "-")
|
|
}
|
|
legal, err := regexp.Compile(`[^[:alnum:]-.]`)
|
|
if err == nil {
|
|
name = legal.ReplaceAllString(name, "")
|
|
}
|
|
for strings.Contains(name, "--") {
|
|
name = strings.Replace(name, "--", "-", -1)
|
|
}
|
|
return name
|
|
}
|
|
|
|
// NormalizeEmail canonicalize an email address.
|
|
// The local part of the email address is lowercased for all domains; the hostname is always lowercased and
|
|
// the local part of the email address is always lowercased for hosts that are known to be case-insensitive (currently only GMail).
|
|
// Normalization follows special rules for known providers: currently, GMail addresses have dots removed in the local part and
|
|
// are stripped of tags (e.g. some.one+tag@gmail.com becomes someone@gmail.com) and all @googlemail.com addresses are
|
|
// normalized to @gmail.com.
|
|
func NormalizeEmail(str string) (string, error) {
|
|
if !IsEmail(str) {
|
|
return "", fmt.Errorf("%s is not an email", str)
|
|
}
|
|
parts := strings.Split(str, "@")
|
|
parts[0] = strings.ToLower(parts[0])
|
|
parts[1] = strings.ToLower(parts[1])
|
|
if parts[1] == "gmail.com" || parts[1] == "googlemail.com" {
|
|
parts[1] = "gmail.com"
|
|
parts[0] = strings.Split(ReplacePattern(parts[0], `\.`, ""), "+")[0]
|
|
}
|
|
return strings.Join(parts, "@"), nil
|
|
}
|
|
|
|
// Truncate a string to the closest length without breaking words.
|
|
func Truncate(str string, length int, ending string) string {
|
|
var aftstr, befstr string
|
|
if len(str) > length {
|
|
words := strings.Fields(str)
|
|
before, present := 0, 0
|
|
for i := range words {
|
|
befstr = aftstr
|
|
before = present
|
|
aftstr = aftstr + words[i] + " "
|
|
present = len(aftstr)
|
|
if present > length && i != 0 {
|
|
if (length - before) < (present - length) {
|
|
return Trim(befstr, " /\\.,\"'#!?&@+-") + ending
|
|
}
|
|
return Trim(aftstr, " /\\.,\"'#!?&@+-") + ending
|
|
}
|
|
}
|
|
}
|
|
|
|
return str
|
|
}
|
|
|
|
// PadLeft pad left side of string if size of string is less then indicated pad length
|
|
func PadLeft(str string, padStr string, padLen int) string {
|
|
return buildPadStr(str, padStr, padLen, true, false)
|
|
}
|
|
|
|
// PadRight pad right side of string if size of string is less then indicated pad length
|
|
func PadRight(str string, padStr string, padLen int) string {
|
|
return buildPadStr(str, padStr, padLen, false, true)
|
|
}
|
|
|
|
// PadBoth pad sides of string if size of string is less then indicated pad length
|
|
func PadBoth(str string, padStr string, padLen int) string {
|
|
return buildPadStr(str, padStr, padLen, true, true)
|
|
}
|
|
|
|
// PadString either left, right or both sides, not the padding string can be unicode and more then one
|
|
// character
|
|
func buildPadStr(str string, padStr string, padLen int, padLeft bool, padRight bool) string {
|
|
|
|
// When padded length is less then the current string size
|
|
if padLen < utf8.RuneCountInString(str) {
|
|
return str
|
|
}
|
|
|
|
padLen -= utf8.RuneCountInString(str)
|
|
|
|
targetLen := padLen
|
|
|
|
targetLenLeft := targetLen
|
|
targetLenRight := targetLen
|
|
if padLeft && padRight {
|
|
targetLenLeft = padLen / 2
|
|
targetLenRight = padLen - targetLenLeft
|
|
}
|
|
|
|
strToRepeatLen := utf8.RuneCountInString(padStr)
|
|
|
|
repeatTimes := int(math.Ceil(float64(targetLen) / float64(strToRepeatLen)))
|
|
repeatedString := strings.Repeat(padStr, repeatTimes)
|
|
|
|
leftSide := ""
|
|
if padLeft {
|
|
leftSide = repeatedString[0:targetLenLeft]
|
|
}
|
|
|
|
rightSide := ""
|
|
if padRight {
|
|
rightSide = repeatedString[0:targetLenRight]
|
|
}
|
|
|
|
return leftSide + str + rightSide
|
|
}
|