Skip to content

Commit

Permalink
Merge pull request #394 from essentialkaos/develop
Browse files Browse the repository at this point in the history
Version 12.81.0
  • Loading branch information
andyone authored Oct 16, 2023
2 parents db9ac45 + f93a10f commit 349d697
Show file tree
Hide file tree
Showing 10 changed files with 182 additions and 45 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
## Changelog

### 12.81.0

* `[knf/validators/network]` Added `HasIP` validator
* `[strutil]` Added method `ReplaceIgnoreCase`
* `[uuid]` `GenUUID4` renamed to `UUID4`
* `[uuid]` `GenUUID5` renamed to `UUID5`
* `[uuid]` Code refactoring

### 12.80.0

* `[system]` Added ANSI color info to `OSInfo`
Expand Down
2 changes: 1 addition & 1 deletion ek.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import (
// ////////////////////////////////////////////////////////////////////////////////// //

// VERSION is current ek package version
const VERSION = "12.80.0"
const VERSION = "12.81.0"

// ////////////////////////////////////////////////////////////////////////////////// //

Expand Down
39 changes: 36 additions & 3 deletions knf/validators/network/validators.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ var (

// URL returns error if config property isn't a valid URL
URL = validateURL

// HasIP returns error if system doesn't have interface with IP from config property
HasIP = validateHasIP
)

// ////////////////////////////////////////////////////////////////////////////////// //
Expand Down Expand Up @@ -82,7 +85,7 @@ func validateMAC(config *knf.Config, prop string, value any) error {
return fmt.Errorf("%s is not a valid MAC address: %v", macStr, err)
}

return err
return nil
}

func validateCIDR(config *knf.Config, prop string, value any) error {
Expand All @@ -98,7 +101,7 @@ func validateCIDR(config *knf.Config, prop string, value any) error {
return fmt.Errorf("%s is not a valid CIDR address: %v", cidrStr, err)
}

return err
return nil
}

func validateURL(config *knf.Config, prop string, value any) error {
Expand All @@ -114,5 +117,35 @@ func validateURL(config *knf.Config, prop string, value any) error {
return fmt.Errorf("%s is not a valid URL address: %v", urlStr, err)
}

return err
return nil
}

func validateHasIP(config *knf.Config, prop string, value any) error {
ipStr := config.GetS(prop)

if ipStr == "" {
return nil
}

interfaces, err := net.Interfaces()

if err != nil {
return fmt.Errorf("Can't get interfaces info for check: %v", err)
}

for _, i := range interfaces {
addr, err := i.Addrs()

if err != nil {
continue
}

for _, a := range addr {
if ipStr == a.(*net.IPNet).IP.String() {
return nil
}
}
}

return fmt.Errorf("The system does not have an interface with the address %s", ipStr)
}
22 changes: 22 additions & 0 deletions knf/validators/network/validators_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ const _CONFIG_DATA = `
test0:
test1: 127.0.0.1
test2: 300.0.400.5
test3: 192.168.1.254
[port]
test0:
Expand Down Expand Up @@ -83,6 +84,27 @@ func (s *ValidatorSuite) TestIPValidator(c *C) {
c.Assert(errs[0].Error(), Equals, "300.0.400.5 is not a valid IP address")
}

func (s *ValidatorSuite) TestHasIPValidator(c *C) {
configFile := createConfig(c, _CONFIG_DATA)

err := knf.Global(configFile)
c.Assert(err, IsNil)

errs := knf.Validate([]*knf.Validator{
{"ip:test0", HasIP, nil},
{"ip:test1", HasIP, nil},
})

c.Assert(errs, HasLen, 0)

errs = knf.Validate([]*knf.Validator{
{"ip:test3", HasIP, nil},
})

c.Assert(errs, HasLen, 1)
c.Assert(errs[0].Error(), Equals, "The system does not have an interface with the address 192.168.1.254")
}

func (s *ValidatorSuite) TestPortValidator(c *C) {
configFile := createConfig(c, _CONFIG_DATA)

Expand Down
9 changes: 9 additions & 0 deletions strutil/example_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,15 @@ func ExampleReplaceAll() {
// M???ag?
}

func ExampleReplaceIgnoreCase() {
fmt.Println(ReplaceIgnoreCase(
"User bob has no item. Add items to user Bob?", "bob", "[Bob]",
))

// Output:
// User [Bob] has no item. Add items to user [Bob]?
}

func ExampleFields() {
fmt.Printf("%#v\n", Fields("Bob Alice, 'Mary Key', \"John Dow\""))

Expand Down
35 changes: 32 additions & 3 deletions strutil/strutil.go
Original file line number Diff line number Diff line change
Expand Up @@ -234,8 +234,8 @@ func SuffixSize(str string, suffix rune) int {
return result
}

// ReplaceAll replaces all symbols in given string
func ReplaceAll(source, from, to string) string {
// ReplaceAll replaces all symbols from replset in string
func ReplaceAll(source, replset, to string) string {
if source == "" {
return ""
}
Expand All @@ -244,7 +244,7 @@ func ReplaceAll(source, from, to string) string {

SOURCELOOP:
for _, sourceSym := range source {
for _, fromSym := range from {
for _, fromSym := range replset {
if fromSym == sourceSym {
result.WriteString(to)
continue SOURCELOOP
Expand All @@ -257,6 +257,35 @@ SOURCELOOP:
return result.String()
}

// ReplaceIgnoreCase replaces part of the string ignoring case
func ReplaceIgnoreCase(source, from, to string) string {
if source == "" || from == "" {
return source
}

var result strings.Builder

from = strings.ToLower(from)
lowSource := strings.ToLower(source)

for {
index := strings.Index(lowSource, from)

if index == -1 {
result.WriteString(source)
break
}

result.WriteString(source[:index])
result.WriteString(to)

source = source[index+len(from):]
lowSource = lowSource[index+len(from):]
}

return result.String()
}

// Exclude excludes substring from given string
func Exclude(data, substr string) string {
if len(data) == 0 || len(substr) == 0 {
Expand Down
13 changes: 13 additions & 0 deletions strutil/strutil_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,13 @@ func (s *StrUtilSuite) TestReplaceAll(c *C) {
c.Assert(ReplaceAll("", "AB12", "?"), Equals, "")
}

func (s *StrUtilSuite) TestReplaceIgnoreCase(c *C) {
c.Assert(ReplaceIgnoreCase("ABCD1234abcd1234AbCd11ABcd", "abcd", "????"), Equals, "????1234????1234????11????")
c.Assert(ReplaceIgnoreCase("TESTtestTEST", "abcd", "????"), Equals, "TESTtestTEST")
c.Assert(ReplaceIgnoreCase("", "abcd", "????"), Equals, "")
c.Assert(ReplaceIgnoreCase("ABCD1234abcd1234AbCd11ABcd", "abcd", ""), Equals, "1234123411")
}

func (s *StrUtilSuite) TestFields(c *C) {
c.Assert(Fields(""), IsNil)
c.Assert(Fields(""), HasLen, 0)
Expand Down Expand Up @@ -252,3 +259,9 @@ func (s *StrUtilSuite) BenchmarkReplaceAll(c *C) {
ReplaceAll("ABCDABCD12341234", "AB12", "?")
}
}

func (s *StrUtilSuite) BenchmarkReplaceIgnoreCase(c *C) {
for i := 0; i < c.N; i++ {
ReplaceIgnoreCase("ABCD1234abcd1234AbCd11ABcd", "abcd", "????")
}
}
12 changes: 4 additions & 8 deletions uuid/example_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,10 @@ import (

// ////////////////////////////////////////////////////////////////////////////////// //

func ExampleGenUUID() {
fmt.Printf("UUID: %s\n", GenUUID())
func ExampleUUID4() {
fmt.Printf("UUID v4: %s\n", UUID4().String())
}

func ExampleGenUUID4() {
fmt.Printf("UUID v4: %s\n", GenUUID4())
}

func ExampleGenUUID5() {
fmt.Printf("UUID v5: %s\n", GenUUID5(NsURL, "http://www.domain.com"))
func ExampleUUID5() {
fmt.Printf("UUID v5: %s\n", UUID5(NsURL, "http://www.domain.com").String())
}
70 changes: 48 additions & 22 deletions uuid/uuid.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,53 +26,79 @@ var (

// ////////////////////////////////////////////////////////////////////////////////// //

// GenUUID generates v4 UUID (Universally Unique Identifier)
func GenUUID() string {
return GenUUID4()
}
// UUID contains UUID data
type UUID []byte

// GenUUID4 generates random generated UUID
func GenUUID4() string {
uuid := make([]byte, 16)
// ////////////////////////////////////////////////////////////////////////////////// //

// UUID4 generates random generated UUID v4
func UUID4() UUID {
uuid := make(UUID, 16)

rand.Read(uuid)

uuid[6] = (uuid[6] & 0X0F) | 0X40
uuid[8] = (uuid[8] & 0X3F) | 0X80
uuid[6] = (uuid[6] & 0x0F) | 0x40
uuid[8] = (uuid[8] & 0x3F) | 0x80

return toString(uuid)
return UUID(uuid)
}

// GenUUID5 generates UUID based on SHA-1 hash of namespace UUID and name
func GenUUID5(ns []byte, name string) string {
uuid := make([]byte, 16)
// UUID5 generates UUID v5 based on SHA-1 hash of namespace UUID and name
func UUID5(ns []byte, name string) UUID {
uuid := make(UUID, 16)

hash := sha1.New()
hash.Write(ns)
hash.Write([]byte(name))

copy(uuid, hash.Sum(nil))

uuid[6] = (uuid[6] & 0X0F) | 0x50
uuid[8] = (uuid[8] & 0X3F) | 0x80
uuid[6] = (uuid[6] & 0x0F) | 0x50
uuid[8] = (uuid[8] & 0x3F) | 0x80

return toString(uuid)
return UUID(uuid)
}

// ////////////////////////////////////////////////////////////////////////////////// //

func toString(uuid []byte) string {
// String returns string representation of UUID
func (u UUID) String() string {
buf := make([]byte, 36)

hex.Encode(buf[0:8], uuid[0:4])
hex.Encode(buf[0:8], u[0:4])
buf[8] = '-'
hex.Encode(buf[9:13], uuid[4:6])
hex.Encode(buf[9:13], u[4:6])
buf[13] = '-'
hex.Encode(buf[14:18], uuid[6:8])
hex.Encode(buf[14:18], u[6:8])
buf[18] = '-'
hex.Encode(buf[19:23], uuid[8:10])
hex.Encode(buf[19:23], u[8:10])
buf[23] = '-'
hex.Encode(buf[24:], uuid[10:])
hex.Encode(buf[24:], u[10:])

return string(buf)
}

// ////////////////////////////////////////////////////////////////////////////////// //

// GenUUID generates v4 UUID (Universally Unique Identifier)
//
// Deprecated: Use method UUID4.String() instead
func GenUUID() string {
return UUID4().String()
}

// GenUUID4 generates random generated UUID
//
// Deprecated: Use method UUID4.String() instead
func GenUUID4() string {
return UUID4().String()
}

// GenUUID5 generates UUID based on SHA-1 hash of namespace UUID and name
//
// Deprecated: Use method UUID5.String() instead
func GenUUID5(ns []byte, name string) string {
return UUID5(ns, name).String()
}

// ////////////////////////////////////////////////////////////////////////////////// //
17 changes: 9 additions & 8 deletions uuid/uuid_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,18 +25,19 @@ var _ = Suite(&UUIDSuite{})

// ////////////////////////////////////////////////////////////////////////////////// //

func (s *UUIDSuite) TestGenUUID(c *C) {
c.Assert(GenUUID(), HasLen, 36)
c.Assert(GenUUID(), Not(Equals), "00000000-0000-0000-0000-000000000000")
}

func (s *UUIDSuite) TestGenUUID4(c *C) {
c.Assert(GenUUID4(), HasLen, 36)
c.Assert(GenUUID4(), Not(Equals), "00000000-0000-0000-0000-000000000000")
c.Assert(UUID4(), HasLen, 16)
c.Assert(UUID4().String(), Not(Equals), "00000000-0000-0000-0000-000000000000")
}

func (s *UUIDSuite) TestGenUUID5(c *C) {
c.Assert(GenUUID5(NsURL, "TEST"), HasLen, 36)
c.Assert(UUID5(NsURL, "TEST"), HasLen, 16)
c.Assert(UUID5(NsURL, "TEST").String(), Not(Equals), "00000000-0000-0000-0000-000000000000")
}

func (s *UUIDSuite) TestDeprecated(c *C) {
c.Assert(GenUUID(), Not(Equals), "00000000-0000-0000-0000-000000000000")
c.Assert(GenUUID4(), Not(Equals), "00000000-0000-0000-0000-000000000000")
c.Assert(GenUUID5(NsURL, "TEST"), Not(Equals), "00000000-0000-0000-0000-000000000000")
}

Expand Down

0 comments on commit 349d697

Please sign in to comment.