...

Source file src/edge-infra.dev/hack/tools/cicterminals/use-database/use-database.go

Documentation: edge-infra.dev/hack/tools/cicterminals/use-database

     1  /*
     2  How to use:
     3  cicterminals useDatabase --databaseHost=localhost --databaseName=dev0 --databaseUser=postgres
     4  --topLevelProjectID=ret-edge-dev0-foreman --chariotTopic=chariot-rides
     5  */
     6  package usedatabase
     7  
     8  import (
     9  	"context"
    10  	"database/sql"
    11  	"encoding/json"
    12  	"fmt"
    13  	"os"
    14  
    15  	"edge-infra.dev/hack/tools/cicterminals/cicterminals"
    16  	"edge-infra.dev/pkg/edge/api/graph/mapper"
    17  	"edge-infra.dev/pkg/edge/api/graph/model"
    18  	query "edge-infra.dev/pkg/edge/api/sql"
    19  	"edge-infra.dev/pkg/edge/api/utils"
    20  )
    21  
    22  // CreateIENode calls getClusters which queries the database and creates the IENodes
    23  func CreateIENode(ctx context.Context, db *sql.DB, projectID, foremanProjectID, cicClusterEdgeID, topic string, dryRun bool) bool {
    24  	return getClusters(ctx, db, projectID, foremanProjectID, cicClusterEdgeID, topic, dryRun)
    25  }
    26  
    27  func getClusters(ctx context.Context, db *sql.DB, projectID, foremanProjectID, cicClusterEdgeID, topic string, dryRun bool) bool {
    28  	rows, err := db.QueryContext(ctx, cicterminals.GetClustersForBanner, projectID)
    29  	if err != nil {
    30  		fmt.Fprintf(os.Stderr, "error getting banner's clusters for project %s: %s\n", projectID, err)
    31  		return true
    32  	}
    33  	for rows.Next() {
    34  		var clusterEdgeID string
    35  
    36  		err := rows.Scan(&clusterEdgeID)
    37  		if err != nil {
    38  			fmt.Fprintf(os.Stderr, "error scanning cluster vars for cluster %s: %s\n", clusterEdgeID, err)
    39  			continue
    40  		}
    41  
    42  		getTerminals(ctx, db, clusterEdgeID, projectID, foremanProjectID, cicClusterEdgeID, topic, dryRun)
    43  	}
    44  	return true
    45  }
    46  
    47  // getTerminals gets all the terminals for the associated clusterEdgeID, fetches the
    48  // cluster network services, and terminal interfaces. Creates a new IENode resource
    49  // for the terminal and sends the IENode to chariot with the correct folder location
    50  // for the cluster infra cluster.
    51  func getTerminals(ctx context.Context, db *sql.DB, clusterEdgeID, projectID, foremanProjectID, cicClusterEdgeID, topic string, dryRun bool) {
    52  	clusterNetworkServices, err := getClusterNetworkServices(ctx, db, clusterEdgeID)
    53  	if err != nil {
    54  		fmt.Fprintf(os.Stderr, "error finding cluster network services for cluster %s: %s\n", clusterEdgeID, err)
    55  		return
    56  	}
    57  
    58  	var edgeVersion string
    59  	row := db.QueryRowContext(ctx, cicterminals.GetClusterEdgeVersion, clusterEdgeID)
    60  	err = row.Scan(&edgeVersion)
    61  	if err != nil {
    62  		fmt.Fprintf(os.Stderr, "error getting edge version for cluster %s: %s\n", clusterEdgeID, err)
    63  		return
    64  	}
    65  
    66  	rows, err := db.QueryContext(ctx, cicterminals.GetTerminalsForCluster, clusterEdgeID)
    67  	if err != nil {
    68  		fmt.Fprintf(os.Stderr, "error getting cluster's terminals %s: %s\n", clusterEdgeID, err)
    69  		return
    70  	}
    71  	for rows.Next() {
    72  		var terminal model.Terminal
    73  
    74  		err := rows.Scan(&terminal.TerminalID, &terminal.Lane, &terminal.Role, &terminal.ClusterEdgeID, &terminal.Hostname, &terminal.Class)
    75  		if err != nil {
    76  			fmt.Fprintf(os.Stderr, "error scanning terminal vars %s: %s\n", clusterEdgeID, err)
    77  			continue
    78  		}
    79  
    80  		interfaces, err := getInterfaces(ctx, db, terminal.TerminalID)
    81  		if err != nil {
    82  			fmt.Fprintf(os.Stderr, "error finding interfaces for terminal %s: %s\n", terminal.TerminalID, err)
    83  			continue
    84  		}
    85  
    86  		terminal.Interfaces = interfaces
    87  
    88  		ienode := mapper.TerminalToCICIENode(&terminal, clusterNetworkServices, make(map[string]string, 0), edgeVersion)
    89  
    90  		ienodebytes, err := json.Marshal(ienode)
    91  		if err != nil {
    92  			fmt.Fprintf(os.Stderr, "error converting IENode to bytes %s: %s\n", terminal.TerminalID, err)
    93  			continue
    94  		}
    95  
    96  		fmt.Println(string(ienodebytes))
    97  		fmt.Println("")
    98  		if !dryRun {
    99  			ienodebase64 := utils.ToBase64(ienodebytes)
   100  			chariotMessage := cicterminals.CreateChariotMessage(projectID, cicClusterEdgeID, cicterminals.Filter, ienodebase64)
   101  			err = cicterminals.InvokeChariot(ctx, foremanProjectID, topic, chariotMessage)
   102  			if err != nil {
   103  				fmt.Fprintf(os.Stderr, "failed to send configmap to chariot %s: %s\n", terminal.TerminalID, err)
   104  				continue
   105  			}
   106  		}
   107  	}
   108  }
   109  
   110  func getInterfaces(ctx context.Context, db *sql.DB, terminalID string) ([]*model.TerminalInterface, error) {
   111  	var interfaces []*model.TerminalInterface
   112  	rows, err := db.QueryContext(ctx, query.GetTerminalInterfaceByTerminalIDQuery, terminalID)
   113  	if err != nil {
   114  		return nil, err
   115  	}
   116  
   117  	for rows.Next() {
   118  		var tInterface model.TerminalInterface
   119  
   120  		err := rows.Scan(&tInterface.TerminalInterfaceID, &tInterface.MacAddress, &tInterface.Dhcp4, &tInterface.Dhcp6, &tInterface.Gateway4, &tInterface.Gateway6, &tInterface.TerminalID)
   121  		if err != nil {
   122  			return nil, err
   123  		}
   124  
   125  		addresses, err := getAddresses(ctx, db, tInterface.TerminalInterfaceID)
   126  		if err != nil {
   127  			return nil, err
   128  		}
   129  
   130  		tInterface.Addresses = addresses
   131  
   132  		interfaces = append(interfaces, &tInterface)
   133  	}
   134  
   135  	return interfaces, rows.Err()
   136  }
   137  
   138  func getAddresses(ctx context.Context, db *sql.DB, interfaceID string) ([]*model.TerminalAddress, error) {
   139  	var addresses []*model.TerminalAddress
   140  	rows, err := db.QueryContext(ctx, query.GetTerminalAddressByInterfaceIDQuery, interfaceID)
   141  	if err != nil {
   142  		return nil, err
   143  	}
   144  
   145  	for rows.Next() {
   146  		var address model.TerminalAddress
   147  
   148  		err := rows.Scan(&address.TerminalAddressID, &address.IP, &address.PrefixLen, &address.Family, &address.TerminalInterfaceID)
   149  		if err != nil {
   150  			return nil, err
   151  		}
   152  
   153  		addresses = append(addresses, &address)
   154  	}
   155  
   156  	return addresses, rows.Err()
   157  }
   158  
   159  func getClusterNetworkServices(ctx context.Context, db *sql.DB, clusterEdgeID string) ([]*model.ClusterNetworkServiceInfo, error) {
   160  	var clusterNetworkServices []*model.ClusterNetworkServiceInfo
   161  	rows, err := db.QueryContext(ctx, query.GetClusterNetworkServices, clusterEdgeID)
   162  	if err != nil {
   163  		return nil, err
   164  	}
   165  
   166  	for rows.Next() {
   167  		var networkService model.ClusterNetworkServiceInfo
   168  
   169  		err := rows.Scan(&networkService.NetworkServiceID, &networkService.IP, &networkService.Family, &networkService.ServiceType, &networkService.Priority)
   170  		if err != nil {
   171  			return nil, err
   172  		}
   173  
   174  		clusterNetworkServices = append(clusterNetworkServices, &networkService)
   175  	}
   176  
   177  	return clusterNetworkServices, nil
   178  }
   179  

View as plain text