Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Testing - 2024-06-06 16:02 #24

Merged
merged 4 commits into from
Jun 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 12 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -115,21 +115,29 @@ Créer d'autres utilisateurs si besoin (dans la barre latérale: *Administration

En cas de modification ou de migration de l'instance, penser à faire un backup de *routers.json*, *global_targets.json* et *mikrotik_targets.json* pour ne pas avoir à ajouter tous les routeurs à nouveau, ainsi que des mots de passe renseignés dans *snmp_config.yml*.

## Ajout et supression de routeur
## mikromap-cli

### Ajout
### Ajout de routeurs à la supervision

L'ajout de routeur à la supervision se fait via *mikromap-cli*:
```bash
cd ~/mikrotik-grafana/bin/
./mikromap-cli
```

Pour ajouter plusieurs routeurs sans redémarrer l'application à chaque fois, utiliser le flag ```-n [valeur positive]```.

- Si l'adresse IP à ajouter correspond à un Watchguard, l'indiquer en ajoutant un *W* sans espace avant l'adresse IP pour éviter des problèmes de compatibilité (ex: ***W**8.8.8.8*)
- Si le routeur ne doit pas être affiché sur la carte, laisser l'adresse postale vide.
> N.B.- L'adresse postale entrée n'a pas besoin d'être parfaitement écrite (pas besoin d'accents, tirets, etc.) mais veiller à inclure un minimum d'informations pour que l'API renvoie les bonnes coordonnées (ex: *1 rue leclerc st etienne* suffit à obtenir *1 Rue du Général Leclerc 42100 Saint-Étienne*)
- Le nom d'utilisateur Grafana renseigné est comparé à celui renvoyé directement par Grafana, et doit donc **être identique** à celui du compte Grafana associé (pas grave si les majuscules sont différentes), sinon il n'apparaîtra pas sur le dashboard de cet utilisateur. Laisser le champ vide si le routeur ne doit être visible que par l'admin.

### Suppression
### Suppression de routeurs de la supervision

Pour supprimer un routeur, utiliser *mikromap-cli* avec le flag ```-n [valeur négative]```. Il n'y a besoin que de l'adresse IP du routeur, et le préfixe *W* n'est pas nécessaire pour désigner un Watchguard.

### Création automatique des utilisateurs

Si le flag ```--users``` est activé, l'outil parcourera tous les routeurs et pour chacun tentera un appel à l'API d'administration de Grafana pour ajouter un utilisateur. Si l'utilisateur n'existe pas encore, il est créé et la paire login:password générée est stockée dans un fichier sous *mikrotik-grafana/users/*.

Pour supprimer un routeur, utiliser *mikromap-cli* et entrer un nombre négatif de routeurs à ajouter. Il n'y a besoin que de l'adresse IP du routeur, et le préfixe *W* n'est pas nécessaire pour désigner un Watchguard.
Pour que les appels à l'API puissent passer, indiquer le mot de passe de l'administateur Grafana avec ```--pass [mot de passe]```. De même, si on fait un appel à une instance distante ou sur un port autre que 3000, indiquer son IP avec ```--grafana [{ip}:{port}]```.
5 changes: 5 additions & 0 deletions src/mikromap-cli/go.mod
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
module mikromap-cli

go 1.19

require (
github.com/pborman/getopt/v2 v2.1.0 // indirect
github.com/sethvargo/go-password v0.3.0 // indirect
)
4 changes: 4 additions & 0 deletions src/mikromap-cli/go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
github.com/pborman/getopt/v2 v2.1.0 h1:eNfR+r+dWLdWmV8g5OlpyrTYHkhVNxHBdN2cCrJmOEA=
github.com/pborman/getopt/v2 v2.1.0/go.mod h1:4NtW75ny4eBw9fO1bhtNdYTlZKYX5/tBLtsOpwKIKd0=
github.com/sethvargo/go-password v0.3.0 h1:OLFHZ91Z7NiNP3dnaPxLxCDXlb6TBuxFzMvv6bu+Ptw=
github.com/sethvargo/go-password v0.3.0/go.mod h1:p6we8DZ0eyYXof9pon7Cqrw98N4KTaYiadDml1dUEEw=
117 changes: 111 additions & 6 deletions src/mikromap-cli/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ import (
"net/http"
"os"
"strings"

"github.com/pborman/getopt/v2"
"github.com/sethvargo/go-password/password"
)

// Structure routers.json
Expand All @@ -33,6 +36,15 @@ type Labels struct {
Job string `json:"job"`
}

// Structure utilisateur Grafana.
type User struct {
Name string `json:"name"`
Email string `json:"email"`
Login string `json:"login"`
Password string `json:"password"`
OrgId int `json:"OrgId"`
}

// Fait un appel à l'API renseignée.
// Prend en entrée une adresse (string), renvoie le code de statut (int) et le corps ([]byte) de la réponse.
// L'API Adresse du gouvernement est gratuite et fonctionne parfaitement pour la France (50 calls/IP/sec).
Expand Down Expand Up @@ -186,6 +198,88 @@ func writePromTargets(data []PromTargets, target string) {
}
}

// Crée un novueau fichier et y écrit la paire login:password d'un utilisateur.
// Méthode de User. Ne prend rien en entrée et ne renvoie rien.
// Les fichiers sont sauvegardés dans ~/mikrotik-grafana/users/.
func (user User) saveUser() {

// Récupération chemin et données à écrire
var path string = fmt.Sprintf("%s/mikrotik-grafana/users/%s", os.Getenv("HOME"), user.Name)
data := fmt.Sprintf("%s:%s", user.Login, user.Password)

// Création du dossier users/ s'il n'existe pas
err := os.Mkdir(strings.TrimSuffix(path, user.Name), 0700)
if err != nil {
log.Fatalf("--- Erreur lors de la création du dossier 'users': %s", err)
}

// Création du fichier
file, err := os.Create(path)
if err != nil {
log.Fatalf("--- Erreur lors de la création du fichier utilisateur : %s", err)
}
defer file.Close()

// Ecriture du fichier
_, err = file.Write([]byte(data))
if err != nil {
log.Fatalf("--- Erreur lors de la sauvegarde de l'utilisateur: %s", err)
}
}

// Parcourt routers.json et fait un call à l'API d'admin Grafana pour chaque nom d'utilisateur.
// Si l'utilisateur existe déjà, l'API renvoie un 412 et l'utilisateur n'est pas créé.
// Sinon l'API renvoie un 200, donc on crée le fichier qui contient la paire login:password.
func addUsers(pass string, grafanaIP string) {

var url string
dataRouters := readJSON()

fmt.Println("--- Création des utilisateurs dans Grafana...")

// Parcours de tous les routeurs
for _, v := range dataRouters {

// Génération du login et du password
login := strings.ToLower(v.Username)
password, err := password.Generate(10, 2, 2, false, false)
if err != nil {
log.Fatalf("--- Erreur lors de la génération du mot de passe: %s", err)
}

// Création du nouvel utilisateur
newUser := User{
Name: v.Username,
Email: login,
Login: login,
Password: password,
OrgId: 1,
}

// Formatage du struc en JSON pour transmission à l'API
payload, err := json.Marshal(newUser)
if err != nil {
log.Fatalf("--- Erreur lors de la génération du payload : %s", err)
}

// Formation de l'URL
url = fmt.Sprintf("http://admin:%s@%s/api/admin/users", pass, grafanaIP)

// Requête POST à l'API
resp, err := http.Post(url, "application/json", bytes.NewBuffer(payload))
if err != nil {
log.Fatalf("--- Erreur lors de la requête à l'API d'administration de Grafana: %s", err)
}

// Si le l'API a crée l'utilisateur avec succès, on crée son fichier via saveUser().
if resp.StatusCode == 200 {
newUser.saveUser()
}
}

fmt.Println("--- Utilisateurs créés.")
}

// Fonction principale qui ajoute un routeur aux fichiers.
// Ne prend rien en entrée et ne renvoie rien.
func addRouter() {
Expand Down Expand Up @@ -331,14 +425,20 @@ func removeRouter() {

func main() {

var n int
// Création flags par défaut
var n int = 1
var users bool = false
var pass string = "admin"
var grafanaIP = "127.0.0.1:3000"

fmt.Print("\033[32mNombre de routeurs à ajouter >>> \033[0m")
_, err := fmt.Scanln(&n)
if err != nil {
log.Fatalf("--- Erreur lors de la récupération de la saisie:\n%s", err)
}
// Récupération des flags.
getopt.Flag(&n, 'n', "Nombre de routeurs à ajouter (ou supprimer si un nombre négatif est entré). Peut valoir 0 (si on veut uniquement créer les utilisateurs déjà dans les fichiers).\nDéfaut:")
getopt.FlagLong(&users, "users", 'u', "Utiliser si les utilisateurs doivent être créés automatiquement sur Grafana. Les paires login:password sont enregistrées dans mikrotik-grafana/users/.")
getopt.FlagLong(&pass, "pass", 'p', "Mot de passe administrateur à utiliser lors des appels à l'API d'administration de Grafana.\nDéfaut:")
getopt.FlagLong(&grafanaIP, "grafana", 'g', "IP:port de l'instance Grafana vers laquelle faire les appels à l'API d'administration.\nDéfaut:")
getopt.ParseV2()

// Appel à addRouter() ou removeRouter() selon la valeur de n
if n >= 0 {
for i := 0; i < n; i++ {
addRouter()
Expand All @@ -348,4 +448,9 @@ func main() {
removeRouter()
}
}

// Appel à addUsers si le flag users est activé
if users {
addUsers(pass, grafanaIP)
}
}