diff --git a/collector/pkg/collector/base.go b/collector/pkg/collector/base.go index d0768a9..2269dee 100644 --- a/collector/pkg/collector/base.go +++ b/collector/pkg/collector/base.go @@ -23,6 +23,18 @@ type BaseCollector struct { func (c *BaseCollector) DetectStorageDevices() ([]models.Device, error) { + //availableDisksJson, err := c.ExecCmd("smartctl", []string{"-j", "--scan"}, "", os.Environ()) + //if err != nil { + // c.logger.Errorf("Error getting block storage info: %v", err) + // return nil, err + //} + // + //var smartctlScan models.Scan + //err = json.Unmarshal([]byte(availableDisksJson), &smartctlScan) + //if err != nil { + // return nil, err + //} + block, err := ghw.Block() if err != nil { c.logger.Errorf("Error getting block storage info: %v", err) @@ -83,7 +95,6 @@ func (c *BaseCollector) DetectStorageDevices() ([]models.Device, error) { approvedDisks = append(approvedDisks, diskModel) } - return approvedDisks, nil } diff --git a/collector/pkg/models/device.go b/collector/pkg/models/device.go index fcac712..ecfcb06 100644 --- a/collector/pkg/models/device.go +++ b/collector/pkg/models/device.go @@ -14,6 +14,8 @@ type Device struct { Capacity int64 `json:"capacity"` FormFactor string `json:"form_factor"` SmartSupport bool `json:"smart_support"` + DeviceProtocol string `json:"device_protocol"` //protocol determines which smart attribute types are available (ATA, NVMe, SCSI) + DeviceType string `json:"device_type"` //device type is used for querying with -d/t flag, should only be used by collector. } type DeviceWrapper struct { diff --git a/collector/pkg/models/scan.go b/collector/pkg/models/scan.go new file mode 100644 index 0000000..d85ff57 --- /dev/null +++ b/collector/pkg/models/scan.go @@ -0,0 +1,19 @@ +package models + +type Scan struct { + JSONFormatVersion []int `json:"json_format_version"` + Smartctl struct { + Version []int `json:"version"` + SvnRevision string `json:"svn_revision"` + PlatformInfo string `json:"platform_info"` + BuildInfo string `json:"build_info"` + Argv []string `json:"argv"` + ExitStatus int `json:"exit_status"` + } `json:"smartctl"` + Devices []struct { + Name string `json:"name"` + InfoName string `json:"info_name"` + Type string `json:"type"` + Protocol string `json:"protocol"` + } `json:"devices"` +} diff --git a/example.scrutiny.yaml b/example.scrutiny.yaml index 593d484..8872922 100644 --- a/example.scrutiny.yaml +++ b/example.scrutiny.yaml @@ -34,7 +34,6 @@ disks: # - /dev/sdb notify: - level: 'warn' # 'warn' or 'error' urls: - "discord://token@channel" - "telegram://token@telegram?channels=channel-1[,channel-2,...]" @@ -52,6 +51,21 @@ notify: - "script:///file/path/on/disk" - "https://www.example.com/path" +limits: + ata: + critical: + error: 10 + standard: + error: 20 + warn: 10 + scsi: + critical: true + standard: true + nvme: + critical: true + standard: true + + collect: metric: enable: true diff --git a/webapp/backend/pkg/models/db/device.go b/webapp/backend/pkg/models/db/device.go index 1aa147b..8721cea 100644 --- a/webapp/backend/pkg/models/db/device.go +++ b/webapp/backend/pkg/models/db/device.go @@ -34,8 +34,8 @@ type Device struct { Capacity int64 `json:"capacity"` FormFactor string `json:"form_factor"` SmartSupport bool `json:"smart_support"` - DeviceProtocol string `json:"device_protocol"` - DeviceType string `json:"device_type"` //device type is used for querying with -d/t flag + DeviceProtocol string `json:"device_protocol"` //protocol determines which smart attribute types are available (ATA, NVMe, SCSI) + DeviceType string `json:"device_type"` //device type is used for querying with -d/t flag, should only be used by collector. SmartResults []Smart `gorm:"foreignkey:DeviceWWN" json:"smart_results"` } diff --git a/webapp/backend/pkg/models/testdata/smart-ata-full.json b/webapp/backend/pkg/models/testdata/smart-ata-full.json new file mode 100644 index 0000000..82b5250 --- /dev/null +++ b/webapp/backend/pkg/models/testdata/smart-ata-full.json @@ -0,0 +1,1708 @@ +{ + "json_format_version": [ + 1, + 0 + ], + "smartctl": { + "version": [ + 7, + 0 + ], + "svn_revision": "4883", + "platform_info": "x86_64-linux-4.19.143-flatcar", + "build_info": "(local build)", + "argv": [ + "smartctl", + "-x", + "-j", + "/dev/sda" + ], + "exit_status": 0 + }, + "device": { + "name": "/dev/sda", + "info_name": "/dev/sda [SAT]", + "type": "sat", + "protocol": "ATA" + }, + "model_family": "Samsung based SSDs", + "model_name": "Samsung SSD 860 EVO 500GB", + "serial_number": "S3YZNB0KB00864E", + "wwn": { + "naa": 5, + "oui": 9528, + "id": 61213911380 + }, + "firmware_version": "RVT02B6Q", + "user_capacity": { + "blocks": 976773168, + "bytes": 500107862016 + }, + "logical_block_size": 512, + "physical_block_size": 512, + "rotation_rate": 0, + "form_factor": { + "ata_value": 3, + "name": "2.5 inches" + }, + "in_smartctl_database": true, + "ata_version": { + "string": "ACS-4 T13/BSR INCITS 529 revision 5", + "major_value": 2556, + "minor_value": 94 + }, + "sata_version": { + "string": "SATA 3.1", + "value": 127 + }, + "interface_speed": { + "max": { + "sata_value": 14, + "string": "6.0 Gb/s", + "units_per_second": 60, + "bits_per_unit": 100000000 + }, + "current": { + "sata_value": 3, + "string": "6.0 Gb/s", + "units_per_second": 60, + "bits_per_unit": 100000000 + } + }, + "local_time": { + "time_t": 1600014563, + "asctime": "Sun Sep 13 16:29:23 2020 UTC" + }, + "read_lookahead": { + "enabled": true + }, + "write_cache": { + "enabled": true + }, + "ata_security": { + "state": 33, + "string": "Disabled, NOT FROZEN [SEC1]", + "enabled": false, + "frozen": false + }, + "smart_status": { + "passed": true + }, + "ata_smart_data": { + "offline_data_collection": { + "status": { + "value": 128, + "string": "was never started" + }, + "completion_seconds": 0 + }, + "self_test": { + "status": { + "value": 0, + "string": "completed without error", + "passed": true + }, + "polling_minutes": { + "short": 2, + "extended": 85 + } + }, + "capabilities": { + "values": [ + 83, + 3 + ], + "exec_offline_immediate_supported": true, + "offline_is_aborted_upon_new_cmd": false, + "offline_surface_scan_supported": false, + "self_tests_supported": true, + "conveyance_self_test_supported": false, + "selective_self_test_supported": true, + "attribute_autosave_enabled": true, + "error_logging_supported": true, + "gp_logging_supported": true + } + }, + "ata_sct_capabilities": { + "value": 61, + "error_recovery_control_supported": true, + "feature_control_supported": true, + "data_table_supported": true + }, + "ata_smart_attributes": { + "revision": 1, + "table": [ + { + "id": 5, + "name": "Reallocated_Sector_Ct", + "value": 100, + "worst": 100, + "thresh": 10, + "when_failed": "", + "flags": { + "value": 51, + "string": "PO--CK ", + "prefailure": true, + "updated_online": true, + "performance": false, + "error_rate": false, + "event_count": true, + "auto_keep": true + }, + "raw": { + "value": 0, + "string": "0" + } + }, + { + "id": 9, + "name": "Power_On_Hours", + "value": 97, + "worst": 97, + "thresh": 0, + "when_failed": "", + "flags": { + "value": 50, + "string": "-O--CK ", + "prefailure": false, + "updated_online": true, + "performance": false, + "error_rate": false, + "event_count": true, + "auto_keep": true + }, + "raw": { + "value": 14551, + "string": "14551" + } + }, + { + "id": 12, + "name": "Power_Cycle_Count", + "value": 99, + "worst": 99, + "thresh": 0, + "when_failed": "", + "flags": { + "value": 50, + "string": "-O--CK ", + "prefailure": false, + "updated_online": true, + "performance": false, + "error_rate": false, + "event_count": true, + "auto_keep": true + }, + "raw": { + "value": 13, + "string": "13" + } + }, + { + "id": 177, + "name": "Wear_Leveling_Count", + "value": 81, + "worst": 81, + "thresh": 0, + "when_failed": "", + "flags": { + "value": 19, + "string": "PO--C- ", + "prefailure": true, + "updated_online": true, + "performance": false, + "error_rate": false, + "event_count": true, + "auto_keep": false + }, + "raw": { + "value": 278, + "string": "278" + } + }, + { + "id": 179, + "name": "Used_Rsvd_Blk_Cnt_Tot", + "value": 100, + "worst": 100, + "thresh": 10, + "when_failed": "", + "flags": { + "value": 19, + "string": "PO--C- ", + "prefailure": true, + "updated_online": true, + "performance": false, + "error_rate": false, + "event_count": true, + "auto_keep": false + }, + "raw": { + "value": 0, + "string": "0" + } + }, + { + "id": 181, + "name": "Program_Fail_Cnt_Total", + "value": 100, + "worst": 100, + "thresh": 10, + "when_failed": "", + "flags": { + "value": 50, + "string": "-O--CK ", + "prefailure": false, + "updated_online": true, + "performance": false, + "error_rate": false, + "event_count": true, + "auto_keep": true + }, + "raw": { + "value": 0, + "string": "0" + } + }, + { + "id": 182, + "name": "Erase_Fail_Count_Total", + "value": 100, + "worst": 100, + "thresh": 10, + "when_failed": "", + "flags": { + "value": 50, + "string": "-O--CK ", + "prefailure": false, + "updated_online": true, + "performance": false, + "error_rate": false, + "event_count": true, + "auto_keep": true + }, + "raw": { + "value": 0, + "string": "0" + } + }, + { + "id": 183, + "name": "Runtime_Bad_Block", + "value": 100, + "worst": 100, + "thresh": 10, + "when_failed": "", + "flags": { + "value": 19, + "string": "PO--C- ", + "prefailure": true, + "updated_online": true, + "performance": false, + "error_rate": false, + "event_count": true, + "auto_keep": false + }, + "raw": { + "value": 0, + "string": "0" + } + }, + { + "id": 187, + "name": "Uncorrectable_Error_Cnt", + "value": 100, + "worst": 100, + "thresh": 0, + "when_failed": "", + "flags": { + "value": 50, + "string": "-O--CK ", + "prefailure": false, + "updated_online": true, + "performance": false, + "error_rate": false, + "event_count": true, + "auto_keep": true + }, + "raw": { + "value": 0, + "string": "0" + } + }, + { + "id": 190, + "name": "Airflow_Temperature_Cel", + "value": 64, + "worst": 43, + "thresh": 0, + "when_failed": "", + "flags": { + "value": 50, + "string": "-O--CK ", + "prefailure": false, + "updated_online": true, + "performance": false, + "error_rate": false, + "event_count": true, + "auto_keep": true + }, + "raw": { + "value": 36, + "string": "36" + } + }, + { + "id": 195, + "name": "ECC_Error_Rate", + "value": 200, + "worst": 200, + "thresh": 0, + "when_failed": "", + "flags": { + "value": 26, + "string": "-O-RC- ", + "prefailure": false, + "updated_online": true, + "performance": false, + "error_rate": true, + "event_count": true, + "auto_keep": false + }, + "raw": { + "value": 0, + "string": "0" + } + }, + { + "id": 199, + "name": "CRC_Error_Count", + "value": 100, + "worst": 100, + "thresh": 0, + "when_failed": "", + "flags": { + "value": 62, + "string": "-OSRCK ", + "prefailure": false, + "updated_online": true, + "performance": true, + "error_rate": true, + "event_count": true, + "auto_keep": true + }, + "raw": { + "value": 0, + "string": "0" + } + }, + { + "id": 235, + "name": "POR_Recovery_Count", + "value": 99, + "worst": 99, + "thresh": 0, + "when_failed": "", + "flags": { + "value": 18, + "string": "-O--C- ", + "prefailure": false, + "updated_online": true, + "performance": false, + "error_rate": false, + "event_count": true, + "auto_keep": false + }, + "raw": { + "value": 4, + "string": "4" + } + }, + { + "id": 241, + "name": "Total_LBAs_Written", + "value": 99, + "worst": 99, + "thresh": 0, + "when_failed": "", + "flags": { + "value": 50, + "string": "-O--CK ", + "prefailure": false, + "updated_online": true, + "performance": false, + "error_rate": false, + "event_count": true, + "auto_keep": true + }, + "raw": { + "value": 64777770148, + "string": "64777770148" + } + } + ] + }, + "power_on_time": { + "hours": 14551 + }, + "power_cycle_count": 13, + "temperature": { + "current": 36, + "power_cycle_min": 28, + "power_cycle_max": 57, + "lifetime_min": 24, + "lifetime_max": 57, + "op_limit_max": 70, + "op_limit_min": 0, + "limit_min": 0, + "limit_max": 70 + }, + "ata_log_directory": { + "gp_dir_version": 1, + "smart_dir_version": 1, + "smart_dir_multi_sector": true, + "table": [ + { + "address": 0, + "name": "Log Directory", + "read": true, + "write": false, + "gp_sectors": 1, + "smart_sectors": 1 + }, + { + "address": 1, + "name": "Summary SMART error log", + "read": true, + "write": false, + "smart_sectors": 1 + }, + { + "address": 2, + "name": "Comprehensive SMART error log", + "read": true, + "write": false, + "smart_sectors": 1 + }, + { + "address": 3, + "name": "Ext. Comprehensive SMART error log", + "read": true, + "write": false, + "gp_sectors": 1 + }, + { + "address": 4, + "name": "Device Statistics log", + "read": true, + "write": false, + "gp_sectors": 8, + "smart_sectors": 8 + }, + { + "address": 6, + "name": "SMART self-test log", + "read": true, + "write": false, + "smart_sectors": 1 + }, + { + "address": 7, + "name": "Extended self-test log", + "read": true, + "write": false, + "gp_sectors": 1 + }, + { + "address": 9, + "name": "Selective self-test log", + "read": true, + "write": true, + "smart_sectors": 1 + }, + { + "address": 16, + "name": "NCQ Command Error log", + "read": true, + "write": false, + "gp_sectors": 1 + }, + { + "address": 17, + "name": "SATA Phy Event Counters log", + "read": true, + "write": false, + "gp_sectors": 1 + }, + { + "address": 19, + "name": "SATA NCQ Send and Receive log", + "read": true, + "write": false, + "gp_sectors": 1 + }, + { + "address": 48, + "name": "IDENTIFY DEVICE data log", + "read": true, + "write": false, + "gp_sectors": 9, + "smart_sectors": 9 + }, + { + "address": 128, + "name": "Host vendor specific log", + "read": true, + "write": true, + "gp_sectors": 16, + "smart_sectors": 16 + }, + { + "address": 129, + "name": "Host vendor specific log", + "read": true, + "write": true, + "gp_sectors": 16, + "smart_sectors": 16 + }, + { + "address": 130, + "name": "Host vendor specific log", + "read": true, + "write": true, + "gp_sectors": 16, + "smart_sectors": 16 + }, + { + "address": 131, + "name": "Host vendor specific log", + "read": true, + "write": true, + "gp_sectors": 16, + "smart_sectors": 16 + }, + { + "address": 132, + "name": "Host vendor specific log", + "read": true, + "write": true, + "gp_sectors": 16, + "smart_sectors": 16 + }, + { + "address": 133, + "name": "Host vendor specific log", + "read": true, + "write": true, + "gp_sectors": 16, + "smart_sectors": 16 + }, + { + "address": 134, + "name": "Host vendor specific log", + "read": true, + "write": true, + "gp_sectors": 16, + "smart_sectors": 16 + }, + { + "address": 135, + "name": "Host vendor specific log", + "read": true, + "write": true, + "gp_sectors": 16, + "smart_sectors": 16 + }, + { + "address": 136, + "name": "Host vendor specific log", + "read": true, + "write": true, + "gp_sectors": 16, + "smart_sectors": 16 + }, + { + "address": 137, + "name": "Host vendor specific log", + "read": true, + "write": true, + "gp_sectors": 16, + "smart_sectors": 16 + }, + { + "address": 138, + "name": "Host vendor specific log", + "read": true, + "write": true, + "gp_sectors": 16, + "smart_sectors": 16 + }, + { + "address": 139, + "name": "Host vendor specific log", + "read": true, + "write": true, + "gp_sectors": 16, + "smart_sectors": 16 + }, + { + "address": 140, + "name": "Host vendor specific log", + "read": true, + "write": true, + "gp_sectors": 16, + "smart_sectors": 16 + }, + { + "address": 141, + "name": "Host vendor specific log", + "read": true, + "write": true, + "gp_sectors": 16, + "smart_sectors": 16 + }, + { + "address": 142, + "name": "Host vendor specific log", + "read": true, + "write": true, + "gp_sectors": 16, + "smart_sectors": 16 + }, + { + "address": 143, + "name": "Host vendor specific log", + "read": true, + "write": true, + "gp_sectors": 16, + "smart_sectors": 16 + }, + { + "address": 144, + "name": "Host vendor specific log", + "read": true, + "write": true, + "gp_sectors": 16, + "smart_sectors": 16 + }, + { + "address": 145, + "name": "Host vendor specific log", + "read": true, + "write": true, + "gp_sectors": 16, + "smart_sectors": 16 + }, + { + "address": 146, + "name": "Host vendor specific log", + "read": true, + "write": true, + "gp_sectors": 16, + "smart_sectors": 16 + }, + { + "address": 147, + "name": "Host vendor specific log", + "read": true, + "write": true, + "gp_sectors": 16, + "smart_sectors": 16 + }, + { + "address": 148, + "name": "Host vendor specific log", + "read": true, + "write": true, + "gp_sectors": 16, + "smart_sectors": 16 + }, + { + "address": 149, + "name": "Host vendor specific log", + "read": true, + "write": true, + "gp_sectors": 16, + "smart_sectors": 16 + }, + { + "address": 150, + "name": "Host vendor specific log", + "read": true, + "write": true, + "gp_sectors": 16, + "smart_sectors": 16 + }, + { + "address": 151, + "name": "Host vendor specific log", + "read": true, + "write": true, + "gp_sectors": 16, + "smart_sectors": 16 + }, + { + "address": 152, + "name": "Host vendor specific log", + "read": true, + "write": true, + "gp_sectors": 16, + "smart_sectors": 16 + }, + { + "address": 153, + "name": "Host vendor specific log", + "read": true, + "write": true, + "gp_sectors": 16, + "smart_sectors": 16 + }, + { + "address": 154, + "name": "Host vendor specific log", + "read": true, + "write": true, + "gp_sectors": 16, + "smart_sectors": 16 + }, + { + "address": 155, + "name": "Host vendor specific log", + "read": true, + "write": true, + "gp_sectors": 16, + "smart_sectors": 16 + }, + { + "address": 156, + "name": "Host vendor specific log", + "read": true, + "write": true, + "gp_sectors": 16, + "smart_sectors": 16 + }, + { + "address": 157, + "name": "Host vendor specific log", + "read": true, + "write": true, + "gp_sectors": 16, + "smart_sectors": 16 + }, + { + "address": 158, + "name": "Host vendor specific log", + "read": true, + "write": true, + "gp_sectors": 16, + "smart_sectors": 16 + }, + { + "address": 159, + "name": "Host vendor specific log", + "read": true, + "write": true, + "gp_sectors": 16, + "smart_sectors": 16 + }, + { + "address": 161, + "name": "Device vendor specific log", + "smart_sectors": 16 + }, + { + "address": 165, + "name": "Device vendor specific log", + "smart_sectors": 16 + }, + { + "address": 206, + "name": "Device vendor specific log", + "smart_sectors": 16 + }, + { + "address": 207, + "name": "Device vendor specific log", + "smart_sectors": 16 + }, + { + "address": 224, + "name": "SCT Command/Status", + "read": true, + "write": true, + "gp_sectors": 1, + "smart_sectors": 1 + }, + { + "address": 225, + "name": "SCT Data Transfer", + "read": true, + "write": true, + "gp_sectors": 1, + "smart_sectors": 1 + } + ] + }, + "ata_smart_error_log": { + "extended": { + "revision": 1, + "sectors": 1, + "count": 0 + } + }, + "ata_smart_self_test_log": { + "extended": { + "revision": 1, + "sectors": 1, + "table": [ + { + "type": { + "value": 1, + "string": "Short offline" + }, + "status": { + "value": 0, + "string": "Completed without error", + "passed": true + }, + "lifetime_hours": 14417 + }, + { + "type": { + "value": 1, + "string": "Short offline" + }, + "status": { + "value": 0, + "string": "Completed without error", + "passed": true + }, + "lifetime_hours": 13985 + }, + { + "type": { + "value": 1, + "string": "Short offline" + }, + "status": { + "value": 0, + "string": "Completed without error", + "passed": true + }, + "lifetime_hours": 12689 + }, + { + "type": { + "value": 2, + "string": "Extended offline" + }, + "status": { + "value": 0, + "string": "Completed without error", + "passed": true + }, + "lifetime_hours": 12667 + }, + { + "type": { + "value": 1, + "string": "Short offline" + }, + "status": { + "value": 0, + "string": "Completed without error", + "passed": true + }, + "lifetime_hours": 12665 + }, + { + "type": { + "value": 1, + "string": "Short offline" + }, + "status": { + "value": 0, + "string": "Completed without error", + "passed": true + }, + "lifetime_hours": 12641 + }, + { + "type": { + "value": 1, + "string": "Short offline" + }, + "status": { + "value": 0, + "string": "Completed without error", + "passed": true + }, + "lifetime_hours": 12593 + }, + { + "type": { + "value": 1, + "string": "Short offline" + }, + "status": { + "value": 0, + "string": "Completed without error", + "passed": true + }, + "lifetime_hours": 12569 + }, + { + "type": { + "value": 1, + "string": "Short offline" + }, + "status": { + "value": 0, + "string": "Completed without error", + "passed": true + }, + "lifetime_hours": 12545 + }, + { + "type": { + "value": 1, + "string": "Short offline" + }, + "status": { + "value": 0, + "string": "Completed without error", + "passed": true + }, + "lifetime_hours": 12521 + }, + { + "type": { + "value": 2, + "string": "Extended offline" + }, + "status": { + "value": 0, + "string": "Completed without error", + "passed": true + }, + "lifetime_hours": 12499 + }, + { + "type": { + "value": 1, + "string": "Short offline" + }, + "status": { + "value": 0, + "string": "Completed without error", + "passed": true + }, + "lifetime_hours": 12497 + }, + { + "type": { + "value": 1, + "string": "Short offline" + }, + "status": { + "value": 0, + "string": "Completed without error", + "passed": true + }, + "lifetime_hours": 12473 + }, + { + "type": { + "value": 1, + "string": "Short offline" + }, + "status": { + "value": 0, + "string": "Completed without error", + "passed": true + }, + "lifetime_hours": 12449 + }, + { + "type": { + "value": 1, + "string": "Short offline" + }, + "status": { + "value": 0, + "string": "Completed without error", + "passed": true + }, + "lifetime_hours": 12425 + }, + { + "type": { + "value": 1, + "string": "Short offline" + }, + "status": { + "value": 0, + "string": "Completed without error", + "passed": true + }, + "lifetime_hours": 12401 + }, + { + "type": { + "value": 1, + "string": "Short offline" + }, + "status": { + "value": 0, + "string": "Completed without error", + "passed": true + }, + "lifetime_hours": 12377 + }, + { + "type": { + "value": 1, + "string": "Short offline" + }, + "status": { + "value": 0, + "string": "Completed without error", + "passed": true + }, + "lifetime_hours": 12353 + }, + { + "type": { + "value": 2, + "string": "Extended offline" + }, + "status": { + "value": 0, + "string": "Completed without error", + "passed": true + }, + "lifetime_hours": 12331 + } + ], + "count": 19, + "error_count_total": 0, + "error_count_outdated": 0 + } + }, + "ata_smart_selective_self_test_log": { + "revision": 1, + "table": [ + { + "lba_min": 0, + "lba_max": 0, + "status": { + "value": 0, + "string": "Not_testing" + } + }, + { + "lba_min": 0, + "lba_max": 0, + "status": { + "value": 0, + "string": "Not_testing" + } + }, + { + "lba_min": 0, + "lba_max": 0, + "status": { + "value": 0, + "string": "Not_testing" + } + }, + { + "lba_min": 0, + "lba_max": 0, + "status": { + "value": 0, + "string": "Not_testing" + } + }, + { + "lba_min": 0, + "lba_max": 0, + "status": { + "value": 0, + "string": "Not_testing" + } + } + ], + "flags": { + "value": 0, + "remainder_scan_enabled": false + }, + "power_up_scan_resume_minutes": 0 + }, + "ata_sct_status": { + "format_version": 3, + "sct_version": 256, + "device_state": { + "value": 0, + "string": "Active" + }, + "temperature": { + "current": 36, + "power_cycle_min": 28, + "power_cycle_max": 57, + "lifetime_min": 24, + "lifetime_max": 57, + "op_limit_max": 70, + "under_limit_count": 0, + "over_limit_count": 0 + }, + "smart_status": { + "passed": true + } + }, + "ata_sct_temperature_history": { + "version": 2, + "sampling_period_minutes": 1, + "logging_interval_minutes": 10, + "temperature": { + "op_limit_min": 0, + "op_limit_max": 70, + "limit_min": 0, + "limit_max": 70 + }, + "size": 128, + "index": 30, + "table": [ + 39, + 39, + 39, + 39, + 39, + 40, + 40, + 40, + 39, + 39, + 39, + 39, + 39, + 39, + 39, + 39, + 39, + 39, + 39, + 39, + 39, + 39, + 39, + 39, + 39, + 38, + 38, + 38, + 38, + 38, + 38, + 38, + 38, + 39, + 39, + 39, + 39, + 39, + 39, + 39, + 39, + 39, + 39, + 39, + 38, + 38, + 38, + 39, + 41, + 42, + 42, + 41, + 42, + 43, + 41, + 40, + 40, + 41, + 41, + 41, + 41, + 42, + 41, + 41, + 42, + 41, + 39, + 38, + 37, + 38, + 38, + 38, + 38, + 38, + 38, + 38, + 38, + 38, + 38, + 38, + 38, + 38, + 37, + 37, + 38, + 37, + 37, + 37, + 37, + 36, + 37, + 36, + 36, + 36, + 36, + 36, + 37, + 36, + 36, + 36, + 36, + 36, + 36, + 36, + 36, + 36, + 36, + 36, + 36, + 36, + 36, + 36, + 36, + 36, + 38, + 37, + 36, + 37, + 36, + 36, + 37, + 37, + 37, + 37, + 36, + 36, + 37, + 37 + ] + }, + "ata_sct_erc": { + "read": { + "enabled": false + }, + "write": { + "enabled": false + } + }, + "ata_device_statistics": { + "pages": [ + { + "number": 1, + "name": "General Statistics", + "revision": 1, + "table": [ + { + "offset": 8, + "name": "Lifetime Power-On Resets", + "size": 4, + "value": 13, + "flags": { + "value": 192, + "string": "V--- ", + "valid": true, + "normalized": false, + "supports_dsn": false, + "monitored_condition_met": false + } + }, + { + "offset": 16, + "name": "Power-on Hours", + "size": 4, + "value": 14551, + "flags": { + "value": 192, + "string": "V--- ", + "valid": true, + "normalized": false, + "supports_dsn": false, + "monitored_condition_met": false + } + }, + { + "offset": 24, + "name": "Logical Sectors Written", + "size": 6, + "value": 64777770148, + "flags": { + "value": 192, + "string": "V--- ", + "valid": true, + "normalized": false, + "supports_dsn": false, + "monitored_condition_met": false + } + }, + { + "offset": 32, + "name": "Number of Write Commands", + "size": 6, + "value": 1348861990, + "flags": { + "value": 192, + "string": "V--- ", + "valid": true, + "normalized": false, + "supports_dsn": false, + "monitored_condition_met": false + } + }, + { + "offset": 40, + "name": "Logical Sectors Read", + "size": 6, + "value": 34909544344, + "flags": { + "value": 192, + "string": "V--- ", + "valid": true, + "normalized": false, + "supports_dsn": false, + "monitored_condition_met": false + } + }, + { + "offset": 48, + "name": "Number of Read Commands", + "size": 6, + "value": 538928995, + "flags": { + "value": 192, + "string": "V--- ", + "valid": true, + "normalized": false, + "supports_dsn": false, + "monitored_condition_met": false + } + }, + { + "offset": 56, + "name": "Date and Time TimeStamp", + "size": 6, + "value": 1360000, + "flags": { + "value": 192, + "string": "V--- ", + "valid": true, + "normalized": false, + "supports_dsn": false, + "monitored_condition_met": false + } + } + ] + }, + { + "number": 4, + "name": "General Errors Statistics", + "revision": 1, + "table": [ + { + "offset": 8, + "name": "Number of Reported Uncorrectable Errors", + "size": 4, + "value": 0, + "flags": { + "value": 192, + "string": "V--- ", + "valid": true, + "normalized": false, + "supports_dsn": false, + "monitored_condition_met": false + } + }, + { + "offset": 16, + "name": "Resets Between Cmd Acceptance and Completion", + "size": 4, + "value": 32, + "flags": { + "value": 192, + "string": "V--- ", + "valid": true, + "normalized": false, + "supports_dsn": false, + "monitored_condition_met": false + } + } + ] + }, + { + "number": 5, + "name": "Temperature Statistics", + "revision": 1, + "table": [ + { + "offset": 8, + "name": "Current Temperature", + "size": 1, + "value": 36, + "flags": { + "value": 192, + "string": "V--- ", + "valid": true, + "normalized": false, + "supports_dsn": false, + "monitored_condition_met": false + } + }, + { + "offset": 32, + "name": "Highest Temperature", + "size": 1, + "value": 57, + "flags": { + "value": 192, + "string": "V--- ", + "valid": true, + "normalized": false, + "supports_dsn": false, + "monitored_condition_met": false + } + }, + { + "offset": 40, + "name": "Lowest Temperature", + "size": 1, + "value": 24, + "flags": { + "value": 192, + "string": "V--- ", + "valid": true, + "normalized": false, + "supports_dsn": false, + "monitored_condition_met": false + } + }, + { + "offset": 88, + "name": "Specified Maximum Operating Temperature", + "size": 1, + "value": 70, + "flags": { + "value": 192, + "string": "V--- ", + "valid": true, + "normalized": false, + "supports_dsn": false, + "monitored_condition_met": false + } + } + ] + }, + { + "number": 6, + "name": "Transport Statistics", + "revision": 1, + "table": [ + { + "offset": 8, + "name": "Number of Hardware Resets", + "size": 4, + "value": 133, + "flags": { + "value": 192, + "string": "V--- ", + "valid": true, + "normalized": false, + "supports_dsn": false, + "monitored_condition_met": false + } + }, + { + "offset": 16, + "name": "Number of ASR Events", + "size": 4, + "value": 0, + "flags": { + "value": 192, + "string": "V--- ", + "valid": true, + "normalized": false, + "supports_dsn": false, + "monitored_condition_met": false + } + }, + { + "offset": 24, + "name": "Number of Interface CRC Errors", + "size": 4, + "value": 0, + "flags": { + "value": 192, + "string": "V--- ", + "valid": true, + "normalized": false, + "supports_dsn": false, + "monitored_condition_met": false + } + } + ] + }, + { + "number": 7, + "name": "Solid State Device Statistics", + "revision": 1, + "table": [ + { + "offset": 8, + "name": "Percentage Used Endurance Indicator", + "size": 1, + "value": 19, + "flags": { + "value": 224, + "string": "VN-- ", + "valid": true, + "normalized": true, + "supports_dsn": false, + "monitored_condition_met": false + } + } + ] + } + ] + }, + "sata_phy_event_counters": { + "table": [ + { + "id": 1, + "name": "Command failed due to ICRC error", + "size": 2, + "value": 0, + "overflow": false + }, + { + "id": 2, + "name": "R_ERR response for data FIS", + "size": 2, + "value": 0, + "overflow": false + }, + { + "id": 3, + "name": "R_ERR response for device-to-host data FIS", + "size": 2, + "value": 0, + "overflow": false + }, + { + "id": 4, + "name": "R_ERR response for host-to-device data FIS", + "size": 2, + "value": 0, + "overflow": false + }, + { + "id": 5, + "name": "R_ERR response for non-data FIS", + "size": 2, + "value": 0, + "overflow": false + }, + { + "id": 6, + "name": "R_ERR response for device-to-host non-data FIS", + "size": 2, + "value": 0, + "overflow": false + }, + { + "id": 7, + "name": "R_ERR response for host-to-device non-data FIS", + "size": 2, + "value": 0, + "overflow": false + }, + { + "id": 8, + "name": "Device-to-host non-data FIS retries", + "size": 2, + "value": 0, + "overflow": false + }, + { + "id": 9, + "name": "Transition from drive PhyRdy to drive PhyNRdy", + "size": 2, + "value": 8, + "overflow": false + }, + { + "id": 10, + "name": "Device-to-host register FISes sent due to a COMRESET", + "size": 2, + "value": 8, + "overflow": false + }, + { + "id": 11, + "name": "CRC errors within host-to-device FIS", + "size": 2, + "value": 0, + "overflow": false + }, + { + "id": 13, + "name": "Non-CRC errors within host-to-device FIS", + "size": 2, + "value": 0, + "overflow": false + }, + { + "id": 15, + "name": "R_ERR response for host-to-device data FIS, CRC", + "size": 2, + "value": 0, + "overflow": false + }, + { + "id": 16, + "name": "R_ERR response for host-to-device data FIS, non-CRC", + "size": 2, + "value": 0, + "overflow": false + }, + { + "id": 18, + "name": "R_ERR response for host-to-device non-data FIS, CRC", + "size": 2, + "value": 0, + "overflow": false + }, + { + "id": 19, + "name": "R_ERR response for host-to-device non-data FIS, non-CRC", + "size": 2, + "value": 0, + "overflow": false + } + ], + "reset": false + } +} diff --git a/webapp/frontend/src/app/app.routing.ts b/webapp/frontend/src/app/app.routing.ts index 9ddf5ad..f7ad8bc 100644 --- a/webapp/frontend/src/app/app.routing.ts +++ b/webapp/frontend/src/app/app.routing.ts @@ -26,8 +26,8 @@ export const appRoutes: Route[] = [ children : [ // Example - {path: 'dashboard', loadChildren: () => import('app/modules/admin/dashboard/dashboard.module').then(m => m.DashboardModule)}, - {path: 'device/:wwn', loadChildren: () => import('app/modules/admin/detail/detail.module').then(m => m.DetailModule)} + {path: 'dashboard', loadChildren: () => import('app/modules/dashboard/dashboard.module').then(m => m.DashboardModule)}, + {path: 'device/:wwn', loadChildren: () => import('app/modules/detail/detail.module').then(m => m.DetailModule)} // 404 & Catch all // {path: '404-not-found', pathMatch: 'full', loadChildren: () => import('app/modules/admin/pages/errors/error-404/error-404.module').then(m => m.Error404Module)}, diff --git a/webapp/frontend/src/app/layout/common/dashboard-settings/dashboard-settings.component.html b/webapp/frontend/src/app/layout/common/dashboard-settings/dashboard-settings.component.html new file mode 100644 index 0000000..d821ecd --- /dev/null +++ b/webapp/frontend/src/app/layout/common/dashboard-settings/dashboard-settings.component.html @@ -0,0 +1,82 @@ +

Scrutiny Settings

+ + +
+
+ + Sort By + + Status + Name + Label + + +
+ +
+ + + +
+ + Critical Error Threshold + + + + Critical Warning Threshold + + +
+ +
+ + Error Threshold + + + + Warning Threshold + + +
+ +
+ + +
+ + Critical Error Threshold + + + + Critical Warning Threshold + + +
+ +
+ +
+ + Critical Error Threshold + + + + Critical Warning Threshold + + +
+
+
+
+
+ +
+ + + + + + + diff --git a/webapp/frontend/src/app/layout/common/dashboard-settings/dashboard-settings.component.scss b/webapp/frontend/src/app/layout/common/dashboard-settings/dashboard-settings.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/webapp/frontend/src/app/layout/common/dashboard-settings/dashboard-settings.component.spec.ts b/webapp/frontend/src/app/layout/common/dashboard-settings/dashboard-settings.component.spec.ts new file mode 100644 index 0000000..95a052f --- /dev/null +++ b/webapp/frontend/src/app/layout/common/dashboard-settings/dashboard-settings.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { DashboardSettingsComponent } from './dashboard-settings.component'; + +describe('DashboardSettingsComponent', () => { + let component: DashboardSettingsComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ DashboardSettingsComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(DashboardSettingsComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/webapp/frontend/src/app/layout/common/dashboard-settings/dashboard-settings.component.ts b/webapp/frontend/src/app/layout/common/dashboard-settings/dashboard-settings.component.ts new file mode 100644 index 0000000..4e1529d --- /dev/null +++ b/webapp/frontend/src/app/layout/common/dashboard-settings/dashboard-settings.component.ts @@ -0,0 +1,17 @@ +import { Component, OnInit } from '@angular/core'; + +@Component({ + selector: 'app-dashboard-settings', + templateUrl: './dashboard-settings.component.html', + styleUrls: ['./dashboard-settings.component.scss'] +}) +export class DashboardSettingsComponent implements OnInit { + + constructor() { } + + ngOnInit(): void { + } + formatLabel(value: number) { + return value; + } +} diff --git a/webapp/frontend/src/app/layout/common/dashboard-settings/dashboard-settings.module.ts b/webapp/frontend/src/app/layout/common/dashboard-settings/dashboard-settings.module.ts new file mode 100644 index 0000000..7c01da2 --- /dev/null +++ b/webapp/frontend/src/app/layout/common/dashboard-settings/dashboard-settings.module.ts @@ -0,0 +1,44 @@ +import { NgModule } from '@angular/core'; +import { RouterModule } from '@angular/router'; +import { Overlay } from '@angular/cdk/overlay'; +import { MAT_AUTOCOMPLETE_SCROLL_STRATEGY, MatAutocompleteModule } from '@angular/material/autocomplete'; +import { MatButtonModule } from '@angular/material/button'; +import { MatSelectModule } from '@angular/material/select'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { MatIconModule } from '@angular/material/icon'; +import { MatInputModule } from '@angular/material/input'; +import { SharedModule } from 'app/shared/shared.module'; +import {DashboardSettingsComponent} from 'app/layout/common/dashboard-settings/dashboard-settings.component' +import { MatDialogModule } from "@angular/material/dialog"; +import { MatButtonToggleModule} from "@angular/material/button-toggle"; +import {MatTabsModule} from "@angular/material/tabs"; +import {MatSliderModule} from "@angular/material/slider"; +import {MatSlideToggleModule} from "@angular/material/slide-toggle"; + +@NgModule({ + declarations: [ + DashboardSettingsComponent + ], + imports : [ + RouterModule.forChild([]), + MatAutocompleteModule, + MatDialogModule, + MatButtonModule, + MatSelectModule, + MatFormFieldModule, + MatIconModule, + MatInputModule, + MatButtonToggleModule, + MatTabsModule, + MatSliderModule, + MatSlideToggleModule, + SharedModule + ], + exports : [ + DashboardSettingsComponent + ], + providers : [] +}) +export class DashboardSettingsModule +{ +} diff --git a/webapp/frontend/src/app/modules/admin/dashboard/dashboard.component.html b/webapp/frontend/src/app/modules/dashboard/dashboard.component.html similarity index 96% rename from webapp/frontend/src/app/modules/admin/dashboard/dashboard.component.html rename to webapp/frontend/src/app/modules/dashboard/dashboard.component.html index 09212ac..af1bc68 100644 --- a/webapp/frontend/src/app/modules/admin/dashboard/dashboard.component.html +++ b/webapp/frontend/src/app/modules/dashboard/dashboard.component.html @@ -10,15 +10,13 @@
- -