This commit is contained in:
crusader
2018-04-20 00:46:38 +09:00
commit f28ff9a303
64 changed files with 2424 additions and 0 deletions

20
crawler/crawler.go Normal file
View File

@@ -0,0 +1,20 @@
package crawler
import (
"git.loafle.net/overflow/crawler-go"
)
var crawlers map[string]crawler.Crawler
func init() {
crawlers = make(map[string]crawler.Crawler, 0)
}
func addCrawler(c crawler.Crawler) {
crawlers[c.Name()] = c
}
func GetCrawlers() map[string]crawler.Crawler {
return crawlers
}

View File

@@ -0,0 +1,133 @@
package health
import (
"crypto/tls"
"encoding/base64"
"fmt"
"net"
"time"
cnsm "git.loafle.net/commons/service_matcher-go"
cuej "git.loafle.net/commons_go/util/encoding/json"
ocsm "git.loafle.net/overflow/commons-go/sensorconfig/model"
"git.loafle.net/overflow/crawler-go"
)
type SocketHeahthCrawler struct {
crawler.Crawler
m cnsm.Matcher
}
func (s *SocketHeahthCrawler) SetMatcher(m cnsm.Matcher) {
s.m = m
}
func (s *SocketHeahthCrawler) getConnection(config *ocsm.SensorConfig) (net.Conn, error) {
connection := config.Target.Connection
ip := connection.IP
port := connection.Port
portType := connection.PortType
ssl := connection.SSL
addr := fmt.Sprintf("%s:%s", ip, port)
conn, err := net.Dial(portType, addr)
if err != nil {
return nil, err
}
if ssl {
cfg := &tls.Config{
InsecureSkipVerify: true,
ServerName: ip,
ClientAuth: tls.RequestClientCert,
}
tlsConn := tls.Client(conn, cfg)
if err := tlsConn.Handshake(); err != nil {
return nil, err
}
conn = tlsConn
}
return conn, nil
}
func (s *SocketHeahthCrawler) CheckHeahth(config *ocsm.SensorConfig) (result map[string]string, err error) {
result = make(map[string]string, 0)
result["StartTime"] = time.Now().String()
conn, cErr := s.getConnection(config)
if cErr != nil {
result["Error"] = cErr.Error()
err = cErr
return
}
defer conn.Close()
connection := config.Target.Connection
port, _ := cuej.NumberToInt(connection.Port)
info := cnsm.NewMatchInfo(connection.IP, port)
if s.m.IsPrePacket() {
result["PacketType"] = "Pre"
buf := make([]byte, 1024)
n, _ := conn.Read(buf)
p := cnsm.NewPacket(buf, n)
if !s.m.Match(info, 0, p) {
result["Packet"] = convertBase64(buf)
result["Error"] = "Not Matched"
return
}
for i := 0; i < s.m.PacketCount(); i++ {
pack := s.m.Packet(i)
conn.Write(pack.Buffer)
buf := make([]byte, 1024)
n, _ := conn.Read(buf)
if !s.m.HasResponse(i + 1) { // empty last response
break
}
p := cnsm.NewPacket(buf, n)
if s.m.Match(info, i+1, p) == false {
result["Packet"] = convertBase64(buf)
result["Error"] = "Not Matched"
return
}
}
} else {
result["PacketType"] = "Post"
for i := 0; i < s.m.PacketCount(); i++ {
pack := s.m.Packet(i)
conn.Write(pack.Buffer)
buf := make([]byte, 1024)
n, _ := conn.Read(buf)
if !s.m.HasResponse(i) { // empty last response
break
}
p := cnsm.NewPacket(buf, n)
if s.m.Match(info, i, p) == false {
result["Packet"] = convertBase64(buf)
result["Error"] = "Not Matched"
return
}
}
}
result["EndTime"] = time.Now().String()
return
}
func convertBase64(buf []byte) string {
return base64.StdEncoding.EncodeToString(buf)
}

View File

@@ -0,0 +1,38 @@
package activedirectory
import (
csma "git.loafle.net/commons/service_matcher-go/activedirectory"
ocsm "git.loafle.net/overflow/commons-go/sensorconfig/model"
"git.loafle.net/overflow/container_network/crawler/health"
"git.loafle.net/overflow/crawler-go"
)
type ActiveDirectoryHealthCrawler struct {
health.SocketHeahthCrawler
}
func (c *ActiveDirectoryHealthCrawler) Name() string {
return "ACTIVEDIRECTORY_HEALTH"
}
func (c *ActiveDirectoryHealthCrawler) String() string {
return "Active Directory Health Crawler"
}
func (c *ActiveDirectoryHealthCrawler) Auth(auth map[string]string) error {
return nil
}
func (c *ActiveDirectoryHealthCrawler) Get(config *ocsm.SensorConfig) (map[string]string, error) {
rss, err := c.CheckHeahth(config)
if err != nil {
return nil, err
}
return rss, nil
}
func NewCrawler() crawler.Crawler {
ad := &ActiveDirectoryHealthCrawler{}
ad.SetMatcher(csma.NewMatcher())
return ad
}

View File

@@ -0,0 +1,27 @@
package activedirectory
import (
"encoding/json"
"testing"
ocsm "git.loafle.net/overflow/commons-go/sensorconfig/model"
"github.com/stretchr/testify/assert"
)
func TestMatch(t *testing.T) {
config := &ocsm.SensorConfig{}
config.Target = &ocsm.Target{}
config.Target.Connection = &ocsm.Connection{
IP: "192.168.1.1",
Port: json.Number(389),
PortType: "tcp",
SSL: false,
}
c := NewCrawler()
rss, err := c.Get(config)
assert.Nil(t, err)
assert.NotNil(t, rss)
}

View File

@@ -0,0 +1,30 @@
package cassandra
import (
cnsmc "git.loafle.net/commons/service_matcher-go/cassandra"
ocsm "git.loafle.net/overflow/commons-go/sensorconfig/model"
"git.loafle.net/overflow/container_network/crawler/health"
crawler "git.loafle.net/overflow/crawler-go"
)
type CassandraHealthCrawler struct {
health.SocketHeahthCrawler
}
func (c *CassandraHealthCrawler) Name() string {
return "CASSANDRA_HEALTH_CRAWLER"
}
func (c *CassandraHealthCrawler) Get(config *ocsm.SensorConfig) (map[string]string, error) {
rss, err := c.CheckHeahth(config)
if err != nil {
return nil, err
}
return rss, nil
}
func NewCrawler() crawler.Crawler {
c := &CassandraHealthCrawler{}
c.SetMatcher(cnsmc.NewMatcher())
return c
}

View File

@@ -0,0 +1,27 @@
package cassandra
import (
"encoding/json"
"testing"
ocsm "git.loafle.net/overflow/commons-go/sensorconfig/model"
"github.com/stretchr/testify/assert"
)
func TestMatch(t *testing.T) {
config := &ocsm.SensorConfig{}
config.Target = &ocsm.Target{}
config.Target.Connection = &ocsm.Connection{
IP: "192.168.1.104",
Port: json.Number(9042),
PortType: "tcp",
SSL: false,
}
c := NewCrawler()
rss, err := c.Get(config)
assert.Nil(t, err)
assert.NotNil(t, rss)
}

View File

@@ -0,0 +1,30 @@
package dns
import (
cnsmd "git.loafle.net/commons/service_matcher-go/dns"
ocsm "git.loafle.net/overflow/commons-go/sensorconfig/model"
"git.loafle.net/overflow/container_network/crawler/health"
crawler "git.loafle.net/overflow/crawler-go"
)
type DNSHealthCrawler struct {
health.SocketHeahthCrawler
}
func (c *DNSHealthCrawler) Name() string {
return "DNS_HEALTH_CRAWLER"
}
func (c *DNSHealthCrawler) Get(config *ocsm.SensorConfig) (map[string]string, error) {
rss, err := c.CheckHeahth(config)
if err != nil {
return nil, err
}
return rss, nil
}
func NewCrawler() crawler.Crawler {
c := &DNSHealthCrawler{}
c.SetMatcher(cnsmd.NewMatcher())
return c
}

View File

@@ -0,0 +1,27 @@
package dns
import (
"encoding/json"
"testing"
ocsm "git.loafle.net/overflow/commons-go/sensorconfig/model"
"github.com/stretchr/testify/assert"
)
func TestMatch(t *testing.T) {
config := &ocsm.SensorConfig{}
config.Target = &ocsm.Target{}
config.Target.Connection = &ocsm.Connection{
IP: "192.168.1.215",
Port: json.Number(53),
PortType: "udp",
SSL: false,
}
c := NewCrawler()
rss, err := c.Get(config)
assert.Nil(t, err)
assert.NotNil(t, rss)
}

View File

@@ -0,0 +1,30 @@
package ftp
import (
cnsmf "git.loafle.net/commons/service_matcher-go/ftp"
ocsm "git.loafle.net/overflow/commons-go/sensorconfig/model"
"git.loafle.net/overflow/container_network/crawler/health"
crawler "git.loafle.net/overflow/crawler-go"
)
type FTPHealthCrawler struct {
health.SocketHeahthCrawler
}
func (c *FTPHealthCrawler) Name() string {
return "FTP_HEALTH_CRAWLER"
}
func (c *FTPHealthCrawler) Get(config *ocsm.SensorConfig) (map[string]string, error) {
rss, err := c.CheckHeahth(config)
if err != nil {
return nil, err
}
return rss, nil
}
func NewCrawler() crawler.Crawler {
c := &FTPHealthCrawler{}
c.SetMatcher(cnsmf.NewMatcher())
return c
}

View File

@@ -0,0 +1,27 @@
package ftp
import (
"encoding/json"
"testing"
ocsm "git.loafle.net/overflow/commons-go/sensorconfig/model"
"github.com/stretchr/testify/assert"
)
func TestMatch(t *testing.T) {
config := &ocsm.SensorConfig{}
config.Target = &ocsm.Target{}
config.Target.Connection = &ocsm.Connection{
IP: "192.168.1.215",
Port: json.Number(21),
PortType: "tcp",
SSL: false,
}
c := NewCrawler()
rss, err := c.Get(config)
assert.Nil(t, err)
assert.NotNil(t, rss)
}

View File

@@ -0,0 +1,30 @@
package http
import (
cnsmh "git.loafle.net/commons/service_matcher-go/http"
ocsm "git.loafle.net/overflow/commons-go/sensorconfig/model"
"git.loafle.net/overflow/container_network/crawler/health"
crawler "git.loafle.net/overflow/crawler-go"
)
type HTTPHealthCrawler struct {
health.SocketHeahthCrawler
}
func (c *HTTPHealthCrawler) Name() string {
return "HTTP_HEALTH_CRAWLER"
}
func (c *HTTPHealthCrawler) Get(config *ocsm.SensorConfig) (map[string]string, error) {
rss, err := c.CheckHeahth(config)
if err != nil {
return nil, err
}
return rss, nil
}
func NewCrawler() crawler.Crawler {
c := &HTTPHealthCrawler{}
c.SetMatcher(cnsmh.NewMatcher())
return c
}

View File

@@ -0,0 +1,27 @@
package http
import (
"encoding/json"
"testing"
ocsm "git.loafle.net/overflow/commons-go/sensorconfig/model"
"github.com/stretchr/testify/assert"
)
func TestMatch(t *testing.T) {
config := &ocsm.SensorConfig{}
config.Target = &ocsm.Target{}
config.Target.Connection = &ocsm.Connection{
IP: "192.168.1.105",
Port: json.Number(80),
PortType: "tcp",
SSL: false,
}
c := NewCrawler()
rss, err := c.Get(config)
assert.Nil(t, err)
assert.NotNil(t, rss)
}

View File

@@ -0,0 +1,30 @@
package imap
import (
cnsmi "git.loafle.net/commons/service_matcher-go/imap"
ocsm "git.loafle.net/overflow/commons-go/sensorconfig/model"
"git.loafle.net/overflow/container_network/crawler/health"
crawler "git.loafle.net/overflow/crawler-go"
)
type IMAPHealthCrawler struct {
health.SocketHeahthCrawler
}
func (c *IMAPHealthCrawler) Name() string {
return "IMAP_HEALTH_CRAWLER"
}
func (c *IMAPHealthCrawler) Get(config *ocsm.SensorConfig) (map[string]string, error) {
rss, err := c.CheckHeahth(config)
if err != nil {
return nil, err
}
return rss, nil
}
func NewCrawler() crawler.Crawler {
c := &IMAPHealthCrawler{}
c.SetMatcher(cnsmi.NewMatcher())
return c
}

View File

@@ -0,0 +1,27 @@
package imap
import (
"encoding/json"
"testing"
ocsm "git.loafle.net/overflow/commons-go/sensorconfig/model"
"github.com/stretchr/testify/assert"
)
func TestMatch(t *testing.T) {
config := &ocsm.SensorConfig{}
config.Target = &ocsm.Target{}
config.Target.Connection = &ocsm.Connection{
IP: "192.168.1.215",
Port: json.Number(993),
PortType: "tcp",
SSL: false,
}
c := NewCrawler()
rss, err := c.Get(config)
assert.Nil(t, err)
assert.NotNil(t, rss)
}

View File

@@ -0,0 +1,30 @@
package ldap
import (
cnsml "git.loafle.net/commons/service_matcher-go/ldap"
ocsm "git.loafle.net/overflow/commons-go/sensorconfig/model"
"git.loafle.net/overflow/container_network/crawler/health"
crawler "git.loafle.net/overflow/crawler-go"
)
type LDAPHealthCrawler struct {
health.SocketHeahthCrawler
}
func (c *LDAPHealthCrawler) Name() string {
return "LDAP_HEALTH_CRAWLER"
}
func (c *LDAPHealthCrawler) Get(config *ocsm.SensorConfig) (map[string]string, error) {
rss, err := c.CheckHeahth(config)
if err != nil {
return nil, err
}
return rss, nil
}
func NewCrawler() crawler.Crawler {
c := &LDAPHealthCrawler{}
c.SetMatcher(cnsml.NewMatcher())
return c
}

View File

@@ -0,0 +1,27 @@
package ldap
import (
"encoding/json"
"testing"
ocsm "git.loafle.net/overflow/commons-go/sensorconfig/model"
"github.com/stretchr/testify/assert"
)
func TestMatch(t *testing.T) {
config := &ocsm.SensorConfig{}
config.Target = &ocsm.Target{}
config.Target.Connection = &ocsm.Connection{
IP: "192.168.1.215",
Port: json.Number(389),
PortType: "tcp",
SSL: false,
}
c := NewCrawler()
rss, err := c.Get(config)
assert.Nil(t, err)
assert.NotNil(t, rss)
}

View File

@@ -0,0 +1,30 @@
package mongodb
import (
cnsmm "git.loafle.net/commons/service_matcher-go/mongodb"
ocsm "git.loafle.net/overflow/commons-go/sensorconfig/model"
"git.loafle.net/overflow/container_network/crawler/health"
crawler "git.loafle.net/overflow/crawler-go"
)
type MongoDBHealthCrawler struct {
health.SocketHeahthCrawler
}
func (c *MongoDBHealthCrawler) Name() string {
return "MONGODB_HEALTH_CRAWLER"
}
func (c *MongoDBHealthCrawler) Get(config *ocsm.SensorConfig) (map[string]string, error) {
rss, err := c.CheckHeahth(config)
if err != nil {
return nil, err
}
return rss, nil
}
func NewCrawler() crawler.Crawler {
c := &MongoDBHealthCrawler{}
c.SetMatcher(cnsmm.NewMatcher())
return c
}

View File

@@ -0,0 +1,27 @@
package mongodb
import (
"encoding/json"
"testing"
ocsm "git.loafle.net/overflow/commons-go/sensorconfig/model"
"github.com/stretchr/testify/assert"
)
func TestMatch(t *testing.T) {
config := &ocsm.SensorConfig{}
config.Target = &ocsm.Target{}
config.Target.Connection = &ocsm.Connection{
IP: "192.168.1.104",
Port: json.Number(27017),
PortType: "tcp",
SSL: false,
}
c := NewCrawler()
rss, err := c.Get(config)
assert.Nil(t, err)
assert.NotNil(t, rss)
}

View File

@@ -0,0 +1,30 @@
package mysql
import (
cnsmm "git.loafle.net/commons/service_matcher-go/mysql"
ocsm "git.loafle.net/overflow/commons-go/sensorconfig/model"
"git.loafle.net/overflow/container_network/crawler/health"
"git.loafle.net/overflow/crawler-go"
)
type MySQLHealthCrawler struct {
health.SocketHeahthCrawler
}
func (c *MySQLHealthCrawler) Name() string {
return "MYSQL_HEALTH_CRAWLER"
}
func (c *MySQLHealthCrawler) Get(config *ocsm.SensorConfig) (map[string]string, error) {
rss, err := c.CheckHeahth(config)
if err != nil {
return nil, err
}
return rss, nil
}
func NewCrawler() crawler.Crawler {
c := &MySQLHealthCrawler{}
c.SetMatcher(cnsmm.NewMatcher())
return c
}

View File

@@ -0,0 +1,26 @@
package mysql
import (
"encoding/json"
"testing"
ocsm "git.loafle.net/overflow/commons-go/sensorconfig/model"
"github.com/stretchr/testify/assert"
)
func TestMatch(t *testing.T) {
config := &ocsm.SensorConfig{}
config.Target = &ocsm.Target{}
config.Target.Connection = &ocsm.Connection{
IP: "192.168.1.103",
Port: json.Number(3306),
PortType: "tcp",
SSL: false,
}
c := NewCrawler()
rss, err := c.Get(config)
assert.Nil(t, err)
assert.NotNil(t, rss)
}

View File

@@ -0,0 +1,30 @@
package netbios
import (
cnsmn "git.loafle.net/commons/service_matcher-go/netbios"
ocsm "git.loafle.net/overflow/commons-go/sensorconfig/model"
"git.loafle.net/overflow/container_network/crawler/health"
"git.loafle.net/overflow/crawler-go"
)
type NetBIOSHealthCrawler struct {
health.SocketHeahthCrawler
}
func (c *NetBIOSHealthCrawler) Name() string {
return "NETBIOS_HEALTH_CRAWLER"
}
func (c *NetBIOSHealthCrawler) Get(config *ocsm.SensorConfig) (map[string]string, error) {
rss, err := c.CheckHeahth(config)
if err != nil {
return nil, err
}
return rss, nil
}
func NewCrawler() crawler.Crawler {
c := &NetBIOSHealthCrawler{}
c.SetMatcher(cnsmn.NewMatcher())
return c
}

View File

@@ -0,0 +1,26 @@
package netbios
import (
"encoding/json"
"testing"
ocsm "git.loafle.net/overflow/commons-go/sensorconfig/model"
"github.com/stretchr/testify/assert"
)
func TestMatch(t *testing.T) {
config := &ocsm.SensorConfig{}
config.Target = &ocsm.Target{}
config.Target.Connection = &ocsm.Connection{
IP: "192.168.1.106",
Port: json.Number(139),
PortType: "tcp",
SSL: false,
}
c := NewCrawler()
rss, err := c.Get(config)
assert.Nil(t, err)
assert.NotNil(t, rss)
}

View File

@@ -0,0 +1,30 @@
package oracle
import (
cnsmo "git.loafle.net/commons/service_matcher-go/oracle"
ocsm "git.loafle.net/overflow/commons-go/sensorconfig/model"
"git.loafle.net/overflow/container_network/crawler/health"
crawler "git.loafle.net/overflow/crawler-go"
)
type OracleHealthCrawler struct {
health.SocketHeahthCrawler
}
func (c *OracleHealthCrawler) Name() string {
return "ORACLE_HEALTH_CRAWLER"
}
func (c *OracleHealthCrawler) Get(config *ocsm.SensorConfig) (map[string]string, error) {
rss, err := c.CheckHeahth(config)
if err != nil {
return nil, err
}
return rss, nil
}
func NewCrawler() crawler.Crawler {
c := &OracleHealthCrawler{}
c.SetMatcher(cnsmo.NewMatcher())
return c
}

View File

@@ -0,0 +1,26 @@
package oracle
import (
"encoding/json"
"testing"
ocsm "git.loafle.net/overflow/commons-go/sensorconfig/model"
"github.com/stretchr/testify/assert"
)
func TestMatch(t *testing.T) {
config := &ocsm.SensorConfig{}
config.Target = &ocsm.Target{}
config.Target.Connection = &ocsm.Connection{
IP: "192.168.1.30",
Port: json.Number(1521),
PortType: "tcp",
SSL: false,
}
c := NewCrawler()
rss, err := c.Get(config)
assert.Nil(t, err)
assert.NotNil(t, rss)
}

View File

@@ -0,0 +1,30 @@
package pop
import (
cnsmp "git.loafle.net/commons/service_matcher-go/pop"
ocsm "git.loafle.net/overflow/commons-go/sensorconfig/model"
"git.loafle.net/overflow/container_network/crawler/health"
crawler "git.loafle.net/overflow/crawler-go"
)
type POPHealthCrawler struct {
health.SocketHeahthCrawler
}
func (c *POPHealthCrawler) Name() string {
return "POP_HEALTH_CRAWLER"
}
func (c *POPHealthCrawler) Get(config *ocsm.SensorConfig) (map[string]string, error) {
rss, err := c.CheckHeahth(config)
if err != nil {
return nil, err
}
return rss, nil
}
func NewCrawler() crawler.Crawler {
c := &POPHealthCrawler{}
c.SetMatcher(cnsmp.NewMatcher())
return c
}

View File

@@ -0,0 +1,26 @@
package pop
import (
"encoding/json"
"testing"
ocsm "git.loafle.net/overflow/commons-go/sensorconfig/model"
"github.com/stretchr/testify/assert"
)
func TestMatch(t *testing.T) {
config := &ocsm.SensorConfig{}
config.Target = &ocsm.Target{}
config.Target.Connection = &ocsm.Connection{
IP: "192.168.1.215",
Port: json.Number(110),
PortType: "tcp",
SSL: false,
}
c := NewCrawler()
rss, err := c.Get(config)
assert.Nil(t, err)
assert.NotNil(t, rss)
}

View File

@@ -0,0 +1,30 @@
package postgresql
import (
cnsmp "git.loafle.net/commons/service_matcher-go/postgresql"
ocsm "git.loafle.net/overflow/commons-go/sensorconfig/model"
"git.loafle.net/overflow/container_network/crawler/health"
crawler "git.loafle.net/overflow/crawler-go"
)
type PostgreSQLHealthCrawler struct {
health.SocketHeahthCrawler
}
func (c *PostgreSQLHealthCrawler) Name() string {
return "POSTGRESQL_HEALTH_CRAWLER"
}
func (c *PostgreSQLHealthCrawler) Get(config *ocsm.SensorConfig) (map[string]string, error) {
rss, err := c.CheckHeahth(config)
if err != nil {
return nil, err
}
return rss, nil
}
func NewCrawler() crawler.Crawler {
c := &PostgreSQLHealthCrawler{}
c.SetMatcher(cnsmp.NewMatcher())
return c
}

View File

@@ -0,0 +1,26 @@
package postgresql
import (
"encoding/json"
"testing"
ocsm "git.loafle.net/overflow/commons-go/sensorconfig/model"
"github.com/stretchr/testify/assert"
)
func TestMatch(t *testing.T) {
config := &ocsm.SensorConfig{}
config.Target = &ocsm.Target{}
config.Target.Connection = &ocsm.Connection{
IP: "192.168.1.107",
Port: json.Number(5432),
PortType: "tcp",
SSL: false,
}
c := NewCrawler()
rss, err := c.Get(config)
assert.Nil(t, err)
assert.NotNil(t, rss)
}

View File

@@ -0,0 +1,30 @@
package redis
import (
cnsmr "git.loafle.net/commons/service_matcher-go/redis"
ocsm "git.loafle.net/overflow/commons-go/sensorconfig/model"
"git.loafle.net/overflow/container_network/crawler/health"
crawler "git.loafle.net/overflow/crawler-go"
)
type RedisHealthCrawler struct {
health.SocketHeahthCrawler
}
func (c *RedisHealthCrawler) Name() string {
return "REDIS_HEALTH_CRAWLER"
}
func (c *RedisHealthCrawler) Get(config *ocsm.SensorConfig) (map[string]string, error) {
rss, err := c.CheckHeahth(config)
if err != nil {
return nil, err
}
return rss, nil
}
func NewCrawler() crawler.Crawler {
c := &RedisHealthCrawler{}
c.SetMatcher(cnsmr.NewMatcher())
return c
}

View File

@@ -0,0 +1,27 @@
package redis
import (
"encoding/json"
"testing"
ocsm "git.loafle.net/overflow/commons-go/sensorconfig/model"
"github.com/stretchr/testify/assert"
)
func TestMatch(t *testing.T) {
config := &ocsm.SensorConfig{}
config.Target = &ocsm.Target{}
config.Target.Connection = &ocsm.Connection{
IP: "192.168.1.104",
Port: json.Number(6379),
PortType: "tcp",
SSL: false,
}
c := NewCrawler()
rss, err := c.Get(config)
assert.Nil(t, err)
assert.NotNil(t, rss)
}

View File

@@ -0,0 +1,30 @@
package rmi
import (
cnsmr "git.loafle.net/commons/service_matcher-go/rmi"
ocsm "git.loafle.net/overflow/commons-go/sensorconfig/model"
"git.loafle.net/overflow/container_network/crawler/health"
crawler "git.loafle.net/overflow/crawler-go"
)
type RMIHealthCrawler struct {
health.SocketHeahthCrawler
}
func (c *RMIHealthCrawler) Name() string {
return "RMI_HEALTH_CRAWLER"
}
func (c *RMIHealthCrawler) Get(config *ocsm.SensorConfig) (map[string]string, error) {
rss, err := c.CheckHeahth(config)
if err != nil {
return nil, err
}
return rss, nil
}
func NewCrawler() crawler.Crawler {
c := &RMIHealthCrawler{}
c.SetMatcher(cnsmr.NewMatcher())
return c
}

View File

@@ -0,0 +1,26 @@
package rmi
import (
"encoding/json"
"testing"
ocsm "git.loafle.net/overflow/commons-go/sensorconfig/model"
"github.com/stretchr/testify/assert"
)
func TestMatch(t *testing.T) {
config := &ocsm.SensorConfig{}
config.Target = &ocsm.Target{}
config.Target.Connection = &ocsm.Connection{
IP: "192.168.1.103",
Port: json.Number(9840),
PortType: "tcp",
SSL: false,
}
c := NewCrawler()
rss, err := c.Get("c")
assert.Nil(t, err)
assert.NotNil(t, rss)
}

View File

@@ -0,0 +1,30 @@
package smb
import (
cnsms "git.loafle.net/commons/service_matcher-go/smb"
ocsm "git.loafle.net/overflow/commons-go/sensorconfig/model"
"git.loafle.net/overflow/container_network/crawler/health"
crawler "git.loafle.net/overflow/crawler-go"
)
type SMBHealthCrawler struct {
health.SocketHeahthCrawler
}
func (c *SMBHealthCrawler) Name() string {
return "SMB_HEALTH_CRAWLER"
}
func (c *SMBHealthCrawler) Get(config *ocsm.SensorConfig) (map[string]string, error) {
rss, err := c.CheckHeahth(config)
if err != nil {
return nil, err
}
return rss, nil
}
func NewCrawler() crawler.Crawler {
c := &SMBHealthCrawler{}
c.SetMatcher(cnsms.NewMatcher())
return c
}

View File

@@ -0,0 +1,26 @@
package smb
import (
"encoding/json"
"testing"
ocsm "git.loafle.net/overflow/commons-go/sensorconfig/model"
"github.com/stretchr/testify/assert"
)
func TestMatch(t *testing.T) {
config := &ocsm.SensorConfig{}
config.Target = &ocsm.Target{}
config.Target.Connection = &ocsm.Connection{
IP: "192.168.1.106",
Port: json.Number(445),
PortType: "tcp",
SSL: false,
}
c := NewCrawler()
rss, err := c.Get(config)
assert.Nil(t, err)
assert.NotNil(t, rss)
}

View File

@@ -0,0 +1,30 @@
package smtp
import (
cnsms "git.loafle.net/commons/service_matcher-go/smtp"
ocsm "git.loafle.net/overflow/commons-go/sensorconfig/model"
"git.loafle.net/overflow/container_network/crawler/health"
crawler "git.loafle.net/overflow/crawler-go"
)
type SMTPHealthCrawler struct {
health.SocketHeahthCrawler
}
func (c *SMTPHealthCrawler) Name() string {
return "SMTP_HEALTH_CRAWLER"
}
func (c *SMTPHealthCrawler) Get(config *ocsm.SensorConfig) (map[string]string, error) {
rss, err := c.CheckHeahth(config)
if err != nil {
return nil, err
}
return rss, nil
}
func NewCrawler() crawler.Crawler {
c := &SMTPHealthCrawler{}
c.SetMatcher(cnsms.NewMatcher())
return c
}

View File

@@ -0,0 +1,26 @@
package smtp
import (
"encoding/json"
"testing"
ocsm "git.loafle.net/overflow/commons-go/sensorconfig/model"
"github.com/stretchr/testify/assert"
)
func TestMatch(t *testing.T) {
config := &ocsm.SensorConfig{}
config.Target = &ocsm.Target{}
config.Target.Connection = &ocsm.Connection{
IP: "192.168.1.215",
Port: json.Number(25),
PortType: "tcp",
SSL: false,
}
c := NewCrawler()
rss, err := c.Get(config)
assert.Nil(t, err)
assert.NotNil(t, rss)
}

View File

@@ -0,0 +1,30 @@
package v2
import (
cnsms "git.loafle.net/commons/service_matcher-go/snmp/v2"
ocsm "git.loafle.net/overflow/commons-go/sensorconfig/model"
"git.loafle.net/overflow/container_network/crawler/health"
"git.loafle.net/overflow/crawler-go"
)
type SNMPHealthCrawler struct {
health.SocketHeahthCrawler
}
func (c *SNMPHealthCrawler) Name() string {
return "SNMPV2C_HEALTH_CRAWLER"
}
func (c *SNMPHealthCrawler) Get(config *ocsm.SensorConfig) (map[string]string, error) {
rss, err := c.CheckHeahth(config)
if err != nil {
return nil, err
}
return rss, nil
}
func NewCrawler() crawler.Crawler {
c := &SNMPHealthCrawler{}
c.SetMatcher(cnsms.NewMatcher())
return c
}

View File

@@ -0,0 +1,26 @@
package v2
import (
"encoding/json"
"testing"
ocsm "git.loafle.net/overflow/commons-go/sensorconfig/model"
"github.com/stretchr/testify/assert"
)
func TestMatch(t *testing.T) {
config := &ocsm.SensorConfig{}
config.Target = &ocsm.Target{}
config.Target.Connection = &ocsm.Connection{
IP: "192.168.1.215",
Port: json.Number(161),
PortType: "udp",
SSL: false,
}
c := NewCrawler()
rss, err := c.Get(config)
assert.Nil(t, err)
assert.NotNil(t, rss)
}

View File

@@ -0,0 +1,30 @@
package v3
import (
cnsms "git.loafle.net/commons/service_matcher-go/snmp/v3"
ocsm "git.loafle.net/overflow/commons-go/sensorconfig/model"
"git.loafle.net/overflow/container_network/crawler/health"
"git.loafle.net/overflow/crawler-go"
)
type SNMPHealthCrawler struct {
health.SocketHeahthCrawler
}
func (c *SNMPHealthCrawler) Name() string {
return "SNMPV3_HEALTH_CRAWLER"
}
func (c *SNMPHealthCrawler) Get(config *ocsm.SensorConfig) (map[string]string, error) {
rss, err := c.CheckHeahth(config)
if err != nil {
return nil, err
}
return rss, nil
}
func NewCrawler() crawler.Crawler {
c := &SNMPHealthCrawler{}
c.SetMatcher(cnsms.NewMatcher())
return c
}

View File

@@ -0,0 +1,26 @@
package v3
import (
"encoding/json"
"testing"
ocsm "git.loafle.net/overflow/commons-go/sensorconfig/model"
"github.com/stretchr/testify/assert"
)
func TestMatch(t *testing.T) {
config := &ocsm.SensorConfig{}
config.Target = &ocsm.Target{}
config.Target.Connection = &ocsm.Connection{
IP: "192.168.1.254",
Port: json.Number(161),
PortType: "udp",
SSL: false,
}
c := NewCrawler()
rss, err := c.Get(config)
assert.Nil(t, err)
assert.NotNil(t, rss)
}

View File

@@ -0,0 +1,30 @@
package sqlserver
import (
cnsms "git.loafle.net/commons/service_matcher-go/sqlserver"
ocsm "git.loafle.net/overflow/commons-go/sensorconfig/model"
"git.loafle.net/overflow/container_network/crawler/health"
crawler "git.loafle.net/overflow/crawler-go"
)
type SQLServerHealthCrawler struct {
health.SocketHeahthCrawler
}
func (c *SQLServerHealthCrawler) Name() string {
return "SQLSERVER_HEALTH_CRAWLER"
}
func (c *SQLServerHealthCrawler) Get(config *ocsm.SensorConfig) (map[string]string, error) {
rss, err := c.CheckHeahth(config)
if err != nil {
return nil, err
}
return rss, nil
}
func NewCrawler() crawler.Crawler {
c := &SQLServerHealthCrawler{}
c.SetMatcher(cnsms.NewMatcher())
return c
}

View File

@@ -0,0 +1,26 @@
package sqlserver
import (
"encoding/json"
"testing"
ocsm "git.loafle.net/overflow/commons-go/sensorconfig/model"
"github.com/stretchr/testify/assert"
)
func TestMatch(t *testing.T) {
config := &ocsm.SensorConfig{}
config.Target = &ocsm.Target{}
config.Target.Connection = &ocsm.Connection{
IP: "192.168.1.106",
Port: json.Number(1433),
PortType: "tcp",
SSL: false,
}
c := NewCrawler()
rss, err := c.Get(config)
assert.Nil(t, err)
assert.NotNil(t, rss)
}

View File

@@ -0,0 +1,30 @@
package ssh
import (
cnsms "git.loafle.net/commons/service_matcher-go/ssh"
ocsm "git.loafle.net/overflow/commons-go/sensorconfig/model"
"git.loafle.net/overflow/container_network/crawler/health"
crawler "git.loafle.net/overflow/crawler-go"
)
type SSHHealthCrawler struct {
health.SocketHeahthCrawler
}
func (c *SSHHealthCrawler) Name() string {
return "SSH_HEALTH_CRAWLER"
}
func (c *SSHHealthCrawler) Get(config *ocsm.SensorConfig) (map[string]string, error) {
rss, err := c.CheckHeahth(config)
if err != nil {
return nil, err
}
return rss, nil
}
func NewCrawler() crawler.Crawler {
c := &SSHHealthCrawler{}
c.SetMatcher(cnsms.NewMatcher())
return c
}

View File

@@ -0,0 +1,26 @@
package ssh
import (
"encoding/json"
"testing"
ocsm "git.loafle.net/overflow/commons-go/sensorconfig/model"
"github.com/stretchr/testify/assert"
)
func TestMatch(t *testing.T) {
config := &ocsm.SensorConfig{}
config.Target = &ocsm.Target{}
config.Target.Connection = &ocsm.Connection{
IP: "192.168.1.215",
Port: json.Number(22),
PortType: "tcp",
SSL: false,
}
c := NewCrawler()
rss, err := c.Get(config)
assert.Nil(t, err)
assert.NotNil(t, rss)
}

View File

@@ -0,0 +1,30 @@
package telnet
import (
cnsmt "git.loafle.net/commons/service_matcher-go/telnet"
ocsm "git.loafle.net/overflow/commons-go/sensorconfig/model"
"git.loafle.net/overflow/container_network/crawler/health"
crawler "git.loafle.net/overflow/crawler-go"
)
type TelnetHealthCrawler struct {
health.SocketHeahthCrawler
}
func (c *TelnetHealthCrawler) Name() string {
return "TELNET_HEALTH_CRAWLER"
}
func (c *TelnetHealthCrawler) Get(config *ocsm.SensorConfig) (map[string]string, error) {
rss, err := c.CheckHeahth(config)
if err != nil {
return nil, err
}
return rss, nil
}
func NewCrawler() crawler.Crawler {
c := &TelnetHealthCrawler{}
c.SetMatcher(cnsmt.NewMatcher())
return c
}

View File

@@ -0,0 +1,26 @@
package telnet
import (
"encoding/json"
"testing"
ocsm "git.loafle.net/overflow/commons-go/sensorconfig/model"
"github.com/stretchr/testify/assert"
)
func TestMatch(t *testing.T) {
config := &ocsm.SensorConfig{}
config.Target = &ocsm.Target{}
config.Target.Connection = &ocsm.Connection{
IP: "192.168.1.215",
Port: json.Number(23),
PortType: "tcp",
SSL: false,
}
c := NewCrawler()
rss, err := c.Get(config)
assert.Nil(t, err)
assert.NotNil(t, rss)
}

View File

@@ -0,0 +1,30 @@
package wmi
import (
cnsmw "git.loafle.net/commons/service_matcher-go/wmi"
ocsm "git.loafle.net/overflow/commons-go/sensorconfig/model"
"git.loafle.net/overflow/container_network/crawler/health"
crawler "git.loafle.net/overflow/crawler-go"
)
type WMIHealthCrawler struct {
health.SocketHeahthCrawler
}
func (c *WMIHealthCrawler) Name() string {
return "WMI_HEALTH_CRAWLER"
}
func (c *WMIHealthCrawler) Get(config *ocsm.SensorConfig) (map[string]string, error) {
rss, err := c.CheckHeahth(config)
if err != nil {
return nil, err
}
return rss, nil
}
func NewCrawler() crawler.Crawler {
c := &WMIHealthCrawler{}
c.SetMatcher(cnsmw.NewMatcher())
return c
}

View File

@@ -0,0 +1,26 @@
package wmi
import (
"encoding/json"
"testing"
ocsm "git.loafle.net/overflow/commons-go/sensorconfig/model"
"github.com/stretchr/testify/assert"
)
func TestMatch(t *testing.T) {
config := &ocsm.SensorConfig{}
config.Target = &ocsm.Target{}
config.Target.Connection = &ocsm.Connection{
IP: "192.168.1.1",
Port: json.Number(135),
PortType: "tcp",
SSL: false,
}
c := NewCrawler()
rss, err := c.Get(config)
assert.Nil(t, err)
assert.NotNil(t, rss)
}

85
crawler/ssh/SSHCrawler.go Normal file
View File

@@ -0,0 +1,85 @@
package ssh
import (
"bufio"
"bytes"
"fmt"
ocsm "git.loafle.net/overflow/commons-go/sensorconfig/model"
"git.loafle.net/overflow/container_network/crawler/ssh/client"
"git.loafle.net/overflow/container_network/crawler/ssh/parser"
crawler "git.loafle.net/overflow/crawler-go"
sensorConfigUtil "git.loafle.net/overflow/overflow_commons_go/modules/sensor_config/util"
)
type SSHCrawler struct {
crawler.Crawler
}
func (c *SSHCrawler) Name() string {
return "SSH_CRAWLER"
}
func (c *SSHCrawler) Get(config *ocsm.SensorConfig) (map[string]string, error) {
sshClient, err := client.New(config.Target)
if nil != err {
return nil, err
}
itemCount := len(config.Items)
results := make(map[string]string, 0)
boundary := uuid.NewV4().String()
commands := ""
for i := 0; i < itemCount; i++ {
switch i {
case 0:
commands = config.Items[i].QueryInfo.Query
default:
commands = fmt.Sprintf("%s ; echo \"--%s\" ; %s ", commands, boundary, config.Items[i].QueryInfo.Query)
}
}
commands = fmt.Sprintf("%s ; echo \"--%s--\" ", commands, boundary)
buf, err := sshClient.RunCommand(commands)
if nil != err {
return nil, err
}
r := bytes.NewReader(buf)
scanner := bufio.NewScanner(r)
pScanner := parser.NewParserScanner(scanner, boundary)
for i := 0; i < itemCount; i++ {
item := config.Items[i]
mode := item.QueryInfo.Extend["mode"].(string)
p := parser.GetParser(mode)
if nil == p {
return nil, fmt.Errorf("Container: Parser[%s] is not exist", mode)
}
rm, err := p.Parse(pScanner)
if nil != err {
return nil, err
}
if nil != rm {
mm := sensorConfigUtil.KeysToMap(item.Keys)
for key, value := range mm {
results[value] = rm[key]
}
}
if !pScanner.Clean() {
break
}
}
return results, nil
}
func NewCrawler() crawler.Crawler {
c := &SSHCrawler{}
return c
}

View File

@@ -0,0 +1,30 @@
package ssh
import (
"encoding/json"
"io/ioutil"
"log"
"testing"
ocsm "git.loafle.net/overflow/commons-go/sensorconfig/model"
"github.com/stretchr/testify/assert"
)
func TestMatch(t *testing.T) {
config := &ocsm.SensorConfig{}
data, err := ioutil.ReadFile("./SSHCrawler_test.json")
if err != nil {
log.Fatal(err)
}
err = json.Unmarshal(data, config)
if err != nil {
log.Fatal(err)
}
c := NewCrawler().(*SSHCrawler)
rss, err := c.Get(config)
assert.Nil(t, err)
assert.NotNil(t, rss)
}

View File

@@ -0,0 +1,123 @@
{
"id": "99",
"target": {
"auth": {
"pw": "!@#$qwer1234",
"id": "administrator"
},
"connection": {
"ip": "192.168.1.15",
"port": "22",
"portType": "tcp",
"ssl": false
}
},
"schedule": {
"interval": "5"
},
"crawler": {
"name": "SSH_CRAWLER",
"container": "go_proxy"
},
"items": [{
"keys": [
{
"metric": "cpu.usage.sum",
"key": "sum"
},
{
"metric": "cpu.usage.user",
"key": "user"
},
{
"metric": "cpu.usage.nice",
"key": "nice"
},
{
"metric": "cpu.usage.system",
"key": "system"
},
{
"metric": "cpu.usage.iowait",
"key": "iowait"
},
{
"metric": "cpu.usage.irq",
"key": "irq"
},
{
"metric": "cpu.usage.softirq",
"key": "softirq"
},
{
"metric": "cpu.usage.steal",
"key": "steal"
},
{
"metric": "cpu.usage.guest",
"key": "guest"
},
{
"metric": "cpu.usage.gnice",
"key": "gnice"
}],
"queryInfo": {
"query": "cat /proc/stat",
"extend": {
"mode" : "cpu"
}
},
"mappingInfo": {
"parseDirection": null,
"arrayColumns": null,
"keyColumns": null,
"valueColumn": null
}
},
{
"keys": [{
"metric": "mem.usage.total",
"key": "MemTotal"
},
{
"metric": "mem.usage.free",
"key": "MemFree"
},
{
"metric": "mem.usage.available",
"key": "MemAvailable"
},
{
"metric": "mem.usage.buffers",
"key": "Buffers"
},
{
"metric": "mem.usage.cached",
"key": "Cached"
},
{
"metric": "mem.swap.usage.total",
"key": "SwapTotal"
},
{
"metric": "mem.swap.usage.free",
"key": "SwapFree"
},
{
"metric": "mem.swap.usage.cached",
"key": "SwapCached"
}],
"queryInfo": {
"query": "cat /proc/meminfo",
"extend": {
"mode": "mem"
}
},
"mappingInfo": {
"parseDirection": null,
"arrayColumns": null,
"keyColumns": null,
"valueColumn": null
}
}]
}

View File

@@ -0,0 +1,127 @@
package client
import (
"bytes"
"fmt"
"io/ioutil"
"time"
"git.loafle.net/commons_go/logging"
cuej "git.loafle.net/commons_go/util/encoding/json"
ocsm "git.loafle.net/overflow/commons-go/sensorconfig/model"
"golang.org/x/crypto/ssh"
)
type SSHConfig struct {
User string
Auth []ssh.AuthMethod
Host string
Port int
}
type SSHClient struct {
conf *SSHConfig
}
func (cli *SSHClient) Session() (*ssh.Session, error) {
sshConfig := &ssh.ClientConfig{
User: cli.conf.User,
Auth: cli.conf.Auth,
HostKeyCallback: ssh.InsecureIgnoreHostKey(),
Timeout: time.Second * 10,
}
addr := fmt.Sprintf("%s:%d", cli.conf.Host, cli.conf.Port)
connection, err := ssh.Dial("tcp", addr, sshConfig)
if err != nil {
return nil, err
}
session, err := connection.NewSession()
if err != nil {
return nil, err
}
modes := ssh.TerminalModes{
ssh.ECHO: 0, // disable echoing
ssh.TTY_OP_ISPEED: 14400, // input speed = 14.4kbaud
ssh.TTY_OP_OSPEED: 14400, // output speed = 14.4kbaud
}
if err := session.RequestPty("xterm", 80, 40, modes); err != nil {
session.Close()
return nil, err
}
return session, nil
}
func (cli *SSHClient) RunCommand(command string) ([]byte, error) {
session, err := cli.Session()
if nil != err {
return nil, err
}
defer func() {
session.Close()
}()
var b bytes.Buffer
session.Stdout = &b
logging.Logger().Debugf("%s \n", command)
if err := session.Run(command); nil != err {
return nil, err
}
return b.Bytes(), nil
}
func parsePrivateKey(keyPath, pw string) (ssh.Signer, error) {
buff, err := ioutil.ReadFile(keyPath)
if err != nil {
return nil, err
}
if pw == "" {
return ssh.ParsePrivateKey(buff)
}
return ssh.ParsePrivateKeyWithPassphrase(buff, []byte(pw))
}
func New(target *ocsm.Target) (*SSHClient, error) {
connection := target.Connection
auth := target.Auth
ip := connection.IP
port, _ := cuej.NumberToInt(connection.Port)
user := auth["id"].(string)
pw := auth["pw"].(string)
keyFilePathObj := auth["keyFilePath"]
keyFilePath := ""
sshAuth := make([]ssh.AuthMethod, 0)
if keyFilePathObj != nil {
keyFilePath = keyFilePathObj.(string)
if "" != keyFilePath {
key, err := parsePrivateKey(keyFilePath, pw)
if err != nil {
return nil, err
}
sshAuth = append(sshAuth, ssh.PublicKeys(key))
}
}
sshAuth = append(sshAuth, ssh.Password(pw))
sshConf := &SSHConfig{
User: user,
Auth: sshAuth,
Host: ip,
Port: port,
}
return &SSHClient{
conf: sshConf,
}, nil
}

View File

@@ -0,0 +1,99 @@
package parser
import (
"strconv"
"strings"
)
type CPUParser struct {
}
func (p *CPUParser) Name() string {
return "cpu"
}
func (p *CPUParser) Parse(scanner *ParserScanner) (map[string]string, error) {
resMap := make(map[string]string, 0)
for scanner.Scan() {
line := scanner.Text()
parts := strings.Fields(line)
if !strings.HasPrefix(parts[0], "cpu") {
continue
}
//var steal, guest, guestNice int64
//if len(parts) > 8 {
// steal = util.StringToInt64(parts[8])
//}
//if len(parts) > 9 {
// guest = util.StringToInt64(parts[9])
//}
if 10 >= len(parts) {
//guestNice = util.StringToInt64(parts[10])
continue
}
//stats = append(stats, CPUStat{
//Device := util.StringToInt64(parts[0])
// User := util.StringToInt64(parts[1])
// Nice := util.StringToInt64(parts[2])
// System := util.StringToInt64(parts[3])
// Idle := util.StringToInt64(parts[4])
// Iowait := util.StringToInt64(parts[5])
// Irq := util.StringToInt64(parts[6])
// SoftIrq := util.StringToInt64(parts[7])
// Steal := util.StringToInt64(parts[8])
// Guest := util.StringToInt64(parts[9])
// GuestNice := util.StringToInt64(parts[10])
//})
// sum := User + Nice + System + Idle + Iowait + Irq + SoftIrq + Steal + Guest + GuestNice
sum := sumFromStrings(parts, 1, 11, nil)
resMap["sum"] = strconv.FormatInt(sum, 10)
resMap["user"] = parts[1]
resMap["nice"] = parts[2]
resMap["system"] = parts[3]
resMap["idle"] = parts[4]
resMap["iowait"] = parts[5]
resMap["irq"] = parts[6]
resMap["softIrq"] = parts[7]
resMap["steal"] = parts[8]
resMap["guest"] = parts[9]
resMap["gnice"] = parts[10]
break // first line only --- cpu
}
//res, err := cpu.parse(keys, stats)
//if err != nil {
// return nil, err
//}
return resMap, scanner.Err()
}
func sumFromStrings(ss []string, startIndex, endIndex int, exclude []int) int64 {
if nil == ss {
return 0
}
var result int64
Loop:
for i := startIndex; i < endIndex; i++ {
if nil != exclude {
for j := 0; j < len(exclude); j++ {
if exclude[j] == i {
continue Loop
}
}
}
i64, _ := strconv.ParseInt(ss[i], 10, 64)
result += i64
}
return result
}

View File

@@ -0,0 +1,33 @@
package parser
import (
"strings"
)
type MemoryParser struct {
}
func (p *MemoryParser) Name() string {
return "mem"
}
func (p *MemoryParser) Parse(scanner *ParserScanner) (map[string]string, error) {
var (
stats = map[string]string{}
)
for scanner.Scan() {
line := scanner.Text()
parts := strings.Fields(line)
key := parts[0][:len(parts[0])-1]
stats[key] = parts[1]
}
//res, err := mem.parse(keys, stats)
//if err != nil {
// return nil, err
//}
return stats, scanner.Err()
}

View File

@@ -0,0 +1,111 @@
package parser
import "bufio"
var parsers map[string]Parser
func init() {
parsers = make(map[string]Parser, 0)
addParser(&CPUParser{})
addParser(&MemoryParser{})
}
func addParser(p Parser) {
parsers[p.Name()] = p
}
func GetParser(name string) Parser {
p, ok := parsers[name]
if !ok {
return nil
}
return p
}
type Parser interface {
Name() string
Parse(scanner *ParserScanner) (map[string]string, error)
}
type ParserScanner struct {
scanner *bufio.Scanner
boundary string
text string
ended bool
eof bool
}
func (ps *ParserScanner) Clean() bool {
if ps.eof {
return false
}
if ps.ended {
ps.ended = false
return true
}
for ps.scanner.Scan() {
line := ps.scanner.Text()
if line == "--"+ps.boundary+"--" {
ps.eof = true
return false
}
if line == "--"+ps.boundary {
break
}
}
return true
}
func (ps *ParserScanner) EOF() bool {
return ps.eof
}
func (ps *ParserScanner) Scan() bool {
if ps.eof || ps.ended {
return false
}
if !ps.scanner.Scan() {
return false
}
line := ps.scanner.Text()
if line == "--"+ps.boundary+"--" {
ps.eof = true
return false
}
if line == "--"+ps.boundary {
ps.ended = true
return false
}
ps.text = line
return true
}
func (ps *ParserScanner) Text() string {
if ps.eof || ps.ended {
return ""
}
return ps.text
}
func (ps *ParserScanner) Err() error {
return ps.scanner.Err()
}
func NewParserScanner(scanner *bufio.Scanner, boundary string) *ParserScanner {
ps := &ParserScanner{
scanner: scanner,
boundary: boundary,
}
return ps
}